Author: akhaldi
Date: Sun Jul 19 23:12:15 2015
New Revision: 68470
URL:
http://svn.reactos.org/svn/reactos?rev=68470&view=rev
Log:
[OLE32_WINETEST] Sync with Wine Staging 1.7.47. CORE-9924
Modified:
trunk/rostests/winetests/ole32/CMakeLists.txt
trunk/rostests/winetests/ole32/clipboard.c
trunk/rostests/winetests/ole32/compobj.c
trunk/rostests/winetests/ole32/dragdrop.c
trunk/rostests/winetests/ole32/ole2.c
trunk/rostests/winetests/ole32/storage32.c
trunk/rostests/winetests/ole32/usrmarshal.c
Modified: trunk/rostests/winetests/ole32/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/CMakeList…
==============================================================================
--- trunk/rostests/winetests/ole32/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/CMakeLists.txt [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -22,4 +22,9 @@
target_link_libraries(ole32_winetest uuid)
set_module_type(ole32_winetest win32cui)
add_importlibs(ole32_winetest oleaut32 ole32 user32 gdi32 advapi32 msvcrt kernel32)
+
+if(MSVC)
+ add_importlibs(ole32_winetest ntdll)
+endif()
+
add_cd_file(TARGET ole32_winetest DESTINATION reactos/bin FOR all)
Modified: trunk/rostests/winetests/ole32/clipboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/clipboard…
==============================================================================
--- trunk/rostests/winetests/ole32/clipboard.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/clipboard.c [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -102,7 +102,7 @@
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid,
&IID_IEnumFORMATETC)) {
IEnumFORMATETC_AddRef(iface);
- *ppvObj = This;
+ *ppvObj = &This->IEnumFORMATETC_iface;
return S_OK;
}
*ppvObj = NULL;
@@ -135,7 +135,8 @@
EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
ULONG count, i;
- trace("next: count %d cur %d\n", celt, This->cur);
+ if (winetest_debug > 1)
+ trace("next: count %d cur %d\n", celt, This->cur);
if(!rgelt)
return E_INVALIDARG;
@@ -207,7 +208,7 @@
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject))
{
IDataObject_AddRef(iface);
- *ppvObj = This;
+ *ppvObj = &This->IDataObject_iface;
return S_OK;
}
*ppvObj = NULL;
Modified: trunk/rostests/winetests/ole32/compobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/compobj.c…
==============================================================================
--- trunk/rostests/winetests/ole32/compobj.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/compobj.c [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -1563,7 +1563,7 @@
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
GetExitCodeThread(thread, &exitcode);
hr = exitcode;
- ok(hr == RPC_E_WRONG_THREAD, "CoRevokeClassObject called from different "
+ ok(hr == RPC_E_WRONG_THREAD || broken(hr == S_OK) /* win8 */,
"CoRevokeClassObject called from different "
"thread to where registered should return RPC_E_WRONG_THREAD instead of
0x%08x\n", hr);
thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
@@ -1973,7 +1973,12 @@
ok(lr == ERROR_SUCCESS, "Couldn't open CLSID key\n");
lr = RegCreateKeyExA(clsidkey, deadbeefA, 0, NULL, 0, KEY_WRITE, NULL,
&deadbeefkey, NULL);
- ok(lr == ERROR_SUCCESS, "Couldn't create class key\n");
+ if (lr) {
+ win_skip("CoGetTreatAsClass() tests will be skipped (failed to create a test
key, error %d)\n",
+ GetLastError());
+ RegCloseKey(clsidkey);
+ return;
+ }
hr = pCoTreatAsClass(&deadbeef, &deadbeef);
ok(hr == REGDB_E_WRITEREGDB, "CoTreatAsClass gave wrong error: %08x\n",
hr);
Modified: trunk/rostests/winetests/ole32/dragdrop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/dragdrop.…
==============================================================================
--- trunk/rostests/winetests/ole32/dragdrop.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/dragdrop.c [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -452,13 +452,16 @@
ok(droptarget_refs >= 1, "DropTarget refs should be at least one\n");
OleUninitialize();
- ok(droptarget_refs >= 1, "DropTarget refs should be at least one\n");
-
- hr = RevokeDragDrop(hwnd);
- ok_ole_success(hr, "RevokeDragDrop");
- ok(droptarget_refs == 0 ||
- broken(droptarget_refs == 1), /* NT4 */
- "DropTarget refs should be zero not %d\n", droptarget_refs);
+
+ /* Win 8 releases the ref in OleUninitialize() */
+ if (droptarget_refs >= 1)
+ {
+ hr = RevokeDragDrop(hwnd);
+ ok_ole_success(hr, "RevokeDragDrop");
+ ok(droptarget_refs == 0 ||
+ broken(droptarget_refs == 1), /* NT4 */
+ "DropTarget refs should be zero not %d\n", droptarget_refs);
+ }
hr = RevokeDragDrop(NULL);
ok(hr == DRAGDROP_E_INVALIDHWND, "RevokeDragDrop with NULL hwnd should return
DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr);
Modified: trunk/rostests/winetests/ole32/ole2.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/ole2.c?re…
==============================================================================
--- trunk/rostests/winetests/ole32/ole2.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/ole2.c [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -1688,6 +1688,113 @@
IStorage_Release(pStorage);
}
+
+static const WCHAR CONTENTS[] =
{'C','O','N','T','E','N','T','S',0};
+
+/* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
+static BYTE dib[] =
+{
+ 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
+
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
+ 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+static IStorage *create_storage( int num )
+{
+ IStorage *stg;
+ IStream *stm;
+ HRESULT hr;
+ ULONG written;
+
+ hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE |
STGM_DELETEONRELEASE, 0, &stg );
+ ok( hr == S_OK, "got %08x\n", hr);
+ hr = IStorage_SetClass( stg, &CLSID_Picture_Dib );
+ ok( hr == S_OK, "got %08x\n", hr);
+ hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE |
STGM_CREATE, 0, 0, &stm );
+ ok( hr == S_OK, "got %08x\n", hr);
+ if (num == 1) /* Set biXPelsPerMeter = 0 */
+ {
+ dib[0x26] = 0;
+ dib[0x27] = 0;
+ }
+ hr = IStream_Write( stm, dib, sizeof(dib), &written );
+ ok( hr == S_OK, "got %08x\n", hr);
+ IStream_Release( stm );
+ return stg;
+}
+
+static void test_data_cache_dib_contents_stream(int num)
+{
+ HRESULT hr;
+ IUnknown *unk;
+ IPersistStorage *persist;
+ IDataObject *data;
+ IViewObject2 *view;
+ IStorage *stg;
+ FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM med;
+ CLSID cls;
+ SIZEL sz;
+
+ hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void
*)&unk );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void *)&persist );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void *)&data );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void *)&view );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+
+ stg = create_storage( num );
+
+ hr = IPersistStorage_Load( persist, stg );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ IStorage_Release( stg );
+
+ hr = IPersistStorage_GetClassID( persist, &cls );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n"
);
+
+ hr = IDataObject_GetData( data, &fmt, &med );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ if (SUCCEEDED(hr))
+ {
+ ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed );
+ ReleaseStgMedium( &med );
+ }
+
+ hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
+ ok( SUCCEEDED(hr), "got %08x\n", hr );
+ if (num == 0)
+ {
+ ok( sz.cx == 1000, "got %d\n", sz.cx );
+ ok( sz.cy == 250, "got %d\n", sz.cy );
+ }
+ else
+ {
+ HDC hdc = GetDC( 0 );
+ LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
+ LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );
+ ok( sz.cx == x, "got %d %d\n", sz.cx, x );
+ ok( sz.cy == y, "got %d %d\n", sz.cy, y );
+
+ ReleaseDC( 0, hdc );
+ }
+
+ IViewObject2_Release( view );
+ IDataObject_Release( data );
+ IPersistStorage_Release( persist );
+ IUnknown_Release( unk );
+}
+
static void test_default_handler(void)
{
HRESULT hr;
@@ -1970,14 +2077,90 @@
Unknown_Release
};
+static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void
**ppv)
+{
+ *ppv = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown) ||
+ IsEqualIID(riid, &IID_IRunnableObject)) {
+ *ppv = iface;
+ }
+
+ if (*ppv)
+ {
+ IUnknown_AddRef((IUnknown *)*ppv);
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI OleRun_Release(IRunnableObject *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid)
+{
+ ok(0, "unxpected\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx)
+{
+ ok(ctx == NULL, "got %p\n", ctx);
+ return 0xdeadc0de;
+}
+
+static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface)
+{
+ ok(0, "unxpected\n");
+ return FALSE;
+}
+
+static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock,
+ BOOL last_unlock_closes)
+{
+ ok(0, "unxpected\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained)
+{
+ ok(0, "unxpected\n");
+ return E_NOTIMPL;
+}
+
+static const IRunnableObjectVtbl oleruntestvtbl =
+{
+ OleRun_QueryInterface,
+ OleRun_AddRef,
+ OleRun_Release,
+ OleRun_GetRunningClass,
+ OleRun_Run,
+ OleRun_IsRunning,
+ OleRun_LockRunning,
+ OleRun_SetContainedObject
+};
+
static IUnknown unknown = { &UnknownVtbl };
+static IRunnableObject testrunnable = { &oleruntestvtbl };
static void test_OleRun(void)
{
HRESULT hr;
+ /* doesn't support IRunnableObject */
hr = OleRun(&unknown);
ok(hr == S_OK, "OleRun failed 0x%08x\n", hr);
+
+ hr = OleRun((IUnknown*)&testrunnable);
+ ok(hr == 0xdeadc0de, "got 0x%08x\n", hr);
}
static void test_OleLockRunning(void)
@@ -2393,6 +2576,8 @@
ok_ole_success(hr, "CoRevokeClassObject");
test_data_cache();
+ test_data_cache_dib_contents_stream( 0 );
+ test_data_cache_dib_contents_stream( 1 );
test_default_handler();
test_runnable();
test_OleRun();
Modified: trunk/rostests/winetests/ole32/storage32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/storage32…
==============================================================================
--- trunk/rostests/winetests/ole32/storage32.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/storage32.c [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -59,6 +59,201 @@
WideCharToMultiByte(CP_ACP, 0, strw1, -1, stra1, sizeof(stra1), NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, strw2, -1, stra2, sizeof(stra2), NULL, NULL);
return lstrcmpA(stra1, stra2);
+}
+
+typedef struct TestLockBytes {
+ ILockBytes ILockBytes_iface;
+ LONG ref;
+ BYTE* contents;
+ ULONG size;
+ ULONG buffer_size;
+ HRESULT lock_hr;
+ ULONG locks_supported;
+ ULONG lock_called;
+} TestLockBytes;
+
+static inline TestLockBytes *impl_from_ILockBytes(ILockBytes *iface)
+{
+ return CONTAINING_RECORD(iface, TestLockBytes, ILockBytes_iface);
+}
+
+static HRESULT WINAPI TestLockBytes_QueryInterface(ILockBytes *iface, REFIID iid,
+ void **ppv)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+
+ if (!ppv) return E_INVALIDARG;
+
+ if (IsEqualIID(&IID_IUnknown, iid) ||
+ IsEqualIID(&IID_ILockBytes, iid))
+ *ppv = &This->ILockBytes_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI TestLockBytes_AddRef(ILockBytes *iface)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ return ref;
+}
+
+static ULONG WINAPI TestLockBytes_Release(ILockBytes *iface)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+ return ref;
+}
+
+static HRESULT WINAPI TestLockBytes_ReadAt(ILockBytes *iface,
+ ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ ULONG dummy;
+
+ if (!pv) return E_INVALIDARG;
+
+ if (!pcbRead) pcbRead = &dummy;
+
+ if (ulOffset.QuadPart >= This->size)
+ {
+ *pcbRead = 0;
+ return S_OK;
+ }
+
+ cb = min(cb, This->size - ulOffset.QuadPart);
+
+ *pcbRead = cb;
+ memcpy(pv, &This->contents[ulOffset.QuadPart], cb);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_WriteAt(ILockBytes *iface,
+ ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ HRESULT hr;
+ ULONG dummy;
+
+ if (!pv) return E_INVALIDARG;
+
+ if (!pcbWritten) pcbWritten = &dummy;
+
+ if (ulOffset.QuadPart + cb > This->size)
+ {
+ ULARGE_INTEGER new_size;
+ new_size.QuadPart = ulOffset.QuadPart + cb;
+ hr = ILockBytes_SetSize(iface, new_size);
+ if (FAILED(hr)) return hr;
+ }
+
+ *pcbWritten = cb;
+ memcpy(&This->contents[ulOffset.QuadPart], pv, cb);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_Flush(ILockBytes *iface)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_SetSize(ILockBytes *iface,
+ ULARGE_INTEGER cb)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+
+ if (This->buffer_size < cb.QuadPart)
+ {
+ ULONG new_buffer_size = max(This->buffer_size * 2, cb.QuadPart);
+ BYTE* new_buffer = HeapAlloc(GetProcessHeap(), 0, new_buffer_size);
+ if (!new_buffer) return E_OUTOFMEMORY;
+ memcpy(new_buffer, This->contents, This->size);
+ HeapFree(GetProcessHeap(), 0, This->contents);
+ This->contents = new_buffer;
+ }
+
+ if (cb.QuadPart > This->size)
+ memset(&This->contents[This->size], 0, cb.QuadPart - This->size);
+
+ This->size = cb.QuadPart;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_LockRegion(ILockBytes *iface,
+ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ This->lock_called++;
+ return This->lock_hr;
+}
+
+static HRESULT WINAPI TestLockBytes_UnlockRegion(ILockBytes *iface,
+ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ return This->lock_hr;
+}
+
+static HRESULT WINAPI TestLockBytes_Stat(ILockBytes *iface,
+ STATSTG *pstatstg, DWORD grfStatFlag)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ static const WCHAR dummy_name[] =
{'d','u','m','m','y',0};
+
+ if (!pstatstg) return E_INVALIDARG;
+
+ memset(pstatstg, 0, sizeof(STATSTG));
+
+ if (!(grfStatFlag & STATFLAG_NONAME))
+ {
+ pstatstg->pwcsName = CoTaskMemAlloc(sizeof(dummy_name));
+ if (!pstatstg->pwcsName) return E_OUTOFMEMORY;
+ memcpy(pstatstg->pwcsName, dummy_name, sizeof(dummy_name));
+ }
+
+ pstatstg->type = STGTY_LOCKBYTES;
+ pstatstg->cbSize.QuadPart = This->size;
+ pstatstg->grfLocksSupported = This->locks_supported;
+
+ return S_OK;
+}
+
+static ILockBytesVtbl TestLockBytes_Vtbl = {
+ TestLockBytes_QueryInterface,
+ TestLockBytes_AddRef,
+ TestLockBytes_Release,
+ TestLockBytes_ReadAt,
+ TestLockBytes_WriteAt,
+ TestLockBytes_Flush,
+ TestLockBytes_SetSize,
+ TestLockBytes_LockRegion,
+ TestLockBytes_UnlockRegion,
+ TestLockBytes_Stat
+};
+
+static void CreateTestLockBytes(TestLockBytes **This)
+{
+ *This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**This));
+
+ if (*This)
+ {
+ (*This)->ILockBytes_iface.lpVtbl = &TestLockBytes_Vtbl;
+ (*This)->ref = 1;
+ }
+}
+
+static void DeleteTestLockBytes(TestLockBytes *This)
+{
+ ok(This->ILockBytes_iface.lpVtbl == &TestLockBytes_Vtbl, "test lock bytes
%p deleted with incorrect vtable\n", This);
+ ok(This->ref == 1, "test lock bytes %p deleted with %i references instead of
1\n", This, This->ref);
+ HeapFree(GetProcessHeap(), 0, This->contents);
+ HeapFree(GetProcessHeap(), 0, This);
}
static void test_hglobal_storage_stat(void)
@@ -3157,22 +3352,22 @@
BOOL todo;
};
-static const int priority_locked_bytes[] = { 0x58, 0x81, 0x93, -1 };
-static const int rwex_locked_bytes[] = { 0x93, 0xa7, 0xbb, 0xcf, -1 };
-static const int rw_locked_bytes[] = { 0x93, 0xa7, -1 };
-static const int nosn_locked_bytes[] = { 0x6c, 0x93, 0xa7, 0xcf, -1 };
-static const int rwdw_locked_bytes[] = { 0x93, 0xa7, 0xcf, -1 };
-static const int wodw_locked_bytes[] = { 0xa7, 0xcf, -1 };
-static const int tr_locked_bytes[] = { 0x93, -1 };
+static const int priority_locked_bytes[] = { 0x158, 0x181, 0x193, -1 };
+static const int rwex_locked_bytes[] = { 0x193, 0x1a7, 0x1bb, 0x1cf, -1 };
+static const int rw_locked_bytes[] = { 0x193, 0x1a7, -1 };
+static const int nosn_locked_bytes[] = { 0x16c, 0x193, 0x1a7, 0x1cf, -1 };
+static const int rwdw_locked_bytes[] = { 0x193, 0x1a7, 0x1cf, -1 };
+static const int wodw_locked_bytes[] = { 0x1a7, 0x1cf, -1 };
+static const int tr_locked_bytes[] = { 0x193, -1 };
static const int no_locked_bytes[] = { -1 };
-static const int roex_locked_bytes[] = { 0x93, 0xbb, 0xcf, -1 };
-
-static const int rwex_fail_ranges[] = { 0x93,0xe3, -1 };
-static const int rw_fail_ranges[] = { 0xbb,0xe3, -1 };
-static const int rwdw_fail_ranges[] = { 0xa7,0xe3, -1 };
-static const int dw_fail_ranges[] = { 0xa7,0xcf, -1 };
-static const int tr_fail_ranges[] = { 0xbb,0xcf, -1 };
-static const int pr_fail_ranges[] = { 0x80,0x81, 0xbb,0xcf, -1 };
+static const int roex_locked_bytes[] = { 0x193, 0x1bb, 0x1cf, -1 };
+
+static const int rwex_fail_ranges[] = { 0x193,0x1e3, -1 };
+static const int rw_fail_ranges[] = { 0x1bb,0x1e3, -1 };
+static const int rwdw_fail_ranges[] = { 0x1a7,0x1e3, -1 };
+static const int dw_fail_ranges[] = { 0x1a7,0x1cf, -1 };
+static const int tr_fail_ranges[] = { 0x1bb,0x1cf, -1 };
+static const int pr_fail_ranges[] = { 0x180,0x181, 0x1bb,0x1cf, -1 };
static const int roex_fail_ranges[] = { 0x0,-1 };
static const struct lock_test lock_tests[] = {
@@ -3189,8 +3384,8 @@
{ STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_DENY_WRITE, FALSE,
GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, rwdw_locked_bytes, rwdw_fail_ranges, FALSE
},
{ STGM_READ|STGM_SHARE_DENY_WRITE, FALSE, GENERIC_READ, FILE_SHARE_READ,
no_locked_bytes, dw_fail_ranges, TRUE },
{ STGM_READ|STGM_TRANSACTED, FALSE, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
tr_locked_bytes, tr_fail_ranges, FALSE },
- { STGM_READ|STGM_SHARE_EXCLUSIVE, FALSE, GENERIC_READ, FILE_SHARE_READ,
roex_locked_bytes, roex_fail_ranges, TRUE },
- { STGM_READ|STGM_SHARE_EXCLUSIVE|STGM_TRANSACTED, FALSE, GENERIC_READ,
FILE_SHARE_READ, roex_locked_bytes, roex_fail_ranges, TRUE },
+ { STGM_READ|STGM_SHARE_EXCLUSIVE, FALSE, GENERIC_READ, FILE_SHARE_READ,
roex_locked_bytes, roex_fail_ranges, FALSE },
+ { STGM_READ|STGM_SHARE_EXCLUSIVE|STGM_TRANSACTED, FALSE, GENERIC_READ,
FILE_SHARE_READ, roex_locked_bytes, roex_fail_ranges, FALSE },
};
static BOOL can_open(LPCWSTR filename, DWORD access, DWORD sharing)
@@ -3317,7 +3512,7 @@
ol.u.s.OffsetHigh = 0;
ol.hEvent = NULL;
- for (ol.u.s.Offset = 0x7fffff00; ol.u.s.Offset != 0x80000000;
ol.u.s.Offset++)
+ for (ol.u.s.Offset = 0x7ffffe00; ol.u.s.Offset != 0x80000000;
ol.u.s.Offset++)
{
if (LockFileEx(hfile, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
0, 1, 0, &ol))
locked = FALSE;
@@ -3329,7 +3524,7 @@
UnlockFileEx(hfile, 0, 1, 0, &ol);
- if ((ol.u.s.Offset&0xff) == *next_lock)
+ if ((ol.u.s.Offset&0x1ff) == *next_lock)
{
expect_locked = TRUE;
next_lock++;
@@ -3366,14 +3561,17 @@
ol.u.s.OffsetHigh = 0;
ol.hEvent = NULL;
- for (ol.u.s.Offset = 0x7fffff00; ol.u.s.Offset != 0x80000000;
ol.u.s.Offset++)
+ for (ol.u.s.Offset = 0x7ffffe00; ol.u.s.Offset != 0x80000000;
ol.u.s.Offset++)
{
if (ol.u.s.Offset == 0x7fffff92 ||
(ol.u.s.Offset == 0x7fffff80 && current->stg_mode ==
(STGM_TRANSACTED|STGM_READWRITE)) ||
(ol.u.s.Offset == 0x7fffff80 && current->stg_mode ==
(STGM_TRANSACTED|STGM_READ)))
continue; /* This makes opens hang */
- LockFileEx(hfile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ol);
+ if (ol.u.s.Offset < 0x7fffff00)
+ LockFileEx(hfile, 0, 0, 1, 0, &ol);
+ else
+ LockFileEx(hfile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ol);
hr = StgOpenStorage(filename, NULL, current->stg_mode, NULL, 0,
&stg);
ok(hr == S_OK || hr == STG_E_LOCKVIOLATION || hr == STG_E_SHAREVIOLATION,
"failed with unexpected hr %x\n", hr);
@@ -3383,11 +3581,11 @@
failed = FAILED(hr);
- if (!expect_failed && (ol.u.s.Offset&0xff) == next_range[0])
+ if (!expect_failed && (ol.u.s.Offset&0x1ff) ==
next_range[0])
{
expect_failed = TRUE;
}
- else if (expect_failed && (ol.u.s.Offset&0xff) ==
next_range[1])
+ else if (expect_failed && (ol.u.s.Offset&0x1ff) ==
next_range[1])
{
expect_failed = FALSE;
next_range += 2;
@@ -3644,6 +3842,54 @@
CloseHandle(hfile);
DeleteFileA(filenameA);
+}
+
+static void test_custom_lockbytes(void)
+{
+ static const WCHAR stmname[] = {
'C','O','N','T','E','N','T','S',0
};
+ TestLockBytes* lockbytes;
+ HRESULT hr;
+ IStorage* stg;
+ IStream* stm;
+
+ CreateTestLockBytes(&lockbytes);
+
+ hr = StgCreateDocfileOnILockBytes(&lockbytes->ILockBytes_iface,
STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED, 0, &stg);
+ ok(hr==S_OK, "StgCreateDocfileOnILockBytes failed %x\n", hr);
+
+ hr = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0,
&stm);
+ ok(hr==S_OK, "IStorage_CreateStream failed %x\n", hr);
+
+ IStream_Release(stm);
+
+ hr = IStorage_Commit(stg, 0);
+
+ IStorage_Release(stg);
+
+ ok(!lockbytes->lock_called, "unexpected call to LockRegion\n");
+
+ lockbytes->locks_supported = LOCK_WRITE|LOCK_EXCLUSIVE|LOCK_ONLYONCE;
+
+ hr = StgCreateDocfileOnILockBytes(&lockbytes->ILockBytes_iface,
STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED, 0, &stg);
+ ok(hr==S_OK, "StgCreateDocfileOnILockBytes failed %x\n", hr);
+
+ hr = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0,
&stm);
+ ok(hr==S_OK, "IStorage_CreateStream failed %x\n", hr);
+
+ IStream_Release(stm);
+
+ hr = IStorage_Commit(stg, 0);
+
+ IStorage_Release(stg);
+
+ ok(lockbytes->lock_called, "expected LockRegion to be called\n");
+
+ lockbytes->lock_hr = STG_E_INVALIDFUNCTION;
+
+ hr = StgCreateDocfileOnILockBytes(&lockbytes->ILockBytes_iface,
STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED, 0, &stg);
+ ok(hr==STG_E_INVALIDFUNCTION, "StgCreateDocfileOnILockBytes failed %x\n",
hr);
+
+ DeleteTestLockBytes(lockbytes);
}
START_TEST(storage32)
@@ -3694,4 +3940,5 @@
test_locking();
test_transacted_shared();
test_overwrite();
-}
+ test_custom_lockbytes();
+}
Modified: trunk/rostests/winetests/ole32/usrmarshal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/usrmarsha…
==============================================================================
--- trunk/rostests/winetests/ole32/usrmarshal.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/ole32/usrmarshal.c [iso-8859-1] Sun Jul 19 23:12:15 2015
@@ -50,13 +50,22 @@
unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *, unsigned char *,
HMETAFILEPICT *);
void __RPC_USER HMETAFILEPICT_UserFree(ULONG *, HMETAFILEPICT *);
+ULONG __RPC_USER HBRUSH_UserSize(ULONG *, ULONG, HBRUSH *);
+unsigned char * __RPC_USER HBRUSH_UserMarshal(ULONG *, unsigned char *, HBRUSH *);
+unsigned char * __RPC_USER HBRUSH_UserUnmarshal(ULONG *, unsigned char *, HBRUSH *);
+void __RPC_USER HBRUSH_UserFree(ULONG *, HBRUSH *);
+
+static BOOL g_expect_user_alloc;
static void * WINAPI user_allocate(SIZE_T size)
{
+ ok(g_expect_user_alloc, "unexpected user_allocate call\n");
return CoTaskMemAlloc(size);
}
+static BOOL g_expect_user_free;
static void WINAPI user_free(void *p)
{
+ ok(g_expect_user_free, "unexpected user_free call\n");
CoTaskMemFree(p);
}
@@ -207,7 +216,6 @@
GlobalUnlock(hglobal);
actual_size = GlobalSize(hglobal);
expected_size = actual_size + 5 * sizeof(DWORD);
- trace("%d: actual size %d\n", block_size, actual_size);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0,
MSHCTX_LOCAL);
size = HGLOBAL_UserSize(&umcb.Flags, 0, &hglobal);
/* native is poorly programmed and allocates 4/8 bytes more than it needs to
@@ -410,7 +418,6 @@
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0,
MSHCTX_DIFFERENTMACHINE);
size = HMETAFILEPICT_UserSize(&umcb.Flags, 0, &hmfp);
ok(size > 20, "size should be at least 20 bytes, not %d\n", size);
- trace("size is %d\n", size);
buffer = HeapAlloc(GetProcessHeap(), 0, size);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_DIFFERENTMACHINE);
buffer_end = HMETAFILEPICT_UserMarshal(&umcb.Flags, buffer, &hmfp);
@@ -476,6 +483,17 @@
HeapFree(GetProcessHeap(), 0, buffer);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0,
MSHCTX_DIFFERENTMACHINE);
HMETAFILEPICT_UserFree(&umcb.Flags, &hmfp2);
+}
+
+typedef struct
+{
+ IUnknown IUnknown_iface;
+ LONG refs;
+} TestUnknown;
+
+static inline TestUnknown *impl_from_IUnknown(IUnknown *iface)
+{
+ return CONTAINING_RECORD(iface, TestUnknown, IUnknown_iface);
}
static HRESULT WINAPI Test_IUnknown_QueryInterface(
@@ -498,12 +516,14 @@
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
{
- return 2; /* non-heap-based object */
+ TestUnknown *This = impl_from_IUnknown(iface);
+ return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
{
- return 1; /* non-heap-based object */
+ TestUnknown *This = impl_from_IUnknown(iface);
+ return InterlockedDecrement(&This->refs);
}
static const IUnknownVtbl TestUnknown_Vtbl =
@@ -548,7 +568,7 @@
/* the rest can be NULLs */
};
-static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
+static TestUnknown Test_Unknown = { {&TestUnknown_Vtbl}, 1 };
static IStream Test_Stream = { &TestStream_Vtbl };
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *, ULONG, ULONG, IUnknown *,
REFIID);
@@ -588,7 +608,8 @@
/* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then
the result of CoMarshalInterface called with the LOWORD of the ctx */
- unk = &Test_Unknown;
+ unk = &Test_Unknown.IUnknown_iface;
+ Test_Unknown.refs = 1;
CreateStreamOnHGlobal(h, TRUE, &stm);
CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL,
MSHLFLAGS_NORMAL);
@@ -596,15 +617,17 @@
IStream_Seek(stm, zero, STREAM_SEEK_CUR, &pos);
marshal_size = pos.u.LowPart;
marshal_data = GlobalLock(h);
- trace("marshal_size %x\n", marshal_size);
+todo_wine
+ ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx);
size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk,
&IID_IUnknown);
ok(size >= marshal_size + 2 * sizeof(DWORD), "marshal size %x got %x\n",
marshal_size, size);
- trace("WdtpInterfacePointer_UserSize returned %x\n", size);
buffer = HeapAlloc(GetProcessHeap(), 0, size);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
umcb_ctx);
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk,
&IID_IUnknown);
+todo_wine
+ ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
wireip = buffer;
ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p
buffer %p\n", buffer_end, buffer);
@@ -625,6 +648,7 @@
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
umcb_ctx);
WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2,
&IID_IUnknown);
ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
+ ok(Test_Unknown.refs == 2, "got %d\n", Test_Unknown.refs);
HeapFree(GetProcessHeap(), 0, buffer);
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0,
MSHCTX_INPROC);
IUnknown_Release(unk2);
@@ -657,7 +681,7 @@
unsigned char *buffer, *buffer_end, *expect_buffer, *expect_buffer_end;
ULONG size, expect_size;
STGMEDIUM med, med2;
- IUnknown *unk = &Test_Unknown;
+ IUnknown *unk = &Test_Unknown.IUnknown_iface;
IStream *stm = &Test_Stream;
/* TYMED_NULL with pUnkForRelease */
@@ -753,6 +777,211 @@
STGMEDIUM_UserFree(&umcb.Flags, &med2);
HeapFree(GetProcessHeap(), 0, expect_buffer);
+}
+
+static void test_marshal_SNB(void)
+{
+ static const WCHAR str1W[] =
{'s','t','r','i','n','g','1',0};
+ static const WCHAR str2W[] = {'s','t','r','2',0};
+ unsigned char *buffer, *src, *mbuf;
+ MIDL_STUB_MESSAGE stub_msg;
+ WCHAR **ptrW, *dataW;
+ USER_MARSHAL_CB umcb;
+ RPC_MESSAGE rpc_msg;
+ RemSNB *wiresnb;
+ SNB snb, snb2;
+ ULONG size;
+
+ /* 4 bytes alignment */
+ snb = NULL;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ size = SNB_UserSize(&umcb.Flags, 3, &snb);
+ ok(size == 16, "Size should be 16, instead of %d\n", size);
+
+ /* NULL block */
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ size = SNB_UserSize(&umcb.Flags, 0, &snb);
+ ok(size == 12, "Size should be 12, instead of %d\n", size);
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ mbuf = SNB_UserMarshal(&umcb.Flags, buffer, &snb);
+ ok(mbuf == buffer + size, "got %p, %p\n", mbuf, buffer + size);
+
+ wiresnb = (RemSNB*)buffer;
+ ok(wiresnb->ulCntStr == 0, "got %u\n", wiresnb->ulCntStr);
+ ok(wiresnb->ulCntChar == 0, "got %u\n", wiresnb->ulCntChar);
+ ok(*(ULONG*)wiresnb->rgString == 0, "got %u\n",
*(ULONG*)wiresnb->rgString);
+
+ snb2 = NULL;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ SNB_UserUnmarshal(&umcb.Flags, buffer, &snb2);
+ ok(snb2 == NULL, "got %p\n", snb2);
+
+ HeapFree(GetProcessHeap(), 0, buffer);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ SNB_UserFree(&umcb.Flags, &snb2);
+
+ /* block with actual data */
+
+ /* allocate source block, n+1 pointers first, then data */
+ src = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR*)*3 + sizeof(str1W) +
sizeof(str2W));
+ ptrW = (WCHAR**)src;
+ dataW = *ptrW = (WCHAR*)(src + 3*sizeof(WCHAR*));
+ ptrW++;
+ *ptrW = (WCHAR*)(src + 3*sizeof(WCHAR*) + sizeof(str1W));
+ ptrW++;
+ *ptrW = NULL;
+ lstrcpyW(dataW, str1W);
+ dataW += lstrlenW(str1W) + 1;
+ lstrcpyW(dataW, str2W);
+
+ snb = (SNB)src;
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ size = SNB_UserSize(&umcb.Flags, 0, &snb);
+ ok(size == 38, "Size should be 38, instead of %d\n", size);
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ SNB_UserMarshal(&umcb.Flags, buffer, &snb);
+
+ wiresnb = (RemSNB*)buffer;
+ ok(wiresnb->ulCntStr == 13, "got %u\n", wiresnb->ulCntStr);
+ ok(wiresnb->ulCntChar == 2, "got %u\n", wiresnb->ulCntChar);
+ /* payload length is stored one more time, as ULONG */
+ 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);
+ 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);
+
+ g_expect_user_alloc = TRUE;
+ snb2 = NULL;
+ SNB_UserUnmarshal(&umcb.Flags, buffer, &snb2);
+ g_expect_user_alloc = FALSE;
+
+ ptrW = snb2;
+ ok(!lstrcmpW(*ptrW, str1W), "unmarshalled string 0: %s\n",
wine_dbgstr_w(*ptrW));
+ ptrW++;
+ ok(!lstrcmpW(*ptrW, str2W), "unmarshalled string 1: %s\n",
wine_dbgstr_w(*ptrW));
+ ptrW++;
+ ok(*ptrW == NULL, "expected terminating NULL ptr, got %p, start %p\n",
*ptrW, snb2);
+
+ HeapFree(GetProcessHeap(), 0, buffer);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+
+ g_expect_user_free = TRUE;
+ SNB_UserFree(&umcb.Flags, &snb2);
+ g_expect_user_free = FALSE;
+
+ HeapFree(GetProcessHeap(), 0, src);
+}
+
+static void test_marshal_HDC(void)
+{
+ MIDL_STUB_MESSAGE stub_msg;
+ HDC hdc = GetDC(0), hdc2;
+ USER_MARSHAL_CB umcb;
+ RPC_MESSAGE rpc_msg;
+ unsigned char *buffer;
+ wireHDC wirehdc;
+ ULONG size;
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ size = HDC_UserSize(&umcb.Flags, 0, &hdc);
+ ok(size == sizeof(*wirehdc), "Wrong size %d\n", size);
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ HDC_UserMarshal(&umcb.Flags, buffer, &hdc);
+ wirehdc = (wireHDC)buffer;
+ ok(wirehdc->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL
instead of 0x%08x\n", wirehdc->fContext);
+ ok(wirehdc->u.hInproc == (LONG_PTR)hdc, "Marshaled value should be %p instead
of %x\n", hdc, wirehdc->u.hRemote);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ HDC_UserUnmarshal(&umcb.Flags, buffer, &hdc2);
+ ok(hdc == hdc2, "Didn't unmarshal properly\n");
+ HeapFree(GetProcessHeap(), 0, buffer);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ HDC_UserFree(&umcb.Flags, &hdc2);
+ ReleaseDC(0, hdc);
+}
+
+static void test_marshal_HICON(void)
+{
+ static const BYTE bmp_bits[1024];
+ MIDL_STUB_MESSAGE stub_msg;
+ HICON hIcon, hIcon2;
+ USER_MARSHAL_CB umcb;
+ RPC_MESSAGE rpc_msg;
+ unsigned char *buffer;
+ wireHICON wirehicon;
+ ULONG size;
+
+ hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, bmp_bits);
+ ok(hIcon != 0, "CreateIcon failed\n");
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ size = HICON_UserSize(&umcb.Flags, 0, &hIcon);
+ ok(size == sizeof(*wirehicon), "Wrong size %d\n", size);
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ HICON_UserMarshal(&umcb.Flags, buffer, &hIcon);
+ wirehicon = (wireHICON)buffer;
+ ok(wirehicon->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL
instead of 0x%08x\n", wirehicon->fContext);
+ ok(wirehicon->u.hInproc == (LONG_PTR)hIcon, "Marshaled value should be %p
instead of %x\n", hIcon, wirehicon->u.hRemote);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ HICON_UserUnmarshal(&umcb.Flags, buffer, &hIcon2);
+ ok(hIcon == hIcon2, "Didn't unmarshal properly\n");
+ HeapFree(GetProcessHeap(), 0, buffer);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ HICON_UserFree(&umcb.Flags, &hIcon2);
+ DestroyIcon(hIcon);
+}
+
+static void test_marshal_HBRUSH(void)
+{
+ MIDL_STUB_MESSAGE stub_msg;
+ HBRUSH hBrush, hBrush2;
+ USER_MARSHAL_CB umcb;
+ RPC_MESSAGE rpc_msg;
+ unsigned char *buffer;
+ LOGBRUSH logbrush;
+ wireHBRUSH wirehbrush;
+ ULONG size;
+
+ logbrush.lbStyle = BS_SOLID;
+ logbrush.lbColor = RGB(0, 0, 0);
+ logbrush.lbHatch = 0;
+
+ hBrush = CreateBrushIndirect(&logbrush);
+ ok(hBrush != 0, "CreateBrushIndirect failed\n");
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ size = HBRUSH_UserSize(&umcb.Flags, 0, &hBrush);
+ ok(size == sizeof(*wirehbrush), "Wrong size %d\n", size);
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ HBRUSH_UserMarshal(&umcb.Flags, buffer, &hBrush);
+ wirehbrush = (wireHBRUSH)buffer;
+ ok(wirehbrush->fContext == WDT_INPROC_CALL, "Context should be
WDT_INPROC_CALL instead of 0x%08x\n", wirehbrush->fContext);
+ ok(wirehbrush->u.hInproc == (LONG_PTR)hBrush, "Marshaled value should be %p
instead of %x\n", hBrush, wirehbrush->u.hRemote);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size,
MSHCTX_LOCAL);
+ HBRUSH_UserUnmarshal(&umcb.Flags, buffer, &hBrush2);
+ ok(hBrush == hBrush2, "Didn't unmarshal properly\n");
+ HeapFree(GetProcessHeap(), 0, buffer);
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
+ HBRUSH_UserFree(&umcb.Flags, &hBrush2);
+ DeleteObject(hBrush);
}
START_TEST(usrmarshal)
@@ -767,6 +996,10 @@
test_marshal_HMETAFILEPICT();
test_marshal_WdtpInterfacePointer();
test_marshal_STGMEDIUM();
+ test_marshal_SNB();
+ test_marshal_HDC();
+ test_marshal_HICON();
+ test_marshal_HBRUSH();
CoUninitialize();
}