Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/main.c | 37 ++++++++++++++++++++++++++++++++++-- dlls/comsvcs/tests/comsvcs.c | 8 ++------ 2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 86ffe2587b..827a6e8e5e 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -551,9 +551,42 @@ static HRESULT WINAPI new_moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *si static HRESULT WINAPI new_moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ret) { - FIXME("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret); + struct new_moniker *moniker = impl_from_IMoniker(iface); + IClassActivator *activator; + IClassFactory *factory; + BIND_OPTS2 bindopts; + MULTI_QI qi; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p, %p, %s, %p.\n", iface, pbc, pmkToLeft, debugstr_guid(riid), ret); + + bindopts.cbStruct = sizeof(bindopts); + if (FAILED(hr = IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts))) + return hr; + + if (!pmkToLeft) + { + qi.pIID = riid; + qi.pItf = NULL; + qi.hr = S_OK; + hr = CoCreateInstanceEx(&moniker->clsid, NULL, bindopts.dwClassContext, bindopts.pServerInfo, 1, &qi); + *ret = qi.pItf; + } + else + { + if (SUCCEEDED(hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator, (void **)&activator))) + { + hr = IClassActivator_GetClassObject(activator, &moniker->clsid, bindopts.dwClassContext, bindopts.locale, riid, ret); + IClassActivator_Release(activator); + } + else if (SUCCEEDED(hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassFactory, (void **)&factory))) + { + hr = IClassFactory_CreateInstance(factory, NULL, riid, ret); + IClassFactory_Release(factory); + } + } + + return hr; }
static HRESULT WINAPI new_moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index d94b99afd1..29de7cfe97 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -352,10 +352,8 @@ todo_wine ok(hr == MK_E_UNAVAILABLE, "Unexpected hr %#x.\n", hr);
hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&obj); -todo_wine ok(hr == S_OK, "Failed to bind to object, hr %#x.\n", hr); - if (SUCCEEDED(hr)) - IUnknown_Release(obj); + IUnknown_Release(obj);
hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&obj); todo_wine @@ -423,10 +421,8 @@ todo_wine bind_opts.dwClassContext = CLSCTX_INPROC_SERVER;
hr = CoGetObject(L"new:msxml2.domdocument", (BIND_OPTS *)&bind_opts, &IID_IXMLDOMDocument, (void **)&obj); -todo_wine ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr); - if (SUCCEEDED(hr)) - IUnknown_Release(obj); + IUnknown_Release(obj);
IBindCtx_Release(bindctx); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/tests/comsvcs.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index 29de7cfe97..d75cbfc642 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -58,6 +58,15 @@ DEFINE_EXPECT(driver_DestroyResource); DEFINE_EXPECT(driver_ResetResource); DEFINE_EXPECT(driver_Release);
+#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) +static void _expect_ref(IUnknown* obj, ULONG ref, int line) +{ + ULONG rc; + IUnknown_AddRef(obj); + rc = IUnknown_Release(obj); + ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); +} + HRESULT driver_DestroyResource_ret = S_OK;
static HRESULT WINAPI driver_QueryInterface(IDispenserDriver *iface, REFIID riid, void **object) @@ -270,6 +279,7 @@ static void create_dispenser(void) static void test_new_moniker(void) { IMoniker *moniker, *moniker2, *inverse, *class_moniker; + IRunningObjectTable *rot; IUnknown *obj, *obj2; BIND_OPTS2 bind_opts; ULARGE_INTEGER size; @@ -425,6 +435,32 @@ todo_wine IUnknown_Release(obj);
IBindCtx_Release(bindctx); + + /* Returned object is not bound to context. */ + hr = CreateBindCtx(0, &bindctx); + ok(hr == S_OK, "Failed to create bind context, hr %#x.\n", hr); + + eaten = 0; + hr = MkParseDisplayName(bindctx, L"new:msxml2.domdocument", &eaten, &moniker); + ok(hr == S_OK, "Failed to parse display name, hr %#x.\n", hr); + ok(eaten, "Unexpected eaten length %u.\n", eaten); + + hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&obj); + ok(hr == S_OK, "Failed to bind to object, hr %#x.\n", hr); + EXPECT_REF(obj, 1); + + hr = IBindCtx_GetRunningObjectTable(bindctx, &rot); + ok(hr == S_OK, "Failed to get rot, hr %#x.\n", hr); + + hr = IRunningObjectTable_GetObject(rot, moniker, &obj2); +todo_wine + ok(hr == MK_E_UNAVAILABLE, "Unexpected hr %#x.\n", hr); + + IRunningObjectTable_Release(rot); + + IUnknown_Release(obj); + + IBindCtx_Release(bindctx); }
START_TEST(comsvcs)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/tests/comsvcs.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index d75cbfc642..63db25bed2 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -67,7 +67,16 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); }
-HRESULT driver_DestroyResource_ret = S_OK; +struct test_driver +{ + IDispenserDriver IDispenserDriver_iface; + HRESULT destroy_resource_hr; +}; + +static struct test_driver *impl_from_IDispenserDriver(IDispenserDriver *iface) +{ + return CONTAINING_RECORD(iface, struct test_driver, IDispenserDriver_iface); +}
static HRESULT WINAPI driver_QueryInterface(IDispenserDriver *iface, REFIID riid, void **object) { @@ -125,8 +134,9 @@ static HRESULT WINAPI driver_ResetResource(IDispenserDriver *iface, const RESID
static HRESULT WINAPI driver_DestroyResource(IDispenserDriver *iface, const RESID resid) { + struct test_driver *driver = impl_from_IDispenserDriver(iface); todo_wine CHECK_EXPECT2(driver_DestroyResource); - return driver_DestroyResource_ret; + return driver->destroy_resource_hr; }
static HRESULT WINAPI driver_DestroyResourceS(IDispenserDriver *iface, const SRESID resid) @@ -149,7 +159,11 @@ static const struct IDispenserDriverVtbl driver_vtbl = driver_DestroyResourceS };
-static IDispenserDriver DispenserDriver = { &driver_vtbl }; +static void init_test_driver(struct test_driver *driver) +{ + driver->IDispenserDriver_iface.lpVtbl = &driver_vtbl; + driver->destroy_resource_hr = S_OK; +}
static DWORD WINAPI com_thread(void *arg) { @@ -174,6 +188,7 @@ static void create_dispenser(void) RESID resid; DWORD ret; BSTR str; + struct test_driver driver;
hr = CoCreateInstance( &CLSID_DispenserManager, NULL, CLSCTX_ALL, &IID_IDispenserManager, (void**)&dispenser); ok(hr == S_OK, "Failed to create object 0x%08x\n", hr); @@ -188,7 +203,9 @@ static void create_dispenser(void) GetExitCodeThread(thread, &ret); ok(ret == CO_E_NOTINITIALIZED, "got unexpected hr %#x\n", ret);
- hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool0, &holder1); + init_test_driver(&driver); + + hr = IDispenserManager_RegisterDispenser(dispenser, &driver.IDispenserDriver_iface, pool0, &holder1); ok(hr == S_OK, "got 0x%08x\n", hr);
/* The above call creates an MTA thread, but we need to wait for it to @@ -199,11 +216,11 @@ static void create_dispenser(void) GetExitCodeThread(thread, &ret); ok(ret == S_OK, "got unexpected hr %#x\n", ret);
- hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool0, &holder2); + hr = IDispenserManager_RegisterDispenser(dispenser, &driver.IDispenserDriver_iface, pool0, &holder2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(holder1 != holder2, "same holder object returned\n");
- hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool1, &holder3); + hr = IDispenserManager_RegisterDispenser(dispenser, &driver.IDispenserDriver_iface, pool1, &holder3); ok(hr == S_OK, "got 0x%08x\n", hr);
if(holder1) @@ -254,14 +271,14 @@ static void create_dispenser(void) todo_wine CHECK_CALLED(driver_ResetResource);
/* DestroyResource return doesn't directly affect the Holder Close return value */ - driver_DestroyResource_ret = E_FAIL; + driver.destroy_resource_hr = E_FAIL; SET_EXPECT(driver_DestroyResource); SET_EXPECT(driver_Release); hr = IHolder_Close(holder2); ok(hr == S_OK, "got 0x%08x\n", hr); CHECK_CALLED(driver_Release); CHECK_CALLED(driver_DestroyResource); - driver_DestroyResource_ret = S_OK; + driver.destroy_resource_hr = S_OK; IHolder_Release(holder2); } if(holder3)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/main.c | 10 ++++++++-- dlls/comsvcs/tests/comsvcs.c | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 827a6e8e5e..0f287a681f 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -600,9 +600,15 @@ static HRESULT WINAPI new_moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, static HRESULT WINAPI new_moniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD flags, IMoniker **ppmkToLeft, IMoniker **ret) { - FIXME("%p, %p, %d, %p, %p.\n", iface, pbc, flags, ppmkToLeft, ret); + TRACE("%p, %p, %d, %p, %p.\n", iface, pbc, flags, ppmkToLeft, ret);
- return E_NOTIMPL; + if (!ret) + return E_POINTER; + + *ret = iface; + IMoniker_AddRef(iface); + + return MK_S_REDUCED_TO_SELF; }
static HRESULT WINAPI new_moniker_ComposeWith(IMoniker *iface, IMoniker *mkRight, BOOL fOnlyIfNotGeneric, diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index 63db25bed2..4d37b60eb9 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -295,7 +295,7 @@ static void create_dispenser(void)
static void test_new_moniker(void) { - IMoniker *moniker, *moniker2, *inverse, *class_moniker; + IMoniker *moniker, *moniker2, *inverse, *class_moniker, *moniker_left; IRunningObjectTable *rot; IUnknown *obj, *obj2; BIND_OPTS2 bind_opts; @@ -356,6 +356,22 @@ static void test_new_moniker(void)
IMoniker_Release(class_moniker);
+ /* Reducing. */ + moniker_left = (void *)0xdeadbeef; + hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ONE, &moniker_left, &moniker2); + ok(hr == MK_S_REDUCED_TO_SELF, "Unexpected hr %#x.\n", hr); + ok(moniker_left == (void *)0xdeadbeef, "Unexpected left moniker.\n"); + ok(moniker2 == moniker, "Unexpected returned moniker.\n"); + IMoniker_Release(moniker2); + + hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ONE, NULL, &moniker2); + ok(hr == MK_S_REDUCED_TO_SELF, "Unexpected hr %#x.\n", hr); + ok(moniker2 == moniker, "Unexpected returned moniker.\n"); + IMoniker_Release(moniker2); + + hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ONE, NULL, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + /* Hashing */ hash = 0; hr = IMoniker_Hash(moniker, &hash);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/main.c | 46 ++++++++++++++++++++++++++++++++++++ dlls/comsvcs/tests/comsvcs.c | 5 ++++ 2 files changed, 51 insertions(+)
diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 0f287a681f..7bfde03b34 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -54,6 +54,7 @@ typedef struct holder struct new_moniker { IMoniker IMoniker_iface; + IROTData IROTData_iface; LONG refcount; CLSID clsid; }; @@ -75,6 +76,11 @@ static struct new_moniker *impl_from_IMoniker(IMoniker *iface) return CONTAINING_RECORD(iface, struct new_moniker, IMoniker_iface); }
+static struct new_moniker *impl_from_IROTData(IROTData *iface) +{ + return CONTAINING_RECORD(iface, struct new_moniker, IROTData_iface); +} + static HRESULT WINAPI holder_QueryInterface(IHolder *iface, REFIID riid, void **object) { holder *This = impl_from_IHolder(iface); @@ -429,6 +435,8 @@ static const IClassFactoryVtbl comsvcscf_vtbl =
static HRESULT WINAPI new_moniker_QueryInterface(IMoniker* iface, REFIID riid, void **obj) { + struct new_moniker *moniker = impl_from_IMoniker(iface); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
*obj = NULL; @@ -440,6 +448,10 @@ static HRESULT WINAPI new_moniker_QueryInterface(IMoniker* iface, REFIID riid, v { *obj = iface; } + else if (IsEqualIID(&IID_IROTData, riid)) + { + *obj = &moniker->IROTData_iface; + }
if (*obj) { @@ -738,6 +750,39 @@ static const IMonikerVtbl new_moniker_vtbl = new_moniker_IsSystemMoniker };
+static HRESULT WINAPI new_moniker_rotdata_QueryInterface(IROTData *iface, REFIID riid, void **obj) +{ + struct new_moniker *moniker = impl_from_IROTData(iface); + return IMoniker_QueryInterface(&moniker->IMoniker_iface, riid, obj); +} + +static ULONG WINAPI new_moniker_rotdata_AddRef(IROTData *iface) +{ + struct new_moniker *moniker = impl_from_IROTData(iface); + return IMoniker_AddRef(&moniker->IMoniker_iface); +} + +static ULONG WINAPI new_moniker_rotdata_Release(IROTData *iface) +{ + struct new_moniker *moniker = impl_from_IROTData(iface); + return IMoniker_Release(&moniker->IMoniker_iface); +} + +static HRESULT WINAPI new_moniker_rotdata_GetComparisonData(IROTData *iface, byte *data, ULONG data_len, ULONG *length) +{ + FIXME("%p, %p, %u, %p.\n", iface, data, data_len, length); + + return E_NOTIMPL; +} + +static const IROTDataVtbl new_moniker_rotdata_vtbl = +{ + new_moniker_rotdata_QueryInterface, + new_moniker_rotdata_AddRef, + new_moniker_rotdata_Release, + new_moniker_rotdata_GetComparisonData, +}; + static const BYTE guid_conv_table[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */ @@ -837,6 +882,7 @@ static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG return E_OUTOFMEMORY;
moniker->IMoniker_iface.lpVtbl = &new_moniker_vtbl; + moniker->IROTData_iface.lpVtbl = &new_moniker_rotdata_vtbl; moniker->refcount = 1; moniker->clsid = guid;
diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index 4d37b60eb9..3b15a1f7e6 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -301,6 +301,7 @@ static void test_new_moniker(void) BIND_OPTS2 bind_opts; ULARGE_INTEGER size; DWORD moniker_type; + IROTData *rot_data; IBindCtx *bindctx; FILETIME filetime; DWORD hash, eaten; @@ -318,6 +319,10 @@ static void test_new_moniker(void) ok(hr == S_OK, "Failed to parse display name, hr %#x.\n", hr); ok(eaten == 40, "Unexpected eaten length %u.\n", eaten);
+ hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rot_data); + ok(hr == S_OK, "Failed to get IROTData, hr %#x.\n", hr); + IROTData_Release(rot_data); + eaten = 0; hr = IMoniker_ParseDisplayName(moniker, bindctx, NULL, (WCHAR *)L"new:20d04fe0-3aea-1069-a2d8-08002b30309d", &eaten, &moniker2);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/main.c | 71 ++++++++++++++++----- dlls/comsvcs/tests/comsvcs.c | 115 ++++++++++++++++++++++++----------- 2 files changed, 138 insertions(+), 48 deletions(-)
diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 7bfde03b34..9ab77dfced 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -57,6 +57,7 @@ struct new_moniker IROTData IROTData_iface; LONG refcount; CLSID clsid; + WCHAR *progid; };
static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret); @@ -481,7 +482,10 @@ static ULONG WINAPI new_moniker_Release(IMoniker* iface) TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) + { + heap_free(moniker->progid); heap_free(moniker); + }
return refcount; } @@ -508,10 +512,10 @@ static HRESULT WINAPI new_moniker_IsDirty(IMoniker* iface) static HRESULT WINAPI new_moniker_Load(IMoniker *iface, IStream *stream) { struct new_moniker *moniker = impl_from_IMoniker(iface); - ULARGE_INTEGER pad; + DWORD progid_len = 0, len, pad = ~0u; + WCHAR *progid = NULL; CLSID clsid; HRESULT hr; - DWORD len;
TRACE("%p, %p.\n", iface, stream);
@@ -519,29 +523,49 @@ static HRESULT WINAPI new_moniker_Load(IMoniker *iface, IStream *stream) if (FAILED(hr)) return hr;
- pad.QuadPart = 1; - hr = IStream_Read(stream, &pad, sizeof(pad), &len); - if (FAILED(hr)) - return hr; + if (SUCCEEDED(hr)) + hr = IStream_Read(stream, &progid_len, sizeof(progid_len), &len);
- if (pad.QuadPart != 0) - return E_FAIL; + if (SUCCEEDED(hr) && progid_len) + { + if (!(progid = heap_alloc(progid_len))) + return E_OUTOFMEMORY; + hr = IStream_Read(stream, progid, progid_len, &len); + }
- moniker->clsid = clsid; + /* Skip terminator. */ + if (SUCCEEDED(hr)) + hr = IStream_Read(stream, &pad, sizeof(pad), &len);
- return S_OK; + if (SUCCEEDED(hr) && pad == 0) + { + moniker->clsid = clsid; + heap_free(moniker->progid); + moniker->progid = progid; + progid = NULL; + } + + heap_free(progid); + + return hr; }
static HRESULT WINAPI new_moniker_Save(IMoniker *iface, IStream *stream, BOOL clear_dirty) { struct new_moniker *moniker = impl_from_IMoniker(iface); - static const ULARGE_INTEGER pad; - ULONG written; + ULONG written, pad = 0, progid_len = 0; HRESULT hr;
TRACE("%p, %p, %d.\n", iface, stream, clear_dirty);
+ if (moniker->progid) + progid_len = lstrlenW(moniker->progid) * sizeof(WCHAR); + hr = IStream_Write(stream, &moniker->clsid, sizeof(moniker->clsid), &written); + if (SUCCEEDED(hr)) + hr = IStream_Write(stream, &progid_len, sizeof(progid_len), &written); + if (SUCCEEDED(hr) && progid_len) + hr = IStream_Write(stream, moniker->progid, progid_len, &written); if (SUCCEEDED(hr)) hr = IStream_Write(stream, &pad, sizeof(pad), &written);
@@ -550,12 +574,16 @@ static HRESULT WINAPI new_moniker_Save(IMoniker *iface, IStream *stream, BOOL cl
static HRESULT WINAPI new_moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size) { + struct new_moniker *moniker = impl_from_IMoniker(iface); + TRACE("%p, %p.\n", iface, size);
if (!size) return E_POINTER;
size->QuadPart = sizeof(CLSID) + 2 * sizeof(DWORD); + if (moniker->progid) + size->QuadPart += lstrlenW(moniker->progid) * sizeof(WCHAR);
return S_OK; } @@ -867,15 +895,21 @@ static HRESULT guid_from_string(const WCHAR *s, GUID *ret) static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG *eaten, IMoniker **ret) { struct new_moniker *moniker; + WCHAR *progid = NULL, *str; GUID guid;
*ret = NULL;
if (wcsnicmp(name, L"new:", 4)) return MK_E_SYNTAX; + str = name + 4;
- if (!guid_from_string(name + 4, &guid) && FAILED(CLSIDFromProgID(name + 4, &guid))) - return MK_E_SYNTAX; + if (!guid_from_string(str, &guid)) + { + if (FAILED(CLSIDFromProgID(str, &guid))) + return MK_E_SYNTAX; + progid = str; + }
moniker = heap_alloc_zero(sizeof(*moniker)); if (!moniker) @@ -885,6 +919,15 @@ static HRESULT new_moniker_parse_displayname(IBindCtx *pbc, LPOLESTR name, ULONG moniker->IROTData_iface.lpVtbl = &new_moniker_rotdata_vtbl; moniker->refcount = 1; moniker->clsid = guid; + if (progid) + { + if (!(moniker->progid = heap_alloc((lstrlenW(progid) + 1) * sizeof(WCHAR)))) + { + IMoniker_Release(&moniker->IMoniker_iface); + return E_OUTOFMEMORY; + } + lstrcpyW(moniker->progid, progid); + }
*ret = &moniker->IMoniker_iface;
diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index 3b15a1f7e6..e6717e0ea3 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -293,23 +293,90 @@ static void create_dispenser(void) IDispenserManager_Release(dispenser); }
+static void test_new_moniker_serialize(const WCHAR *clsid, const WCHAR *progid, IMoniker *moniker) +{ + DWORD expected_size, progid_len = 0; + ULARGE_INTEGER size; + IStream *stream; + HGLOBAL hglobal; + CLSID guid; + HRESULT hr; + DWORD *ptr; + + hr = IMoniker_GetSizeMax(moniker, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + expected_size = sizeof(GUID) + 2 * sizeof(DWORD); + if (progid) + { + progid_len = lstrlenW(progid) * sizeof(*progid); + expected_size += progid_len; + } + + size.QuadPart = 0; + hr = IMoniker_GetSizeMax(moniker, &size); + ok(hr == S_OK, "Failed to get size, hr %#x.\n", hr); + ok(size.QuadPart == expected_size, "Unexpected size %s, expected %#x.\n", wine_dbgstr_longlong(size.QuadPart), + expected_size); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); + + hr = IMoniker_Save(moniker, stream, FALSE); + ok(hr == S_OK, "Failed to save moniker, hr %#x.\n", hr); + + hr = GetHGlobalFromStream(stream, &hglobal); + ok(hr == S_OK, "Failed to get a handle, hr %#x.\n", hr); + + ptr = GlobalLock(hglobal); + ok(!!ptr, "Failed to get data pointer.\n"); + + hr = CLSIDFromString(clsid, &guid); + ok(hr == S_OK, "Failed to get CLSID, hr %#x.\n", hr); + ok(IsEqualGUID((GUID *)ptr, &guid), "Unexpected buffer content.\n"); + ptr += sizeof(GUID)/sizeof(DWORD); + + /* Serialization format: + + GUID guid; + DWORD progid_len; + WCHAR progid[progid_len/2]; + DWORD null; + */ + + if (progid) + { + ok(*ptr == progid_len, "Unexpected progid length.\n"); + ptr++; + ok(!memcmp(ptr, progid, progid_len), "Unexpected progid.\n"); + ptr += progid_len / sizeof(DWORD); + } + else + { + ok(*ptr == 0, "Unexpected progid length.\n"); + ptr++; + } + ok(*ptr == 0, "Unexpected terminator.\n"); + + GlobalUnlock(hglobal); + + IStream_Release(stream); +} + static void test_new_moniker(void) { IMoniker *moniker, *moniker2, *inverse, *class_moniker, *moniker_left; IRunningObjectTable *rot; IUnknown *obj, *obj2; BIND_OPTS2 bind_opts; - ULARGE_INTEGER size; DWORD moniker_type; IROTData *rot_data; IBindCtx *bindctx; FILETIME filetime; DWORD hash, eaten; - IStream *stream; - HGLOBAL hglobal; CLSID clsid; HRESULT hr; - void *ptr; + WCHAR *str;
hr = CreateBindCtx(0, &bindctx); ok(hr == S_OK, "Failed to create bind context, hr %#x.\n", hr); @@ -424,36 +491,7 @@ todo_wine ok(obj == NULL, "Unexpected return value.\n");
/* Serialization. */ - hr = IMoniker_GetSizeMax(moniker, NULL); - ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); - - size.QuadPart = 0; - hr = IMoniker_GetSizeMax(moniker, &size); - ok(hr == S_OK, "Failed to get size, hr %#x.\n", hr); - ok(size.QuadPart == (sizeof(GUID) + 2 * sizeof(DWORD)), "Unexpected size %s.\n", - wine_dbgstr_longlong(size.QuadPart)); - - hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); - ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr); - - hr = IMoniker_Save(moniker, stream, FALSE); - ok(hr == S_OK, "Failed to save moniker, hr %#x.\n", hr); - - hr = GetHGlobalFromStream(stream, &hglobal); - ok(hr == S_OK, "Failed to get a handle, hr %#x.\n", hr); - - ptr = GlobalLock(hglobal); - ok(!!ptr, "Failed to get data pointer.\n"); - - hr = CLSIDFromString(L"{20d04fe0-3aea-1069-a2d8-08002b30309d}", &clsid); - ok(hr == S_OK, "Failed to get CLSID, hr %#x.\n", hr); - ok(IsEqualGUID((GUID *)ptr, &clsid), "Unexpected buffer content.\n"); - ok(*(DWORD *)((BYTE *)ptr + sizeof(GUID)) == 0, "Unexpected buffer content.\n"); - ok(*(DWORD *)((BYTE *)ptr + sizeof(GUID) + sizeof(DWORD)) == 0, "Unexpected buffer content.\n"); - - GlobalUnlock(hglobal); - - IStream_Release(stream); + test_new_moniker_serialize(L"{20d04fe0-3aea-1069-a2d8-08002b30309d}", NULL, moniker);
hr = IMoniker_IsDirty(moniker); ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); @@ -483,6 +521,15 @@ todo_wine ok(hr == S_OK, "Failed to parse display name, hr %#x.\n", hr); ok(eaten, "Unexpected eaten length %u.\n", eaten);
+ hr = CLSIDFromProgID(L"msxml2.domdocument", &clsid); + ok(hr == S_OK, "Failed to get clsid, hr %#x.\n", hr); + + hr = StringFromCLSID(&clsid, &str); + ok(hr == S_OK, "Failed to get guid string, hr %#x.\n", hr); + + test_new_moniker_serialize(str, L"msxml2.domdocument", moniker); + CoTaskMemFree(str); + hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&obj); ok(hr == S_OK, "Failed to bind to object, hr %#x.\n", hr); EXPECT_REF(obj, 1);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comsvcs/tests/comsvcs.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index e6717e0ea3..ca59951c81 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -42,7 +42,6 @@
#define CHECK_EXPECT2(func) \ do { \ - trace(#func "\n"); \ ok(expect_ ##func, "unexpected call " #func "\n"); \ called_ ## func = TRUE; \ }while(0) @@ -94,7 +93,6 @@ static HRESULT WINAPI driver_QueryInterface(IDispenserDriver *iface, REFIID riid
static ULONG WINAPI driver_AddRef(IDispenserDriver *iface) { - trace("AddRef\n"); return 2; }