[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