[1/2] ole32: Add a storage test using a custom ILockBytes.
Vincent Povirk
madewokherd at gmail.com
Mon Jul 6 15:31:24 CDT 2015
-------------- next part --------------
From 2932b0ba7dfe075c9e64c591f75113c7d5b1bc04 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Mon, 6 Jul 2015 14:17:17 -0500
Subject: [PATCH 1/2] ole32: Add a storage test using a custom ILockBytes.
---
dlls/ole32/tests/storage32.c | 214 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 214 insertions(+)
diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c
index 0113d1b..63a803a 100644
--- a/dlls/ole32/tests/storage32.c
+++ b/dlls/ole32/tests/storage32.c
@@ -57,6 +57,194 @@ static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2)
return lstrcmpA(stra1, stra2);
}
+typedef struct TestLockBytes {
+ ILockBytes ILockBytes_iface;
+ LONG ref;
+ BYTE* contents;
+ ULONG size;
+ ULONG buffer_size;
+} TestLockBytes;
+
+static inline TestLockBytes *impl_from_ILockBytes(ILockBytes *iface)
+{
+ return CONTAINING_RECORD(iface, TestLockBytes, ILockBytes_iface);
+}
+
+static HRESULT WINAPI TestLockBytes_QueryInterface(ILockBytes *iface, REFIID iid,
+ void **ppv)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+
+ if (!ppv) return E_INVALIDARG;
+
+ if (IsEqualIID(&IID_IUnknown, iid) ||
+ IsEqualIID(&IID_ILockBytes, iid))
+ *ppv = &This->ILockBytes_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI TestLockBytes_AddRef(ILockBytes *iface)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ return ref;
+}
+
+static ULONG WINAPI TestLockBytes_Release(ILockBytes *iface)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+ return ref;
+}
+
+static HRESULT WINAPI TestLockBytes_ReadAt(ILockBytes *iface,
+ ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ ULONG dummy;
+
+ if (!pv) return E_INVALIDARG;
+
+ if (!pcbRead) pcbRead = &dummy;
+
+ if (ulOffset.QuadPart >= This->size)
+ {
+ *pcbRead = 0;
+ return S_OK;
+ }
+
+ cb = min(cb, This->size - ulOffset.QuadPart);
+
+ *pcbRead = cb;
+ memcpy(pv, &This->contents[ulOffset.QuadPart], cb);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_WriteAt(ILockBytes *iface,
+ ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ HRESULT hr;
+ ULONG dummy;
+
+ if (!pv) return E_INVALIDARG;
+
+ if (!pcbWritten) pcbWritten = &dummy;
+
+ if (ulOffset.QuadPart + cb > This->size)
+ {
+ ULARGE_INTEGER new_size;
+ new_size.QuadPart = ulOffset.QuadPart + cb;
+ hr = ILockBytes_SetSize(iface, new_size);
+ if (FAILED(hr)) return hr;
+ }
+
+ *pcbWritten = cb;
+ memcpy(&This->contents[ulOffset.QuadPart], pv, cb);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_Flush(ILockBytes *iface)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_SetSize(ILockBytes *iface,
+ ULARGE_INTEGER cb)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+
+ if (This->buffer_size < cb.QuadPart)
+ {
+ ULONG new_buffer_size = max(This->buffer_size * 2, cb.QuadPart);
+ BYTE* new_buffer = HeapAlloc(GetProcessHeap(), 0, new_buffer_size);
+ if (!new_buffer) return E_OUTOFMEMORY;
+ memcpy(new_buffer, This->contents, This->size);
+ HeapFree(GetProcessHeap(), 0, This->contents);
+ This->contents = new_buffer;
+ }
+
+ if (cb.QuadPart > This->size)
+ memset(&This->contents[This->size], 0, cb.QuadPart - This->size);
+
+ This->size = cb.QuadPart;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_LockRegion(ILockBytes *iface,
+ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_UnlockRegion(ILockBytes *iface,
+ ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI TestLockBytes_Stat(ILockBytes *iface,
+ STATSTG *pstatstg, DWORD grfStatFlag)
+{
+ TestLockBytes *This = impl_from_ILockBytes(iface);
+ static const WCHAR dummy_name[] = {'d','u','m','m','y',0};
+
+ if (!pstatstg) return E_INVALIDARG;
+
+ memset(pstatstg, 0, sizeof(STATSTG));
+
+ if (!(grfStatFlag & STATFLAG_NONAME))
+ {
+ pstatstg->pwcsName = CoTaskMemAlloc(sizeof(dummy_name));
+ if (!pstatstg->pwcsName) return E_OUTOFMEMORY;
+ memcpy(pstatstg->pwcsName, dummy_name, sizeof(dummy_name));
+ }
+
+ pstatstg->type = STGTY_LOCKBYTES;
+ pstatstg->cbSize.QuadPart = This->size;
+
+ return S_OK;
+}
+
+static const ILockBytesVtbl TestLockBytes_Vtbl = {
+ TestLockBytes_QueryInterface,
+ TestLockBytes_AddRef,
+ TestLockBytes_Release,
+ TestLockBytes_ReadAt,
+ TestLockBytes_WriteAt,
+ TestLockBytes_Flush,
+ TestLockBytes_SetSize,
+ TestLockBytes_LockRegion,
+ TestLockBytes_UnlockRegion,
+ TestLockBytes_Stat
+};
+
+static void CreateTestLockBytes(TestLockBytes **This)
+{
+ *This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**This));
+
+ if (*This)
+ {
+ (*This)->ILockBytes_iface.lpVtbl = &TestLockBytes_Vtbl;
+ (*This)->ref = 1;
+ }
+}
+
+static void DeleteTestLockBytes(TestLockBytes *This)
+{
+ ok(This->ILockBytes_iface.lpVtbl == &TestLockBytes_Vtbl, "test lock bytes %p deleted with incorrect vtable\n", This);
+ ok(This->ref == 1, "test lock bytes %p deleted with %i references instead of 1\n", This, This->ref);
+ HeapFree(GetProcessHeap(), 0, This->contents);
+ HeapFree(GetProcessHeap(), 0, This);
+}
+
static void test_hglobal_storage_stat(void)
{
ILockBytes *ilb = NULL;
@@ -3645,6 +3833,31 @@ static void test_overwrite(void)
DeleteFileA(filenameA);
}
+static void test_custom_lockbytes(void)
+{
+ static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
+ TestLockBytes* lockbytes;
+ HRESULT hr;
+ IStorage* stg;
+ IStream* stm;
+
+ CreateTestLockBytes(&lockbytes);
+
+ hr = StgCreateDocfileOnILockBytes(&lockbytes->ILockBytes_iface, STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED, 0, &stg);
+ ok(hr==S_OK, "StgCreateDocfileOnILockBytes failed %x\n", hr);
+
+ hr = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stm);
+ ok(hr==S_OK, "IStorage_CreateStream failed %x\n", hr);
+
+ IStream_Release(stm);
+
+ hr = IStorage_Commit(stg, 0);
+
+ IStorage_Release(stg);
+
+ DeleteTestLockBytes(lockbytes);
+}
+
START_TEST(storage32)
{
CHAR temp[MAX_PATH];
@@ -3693,4 +3906,5 @@ START_TEST(storage32)
test_locking();
test_transacted_shared();
test_overwrite();
+ test_custom_lockbytes();
}
--
2.1.4
More information about the wine-patches
mailing list