[PATCH 3/4] comsvcs: Implement IPersistStream methods for "new" moniker.

Nikolay Sivov nsivov at codeweavers.com
Tue Nov 5 04:09:29 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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 58a5f26823..c7d6aaa613 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 8e59abc52b..bdd078da33 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);
 }
-- 
2.24.0.rc1




More information about the wine-devel mailing list