[PATCH 1/2] ole32/tests: Add a test for custom ILockBytes on HGlobal implementation.

Dmitry Timoshkov dmitry at baikal.ru
Tue Mar 30 09:41:37 CDT 2021


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/ole32/tests/storage32.c | 164 +++++++++++++++++++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c
index eea78c6d3fe..da2e411eea4 100644
--- a/dlls/ole32/tests/storage32.c
+++ b/dlls/ole32/tests/storage32.c
@@ -3876,6 +3876,9 @@ static void test_custom_lockbytes(void)
 
     hr = IStorage_Commit(stg, 0);
 
+    ok(lockbytes->contents != NULL, "lockbytes->contents should not be NULL\n");
+    ok(*(DWORD *)lockbytes->contents == 0xe011cfd0, "contents: %08x\n", *(DWORD *)lockbytes->contents);
+
     IStorage_Release(stg);
 
     ok(!lockbytes->lock_called, "unexpected call to LockRegion\n");
@@ -3904,6 +3907,166 @@ static void test_custom_lockbytes(void)
     DeleteTestLockBytes(lockbytes);
 }
 
+struct byte_array_t
+{
+    ILockBytes ILockBytes_iface;
+    ILockBytes *lock_bytes;
+    HGLOBAL mem;
+    LONG ref;
+};
+
+static inline struct byte_array_t *byte_array_from_ILockBytes(ILockBytes *iface)
+{
+    return CONTAINING_RECORD(iface, struct byte_array_t, ILockBytes_iface);
+}
+
+static HRESULT WINAPI byte_array_QueryInterface(ILockBytes *iface, REFIID iid, void **ppv)
+{
+    if (!ppv) return E_INVALIDARG;
+
+    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_ILockBytes, iid))
+    {
+        ILockBytes_AddRef(iface);
+        *ppv = iface;
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI byte_array_AddRef(ILockBytes *iface)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI byte_array_Release(ILockBytes *iface)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+    if (!ref)
+    {
+        ILockBytes_Release(This->lock_bytes);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+static HRESULT WINAPI byte_array_ReadAt(ILockBytes *iface,
+    ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return ILockBytes_ReadAt(This->lock_bytes, ulOffset, pv, cb, pcbRead);
+}
+
+static HRESULT WINAPI byte_array_WriteAt(ILockBytes *iface,
+    ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return ILockBytes_WriteAt(This->lock_bytes, ulOffset, pv, cb, pcbWritten);
+}
+
+static HRESULT WINAPI byte_array_Flush(ILockBytes *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI byte_array_SetSize(ILockBytes *iface, ULARGE_INTEGER cb)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return ILockBytes_SetSize(This->lock_bytes, cb);
+}
+
+static HRESULT WINAPI byte_array_LockRegion(ILockBytes *iface,
+    ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return ILockBytes_LockRegion(This->lock_bytes, libOffset, cb, dwLockType);
+}
+
+static HRESULT WINAPI byte_array_UnlockRegion(ILockBytes *iface,
+    ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return ILockBytes_UnlockRegion(This->lock_bytes, libOffset, cb, dwLockType);
+}
+
+static HRESULT WINAPI byte_array_Stat(ILockBytes *iface,
+    STATSTG *pstatstg, DWORD grfStatFlag)
+{
+    struct byte_array_t *This = byte_array_from_ILockBytes(iface);
+    return ILockBytes_Stat(This->lock_bytes, pstatstg, grfStatFlag);
+}
+
+static const ILockBytesVtbl byte_array_Vtbl =
+{
+    byte_array_QueryInterface,
+    byte_array_AddRef,
+    byte_array_Release,
+    byte_array_ReadAt,
+    byte_array_WriteAt,
+    byte_array_Flush,
+    byte_array_SetSize,
+    byte_array_LockRegion,
+    byte_array_UnlockRegion,
+    byte_array_Stat
+};
+
+static struct byte_array_t *create_byte_array(void)
+{
+    struct byte_array_t *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+    if (This)
+    {
+        HRESULT hr;
+
+        This->ref = 1;
+        This->ILockBytes_iface.lpVtbl = &byte_array_Vtbl;
+        This->mem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 1024);
+        hr = CreateILockBytesOnHGlobal(This->mem, TRUE, &This->lock_bytes);
+        ok(hr == S_OK, "CreateILockBytesOnHGlobal error %#x\n", hr);
+    }
+    return This;
+}
+
+static void test_custom_lockbytes_on_hglobal(void)
+{
+    static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
+    struct byte_array_t *This;
+    HRESULT hr;
+    IStorage *stg;
+    IStream *stm;
+    DWORD *p;
+
+    This = create_byte_array();
+
+    hr = StgCreateDocfileOnILockBytes(&This->ILockBytes_iface, STGM_CREATE | STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE, 0, &stg);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    hr = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    IStream_Write(stm, "Hello World!", 12, NULL);
+    IStream_Release(stm);
+
+    p = GlobalLock(This->mem);
+todo_wine
+    ok(*p == 0, "got %#x\n", *p);
+    memset(p, 0, 512);
+    GlobalUnlock(This->mem);
+
+    hr = IStorage_Commit(stg, STGC_DEFAULT);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    IStorage_Release(stg);
+
+    p = GlobalLock(This->mem);
+todo_wine
+    ok(*p == 0xe011cfd0, "got %#x\n", *p);
+    GlobalUnlock(This->mem);
+
+    ILockBytes_Release(&This->ILockBytes_iface);
+}
+
 START_TEST(storage32)
 {
     CHAR temp[MAX_PATH];
@@ -3953,4 +4116,5 @@ START_TEST(storage32)
     test_transacted_shared();
     test_overwrite();
     test_custom_lockbytes();
+    test_custom_lockbytes_on_hglobal();
 }
-- 
2.30.2




More information about the wine-devel mailing list