mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[OLE32_WINETEST] Sync with Wine Staging 1.7.47. CORE-9924
svn path=/trunk/; revision=68470
This commit is contained in:
parent
bc504c5a3f
commit
afe5b2c7bf
7 changed files with 721 additions and 42 deletions
|
@ -22,4 +22,9 @@ add_executable(ole32_winetest ${SOURCE})
|
|||
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)
|
||||
|
|
|
@ -102,7 +102,7 @@ static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFII
|
|||
|
||||
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 @@ static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt,
|
|||
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 @@ static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID r
|
|||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject)) {
|
||||
IDataObject_AddRef(iface);
|
||||
*ppvObj = This;
|
||||
*ppvObj = &This->IDataObject_iface;
|
||||
return S_OK;
|
||||
}
|
||||
*ppvObj = NULL;
|
||||
|
|
|
@ -1563,7 +1563,7 @@ static void test_registered_object_thread_affinity(void)
|
|||
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 @@ static void test_TreatAsClass(void)
|
|||
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);
|
||||
|
|
|
@ -452,13 +452,16 @@ static void test_Register_Revoke(void)
|
|||
|
||||
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);
|
||||
|
|
|
@ -1688,6 +1688,113 @@ static void test_data_cache(void)
|
|||
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 @@ static const IUnknownVtbl UnknownVtbl =
|
|||
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 @@ START_TEST(ole2)
|
|||
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();
|
||||
|
|
|
@ -61,6 +61,201 @@ static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2)
|
|||
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)
|
||||
{
|
||||
ILockBytes *ilb = NULL;
|
||||
|
@ -3157,22 +3352,22 @@ struct lock_test
|
|||
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 roex_locked_bytes[] = { 0x193, 0x1bb, 0x1cf, -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 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 @@ static const struct lock_test lock_tests[] = {
|
|||
{ 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 @@ static void test_locking(void)
|
|||
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 @@ static void test_locking(void)
|
|||
|
||||
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 @@ static void test_locking(void)
|
|||
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 @@ static void test_locking(void)
|
|||
|
||||
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;
|
||||
|
@ -3646,6 +3844,54 @@ static void test_overwrite(void)
|
|||
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)
|
||||
{
|
||||
CHAR temp[MAX_PATH];
|
||||
|
@ -3694,4 +3940,5 @@ START_TEST(storage32)
|
|||
test_locking();
|
||||
test_transacted_shared();
|
||||
test_overwrite();
|
||||
test_custom_lockbytes();
|
||||
}
|
||||
|
|
|
@ -50,13 +50,22 @@ unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal (ULONG *, unsigned char *,
|
|||
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 @@ static void test_marshal_HGLOBAL(void)
|
|||
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 @@ static void test_marshal_HMETAFILEPICT(void)
|
|||
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);
|
||||
|
@ -478,6 +485,17 @@ static void test_marshal_HMETAFILEPICT(void)
|
|||
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(
|
||||
LPUNKNOWN iface,
|
||||
REFIID riid,
|
||||
|
@ -498,12 +516,14 @@ static HRESULT WINAPI Test_IUnknown_QueryInterface(
|
|||
|
||||
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 @@ static const IStreamVtbl TestStream_Vtbl =
|
|||
/* 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 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
|
|||
/* 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 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
|
|||
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 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
|
|||
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 @@ static void test_marshal_STGMEDIUM(void)
|
|||
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 */
|
||||
|
@ -755,6 +779,211 @@ static void test_marshal_STGMEDIUM(void)
|
|||
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)
|
||||
{
|
||||
CoInitialize(NULL);
|
||||
|
@ -767,6 +996,10 @@ START_TEST(usrmarshal)
|
|||
test_marshal_HMETAFILEPICT();
|
||||
test_marshal_WdtpInterfacePointer();
|
||||
test_marshal_STGMEDIUM();
|
||||
test_marshal_SNB();
|
||||
test_marshal_HDC();
|
||||
test_marshal_HICON();
|
||||
test_marshal_HBRUSH();
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue