From ae722c45ad3e670f8a0d82facd0e03381e8cab04 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 27 Aug 2012 15:50:56 -0500 Subject: [PATCH] ole32: Add tests for StgConvertPropertyToVariant. --- dlls/ole32/tests/propvariant.c | 164 +++++++++++++++++++++++++++++++++ include/propidl.idl | 4 + 2 files changed, 168 insertions(+) diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c index 50adfe7b04b..29fa2f0e1ec 100644 --- a/dlls/ole32/tests/propvariant.c +++ b/dlls/ole32/tests/propvariant.c @@ -245,8 +245,172 @@ static void test_copy(void) memset(&propvarSrc, 0, sizeof(propvarSrc)); } +struct _PMemoryAllocator_vtable { + void *Allocate; /* virtual void* Allocate(ULONG cbSize); */ + void *Free; /* virtual void Free(void *pv); */ +}; + +typedef struct _PMemoryAllocator { + struct _PMemoryAllocator_vtable *vt; +} PMemoryAllocator; + +#ifdef __i386__ +#define __thiscall __stdcall +#else +#define __thiscall __cdecl +#endif + +static void * __thiscall PMemoryAllocator_Allocate(PMemoryAllocator *_this, ULONG cbSize) +{ + return CoTaskMemAlloc(cbSize); +} + +static void __thiscall PMemoryAllocator_Free(PMemoryAllocator *_this, void *pv) +{ + CoTaskMemFree(pv); +} + +#ifdef __i386__ + +#include "pshpack1.h" +typedef struct +{ + BYTE pop_eax; /* popl %eax */ + BYTE push_ecx; /* pushl %ecx */ + BYTE push_eax; /* pushl %eax */ + BYTE jmp_func; /* jmp $func */ + DWORD func; +} THISCALL_TO_STDCALL_THUNK; +#include "poppack.h" + +static THISCALL_TO_STDCALL_THUNK *wrapperCodeMem = NULL; + +static void fill_thunk(THISCALL_TO_STDCALL_THUNK *thunk, void *fn) +{ + thunk->pop_eax = 0x58; + thunk->push_ecx = 0x51; + thunk->push_eax = 0x50; + thunk->jmp_func = 0xe9; + thunk->func = (char*)fn - (char*)(&thunk->func + 1); +} + +static void setup_vtable(struct _PMemoryAllocator_vtable *vtable) +{ + wrapperCodeMem = VirtualAlloc(NULL, 2 * sizeof(*wrapperCodeMem), + MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + fill_thunk(&wrapperCodeMem[0], PMemoryAllocator_Allocate); + fill_thunk(&wrapperCodeMem[1], PMemoryAllocator_Free); + + vtable->Allocate = &wrapperCodeMem[0]; + vtable->Free = &wrapperCodeMem[1]; +} + +#else + +static void setup_vtable(struct _PMemoryAllocator_vtable *vtable) +{ + vtable->Allocate = PMemoryAllocator_Allocate; + vtable->Free = PMemoryAllocator_Free; +} + +#endif + +static const char serialized_empty[] = { + 0,0, /* VT_EMPTY */ + 0,0, /* padding */ +}; + +static const char serialized_null[] = { + 1,0, /* VT_NULL */ + 0,0, /* padding */ +}; + +static const char serialized_i4[] = { + 3,0, /* VT_I4 */ + 0,0, /* padding */ + 0xef,0xcd,0xab,0xfe +}; + +static const char serialized_bstr_wc[] = { + 8,0, /* VT_BSTR */ + 0,0, /* padding */ + 10,0,0,0, /* size */ + 't',0,'e',0, + 's',0,'t',0, + 0,0,0,0 +}; + +static const char serialized_bstr_mb[] = { + 8,0, /* VT_BSTR */ + 0,0, /* padding */ + 5,0,0,0, /* size */ + 't','e','s','t', + 0,0,0,0 +}; + +static void test_propertytovariant(void) +{ + HANDLE hole32; + BOOLEAN (__stdcall *pStgConvertPropertyToVariant)(const SERIALIZEDPROPERTYVALUE*,USHORT,PROPVARIANT*,PMemoryAllocator*); + PROPVARIANT propvar; + PMemoryAllocator allocator; + struct _PMemoryAllocator_vtable vtable; + BOOLEAN ret; + static const WCHAR test_string[] = {'t','e','s','t',0}; + + hole32 = GetModuleHandleA("ole32"); + + pStgConvertPropertyToVariant = (void*)GetProcAddress(hole32, "StgConvertPropertyToVariant"); + + if (!pStgConvertPropertyToVariant) + { + todo_wine win_skip("StgConvertPropertyToVariant not available\n"); + return; + } + + setup_vtable(&vtable); + allocator.vt = &vtable; + + ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_empty, + CP_WINUNICODE, &propvar, &allocator); + + ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret); + ok(propvar.vt == VT_EMPTY, "unexpected vt %x\n", propvar.vt); + + ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_null, + CP_WINUNICODE, &propvar, &allocator); + + ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret); + ok(propvar.vt == VT_NULL, "unexpected vt %x\n", propvar.vt); + + ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_i4, + CP_WINUNICODE, &propvar, &allocator); + + ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret); + ok(propvar.vt == VT_I4, "unexpected vt %x\n", propvar.vt); + ok(U(propvar).lVal == 0xfeabcdef, "unexpected lVal %x\n", U(propvar).lVal); + + ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_bstr_wc, + CP_WINUNICODE, &propvar, &allocator); + + ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret); + ok(propvar.vt == VT_BSTR, "unexpected vt %x\n", propvar.vt); + ok(!lstrcmpW(U(propvar).bstrVal, test_string), "unexpected string value\n"); + PropVariantClear(&propvar); + + ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_bstr_mb, + CP_UTF8, &propvar, &allocator); + + ok(ret == 0, "StgConvertPropertyToVariant returned %i\n", ret); + ok(propvar.vt == VT_BSTR, "unexpected vt %x\n", propvar.vt); + ok(!lstrcmpW(U(propvar).bstrVal, test_string), "unexpected string value\n"); + PropVariantClear(&propvar); +} + START_TEST(propvariant) { test_validtypes(); test_copy(); + test_propertytovariant(); } diff --git a/include/propidl.idl b/include/propidl.idl index 3fc7515a6bf..fbe80d8174e 100644 --- a/include/propidl.idl +++ b/include/propidl.idl @@ -431,6 +431,10 @@ interface IEnumSTATPROPSETSTG : IUnknown [out] IEnumSTATPROPSETSTG **ppenum); } +typedef struct SERIALIZEDPROPERTYVALUE { + DWORD dwType; + BYTE rgb[1]; +} SERIALIZEDPROPERTYVALUE; cpp_quote("HRESULT WINAPI FreePropVariantArray(ULONG,PROPVARIANT*);") cpp_quote("HRESULT WINAPI PropVariantClear(PROPVARIANT*);")