mirror of
https://github.com/reactos/reactos.git
synced 2025-06-18 19:35:21 +00:00
[OLE32_WINETEST]
sync OLE32_WINETEST with wine 1.1.40 svn path=/trunk/; revision=46077
This commit is contained in:
parent
f0a96d12a1
commit
418f2cc0e1
9 changed files with 2508 additions and 242 deletions
|
@ -477,8 +477,6 @@ static void test_get_clipboard(void)
|
|||
hr = IDataObject_QueryGetData(data_obj, &fmtetc);
|
||||
ok(hr == DV_E_FORMATETC || broken(hr == S_OK),
|
||||
"IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
|
||||
if (hr == S_OK)
|
||||
ReleaseStgMedium(&stgmedium);
|
||||
|
||||
InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
|
||||
fmtetc.cfFormat = CF_RIFF;
|
||||
|
@ -499,19 +497,19 @@ static void test_get_clipboard(void)
|
|||
InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
|
||||
hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
|
||||
ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
|
||||
ReleaseStgMedium(&stgmedium);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
|
||||
|
||||
InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
|
||||
fmtetc.dwAspect = 0xdeadbeef;
|
||||
hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
|
||||
ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
|
||||
ReleaseStgMedium(&stgmedium);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
|
||||
|
||||
InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
|
||||
fmtetc.dwAspect = DVASPECT_THUMBNAIL;
|
||||
hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
|
||||
ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
|
||||
ReleaseStgMedium(&stgmedium);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
|
||||
|
||||
InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
|
||||
fmtetc.lindex = 256;
|
||||
|
@ -528,11 +526,13 @@ static void test_get_clipboard(void)
|
|||
fmtetc.cfFormat = CF_RIFF;
|
||||
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;
|
||||
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);
|
||||
|
||||
ok(DataObjectImpl_GetData_calls == 6, "DataObjectImpl_GetData should have been called 6 times instead of %d times\n", DataObjectImpl_GetData_calls);
|
||||
|
||||
|
@ -735,7 +735,7 @@ static void test_cf_dataobject(IDataObject *data)
|
|||
DVTARGETDEVICE *target;
|
||||
|
||||
ok(fmt_ptr->fmt.ptd != NULL, "target device offset zero\n");
|
||||
target = (DVTARGETDEVICE*)((char*)priv + (DWORD)fmt_ptr->fmt.ptd);
|
||||
target = (DVTARGETDEVICE*)((char*)priv + (DWORD_PTR)fmt_ptr->fmt.ptd);
|
||||
ok(!memcmp(target, fmt.ptd, fmt.ptd->tdSize), "target devices differ\n");
|
||||
CoTaskMemFree(fmt.ptd);
|
||||
}
|
||||
|
@ -967,7 +967,7 @@ static void test_consumer_refs(void)
|
|||
hr = IDataObject_GetData(get1, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(DataObjectImpl_GetData_calls == 0, "GetData called\n");
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
hr = OleGetClipboard(&get2);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
|
@ -1004,7 +1004,7 @@ static void test_consumer_refs(void)
|
|||
hr = IDataObject_GetData(get1, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
refs = count_refs(src);
|
||||
ok(refs == old_refs + 1, "%d %d\n", refs, old_refs);
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ static void test_consumer_refs(void)
|
|||
hr = IDataObject_GetData(get1, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
refs = count_refs(src);
|
||||
ok(refs == 2, "%d\n", refs);
|
||||
|
@ -1047,7 +1047,7 @@ static void test_consumer_refs(void)
|
|||
hr = IDataObject_GetData(get1, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
refs = count_refs(src);
|
||||
ok(refs == 1, "%d\n", refs);
|
||||
|
@ -1096,23 +1096,24 @@ static void test_flushed_getdata(void)
|
|||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, CF_TEXT, TYMED_ISTREAM);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == E_FAIL, "got %08x\n", hr);
|
||||
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);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
/* stream format -> global & stream */
|
||||
|
||||
|
@ -1120,23 +1121,24 @@ static void test_flushed_getdata(void)
|
|||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_stream, TYMED_ISTORAGE);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == E_FAIL, "got %08x\n", hr);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_stream, TYMED_HGLOBAL);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_stream, 0xffff);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
/* storage format -> global, stream & storage */
|
||||
|
||||
|
@ -1144,34 +1146,36 @@ static void test_flushed_getdata(void)
|
|||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
hr = IStorage_Stat(med.u.pstg, &stat, STATFLAG_NONAME);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(stat.grfMode == (STGM_SHARE_EXCLUSIVE | STGM_READWRITE), "got %08x\n", stat.grfMode);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) {
|
||||
hr = IStorage_Stat(med.u.pstg, &stat, STATFLAG_NONAME);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(stat.grfMode == (STGM_SHARE_EXCLUSIVE | STGM_READWRITE), "got %08x\n", stat.grfMode);
|
||||
ReleaseStgMedium(&med);
|
||||
}
|
||||
|
||||
InitFormatEtc(fmt, cf_storage, TYMED_ISTREAM);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL | TYMED_ISTREAM);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_storage, 0xffff);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
/* complex format with target device */
|
||||
|
||||
|
@ -1180,7 +1184,7 @@ static void test_flushed_getdata(void)
|
|||
ok(hr == DV_E_FORMATETC ||
|
||||
broken(hr == S_OK), /* win9x, winme & nt4 */
|
||||
"got %08x\n", hr);
|
||||
if(hr == S_OK) ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
InitFormatEtc(fmt, cf_another, 0xffff);
|
||||
memset(&dm, 0, sizeof(dm));
|
||||
|
@ -1199,7 +1203,7 @@ static void test_flushed_getdata(void)
|
|||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
|
||||
ReleaseStgMedium(&med);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, fmt.ptd);
|
||||
|
||||
|
@ -1235,6 +1239,8 @@ static void test_nonole_clipboard(void)
|
|||
FORMATETC fmt;
|
||||
HGLOBAL h, hblob, htext;
|
||||
HENHMETAFILE emf;
|
||||
STGMEDIUM med;
|
||||
DWORD obj_type;
|
||||
|
||||
r = OpenClipboard(NULL);
|
||||
ok(r, "gle %d\n", GetLastError());
|
||||
|
@ -1349,6 +1355,13 @@ static void test_nonole_clipboard(void)
|
|||
ok(hr == S_FALSE, "got %08x\n", hr);
|
||||
IEnumFORMATETC_Release(enum_fmt);
|
||||
|
||||
InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF);
|
||||
hr = IDataObject_GetData(get, &fmt, &med);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
obj_type = GetObjectType(U(med).hEnhMetaFile);
|
||||
ok(obj_type == OBJ_ENHMETAFILE, "got %d\n", obj_type);
|
||||
if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
|
||||
|
||||
IDataObject_Release(get);
|
||||
|
||||
r = OpenClipboard(NULL);
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#define USE_COM_CONTEXT_DEF
|
||||
#include "initguid.h"
|
||||
#include "objbase.h"
|
||||
#include "shlguid.h"
|
||||
#include "urlmon.h" /* for CLSID_FileProtocol */
|
||||
|
||||
#include "initguid.h"
|
||||
#include "ctxtcall.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
@ -39,6 +40,7 @@ HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
|
|||
HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv);
|
||||
HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject);
|
||||
HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew);
|
||||
HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token);
|
||||
|
||||
#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)
|
||||
|
@ -201,6 +203,13 @@ static void test_StringFromGUID2(void)
|
|||
{
|
||||
WCHAR str[50];
|
||||
int len;
|
||||
|
||||
/* invalid pointer */
|
||||
SetLastError(0xdeadbeef);
|
||||
len = StringFromGUID2(NULL,str,50);
|
||||
ok(len == 0, "len: %d (expected 0)\n", len);
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %x\n", GetLastError());
|
||||
|
||||
/* Test corner cases for buffer size */
|
||||
len = StringFromGUID2(&CLSID_StdFont,str,50);
|
||||
ok(len == 39, "len: %d (expected 39)\n", len);
|
||||
|
@ -231,7 +240,7 @@ static DWORD CALLBACK ole_initialize_thread(LPVOID pv)
|
|||
hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
SetEvent(info->wait);
|
||||
WaitForSingleObject(info->stop, INFINITE);
|
||||
WaitForSingleObject(info->stop, 10000);
|
||||
|
||||
CoUninitialize();
|
||||
return hr;
|
||||
|
@ -252,7 +261,25 @@ static void test_CoCreateInstance(void)
|
|||
ok(pUnk == NULL, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
|
||||
|
||||
OleInitialize(NULL);
|
||||
|
||||
/* test errors returned for non-registered clsids */
|
||||
hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
|
||||
hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pUnk);
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc handler should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
|
||||
hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&pUnk);
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered local server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
|
||||
hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_REMOTE_SERVER, &IID_IUnknown, (void **)&pUnk);
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered remote server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
|
||||
|
||||
hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
|
||||
if(hr == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
skip("IE not installed so can't test CoCreateInstance\n");
|
||||
OleUninitialize();
|
||||
return;
|
||||
}
|
||||
|
||||
ok_ole_success(hr, "CoCreateInstance");
|
||||
if(pUnk) IUnknown_Release(pUnk);
|
||||
OleUninitialize();
|
||||
|
@ -272,7 +299,7 @@ static void test_CoCreateInstance(void)
|
|||
thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
|
||||
WaitForSingleObject(info.wait, INFINITE);
|
||||
ok( !WaitForSingleObject(info.wait, 10000 ), "wait timed out\n" );
|
||||
|
||||
pUnk = (IUnknown *)0xdeadbeef;
|
||||
hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
|
||||
|
@ -280,7 +307,7 @@ static void test_CoCreateInstance(void)
|
|||
if (pUnk) IUnknown_Release(pUnk);
|
||||
|
||||
SetEvent(info.stop);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
|
@ -321,15 +348,20 @@ static void test_CoGetClassObject(void)
|
|||
thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
|
||||
WaitForSingleObject(info.wait, INFINITE);
|
||||
ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
|
||||
|
||||
pUnk = (IUnknown *)0xdeadbeef;
|
||||
hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
|
||||
ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
|
||||
if (pUnk) IUnknown_Release(pUnk);
|
||||
if(hr == REGDB_E_CLASSNOTREG)
|
||||
skip("IE not installed so can't test CoGetClassObject\n");
|
||||
else
|
||||
{
|
||||
ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
|
||||
if (pUnk) IUnknown_Release(pUnk);
|
||||
}
|
||||
|
||||
SetEvent(info.stop);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
|
@ -816,6 +848,14 @@ static void test_CoRegisterClassObject(void)
|
|||
hr = CoRevokeClassObject(cookie);
|
||||
ok_ole_success(hr, "CoRevokeClassObject");
|
||||
|
||||
/* test whether an object that doesn't support IClassFactory can be
|
||||
* registered for CLSCTX_LOCAL_SERVER */
|
||||
hr = CoRegisterClassObject(&CLSID_WineOOPTest, &Test_Unknown,
|
||||
CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
|
||||
ok_ole_success(hr, "CoRegisterClassObject");
|
||||
hr = CoRevokeClassObject(cookie);
|
||||
ok_ole_success(hr, "CoRevokeClassObject");
|
||||
|
||||
/* test whether registered class becomes invalid when apartment is destroyed */
|
||||
hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
|
||||
CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
|
||||
|
@ -935,7 +975,7 @@ static void test_registered_object_thread_affinity(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, get_class_object_thread, (LPVOID)CLSCTX_INPROC_SERVER, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object "
|
||||
|
@ -948,7 +988,7 @@ static void test_registered_object_thread_affinity(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok ( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr);
|
||||
|
@ -964,7 +1004,7 @@ static void test_registered_object_thread_affinity(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, get_class_object_proxy_thread, (LPVOID)CLSCTX_LOCAL_SERVER, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
while (MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)
|
||||
while (MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
|
@ -985,7 +1025,7 @@ static void test_registered_object_thread_affinity(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, revoke_class_object_thread, (LPVOID)(DWORD_PTR)cookie, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
ok(hr == RPC_E_WRONG_THREAD, "CoRevokeClassObject called from different "
|
||||
|
@ -993,7 +1033,7 @@ static void test_registered_object_thread_affinity(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different "
|
||||
|
@ -1030,7 +1070,7 @@ static void test_CoFreeUnusedLibraries(void)
|
|||
hr = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pUnk);
|
||||
if (hr == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
trace("IE not installed so can't run CoFreeUnusedLibraries test\n");
|
||||
skip("IE not installed so can't run CoFreeUnusedLibraries test\n");
|
||||
CoUninitialize();
|
||||
return;
|
||||
}
|
||||
|
@ -1047,7 +1087,7 @@ static void test_CoFreeUnusedLibraries(void)
|
|||
ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
|
||||
|
||||
thread = CreateThread(NULL, 0, free_libraries_thread, NULL, 0, &tid);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
CloseHandle(thread);
|
||||
|
||||
ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
|
||||
|
@ -1065,8 +1105,12 @@ static void test_CoGetObjectContext(void)
|
|||
ULONG refs;
|
||||
IComThreadingInfo *pComThreadingInfo;
|
||||
IContextCallback *pContextCallback;
|
||||
IObjContext *pObjContext;
|
||||
APTTYPE apttype;
|
||||
THDTYPE thdtype;
|
||||
struct info info;
|
||||
HANDLE thread;
|
||||
DWORD tid, exitcode;
|
||||
|
||||
if (!pCoGetObjectContext)
|
||||
{
|
||||
|
@ -1078,6 +1122,36 @@ static void test_CoGetObjectContext(void)
|
|||
ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
|
||||
ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n");
|
||||
|
||||
/* show that COM doesn't have to be initialized for multi-threaded apartments if another
|
||||
thread has already done so */
|
||||
|
||||
info.wait = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
|
||||
|
||||
info.stop = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError());
|
||||
|
||||
thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
|
||||
ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
|
||||
|
||||
pComThreadingInfo = NULL;
|
||||
hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
|
||||
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
||||
IComThreadingInfo_Release(pComThreadingInfo);
|
||||
|
||||
SetEvent(info.stop);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr);
|
||||
|
||||
CloseHandle(thread);
|
||||
CloseHandle(info.wait);
|
||||
CloseHandle(info.stop);
|
||||
|
||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
|
||||
|
@ -1130,6 +1204,12 @@ static void test_CoGetObjectContext(void)
|
|||
ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
|
||||
}
|
||||
|
||||
hr = pCoGetObjectContext(&IID_IObjContext, (void **)&pObjContext);
|
||||
ok_ole_success(hr, "CoGetObjectContext");
|
||||
|
||||
refs = IObjContext_Release(pObjContext);
|
||||
ok(refs == 0, "pObjContext should have 0 refs instead of %d refs\n", refs);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
|
@ -1233,6 +1313,101 @@ static void test_CoGetCallContext(void)
|
|||
CoUninitialize();
|
||||
}
|
||||
|
||||
static void test_CoGetContextToken(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
ULONG refs;
|
||||
ULONG_PTR token;
|
||||
IObjContext *ctx;
|
||||
struct info info;
|
||||
HANDLE thread;
|
||||
DWORD tid, exitcode;
|
||||
|
||||
if (!pCoGetContextToken)
|
||||
{
|
||||
win_skip("CoGetContextToken not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
token = 0xdeadbeef;
|
||||
hr = pCoGetContextToken(&token);
|
||||
ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr);
|
||||
ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token);
|
||||
|
||||
/* show that COM doesn't have to be initialized for multi-threaded apartments if another
|
||||
thread has already done so */
|
||||
|
||||
info.wait = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
|
||||
|
||||
info.stop = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError());
|
||||
|
||||
thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
|
||||
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
|
||||
|
||||
ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
|
||||
|
||||
token = 0;
|
||||
hr = pCoGetContextToken(&token);
|
||||
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
||||
|
||||
SetEvent(info.stop);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
|
||||
GetExitCodeThread(thread, &exitcode);
|
||||
hr = exitcode;
|
||||
ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr);
|
||||
|
||||
CloseHandle(thread);
|
||||
CloseHandle(info.wait);
|
||||
CloseHandle(info.stop);
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
hr = pCoGetContextToken(NULL);
|
||||
ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr);
|
||||
|
||||
token = 0;
|
||||
hr = pCoGetContextToken(&token);
|
||||
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
||||
ok(token, "Expected token != 0\n");
|
||||
|
||||
refs = IUnknown_AddRef((IUnknown *)token);
|
||||
todo_wine ok(refs == 1, "Expected 1, got %u\n", refs);
|
||||
|
||||
hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx);
|
||||
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
||||
todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
|
||||
|
||||
refs = IUnknown_AddRef((IUnknown *)ctx);
|
||||
todo_wine ok(refs == 3, "Expected 3, got %u\n", refs);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)ctx);
|
||||
todo_wine ok(refs == 2, "Expected 2, got %u\n", refs);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)token);
|
||||
ok(refs == 1, "Expected 1, got %u\n", refs);
|
||||
|
||||
/* CoGetContextToken does not add a reference */
|
||||
token = 0;
|
||||
hr = pCoGetContextToken(&token);
|
||||
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
||||
ok(token, "Expected token != 0\n");
|
||||
todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
|
||||
|
||||
refs = IUnknown_AddRef((IUnknown *)ctx);
|
||||
ok(refs == 2, "Expected 1, got %u\n", refs);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)ctx);
|
||||
ok(refs == 1, "Expected 0, got %u\n", refs);
|
||||
|
||||
refs = IUnknown_Release((IUnknown *)ctx);
|
||||
ok(refs == 0, "Expected 0, got %u\n", refs);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
static void test_CoGetTreatAsClass(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -1259,7 +1434,7 @@ static void test_CoInitializeEx(void)
|
|||
/* Calling OleInitialize for the first time should yield S_OK even with
|
||||
* apartment already initialized by previous CoInitialize(Ex) calls. */
|
||||
hr = OleInitialize(NULL);
|
||||
todo_wine ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
|
||||
ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
|
||||
|
||||
/* Subsequent calls to OleInitialize should return S_FALSE */
|
||||
hr = OleInitialize(NULL);
|
||||
|
@ -1276,6 +1451,7 @@ START_TEST(compobj)
|
|||
pCoGetObjectContext = (void*)GetProcAddress(hOle32, "CoGetObjectContext");
|
||||
pCoSwitchCallContext = (void*)GetProcAddress(hOle32, "CoSwitchCallContext");
|
||||
pCoGetTreatAsClass = (void*)GetProcAddress(hOle32,"CoGetTreatAsClass");
|
||||
pCoGetContextToken = (void*)GetProcAddress(hOle32, "CoGetContextToken");
|
||||
if (!(pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx")))
|
||||
{
|
||||
trace("You need DCOM95 installed to run this test\n");
|
||||
|
@ -1301,6 +1477,7 @@ START_TEST(compobj)
|
|||
test_CoFreeUnusedLibraries();
|
||||
test_CoGetObjectContext();
|
||||
test_CoGetCallContext();
|
||||
test_CoGetContextToken();
|
||||
test_CoGetTreatAsClass();
|
||||
test_CoInitializeEx();
|
||||
}
|
||||
|
|
|
@ -75,6 +75,157 @@ static void test_streamonhglobal(IStream *pStream)
|
|||
hr = IStream_SetSize(pStream, ull);
|
||||
ok_ole_success(hr, "IStream_SetSize");
|
||||
|
||||
/* IStream_Seek -- NULL position argument */
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, NULL);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
/* IStream_Seek -- valid position argument (seek from current position) */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- invalid seek argument */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 123;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_END+1, &ull);
|
||||
ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr);
|
||||
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should not have changed HighPart, got %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- valid position argument (seek to beginning) */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- valid position argument (seek to end) */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_END, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- ignore HighPart in the move value (seek from current position) */
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = sizeof(data);
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = -1;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- ignore HighPart in the move value (seek to beginning) */
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = sizeof(data);
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = -1;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- invalid LowPart value (seek from current position) */
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = sizeof(data);
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0x80000000;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr);
|
||||
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- invalid LowPart value (seek to beginning) */
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = sizeof(data);
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0x80000000;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr);
|
||||
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- valid LowPart value (seek to beginning) */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0x7FFFFFFF;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0x7FFFFFFF, "should have set LowPart to 0x7FFFFFFF instead of %08x\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- valid LowPart value (seek from current position) */
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0x7FFFFFFF;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0x7FFFFFFF, "should have set LowPart to 0x7FFFFFFF instead of %08x\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- second seek allows you to go past 0x7FFFFFFF size */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 9;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0x80000008, "should have set LowPart to 0x80000008 instead of %08x\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
/* IStream_Seek -- seek wraps position/size on integer overflow */
|
||||
ull.u.HighPart = 0xCAFECAFE;
|
||||
ull.u.LowPart = 0xCAFECAFE;
|
||||
ll.u.HighPart = 0;
|
||||
ll.u.LowPart = 0x7FFFFFFF;
|
||||
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
ok(ull.u.LowPart == 0x00000007, "should have set LowPart to 0x00000007 instead of %08x\n", ull.u.LowPart);
|
||||
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
|
||||
|
||||
hr = IStream_Commit(pStream, STGC_DEFAULT);
|
||||
ok_ole_success(hr, "IStream_Commit");
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "initguid.h"
|
||||
#include "objbase.h"
|
||||
#include "olectl.h"
|
||||
#include "shlguid.h"
|
||||
#include "shobjidl.h"
|
||||
#include "initguid.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
|
@ -276,7 +276,7 @@ static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object,
|
|||
*thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid);
|
||||
|
||||
/* wait for marshaling to complete before returning */
|
||||
WaitForSingleObject(marshal_event, INFINITE);
|
||||
ok( !WaitForSingleObject(marshal_event, 10000), "wait timed out\n" );
|
||||
CloseHandle(marshal_event);
|
||||
|
||||
return tid;
|
||||
|
@ -293,7 +293,7 @@ static void release_host_object(DWORD tid)
|
|||
{
|
||||
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
PostThreadMessage(tid, RELEASEMARSHALDATA, 0, (LPARAM)event);
|
||||
WaitForSingleObject(event, INFINITE);
|
||||
ok( !WaitForSingleObject(event, 10000), "wait timed out\n" );
|
||||
CloseHandle(event);
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ static void end_host_object(DWORD tid, HANDLE thread)
|
|||
BOOL ret = PostThreadMessage(tid, WM_QUIT, 0, 0);
|
||||
ok(ret, "PostThreadMessage failed with error %d\n", GetLastError());
|
||||
/* be careful of races - don't return until hosting thread has terminated */
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
|
@ -843,7 +843,7 @@ static DWORD CALLBACK no_couninitialize_server_proc(LPVOID p)
|
|||
|
||||
SetEvent(ncu_params->marshal_event);
|
||||
|
||||
WaitForSingleObject(ncu_params->unmarshal_event, INFINITE);
|
||||
ok( !WaitForSingleObject(ncu_params->unmarshal_event, 10000), "wait timed out\n" );
|
||||
|
||||
/* die without calling CoUninitialize */
|
||||
|
||||
|
@ -872,7 +872,7 @@ static void test_no_couninitialize_server(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, no_couninitialize_server_proc, &ncu_params, 0, &tid);
|
||||
|
||||
WaitForSingleObject(ncu_params.marshal_event, INFINITE);
|
||||
ok( !WaitForSingleObject(ncu_params.marshal_event, 10000), "wait timed out\n" );
|
||||
ok_more_than_one_lock();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
|
@ -883,7 +883,7 @@ static void test_no_couninitialize_server(void)
|
|||
ok_more_than_one_lock();
|
||||
|
||||
SetEvent(ncu_params.unmarshal_event);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
|
||||
ok_no_locks();
|
||||
|
||||
|
@ -942,7 +942,7 @@ static void test_no_couninitialize_client(void)
|
|||
|
||||
thread = CreateThread(NULL, 0, no_couninitialize_client_proc, &ncu_params, 0, &tid);
|
||||
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
CloseHandle(thread);
|
||||
|
||||
ok_no_locks();
|
||||
|
@ -1109,7 +1109,7 @@ static DWORD CALLBACK weak_and_normal_marshal_thread_proc(void *p)
|
|||
|
||||
SetEvent(data->hReadyEvent);
|
||||
|
||||
while (WAIT_OBJECT_0 + 1 == MsgWaitForMultipleObjects(1, &hQuitEvent, FALSE, INFINITE, QS_ALLINPUT))
|
||||
while (WAIT_OBJECT_0 + 1 == MsgWaitForMultipleObjects(1, &hQuitEvent, FALSE, 10000, QS_ALLINPUT))
|
||||
{
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
DispatchMessage(&msg);
|
||||
|
@ -1141,7 +1141,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
|
|||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
||||
thread = CreateThread(NULL, 0, weak_and_normal_marshal_thread_proc, &data, 0, &tid);
|
||||
WaitForSingleObject(data.hReadyEvent, INFINITE);
|
||||
ok( !WaitForSingleObject(data.hReadyEvent, 10000), "wait timed out\n" );
|
||||
CloseHandle(data.hReadyEvent);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
@ -1170,7 +1170,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
|
|||
IStream_Release(data.pStreamNormal);
|
||||
|
||||
SetEvent(data.hQuitEvent);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
|
@ -1257,7 +1257,7 @@ static void test_lock_object_external(void)
|
|||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoReleaseMarshalData(pStream);
|
||||
ok_ole_success(hr, CoReleaseMarshalData);
|
||||
IStream_Release(pStream);
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
|
@ -1268,6 +1268,39 @@ static void test_lock_object_external(void)
|
|||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, TRUE);
|
||||
|
||||
ok_no_locks();
|
||||
|
||||
/* test CoLockObjectExternal releases reference to object with
|
||||
* fLastUnlockReleases as TRUE and there are only strong references on
|
||||
* the object */
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE);
|
||||
|
||||
ok_no_locks();
|
||||
|
||||
/* test CoLockObjectExternal doesn't release the last reference to an
|
||||
* object with fLastUnlockReleases as TRUE and there is a weak reference
|
||||
* on the object */
|
||||
hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
|
||||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
|
||||
|
||||
ok_no_locks();
|
||||
|
||||
IStream_Release(pStream);
|
||||
}
|
||||
|
||||
/* tests disconnecting stubs */
|
||||
|
@ -1449,7 +1482,7 @@ static void test_proxy_used_in_wrong_thread(void)
|
|||
/* create a thread that we can misbehave in */
|
||||
thread = CreateThread(NULL, 0, bad_thread_proc, pProxy, 0, &tid2);
|
||||
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
CloseHandle(thread);
|
||||
|
||||
/* do release statement on Win9x that we should have done above */
|
||||
|
@ -1799,6 +1832,7 @@ static HRESULT WINAPI TestRE_IClassFactory_CreateInstance(
|
|||
BOOL ret = SendMessageTimeout(hwnd_app, WM_NULL, 0, 0, SMTO_BLOCK, 5000, &res);
|
||||
ok(ret, "Timed out sending a message to originating window during RPC call\n");
|
||||
}
|
||||
*ppvObj = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2071,7 +2105,7 @@ static void test_freethreadedmarshaldata(IStream *pStream, MSHCTX mshctx, void *
|
|||
{
|
||||
DWORD expected_size = round_global_size(3*sizeof(DWORD) + sizeof(GUID));
|
||||
ok(size == expected_size ||
|
||||
broken(size == round_global_size(2*sizeof(DWORD))) /* Win9x & NT4 */,
|
||||
broken(size == (2*sizeof(DWORD))) /* Win9x & NT4 */,
|
||||
"size should have been %d instead of %d\n", expected_size, size);
|
||||
|
||||
ok(*(DWORD *)marshal_data == mshlflags, "expected 0x%x, but got 0x%x for mshctx\n", mshlflags, *(DWORD *)marshal_data);
|
||||
|
@ -2259,7 +2293,7 @@ static void reg_unreg_wine_test_class(BOOL Register)
|
|||
{
|
||||
error = RegCreateKeyEx(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
|
||||
ok(error == ERROR_SUCCESS, "RegCreateKeyEx failed with error %d\n", error);
|
||||
error = RegSetValueEx(hkey, NULL, 0, REG_SZ, (const unsigned char *)"ole32.dll", strlen("ole32.dll") + 1);
|
||||
error = RegSetValueEx(hkey, NULL, 0, REG_SZ, (const unsigned char *)"\"ole32.dll\"", strlen("\"ole32.dll\"") + 1);
|
||||
ok(error == ERROR_SUCCESS, "RegSetValueEx failed with error %d\n", error);
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
@ -2280,7 +2314,6 @@ static void test_inproc_handler(void)
|
|||
reg_unreg_wine_test_class(TRUE);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject);
|
||||
todo_wine
|
||||
ok_ole_success(hr, "CoCreateInstance");
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
@ -2701,7 +2734,7 @@ static void test_local_server(void)
|
|||
ok(process != NULL, "couldn't start local server process, error was %d\n", GetLastError());
|
||||
|
||||
ready_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
|
||||
WaitForSingleObject(ready_event, INFINITE);
|
||||
ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
|
||||
CloseHandle(ready_event);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IClassFactory, (void **)&cf);
|
||||
|
@ -2781,13 +2814,13 @@ static void test_globalinterfacetable(void)
|
|||
* to exit before we can return */
|
||||
thread = CreateThread(NULL, 0, get_global_interface_proc, ¶ms, 0, &tid);
|
||||
|
||||
ret = MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT);
|
||||
ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT);
|
||||
while (ret == WAIT_OBJECT_0 + 1)
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
DispatchMessage(&msg);
|
||||
ret = MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT);
|
||||
ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT);
|
||||
}
|
||||
|
||||
CloseHandle(thread);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
#include "initguid.h"
|
||||
#include "comcat.h"
|
||||
#include "olectl.h"
|
||||
|
||||
|
@ -1142,7 +1143,7 @@ static void test_moniker(
|
|||
LPBYTE moniker_data;
|
||||
DWORD moniker_size;
|
||||
DWORD i;
|
||||
BOOL same = TRUE;
|
||||
BOOL same;
|
||||
BYTE buffer[128];
|
||||
IMoniker * moniker_proxy;
|
||||
LPOLESTR display_name;
|
||||
|
@ -1182,6 +1183,7 @@ static void test_moniker(
|
|||
testname, sizeof_expected_moniker_comparison_data, moniker_size);
|
||||
|
||||
/* then do a byte-by-byte comparison */
|
||||
same = TRUE;
|
||||
for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
|
||||
{
|
||||
if (expected_moniker_comparison_data[i] != buffer[i])
|
||||
|
@ -1225,6 +1227,7 @@ static void test_moniker(
|
|||
testname, (DWORD)round_global_size(sizeof_expected_moniker_saved_data), moniker_size);
|
||||
|
||||
/* then do a byte-by-byte comparison */
|
||||
same = TRUE;
|
||||
for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_saved_data)); i++)
|
||||
{
|
||||
if (expected_moniker_saved_data[i] != moniker_data[i])
|
||||
|
@ -1271,6 +1274,7 @@ static void test_moniker(
|
|||
testname, (DWORD)round_global_size(sizeof_expected_moniker_marshal_data), moniker_size);
|
||||
|
||||
/* then do a byte-by-byte comparison */
|
||||
same = TRUE;
|
||||
if (expected_moniker_marshal_data)
|
||||
{
|
||||
for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_marshal_data)); i++)
|
||||
|
@ -1428,6 +1432,16 @@ static void test_file_monikers(void)
|
|||
for (i = 0; i < COUNTOF(wszFile); ++i)
|
||||
{
|
||||
int j ;
|
||||
if (i == 2)
|
||||
{
|
||||
BOOL used;
|
||||
WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, wszFile[i], -1, NULL, 0, NULL, &used );
|
||||
if (used)
|
||||
{
|
||||
skip("string 2 doesn't round trip in codepage %u\n", GetACP() );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (j = lstrlenW(wszFile[i]); j > 0; --j)
|
||||
{
|
||||
wszFile[i][j] = 0;
|
||||
|
@ -1481,7 +1495,6 @@ static void test_item_moniker(void)
|
|||
|
||||
/* IsRunning test */
|
||||
hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
|
||||
todo_wine
|
||||
ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
|
||||
|
||||
hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
|
||||
|
@ -1617,7 +1630,6 @@ static void test_generic_composite_moniker(void)
|
|||
|
||||
/* IsRunning test */
|
||||
hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
|
||||
todo_wine
|
||||
ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
|
||||
|
||||
hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
|
||||
|
@ -1631,7 +1643,6 @@ static void test_generic_composite_moniker(void)
|
|||
todo_wine
|
||||
ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
|
||||
|
||||
todo_wine
|
||||
hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
|
||||
ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
|
||||
|
||||
|
@ -1853,6 +1864,75 @@ static void test_bind_context(void)
|
|||
ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
|
||||
}
|
||||
|
||||
static void test_save_load_filemoniker(void)
|
||||
{
|
||||
IMoniker* pMk;
|
||||
IStream* pStm;
|
||||
HRESULT hr;
|
||||
ULARGE_INTEGER size;
|
||||
LARGE_INTEGER zero_pos, dead_pos, nulls_pos;
|
||||
DWORD some_val = 0xFEDCBA98;
|
||||
int i;
|
||||
|
||||
/* see FileMonikerImpl_Save docs */
|
||||
zero_pos.QuadPart = 0;
|
||||
dead_pos.QuadPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD);
|
||||
nulls_pos.QuadPart = dead_pos.QuadPart + sizeof(WORD);
|
||||
|
||||
/* create the stream we're going to write to */
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
|
||||
ok_ole_success(hr, "CreateStreamOnHGlobal");
|
||||
|
||||
size.u.LowPart = 128;
|
||||
hr = IStream_SetSize(pStm, size);
|
||||
ok_ole_success(hr, "IStream_SetSize");
|
||||
|
||||
/* create and save a moniker */
|
||||
hr = CreateFileMoniker(wszFileName1, &pMk);
|
||||
ok_ole_success(hr, "CreateFileMoniker");
|
||||
|
||||
hr = IMoniker_Save(pMk, pStm, TRUE);
|
||||
ok_ole_success(hr, "IMoniker_Save");
|
||||
|
||||
hr = IMoniker_Release(pMk);
|
||||
ok_ole_success(hr, "IMoniker_Release");
|
||||
|
||||
/* overwrite the constants with various values */
|
||||
hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
|
||||
ok_ole_success(hr, "IStream_Write");
|
||||
|
||||
hr = IStream_Seek(pStm, dead_pos, STREAM_SEEK_SET, NULL);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
|
||||
ok_ole_success(hr, "IStream_Write");
|
||||
|
||||
hr = IStream_Seek(pStm, nulls_pos, STREAM_SEEK_SET, NULL);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
for(i = 0; i < 5; ++i){
|
||||
hr = IStream_Write(pStm, &some_val, sizeof(DWORD), NULL);
|
||||
ok_ole_success(hr, "IStream_Write");
|
||||
}
|
||||
|
||||
/* go back to the start of the stream */
|
||||
hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
|
||||
ok_ole_success(hr, "IStream_Seek");
|
||||
|
||||
/* create a new moniker and load into it */
|
||||
hr = CreateFileMoniker(wszFileName1, &pMk);
|
||||
ok_ole_success(hr, "CreateFileMoniker");
|
||||
|
||||
hr = IMoniker_Load(pMk, pStm);
|
||||
ok_ole_success(hr, "IMoniker_Load");
|
||||
|
||||
hr = IMoniker_Release(pMk);
|
||||
ok_ole_success(hr, "IMoniker_Release");
|
||||
|
||||
hr = IStream_Release(pStm);
|
||||
ok_ole_success(hr, "IStream_Release");
|
||||
}
|
||||
|
||||
START_TEST(moniker)
|
||||
{
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
@ -1866,6 +1946,7 @@ START_TEST(moniker)
|
|||
test_anti_moniker();
|
||||
test_generic_composite_moniker();
|
||||
test_pointer_moniker();
|
||||
test_save_load_filemoniker();
|
||||
|
||||
/* FIXME: test moniker creation funcs and parsing other moniker formats */
|
||||
|
||||
|
|
|
@ -1556,6 +1556,45 @@ static void test_runnable(void)
|
|||
g_showRunnable = TRUE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
|
||||
if (*ppv)
|
||||
{
|
||||
IUnknown_AddRef((IUnknown *)*ppv);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Unknown_Release(IUnknown *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const IUnknownVtbl UnknownVtbl =
|
||||
{
|
||||
Unknown_QueryInterface,
|
||||
Unknown_AddRef,
|
||||
Unknown_Release
|
||||
};
|
||||
|
||||
static IUnknown Unknown2 = { &UnknownVtbl };
|
||||
|
||||
static void test_OleLockRunning(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = OleLockRunning((LPUNKNOWN)&Unknown2, TRUE, FALSE);
|
||||
ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
|
||||
}
|
||||
|
||||
START_TEST(ole2)
|
||||
{
|
||||
DWORD dwRegister;
|
||||
|
@ -1587,6 +1626,7 @@ START_TEST(ole2)
|
|||
test_data_cache();
|
||||
test_default_handler();
|
||||
test_runnable();
|
||||
test_OleLockRunning();
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ static void testProps(void)
|
|||
ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val),
|
||||
"Didn't get expected type or value for property (got type %d, value %s)\n",
|
||||
var.vt, U(var).pszVal);
|
||||
PropVariantClear(&var);
|
||||
|
||||
/* read clipboard format */
|
||||
spec.ulKind = PRSPEC_PROPID;
|
||||
|
@ -282,6 +283,7 @@ static void testProps(void)
|
|||
ok(var.vt == VT_LPSTR && !lstrcmpA(U(var).pszVal, val),
|
||||
"Didn't get expected type or value for property (got type %d, value %s)\n",
|
||||
var.vt, U(var).pszVal);
|
||||
PropVariantClear(&var);
|
||||
|
||||
IPropertyStorage_Release(propertyStorage);
|
||||
IPropertySetStorage_Release(propSetStorage);
|
||||
|
@ -364,11 +366,13 @@ static void testCodepage(void)
|
|||
ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
|
||||
ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "hi"),
|
||||
"Didn't get expected type or value for property\n");
|
||||
PropVariantClear(&var);
|
||||
/* This seemingly non-sensical test is to show that the string is indeed
|
||||
* interpreted according to the current system code page, not according to
|
||||
* the property set's code page. (If the latter were true, the whole
|
||||
* string would be maintained. As it is, only the first character is.)
|
||||
*/
|
||||
var.vt = VT_LPSTR;
|
||||
U(var).pszVal = (LPSTR)wval;
|
||||
hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
|
||||
ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
|
||||
|
@ -376,6 +380,8 @@ static void testCodepage(void)
|
|||
ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr);
|
||||
ok(var.vt == VT_LPSTR && !strcmp(U(var).pszVal, "h"),
|
||||
"Didn't get expected type or value for property\n");
|
||||
PropVariantClear(&var);
|
||||
|
||||
/* now that a property's been set, you can't change the code page */
|
||||
spec.ulKind = PRSPEC_PROPID;
|
||||
U(spec).propid = PID_CODEPAGE;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
ULONG __RPC_USER HMETAFILE_UserSize(ULONG *, unsigned long, HMETAFILE *);
|
||||
ULONG __RPC_USER HMETAFILE_UserSize(ULONG *, ULONG, HMETAFILE *);
|
||||
unsigned char * __RPC_USER HMETAFILE_UserMarshal(ULONG *, unsigned char *, HMETAFILE *);
|
||||
unsigned char * __RPC_USER HMETAFILE_UserUnmarshal(ULONG *, unsigned char *, HMETAFILE *);
|
||||
void __RPC_USER HMETAFILE_UserFree(ULONG *, HMETAFILE *);
|
||||
|
@ -145,7 +145,7 @@ static void test_marshal_HWND(void)
|
|||
HWND_UserMarshal(&umcb.Flags, buffer, &hwnd);
|
||||
wirehwnd = (wireHWND)buffer;
|
||||
ok(wirehwnd->fContext == WDT_INPROC_CALL, "Context should be WDT_INPROC_CALL instead of 0x%08x\n", wirehwnd->fContext);
|
||||
ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %p\n", hwnd, (HANDLE)wirehwnd->u.hRemote);
|
||||
ok(wirehwnd->u.hInproc == (LONG_PTR)hwnd, "Marshaled value should be %p instead of %x\n", hwnd, wirehwnd->u.hRemote);
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
HWND_UserUnmarshal(&umcb.Flags, buffer, &hwnd2);
|
||||
|
@ -162,7 +162,7 @@ static void test_marshal_HGLOBAL(void)
|
|||
MIDL_STUB_MESSAGE stub_msg;
|
||||
RPC_MESSAGE rpc_msg;
|
||||
unsigned char *buffer;
|
||||
ULONG size;
|
||||
ULONG size, block_size;
|
||||
HGLOBAL hglobal;
|
||||
HGLOBAL hglobal2;
|
||||
unsigned char *wirehglobal;
|
||||
|
@ -188,39 +188,52 @@ static void test_marshal_HGLOBAL(void)
|
|||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
|
||||
|
||||
hglobal = GlobalAlloc(0, 4);
|
||||
buffer = GlobalLock(hglobal);
|
||||
for (i = 0; i < 4; i++)
|
||||
buffer[i] = i;
|
||||
GlobalUnlock(hglobal);
|
||||
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
|
||||
* here - Wine doesn't have to emulate that */
|
||||
ok((size == 24) || broken(size == 28) || broken(size == 32), "Size should be 24, instead of %d\n", size);
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
|
||||
wirehglobal = buffer;
|
||||
ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n");
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == 4, "buffer+0x8 should be size of HGLOBAL instead of %d\n", *(ULONG *)wirehglobal);
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n");
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == 4, "buffer+0x10 should be size of HGLOBAL instead of %d\n", *(ULONG *)wirehglobal);
|
||||
wirehglobal += sizeof(ULONG);
|
||||
for (i = 0; i < 4; i++)
|
||||
ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
|
||||
ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
|
||||
GlobalFree(hglobal);
|
||||
|
||||
for(block_size = 0; block_size <= 17; block_size++)
|
||||
{
|
||||
ULONG actual_size, expected_size;
|
||||
|
||||
hglobal = GlobalAlloc(0, block_size);
|
||||
buffer = GlobalLock(hglobal);
|
||||
for (i = 0; i < block_size; i++)
|
||||
buffer[i] = i;
|
||||
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
|
||||
* here - Wine doesn't have to emulate that */
|
||||
ok(size == expected_size ||
|
||||
broken(size == expected_size + 4) ||
|
||||
broken(size == expected_size + 8),
|
||||
"%d: got size %d\n", block_size, size);
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserMarshal(&umcb.Flags, buffer, &hglobal);
|
||||
wirehglobal = buffer;
|
||||
ok(*(ULONG *)wirehglobal == WDT_REMOTE_CALL, "Context should be WDT_REMOTE_CALL instead of 0x%08x\n", *(ULONG *)wirehglobal);
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0x4 should be HGLOBAL\n");
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x8 %08x\n", block_size, *(ULONG *)wirehglobal);
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == (ULONG)(ULONG_PTR)hglobal, "buffer+0xc should be HGLOBAL\n");
|
||||
wirehglobal += sizeof(ULONG);
|
||||
ok(*(ULONG *)wirehglobal == actual_size, "%d: buffer+0x10 %08x\n", block_size, *(ULONG *)wirehglobal);
|
||||
wirehglobal += sizeof(ULONG);
|
||||
for (i = 0; i < block_size; i++)
|
||||
ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i);
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2);
|
||||
ok(hglobal2 != NULL, "Didn't unmarshal properly\n");
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_LOCAL);
|
||||
HGLOBAL_UserFree(&umcb.Flags, &hglobal2);
|
||||
GlobalFree(hglobal);
|
||||
}
|
||||
}
|
||||
|
||||
static HENHMETAFILE create_emf(void)
|
||||
|
@ -495,14 +508,50 @@ static const IUnknownVtbl TestUnknown_Vtbl =
|
|||
Test_IUnknown_Release,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI Test_IStream_QueryInterface(IStream *iface,
|
||||
REFIID riid, LPVOID *ppvObj)
|
||||
{
|
||||
if (ppvObj == NULL) return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IStream))
|
||||
{
|
||||
*ppvObj = iface;
|
||||
IStream_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*ppvObj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_IStream_AddRef(IStream *iface)
|
||||
{
|
||||
return 2; /* non-heap-based object */
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_IStream_Release(IStream *iface)
|
||||
{
|
||||
return 1; /* non-heap-based object */
|
||||
}
|
||||
|
||||
static const IStreamVtbl TestStream_Vtbl =
|
||||
{
|
||||
Test_IStream_QueryInterface,
|
||||
Test_IStream_AddRef,
|
||||
Test_IStream_Release
|
||||
/* the rest can be NULLs */
|
||||
};
|
||||
|
||||
static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
|
||||
static IStream Test_Stream = { &TestStream_Vtbl };
|
||||
|
||||
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *, ULONG, ULONG, IUnknown *, REFIID);
|
||||
unsigned char * __RPC_USER WdtpInterfacePointer_UserMarshal(ULONG *, ULONG, unsigned char *, IUnknown *, REFIID);
|
||||
unsigned char * __RPC_USER WdtpInterfacePointer_UserUnmarshal(ULONG *, unsigned char *, IUnknown **, REFIID);
|
||||
void __RPC_USER WdtpInterfacePointer_UserFree(IUnknown *);
|
||||
|
||||
static void test_marshal_WdtpInterfacePointer(void)
|
||||
static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
|
||||
{
|
||||
USER_MARSHAL_CB umcb;
|
||||
MIDL_STUB_MESSAGE stub_msg;
|
||||
|
@ -512,64 +561,196 @@ static void test_marshal_WdtpInterfacePointer(void)
|
|||
IUnknown *unk;
|
||||
IUnknown *unk2;
|
||||
unsigned char *wireip;
|
||||
const IID *iid;
|
||||
HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
|
||||
IStream *stm;
|
||||
void *marshal_data;
|
||||
LARGE_INTEGER zero;
|
||||
ULARGE_INTEGER pos;
|
||||
DWORD marshal_size;
|
||||
|
||||
/* shows that the WdtpInterfacePointer functions don't marshal anything for
|
||||
* NULL pointers, so code using these functions must handle that case
|
||||
* itself */
|
||||
|
||||
unk = NULL;
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
|
||||
size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown);
|
||||
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 == 0, "size should be 0 bytes, not %d\n", size);
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown);
|
||||
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
|
||||
wireip = buffer;
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
|
||||
/* 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;
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
|
||||
size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 0, unk, &IID_IUnknown);
|
||||
todo_wine
|
||||
ok(size > 28, "size should be > 28 bytes, not %d\n", size);
|
||||
trace("WdtpInterfacePointer_UserSize returned %d\n", size);
|
||||
|
||||
CreateStreamOnHGlobal(h, TRUE, &stm);
|
||||
CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL);
|
||||
zero.QuadPart = 0;
|
||||
IStream_Seek(stm, zero, STREAM_SEEK_CUR, &pos);
|
||||
marshal_size = pos.u.LowPart;
|
||||
marshal_data = GlobalLock(h);
|
||||
trace("marshal_size %x\n", marshal_size);
|
||||
|
||||
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, MSHCTX_INPROC);
|
||||
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, buffer, unk, &IID_IUnknown);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
|
||||
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
|
||||
wireip = buffer;
|
||||
if (size >= 28)
|
||||
{
|
||||
ok(*(DWORD *)wireip == 0x44, "wireip + 0x0 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
ok(*(DWORD *)wireip == 0x44, "wireip + 0x4 should be 0x44 instead of 0x%08x\n", *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
ok(*(DWORD *)wireip == 0x574f454d /* 'MEOW' */, "wireip + 0x8 should be 0x574f454d instead of 0x%08x\n", *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
ok(*(DWORD *)wireip == 0x1, "wireip + 0xc should be 0x1 instead of 0x%08x\n", *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
iid = (const IID *)wireip;
|
||||
ok(IsEqualIID(iid, &IID_IUnknown),
|
||||
"wireip + 0x10 should be IID_IUnknown instead of {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
|
||||
iid->Data1, iid->Data2, iid->Data3,
|
||||
iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3],
|
||||
iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7]);
|
||||
wireip += sizeof(IID);
|
||||
ok(*(DWORD *)wireip == 0, "wireip + 0x1c should be 0 instead of 0x%08x\n", *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
ok(*(DWORD *)wireip == 5, "wireip + 0x20 should be 5 instead of %d\n", *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
/* the rest is dynamic so can't really be tested */
|
||||
}
|
||||
|
||||
ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p (diff %x)\n", buffer_end, buffer, buffer_end - buffer);
|
||||
|
||||
ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
|
||||
wireip += sizeof(DWORD);
|
||||
|
||||
ok(!memcmp(marshal_data, wireip, marshal_size), "buffer mismatch\n");
|
||||
GlobalUnlock(h);
|
||||
zero.QuadPart = 0;
|
||||
IStream_Seek(stm, zero, STREAM_SEEK_SET, NULL);
|
||||
CoReleaseMarshalData(stm);
|
||||
IStream_Release(stm);
|
||||
|
||||
unk2 = NULL;
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_INPROC);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx);
|
||||
WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown);
|
||||
todo_wine
|
||||
ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n");
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC);
|
||||
WdtpInterfacePointer_UserFree(unk2);
|
||||
}
|
||||
|
||||
static void test_marshal_WdtpInterfacePointer(void)
|
||||
{
|
||||
/*
|
||||
* There are two places where we can pass the marshalling ctx: as
|
||||
* part of the umcb and as a separate flag. The loword of that
|
||||
* separate flag field is what matters.
|
||||
*/
|
||||
|
||||
/* All three are marshalled as inproc */
|
||||
marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_INPROC);
|
||||
marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_INPROC);
|
||||
marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_INPROC, 0xffff));
|
||||
|
||||
/* All three are marshalled as remote */
|
||||
marshal_WdtpInterfacePointer(MSHCTX_INPROC, MSHCTX_DIFFERENTMACHINE);
|
||||
marshal_WdtpInterfacePointer(MSHCTX_DIFFERENTMACHINE, MSHCTX_DIFFERENTMACHINE);
|
||||
marshal_WdtpInterfacePointer(MSHCTX_INPROC, MAKELONG(MSHCTX_DIFFERENTMACHINE, 0xffff));
|
||||
}
|
||||
|
||||
static void test_marshal_STGMEDIUM(void)
|
||||
{
|
||||
USER_MARSHAL_CB umcb;
|
||||
MIDL_STUB_MESSAGE stub_msg;
|
||||
RPC_MESSAGE rpc_msg;
|
||||
unsigned char *buffer, *buffer_end, *expect_buffer, *expect_buffer_end;
|
||||
ULONG size, expect_size;
|
||||
STGMEDIUM med, med2;
|
||||
IUnknown *unk = &Test_Unknown;
|
||||
IStream *stm = &Test_Stream;
|
||||
|
||||
/* TYMED_NULL with pUnkForRelease */
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
||||
expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 2 * sizeof(DWORD), unk, &IID_IUnknown);
|
||||
expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
|
||||
expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 2 * sizeof(DWORD), unk, &IID_IUnknown);
|
||||
|
||||
med.tymed = TYMED_NULL;
|
||||
U(med).pstg = NULL;
|
||||
med.pUnkForRelease = unk;
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
||||
size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
|
||||
ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
|
||||
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
||||
buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
|
||||
ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n");
|
||||
ok(*(DWORD*)buffer == TYMED_NULL, "got %08x\n", *(DWORD*)buffer);
|
||||
ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1));
|
||||
ok(!memcmp(buffer+8, expect_buffer + 8, expect_buffer_end - expect_buffer - 8), "buffer mismatch\n");
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
||||
|
||||
/* native crashes if this is uninitialised, presumably because it
|
||||
tries to release it */
|
||||
med2.tymed = TYMED_NULL;
|
||||
U(med2).pstm = NULL;
|
||||
med2.pUnkForRelease = NULL;
|
||||
|
||||
STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
|
||||
|
||||
ok(med2.tymed == TYMED_NULL, "got tymed %x\n", med2.tymed);
|
||||
ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
||||
STGMEDIUM_UserFree(&umcb.Flags, &med2);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, expect_buffer);
|
||||
|
||||
/* TYMED_ISTREAM with pUnkForRelease */
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
||||
expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream);
|
||||
expect_size = WdtpInterfacePointer_UserSize(&umcb.Flags, umcb.Flags, expect_size, unk, &IID_IUnknown);
|
||||
|
||||
expect_buffer = HeapAlloc(GetProcessHeap(), 0, expect_size);
|
||||
/* There may be a hole between the two interfaces so init the buffer to something */
|
||||
memset(expect_buffer, 0xcc, expect_size);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, expect_buffer, expect_size, MSHCTX_DIFFERENTMACHINE);
|
||||
expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer + 3 * sizeof(DWORD), (IUnknown*)stm, &IID_IStream);
|
||||
expect_buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, umcb.Flags, expect_buffer_end, unk, &IID_IUnknown);
|
||||
|
||||
med.tymed = TYMED_ISTREAM;
|
||||
U(med).pstm = stm;
|
||||
med.pUnkForRelease = unk;
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
||||
size = STGMEDIUM_UserSize(&umcb.Flags, 0, &med);
|
||||
ok(size == expect_size, "size %d should be %d bytes\n", size, expect_size);
|
||||
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
memset(buffer, 0xcc, size);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
||||
buffer_end = STGMEDIUM_UserMarshal(&umcb.Flags, buffer, &med);
|
||||
ok(buffer_end - buffer == expect_buffer_end - expect_buffer, "buffer size mismatch\n");
|
||||
ok(*(DWORD*)buffer == TYMED_ISTREAM, "got %08x\n", *(DWORD*)buffer);
|
||||
ok(*((DWORD*)buffer+1) != 0, "got %08x\n", *((DWORD*)buffer+1));
|
||||
ok(*((DWORD*)buffer+2) != 0, "got %08x\n", *((DWORD*)buffer+2));
|
||||
ok(!memcmp(buffer + 12, expect_buffer + 12, (buffer_end - buffer) - 12), "buffer mismatch\n");
|
||||
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
|
||||
|
||||
/* native crashes if this is uninitialised, presumably because it
|
||||
tries to release it */
|
||||
med2.tymed = TYMED_NULL;
|
||||
U(med2).pstm = NULL;
|
||||
med2.pUnkForRelease = NULL;
|
||||
|
||||
STGMEDIUM_UserUnmarshal(&umcb.Flags, buffer, &med2);
|
||||
|
||||
ok(med2.tymed == TYMED_ISTREAM, "got tymed %x\n", med2.tymed);
|
||||
ok(U(med2).pstm != NULL, "Incorrectly unmarshalled\n");
|
||||
ok(med2.pUnkForRelease != NULL, "Incorrectly unmarshalled\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
|
||||
STGMEDIUM_UserFree(&umcb.Flags, &med2);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, expect_buffer);
|
||||
}
|
||||
|
||||
START_TEST(usrmarshal)
|
||||
{
|
||||
CoInitialize(NULL);
|
||||
|
@ -581,6 +762,7 @@ START_TEST(usrmarshal)
|
|||
test_marshal_HMETAFILE();
|
||||
test_marshal_HMETAFILEPICT();
|
||||
test_marshal_WdtpInterfacePointer();
|
||||
test_marshal_STGMEDIUM();
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue