[OLE32_WINETEST] Sync with Wine Staging 4.0. CORE-15682
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 29 Jan 2019 12:16:05 +0000 (13:16 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 29 Jan 2019 12:16:05 +0000 (13:16 +0100)
modules/rostests/winetests/ole32/clipboard.c
modules/rostests/winetests/ole32/compobj.c
modules/rostests/winetests/ole32/dragdrop.c
modules/rostests/winetests/ole32/marshal.c
modules/rostests/winetests/ole32/moniker.c
modules/rostests/winetests/ole32/ole2.c
modules/rostests/winetests/ole32/ole_server.c
modules/rostests/winetests/ole32/propvariant.c
modules/rostests/winetests/ole32/stg_prop.c
modules/rostests/winetests/ole32/storage32.c
modules/rostests/winetests/ole32/usrmarshal.c

index 002312d..d7f18ef 100644 (file)
@@ -61,6 +61,7 @@ typedef struct DataObjectImpl {
     HANDLE text;
     IStream *stm;
     IStorage *stg;
     HANDLE text;
     IStream *stm;
     IStorage *stg;
+    HMETAFILEPICT hmfp;
 } DataObjectImpl;
 
 typedef struct EnumFormatImpl {
 } DataObjectImpl;
 
 typedef struct EnumFormatImpl {
@@ -82,6 +83,26 @@ static UINT cf_stream, cf_storage, cf_global, cf_another, cf_onemore;
 
 static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);
 
 
 static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);
 
+static HMETAFILE create_mf(void)
+{
+    RECT rect = {0, 0, 100, 100};
+    HDC hdc = CreateMetaFileA(NULL);
+    ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
+    return CloseMetaFile(hdc);
+}
+
+static HMETAFILEPICT create_metafilepict(void)
+{
+    HGLOBAL ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
+    METAFILEPICT *mf = GlobalLock(ret);
+    mf->mm = MM_ANISOTROPIC;
+    mf->xExt = 100;
+    mf->yExt = 200;
+    mf->hMF = create_mf();
+    GlobalUnlock(ret);
+    return ret;
+}
+
 static inline DataObjectImpl *impl_from_IDataObject(IDataObject *iface)
 {
     return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface);
 static inline DataObjectImpl *impl_from_IDataObject(IDataObject *iface)
 {
     return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface);
@@ -232,6 +253,12 @@ static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
         HeapFree(GetProcessHeap(), 0, This->fmtetc);
         if(This->stm) IStream_Release(This->stm);
         if(This->stg) IStorage_Release(This->stg);
         HeapFree(GetProcessHeap(), 0, This->fmtetc);
         if(This->stm) IStream_Release(This->stm);
         if(This->stg) IStorage_Release(This->stg);
+        if(This->hmfp) {
+            METAFILEPICT *mfp = GlobalLock(This->hmfp);
+            DeleteMetaFile(mfp->hMF);
+            GlobalUnlock(This->hmfp);
+            GlobalFree(This->hmfp);
+        }
         HeapFree(GetProcessHeap(), 0, This);
     }
 
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -242,7 +269,6 @@ static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pfor
 {
     DataObjectImpl *This = impl_from_IDataObject(iface);
     UINT i;
 {
     DataObjectImpl *This = impl_from_IDataObject(iface);
     UINT i;
-    BOOL foundFormat = FALSE;
 
     trace("getdata: %s\n", dump_fmtetc(pformatetc));
 
 
     trace("getdata: %s\n", dump_fmtetc(pformatetc));
 
@@ -259,7 +285,6 @@ static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pfor
     {
         if(This->fmtetc[i].cfFormat == pformatetc->cfFormat)
         {
     {
         if(This->fmtetc[i].cfFormat == pformatetc->cfFormat)
         {
-            foundFormat = TRUE;
             if(This->fmtetc[i].tymed & pformatetc->tymed)
             {
                 pmedium->pUnkForRelease = (LPUNKNOWN)iface;
             if(This->fmtetc[i].tymed & pformatetc->tymed)
             {
                 pmedium->pUnkForRelease = (LPUNKNOWN)iface;
@@ -282,12 +307,17 @@ static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pfor
                     IStorage_AddRef(This->stg);
                     U(*pmedium).pstg = This->stg;
                 }
                     IStorage_AddRef(This->stg);
                     U(*pmedium).pstg = This->stg;
                 }
+                else if(pformatetc->cfFormat == CF_METAFILEPICT)
+                {
+                    pmedium->tymed = TYMED_MFPICT;
+                    U(*pmedium).hMetaFilePict = This->hmfp;
+                }
                 return S_OK;
             }
         }
     }
 
                 return S_OK;
             }
         }
     }
 
-    return foundFormat ? DV_E_TYMED : DV_E_FORMATETC;
+    return E_FAIL;
 }
 
 static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
 }
 
 static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
@@ -384,27 +414,34 @@ static const IDataObjectVtbl VT_DataObjectImpl =
     DataObjectImpl_EnumDAdvise
 };
 
     DataObjectImpl_EnumDAdvise
 };
 
-static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
+static HRESULT DataObjectImpl_CreateFromHGlobal(HGLOBAL text, LPDATAOBJECT *dataobj)
 {
     DataObjectImpl *obj;
 
     obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
     obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl;
     obj->ref = 1;
 {
     DataObjectImpl *obj;
 
     obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
     obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl;
     obj->ref = 1;
-    obj->text = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
-    strcpy(GlobalLock(obj->text), text);
-    GlobalUnlock(obj->text);
+    obj->text = text;
     obj->stm = NULL;
     obj->stg = NULL;
     obj->stm = NULL;
     obj->stg = NULL;
+    obj->hmfp = NULL;
 
     obj->fmtetc_cnt = 1;
     obj->fmtetc = HeapAlloc(GetProcessHeap(), 0, obj->fmtetc_cnt*sizeof(FORMATETC));
     InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
 
 
     obj->fmtetc_cnt = 1;
     obj->fmtetc = HeapAlloc(GetProcessHeap(), 0, obj->fmtetc_cnt*sizeof(FORMATETC));
     InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
 
-    *lplpdataobj = &obj->IDataObject_iface;
+    *dataobj = &obj->IDataObject_iface;
     return S_OK;
 }
 
     return S_OK;
 }
 
+static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
+{
+    HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
+    strcpy(GlobalLock(h), text);
+    GlobalUnlock(h);
+    return DataObjectImpl_CreateFromHGlobal(h, lplpdataobj);
+}
+
 static const char *cmpl_stm_data = "complex stream";
 static const char *cmpl_text_data = "complex text";
 static const WCHAR device_name[] = {'m','y','d','e','v',0};
 static const char *cmpl_stm_data = "complex stream";
 static const char *cmpl_text_data = "complex text";
 static const WCHAR device_name[] = {'m','y','d','e','v',0};
@@ -428,7 +465,9 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
     StgCreateDocfileOnILockBytes(lbs, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &obj->stg);
     ILockBytes_Release(lbs);
 
     StgCreateDocfileOnILockBytes(lbs, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &obj->stg);
     ILockBytes_Release(lbs);
 
-    obj->fmtetc_cnt = 8;
+    obj->hmfp = create_metafilepict();
+
+    obj->fmtetc_cnt = 9;
     /* zeroing here since FORMATETC has a hole in it, and it's confusing to have this uninitialised. */
     obj->fmtetc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, obj->fmtetc_cnt*sizeof(FORMATETC));
     InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
     /* zeroing here since FORMATETC has a hole in it, and it's confusing to have this uninitialised. */
     obj->fmtetc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, obj->fmtetc_cnt*sizeof(FORMATETC));
     InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
@@ -456,6 +495,7 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
     InitFormatEtc(obj->fmtetc[6], cf_another, 0xfffff);
     InitFormatEtc(obj->fmtetc[7], cf_another, 0xfffff);
     obj->fmtetc[7].dwAspect = DVASPECT_ICON;
     InitFormatEtc(obj->fmtetc[6], cf_another, 0xfffff);
     InitFormatEtc(obj->fmtetc[7], cf_another, 0xfffff);
     obj->fmtetc[7].dwAspect = DVASPECT_ICON;
+    InitFormatEtc(obj->fmtetc[8], CF_METAFILEPICT, TYMED_MFPICT);
 
     *lplpdataobj = &obj->IDataObject_iface;
     return S_OK;
 
     *lplpdataobj = &obj->IDataObject_iface;
     return S_OK;
@@ -510,13 +550,11 @@ static void test_get_clipboard(void)
     ok(hr == DV_E_FORMATETC || broken(hr == S_OK),
         "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
 
     ok(hr == DV_E_FORMATETC || broken(hr == S_OK),
         "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
 
-    InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
-    fmtetc.cfFormat = CF_RIFF;
+    InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL);
     hr = IDataObject_QueryGetData(data_obj, &fmtetc);
     ok(hr == DV_E_CLIPFORMAT, "IDataObject_QueryGetData should have failed with DV_E_CLIPFORMAT instead of 0x%08x\n", hr);
 
     hr = IDataObject_QueryGetData(data_obj, &fmtetc);
     ok(hr == DV_E_CLIPFORMAT, "IDataObject_QueryGetData should have failed with DV_E_CLIPFORMAT instead of 0x%08x\n", hr);
 
-    InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
-    fmtetc.tymed = TYMED_FILE;
+    InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE);
     hr = IDataObject_QueryGetData(data_obj, &fmtetc);
     ok(hr == S_OK, "IDataObject_QueryGetData failed with error 0x%08x\n", hr);
 
     hr = IDataObject_QueryGetData(data_obj, &fmtetc);
     ok(hr == S_OK, "IDataObject_QueryGetData failed with error 0x%08x\n", hr);
 
@@ -554,14 +592,12 @@ static void test_get_clipboard(void)
         ReleaseStgMedium(&stgmedium);
     }
 
         ReleaseStgMedium(&stgmedium);
     }
 
-    InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
-    fmtetc.cfFormat = CF_RIFF;
+    InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL);
     hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
     ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
     if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
 
     hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
     ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
     if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
 
-    InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
-    fmtetc.tymed = TYMED_FILE;
+    InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE);
     hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
     ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08x\n", hr);
     if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
     hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
     ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08x\n", hr);
     if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
@@ -591,6 +627,11 @@ static void test_enum_fmtetc(IDataObject *src)
     hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
     ok(hr == S_OK, "got %08x\n", hr);
     ok(DataObjectImpl_EnumFormatEtc_calls == 0, "EnumFormatEtc was called\n");
     hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
     ok(hr == S_OK, "got %08x\n", hr);
     ok(DataObjectImpl_EnumFormatEtc_calls == 0, "EnumFormatEtc was called\n");
+    if (FAILED(hr))
+    {
+        skip("EnumFormatEtc failed, skipping tests.\n");
+        return;
+    }
 
     if(src) IDataObject_EnumFormatEtc(src, DATADIR_GET, &src_enum);
 
 
     if(src) IDataObject_EnumFormatEtc(src, DATADIR_GET, &src_enum);
 
@@ -826,6 +867,44 @@ static void test_cf_dataobject(IDataObject *data)
     ok(found_priv_data, "didn't find cf_ole_priv_data\n");
 }
 
     ok(found_priv_data, "didn't find cf_ole_priv_data\n");
 }
 
+static void test_complex_get_clipboard(void)
+{
+    HRESULT hr;
+    IDataObject *data_obj;
+    FORMATETC fmtetc;
+    STGMEDIUM stgmedium;
+
+    hr = OleGetClipboard(&data_obj);
+    ok(hr == S_OK, "OleGetClipboard failed with error 0x%08x\n", hr);
+
+    DataObjectImpl_GetData_calls = 0;
+
+    InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_MFPICT);
+    hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
+    ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
+
+    InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_HGLOBAL);
+    hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
+    ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
+
+    InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_HGLOBAL);
+    hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
+    ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
+
+    InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_ENHMF);
+    hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
+    ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
+
+    ok(DataObjectImpl_GetData_calls == 5,
+            "DataObjectImpl_GetData called 5 times instead of %d times\n",
+            DataObjectImpl_GetData_calls);
+    IDataObject_Release(data_obj);
+}
+
 static void test_set_clipboard(void)
 {
     HRESULT hr;
 static void test_set_clipboard(void)
 {
     HRESULT hr;
@@ -933,6 +1012,7 @@ static void test_set_clipboard(void)
     trace("setting complex\n");
     hr = OleSetClipboard(data_cmpl);
     ok(hr == S_OK, "failed to set clipboard to complex data, hr = 0x%08x\n", hr);
     trace("setting complex\n");
     hr = OleSetClipboard(data_cmpl);
     ok(hr == S_OK, "failed to set clipboard to complex data, hr = 0x%08x\n", hr);
+    test_complex_get_clipboard();
     test_cf_dataobject(data_cmpl);
     test_enum_fmtetc(data_cmpl);
 
     test_cf_dataobject(data_cmpl);
     test_enum_fmtetc(data_cmpl);
 
@@ -1206,6 +1286,24 @@ static void test_consumer_refs(void)
     IDataObject_Release(src);
 }
 
     IDataObject_Release(src);
 }
 
+static HGLOBAL create_storage(void)
+{
+    ILockBytes *ilb;
+    IStorage *stg;
+    HGLOBAL hg;
+    HRESULT hr;
+
+    hr = CreateILockBytesOnHGlobal(NULL, FALSE, &ilb);
+    ok(hr == S_OK, "got %08x\n", hr);
+    hr = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stg);
+    ok(hr == S_OK, "got %08x\n", hr);
+    IStorage_Release(stg);
+    hr = GetHGlobalFromILockBytes(ilb, &hg);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ILockBytes_Release(ilb);
+    return hg;
+}
+
 static void test_flushed_getdata(void)
 {
     HRESULT hr;
 static void test_flushed_getdata(void)
 {
     HRESULT hr;
@@ -1347,9 +1445,51 @@ static void test_flushed_getdata(void)
         HeapFree(GetProcessHeap(), 0, fmt.ptd);
     }
 
         HeapFree(GetProcessHeap(), 0, fmt.ptd);
     }
 
+    /* CF_ENHMETAFILE format */
+    InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF);
+    hr = IDataObject_GetData(get, &fmt, &med);
+    ok(hr == S_OK, "got %08x\n", hr);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
+
+    IDataObject_Release(get);
+    IDataObject_Release(src);
+
+    hr = DataObjectImpl_CreateFromHGlobal(create_storage(), &src);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = OleSetClipboard(src);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = OleGetClipboard(&get);
+    ok(hr == S_OK, "got %08x\n", hr);
+    InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
+    hr = IDataObject_GetData(get, &fmt, &med);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
+    IDataObject_Release(get);
+
+    hr = OleFlushClipboard();
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = OleGetClipboard(&get);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
+    hr = IDataObject_GetData(get, &fmt, &med);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
+
+    InitFormatEtc(fmt, CF_TEXT, 0xffff);
+    hr = IDataObject_GetData(get, &fmt, &med);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
 
     IDataObject_Release(get);
     IDataObject_Release(src);
 
     IDataObject_Release(get);
     IDataObject_Release(src);
+
     OleUninitialize();
 }
 
     OleUninitialize();
 }
 
@@ -1377,7 +1517,7 @@ static void test_nonole_clipboard(void)
     IDataObject *get;
     IEnumFORMATETC *enum_fmt;
     FORMATETC fmt;
     IDataObject *get;
     IEnumFORMATETC *enum_fmt;
     FORMATETC fmt;
-    HGLOBAL h, hblob, htext;
+    HGLOBAL h, hblob, htext, hstorage;
     HENHMETAFILE emf;
     STGMEDIUM med;
     DWORD obj_type;
     HENHMETAFILE emf;
     STGMEDIUM med;
     DWORD obj_type;
@@ -1408,6 +1548,7 @@ static void test_nonole_clipboard(void)
     htext = create_text();
     hblob = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE|GMEM_ZEROINIT, 10);
     emf = create_emf();
     htext = create_text();
     hblob = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE|GMEM_ZEROINIT, 10);
     emf = create_emf();
+    hstorage = create_storage();
 
     r = OpenClipboard(NULL);
     ok(r, "gle %d\n", GetLastError());
 
     r = OpenClipboard(NULL);
     ok(r, "gle %d\n", GetLastError());
@@ -1417,6 +1558,8 @@ static void test_nonole_clipboard(void)
     ok(h == hblob, "got %p\n", h);
     h = SetClipboardData(CF_ENHMETAFILE, emf);
     ok(h == emf, "got %p\n", h);
     ok(h == hblob, "got %p\n", h);
     h = SetClipboardData(CF_ENHMETAFILE, emf);
     ok(h == emf, "got %p\n", h);
+    h = SetClipboardData(cf_storage, hstorage);
+    ok(h == hstorage, "got %p\n", h);
     r = CloseClipboard();
     ok(r, "gle %d\n", GetLastError());
 
     r = CloseClipboard();
     ok(r, "gle %d\n", GetLastError());
 
@@ -1424,6 +1567,11 @@ static void test_nonole_clipboard(void)
     ok(hr == S_OK, "got %08x\n", hr);
     hr = IDataObject_EnumFormatEtc(get, DATADIR_GET, &enum_fmt);
     ok(hr == S_OK, "got %08x\n", hr);
     ok(hr == S_OK, "got %08x\n", hr);
     hr = IDataObject_EnumFormatEtc(get, DATADIR_GET, &enum_fmt);
     ok(hr == S_OK, "got %08x\n", hr);
+    if (FAILED(hr))
+    {
+        skip("EnumFormatEtc failed, skipping tests.\n");
+        return;
+    }
 
     hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
     ok(hr == S_OK, "got %08x\n", hr);
 
     hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
     ok(hr == S_OK, "got %08x\n", hr);
@@ -1449,6 +1597,14 @@ static void test_nonole_clipboard(void)
     ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
     ok(fmt.tymed == TYMED_ENHMF, "tymed %x\n", fmt.tymed);
 
     ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
     ok(fmt.tymed == TYMED_ENHMF, "tymed %x\n", fmt.tymed);
 
+    hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(fmt.cfFormat == cf_storage, "cf %04x\n", fmt.cfFormat);
+    ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
+    ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
+    ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
+    ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
+
     hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
     ok(hr == S_OK, "got %08x\n", hr); /* User32 adds some synthesised formats */
 
     hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
     ok(hr == S_OK, "got %08x\n", hr); /* User32 adds some synthesised formats */
 
@@ -1494,6 +1650,12 @@ static void test_nonole_clipboard(void)
     ok(obj_type == OBJ_ENHMETAFILE, "got %d\n", obj_type);
     if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
 
     ok(obj_type == OBJ_ENHMETAFILE, "got %d\n", obj_type);
     if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
 
+    InitFormatEtc(fmt, cf_storage, TYMED_ISTORAGE);
+    hr = IDataObject_GetData(get, &fmt, &med);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
+    if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
+
     IDataObject_Release(get);
 
     r = OpenClipboard(NULL);
     IDataObject_Release(get);
 
     r = OpenClipboard(NULL);
index aedbc08..33a7585 100644 (file)
@@ -27,9 +27,6 @@
 #include "windef.h"
 #include "winbase.h"
 #define USE_COM_CONTEXT_DEF
 #include "windef.h"
 #include "winbase.h"
 #define USE_COM_CONTEXT_DEF
-#ifndef __REACTOS__
-#include "initguid.h"
-#endif
 #include "objbase.h"
 #include "shlguid.h"
 #include "urlmon.h" /* for CLSID_FileProtocol */
 #include "objbase.h"
 #include "shlguid.h"
 #include "urlmon.h" /* for CLSID_FileProtocol */
 #include "ctxtcall.h"
 
 #include "wine/test.h"
 #include "ctxtcall.h"
 
 #include "wine/test.h"
-
-#ifdef __REACTOS__
-#include <initguid.h>
-#endif
+#include "initguid.h"
 
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
 
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -101,9 +95,7 @@ static const GUID IID_Testiface5 = { 0x62222222, 0x1234, 0x1234, { 0x12, 0x34, 0
 static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
 static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
 
 static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
 static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
 
-DEFINE_GUID(CLSID_InProcFreeMarshaler, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26);
 DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26);
-DEFINE_GUID(CLSID_GlobalOptions, 0x0000034b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 
 static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
 
 static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
@@ -203,7 +195,7 @@ static BOOL create_manifest_file(const char *filename, const char *manifest)
     WCHAR path[MAX_PATH];
 
     MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
     WCHAR path[MAX_PATH];
 
     MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
-    GetFullPathNameW(path, sizeof(manifest_path)/sizeof(WCHAR), manifest_path, NULL);
+    GetFullPathNameW(path, ARRAY_SIZE(manifest_path), manifest_path, NULL);
 
     manifest_len = strlen(manifest);
     file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
 
     manifest_len = strlen(manifest);
     file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
@@ -2340,7 +2332,7 @@ static void test_OleRegGetUserType(void)
     }
 
     /* test using registered CLSID */
     }
 
     /* test using registered CLSID */
-    StringFromGUID2(&CLSID_non_existent, clsidW, sizeof(clsidW)/sizeof(clsidW[0]));
+    StringFromGUID2(&CLSID_non_existent, clsidW, ARRAY_SIZE(clsidW));
 
     ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition);
     if (!ret)
 
     ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition);
     if (!ret)
@@ -2528,7 +2520,7 @@ static void flush_messages(void)
 
 static LRESULT CALLBACK cowait_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 {
 
 static LRESULT CALLBACK cowait_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
 {
-    if(cowait_msgs_last < sizeof(cowait_msgs)/sizeof(*cowait_msgs))
+    if(cowait_msgs_last < ARRAY_SIZE(cowait_msgs))
         cowait_msgs[cowait_msgs_last++] = msg;
     if(msg == WM_DDE_FIRST)
         return 6;
         cowait_msgs[cowait_msgs_last++] = msg;
     if(msg == WM_DDE_FIRST)
         return 6;
index 6abe4a9..5994d60 100644 (file)
@@ -701,7 +701,7 @@ static void test_DoDragDrop(void)
     GetWindowRect(hwnd, &rect);
     ok(SetCursorPos(rect.left+50, rect.top+50), "SetCursorPos failed\n");
 
     GetWindowRect(hwnd, &rect);
     ok(SetCursorPos(rect.left+50, rect.top+50), "SetCursorPos failed\n");
 
-    for (seq = 0; seq < sizeof(call_lists) / sizeof(call_lists[0]); seq++)
+    for (seq = 0; seq < ARRAY_SIZE(call_lists); seq++)
     {
         DWORD effect_in;
         trace("%d\n", seq);
     {
         DWORD effect_in;
         trace("%d\n", seq);
index 943321b..22a6796 100644 (file)
@@ -31,7 +31,6 @@
 #include "olectl.h"
 #include "shlguid.h"
 #include "shobjidl.h"
 #include "olectl.h"
 #include "shlguid.h"
 #include "shobjidl.h"
-#include "initguid.h"
 
 #include "wine/test.h"
 #include "wine/heap.h"
 
 #include "wine/test.h"
 #include "wine/heap.h"
         expect_ ## func = called_ ## func = FALSE; \
     }while(0)
 
         expect_ ## func = called_ ## func = FALSE; \
     }while(0)
 
-DEFINE_GUID(CLSID_StdGlobalInterfaceTable,0x00000323,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
-DEFINE_GUID(CLSID_ManualResetEvent,       0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
-
 static const GUID CLSID_WineTestPSFactoryBuffer = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
 static const GUID CLSID_WineTestPSFactoryBuffer = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
+static const GUID CLSID_DfMarshal = { 0x0000030b, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
 
 /* functions that are not present on all versions of Windows */
 static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
 
 /* functions that are not present on all versions of Windows */
 static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
@@ -77,6 +74,51 @@ static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
 #define ok_zero_external_conn() do {if (with_external_conn) ok(!external_connections, "got %d external connections\n", external_connections);} while(0);
 #define ok_last_release_closes(b) do {if (with_external_conn) ok(last_release_closes == b, "got %d expected %d\n", last_release_closes, b);} while(0);
 
 #define ok_zero_external_conn() do {if (with_external_conn) ok(!external_connections, "got %d external connections\n", external_connections);} while(0);
 #define ok_last_release_closes(b) do {if (with_external_conn) ok(last_release_closes == b, "got %d expected %d\n", last_release_closes, b);} while(0);
 
+#define OBJREF_SIGNATURE (0x574f454d)
+#define OBJREF_STANDARD (0x1)
+#define OBJREF_CUSTOM (0x4)
+
+typedef struct tagDUALSTRINGARRAY {
+    unsigned short wNumEntries;
+    unsigned short wSecurityOffset;
+    unsigned short aStringArray[1];
+} DUALSTRINGARRAY;
+
+typedef UINT64 OXID;
+typedef UINT64 OID;
+typedef GUID IPID;
+
+typedef struct tagSTDOBJREF {
+    ULONG flags;
+    ULONG cPublicRefs;
+    OXID oxid;
+    OID oid;
+    IPID ipid;
+} STDOBJREF;
+
+typedef struct tagOBJREF {
+    ULONG signature;
+    ULONG flags;
+    GUID iid;
+    union {
+        struct OR_STANDARD {
+            STDOBJREF std;
+            DUALSTRINGARRAY saResAddr;
+        } u_standard;
+        struct OR_HANDLER {
+            STDOBJREF std;
+            CLSID clsid;
+            DUALSTRINGARRAY saResAddr;
+        } u_handler;
+        struct OR_CUSTOM {
+            CLSID clsid;
+            ULONG cbExtension;
+            ULONG size;
+            byte *pData;
+        } u_custom;
+    } u_objref;
+} OBJREF;
+
 static const IID IID_IWineTest =
 {
     0x5201163f,
 static const IID IID_IWineTest =
 {
     0x5201163f,
@@ -1297,7 +1339,7 @@ static void test_marshal_channel_buffer(void)
     SET_EXPECT(GetWindow);
     hr = IOleWindow_GetWindow(ole_window, &hwnd);
     ok(hr == S_OK, "GetWindow failed: %08x\n", hr);
     SET_EXPECT(GetWindow);
     hr = IOleWindow_GetWindow(ole_window, &hwnd);
     ok(hr == S_OK, "GetWindow failed: %08x\n", hr);
-    ok(hwnd == (HWND)0xdeadbeef, "hwnd = %p\n", hwnd);
+    ok((DWORD)(DWORD_PTR)hwnd == 0xdeadbeef, "hwnd = %p\n", hwnd);
     CHECK_CALLED(Invoke);
     CHECK_CALLED(GetWindow);
 
     CHECK_CALLED(Invoke);
     CHECK_CALLED(GetWindow);
 
@@ -1314,6 +1356,293 @@ todo_wine
     end_host_object(tid, thread);
 }
 
     end_host_object(tid, thread);
 }
 
+static const CLSID *unmarshal_class;
+DEFINE_EXPECT(CustomMarshal_GetUnmarshalClass);
+DEFINE_EXPECT(CustomMarshal_GetMarshalSizeMax);
+DEFINE_EXPECT(CustomMarshal_MarshalInterface);
+
+static HRESULT WINAPI CustomMarshal_QueryInterface(IMarshal *iface, REFIID riid, void **ppv)
+{
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal)) {
+        *ppv = iface;
+    }
+    else
+    {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI CustomMarshal_AddRef(IMarshal *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI CustomMarshal_Release(IMarshal *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI CustomMarshal_GetUnmarshalClass(IMarshal *iface, REFIID riid,
+        void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
+{
+    CHECK_EXPECT(CustomMarshal_GetUnmarshalClass);
+    *clsid = *unmarshal_class;
+    return S_OK;
+}
+
+static HRESULT WINAPI CustomMarshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid,
+        void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *size)
+{
+    CHECK_EXPECT(CustomMarshal_GetMarshalSizeMax);
+    ok(size != NULL, "size = NULL\n");
+
+    *size = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI CustomMarshal_MarshalInterface(IMarshal *iface, IStream *stream,
+        REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
+{
+    IMarshal *std_marshal;
+    STATSTG stat;
+    HRESULT hr;
+
+    CHECK_EXPECT(CustomMarshal_MarshalInterface);
+
+    if(unmarshal_class != &CLSID_StdMarshal)
+        return S_OK;
+
+    hr = IStream_Stat(stream, &stat, STATFLAG_DEFAULT);
+    ok_ole_success(hr, IStream_Stat);
+    ok(U(stat.cbSize).LowPart == 0, "stream is not empty (%d)\n", U(stat.cbSize).LowPart);
+    ok(U(stat.cbSize).HighPart == 0, "stream is not empty (%d)\n", U(stat.cbSize).HighPart);
+
+    hr = CoGetStandardMarshal(riid, (IUnknown*)iface,
+            dwDestContext, NULL, mshlflags, &std_marshal);
+    ok_ole_success(hr, CoGetStandardMarshal);
+    hr = IMarshal_MarshalInterface(std_marshal, stream, riid, pv,
+            dwDestContext, pvDestContext, mshlflags);
+    ok_ole_success(hr, IMarshal_MarshalInterface);
+    IMarshal_Release(std_marshal);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI CustomMarshal_UnmarshalInterface(IMarshal *iface,
+        IStream *stream, REFIID riid, void **ppv)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CustomMarshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CustomMarshal_DisconnectObject(IMarshal *iface, DWORD res)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static IMarshalVtbl CustomMarshalVtbl =
+{
+    CustomMarshal_QueryInterface,
+    CustomMarshal_AddRef,
+    CustomMarshal_Release,
+    CustomMarshal_GetUnmarshalClass,
+    CustomMarshal_GetMarshalSizeMax,
+    CustomMarshal_MarshalInterface,
+    CustomMarshal_UnmarshalInterface,
+    CustomMarshal_ReleaseMarshalData,
+    CustomMarshal_DisconnectObject
+};
+
+static IMarshal CustomMarshal = { &CustomMarshalVtbl };
+
+static void test_StdMarshal_custom_marshaling(void)
+{
+    IStream *stream;
+    IUnknown *unk;
+    DWORD size;
+    HRESULT hr;
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok_ole_success(hr, CreateStreamOnHGlobal);
+
+    unmarshal_class = &CLSID_StdMarshal;
+    SET_EXPECT(CustomMarshal_GetUnmarshalClass);
+    SET_EXPECT(CustomMarshal_MarshalInterface);
+    hr = CoMarshalInterface(stream, &IID_IUnknown, (IUnknown*)&CustomMarshal,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, CoMarshalInterface);
+    CHECK_CALLED(CustomMarshal_GetUnmarshalClass);
+    CHECK_CALLED(CustomMarshal_MarshalInterface);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&unk);
+    ok_ole_success(hr, CoUnmarshalInterface);
+    ok(unk == (IUnknown*)&CustomMarshal, "unk != &CustomMarshal\n");
+    IUnknown_Release(unk);
+    IStream_Release(stream);
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok_ole_success(hr, CreateStreamOnHGlobal);
+
+    SET_EXPECT(CustomMarshal_GetUnmarshalClass);
+    SET_EXPECT(CustomMarshal_MarshalInterface);
+    hr = CoMarshalInterface(stream, &IID_IUnknown, (IUnknown*)&CustomMarshal,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, CoMarshalInterface);
+    CHECK_CALLED(CustomMarshal_GetUnmarshalClass);
+    CHECK_CALLED(CustomMarshal_MarshalInterface);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    hr = CoReleaseMarshalData(stream);
+    ok_ole_success(hr, CoReleaseMarshalData);
+    IStream_Release(stream);
+
+    SET_EXPECT(CustomMarshal_GetMarshalSizeMax);
+    hr = CoGetMarshalSizeMax(&size, &IID_IUnknown, (IUnknown*)&CustomMarshal,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, CoGetMarshalSizeMax);
+    CHECK_CALLED(CustomMarshal_GetMarshalSizeMax);
+    ok(size == sizeof(OBJREF), "size = %d, expected %d\n", size, (int)sizeof(OBJREF));
+}
+
+static void test_DfMarshal_custom_marshaling(void)
+{
+    DWORD size, read;
+    IStream *stream;
+    OBJREF objref;
+    HRESULT hr;
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok_ole_success(hr, CreateStreamOnHGlobal);
+
+    unmarshal_class = &CLSID_DfMarshal;
+    SET_EXPECT(CustomMarshal_GetUnmarshalClass);
+    SET_EXPECT(CustomMarshal_GetMarshalSizeMax);
+    SET_EXPECT(CustomMarshal_MarshalInterface);
+    hr = CoMarshalInterface(stream, &IID_IUnknown, (IUnknown*)&CustomMarshal,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, CoMarshalInterface);
+    CHECK_CALLED(CustomMarshal_GetUnmarshalClass);
+    CHECK_CALLED(CustomMarshal_GetMarshalSizeMax);
+    CHECK_CALLED(CustomMarshal_MarshalInterface);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData);
+    hr = IStream_Read(stream, &objref, size, &read);
+    ok_ole_success(hr, IStream_Read);
+    ok(read == size, "read = %d, expected %d\n", read, size);
+    ok(objref.signature == OBJREF_SIGNATURE, "objref.signature = %x\n",
+            objref.signature);
+    ok(objref.flags == OBJREF_CUSTOM, "objref.flags = %x\n", objref.flags);
+    ok(IsEqualIID(&objref.iid, &IID_IUnknown), "objref.iid = %s\n",
+            wine_dbgstr_guid(&objref.iid));
+    ok(IsEqualIID(&objref.u_objref.u_custom.clsid, &CLSID_DfMarshal),
+            "custom.clsid = %s\n", wine_dbgstr_guid(&objref.u_objref.u_custom.clsid));
+    ok(!objref.u_objref.u_custom.cbExtension, "custom.cbExtension = %d\n",
+            objref.u_objref.u_custom.cbExtension);
+    ok(!objref.u_objref.u_custom.size, "custom.size = %d\n",
+            objref.u_objref.u_custom.size);
+
+    IStream_Release(stream);
+
+    SET_EXPECT(CustomMarshal_GetMarshalSizeMax);
+    hr = CoGetMarshalSizeMax(&size, &IID_IUnknown, (IUnknown*)&CustomMarshal,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, CoGetMarshalSizeMax);
+    CHECK_CALLED(CustomMarshal_GetMarshalSizeMax);
+    ok(size == sizeof(OBJREF), "size = %d, expected %d\n", size, (int)sizeof(OBJREF));
+}
+
+static void test_CoGetStandardMarshal(void)
+{
+    DUALSTRINGARRAY *dualstringarr;
+    STDOBJREF *stdobjref;
+    OBJREF objref;
+    IMarshal *marshal;
+    DWORD size, read;
+    IStream *stream;
+    IUnknown *unk;
+    CLSID clsid;
+    HRESULT hr;
+
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+    ok_ole_success(hr, CreateStreamOnHGlobal);
+
+    hr = CoGetStandardMarshal(&IID_IUnknown, &Test_Unknown,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &marshal);
+    ok_ole_success(hr, CoGetStandardMarshal);
+
+    hr = IMarshal_GetUnmarshalClass(marshal, &IID_IUnknown, &Test_Unknown,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &clsid);
+    ok_ole_success(hr, IMarshal_GetUnmarshalClass);
+    ok(IsEqualGUID(&clsid, &CLSID_StdMarshal), "clsid = %s\n", wine_dbgstr_guid(&clsid));
+
+    hr = IMarshal_GetMarshalSizeMax(marshal, &IID_IUnknown, &Test_Unknown,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &size);
+    ok_ole_success(hr, IMarshal_GetMarshalSizeMax);
+    hr = CoGetMarshalSizeMax(&read, &IID_IUnknown, &Test_Unknown,
+            MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, CoGetMarshalSizeMax);
+    ok(size == read, "IMarshal_GetMarshalSizeMax size = %d, expected %d\n", size, read);
+
+    hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUnknown,
+            &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, IMarshal_MarshalInterface);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    size = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
+    hr = IStream_Read(stream, &objref, size, &read);
+    ok_ole_success(hr, IStream_Read);
+    ok(read == size, "read = %d, expected %d\n", read, size);
+    ok(objref.signature == OBJREF_SIGNATURE, "objref.signature = %x\n",
+            objref.signature);
+    ok(objref.flags == OBJREF_STANDARD, "objref.flags = %x\n", objref.flags);
+    ok(IsEqualIID(&objref.iid, &IID_IUnknown), "objref.iid = %s\n",
+            wine_dbgstr_guid(&objref.iid));
+    stdobjref = &objref.u_objref.u_standard.std;
+    ok(stdobjref->flags == 0, "stdobjref.flags = %d\n", stdobjref->flags);
+    ok(stdobjref->cPublicRefs == 5, "stdobjref.cPublicRefs = %d\n",
+            stdobjref->cPublicRefs);
+    dualstringarr = &objref.u_objref.u_standard.saResAddr;
+    ok(dualstringarr->wNumEntries == 0, "dualstringarr.wNumEntries = %d\n",
+            dualstringarr->wNumEntries);
+    ok(dualstringarr->wSecurityOffset == 0, "dualstringarr.wSecurityOffset = %d\n",
+            dualstringarr->wSecurityOffset);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    hr = IMarshal_UnmarshalInterface(marshal, stream, &IID_IUnknown, (void**)&unk);
+    ok_ole_success(hr, IMarshal_UnmarshalInterface);
+    IUnknown_Release(unk);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUnknown,
+            &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, IMarshal_MarshalInterface);
+
+    hr = IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL);
+    ok_ole_success(hr, IStream_Seek);
+    hr = IMarshal_ReleaseMarshalData(marshal, stream);
+    ok_ole_success(hr, IMarshal_ReleaseMarshalData);
+    IStream_Release(stream);
+
+    IMarshal_Release(marshal);
+}
 struct ncu_params
 {
     LPSTREAM stream;
 struct ncu_params
 {
     LPSTREAM stream;
@@ -2878,6 +3207,7 @@ static void test_freethreadedmarshaler(void)
     IStream *pStream;
     IUnknown *pProxy;
     static const LARGE_INTEGER llZero;
     IStream *pStream;
     IUnknown *pProxy;
     static const LARGE_INTEGER llZero;
+    CLSID clsid;
 
     cLocks = 0;
     hr = CoCreateFreeThreadedMarshaler(NULL, &pFTUnknown);
 
     cLocks = 0;
     hr = CoCreateFreeThreadedMarshaler(NULL, &pFTUnknown);
@@ -2891,6 +3221,12 @@ static void test_freethreadedmarshaler(void)
 
     /* inproc normal marshaling */
 
 
     /* inproc normal marshaling */
 
+    hr = IMarshal_GetUnmarshalClass(pFTMarshal, &IID_IClassFactory,
+            &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &clsid);
+    ok_ole_success(hr, IMarshal_GetUnmarshalClass);
+    ok(IsEqualIID(&clsid, &CLSID_InProcFreeMarshaler), "clsid = %s\n",
+            wine_dbgstr_guid(&clsid));
+
     hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
         &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
     ok_ole_success(hr, IMarshal_MarshalInterface);
     hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory,
         &Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
     ok_ole_success(hr, IMarshal_MarshalInterface);
@@ -2907,27 +3243,6 @@ static void test_freethreadedmarshaler(void)
 
     ok_no_locks();
 
 
     ok_no_locks();
 
-/* native doesn't allow us to unmarshal or release the stream data,
- * presumably because it wants us to call CoMarshalInterface instead */
-    if (0)
-    {
-    /* local normal marshaling */
-
-    IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
-    hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory, &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
-    ok_ole_success(hr, IMarshal_MarshalInterface);
-
-    ok_more_than_one_lock();
-
-    test_freethreadedmarshaldata(pStream, MSHCTX_LOCAL, &Test_ClassFactory, MSHLFLAGS_NORMAL);
-
-    IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
-    hr = IMarshal_ReleaseMarshalData(pFTMarshal, pStream);
-    ok_ole_success(hr, IMarshal_ReleaseMarshalData);
-
-    ok_no_locks();
-    }
-
     /* inproc table-strong marshaling */
 
     IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
     /* inproc table-strong marshaling */
 
     IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
@@ -3005,6 +3320,28 @@ static void test_freethreadedmarshaler(void)
 
     ok_no_locks();
 
 
     ok_no_locks();
 
+    /* local normal marshaling */
+
+    hr = IMarshal_GetUnmarshalClass(pFTMarshal, &IID_IClassFactory,
+            &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL, &clsid);
+    ok_ole_success(hr, IMarshal_GetUnmarshalClass);
+    ok(IsEqualIID(&clsid, &CLSID_StdMarshal), "clsid = %s\n",
+            wine_dbgstr_guid(&clsid));
+
+    IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
+    hr = IMarshal_MarshalInterface(pFTMarshal, pStream, &IID_IClassFactory, &Test_ClassFactory, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
+    ok_ole_success(hr, IMarshal_MarshalInterface);
+
+    ok_more_than_one_lock();
+
+    test_freethreadedmarshaldata(pStream, MSHCTX_LOCAL, &Test_ClassFactory, MSHLFLAGS_NORMAL);
+
+    IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
+    hr = CoReleaseMarshalData(pStream);
+    ok_ole_success(hr, CoReleaseMarshalData);
+
+    ok_no_locks();
+
     IStream_Release(pStream);
     IMarshal_Release(pFTMarshal);
 }
     IStream_Release(pStream);
     IMarshal_Release(pFTMarshal);
 }
@@ -3943,8 +4280,8 @@ static const char *debugstr_iid(REFIID riid)
     WCHAR bufferW[39];
     char buffer[39];
     LONG name_size = sizeof(name);
     WCHAR bufferW[39];
     char buffer[39];
     LONG name_size = sizeof(name);
-    StringFromGUID2(riid, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
-    WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
+    StringFromGUID2(riid, bufferW, ARRAY_SIZE(bufferW));
+    WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer, sizeof(buffer), NULL, NULL);
     if (RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_QUERY_VALUE, &hkeyInterface) != ERROR_SUCCESS)
     {
         memcpy(name, buffer, sizeof(buffer));
     if (RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_QUERY_VALUE, &hkeyInterface) != ERROR_SUCCESS)
     {
         memcpy(name, buffer, sizeof(buffer));
@@ -4323,6 +4660,9 @@ START_TEST(marshal)
     } while (with_external_conn);
 
     test_marshal_channel_buffer();
     } while (with_external_conn);
 
     test_marshal_channel_buffer();
+    test_StdMarshal_custom_marshaling();
+    test_DfMarshal_custom_marshaling();
+    test_CoGetStandardMarshal();
     test_hresult_marshaling();
     test_proxy_used_in_wrong_thread();
     test_message_filter();
     test_hresult_marshaling();
     test_proxy_used_in_wrong_thread();
     test_message_filter();
index 7b67dfd..5bcc136 100644 (file)
@@ -29,7 +29,6 @@
 #include "winbase.h"
 #include "objbase.h"
 #include "ocidl.h"
 #include "winbase.h"
 #include "objbase.h"
 #include "ocidl.h"
-#include "initguid.h"
 #include "comcat.h"
 #include "olectl.h"
 
 #include "comcat.h"
 #include "olectl.h"
 
@@ -38,7 +37,6 @@
 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
-#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
 
 #define CHECK_EXPECTED_METHOD(method_name) \
 do { \
 
 #define CHECK_EXPECTED_METHOD(method_name) \
 do { \
@@ -905,7 +903,7 @@ static void test_MkParseDisplayName(void)
     hr = CreateBindCtx(0, &pbc);
     ok_ole_success(hr, CreateBindCtx);
 
     hr = CreateBindCtx(0, &pbc);
     ok_ole_success(hr, CreateBindCtx);
 
-    for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
     {
         eaten = 0xdeadbeef;
         pmk = (IMoniker *)0xdeadbeef;
     {
         eaten = 0xdeadbeef;
         pmk = (IMoniker *)0xdeadbeef;
@@ -947,7 +945,7 @@ static void test_MkParseDisplayName(void)
     pmk = NULL;
     hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
     pmk = NULL;
     hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
-    ok(eaten == sizeof(wszDisplayName)/sizeof(WCHAR) - 1,
+    ok(eaten == ARRAY_SIZE(wszDisplayName) - 1,
         "Processed character count should have been 43 instead of %u\n", eaten);
     if (pmk)
     {
         "Processed character count should have been 43 instead of %u\n", eaten);
     if (pmk)
     {
@@ -969,7 +967,7 @@ static void test_MkParseDisplayName(void)
     pmk = NULL;
     hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
     pmk = NULL;
     hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
-    ok(eaten == sizeof(wszDisplayNameRunning)/sizeof(WCHAR) - 1,
+    ok(eaten == ARRAY_SIZE(wszDisplayNameRunning) - 1,
         "Processed character count should have been 15 instead of %u\n", eaten);
     if (pmk)
     {
         "Processed character count should have been 15 instead of %u\n", eaten);
     if (pmk)
     {
@@ -987,7 +985,7 @@ static void test_MkParseDisplayName(void)
     expected_display_name = wszDisplayNameProgId1;
     hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
     expected_display_name = wszDisplayNameProgId1;
     hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
-    ok(eaten == sizeof(wszDisplayNameProgId1)/sizeof(WCHAR) - 1,
+    ok(eaten == ARRAY_SIZE(wszDisplayNameProgId1) - 1,
         "Processed character count should have been 8 instead of %u\n", eaten);
     if (pmk)
     {
         "Processed character count should have been 8 instead of %u\n", eaten);
     if (pmk)
     {
@@ -999,7 +997,7 @@ static void test_MkParseDisplayName(void)
     expected_display_name = wszDisplayNameProgId2;
     hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
     expected_display_name = wszDisplayNameProgId2;
     hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
-    ok(eaten == sizeof(wszDisplayNameProgId2)/sizeof(WCHAR) - 1,
+    ok(eaten == ARRAY_SIZE(wszDisplayNameProgId2) - 1,
         "Processed character count should have been 8 instead of %u\n", eaten);
     if (pmk)
     {
         "Processed character count should have been 8 instead of %u\n", eaten);
     if (pmk)
     {
@@ -1021,7 +1019,8 @@ static void test_MkParseDisplayName(void)
 
     GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
     strcat(szDisplayNameFile, "\\kernel32.dll");
 
     GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
     strcat(szDisplayNameFile, "\\kernel32.dll");
-    len = MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
+    len = MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile,
+        ARRAY_SIZE(wszDisplayNameFile));
     hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
     ok(eaten == len - 1, "Processed character count should have been %d instead of %u\n", len - 1, eaten);
     hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
     ok(eaten == len - 1, "Processed character count should have been %d instead of %u\n", len - 1, eaten);
@@ -1034,7 +1033,8 @@ static void test_MkParseDisplayName(void)
 
     hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
 
     hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
     ok_ole_success(hr, MkParseDisplayName);
-    ok(eaten == sizeof(wszDisplayName)/sizeof(WCHAR) - 1, "Processed character count should have been 43 instead of %u\n", eaten);
+    ok(eaten == ARRAY_SIZE(wszDisplayName) - 1,
+        "Processed character count should have been 43 instead of %u\n", eaten);
 
     if (pmk)
     {
 
     if (pmk)
     {
@@ -1550,7 +1550,7 @@ static void test_file_monikers(void)
 
     trace("ACP is %u\n", GetACP());
 
 
     trace("ACP is %u\n", GetACP());
 
-    for (i = 0; i < COUNTOF(wszFile); ++i)
+    for (i = 0; i < ARRAY_SIZE(wszFile); ++i)
     {
         int j ;
         if (i == 2)
     {
         int j ;
         if (i == 2)
index dd9257d..3b289f7 100644 (file)
 
 #include "wine/test.h"
 
 
 #include "wine/test.h"
 
-#include "initguid.h"
-
-DEFINE_GUID(CLSID_Picture_Metafile,0x315,0,0,0xc0,0,0,0,0,0,0,0x46);
-DEFINE_GUID(CLSID_Picture_Dib,0x316,0,0,0xc0,0,0,0,0,0,0,0x46);
-DEFINE_GUID(CLSID_Picture_EnhMetafile,0x319,0,0,0xc0,0,0,0,0,0,0,0x46);
-
 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
 
 #define DEFINE_EXPECT(func) \
 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
 
 #define DEFINE_EXPECT(func) \
@@ -261,6 +255,21 @@ static void create_mfpict(STGMEDIUM *med)
     med->pUnkForRelease = NULL;
 }
 
     med->pUnkForRelease = NULL;
 }
 
+static void create_text(STGMEDIUM *med)
+{
+    HGLOBAL handle;
+    char *p;
+
+    handle = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, 5);
+    p = GlobalLock(handle);
+    strcpy(p, "test");
+    GlobalUnlock(handle);
+
+    med->tymed = TYMED_HGLOBAL;
+    U(med)->hGlobal = handle;
+    med->pUnkForRelease = NULL;
+}
+
 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
 {
     CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
 {
     CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
@@ -1494,6 +1503,12 @@ static HRESULT WINAPI DataObject_GetData( IDataObject *iface, FORMATETC *fmt_in,
             case CF_BITMAP:
                 create_bitmap( med );
                 return S_OK;
             case CF_BITMAP:
                 create_bitmap( med );
                 return S_OK;
+            case CF_ENHMETAFILE:
+                create_emf( med );
+                return S_OK;
+            case CF_TEXT:
+                create_text( med );
+                return S_OK;
             default:
                 trace( "unhandled fmt %d\n", fmt->cfFormat );
             }
             default:
                 trace( "unhandled fmt %d\n", fmt->cfFormat );
             }
@@ -1732,7 +1747,7 @@ static void test_data_cache(void)
         { NULL, 0 }
     };
 
         { NULL, 0 }
     };
 
-    GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
+    GetSystemDirectoryA(szSystemDir, ARRAY_SIZE(szSystemDir));
 
     expected_method_list = methods_cacheinitnew;
 
 
     expected_method_list = methods_cacheinitnew;
 
@@ -1864,7 +1879,7 @@ static void test_data_cache(void)
     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
     ok_ole_success(hr, "IOleCache_Cache");
 
     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
     ok_ole_success(hr, "IOleCache_Cache");
 
-    MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
+    MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, ARRAY_SIZE(wszPath));
     memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
 
     fmtetc.cfFormat = CF_METAFILEPICT;
     memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
 
     fmtetc.cfFormat = CF_METAFILEPICT;
@@ -2494,7 +2509,7 @@ static void test_data_cache_init(void)
         { &CLSID_Picture_EnhMetafile, 3, 1 }
     };
 
         { &CLSID_Picture_EnhMetafile, 3, 1 }
     };
 
-    for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(data); i++)
     {
         hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache );
         ok( hr == S_OK, "got %08x\n", hr );
     {
         hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache );
         ok( hr == S_OK, "got %08x\n", hr );
@@ -4080,6 +4095,8 @@ static void check_storage_contents(IStorage *stg, const struct storage_def *stg_
 
         *enumerated_streams += 1;
     }
 
         *enumerated_streams += 1;
     }
+
+    IEnumSTATSTG_Release(enumstg);
 }
 
 static HRESULT stgmedium_cmp(const STGMEDIUM *med1, STGMEDIUM *med2)
 }
 
 static HRESULT stgmedium_cmp(const STGMEDIUM *med1, STGMEDIUM *med2)
@@ -4545,7 +4562,7 @@ static void test_data_cache_contents(void)
         { &stg_def_9, &stg_def_9_saved },
     };
 
         { &stg_def_9, &stg_def_9_saved },
     };
 
-    for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(test_data); i++)
     {
         if (winetest_debug > 1)
             trace("start testing storage def %d\n", i);
     {
         if (winetest_debug > 1)
             trace("start testing storage def %d\n", i);
@@ -4597,6 +4614,175 @@ todo_wine_if(!(test_data[i].in == &stg_def_0 || test_data[i].in == &stg_def_4 ||
     }
 }
 
     }
 }
 
+static void test_OleCreateStaticFromData(void)
+{
+    HRESULT hr;
+    IOleObject *ole_obj = NULL;
+    IStorage *storage;
+    ILockBytes *ilb;
+    IPersist *persist;
+    CLSID clsid;
+    STATSTG statstg;
+    int enumerated_streams, matched_streams;
+    STGMEDIUM stgmed;
+    static FORMATETC dib_fmt[] =
+    {
+        { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
+        { 0 }
+    };
+    static FORMATETC emf_fmt[] =
+    {
+        { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF },
+        { 0 }
+    };
+    static FORMATETC text_fmt[] =
+    {
+        { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
+        { 0 }
+    };
+    static const struct expected_method methods_create_from_dib[] =
+    {
+        { "DataObject_EnumFormatEtc", TEST_TODO },
+        { "DataObject_GetDataHere", 0 },
+        { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE } },
+        { NULL }
+    };
+    static const struct expected_method methods_createstatic_from_dib[] =
+    {
+        { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+        { NULL }
+    };
+    static const struct expected_method methods_createstatic_from_emf[] =
+    {
+        { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
+        { NULL }
+    };
+    static const struct expected_method methods_createstatic_from_text[] =
+    {
+        { "DataObject_GetData", 0, { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
+        { NULL }
+    };
+    static struct storage_def stg_def_dib =
+    {
+        &CLSID_Picture_Dib, 3,
+        {{ "\1Ole", -1, 0, 0, NULL, 0 },
+         { "\1CompObj", -1, 0, 0, NULL, 0 },
+         { "CONTENTS", -1, 0, 0, NULL, 0 }}
+    };
+    static struct storage_def stg_def_emf =
+    {
+        &CLSID_Picture_EnhMetafile, 3,
+        {{ "\1Ole", -1, 0, 0, NULL, 0 },
+         { "\1CompObj", -1, 0, 0, NULL, 0 },
+         { "CONTENTS", -1, 0, 0, NULL, 0 }}
+    };
+
+
+    hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
+    ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr);
+    hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
+                                      0, &storage);
+    ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr);
+    ILockBytes_Release(ilb);
+
+    hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT,
+                                 dib_fmt, NULL, NULL, (void **)&ole_obj);
+    ok(hr == E_INVALIDARG, "OleCreateStaticFromData should fail: 0x%08x.\n", hr);
+
+    hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT,
+                                 dib_fmt, NULL, storage, NULL);
+    ok(hr == E_INVALIDARG, "OleCreateStaticFromData should fail: 0x%08x.\n", hr);
+
+    /* CF_DIB */
+    g_dataobject_fmts = dib_fmt;
+    expected_method_list = methods_createstatic_from_dib;
+    hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT,
+                                 dib_fmt, NULL, storage, (void **)&ole_obj);
+    ok(hr == S_OK, "OleCreateStaticFromData failed: 0x%08x.\n", hr);
+    hr = IOleObject_QueryInterface(ole_obj, &IID_IPersist, (void **)&persist);
+    ok(hr == S_OK, "IOleObject_QueryInterface failed: 0x%08x.\n", hr);
+    hr = IPersist_GetClassID(persist, &clsid);
+    ok(hr == S_OK, "IPersist_GetClassID failed: 0x%08x.\n", hr);
+    ok(IsEqualCLSID(&clsid, &CLSID_Picture_Dib), "Got wrong clsid: %s, expected: %s.\n",
+       wine_dbgstr_guid(&clsid), wine_dbgstr_guid(&CLSID_Picture_Dib));
+    hr = IStorage_Stat(storage, &statstg, STATFLAG_NONAME);
+    ok_ole_success(hr, "IStorage_Stat");
+    ok(IsEqualCLSID(&CLSID_Picture_Dib, &statstg.clsid), "Wrong CLSID in storage.\n");
+    enumerated_streams = matched_streams = -1;
+    get_stgmedium(CF_DIB, &stgmed);
+    get_stgdef(&stg_def_dib, CF_DIB, &stgmed, 2);
+    check_storage_contents(storage, &stg_def_dib, &enumerated_streams, &matched_streams);
+    ok(enumerated_streams == matched_streams, "enumerated %d != matched %d\n",
+       enumerated_streams, matched_streams);
+    ok(enumerated_streams == stg_def_dib.stream_count, "created %d != def streams %d\n",
+       enumerated_streams, stg_def_dib.stream_count);
+    ReleaseStgMedium(&stgmed);
+    IPersist_Release(persist);
+    IStorage_Release(storage);
+    IOleObject_Release(ole_obj);
+
+    /* CF_ENHMETAFILE */
+    hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
+    ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr);
+    hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
+                                      0, &storage);
+    ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr);
+    ILockBytes_Release(ilb);
+    g_dataobject_fmts = emf_fmt;
+    expected_method_list = methods_createstatic_from_emf;
+    hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT,
+                                 emf_fmt, NULL, storage, (void **)&ole_obj);
+    ok(hr == S_OK, "OleCreateStaticFromData failed: 0x%08x.\n", hr);
+    hr = IOleObject_QueryInterface(ole_obj, &IID_IPersist, (void **)&persist);
+    ok(hr == S_OK, "IOleObject_QueryInterface failed: 0x%08x.\n", hr);
+    hr = IPersist_GetClassID(persist, &clsid);
+    ok(hr == S_OK, "IPersist_GetClassID failed: 0x%08x.\n", hr);
+    ok(IsEqualCLSID(&clsid, &CLSID_Picture_EnhMetafile), "Got wrong clsid: %s, expected: %s.\n",
+       wine_dbgstr_guid(&clsid), wine_dbgstr_guid(&CLSID_Picture_EnhMetafile));
+    hr = IStorage_Stat(storage, &statstg, STATFLAG_NONAME);
+    ok_ole_success(hr, "IStorage_Stat");
+    ok(IsEqualCLSID(&CLSID_Picture_EnhMetafile, &statstg.clsid), "Wrong CLSID in storage.\n");
+    enumerated_streams = matched_streams = -1;
+    get_stgmedium(CF_ENHMETAFILE, &stgmed);
+    get_stgdef(&stg_def_emf, CF_ENHMETAFILE, &stgmed, 2);
+    check_storage_contents(storage, &stg_def_emf, &enumerated_streams, &matched_streams);
+    ok(enumerated_streams == matched_streams, "enumerated %d != matched %d\n",
+       enumerated_streams, matched_streams);
+    ok(enumerated_streams == stg_def_emf.stream_count, "created %d != def streams %d\n",
+       enumerated_streams, stg_def_emf.stream_count);
+    ReleaseStgMedium(&stgmed);
+    IPersist_Release(persist);
+    IStorage_Release(storage);
+    IOleObject_Release(ole_obj);
+
+    /* CF_TEXT */
+    hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
+    ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr);
+    hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
+                                      0, &storage);
+    ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr);
+    ILockBytes_Release(ilb);
+    g_dataobject_fmts = text_fmt;
+    expected_method_list = methods_createstatic_from_text;
+    hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT,
+                                 text_fmt, NULL, storage, (void **)&ole_obj);
+    ok(hr == DV_E_CLIPFORMAT, "OleCreateStaticFromData should fail: 0x%08x.\n", hr);
+    IStorage_Release(storage);
+
+    hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
+    ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr);
+    hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE,
+                                      0, &storage);
+    ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr);
+    ILockBytes_Release(ilb);
+    g_dataobject_fmts = dib_fmt;
+    expected_method_list = methods_create_from_dib;
+    hr = OleCreateFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, dib_fmt, NULL,
+                           storage, (void **)&ole_obj);
+    todo_wine ok(hr == DV_E_FORMATETC, "OleCreateFromData should failed: 0x%08x.\n", hr);
+    IStorage_Release(storage);
+}
+
 START_TEST(ole2)
 {
     DWORD dwRegister;
 START_TEST(ole2)
 {
     DWORD dwRegister;
@@ -4647,6 +4833,7 @@ START_TEST(ole2)
     test_data_cache_save();
     test_data_cache_save_data();
     test_data_cache_contents();
     test_data_cache_save();
     test_data_cache_save_data();
     test_data_cache_contents();
+    test_OleCreateStaticFromData();
 
     CoUninitialize();
 }
 
     CoUninitialize();
 }
index 77abda4..2f5a3ca 100644 (file)
@@ -30,9 +30,6 @@
 
 #include <initguid.h>
 DEFINE_GUID(CLSID_WineTestObject, 0xdeadbeef,0xdead,0xbeef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef);
 
 #include <initguid.h>
 DEFINE_GUID(CLSID_WineTestObject, 0xdeadbeef,0xdead,0xbeef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef);
-#ifndef CLSID_IdentityUnmarshal
-DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
-#endif
 DEFINE_GUID(CLSID_UnknownUnmarshal,0x4c1e39e1,0xe3e3,0x4296,0xaa,0x86,0xec,0x93,0x8d,0x89,0x6e,0x92);
 
 struct winetest_info
 DEFINE_GUID(CLSID_UnknownUnmarshal,0x4c1e39e1,0xe3e3,0x4296,0xaa,0x86,0xec,0x93,0x8d,0x89,0x6e,0x92);
 
 struct winetest_info
@@ -69,7 +66,7 @@ static const char *debugstr_guid(const GUID *guid)
 
     if (!guid) return "(null)";
 
 
     if (!guid) return "(null)";
 
-    for (i = 0; i < sizeof(guid_name)/sizeof(guid_name[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(guid_name); i++)
     {
         if (IsEqualIID(guid, guid_name[i].guid))
             return guid_name[i].name;
     {
         if (IsEqualIID(guid, guid_name[i].guid))
             return guid_name[i].name;
index ade45fb..97c4eec 100644 (file)
@@ -189,7 +189,7 @@ static void test_validtypes(void)
     ok(U(propvar).uhVal.QuadPart == 0, "expected 0, got %#x/%#x\n",
        U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
 
     ok(U(propvar).uhVal.QuadPart == 0, "expected 0, got %#x/%#x\n",
        U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
 
-    for (i = 0; i < sizeof(valid_types)/sizeof(valid_types[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(valid_types); i++)
     {
         VARTYPE vt;
 
     {
         VARTYPE vt;
 
index c6d7d3e..24ae03e 100644 (file)
 #define COBJMACROS
 #include "objbase.h"
 #include "wine/test.h"
 #define COBJMACROS
 #include "objbase.h"
 #include "wine/test.h"
-#include "initguid.h"
-
-DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
-DEFINE_GUID(FMTID_SummaryInformation,0xF29F85E0,0x4FF9,0x1068,0xAB,0x91,0x08,0x00,0x2B,0x27,0xB3,0xD9);
-DEFINE_GUID(FMTID_DocSummaryInformation,0xD5CDD502,0x2E9C,0x101B,0x93,0x97,0x08,0x00,0x2B,0x2C,0xF9,0xAE);
-DEFINE_GUID(FMTID_UserDefinedProperties,0xD5CDD505,0x2E9C,0x101B,0x93,0x97,0x08,0x00,0x2B,0x2C,0xF9,0xAE);
 
 #ifndef PID_BEHAVIOR
 #define PID_BEHAVIOR 0x80000003
 
 #ifndef PID_BEHAVIOR
 #define PID_BEHAVIOR 0x80000003
index 89ffc95..2467410 100644 (file)
@@ -21,7 +21,9 @@
 #include <stdio.h>
 
 #define COBJMACROS
 #include <stdio.h>
 
 #define COBJMACROS
-#ifndef __REACTOS__
+#ifdef __REACTOS__
+#define CONST_VTABLE
+#else
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #endif
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
 #endif
@@ -222,7 +224,7 @@ static HRESULT WINAPI TestLockBytes_Stat(ILockBytes *iface,
     return S_OK;
 }
 
     return S_OK;
 }
 
-static /* const */ ILockBytesVtbl TestLockBytes_Vtbl = {
+static const ILockBytesVtbl TestLockBytes_Vtbl = {
     TestLockBytes_QueryInterface,
     TestLockBytes_AddRef,
     TestLockBytes_Release,
     TestLockBytes_QueryInterface,
     TestLockBytes_AddRef,
     TestLockBytes_Release,
@@ -2086,9 +2088,9 @@ static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD
 {
     int i, j, idx = 0;
 
 {
     int i, j, idx = 0;
 
-    for (i = 0; i < sizeof(access_modes)/sizeof(access_modes[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(access_modes); i++)
     {
     {
-        for (j = 0; j < sizeof(share_modes)/sizeof(share_modes[0]); j++)
+        for (j = 0; j < ARRAY_SIZE(share_modes); j++)
         {
             DWORD lasterr;
             HANDLE hfile;
         {
             DWORD lasterr;
             HANDLE hfile;
@@ -3492,7 +3494,7 @@ static void test_locking(void)
     IStorage *stg;
     HRESULT hr;
 
     IStorage *stg;
     HRESULT hr;
 
-    for (i=0; i<sizeof(lock_tests)/sizeof(lock_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(lock_tests); i++)
     {
         const struct lock_test *current = &lock_tests[i];
         BOOL any_failure = FALSE;
     {
         const struct lock_test *current = &lock_tests[i];
         BOOL any_failure = FALSE;
index 3919395..bbe7fb5 100644 (file)
@@ -1067,7 +1067,7 @@ static void test_marshal_SNB(void)
     ok(*(ULONG*)wiresnb->rgString == wiresnb->ulCntStr, "got %u\n", *(ULONG*)wiresnb->rgString);
     dataW = &wiresnb->rgString[2];
     ok(!lstrcmpW(dataW, str1W), "marshalled string 0: %s\n", wine_dbgstr_w(dataW));
     ok(*(ULONG*)wiresnb->rgString == wiresnb->ulCntStr, "got %u\n", *(ULONG*)wiresnb->rgString);
     dataW = &wiresnb->rgString[2];
     ok(!lstrcmpW(dataW, str1W), "marshalled string 0: %s\n", wine_dbgstr_w(dataW));
-    dataW += sizeof(str1W)/sizeof(WCHAR);
+    dataW += ARRAY_SIZE(str1W);
     ok(!lstrcmpW(dataW, str2W), "marshalled string 1: %s\n", wine_dbgstr_w(dataW));
 
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
     ok(!lstrcmpW(dataW, str2W), "marshalled string 1: %s\n", wine_dbgstr_w(dataW));
 
     init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);