From 239055cfc71b241df94150b066e9f3be87102da4 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 5 Nov 2019 13:09:29 +0300 Subject: [PATCH] comsvcs: Implement IPersistStream methods for "new" moniker. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/comsvcs/main.c | 59 ++++++++++++++++++++++++++++++------ dlls/comsvcs/tests/comsvcs.c | 44 ++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index 58a5f268232..c7d6aaa6132 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -476,37 +476,76 @@ static ULONG WINAPI new_moniker_Release(IMoniker* iface) static HRESULT WINAPI new_moniker_GetClassID(IMoniker *iface, CLSID *clsid) { - FIXME("%p, %p.\n", iface, clsid); + TRACE("%p, %p.\n", iface, clsid); - return E_NOTIMPL; + if (!clsid) + return E_POINTER; + + *clsid = CLSID_NewMoniker; + + return S_OK; } static HRESULT WINAPI new_moniker_IsDirty(IMoniker* iface) { - FIXME("%p.\n", iface); + TRACE("%p.\n", iface); - return E_NOTIMPL; + return S_FALSE; } static HRESULT WINAPI new_moniker_Load(IMoniker *iface, IStream *stream) { - FIXME("%p, %p.\n", iface, stream); + struct new_moniker *moniker = impl_from_IMoniker(iface); + ULARGE_INTEGER pad; + CLSID clsid; + HRESULT hr; + DWORD len; - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, stream); + + hr = IStream_Read(stream, &clsid, sizeof(clsid), &len); + if (FAILED(hr)) + return hr; + + pad.QuadPart = 1; + hr = IStream_Read(stream, &pad, sizeof(pad), &len); + if (FAILED(hr)) + return hr; + + if (pad.QuadPart != 0) + return E_FAIL; + + moniker->clsid = clsid; + + return S_OK; } static HRESULT WINAPI new_moniker_Save(IMoniker *iface, IStream *stream, BOOL clear_dirty) { - FIXME("%p, %p, %d.\n", iface, stream, clear_dirty); + struct new_moniker *moniker = impl_from_IMoniker(iface); + static const ULARGE_INTEGER pad; + ULONG written; + HRESULT hr; - return E_NOTIMPL; + TRACE("%p, %p, %d.\n", iface, stream, clear_dirty); + + hr = IStream_Write(stream, &moniker->clsid, sizeof(moniker->clsid), &written); + if (SUCCEEDED(hr)) + hr = IStream_Write(stream, &pad, sizeof(pad), &written); + + return hr; } static HRESULT WINAPI new_moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *size) { - FIXME("%p, %p.\n", iface, size); + TRACE("%p, %p.\n", iface, size); - return E_NOTIMPL; + if (!size) + return E_POINTER; + + size->QuadPart = sizeof(CLSID) + 2 * sizeof(DWORD); + + return S_OK; } static HRESULT WINAPI new_moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, diff --git a/dlls/comsvcs/tests/comsvcs.c b/dlls/comsvcs/tests/comsvcs.c index 8e59abc52b5..bdd078da33c 100644 --- a/dlls/comsvcs/tests/comsvcs.c +++ b/dlls/comsvcs/tests/comsvcs.c @@ -270,13 +270,17 @@ static void create_dispenser(void) static void test_new_moniker(void) { IMoniker *moniker, *moniker2, *inverse, *class_moniker; + IUnknown *obj, *obj2; + ULARGE_INTEGER size; DWORD moniker_type; IBindCtx *bindctx; FILETIME filetime; DWORD hash, eaten; - IUnknown *obj, *obj2; + IStream *stream; + HGLOBAL hglobal; CLSID clsid; HRESULT hr; + void *ptr; hr = CreateBindCtx(0, &bindctx); ok(hr == S_OK, "Failed to create bind context, hr %#x.\n", hr); @@ -372,6 +376,44 @@ todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); 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); + + hr = IMoniker_IsDirty(moniker); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + + hr = IMoniker_GetClassID(moniker, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + IMoniker_Release(moniker); IBindCtx_Release(bindctx); }