From f38983022a637df77f9caebae4e6d5fdc334d072 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 24 Apr 2014 12:14:13 +0000 Subject: [PATCH] [OLE32] * Sync with Wine 1.7.17. CORE-8080 svn path=/trunk/; revision=62938 --- reactos/dll/win32/ole32/antimoniker.c | 2 +- reactos/dll/win32/ole32/bindctx.c | 7 +- reactos/dll/win32/ole32/classmoniker.c | 37 +- reactos/dll/win32/ole32/comcat.c | 363 ++++----- reactos/dll/win32/ole32/compobj.c | 811 ++++++++++++++++----- reactos/dll/win32/ole32/compobj_private.h | 2 + reactos/dll/win32/ole32/compositemoniker.c | 8 +- reactos/dll/win32/ole32/dcom.idl | 3 + reactos/dll/win32/ole32/filemoniker.c | 166 ++--- reactos/dll/win32/ole32/ifs.c | 32 +- reactos/dll/win32/ole32/irot.idl | 2 + reactos/dll/win32/ole32/itemmoniker.c | 2 +- reactos/dll/win32/ole32/marshal.c | 83 +-- reactos/dll/win32/ole32/moniker.c | 12 +- reactos/dll/win32/ole32/ole2.c | 158 ++-- reactos/dll/win32/ole32/ole32.spec | 8 +- reactos/dll/win32/ole32/ole32_objidl.idl | 3 + reactos/dll/win32/ole32/ole32_oleidl.idl | 3 + reactos/dll/win32/ole32/ole32_unknwn.idl | 3 + reactos/dll/win32/ole32/stg_prop.c | 6 +- reactos/dll/win32/ole32/storage32.c | 175 +++-- reactos/dll/win32/ole32/storage32.h | 10 +- reactos/dll/win32/ole32/stubmanager.c | 9 +- reactos/include/psdk/objbase.h | 50 +- reactos/media/doc/README.WINE | 2 +- 25 files changed, 1228 insertions(+), 729 deletions(-) diff --git a/reactos/dll/win32/ole32/antimoniker.c b/reactos/dll/win32/ole32/antimoniker.c index 93a714056bc..86d30267dae 100644 --- a/reactos/dll/win32/ole32/antimoniker.c +++ b/reactos/dll/win32/ole32/antimoniker.c @@ -112,7 +112,7 @@ AntiMonikerImpl_Release(IMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* destroy the object if there's no more reference on it */ + /* destroy the object if there are no more references to it */ if (ref == 0) { if (This->pMarshal) IUnknown_Release(This->pMarshal); diff --git a/reactos/dll/win32/ole32/bindctx.c b/reactos/dll/win32/ole32/bindctx.c index 18e52da470f..d3f27d7b905 100644 --- a/reactos/dll/win32/ole32/bindctx.c +++ b/reactos/dll/win32/ole32/bindctx.c @@ -421,9 +421,8 @@ static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This, LPOLESTR pszkey, DWORD *index) { - DWORD i; - BYTE found=0; + BOOL found = FALSE; TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index); @@ -440,14 +439,14 @@ static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This, ) ) - found=1; + found = TRUE; } } else /* search object identified by a moniker*/ for(i=0; ( (ibindCtxTableLastIndex) && (!found));i++) if(This->bindCtxTable[i].pObj==punk) - found=1; + found = TRUE; if (index != NULL) *index=i-1; diff --git a/reactos/dll/win32/ole32/classmoniker.c b/reactos/dll/win32/ole32/classmoniker.c index c3a937b2d93..2d3dff884eb 100644 --- a/reactos/dll/win32/ole32/classmoniker.c +++ b/reactos/dll/win32/ole32/classmoniker.c @@ -103,20 +103,6 @@ static ULONG WINAPI ClassMoniker_AddRef(IMoniker* iface) return InterlockedIncrement(&This->ref); } -/****************************************************************************** - * ClassMoniker_Destroy (local function) - *******************************************************************************/ -static HRESULT ClassMoniker_Destroy(ClassMoniker* This) -{ - TRACE("(%p)\n",This); - - if (This->pMarshal) IUnknown_Release(This->pMarshal); - - HeapFree(GetProcessHeap(),0,This); - - return S_OK; -} - /****************************************************************************** * ClassMoniker_Release ******************************************************************************/ @@ -129,8 +115,12 @@ static ULONG WINAPI ClassMoniker_Release(IMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* destroy the object if there's no more reference on it */ - if (ref == 0) ClassMoniker_Destroy(This); + /* destroy the object if there are no more references to it */ + if (ref == 0) + { + if (This->pMarshal) IUnknown_Release(This->pMarshal); + HeapFree(GetProcessHeap(),0,This); + } return ref; } @@ -262,7 +252,7 @@ static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface, VOID** ppvResult) { TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult); - return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult); + return IMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult); } /****************************************************************************** @@ -279,7 +269,7 @@ static HRESULT WINAPI ClassMoniker_Reduce(IMoniker* iface, if (!ppmkReduced) return E_POINTER; - ClassMoniker_AddRef(iface); + IMoniker_AddRef(iface); *ppmkReduced = iface; @@ -585,7 +575,7 @@ static HRESULT WINAPI ClassMonikerROTData_QueryInterface(IROTData *iface,REFIID TRACE("(%p,%p,%p)\n",iface,riid,ppvObject); - return ClassMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject); + return IMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject); } /*********************************************************************** @@ -597,7 +587,7 @@ static ULONG WINAPI ClassMonikerROTData_AddRef(IROTData *iface) TRACE("(%p)\n",iface); - return ClassMoniker_AddRef(&This->IMoniker_iface); + return IMoniker_AddRef(&This->IMoniker_iface); } /*********************************************************************** @@ -609,7 +599,7 @@ static ULONG WINAPI ClassMonikerROTData_Release(IROTData* iface) TRACE("(%p)\n",iface); - return ClassMoniker_Release(&This->IMoniker_iface); + return IMoniker_Release(&This->IMoniker_iface); } /****************************************************************************** @@ -859,9 +849,10 @@ static const IClassFactoryVtbl ClassMonikerCFVtbl = ClassMonikerCF_CreateInstance, ClassMonikerCF_LockServer }; -static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl; + +static IClassFactory ClassMonikerCF = { &ClassMonikerCFVtbl }; HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv) { - return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv); + return IClassFactory_QueryInterface(&ClassMonikerCF, riid, ppv); } diff --git a/reactos/dll/win32/ole32/comcat.c b/reactos/dll/win32/ole32/comcat.c index 0f23debd955..d0cebba0b52 100644 --- a/reactos/dll/win32/ole32/comcat.c +++ b/reactos/dll/win32/ole32/comcat.c @@ -38,14 +38,16 @@ static ComCatMgrImpl COMCAT_ComCatMgr = { &COMCAT_ICatInformation_Vtbl } }; -struct class_categories { - LPCWSTR impl_strings; - LPCWSTR req_strings; +struct class_categories +{ + ULONG size; /* total length, including structure itself */ + ULONG impl_offset; + ULONG req_offset; }; -static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid); -static LPENUMGUID COMCAT_CLSID_IEnumGUID_Construct(struct class_categories *class_categories); -static LPENUMGUID COMCAT_CATID_IEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req); +static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret); +static HRESULT CLSIDEnumGUID_Construct(struct class_categories *class_categories, IEnumCLSID **ret); +static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req, IEnumCATID **ret); /********************************************************************** * File-scope string constants @@ -68,14 +70,14 @@ static HRESULT COMCAT_RegisterClassCategories( ULONG cCategories, const CATID *rgcatid) { - WCHAR keyname[39]; + WCHAR keyname[CHARS_IN_GUID]; HRESULT res; HKEY clsid_key, class_key, type_key; if (cCategories && rgcatid == NULL) return E_POINTER; /* Format the class key name. */ - res = StringFromGUID2(rclsid, keyname, 39); + res = StringFromGUID2(rclsid, keyname, CHARS_IN_GUID); if (FAILED(res)) return res; /* Create (or open) the CLSID key. */ @@ -92,7 +94,7 @@ static HRESULT COMCAT_RegisterClassCategories( HKEY key; /* Format the category key name. */ - res = StringFromGUID2(rgcatid, keyname, 39); + res = StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID); if (FAILED(res)) continue; /* Do the register. */ @@ -124,7 +126,7 @@ static HRESULT COMCAT_UnRegisterClassCategories( if (cCategories && rgcatid == NULL) return E_POINTER; /* Format the class category type key name. */ - res = StringFromGUID2(rclsid, keyname + 6, 39); + res = StringFromGUID2(rclsid, keyname + 6, CHARS_IN_GUID); if (FAILED(res)) return res; keyname[44] = '\\'; lstrcpyW(keyname + 45, type); @@ -135,7 +137,7 @@ static HRESULT COMCAT_UnRegisterClassCategories( for (; cCategories; --cCategories, ++rgcatid) { /* Format the category key name. */ - res = StringFromGUID2(rgcatid, keyname, 39); + res = StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID); if (FAILED(res)) continue; /* Do the unregister. */ @@ -179,25 +181,26 @@ static struct class_categories *COMCAT_PrepareClassCategories( { struct class_categories *categories; WCHAR *strings; + ULONG size; - categories = HeapAlloc( - GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(struct class_categories) + - ((impl_count + req_count) * 39 + 2) * sizeof(WCHAR)); + size = sizeof(struct class_categories) + ((impl_count + req_count)*CHARS_IN_GUID + 2)*sizeof(WCHAR); + categories = HeapAlloc(GetProcessHeap(), 0, size); if (categories == NULL) return categories; + categories->size = size; + categories->impl_offset = sizeof(struct class_categories); + categories->req_offset = categories->impl_offset + (impl_count*CHARS_IN_GUID + 1)*sizeof(WCHAR); + strings = (WCHAR *)(categories + 1); - categories->impl_strings = strings; while (impl_count--) { - StringFromGUID2(impl_catids++, strings, 39); - strings += 39; + StringFromGUID2(impl_catids++, strings, CHARS_IN_GUID); + strings += CHARS_IN_GUID; } *strings++ = 0; - categories->req_strings = strings; while (req_count--) { - StringFromGUID2(req_catids++, strings, 39); - strings += 39; + StringFromGUID2(req_catids++, strings, CHARS_IN_GUID); + strings += CHARS_IN_GUID; } *strings++ = 0; @@ -211,16 +214,20 @@ static HRESULT COMCAT_IsClassOfCategories( HKEY key, struct class_categories const* categories) { + const WCHAR *impl_strings, *req_strings; HKEY subkey; HRESULT res; DWORD index; LPCWSTR string; + impl_strings = (WCHAR*)((BYTE*)categories + categories->impl_offset); + req_strings = (WCHAR*)((BYTE*)categories + categories->req_offset); + /* Check that every given category is implemented by class. */ - if (*categories->impl_strings) { + if (*impl_strings) { res = open_classes_key(key, impl_keyname, KEY_READ, &subkey); if (res != ERROR_SUCCESS) return S_FALSE; - for (string = categories->impl_strings; *string; string += 39) { + for (string = impl_strings; *string; string += CHARS_IN_GUID) { HKEY catkey; res = open_classes_key(subkey, string, 0, &catkey); if (res != ERROR_SUCCESS) { @@ -236,14 +243,14 @@ static HRESULT COMCAT_IsClassOfCategories( res = open_classes_key(key, req_keyname, KEY_READ, &subkey); if (res == ERROR_SUCCESS) { for (index = 0; ; ++index) { - WCHAR keyname[39]; - DWORD size = 39; + WCHAR keyname[CHARS_IN_GUID]; + DWORD size = CHARS_IN_GUID; res = RegEnumKeyExW(subkey, index, keyname, &size, NULL, NULL, NULL, NULL); if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break; - if (size != 38) continue; /* bogus catid in registry */ - for (string = categories->req_strings; *string; string += 39) + if (size != CHARS_IN_GUID-1) continue; /* bogus catid in registry */ + for (string = req_strings; *string; string += CHARS_IN_GUID) if (!strcmpiW(string, keyname)) break; if (!*string) { RegCloseKey(subkey); @@ -321,19 +328,18 @@ static HRESULT WINAPI COMCAT_ICatRegister_RegisterCategories( for (; cCategories; --cCategories, ++rgci) { static const WCHAR fmt[] = { '%', 'l', 'X', 0 }; - WCHAR keyname[39]; + WCHAR keyname[CHARS_IN_GUID]; WCHAR valname[9]; HKEY cat_key; /* Create (or open) the key for this category. */ - if (!StringFromGUID2(&rgci->catid, keyname, 39)) continue; + if (!StringFromGUID2(&rgci->catid, keyname, CHARS_IN_GUID)) continue; res = create_classes_key(comcat_key, keyname, KEY_READ|KEY_WRITE, &cat_key); if (res != ERROR_SUCCESS) continue; /* Set the value for this locale's description. */ wsprintfW(valname, fmt, rgci->lcid); - RegSetValueExW(cat_key, valname, 0, REG_SZ, - (CONST BYTE*)(rgci->szDescription), + RegSetValueExW(cat_key, valname, 0, REG_SZ, (const BYTE*)rgci->szDescription, (lstrlenW(rgci->szDescription) + 1) * sizeof(WCHAR)); RegCloseKey(cat_key); @@ -364,10 +370,10 @@ static HRESULT WINAPI COMCAT_ICatRegister_UnRegisterCategories( if (res != ERROR_SUCCESS) return E_FAIL; for (; cCategories; --cCategories, ++rgcatid) { - WCHAR keyname[39]; + WCHAR keyname[CHARS_IN_GUID]; /* Delete the key for this category. */ - if (!StringFromGUID2(rgcatid, keyname, 39)) continue; + if (!StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID)) continue; RegDeleteKeyW(comcat_key, keyname); } @@ -474,10 +480,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumCategories( if (ppenumCatInfo == NULL) return E_POINTER; - *ppenumCatInfo = COMCAT_IEnumCATEGORYINFO_Construct(lcid); - if (*ppenumCatInfo == NULL) return E_OUTOFMEMORY; - IEnumCATEGORYINFO_AddRef(*ppenumCatInfo); - return S_OK; + return EnumCATEGORYINFO_Construct(lcid, ppenumCatInfo); } /********************************************************************** @@ -500,7 +503,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_GetCategoryDesc( if (rcatid == NULL || ppszDesc == NULL) return E_INVALIDARG; /* Open the key for this category. */ - if (!StringFromGUID2(rcatid, keyname + 21, 39)) return E_FAIL; + if (!StringFromGUID2(rcatid, keyname + 21, CHARS_IN_GUID)) return E_FAIL; res = open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &key); if (res != ERROR_SUCCESS) return CAT_E_CATIDNOEXIST; @@ -534,6 +537,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories( LPENUMCLSID *ppenumCLSID) { struct class_categories *categories; + HRESULT hr; TRACE("\n"); @@ -549,13 +553,15 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumClassesOfCategories( categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl, cRequired, rgcatidReq); if (categories == NULL) return E_OUTOFMEMORY; - *ppenumCLSID = COMCAT_CLSID_IEnumGUID_Construct(categories); - if (*ppenumCLSID == NULL) { + + hr = CLSIDEnumGUID_Construct(categories, ppenumCLSID); + if (FAILED(hr)) + { HeapFree(GetProcessHeap(), 0, categories); - return E_OUTOFMEMORY; + return hr; } - IEnumGUID_AddRef(*ppenumCLSID); - return S_OK; + + return hr; } /********************************************************************** @@ -587,7 +593,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_IsClassOfCategories( if ((cImplemented && rgcatidImpl == NULL) || (cRequired && rgcatidReq == NULL)) return E_POINTER; - res = StringFromGUID2(rclsid, keyname + 6, 39); + res = StringFromGUID2(rclsid, keyname + 6, CHARS_IN_GUID); if (FAILED(res)) return res; categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl, @@ -622,9 +628,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumImplCategoriesOfClass( if (rclsid == NULL || ppenumCATID == NULL) return E_POINTER; - *ppenumCATID = COMCAT_CATID_IEnumGUID_Construct(rclsid, postfix); - if (*ppenumCATID == NULL) return E_OUTOFMEMORY; - return S_OK; + return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID); } /********************************************************************** @@ -644,9 +648,7 @@ static HRESULT WINAPI COMCAT_ICatInformation_EnumReqCategoriesOfClass( if (rclsid == NULL || ppenumCATID == NULL) return E_POINTER; - *ppenumCATID = COMCAT_CATID_IEnumGUID_Construct(rclsid, postfix); - if (*ppenumCATID == NULL) return E_OUTOFMEMORY; - return S_OK; + return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID); } /********************************************************************** @@ -857,8 +859,8 @@ static HRESULT WINAPI COMCAT_IEnumCATEGORYINFO_Next( if (This->key) while (fetched < celt) { LSTATUS res; HRESULT hr; - WCHAR catid[39]; - DWORD cName = 39; + WCHAR catid[CHARS_IN_GUID]; + DWORD cName = CHARS_IN_GUID; HKEY subkey; res = RegEnumKeyExW(This->key, This->next_index, catid, &cName, @@ -948,21 +950,23 @@ static const IEnumCATEGORYINFOVtbl COMCAT_IEnumCATEGORYINFO_Vtbl = COMCAT_IEnumCATEGORYINFO_Clone }; -static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid) +static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret) { + static const WCHAR keyname[] = {'C','o','m','p','o','n','e','n','t',' ','C','a','t','e','g','o','r','i','e','s',0}; IEnumCATEGORYINFOImpl *This; - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumCATEGORYINFOImpl)); - if (This) { - static const WCHAR keyname[] = { 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n', - 't', ' ', 'C', 'a', 't', 'e', 'g', 'o', - 'r', 'i', 'e', 's', 0 }; + *ret = NULL; - This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl; - This->lcid = lcid; - open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); - } - return &This->IEnumCATEGORYINFO_iface; + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumCATEGORYINFOImpl)); + if (!This) return E_OUTOFMEMORY; + + This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl; + This->ref = 1; + This->lcid = lcid; + open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); + + *ret = &This->IEnumCATEGORYINFO_iface; + return S_OK; } /********************************************************************** @@ -973,23 +977,20 @@ static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid) */ typedef struct { - const IEnumGUIDVtbl *lpVtbl; + IEnumGUID IEnumGUID_iface; LONG ref; struct class_categories *categories; HKEY key; DWORD next_index; } CLSID_IEnumGUIDImpl; -static ULONG WINAPI COMCAT_CLSID_IEnumGUID_AddRef(LPENUMGUID iface) +static inline CLSID_IEnumGUIDImpl *impl_from_IEnumCLSID(IEnumGUID *iface) { - CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface; - TRACE("\n"); - - return InterlockedIncrement(&This->ref); + return CONTAINING_RECORD(iface, CLSID_IEnumGUIDImpl, IEnumGUID_iface); } -static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_QueryInterface( - LPENUMGUID iface, +static HRESULT WINAPI CLSIDEnumGUID_QueryInterface( + IEnumGUID *iface, REFIID riid, LPVOID *ppvObj) { @@ -1001,16 +1002,24 @@ static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_QueryInterface( IsEqualGUID(riid, &IID_IEnumGUID)) { *ppvObj = iface; - COMCAT_CLSID_IEnumGUID_AddRef(iface); + IEnumGUID_AddRef(iface); return S_OK; } return E_NOINTERFACE; } -static ULONG WINAPI COMCAT_CLSID_IEnumGUID_Release(LPENUMGUID iface) +static ULONG WINAPI CLSIDEnumGUID_AddRef(IEnumGUID *iface) { - CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface; + CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); + TRACE("\n"); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI CLSIDEnumGUID_Release(IEnumGUID *iface) +{ + CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); ULONG ref; TRACE("\n"); @@ -1025,13 +1034,13 @@ static ULONG WINAPI COMCAT_CLSID_IEnumGUID_Release(LPENUMGUID iface) return ref; } -static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Next( - LPENUMGUID iface, +static HRESULT WINAPI CLSIDEnumGUID_Next( + IEnumGUID *iface, ULONG celt, GUID *rgelt, ULONG *pceltFetched) { - CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface; + CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); ULONG fetched = 0; TRACE("\n"); @@ -1041,8 +1050,8 @@ static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Next( if (This->key) while (fetched < celt) { LSTATUS res; HRESULT hr; - WCHAR clsid[39]; - DWORD cName = 39; + WCHAR clsid[CHARS_IN_GUID]; + DWORD cName = CHARS_IN_GUID; HKEY subkey; res = RegEnumKeyExW(This->key, This->next_index, clsid, &cName, @@ -1068,11 +1077,11 @@ static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Next( return fetched == celt ? S_OK : S_FALSE; } -static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Skip( - LPENUMGUID iface, +static HRESULT WINAPI CLSIDEnumGUID_Skip( + IEnumGUID *iface, ULONG celt) { - CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface; + CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); TRACE("\n"); @@ -1081,9 +1090,9 @@ static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Skip( return S_OK; } -static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Reset(LPENUMGUID iface) +static HRESULT WINAPI CLSIDEnumGUID_Reset(IEnumGUID *iface) { - CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface; + CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); TRACE("\n"); @@ -1091,64 +1100,70 @@ static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Reset(LPENUMGUID iface) return S_OK; } -static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Clone( - LPENUMGUID iface, +static HRESULT WINAPI CLSIDEnumGUID_Clone( + IEnumGUID *iface, IEnumGUID **ppenum) { - CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface; - static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 }; - CLSID_IEnumGUIDImpl *new_this; - DWORD size; + static const WCHAR keynameW[] = {'C','L','S','I','D',0}; + CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface); + CLSID_IEnumGUIDImpl *cloned; - TRACE("\n"); + TRACE("(%p)->(%p)\n", This, ppenum); if (ppenum == NULL) return E_POINTER; - new_this = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl)); - if (new_this == NULL) return E_OUTOFMEMORY; + *ppenum = NULL; - new_this->lpVtbl = This->lpVtbl; - new_this->ref = 1; - size = HeapSize(GetProcessHeap(), 0, This->categories); - new_this->categories = - HeapAlloc(GetProcessHeap(), 0, size); - if (new_this->categories == NULL) { - HeapFree(GetProcessHeap(), 0, new_this); + cloned = HeapAlloc(GetProcessHeap(), 0, sizeof(CLSID_IEnumGUIDImpl)); + if (cloned == NULL) return E_OUTOFMEMORY; + + cloned->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl; + cloned->ref = 1; + + cloned->categories = HeapAlloc(GetProcessHeap(), 0, This->categories->size); + if (cloned->categories == NULL) { + HeapFree(GetProcessHeap(), 0, cloned); return E_OUTOFMEMORY; } - memcpy(new_this->categories, This->categories, size); - /* FIXME: could we more efficiently use DuplicateHandle? */ - open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &new_this->key); - new_this->next_index = This->next_index; + memcpy(cloned->categories, This->categories, This->categories->size); - *ppenum = (LPENUMGUID)new_this; + cloned->key = NULL; + open_classes_key(HKEY_CLASSES_ROOT, keynameW, KEY_READ, &cloned->key); + cloned->next_index = This->next_index; + + *ppenum = &cloned->IEnumGUID_iface; return S_OK; } -static const IEnumGUIDVtbl COMCAT_CLSID_IEnumGUID_Vtbl = +static const IEnumGUIDVtbl CLSIDEnumGUIDVtbl = { - COMCAT_CLSID_IEnumGUID_QueryInterface, - COMCAT_CLSID_IEnumGUID_AddRef, - COMCAT_CLSID_IEnumGUID_Release, - COMCAT_CLSID_IEnumGUID_Next, - COMCAT_CLSID_IEnumGUID_Skip, - COMCAT_CLSID_IEnumGUID_Reset, - COMCAT_CLSID_IEnumGUID_Clone + CLSIDEnumGUID_QueryInterface, + CLSIDEnumGUID_AddRef, + CLSIDEnumGUID_Release, + CLSIDEnumGUID_Next, + CLSIDEnumGUID_Skip, + CLSIDEnumGUID_Reset, + CLSIDEnumGUID_Clone }; -static LPENUMGUID COMCAT_CLSID_IEnumGUID_Construct(struct class_categories *categories) +static HRESULT CLSIDEnumGUID_Construct(struct class_categories *categories, IEnumCLSID **ret) { + static const WCHAR keyname[] = {'C','L','S','I','D',0}; CLSID_IEnumGUIDImpl *This; - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl)); - if (This) { - static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 }; + *ret = NULL; - This->lpVtbl = &COMCAT_CLSID_IEnumGUID_Vtbl; - This->categories = categories; - open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); - } - return (LPENUMGUID)This; + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl)); + if (!This) return E_OUTOFMEMORY; + + This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl; + This->ref = 1; + This->categories = categories; + open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); + + *ret = &This->IEnumGUID_iface; + + return S_OK; } /********************************************************************** @@ -1159,23 +1174,20 @@ static LPENUMGUID COMCAT_CLSID_IEnumGUID_Construct(struct class_categories *cate */ typedef struct { - const IEnumGUIDVtbl *lpVtbl; + IEnumGUID IEnumGUID_iface; LONG ref; WCHAR keyname[68]; HKEY key; DWORD next_index; } CATID_IEnumGUIDImpl; -static ULONG WINAPI COMCAT_CATID_IEnumGUID_AddRef(LPENUMGUID iface) +static inline CATID_IEnumGUIDImpl *impl_from_IEnumCATID(IEnumGUID *iface) { - CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface; - TRACE("\n"); - - return InterlockedIncrement(&This->ref); + return CONTAINING_RECORD(iface, CATID_IEnumGUIDImpl, IEnumGUID_iface); } -static HRESULT WINAPI COMCAT_CATID_IEnumGUID_QueryInterface( - LPENUMGUID iface, +static HRESULT WINAPI CATIDEnumGUID_QueryInterface( + IEnumGUID *iface, REFIID riid, LPVOID *ppvObj) { @@ -1187,16 +1199,24 @@ static HRESULT WINAPI COMCAT_CATID_IEnumGUID_QueryInterface( IsEqualGUID(riid, &IID_IEnumGUID)) { *ppvObj = iface; - COMCAT_CATID_IEnumGUID_AddRef(iface); + IEnumGUID_AddRef(iface); return S_OK; } return E_NOINTERFACE; } -static ULONG WINAPI COMCAT_CATID_IEnumGUID_Release(LPENUMGUID iface) +static ULONG WINAPI CATIDEnumGUID_AddRef(IEnumGUID *iface) { - CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface; + CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface); + TRACE("\n"); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI CATIDEnumGUID_Release(IEnumGUID *iface) +{ + CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface); ULONG ref; TRACE("\n"); @@ -1210,13 +1230,13 @@ static ULONG WINAPI COMCAT_CATID_IEnumGUID_Release(LPENUMGUID iface) return ref; } -static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Next( - LPENUMGUID iface, +static HRESULT WINAPI CATIDEnumGUID_Next( + IEnumGUID *iface, ULONG celt, GUID *rgelt, ULONG *pceltFetched) { - CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface; + CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface); ULONG fetched = 0; TRACE("\n"); @@ -1226,8 +1246,8 @@ static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Next( if (This->key) while (fetched < celt) { LSTATUS res; HRESULT hr; - WCHAR catid[39]; - DWORD cName = 39; + WCHAR catid[CHARS_IN_GUID]; + DWORD cName = CHARS_IN_GUID; res = RegEnumKeyExW(This->key, This->next_index, catid, &cName, NULL, NULL, NULL, NULL); @@ -1245,11 +1265,11 @@ static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Next( return fetched == celt ? S_OK : S_FALSE; } -static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Skip( - LPENUMGUID iface, +static HRESULT WINAPI CATIDEnumGUID_Skip( + IEnumGUID *iface, ULONG celt) { - CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface; + CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface); TRACE("\n"); @@ -1258,9 +1278,9 @@ static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Skip( return S_OK; } -static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Reset(LPENUMGUID iface) +static HRESULT WINAPI CATIDEnumGUID_Reset(IEnumGUID *iface) { - CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface; + CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface); TRACE("\n"); @@ -1268,11 +1288,11 @@ static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Reset(LPENUMGUID iface) return S_OK; } -static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Clone( - LPENUMGUID iface, +static HRESULT WINAPI CATIDEnumGUID_Clone( + IEnumGUID *iface, IEnumGUID **ppenum) { - CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface; + CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface); CATID_IEnumGUIDImpl *new_this; TRACE("\n"); @@ -1282,42 +1302,49 @@ static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Clone( new_this = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl)); if (new_this == NULL) return E_OUTOFMEMORY; - new_this->lpVtbl = This->lpVtbl; + new_this->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl; new_this->ref = 1; lstrcpyW(new_this->keyname, This->keyname); /* FIXME: could we more efficiently use DuplicateHandle? */ open_classes_key(HKEY_CLASSES_ROOT, new_this->keyname, KEY_READ, &new_this->key); new_this->next_index = This->next_index; - *ppenum = (LPENUMGUID)new_this; + *ppenum = &new_this->IEnumGUID_iface; return S_OK; } -static const IEnumGUIDVtbl COMCAT_CATID_IEnumGUID_Vtbl = +static const IEnumGUIDVtbl CATIDEnumGUIDVtbl = { - COMCAT_CATID_IEnumGUID_QueryInterface, - COMCAT_CATID_IEnumGUID_AddRef, - COMCAT_CATID_IEnumGUID_Release, - COMCAT_CATID_IEnumGUID_Next, - COMCAT_CATID_IEnumGUID_Skip, - COMCAT_CATID_IEnumGUID_Reset, - COMCAT_CATID_IEnumGUID_Clone + CATIDEnumGUID_QueryInterface, + CATIDEnumGUID_AddRef, + CATIDEnumGUID_Release, + CATIDEnumGUID_Next, + CATIDEnumGUID_Skip, + CATIDEnumGUID_Reset, + CATIDEnumGUID_Clone }; -static LPENUMGUID COMCAT_CATID_IEnumGUID_Construct( - REFCLSID rclsid, LPCWSTR postfix) +static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR postfix, IEnumGUID **ret) { + static const WCHAR prefixW[] = {'C','L','S','I','D','\\',0}; + WCHAR keyname[100], clsidW[CHARS_IN_GUID]; CATID_IEnumGUIDImpl *This; - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl)); - if (This) { - WCHAR prefix[] = { 'C', 'L', 'S', 'I', 'D', '\\' }; + *ret = NULL; - This->lpVtbl = &COMCAT_CATID_IEnumGUID_Vtbl; - memcpy(This->keyname, prefix, sizeof(prefix)); - StringFromGUID2(rclsid, This->keyname + 6, 39); - lstrcpyW(This->keyname + 44, postfix); - open_classes_key(HKEY_CLASSES_ROOT, This->keyname, KEY_READ, &This->key); - } - return (LPENUMGUID)This; + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl)); + if (!This) return E_OUTOFMEMORY; + + StringFromGUID2(rclsid, clsidW, CHARS_IN_GUID); + + This->IEnumGUID_iface.lpVtbl = &CATIDEnumGUIDVtbl; + This->ref = 1; + strcpyW(keyname, prefixW); + strcatW(keyname, clsidW); + strcatW(keyname, postfix); + + open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key); + + *ret = &This->IEnumGUID_iface; + return S_OK; } diff --git a/reactos/dll/win32/ole32/compobj.c b/reactos/dll/win32/ole32/compobj.c index 5baffd159de..5d8fb0c3b2f 100644 --- a/reactos/dll/win32/ole32/compobj.c +++ b/reactos/dll/win32/ole32/compobj.c @@ -62,6 +62,82 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION csApartment = { &critsect_debug, -1, 0, 0, 0, 0 }; +enum comclass_threadingmodel +{ + ThreadingModel_Apartment = 1, + ThreadingModel_Free = 2, + ThreadingModel_No = 3, + ThreadingModel_Both = 4, + ThreadingModel_Neutral = 5 +}; + +enum comclass_miscfields +{ + MiscStatus = 1, + MiscStatusIcon = 2, + MiscStatusContent = 4, + MiscStatusThumbnail = 8, + MiscStatusDocPrint = 16 +}; + +struct comclassredirect_data +{ + ULONG size; + BYTE res; + BYTE miscmask; + BYTE res1[2]; + DWORD model; + GUID clsid; + GUID alias; + GUID clsid2; + GUID tlbid; + ULONG name_len; + ULONG name_offset; + ULONG progid_len; + ULONG progid_offset; + ULONG clrdata_len; + ULONG clrdata_offset; + DWORD miscstatus; + DWORD miscstatuscontent; + DWORD miscstatusthumbnail; + DWORD miscstatusicon; + DWORD miscstatusdocprint; +}; + +struct ifacepsredirect_data +{ + ULONG size; + DWORD mask; + GUID iid; + ULONG nummethods; + GUID tlbid; + GUID base; + ULONG name_len; + ULONG name_offset; +}; + +struct progidredirect_data +{ + ULONG size; + DWORD reserved; + ULONG clsid_offset; +}; + +struct class_reg_data +{ + union + { + struct + { + struct comclassredirect_data *data; + void *section; + HANDLE hactctx; + } actctx; + HKEY hkey; + } u; + BOOL hkey; +}; + struct registered_psclsid { struct list entry; @@ -123,6 +199,71 @@ static CRITICAL_SECTION_DEBUG class_cs_debug = }; static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0, 0 }; +static inline enum comclass_miscfields dvaspect_to_miscfields(DWORD aspect) +{ + switch (aspect) + { + case DVASPECT_CONTENT: + return MiscStatusContent; + case DVASPECT_THUMBNAIL: + return MiscStatusThumbnail; + case DVASPECT_ICON: + return MiscStatusIcon; + case DVASPECT_DOCPRINT: + return MiscStatusDocPrint; + default: + return MiscStatus; + }; +} + +BOOL actctx_get_miscstatus(const CLSID *clsid, DWORD aspect, DWORD *status) +{ + ACTCTX_SECTION_KEYED_DATA data; + + data.cbSize = sizeof(data); + if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, + clsid, &data)) + { + struct comclassredirect_data *comclass = (struct comclassredirect_data*)data.lpData; + enum comclass_miscfields misc = dvaspect_to_miscfields(aspect); + + if (!(comclass->miscmask & misc)) + { + if (!(comclass->miscmask & MiscStatus)) + { + *status = 0; + return TRUE; + } + misc = MiscStatus; + } + + switch (misc) + { + case MiscStatus: + *status = comclass->miscstatus; + break; + case MiscStatusIcon: + *status = comclass->miscstatusicon; + break; + case MiscStatusContent: + *status = comclass->miscstatuscontent; + break; + case MiscStatusThumbnail: + *status = comclass->miscstatusthumbnail; + break; + case MiscStatusDocPrint: + *status = comclass->miscstatusdocprint; + break; + default: + ; + }; + + return TRUE; + } + else + return FALSE; +} + /* wrapper for NtCreateKey that creates the key recursively if necessary */ static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr ) { @@ -320,7 +461,7 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret) DllCanUnloadNowFunc DllCanUnloadNow; DllGetClassObjectFunc DllGetClassObject; - TRACE("\n"); + TRACE("%s\n", debugstr_w(library_name)); *ret = COMPOBJ_DllList_Get(library_name); if (*ret) return S_OK; @@ -1203,14 +1344,17 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath, * * Reads a registry value and expands it when necessary */ -static DWORD COM_RegReadPath(HKEY hkeyroot, WCHAR * dst, DWORD dstlen) +static DWORD COM_RegReadPath(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen) { - DWORD ret; + DWORD ret; + + if (regdata->hkey) + { DWORD keytype; WCHAR src[MAX_PATH]; DWORD dwLength = dstlen * sizeof(WCHAR); - if( (ret = RegQueryValueExW(hkeyroot, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) { + if( (ret = RegQueryValueExW(regdata->u.hkey, NULL, NULL, &keytype, (BYTE*)src, &dwLength)) == ERROR_SUCCESS ) { if (keytype == REG_EXPAND_SZ) { if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) ret = ERROR_MORE_DATA; } else { @@ -1228,11 +1372,24 @@ static DWORD COM_RegReadPath(HKEY hkeyroot, WCHAR * dst, DWORD dstlen) } } return ret; + } + else + { + ULONG_PTR cookie; + WCHAR *nameW; + + *dst = 0; + nameW = (WCHAR*)((BYTE*)regdata->u.actctx.section + regdata->u.actctx.data->name_offset); + ActivateActCtx(regdata->u.actctx.hactctx, &cookie); + ret = SearchPathW(NULL, nameW, NULL, dstlen, dst, NULL); + DeactivateActCtx(0, cookie); + return !*dst; + } } struct host_object_params { - HKEY hkeydll; + struct class_reg_data regdata; CLSID clsid; /* clsid of object to marshal */ IID iid; /* interface to marshal */ HANDLE event; /* event signalling when ready for multi-threaded case */ @@ -1251,7 +1408,7 @@ static HRESULT apartment_hostobject(struct apartment *apt, TRACE("clsid %s, iid %s\n", debugstr_guid(¶ms->clsid), debugstr_guid(¶ms->iid)); - if (COM_RegReadPath(params->hkeydll, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) + if (COM_RegReadPath(¶ms->regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) { /* failure: CLSID is not found in registry */ WARN("class %s not registered inproc\n", debugstr_guid(¶ms->clsid)); @@ -1348,7 +1505,7 @@ static DWORD CALLBACK apartment_hostobject_thread(LPVOID p) * caller of this function */ static HRESULT apartment_hostobject_in_hostapt( struct apartment *apt, BOOL multi_threaded, BOOL main_apartment, - HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv) + const struct class_reg_data *regdata, REFCLSID rclsid, REFIID riid, void **ppv) { struct host_object_params params; HWND apartment_hwnd = NULL; @@ -1418,7 +1575,7 @@ static HRESULT apartment_hostobject_in_hostapt( } } - params.hkeydll = hkeydll; + params.regdata = *regdata; params.clsid = *rclsid; params.iid = *riid; hr = CreateStreamOnHGlobal(NULL, TRUE, ¶ms.stream); @@ -1454,6 +1611,29 @@ static HRESULT apartment_hostobject_in_hostapt( return hr; } +#ifndef __REACTOS__ +static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context ) +{ + WNDCLASSW wclass; + + /* Dispatching to the correct thread in an apartment is done through + * window messages rather than RPC transports. When an interface is + * marshalled into another apartment in the same process, a window of the + * following class is created. The *caller* of CoMarshalInterface (i.e., the + * application) is responsible for pumping the message loop in that thread. + * The WM_USER messages which point to the RPCs are then dispatched to + * apartment_wndproc by the user's code from the apartment in which the + * interface was unmarshalled. + */ + memset(&wclass, 0, sizeof(wclass)); + wclass.lpfnWndProc = apartment_wndproc; + wclass.hInstance = hProxyDll; + wclass.lpszClassName = wszAptWinClass; + RegisterClassW(&wclass); + return TRUE; +} +#endif + /* create a window for the apartment or return the current one if one has * already been created */ HRESULT apartment_createwindowifneeded(struct apartment *apt) @@ -1492,6 +1672,8 @@ void apartment_joinmta(void) COM_CurrentInfo()->apt = MTA; } +#ifdef __REACTOS__ + static void COMPOBJ_InitProcess( void ) { WNDCLASSW wclass; @@ -1517,6 +1699,8 @@ static void COMPOBJ_UninitProcess( void ) UnregisterClassW(wszAptWinClass, hProxyDll); } +#endif + static void COM_TlsDestroy(void) { struct oletls *info = NtCurrentTeb()->ReservedForOle; @@ -1883,9 +2067,103 @@ static inline BOOL is_valid_hex(WCHAR c) return TRUE; } +static const BYTE guid_conv_table[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */ + 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */ + 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */ +}; + +/* conversion helper for CLSIDFromString/IIDFromString */ +static BOOL guid_from_string(LPCWSTR s, GUID *id) +{ + int i; + + if (!s || s[0]!='{') { + memset( id, 0, sizeof (CLSID) ); + if(!s) return TRUE; + return FALSE; + } + + TRACE("%s -> %p\n", debugstr_w(s), id); + + /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ + + id->Data1 = 0; + for (i = 1; i < 9; i++) { + if (!is_valid_hex(s[i])) return FALSE; + id->Data1 = (id->Data1 << 4) | guid_conv_table[s[i]]; + } + if (s[9]!='-') return FALSE; + + id->Data2 = 0; + for (i = 10; i < 14; i++) { + if (!is_valid_hex(s[i])) return FALSE; + id->Data2 = (id->Data2 << 4) | guid_conv_table[s[i]]; + } + if (s[14]!='-') return FALSE; + + id->Data3 = 0; + for (i = 15; i < 19; i++) { + if (!is_valid_hex(s[i])) return FALSE; + id->Data3 = (id->Data3 << 4) | guid_conv_table[s[i]]; + } + if (s[19]!='-') return FALSE; + + for (i = 20; i < 37; i+=2) { + if (i == 24) { + if (s[i]!='-') return FALSE; + i++; + } + if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE; + id->Data4[(i-20)/2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]]; + } + + if (s[37] == '}' && s[38] == '\0') + return TRUE; + + return FALSE; +} + +/*****************************************************************************/ + +static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid) +{ + static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 }; + WCHAR buf2[CHARS_IN_GUID]; + LONG buf2len = sizeof(buf2); + HKEY xhkey; + WCHAR *buf; + + memset(clsid, 0, sizeof(*clsid)); + buf = HeapAlloc( GetProcessHeap(),0,(strlenW(progid)+8) * sizeof(WCHAR) ); + if (!buf) return E_OUTOFMEMORY; + strcpyW( buf, progid ); + strcatW( buf, clsidW ); + if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey)) + { + HeapFree(GetProcessHeap(),0,buf); + WARN("couldn't open key for ProgID %s\n", debugstr_w(progid)); + return CO_E_CLASSSTRING; + } + HeapFree(GetProcessHeap(),0,buf); + + if (RegQueryValueW(xhkey,NULL,buf2,&buf2len)) + { + RegCloseKey(xhkey); + WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid)); + return CO_E_CLASSSTRING; + } + RegCloseKey(xhkey); + return guid_from_string(buf2, clsid) ? S_OK : CO_E_CLASSSTRING; +} + /****************************************************************************** * CLSIDFromString [OLE32.@] - * IIDFromString [OLE32.@] * * Converts a unique identifier from its string representation into * the GUID struct. @@ -1901,87 +2179,61 @@ static inline BOOL is_valid_hex(WCHAR c) * SEE ALSO * StringFromCLSID */ -static HRESULT __CLSIDFromString(LPCWSTR s, LPCLSID id) -{ - int i; - BYTE table[256]; - - if (!s || s[0]!='{') { - memset( id, 0, sizeof (CLSID) ); - if(!s) return S_OK; - return CO_E_CLASSSTRING; - } - - TRACE("%s -> %p\n", debugstr_w(s), id); - - /* quick lookup table */ - memset(table, 0, 256); - - for (i = 0; i < 10; i++) { - table['0' + i] = i; - } - for (i = 0; i < 6; i++) { - table['A' + i] = i+10; - table['a' + i] = i+10; - } - - /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ - - id->Data1 = 0; - for (i = 1; i < 9; i++) { - if (!is_valid_hex(s[i])) return CO_E_CLASSSTRING; - id->Data1 = (id->Data1 << 4) | table[s[i]]; - } - if (s[9]!='-') return CO_E_CLASSSTRING; - - id->Data2 = 0; - for (i = 10; i < 14; i++) { - if (!is_valid_hex(s[i])) return CO_E_CLASSSTRING; - id->Data2 = (id->Data2 << 4) | table[s[i]]; - } - if (s[14]!='-') return CO_E_CLASSSTRING; - - id->Data3 = 0; - for (i = 15; i < 19; i++) { - if (!is_valid_hex(s[i])) return CO_E_CLASSSTRING; - id->Data3 = (id->Data3 << 4) | table[s[i]]; - } - if (s[19]!='-') return CO_E_CLASSSTRING; - - for (i = 20; i < 37; i+=2) { - if (i == 24) { - if (s[i]!='-') return CO_E_CLASSSTRING; - i++; - } - if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return CO_E_CLASSSTRING; - id->Data4[(i-20)/2] = table[s[i]] << 4 | table[s[i+1]]; - } - - if (s[37] == '}' && s[38] == '\0') - return S_OK; - - return CO_E_CLASSSTRING; -} - -/*****************************************************************************/ - HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id ) { - HRESULT ret; + HRESULT ret = CO_E_CLASSSTRING; + CLSID tmp_id; if (!id) return E_INVALIDARG; - ret = __CLSIDFromString(idstr, id); - if(ret != S_OK) { /* It appears a ProgID is also valid */ - CLSID tmp_id; - ret = CLSIDFromProgID(idstr, &tmp_id); - if(SUCCEEDED(ret)) - *id = tmp_id; - } + if (guid_from_string(idstr, id)) + return S_OK; + + /* It appears a ProgID is also valid */ + ret = clsid_from_string_reg(idstr, &tmp_id); + if(SUCCEEDED(ret)) + *id = tmp_id; + return ret; } +/****************************************************************************** + * IIDFromString [OLE32.@] + * + * Converts a interface identifier from its string representation into + * the IID struct. + * + * PARAMS + * idstr [I] The string representation of the GUID. + * id [O] IID converted from the string. + * + * RETURNS + * S_OK on success + * CO_E_IIDSTRING if idstr is not a valid IID + * + * SEE ALSO + * StringFromIID + */ +HRESULT WINAPI IIDFromString(LPCOLESTR s, IID *iid) +{ + TRACE("%s -> %p\n", debugstr_w(s), iid); + + if (!s) + { + memset(iid, 0, sizeof(*iid)); + return S_OK; + } + + /* length mismatch is a special case */ + if (strlenW(s) + 1 != CHARS_IN_GUID) + return E_INVALIDARG; + + if (s[0] != '{') + return CO_E_IIDSTRING; + + return guid_from_string(s, iid) ? S_OK : CO_E_IIDSTRING; +} /****************************************************************************** * StringFromCLSID [OLE32.@] @@ -2003,11 +2255,7 @@ HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id ) */ HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR *idstr) { - HRESULT ret; - LPMALLOC mllc; - - if ((ret = CoGetMalloc(0,&mllc))) return ret; - if (!(*idstr = IMalloc_Alloc( mllc, CHARS_IN_GUID * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + if (!(*idstr = CoTaskMemAlloc(CHARS_IN_GUID * sizeof(WCHAR)))) return E_OUTOFMEMORY; StringFromGUID2( id, *idstr, CHARS_IN_GUID ); return S_OK; } @@ -2123,20 +2371,39 @@ HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey * E_OUTOFMEMORY * REGDB_E_CLASSNOTREG if the given clsid has no associated ProgID */ -HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID) +HRESULT WINAPI DECLSPEC_HOTPATCH ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID) { static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0}; + ACTCTX_SECTION_KEYED_DATA data; HKEY hkey; HRESULT ret; LONG progidlen = 0; if (!ppszProgID) - { - ERR("ppszProgId isn't optional\n"); return E_INVALIDARG; - } *ppszProgID = NULL; + + data.cbSize = sizeof(data); + if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, + clsid, &data)) + { + struct comclassredirect_data *comclass = (struct comclassredirect_data*)data.lpData; + if (comclass->progid_len) + { + WCHAR *ptrW; + + *ppszProgID = CoTaskMemAlloc(comclass->progid_len + sizeof(WCHAR)); + if (!*ppszProgID) return E_OUTOFMEMORY; + + ptrW = (WCHAR*)((BYTE*)comclass + comclass->progid_offset); + memcpy(*ppszProgID, ptrW, comclass->progid_len + sizeof(WCHAR)); + return S_OK; + } + else + return REGDB_E_CLASSNOTREG; + } + ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey); if (FAILED(ret)) return ret; @@ -2176,42 +2443,24 @@ HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID) * Success: S_OK * Failure: CO_E_CLASSSTRING - the given ProgID cannot be found. */ -HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid) +HRESULT WINAPI DECLSPEC_HOTPATCH CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid) { - static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 }; - WCHAR buf2[CHARS_IN_GUID]; - LONG buf2len = sizeof(buf2); - HKEY xhkey; - WCHAR *buf; + ACTCTX_SECTION_KEYED_DATA data; if (!progid || !clsid) - { - ERR("neither progid (%p) nor clsid (%p) are optional\n", progid, clsid); return E_INVALIDARG; - } - /* initialise clsid in case of failure */ - memset(clsid, 0, sizeof(*clsid)); - - buf = HeapAlloc( GetProcessHeap(),0,(strlenW(progid)+8) * sizeof(WCHAR) ); - strcpyW( buf, progid ); - strcatW( buf, clsidW ); - if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey)) + data.cbSize = sizeof(data); + if (FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, + progid, &data)) { - HeapFree(GetProcessHeap(),0,buf); - WARN("couldn't open key for ProgID %s\n", debugstr_w(progid)); - return CO_E_CLASSSTRING; + struct progidredirect_data *progiddata = (struct progidredirect_data*)data.lpData; + CLSID *alias = (CLSID*)((BYTE*)data.lpSectionBase + progiddata->clsid_offset); + *clsid = *alias; + return S_OK; } - HeapFree(GetProcessHeap(),0,buf); - if (RegQueryValueW(xhkey,NULL,buf2,&buf2len)) - { - RegCloseKey(xhkey); - WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid)); - return CO_E_CLASSSTRING; - } - RegCloseKey(xhkey); - return __CLSIDFromString(buf2,clsid); + return clsid_from_string_reg(progid, clsid); } /****************************************************************************** @@ -2270,6 +2519,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) HKEY hkey; APARTMENT *apt = COM_CurrentApt(); struct registered_psclsid *registered_psclsid; + ACTCTX_SECTION_KEYED_DATA data; TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid); @@ -2280,10 +2530,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) } if (!pclsid) - { - ERR("pclsid isn't optional\n"); return E_INVALIDARG; - } EnterCriticalSection(&apt->cs); @@ -2297,6 +2544,15 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) LeaveCriticalSection(&apt->cs); + data.cbSize = sizeof(data); + if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, + riid, &data)) + { + struct ifacepsredirect_data *ifaceps = (struct ifacepsredirect_data*)data.lpData; + *pclsid = ifaceps->iid; + return S_OK; + } + /* Interface\\{string form of riid}\\ProxyStubClsid32 */ strcpyW(path, wszInterface); StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID); @@ -2561,19 +2817,36 @@ HRESULT WINAPI CoRegisterClassObject( return S_OK; } -static void get_threading_model(HKEY key, LPWSTR value, DWORD len) +static enum comclass_threadingmodel get_threading_model(const struct class_reg_data *data) { - static const WCHAR wszThreadingModel[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; - DWORD keytype; - DWORD ret; - DWORD dwLength = len * sizeof(WCHAR); + if (data->hkey) + { + static const WCHAR wszThreadingModel[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; + static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0}; + static const WCHAR wszFree[] = {'F','r','e','e',0}; + static const WCHAR wszBoth[] = {'B','o','t','h',0}; + WCHAR threading_model[10 /* strlenW(L"apartment")+1 */]; + DWORD dwLength = sizeof(threading_model); + DWORD keytype; + DWORD ret; - ret = RegQueryValueExW(key, wszThreadingModel, NULL, &keytype, (LPBYTE)value, &dwLength); - if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ)) - value[0] = '\0'; + ret = RegQueryValueExW(data->u.hkey, wszThreadingModel, NULL, &keytype, (BYTE*)threading_model, &dwLength); + if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ)) + threading_model[0] = '\0'; + + if (!strcmpiW(threading_model, wszApartment)) return ThreadingModel_Apartment; + if (!strcmpiW(threading_model, wszFree)) return ThreadingModel_Free; + if (!strcmpiW(threading_model, wszBoth)) return ThreadingModel_Both; + + /* there's not specific handling for this case */ + if (threading_model[0]) return ThreadingModel_Neutral; + return ThreadingModel_No; + } + else + return data->u.actctx.data->model; } -static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, +static HRESULT get_inproc_class_object(APARTMENT *apt, const struct class_reg_data *regdata, REFCLSID rclsid, REFIID riid, BOOL hostifnecessary, void **ppv) { @@ -2582,37 +2855,30 @@ static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, if (hostifnecessary) { - static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0}; - static const WCHAR wszFree[] = {'F','r','e','e',0}; - static const WCHAR wszBoth[] = {'B','o','t','h',0}; - WCHAR threading_model[10 /* strlenW(L"apartment")+1 */]; + enum comclass_threadingmodel model = get_threading_model(regdata); - get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model)); - /* "Apartment" */ - if (!strcmpiW(threading_model, wszApartment)) + if (model == ThreadingModel_Apartment) { apartment_threaded = TRUE; if (apt->multi_threaded) - return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, hkeydll, rclsid, riid, ppv); + return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, regdata, rclsid, riid, ppv); } - /* "Free" */ - else if (!strcmpiW(threading_model, wszFree)) + else if (model == ThreadingModel_Free) { apartment_threaded = FALSE; if (!apt->multi_threaded) - return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, hkeydll, rclsid, riid, ppv); + return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, regdata, rclsid, riid, ppv); } /* everything except "Apartment", "Free" and "Both" */ - else if (strcmpiW(threading_model, wszBoth)) + else if (model != ThreadingModel_Both) { apartment_threaded = TRUE; /* everything else is main-threaded */ - if (threading_model[0]) - FIXME("unrecognised threading model %s for object %s, should be main-threaded?\n", - debugstr_w(threading_model), debugstr_guid(rclsid)); + if (model != ThreadingModel_No) + FIXME("unrecognised threading model %d for object %s, should be main-threaded?\n", model, debugstr_guid(rclsid)); if (apt->multi_threaded || !apt->main) - return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, hkeydll, rclsid, riid, ppv); + return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, regdata, rclsid, riid, ppv); } else apartment_threaded = FALSE; @@ -2620,7 +2886,7 @@ static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, else apartment_threaded = !apt->multi_threaded; - if (COM_RegReadPath(hkeydll, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) + if (COM_RegReadPath(regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) { /* failure: CLSID is not found in registry */ WARN("class %s not registered inproc\n", debugstr_guid(rclsid)); @@ -2657,11 +2923,12 @@ static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, * SEE ALSO * CoCreateInstance() */ -HRESULT WINAPI CoGetClassObject( +HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv) { - LPUNKNOWN regClassObject; + struct class_reg_data clsreg; + IUnknown *regClassObject; HRESULT hres = E_UNEXPECTED; APARTMENT *apt; BOOL release_apt = FALSE; @@ -2688,6 +2955,39 @@ HRESULT WINAPI CoGetClassObject( debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo); } + if (CLSCTX_INPROC_SERVER & dwClsContext) + { + if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler)) + { + if (release_apt) apartment_release(apt); + return FTMarshalCF_Create(iid, ppv); + } + } + + if (CLSCTX_INPROC & dwClsContext) + { + ACTCTX_SECTION_KEYED_DATA data; + + data.cbSize = sizeof(data); + /* search activation context first */ + if (FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, + ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, + rclsid, &data)) + { + struct comclassredirect_data *comclass = (struct comclassredirect_data*)data.lpData; + + clsreg.u.actctx.hactctx = data.hActCtx; + clsreg.u.actctx.data = data.lpData; + clsreg.u.actctx.section = data.lpSectionBase; + clsreg.hkey = FALSE; + + hres = get_inproc_class_object(apt, &clsreg, &comclass->clsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv); + ReleaseActCtx(data.hActCtx); + if (release_apt) apartment_release(apt); + return hres; + } + } + /* * First, try and see if we can't match the class ID with one of the * registered classes. @@ -2714,12 +3014,6 @@ HRESULT WINAPI CoGetClassObject( static const WCHAR wszInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0}; HKEY hkey; - if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler)) - { - if (release_apt) apartment_release(apt); - return FTMarshalCF_Create(iid, ppv); - } - hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey); if (FAILED(hres)) { @@ -2734,8 +3028,10 @@ HRESULT WINAPI CoGetClassObject( if (SUCCEEDED(hres)) { - hres = get_inproc_class_object(apt, hkey, rclsid, iid, - !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv); + clsreg.u.hkey = hkey; + clsreg.hkey = TRUE; + + hres = get_inproc_class_object(apt, &clsreg, rclsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv); RegCloseKey(hkey); } @@ -2768,8 +3064,10 @@ HRESULT WINAPI CoGetClassObject( if (SUCCEEDED(hres)) { - hres = get_inproc_class_object(apt, hkey, rclsid, iid, - !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv); + clsreg.u.hkey = hkey; + clsreg.hkey = TRUE; + + hres = get_inproc_class_object(apt, &clsreg, rclsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv); RegCloseKey(hkey); } @@ -2850,7 +3148,7 @@ HRESULT WINAPI CoResumeClassObjects(void) * SEE ALSO * CoGetClassObject() */ -HRESULT WINAPI CoCreateInstance( +HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, @@ -2925,10 +3223,40 @@ HRESULT WINAPI CoCreateInstance( return hres; } +static void init_multi_qi(DWORD count, MULTI_QI *mqi) +{ + ULONG i; + + for (i = 0; i < count; i++) + { + mqi[i].pItf = NULL; + mqi[i].hr = E_NOINTERFACE; + } +} + +static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi) +{ + ULONG index, fetched = 0; + + for (index = 0; index < count; index++) + { + mqi[index].hr = IUnknown_QueryInterface(unk, mqi[index].pIID, (void**)&mqi[index].pItf); + if (mqi[index].hr == S_OK) + fetched++; + } + + IUnknown_Release(unk); + + if (fetched == 0) + return E_NOINTERFACE; + + return fetched == count ? S_OK : CO_S_NOTALLINTERFACES; +} + /*********************************************************************** * CoCreateInstanceEx [OLE32.@] */ -HRESULT WINAPI CoCreateInstanceEx( +HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, @@ -2938,8 +3266,6 @@ HRESULT WINAPI CoCreateInstanceEx( { IUnknown* pUnk = NULL; HRESULT hr; - ULONG index; - ULONG successCount = 0; /* * Sanity check @@ -2950,14 +3276,7 @@ HRESULT WINAPI CoCreateInstanceEx( if (pServerInfo!=NULL) FIXME("() non-NULL pServerInfo not supported!\n"); - /* - * Initialize all the "out" parameters. - */ - for (index = 0; index < cmq; index++) - { - pResults[index].pItf = NULL; - pResults[index].hr = E_NOINTERFACE; - } + init_multi_qi(cmq, pResults); /* * Get the object and get its IUnknown pointer. @@ -2971,31 +3290,133 @@ HRESULT WINAPI CoCreateInstanceEx( if (hr != S_OK) return hr; - /* - * Then, query for all the interfaces requested. - */ - for (index = 0; index < cmq; index++) - { - pResults[index].hr = IUnknown_QueryInterface(pUnk, - pResults[index].pIID, - (VOID**)&(pResults[index].pItf)); + return return_multi_qi(pUnk, cmq, pResults); +} - if (pResults[index].hr == S_OK) - successCount++; +/*********************************************************************** + * CoGetInstanceFromFile [OLE32.@] + */ +HRESULT WINAPI CoGetInstanceFromFile( + COSERVERINFO *server_info, + CLSID *rclsid, + IUnknown *outer, + DWORD cls_context, + DWORD grfmode, + OLECHAR *filename, + DWORD count, + MULTI_QI *results +) +{ + IPersistFile *pf = NULL; + IUnknown* unk = NULL; + CLSID clsid; + HRESULT hr; + + if (count == 0 || !results) + return E_INVALIDARG; + + if (server_info) + FIXME("() non-NULL server_info not supported\n"); + + init_multi_qi(count, results); + + /* optionaly get CLSID from a file */ + if (!rclsid) + { + hr = GetClassFile(filename, &clsid); + if (FAILED(hr)) + { + ERR("failed to get CLSID from a file\n"); + return hr; + } + + rclsid = &clsid; } - /* - * Release our temporary unknown pointer. - */ - IUnknown_Release(pUnk); + hr = CoCreateInstance(rclsid, + outer, + cls_context, + &IID_IUnknown, + (void**)&unk); - if (successCount == 0) - return E_NOINTERFACE; + if (hr != S_OK) + return hr; - if (successCount!=cmq) - return CO_S_NOTALLINTERFACES; + /* init from file */ + hr = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&pf); + if (FAILED(hr)) + ERR("failed to get IPersistFile\n"); - return S_OK; + if (pf) + { + IPersistFile_Load(pf, filename, grfmode); + IPersistFile_Release(pf); + } + + return return_multi_qi(unk, count, results); +} + +/*********************************************************************** + * CoGetInstanceFromIStorage [OLE32.@] + */ +HRESULT WINAPI CoGetInstanceFromIStorage( + COSERVERINFO *server_info, + CLSID *rclsid, + IUnknown *outer, + DWORD cls_context, + IStorage *storage, + DWORD count, + MULTI_QI *results +) +{ + IPersistStorage *ps = NULL; + IUnknown* unk = NULL; + STATSTG stat; + HRESULT hr; + + if (count == 0 || !results || !storage) + return E_INVALIDARG; + + if (server_info) + FIXME("() non-NULL server_info not supported\n"); + + init_multi_qi(count, results); + + /* optionaly get CLSID from a file */ + if (!rclsid) + { + memset(&stat.clsid, 0, sizeof(stat.clsid)); + hr = IStorage_Stat(storage, &stat, STATFLAG_NONAME); + if (FAILED(hr)) + { + ERR("failed to get CLSID from a file\n"); + return hr; + } + + rclsid = &stat.clsid; + } + + hr = CoCreateInstance(rclsid, + outer, + cls_context, + &IID_IUnknown, + (void**)&unk); + + if (hr != S_OK) + return hr; + + /* init from IStorage */ + hr = IUnknown_QueryInterface(unk, &IID_IPersistStorage, (void**)&ps); + if (FAILED(hr)) + ERR("failed to get IPersistStorage\n"); + + if (ps) + { + IPersistStorage_Load(ps, storage); + IPersistStorage_Release(ps); + } + + return return_multi_qi(unk, count, results); } /*********************************************************************** @@ -3074,7 +3495,7 @@ void WINAPI CoFreeAllLibraries(void) * SEE ALSO * CoLoadLibrary, CoFreeAllLibraries, CoFreeLibrary */ -void WINAPI CoFreeUnusedLibrariesEx(DWORD dwUnloadDelay, DWORD dwReserved) +void WINAPI DECLSPEC_HOTPATCH CoFreeUnusedLibrariesEx(DWORD dwUnloadDelay, DWORD dwReserved) { struct apartment *apt = COM_CurrentApt(); if (!apt) @@ -3098,7 +3519,7 @@ void WINAPI CoFreeUnusedLibrariesEx(DWORD dwUnloadDelay, DWORD dwReserved) * SEE ALSO * CoLoadLibrary, CoFreeAllLibraries, CoFreeLibrary */ -void WINAPI CoFreeUnusedLibraries(void) +void WINAPI DECLSPEC_HOTPATCH CoFreeUnusedLibraries(void) { CoFreeUnusedLibrariesEx(INFINITE, 0); } @@ -4532,9 +4953,13 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) hres = COM_OpenKeyForCLSID(rclsid, wszInprocHandler32, KEY_READ, &hkey); if (SUCCEEDED(hres)) { + struct class_reg_data regdata; WCHAR dllpath[MAX_PATH+1]; - if (COM_RegReadPath(hkey, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS) + regdata.u.hkey = hkey; + regdata.hkey = TRUE; + + if (COM_RegReadPath(®data, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS) { static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0}; if (!strcmpiW(dllpath, wszOle32)) diff --git a/reactos/dll/win32/ole32/compobj_private.h b/reactos/dll/win32/ole32/compobj_private.h index dd3400d8d6c..5dc8eb8e5aa 100644 --- a/reactos/dll/win32/ole32/compobj_private.h +++ b/reactos/dll/win32/ole32/compobj_private.h @@ -304,6 +304,8 @@ extern UINT ole_private_data_clipboard_format DECLSPEC_HIDDEN; extern LSTATUS create_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN; extern LSTATUS open_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN; +extern BOOL actctx_get_miscstatus(const CLSID*, DWORD, DWORD*) DECLSPEC_HIDDEN; + static inline void *heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); diff --git a/reactos/dll/win32/ole32/compositemoniker.c b/reactos/dll/win32/ole32/compositemoniker.c index 076033bc3fa..15417ceb482 100644 --- a/reactos/dll/win32/ole32/compositemoniker.c +++ b/reactos/dll/win32/ole32/compositemoniker.c @@ -22,7 +22,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */ +#define BLOCK_TAB_SIZE 5 /* represent the first size table and its increment block size */ /* CompositeMoniker data structure */ typedef struct CompositeMonikerImpl{ @@ -141,7 +141,7 @@ CompositeMonikerImpl_Release(IMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* destroy the object if there's no more reference on it */ + /* destroy the object if there are no more references to it */ if (ref == 0){ /* release all the components before destroying this object */ @@ -1527,7 +1527,7 @@ EnumMonikerImpl_Release(IEnumMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* destroy the object if there's no more reference on it */ + /* destroy the object if there are no more references to it */ if (ref == 0) { for(i=0;itabSize;i++) @@ -1923,10 +1923,12 @@ CreateGenericComposite(IMoniker *pmkFirst, IMoniker *pmkRest, IMoniker **ppmkCom if (pmkFirst==NULL && pmkRest!=NULL){ *ppmkComposite=pmkRest; + IMoniker_AddRef(pmkRest); return S_OK; } else if (pmkFirst!=NULL && pmkRest==NULL){ *ppmkComposite=pmkFirst; + IMoniker_AddRef(pmkFirst); return S_OK; } else if (pmkFirst==NULL && pmkRest==NULL) diff --git a/reactos/dll/win32/ole32/dcom.idl b/reactos/dll/win32/ole32/dcom.idl index 4517b46d871..c3d090a9cb6 100644 --- a/reactos/dll/win32/ole32/dcom.idl +++ b/reactos/dll/win32/ole32/dcom.idl @@ -19,6 +19,9 @@ /* see the official DCOM specification * (there's a copy at http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm) */ +#pragma makedep proxy +#pragma makedep register + import "unknwn.idl"; [ diff --git a/reactos/dll/win32/ole32/filemoniker.c b/reactos/dll/win32/ole32/filemoniker.c index d327e96922d..95e0e13e2c8 100644 --- a/reactos/dll/win32/ole32/filemoniker.c +++ b/reactos/dll/win32/ole32/filemoniker.c @@ -119,7 +119,7 @@ FileMonikerImpl_Release(IMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* destroy the object if there's no more reference on it */ + /* destroy the object if there are no more references to it */ if (ref == 0) FileMonikerImpl_Destroy(This); return ref; @@ -918,11 +918,12 @@ static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { - LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath; - IBindCtx *pbind; + LPOLESTR pathThis = NULL, pathOther = NULL,*stringTable1,*stringTable2,commonPath = NULL; + IBindCtx *bindctx; DWORD mkSys; ULONG nb1,nb2,i,sameIdx; - BOOL machimeNameCase=FALSE; + BOOL machineNameCase = FALSE; + HRESULT ret; if (ppmkPrefix==NULL) return E_POINTER; @@ -934,81 +935,81 @@ FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p /* check if we have the same type of moniker */ IMoniker_IsSystemMoniker(pmkOther,&mkSys); + if (mkSys != MKSYS_FILEMONIKER) + return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix); - if(mkSys==MKSYS_FILEMONIKER){ - HRESULT ret; - - ret = CreateBindCtx(0,&pbind); - if (FAILED(ret)) - return ret; - - /* create a string based on common part of the two paths */ - - ret = IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis); - if (FAILED(ret)) - return ret; - ret = IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther); - if (FAILED(ret)) - return ret; - - nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1); - if (FAILED(nb1)) - return nb1; - nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2); - if (FAILED(nb2)) - { - free_stringtable(stringTable1); - return nb2; - } - - if (nb1==0 || nb2==0) - { - free_stringtable(stringTable1); - free_stringtable(stringTable2); - return MK_E_NOPREFIX; - } - - commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1)); - if (!commonPath) - return E_OUTOFMEMORY; - - *commonPath=0; - - for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) && - (stringTable2[sameIdx]!=NULL) && - (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++); - - if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){ - - machimeNameCase=TRUE; - - for(i=2;i 3 || nb2 > 3) ) - ret = MK_E_NOPREFIX; - else - { - for(i=0;i 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){ + machineNameCase = TRUE; + + for(i=2;i 3 || nb2 > 3) ) + ret = MK_E_NOPREFIX; else - return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix); + { + for (i = 0; i < sameIdx; i++) + strcatW(commonPath,stringTable1[i]); + ret = CreateFileMoniker(commonPath, ppmkPrefix); + } + +failed: + IBindCtx_Release(bindctx); + CoTaskMemFree(pathThis); + CoTaskMemFree(pathOther); + CoTaskMemFree(commonPath); + free_stringtable(stringTable1); + free_stringtable(stringTable2); + + return ret; } /****************************************************************************** @@ -1088,8 +1089,7 @@ lend: CoTaskMemFree(strgtable); } - if (word) - CoTaskMemFree(word); + CoTaskMemFree(word); return ret; } @@ -1343,7 +1343,7 @@ static HRESULT FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPa LPOLESTR *tabStr=0; static const WCHAR twoPoint[]={'.','.',0}; static const WCHAR bkSlash[]={'\\',0}; - BYTE addBkSlash; + BOOL addBkSlash; TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName)); @@ -1364,14 +1364,14 @@ static HRESULT FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPa if (nb > 0 ){ - addBkSlash=1; + addBkSlash = TRUE; if (lstrcmpW(tabStr[0],twoPoint)!=0) - addBkSlash=0; + addBkSlash = FALSE; else for(i=0;ifilePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR)); diff --git a/reactos/dll/win32/ole32/ifs.c b/reactos/dll/win32/ole32/ifs.c index b11d5dac83c..09e95c55958 100644 --- a/reactos/dll/win32/ole32/ifs.c +++ b/reactos/dll/win32/ole32/ifs.c @@ -57,7 +57,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug = static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 }; /* resize the old table */ -static int SetSpyedBlockTableLength ( DWORD NewLength ) +static BOOL SetSpyedBlockTableLength ( DWORD NewLength ) { LPVOID *NewSpyedBlocks; @@ -72,14 +72,13 @@ static int SetSpyedBlockTableLength ( DWORD NewLength ) } /* add a location to the table */ -static int AddMemoryLocation(LPVOID * pMem) +static BOOL AddMemoryLocation(LPVOID * pMem) { LPVOID * Current; /* allocate the table if not already allocated */ - if (!Malloc32.SpyedBlockTableLength) { - if (!SetSpyedBlockTableLength(0x1000)) return 0; - } + if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000)) + return FALSE; /* find a free location */ Current = Malloc32.SpyedBlocks; @@ -88,7 +87,8 @@ static int AddMemoryLocation(LPVOID * pMem) if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) { /* no more space in table, grow it */ DWORD old_length = Malloc32.SpyedBlockTableLength; - if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0; + if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000)) + return FALSE; Current = Malloc32.SpyedBlocks + old_length; } }; @@ -97,31 +97,31 @@ static int AddMemoryLocation(LPVOID * pMem) *Current = pMem; Malloc32.SpyedAllocationsLeft++; /*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/ - return 1; + return TRUE; } -static int RemoveMemoryLocation(LPCVOID pMem) +static BOOL RemoveMemoryLocation(LPCVOID pMem) { LPVOID * Current; /* allocate the table if not already allocated */ - if (!Malloc32.SpyedBlockTableLength) { - if (!SetSpyedBlockTableLength(0x1000)) return 0; - } + if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000)) + return FALSE; Current = Malloc32.SpyedBlocks; /* find the location */ while (*Current != pMem) { Current++; - if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) return 0; /* not found */ + if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) + return FALSE; /* not found */ } /* location found */ Malloc32.SpyedAllocationsLeft--; /*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/ *Current = NULL; - return 1; + return TRUE; } /****************************************************************************** @@ -236,7 +236,7 @@ static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) { */ static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) { - BOOL fSpyed = 0; + BOOL fSpyed = FALSE; TRACE("(%p)\n",pv); @@ -273,7 +273,7 @@ static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) { static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) { DWORD cb; - BOOL fSpyed = 0; + BOOL fSpyed = FALSE; TRACE("(%p)\n",pv); @@ -297,7 +297,7 @@ static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) { */ static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) { - BOOL fSpyed = 0; + BOOL fSpyed = FALSE; int didAlloc; TRACE("(%p)\n",pv); diff --git a/reactos/dll/win32/ole32/irot.idl b/reactos/dll/win32/ole32/irot.idl index 95236db6e44..ca730fdd3dc 100644 --- a/reactos/dll/win32/ole32/irot.idl +++ b/reactos/dll/win32/ole32/irot.idl @@ -16,4 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep client + #include "wine/irot.idl" diff --git a/reactos/dll/win32/ole32/itemmoniker.c b/reactos/dll/win32/ole32/itemmoniker.c index 055b69563e5..c88b4dec311 100644 --- a/reactos/dll/win32/ole32/itemmoniker.c +++ b/reactos/dll/win32/ole32/itemmoniker.c @@ -107,7 +107,7 @@ static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* destroy the object if there's no more reference on it */ + /* destroy the object if there are no more references to it */ if (ref == 0) ItemMonikerImpl_Destroy(This); return ref; diff --git a/reactos/dll/win32/ole32/marshal.c b/reactos/dll/win32/ole32/marshal.c index 11cceda74c2..411f508d98b 100644 --- a/reactos/dll/win32/ole32/marshal.c +++ b/reactos/dll/win32/ole32/marshal.c @@ -92,7 +92,8 @@ static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf) HRESULT hr; CLSID clsid; - if ((hr = CoGetPSClsid(riid, &clsid))) + hr = CoGetPSClsid(riid, &clsid); + if (hr != S_OK) return hr; return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER | WINE_CLSCTX_DONT_HOST, NULL, &IID_IPSFactoryBuffer, (LPVOID*)facbuf); @@ -1150,15 +1151,17 @@ HRESULT apartment_disconnectproxies(struct apartment *apt) /********************** StdMarshal implementation ****************************/ typedef struct _StdMarshalImpl { - const IMarshalVtbl *lpvtbl; - LONG ref; - - IID iid; - DWORD dwDestContext; - LPVOID pvDestContext; - DWORD mshlflags; + IMarshal IMarshal_iface; + LONG ref; + DWORD dest_context; + void *dest_context_data; } StdMarshalImpl; +static inline StdMarshalImpl *impl_from_StdMarshal(IMarshal *iface) +{ + return CONTAINING_RECORD(iface, StdMarshalImpl, IMarshal_iface); +} + static HRESULT WINAPI StdMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, void **ppv) { @@ -1174,16 +1177,16 @@ StdMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, void **ppv) } static ULONG WINAPI -StdMarshalImpl_AddRef(LPMARSHAL iface) +StdMarshalImpl_AddRef(IMarshal *iface) { - StdMarshalImpl *This = (StdMarshalImpl *)iface; + StdMarshalImpl *This = impl_from_StdMarshal(iface); return InterlockedIncrement(&This->ref); } static ULONG WINAPI -StdMarshalImpl_Release(LPMARSHAL iface) +StdMarshalImpl_Release(IMarshal *iface) { - StdMarshalImpl *This = (StdMarshalImpl *)iface; + StdMarshalImpl *This = impl_from_StdMarshal(iface); ULONG ref = InterlockedDecrement(&This->ref); if (!ref) HeapFree(GetProcessHeap(),0,This); @@ -1192,7 +1195,7 @@ StdMarshalImpl_Release(LPMARSHAL iface) static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass( - LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, + IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid) { *pCid = CLSID_DfMarshal; @@ -1201,7 +1204,7 @@ StdMarshalImpl_GetUnmarshalClass( static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax( - LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, + IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize) { *pSize = sizeof(STDOBJREF); @@ -1210,7 +1213,7 @@ StdMarshalImpl_GetMarshalSizeMax( static HRESULT WINAPI StdMarshalImpl_MarshalInterface( - LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context, + IMarshal *iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context, void* dest_context_data, DWORD mshlflags) { STDOBJREF stdobjref; @@ -1312,9 +1315,9 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, } static HRESULT WINAPI -StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv) +StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv) { - StdMarshalImpl *This = (StdMarshalImpl *)iface; + StdMarshalImpl *This = impl_from_StdMarshal(iface); struct stub_manager *stubmgr = NULL; STDOBJREF stdobjref; ULONG res; @@ -1380,8 +1383,8 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v wine_dbgstr_longlong(stdobjref.oxid)); if (hres == S_OK) - hres = unmarshal_object(&stdobjref, apt, This->dwDestContext, - This->pvDestContext, riid, + hres = unmarshal_object(&stdobjref, apt, This->dest_context, + This->dest_context_data, riid, stubmgr ? &stubmgr->oxid_info : NULL, ppv); if (stubmgr) stub_manager_int_release(stubmgr); @@ -1394,7 +1397,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v } static HRESULT WINAPI -StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) +StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm) { STDOBJREF stdobjref; ULONG res; @@ -1436,13 +1439,13 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) } static HRESULT WINAPI -StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) +StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved) { FIXME("(), stub!\n"); return S_OK; } -static const IMarshalVtbl VT_StdMarshal = +static const IMarshalVtbl StdMarshalVtbl = { StdMarshalImpl_QueryInterface, StdMarshalImpl_AddRef, @@ -1455,15 +1458,24 @@ static const IMarshalVtbl VT_StdMarshal = StdMarshalImpl_DisconnectObject }; -static HRESULT StdMarshalImpl_Construct(REFIID riid, void** ppvObject) +static HRESULT StdMarshalImpl_Construct(REFIID riid, DWORD dest_context, void *dest_context_data, void** ppvObject) { - StdMarshalImpl * pStdMarshal = - HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StdMarshalImpl)); + HRESULT hr; + + StdMarshalImpl *pStdMarshal = HeapAlloc(GetProcessHeap(), 0, sizeof(StdMarshalImpl)); if (!pStdMarshal) return E_OUTOFMEMORY; - pStdMarshal->lpvtbl = &VT_StdMarshal; + + pStdMarshal->IMarshal_iface.lpVtbl = &StdMarshalVtbl; pStdMarshal->ref = 0; - return IMarshal_QueryInterface((IMarshal*)pStdMarshal, riid, ppvObject); + pStdMarshal->dest_context = dest_context; + pStdMarshal->dest_context_data = dest_context_data; + + hr = IMarshal_QueryInterface(&pStdMarshal->IMarshal_iface, riid, ppvObject); + if (FAILED(hr)) + HeapFree(GetProcessHeap(), 0, pStdMarshal); + + return hr; } /*********************************************************************** @@ -1493,8 +1505,6 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPMARSHAL *ppMarshal) { - StdMarshalImpl *dm; - if (pUnk == NULL) { FIXME("(%s,NULL,%x,%p,%x,%p), unimplemented yet.\n", @@ -1503,17 +1513,8 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, } TRACE("(%s,%p,%x,%p,%x,%p)\n", debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal); - *ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl)); - dm = (StdMarshalImpl*) *ppMarshal; - if (!dm) return E_FAIL; - dm->lpvtbl = &VT_StdMarshal; - dm->ref = 1; - dm->iid = *riid; - dm->dwDestContext = dwDestContext; - dm->pvDestContext = pvDestContext; - dm->mshlflags = mshlflags; - return S_OK; + return StdMarshalImpl_Construct(&IID_IMarshal, dwDestContext, pvDestContext, (void**)ppMarshal); } /*********************************************************************** @@ -1570,7 +1571,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, if (objref.flags & OBJREF_STANDARD) { TRACE("Using standard unmarshaling\n"); - hr = StdMarshalImpl_Construct(&IID_IMarshal, (LPVOID*)marshal); + hr = StdMarshalImpl_Construct(&IID_IMarshal, 0, NULL, (LPVOID*)marshal); } else if (objref.flags & OBJREF_CUSTOM) { @@ -2007,7 +2008,7 @@ static HRESULT WINAPI StdMarshalCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) { if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal)) - return StdMarshalImpl_Construct(riid, ppv); + return StdMarshalImpl_Construct(riid, 0, NULL, ppv); FIXME("(%s), not supported.\n",debugstr_guid(riid)); return E_NOINTERFACE; diff --git a/reactos/dll/win32/ole32/moniker.c b/reactos/dll/win32/ole32/moniker.c index 23650d14ecd..369a50b1758 100644 --- a/reactos/dll/win32/ole32/moniker.c +++ b/reactos/dll/win32/ole32/moniker.c @@ -371,7 +371,7 @@ RunningObjectTableImpl_Release(IRunningObjectTable* iface) ref = InterlockedDecrement(&This->ref); - /* uninitialize ROT structure if there's no more references to it */ + /* uninitialize ROT structure if there are no more references to it */ if (ref == 0) { struct list *cursor, *cursor2; @@ -1230,8 +1230,10 @@ HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid) absFile=pathDec[nbElm-1]; /* failed if the path represents a directory and not an absolute file name*/ - if (!lstrcmpW(absFile, bkslashW)) + if (!lstrcmpW(absFile, bkslashW)) { + CoTaskMemFree(pathDec); return MK_E_INVALIDEXTENSION; + } /* get the extension of the file */ extension = NULL; @@ -1239,8 +1241,10 @@ HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid) for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--) /* nothing */; - if (!extension || !lstrcmpW(extension, dotW)) + if (!extension || !lstrcmpW(extension, dotW)) { + CoTaskMemFree(pathDec); return MK_E_INVALIDEXTENSION; + } res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId); @@ -1317,7 +1321,7 @@ static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface) ref = InterlockedDecrement(&This->ref); - /* uninitialize rot structure if there's no more reference to it*/ + /* uninitialize ROT structure if there are no more references to it */ if (ref == 0) { ULONG i; diff --git a/reactos/dll/win32/ole32/ole2.c b/reactos/dll/win32/ole32/ole2.c index 4620dbacee9..363dfc845be 100644 --- a/reactos/dll/win32/ole32/ole2.c +++ b/reactos/dll/win32/ole32/ole2.c @@ -30,7 +30,7 @@ WINE_DECLARE_DEBUG_CHANNEL(accel); /****************************************************************************** * These are static/global variables and internal data structures that the - * OLE module uses to maintain it's state. + * OLE module uses to maintain its state. */ typedef struct tagTrackerWindowInfo { @@ -43,7 +43,7 @@ typedef struct tagTrackerWindowInfo BOOL escPressed; HWND curTargetHWND; /* window the mouse is hovering over */ - HWND curDragTargetHWND; /* might be a ancestor of curTargetHWND */ + HWND curDragTargetHWND; /* might be an ancestor of curTargetHWND */ IDropTarget* curDragTarget; POINTL curMousePos; /* current position of the mouse in screen coordinates */ DWORD dwKeyState; /* current state of the shift and ctrl keys and the mouse buttons */ @@ -131,7 +131,6 @@ extern void OLEClipbrd_Initialize(void); */ static void OLEDD_Initialize(void); static LRESULT WINAPI OLEDD_DragTrackerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo); static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo); static DWORD OLEDD_GetButtonState(void); @@ -869,6 +868,8 @@ HRESULT WINAPI OleRegGetMiscStatus( *pdwStatus = 0; + if (actctx_get_miscstatus(clsid, dwAspect, pdwStatus)) return S_OK; + /* * Open the class id Key */ @@ -1304,7 +1305,7 @@ HRESULT WINAPI OleLoad( if (SUCCEEDED(hres) && pClientSite) /* - * Inform the new object of it's client site. + * Inform the new object of its client site. */ hres = IOleObject_SetClientSite(pOleObject, pClientSite); @@ -2171,10 +2172,6 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc( } case WM_TIMER: case WM_MOUSEMOVE: - { - OLEDD_TrackMouseMove((TrackerWindowInfo*)GetWindowLongPtrA(hwnd, 0)); - break; - } case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: @@ -2199,19 +2196,16 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc( } /*** - * OLEDD_TrackMouseMove() + * OLEDD_TrackStateChange() * * This method is invoked while a drag and drop operation is in effect. - * it will generate the appropriate callbacks in the drop source - * and drop target. It will also provide the expected feedback to - * the user. * * params: * trackerInfo - Pointer to the structure identifying the * drag & drop operation that is currently * active. */ -static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) +static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) { HWND hwndNewTarget = 0; HRESULT hr = S_OK; @@ -2224,6 +2218,10 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) pt.y = trackerInfo->curMousePos.y; hwndNewTarget = WindowFromPoint(pt); + trackerInfo->returnValue = IDropSource_QueryContinueDrag(trackerInfo->dropSource, + trackerInfo->escPressed, + trackerInfo->dwKeyState); + /* * Every time, we re-initialize the effects passed to the * IDropTarget to the effects allowed by the source. @@ -2240,7 +2238,8 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) IDropTarget_DragOver(trackerInfo->curDragTarget, trackerInfo->dwKeyState, trackerInfo->curMousePos, - trackerInfo->pdwEffect); + trackerInfo->pdwEffect); + *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect; } else { @@ -2282,6 +2281,7 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) trackerInfo->dwKeyState, trackerInfo->curMousePos, trackerInfo->pdwEffect); + *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect; /* failed DragEnter() means invalid target */ if (hr != S_OK) @@ -2347,29 +2347,6 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo) SetCursor(hCur); } -} - -/*** - * OLEDD_TrackStateChange() - * - * This method is invoked while a drag and drop operation is in effect. - * It is used to notify the drop target/drop source callbacks when - * the state of the keyboard or mouse button change. - * - * params: - * trackerInfo - Pointer to the structure identifying the - * drag & drop operation that is currently - * active. - */ -static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) -{ - /* - * Ask the drop source what to do with the operation. - */ - trackerInfo->returnValue = IDropSource_QueryContinueDrag( - trackerInfo->dropSource, - trackerInfo->escPressed, - trackerInfo->dwKeyState); /* * All the return valued will stop the operation except the S_OK @@ -2402,18 +2379,18 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo) */ case DRAGDROP_S_DROP: if (*trackerInfo->pdwEffect != DROPEFFECT_NONE) - IDropTarget_Drop(trackerInfo->curDragTarget, - trackerInfo->dataObject, - trackerInfo->dwKeyState, - trackerInfo->curMousePos, - trackerInfo->pdwEffect); + trackerInfo->returnValue = IDropTarget_Drop(trackerInfo->curDragTarget, + trackerInfo->dataObject, + trackerInfo->dwKeyState, + trackerInfo->curMousePos, + trackerInfo->pdwEffect); else IDropTarget_DragLeave(trackerInfo->curDragTarget); break; /* * If the source told us that we should cancel, fool the drop - * target by telling it that the mouse left it's window. + * target by telling it that the mouse left its window. * Also set the drop effect to "NONE" in case the application * ignores the result of DoDragDrop. */ @@ -2715,8 +2692,59 @@ done: */ HRESULT WINAPI OleDoAutoConvert(LPSTORAGE pStg, LPCLSID pClsidNew) { - FIXME("(%p,%p) : stub\n",pStg,pClsidNew); - return E_NOTIMPL; + WCHAR *user_type_old, *user_type_new; + CLIPFORMAT cf; + STATSTG stat; + CLSID clsid; + HRESULT hr; + + TRACE("(%p, %p)\n", pStg, pClsidNew); + + *pClsidNew = CLSID_NULL; + if(!pStg) + return E_INVALIDARG; + hr = IStorage_Stat(pStg, &stat, STATFLAG_NONAME); + if(FAILED(hr)) + return hr; + + *pClsidNew = stat.clsid; + hr = OleGetAutoConvert(&stat.clsid, &clsid); + if(FAILED(hr)) + return hr; + + hr = IStorage_SetClass(pStg, &clsid); + if(FAILED(hr)) + return hr; + + hr = ReadFmtUserTypeStg(pStg, &cf, &user_type_old); + if(FAILED(hr)) { + cf = 0; + user_type_new = NULL; + } + + hr = OleRegGetUserType(&clsid, USERCLASSTYPE_FULL, &user_type_new); + if(FAILED(hr)) + user_type_new = NULL; + + hr = WriteFmtUserTypeStg(pStg, cf, user_type_new); + CoTaskMemFree(user_type_new); + if(FAILED(hr)) + { + CoTaskMemFree(user_type_old); + IStorage_SetClass(pStg, &stat.clsid); + return hr; + } + + hr = SetConvertStg(pStg, TRUE); + if(FAILED(hr)) + { + WriteFmtUserTypeStg(pStg, cf, user_type_old); + IStorage_SetClass(pStg, &stat.clsid); + } + else + *pClsidNew = clsid; + CoTaskMemFree(user_type_old); + return hr; } /****************************************************************************** @@ -2809,6 +2837,8 @@ static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt) case VT_UI2: case VT_UI4: case VT_UI8: + case VT_INT: + case VT_UINT: case VT_LPSTR: case VT_LPWSTR: case VT_FILETIME: @@ -2861,7 +2891,10 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */ hr = PROPVARIANT_ValidateType(pvar->vt); if (FAILED(hr)) + { + memset(pvar, 0, sizeof(*pvar)); return hr; + } switch(pvar->vt) { @@ -2882,6 +2915,8 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */ case VT_UI2: case VT_UI4: case VT_UI8: + case VT_INT: + case VT_UINT: case VT_FILETIME: break; case VT_STREAM: @@ -2946,12 +2981,14 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */ } } else + { WARN("Invalid/unsupported type %d\n", pvar->vt); + hr = STG_E_INVALIDPARAMETER; + } } - ZeroMemory(pvar, sizeof(*pvar)); - - return S_OK; + memset(pvar, 0, sizeof(*pvar)); + return hr; } /*********************************************************************** @@ -2988,6 +3025,8 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ case VT_ERROR: case VT_I8: case VT_UI8: + case VT_INT: + case VT_UINT: case VT_R8: case VT_CY: case VT_DATE: @@ -2997,21 +3036,28 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ case VT_STREAMED_OBJECT: case VT_STORAGE: case VT_STORED_OBJECT: - IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream); + if (pvarDest->u.pStream) + IStream_AddRef(pvarDest->u.pStream); break; case VT_CLSID: pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID)); *pvarDest->u.puuid = *pvarSrc->u.puuid; break; case VT_LPSTR: - len = strlen(pvarSrc->u.pszVal); - pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR)); - CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR)); + if (pvarSrc->u.pszVal) + { + len = strlen(pvarSrc->u.pszVal); + pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR)); + CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR)); + } break; case VT_LPWSTR: - len = lstrlenW(pvarSrc->u.pwszVal); - pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); - CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR)); + if (pvarSrc->u.pwszVal) + { + len = lstrlenW(pvarSrc->u.pwszVal); + pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); + CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR)); + } break; case VT_BLOB: case VT_BLOB_OBJECT: @@ -3071,7 +3117,7 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ return E_INVALIDARG; } len = pvarSrc->u.capropvar.cElems; - pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize); + pvarDest->u.capropvar.pElems = len ? CoTaskMemAlloc(len * elemSize) : NULL; if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT)) { for (i = 0; i < len; i++) diff --git a/reactos/dll/win32/ole32/ole32.spec b/reactos/dll/win32/ole32/ole32.spec index aef85c8e614..a12c2c4a19f 100644 --- a/reactos/dll/win32/ole32/ole32.spec +++ b/reactos/dll/win32/ole32/ole32.spec @@ -29,8 +29,8 @@ @ stdcall CoGetCurrentLogicalThreadId(ptr) @ stdcall CoGetCurrentProcess() @ stdcall CoGetDefaultContext(long ptr ptr) -@ stub CoGetInstanceFromFile #@ stdcall (ptr ptr ptr long wstr long ptr) return 0,ERR_NOTIMPLEMENTED -@ stub CoGetInstanceFromIStorage #@ stdcall (ptr ptr ptr long ptr long ptr) return 0,ERR_NOTIMPLEMENTED +@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) +@ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) @ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr) @ stdcall CoGetMalloc(long ptr) @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long) @@ -70,7 +70,7 @@ @ stdcall CoResumeClassObjects() @ stdcall CoRevertToSelf() @ stdcall CoRevokeClassObject(long) -@ stdcall CoRevokeInitializeSpy(double) +@ stdcall CoRevokeInitializeSpy(int64) @ stdcall CoRevokeMallocSpy() @ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long) @ stdcall CoSetState(ptr) @@ -164,7 +164,7 @@ @ stdcall HWND_UserMarshal(ptr ptr ptr) @ stdcall HWND_UserSize(ptr long ptr) @ stdcall HWND_UserUnmarshal(ptr ptr ptr) -@ stdcall IIDFromString(wstr ptr) CLSIDFromString +@ stdcall IIDFromString(wstr ptr) @ stub I_RemoteMain @ stdcall IsAccelerator(long long ptr long) @ stdcall IsEqualGUID(ptr ptr) diff --git a/reactos/dll/win32/ole32/ole32_objidl.idl b/reactos/dll/win32/ole32/ole32_objidl.idl index 057a3e3681d..d2c1a9999e6 100644 --- a/reactos/dll/win32/ole32/ole32_objidl.idl +++ b/reactos/dll/win32/ole32/ole32_objidl.idl @@ -20,6 +20,9 @@ including objidl.h at some point. This will cause all sorts of errors so the easiest thing to do is just comment out our entire header. */ +#pragma makedep proxy +#pragma makedep register + cpp_quote("#if 0 /* ole32_objidl.idl hack */") #include "objidl.idl" cpp_quote("#endif /* ole32_objidl.idl hack */") diff --git a/reactos/dll/win32/ole32/ole32_oleidl.idl b/reactos/dll/win32/ole32/ole32_oleidl.idl index a3bd8810129..0f4fabc512a 100644 --- a/reactos/dll/win32/ole32/ole32_oleidl.idl +++ b/reactos/dll/win32/ole32/ole32_oleidl.idl @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep proxy +#pragma makedep register + #include "oleidl.idl" [ diff --git a/reactos/dll/win32/ole32/ole32_unknwn.idl b/reactos/dll/win32/ole32/ole32_unknwn.idl index 9be195f4d76..f3176a0d18a 100644 --- a/reactos/dll/win32/ole32/ole32_unknwn.idl +++ b/reactos/dll/win32/ole32/ole32_unknwn.idl @@ -20,6 +20,9 @@ including unknwn.h at some point. This will cause all sorts of errors so the easiest thing to do is just comment out our entire header. */ +#pragma makedep proxy +#pragma makedep register + cpp_quote("#if 0 /* oleaut32_unknwn.idl hack */") #include "unknwn.idl" cpp_quote("#endif /* oleaut32_unknwn.idl hack */") diff --git a/reactos/dll/win32/ole32/stg_prop.c b/reactos/dll/win32/ole32/stg_prop.c index 499bc7bbe0e..6eea4f9a4f5 100644 --- a/reactos/dll/win32/ole32/stg_prop.c +++ b/reactos/dll/win32/ole32/stg_prop.c @@ -1375,8 +1375,8 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This) goto end; } /* wackiness alert: if the format ID is FMTID_DocSummaryInformation, there - * follow not one, but two sections. The first is the standard properties - * for the document summary information, and the second is user-defined + * follows not one, but two sections. The first contains the standard properties + * for the document summary information, and the second consists of user-defined * properties. This is the only case in which multiple sections are * allowed. * Reading the second stream isn't implemented yet. @@ -2746,7 +2746,7 @@ BOOLEAN WINAPI StgConvertPropertyToVariant(const SERIALIZEDPROPERTYVALUE* prop, PropVariantInit(pvar); } - return 0; + return FALSE; } SERIALIZEDPROPERTYVALUE* WINAPI StgConvertVariantToProperty(const PROPVARIANT *pvar, diff --git a/reactos/dll/win32/ole32/storage32.c b/reactos/dll/win32/ole32/storage32.c index 57a7fef1eda..fd59674acf6 100644 --- a/reactos/dll/win32/ole32/storage32.c +++ b/reactos/dll/win32/ole32/storage32.c @@ -119,20 +119,20 @@ typedef struct TransactedDirEntry DirRef transactedParentEntry; /* True if this entry is being used. */ - int inuse; + BOOL inuse; /* True if data is up to date. */ - int read; + BOOL read; /* True if this entry has been modified. */ - int dirty; + BOOL dirty; /* True if this entry's stream has been modified. */ - int stream_dirty; + BOOL stream_dirty; /* True if this entry has been deleted in the transacted storage, but the * delete has not yet been committed. */ - int deleted; + BOOL deleted; /* If this entry's stream has been modified, a reference to where the stream * is stored in the snapshot file. */ @@ -1404,7 +1404,7 @@ static HRESULT insertIntoTree( * The root storage contains some element, therefore, start the research * for the appropriate location. */ - BOOL found = 0; + BOOL found = FALSE; DirRef current, next, previous, currentEntryId; /* @@ -1423,7 +1423,7 @@ static HRESULT insertIntoTree( next = currentEntry.rightChild; current = currentEntryId; - while (found == 0) + while (!found) { LONG diff = entryNameCmp( newEntry.name, currentEntry.name); @@ -1442,7 +1442,7 @@ static HRESULT insertIntoTree( StorageBaseImpl_WriteDirEntry(This, current, ¤tEntry); - found = 1; + found = TRUE; } } else if (diff > 0) @@ -1460,7 +1460,7 @@ static HRESULT insertIntoTree( StorageBaseImpl_WriteDirEntry(This, current, ¤tEntry); - found = 1; + found = TRUE; } } else @@ -2767,7 +2767,7 @@ static HRESULT StorageImpl_Construct( else This->base.lockingrole = SWMR_None; - This->base.reverted = 0; + This->base.reverted = FALSE; /* * Initialize the big block cache. @@ -2997,7 +2997,7 @@ static void StorageImpl_Invalidate(StorageBaseImpl* iface) StorageBaseImpl_DeleteAll(&This->base); - This->base.reverted = 1; + This->base.reverted = TRUE; } static void StorageImpl_Destroy(StorageBaseImpl* iface) @@ -4364,7 +4364,7 @@ static DirRef TransactedSnapshotImpl_FindFreeEntry(TransactedSnapshotImpl *This) This->entries_size = new_size; } - This->entries[result].inuse = 1; + This->entries[result].inuse = TRUE; This->firstFreeEntry = result+1; @@ -4385,7 +4385,7 @@ static DirRef TransactedSnapshotImpl_CreateStubEntry( entry->newTransactedParentEntry = entry->transactedParentEntry = parentEntryRef; - entry->read = 0; + entry->read = FALSE; } return stubEntryRef; @@ -4430,7 +4430,7 @@ static HRESULT TransactedSnapshotImpl_EnsureReadEntry( if (SUCCEEDED(hr)) { memcpy(&This->entries[entry].data, &data, sizeof(DirEntry)); - This->entries[entry].read = 1; + This->entries[entry].read = TRUE; } } @@ -4469,7 +4469,7 @@ static HRESULT TransactedSnapshotImpl_MakeStreamDirty( } if (SUCCEEDED(hr)) - This->entries[entry].stream_dirty = 1; + This->entries[entry].stream_dirty = TRUE; if (This->entries[entry].transactedParentEntry != DIRENTRY_NULL) { @@ -4479,7 +4479,7 @@ static HRESULT TransactedSnapshotImpl_MakeStreamDirty( delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[entry].transactedParentEntry); if (delete_ref != DIRENTRY_NULL) - This->entries[delete_ref].deleted = 1; + This->entries[delete_ref].deleted = TRUE; This->entries[entry].transactedParentEntry = This->entries[entry].newTransactedParentEntry = DIRENTRY_NULL; } @@ -4773,9 +4773,9 @@ static HRESULT WINAPI TransactedSnapshotImpl_Commit( { StorageBaseImpl_StreamSetSize(This->scratch, entry->stream_entry, zero); StorageBaseImpl_DestroyDirEntry(This->scratch, entry->stream_entry); - entry->stream_dirty = 0; + entry->stream_dirty = FALSE; } - entry->dirty = 0; + entry->dirty = FALSE; entry->transactedParentEntry = entry->newTransactedParentEntry; } } @@ -4831,7 +4831,7 @@ static void TransactedSnapshotImpl_Invalidate(StorageBaseImpl* This) { TRACE("Storage invalidated (stg=%p)\n", This); - This->reverted = 1; + This->reverted = TRUE; StorageBaseImpl_DeleteAll(This); } @@ -4875,8 +4875,8 @@ static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base, new_entry = &This->entries[new_ref]; new_entry->newTransactedParentEntry = new_entry->transactedParentEntry = DIRENTRY_NULL; - new_entry->read = 1; - new_entry->dirty = 1; + new_entry->read = TRUE; + new_entry->dirty = TRUE; memcpy(&new_entry->data, newData, sizeof(DirEntry)); *index = new_ref; @@ -4901,7 +4901,7 @@ static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base, if (index != This->base.storageDirEntry) { - This->entries[index].dirty = 1; + This->entries[index].dirty = TRUE; if (data->size.QuadPart == 0 && This->entries[index].transactedParentEntry != DIRENTRY_NULL) @@ -4912,7 +4912,7 @@ static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base, delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry); if (delete_ref != DIRENTRY_NULL) - This->entries[delete_ref].deleted = 1; + This->entries[delete_ref].deleted = TRUE; This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; } @@ -4953,7 +4953,7 @@ static HRESULT TransactedSnapshotImpl_DestroyDirEntry(StorageBaseImpl *base, } else { - This->entries[index].deleted = 1; + This->entries[index].deleted = TRUE; } return S_OK; @@ -5029,7 +5029,7 @@ static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base, This->entries[index].stream_entry, zero); StorageBaseImpl_DestroyDirEntry(This->scratch, This->entries[index].stream_entry); - This->entries[index].stream_dirty = 0; + This->entries[index].stream_dirty = FALSE; } else if (This->entries[index].transactedParentEntry != DIRENTRY_NULL) { @@ -5037,7 +5037,7 @@ static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base, delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry); if (delete_ref != DIRENTRY_NULL) - This->entries[delete_ref].deleted = 1; + This->entries[delete_ref].deleted = TRUE; This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; } @@ -5236,7 +5236,7 @@ static void StorageInternalImpl_Invalidate( StorageBaseImpl *base ) { TRACE("Storage invalidated (stg=%p)\n", This); - This->base.reverted = 1; + This->base.reverted = TRUE; This->parentStorage = NULL; @@ -5721,7 +5721,7 @@ static StorageInternalImpl* StorageInternalImpl_Construct( newStorage->base.baseVtbl = &StorageInternalImpl_BaseVtbl; newStorage->base.openFlags = (openFlags & ~STGM_CREATE); - newStorage->base.reverted = 0; + newStorage->base.reverted = FALSE; newStorage->base.ref = 1; @@ -5732,7 +5732,7 @@ static StorageInternalImpl* StorageInternalImpl_Construct( */ newStorage->base.storageDirEntry = storageDirEntry; - newStorage->base.create = 0; + newStorage->base.create = FALSE; return newStorage; } @@ -6019,10 +6019,10 @@ HRESULT BlockChainStream_GetBlockAtOffset(BlockChainStream *This, { if (!StorageImpl_WriteBigBlock(This->parentStorage, result->sector, result->data)) return STG_E_WRITEFAULT; - result->dirty = 0; + result->dirty = FALSE; } - result->read = 0; + result->read = FALSE; result->index = index; result->sector = *sector; } @@ -6047,9 +6047,9 @@ BlockChainStream* BlockChainStream_Construct( newStream->indexCacheLen = 0; newStream->indexCacheSize = 0; newStream->cachedBlocks[0].index = 0xffffffff; - newStream->cachedBlocks[0].dirty = 0; + newStream->cachedBlocks[0].dirty = FALSE; newStream->cachedBlocks[1].index = 0xffffffff; - newStream->cachedBlocks[1].dirty = 0; + newStream->cachedBlocks[1].dirty = FALSE; newStream->blockToEvict = 0; if (FAILED(BlockChainStream_UpdateIndexCache(newStream))) @@ -6071,7 +6071,7 @@ HRESULT BlockChainStream_Flush(BlockChainStream* This) if (This->cachedBlocks[i].dirty) { if (StorageImpl_WriteBigBlock(This->parentStorage, This->cachedBlocks[i].sector, This->cachedBlocks[i].data)) - This->cachedBlocks[i].dirty = 0; + This->cachedBlocks[i].dirty = FALSE; else return STG_E_WRITEFAULT; } @@ -6211,7 +6211,7 @@ HRESULT BlockChainStream_ReadAt(BlockChainStream* This, if (FAILED(StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data, &read)) && !read) return STG_E_READFAULT; - cachedBlock->read = 1; + cachedBlock->read = TRUE; } memcpy(bufferWalker, cachedBlock->data+offsetInBlock, bytesToReadInBuffer); @@ -6299,8 +6299,8 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This, memcpy(cachedBlock->data+offsetInBlock, bufferWalker, bytesToWrite); bytesWrittenAt = bytesToWrite; - cachedBlock->read = 1; - cachedBlock->dirty = 1; + cachedBlock->read = TRUE; + cachedBlock->dirty = TRUE; } blockNoInSequence++; @@ -6402,7 +6402,7 @@ static BOOL BlockChainStream_Shrink(BlockChainStream* This, if (This->cachedBlocks[i].index >= numBlocks) { This->cachedBlocks[i].index = 0xffffffff; - This->cachedBlocks[i].dirty = 0; + This->cachedBlocks[i].dirty = FALSE; } } @@ -7590,11 +7590,21 @@ HRESULT WINAPI StgOpenStorage( HANDLE hFile = 0; DWORD shareMode; DWORD accessMode; + LPWSTR temp_name = NULL; TRACE("(%s, %p, %x, %p, %d, %p)\n", debugstr_w(pwcsName), pstgPriority, grfMode, snbExclude, reserved, ppstgOpen); + if (pstgPriority) + { + /* FIXME: Copy ILockBytes instead? But currently for STGM_PRIORITY it'll be read-only. */ + hr = StorageBaseImpl_GetFilename((StorageBaseImpl*)pstgPriority, &temp_name); + if (FAILED(hr)) goto end; + pwcsName = temp_name; + TRACE("using filename %s\n", debugstr_w(temp_name)); + } + if (pwcsName == 0) { hr = STG_E_INVALIDNAME; @@ -7756,6 +7766,8 @@ HRESULT WINAPI StgOpenStorage( *ppstgOpen = &newStorage->IStorage_iface; end: + CoTaskMemFree(temp_name); + if (pstgPriority) IStorage_Release(pstgPriority); TRACE("<-- %08x, IStorage %p\n", hr, ppstgOpen ? *ppstgOpen : NULL); return hr; } @@ -8667,7 +8679,10 @@ static HRESULT STREAM_ReadString( IStream *stm, LPWSTR *string ) len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 ); wstr = CoTaskMemAlloc( (len + 1)*sizeof (WCHAR) ); if( wstr ) + { MultiByteToWideChar( CP_ACP, 0, str, count, wstr, len ); + wstr[len] = 0; + } CoTaskMemFree( str ); *string = wstr; @@ -8726,32 +8741,37 @@ static HRESULT STORAGE_WriteCompObj( LPSTORAGE pstg, CLSID *clsid, HRESULT WINAPI WriteFmtUserTypeStg( LPSTORAGE pstg, CLIPFORMAT cf, LPOLESTR lpszUserType) { + STATSTG stat; HRESULT r; WCHAR szwClipName[0x40]; - CLSID clsid = CLSID_NULL; + CLSID clsid; LPWSTR wstrProgID = NULL; DWORD n; TRACE("(%p,%x,%s)\n",pstg,cf,debugstr_w(lpszUserType)); /* get the clipboard format name */ - n = GetClipboardFormatNameW( cf, szwClipName, sizeof(szwClipName)/sizeof(szwClipName[0]) ); - szwClipName[n]=0; + if( cf ) + { + n = GetClipboardFormatNameW( cf, szwClipName, + sizeof(szwClipName)/sizeof(szwClipName[0]) ); + szwClipName[n]=0; + } TRACE("Clipboard name is %s\n", debugstr_w(szwClipName)); - /* FIXME: There's room to save a CLSID and its ProgID, but - the CLSID is not looked up in the registry and in all the - tests I wrote it was CLSID_NULL. Where does it come from? - */ + r = IStorage_Stat(pstg, &stat, STATFLAG_NONAME); + if(SUCCEEDED(r)) + clsid = stat.clsid; + else + clsid = CLSID_NULL; - /* get the real program ID. This may fail, but that's fine */ ProgIDFromCLSID(&clsid, &wstrProgID); TRACE("progid is %s\n",debugstr_w(wstrProgID)); - r = STORAGE_WriteCompObj( pstg, &clsid, - lpszUserType, szwClipName, wstrProgID ); + r = STORAGE_WriteCompObj( pstg, &clsid, lpszUserType, + cf ? szwClipName : NULL, wstrProgID ); CoTaskMemFree(wstrProgID); @@ -9472,51 +9492,52 @@ HRESULT WINAPI GetConvertStg(IStorage *stg) */ HRESULT WINAPI SetConvertStg(IStorage *storage, BOOL convert) { + static const WCHAR stream_1oleW[] = {1,'O','l','e',0}; DWORD flags = convert ? OleStream_Convert : 0; + IStream *stream; + DWORD header[2]; HRESULT hr; TRACE("(%p, %d)\n", storage, convert); - hr = STORAGE_CreateOleStream(storage, flags); - if (hr == STG_E_FILEALREADYEXISTS) + hr = IStorage_OpenStream(storage, stream_1oleW, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream); + if (FAILED(hr)) { - static const WCHAR stream_1oleW[] = {1,'O','l','e',0}; - IStream *stream; - DWORD header[2]; + if (hr != STG_E_FILENOTFOUND) + return hr; - hr = IStorage_OpenStream(storage, stream_1oleW, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream); - if (FAILED(hr)) return hr; + return STORAGE_CreateOleStream(storage, flags); + } - hr = IStream_Read(stream, header, sizeof(header), NULL); + hr = IStream_Read(stream, header, sizeof(header), NULL); + if (FAILED(hr)) + { + IStream_Release(stream); + return hr; + } + + /* update flag if differs */ + if ((header[1] ^ flags) & OleStream_Convert) + { + LARGE_INTEGER pos = {{0}}; + + if (header[1] & OleStream_Convert) + flags = header[1] & ~OleStream_Convert; + else + flags = header[1] | OleStream_Convert; + + pos.QuadPart = sizeof(DWORD); + hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); if (FAILED(hr)) { IStream_Release(stream); return hr; } - /* update flag if differs */ - if ((header[1] ^ flags) & OleStream_Convert) - { - LARGE_INTEGER pos; - - if (header[1] & OleStream_Convert) - flags = header[1] & ~OleStream_Convert; - else - flags = header[1] | OleStream_Convert; - - pos.QuadPart = sizeof(DWORD); - hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); - if (FAILED(hr)) - { - IStream_Release(stream); - return hr; - } - - hr = IStream_Write(stream, &flags, sizeof(flags), NULL); - } - IStream_Release(stream); + hr = IStream_Write(stream, &flags, sizeof(flags), NULL); } + IStream_Release(stream); return hr; } diff --git a/reactos/dll/win32/ole32/storage32.h b/reactos/dll/win32/ole32/storage32.h index e8f1fb63e15..939a2e08f99 100644 --- a/reactos/dll/win32/ole32/storage32.h +++ b/reactos/dll/win32/ole32/storage32.h @@ -191,7 +191,7 @@ struct StorageBaseImpl /* * TRUE if this object has been invalidated */ - int reverted; + BOOL reverted; /* * Index of the directory entry of this storage @@ -213,8 +213,8 @@ struct StorageBaseImpl */ DWORD stateBits; - BOOL create; /* Was the storage created or opened. - The behaviour of STGM_SIMPLE depends on this */ + BOOL create; /* Was the storage created or opened. + The behaviour of STGM_SIMPLE depends on this */ /* * If this storage was opened in transacted mode, the object that implements * the transacted snapshot or cache. @@ -514,8 +514,8 @@ typedef struct BlockChainBlock { ULONG index; ULONG sector; - int read; - int dirty; + BOOL read; + BOOL dirty; BYTE data[MAX_BIG_BLOCK_SIZE]; } BlockChainBlock; diff --git a/reactos/dll/win32/ole32/stubmanager.c b/reactos/dll/win32/ole32/stubmanager.c index e1981e41954..9d96899cbaa 100644 --- a/reactos/dll/win32/ole32/stubmanager.c +++ b/reactos/dll/win32/ole32/stubmanager.c @@ -315,7 +315,7 @@ struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object) * threads have a reference to it */ void apartment_disconnectobject(struct apartment *apt, void *object) { - int found = FALSE; + BOOL found = FALSE; struct stub_manager *stubmgr; EnterCriticalSection(&apt->cs); @@ -421,10 +421,11 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc); if (last_extern_ref && m->extern_conn) - IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, TRUE /* FIXME: Use last_unlock releases? */); + IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, last_unlock_releases); if (rc == 0) - stub_manager_int_release(m); + if (!(m->extern_conn && last_unlock_releases && m->weakrefs)) + stub_manager_int_release(m); return rc; } @@ -562,7 +563,7 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const else if (ifstub->flags & MSHLFLAGS_TABLESTRONG) refs = 1; - stub_manager_ext_release(m, refs, tableweak, FALSE); + stub_manager_ext_release(m, refs, tableweak, !tableweak); } /* is an ifstub table marshaled? */ diff --git a/reactos/include/psdk/objbase.h b/reactos/include/psdk/objbase.h index 1db973dc8a7..da464214c1b 100644 --- a/reactos/include/psdk/objbase.h +++ b/reactos/include/psdk/objbase.h @@ -41,7 +41,7 @@ * virtual methods in C++ and a structure with a table of pointer to functions in C. * Unfortunately the layout of the virtual table is compiler specific, the layout of * g++ virtual tables is not the same as that of an egcs virtual table which is not the - * same as that generated by Visual C+. There are workarounds to make the virtual tables + * same as that generated by Visual C++. There are workarounds to make the virtual tables * compatible via padding but unfortunately the one which is imposed to the WINE emulator * by the Windows binaries, i.e. the Visual C++ one, is the most compact of all. * @@ -168,47 +168,6 @@ * - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions. * - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE * macro is defined in which case we would not be here. - * - * - * Implementing a COM interface. - * - * This continues the above example. This example assumes that the implementation is in C. - * - * typedef struct IDirect3DImpl { - * void* lpVtbl; - * // ... - * - * } IDirect3DImpl; - * - * static IDirect3DVtbl d3dvt; - * - * // implement the IDirect3D methods here - * - * int IDirect3D_QueryInterface(IDirect3D* me) - * { - * IDirect3DImpl *This = (IDirect3DImpl *)me; - * // ... - * } - * - * // ... - * - * static IDirect3DVtbl d3dvt = { - * IDirect3D_QueryInterface, - * IDirect3D_Add, - * IDirect3D_Add2, - * IDirect3D_Initialize, - * IDirect3D_SetWidth - * }; - * - * Comments: - * - We first define what the interface really contains. This is the IDirect3DImpl structure. The - * first field must of course be the virtual table pointer. Everything else is free. - * - Then we predeclare our static virtual table variable, we will need its address in some - * methods to initialize the virtual table pointer of the returned interface objects. - * - Then we implement the interface methods. To match what has been declared in the header file - * they must take a pointer to an IDirect3D structure and we must cast it to an IDirect3DImpl so - * that we can manipulate the fields. - * - Finally we initialize the virtual table. */ #if defined(__cplusplus) && !defined(CINTERFACE) @@ -772,6 +731,13 @@ StringFromGUID2( _Out_writes_to_(cmax, return) LPOLESTR str, _In_ INT cmax); +_Check_return_ +HRESULT +WINAPI +IIDFromString( + _In_ LPCOLESTR lpsz, + _Out_ LPIID lpiid); + /***************************************************************************** * COM Server dll - exports */ diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index f2ffcd4405a..5ebcbe6515e 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -145,7 +145,7 @@ reactos/dll/win32/ntprint # Synced to Wine-1.7.1 reactos/dll/win32/objsel # Synced to Wine-1.7.1 reactos/dll/win32/odbc32 # Synced to Wine-1.7.17. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to Wine-1.7.1 -reactos/dll/win32/ole32 # Synced to Wine-1.7.1 +reactos/dll/win32/ole32 # Synced to Wine-1.7.17 reactos/dll/win32/oleacc # Synced to Wine-1.7.1 reactos/dll/win32/oleaut32 # Synced to Wine-1.7.1 reactos/dll/win32/olecli32 # Synced to Wine-1.7.1