[OLE32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 24 Apr 2014 12:14:13 +0000 (12:14 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 24 Apr 2014 12:14:13 +0000 (12:14 +0000)
* Sync with Wine 1.7.17.
CORE-8080

svn path=/trunk/; revision=62938

25 files changed:
reactos/dll/win32/ole32/antimoniker.c
reactos/dll/win32/ole32/bindctx.c
reactos/dll/win32/ole32/classmoniker.c
reactos/dll/win32/ole32/comcat.c
reactos/dll/win32/ole32/compobj.c
reactos/dll/win32/ole32/compobj_private.h
reactos/dll/win32/ole32/compositemoniker.c
reactos/dll/win32/ole32/dcom.idl
reactos/dll/win32/ole32/filemoniker.c
reactos/dll/win32/ole32/ifs.c
reactos/dll/win32/ole32/irot.idl
reactos/dll/win32/ole32/itemmoniker.c
reactos/dll/win32/ole32/marshal.c
reactos/dll/win32/ole32/moniker.c
reactos/dll/win32/ole32/ole2.c
reactos/dll/win32/ole32/ole32.spec
reactos/dll/win32/ole32/ole32_objidl.idl
reactos/dll/win32/ole32/ole32_oleidl.idl
reactos/dll/win32/ole32/ole32_unknwn.idl
reactos/dll/win32/ole32/stg_prop.c
reactos/dll/win32/ole32/storage32.c
reactos/dll/win32/ole32/storage32.h
reactos/dll/win32/ole32/stubmanager.c
reactos/include/psdk/objbase.h
reactos/media/doc/README.WINE

index 93a7140..86d3026 100644 (file)
@@ -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);
index 18e52da..d3f27d7 100644 (file)
@@ -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; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
             if(This->bindCtxTable[i].pObj==punk)
-                found=1;
+                found = TRUE;
 
     if (index != NULL)
         *index=i-1;
index c3a937b..2d3dff8 100644 (file)
@@ -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);
 }
index 0f23deb..d0cebba 100644 (file)
@@ -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;
 
+    *ret = NULL;
+
     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 };
-
-        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;
+    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 = impl_from_IEnumCLSID(iface);
+    TRACE("\n");
+
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI CLSIDEnumGUID_Release(IEnumGUID *iface)
 {
-    CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)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);
+
+    cloned->key = NULL;
+    open_classes_key(HKEY_CLASSES_ROOT, keynameW, KEY_READ, &cloned->key);
+    cloned->next_index = This->next_index;
 
-    *ppenum = (LPENUMGUID)new_this;
+    *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;
 
+    *ret = NULL;
+
     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl));
-    if (This) {
-       static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 };
+    if (!This) return E_OUTOFMEMORY;
 
-       This->lpVtbl = &COMCAT_CLSID_IEnumGUID_Vtbl;
-       This->categories = categories;
-       open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
-    }
-    return (LPENUMGUID)This;
+    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;
 
+    *ret = NULL;
+
     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl));
-    if (This) {
-       WCHAR prefix[] = { 'C', 'L', 'S', 'I', 'D', '\\' };
-
-       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;
+    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;
 }
index 5baffd1..5d8fb0c 100644 (file)
@@ -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(&params->clsid), debugstr_guid(&params->iid));
 
-    if (COM_RegReadPath(params->hkeydll, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+    if (COM_RegReadPath(&params->regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
     {
         /* failure: CLSID is not found in registry */
         WARN("class %s not registered inproc\n", debugstr_guid(&params->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, &params.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,105 +2067,173 @@ static inline BOOL is_valid_hex(WCHAR c)
     return TRUE;
 }
 
-/******************************************************************************
- *             CLSIDFromString [OLE32.@]
- *             IIDFromString   [OLE32.@]
- *
- * Converts a unique identifier from its string representation into
- * the GUID struct.
- *
- * PARAMS
- *  idstr [I] The string representation of the GUID.
- *  id    [O] GUID converted from the string.
- *
- * RETURNS
- *   S_OK on success
- *   CO_E_CLASSSTRING if idstr is not a valid CLSID
- *
- * SEE ALSO
- *  StringFromCLSID
- */
-static HRESULT __CLSIDFromString(LPCWSTR s, LPCLSID id)
+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;
-  BYTE table[256];
 
   if (!s || s[0]!='{') {
     memset( id, 0, sizeof (CLSID) );
-    if(!s) return S_OK;
-    return CO_E_CLASSSTRING;
+    if(!s) return TRUE;
+    return FALSE;
   }
 
   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 (!is_valid_hex(s[i])) return FALSE;
+    id->Data1 = (id->Data1 << 4) | guid_conv_table[s[i]];
   }
-  if (s[9]!='-') return CO_E_CLASSSTRING;
+  if (s[9]!='-') return FALSE;
 
   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 (!is_valid_hex(s[i])) return FALSE;
+    id->Data2 = (id->Data2 << 4) | guid_conv_table[s[i]];
   }
-  if (s[14]!='-') return CO_E_CLASSSTRING;
+  if (s[14]!='-') return FALSE;
 
   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 (!is_valid_hex(s[i])) return FALSE;
+    id->Data3 = (id->Data3 << 4) | guid_conv_table[s[i]];
   }
-  if (s[19]!='-') return CO_E_CLASSSTRING;
+  if (s[19]!='-') return FALSE;
 
   for (i = 20; i < 37; i+=2) {
     if (i == 24) {
-      if (s[i]!='-') return CO_E_CLASSSTRING;
+      if (s[i]!='-') return FALSE;
       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 (!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 S_OK;
+    return TRUE;
 
-  return CO_E_CLASSSTRING;
+  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.@]
+ *
+ * Converts a unique identifier from its string representation into
+ * the GUID struct.
+ *
+ * PARAMS
+ *  idstr [I] The string representation of the GUID.
+ *  id    [O] GUID converted from the string.
+ *
+ * RETURNS
+ *   S_OK on success
+ *   CO_E_CLASSSTRING if idstr is not a valid CLSID
+ *
+ * SEE ALSO
+ *  StringFromCLSID
+ */
 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(data->u.hkey, wszThreadingModel, NULL, &keytype, (BYTE*)threading_model, &dwLength);
+        if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ))
+            threading_model[0] = '\0';
 
-    ret = RegQueryValueExW(key, wszThreadingModel, NULL, &keytype, (LPBYTE)value, &dwLength);
-    if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ))
-        value[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++)
+  return return_multi_qi(pUnk, cmq, pResults);
+}
+
+/***********************************************************************
+ *           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)
   {
-    pResults[index].hr = IUnknown_QueryInterface(pUnk,
-                                                pResults[index].pIID,
-                                                (VOID**)&(pResults[index].pItf));
+    hr = GetClassFile(filename, &clsid);
+    if (FAILED(hr))
+    {
+      ERR("failed to get CLSID from a file\n");
+      return hr;
+    }
 
-    if (pResults[index].hr == S_OK)
-      successCount++;
+    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(&regdata, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
         {
             static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
             if (!strcmpiW(dllpath, wszOle32))
index dd3400d..5dc8eb8 100644 (file)
@@ -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);
index 076033b..15417ce 100644 (file)
@@ -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;i<This->tabSize;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)
index 4517b46..c3d090a 100644 (file)
@@ -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";
 
 [
index d327e96..95e0e13 100644 (file)
@@ -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;
+    ret = CreateBindCtx(0, &bindctx);
+    if (FAILED(ret))
+        return ret;
 
-        *commonPath=0;
+    /* create a string based on common part of the two paths */
+    ret = IMoniker_GetDisplayName(iface, bindctx, NULL, &pathThis);
+    if (FAILED(ret))
+        goto failed;
 
-        for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
-                         (stringTable2[sameIdx]!=NULL) &&
-                         (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
+    ret = IMoniker_GetDisplayName(pmkOther, bindctx, NULL, &pathOther);
+    if (FAILED(ret))
+        goto failed;
 
-        if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
+    nb1 = FileMonikerImpl_DecomposePath(pathThis, &stringTable1);
+    if (FAILED(nb1)) {
+        ret = nb1;
+        goto failed;
+    }
 
-            machimeNameCase=TRUE;
+    nb2 = FileMonikerImpl_DecomposePath(pathOther, &stringTable2);
+    if (FAILED(nb2)) {
+        ret = nb2;
+        goto failed;
+    }
 
-            for(i=2;i<sameIdx;i++)
+    if (nb1 == 0 || nb2 == 0) {
+        ret = MK_E_NOPREFIX;
+        goto failed;
+    }
 
-                if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
-                    machimeNameCase=FALSE;
-                    break;
-            }
-        }
+    commonPath = CoTaskMemAlloc(sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
+    if (!commonPath) {
+        ret = E_OUTOFMEMORY;
+        goto failed;
+    }
 
-        if (machimeNameCase && *stringTable1[sameIdx-1]=='\\')
-            sameIdx--;
+    *commonPath = 0;
+    for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
+                     (stringTable2[sameIdx]!=NULL) &&
+                     (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
 
-        if (machimeNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) )
-            ret = MK_E_NOPREFIX;
-        else
-        {
-            for(i=0;i<sameIdx;i++)
-                strcatW(commonPath,stringTable1[i]);
+    if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
+        machineNameCase = TRUE;
 
-            free_stringtable(stringTable1);
-            free_stringtable(stringTable2);
-            ret = CreateFileMoniker(commonPath,ppmkPrefix);
+    for(i=2;i<sameIdx;i++)
+        if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
+            machineNameCase = FALSE;
+            break;
         }
-        HeapFree(GetProcessHeap(),0,commonPath);
-        return ret;
     }
+
+    if (machineNameCase && *stringTable1[sameIdx-1]=='\\')
+        sameIdx--;
+
+    if (machineNameCase && (sameIdx<=3) && (nb1 > 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;i<nb;i++){
 
                 if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
-                    addBkSlash=0;
+                    addBkSlash = FALSE;
                     break;
                 }
                 else
@@ -1379,13 +1379,13 @@ static HRESULT FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPa
                     if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
                         *tabStr[i]=0;
                         sizeStr--;
-                        addBkSlash=0;
+                        addBkSlash = FALSE;
                         break;
                     }
             }
 
         if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
-            addBkSlash=0;
+            addBkSlash = FALSE;
 
         This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
 
index b11d5da..09e95c5 100644 (file)
@@ -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);
index 95236db..ca730fd 100644 (file)
@@ -16,4 +16,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#pragma makedep client
+
 #include "wine/irot.idl"
index 055b695..c88b4de 100644 (file)
@@ -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;
index 11cceda..411f508 100644 (file)
@@ -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;
index 23650d1..369a50b 100644 (file)
@@ -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;
index 4620dba..363dfc8 100644 (file)
@@ -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++)
index aef85c8..a12c2c4 100644 (file)
@@ -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)
 @ 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)
index 057a3e3..d2c1a99 100644 (file)
@@ -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 */")
index a3bd881..0f4fabc 100644 (file)
@@ -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"
 
 [
index 9be195f..f3176a0 100644 (file)
@@ -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 */")
index 499bc7b..6eea4f9 100644 (file)
@@ -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,
index 57a7fef..fd59674 100644 (file)
@@ -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,
                                         &currentEntry);
-          found = 1;
+          found = TRUE;
         }
       }
       else if (diff > 0)
@@ -1460,7 +1460,7 @@ static HRESULT insertIntoTree(
           StorageBaseImpl_WriteDirEntry(This,
                                         current,
                                         &currentEntry);
-          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;
 }
 
index e8f1fb6..939a2e0 100644 (file)
@@ -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;
 
index e1981e4..9d96899 100644 (file)
@@ -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? */
index 1db973d..da46421 100644 (file)
@@ -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.
  *
  *  - 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
  */
index f2ffcd4..5ebcbe6 100644 (file)
@@ -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