Vincent Povirk : ole32: Implement StgConvertPropertyToVariant.
Alexandre Julliard
julliard at winehq.org
Tue Aug 28 14:44:39 CDT 2012
Module: wine
Branch: master
Commit: 58c2462c36b199bc36b3c4cf5546a228450e3653
URL: http://source.winehq.org/git/wine.git/?a=commit;h=58c2462c36b199bc36b3c4cf5546a228450e3653
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Aug 27 17:01:24 2012 -0500
ole32: Implement StgConvertPropertyToVariant.
---
dlls/ole32/ole32.spec | 1 +
dlls/ole32/stg_prop.c | 78 +++++++++++++++++++++++++++++++++------
dlls/ole32/tests/propvariant.c | 12 ++++---
3 files changed, 74 insertions(+), 17 deletions(-)
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index 5fcf841..a27adfb 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -253,6 +253,7 @@
@ stdcall SetConvertStg(ptr long)
@ stub SetDocumentBitStg
@ stdcall SetErrorInfo(long ptr)
+@ stdcall StgConvertPropertyToVariant(ptr long ptr ptr)
@ stdcall StgCreateDocfile(wstr long long ptr)
@ stdcall StgCreateDocfileOnILockBytes(ptr long long ptr)
@ stdcall StgCreatePropSetStg(ptr long ptr)
diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c
index 9e3df45..103f145 100644
--- a/dlls/ole32/stg_prop.c
+++ b/dlls/ole32/stg_prop.c
@@ -36,6 +36,9 @@
* PropertyStorage_ReadFromStream
*/
+#include "config.h"
+#include "wine/port.h"
+
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
@@ -1030,11 +1033,22 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
return hr;
}
+#ifdef __i386__
+#define __thiscall __stdcall
+#else
+#define __thiscall __cdecl
+#endif
+
+static __thiscall void* Allocate_CoTaskMemAlloc(void *userdata, ULONG size)
+{
+ return CoTaskMemAlloc(size);
+}
+
/* FIXME: there isn't any checking whether the read property extends past the
* end of the buffer.
*/
-static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
- PROPVARIANT *prop, const BYTE *data)
+static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data,
+ UINT codepage, void* (__thiscall *allocate)(void *userdata, ULONG size), void *allocate_data)
{
HRESULT hr = S_OK;
@@ -1078,21 +1092,21 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
DWORD count;
StorageUtl_ReadDWord(data, 0, &count);
- if (This->codePage == CP_UNICODE && count / 2)
+ if (codepage == CP_UNICODE && count / 2)
{
WARN("Unicode string has odd number of bytes\n");
hr = STG_E_INVALIDHEADER;
}
else
{
- prop->u.pszVal = CoTaskMemAlloc(count);
+ prop->u.pszVal = allocate(allocate_data, count);
if (prop->u.pszVal)
{
memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
- /* This is stored in the code page specified in This->codePage.
+ /* This is stored in the code page specified in codepage.
* Don't convert it, the caller will just store it as-is.
*/
- if (This->codePage == CP_UNICODE)
+ if (codepage == CP_UNICODE)
{
/* Make sure it's NULL-terminated */
prop->u.pszVal[count / sizeof(WCHAR) - 1] = '\0';
@@ -1117,7 +1131,7 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
StorageUtl_ReadDWord(data, 0, &count);
prop->u.blob.cbSize = count;
- prop->u.blob.pBlobData = CoTaskMemAlloc(count);
+ prop->u.blob.pBlobData = allocate(allocate_data, count);
if (prop->u.blob.pBlobData)
{
memcpy(prop->u.blob.pBlobData, data + sizeof(DWORD), count);
@@ -1132,7 +1146,7 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
DWORD count;
StorageUtl_ReadDWord(data, 0, &count);
- prop->u.pwszVal = CoTaskMemAlloc(count * sizeof(WCHAR));
+ prop->u.pwszVal = allocate(allocate_data, count * sizeof(WCHAR));
if (prop->u.pwszVal)
{
memcpy(prop->u.pwszVal, data + sizeof(DWORD),
@@ -1159,10 +1173,10 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
if (len > 8)
{
len -= 8;
- prop->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA));
+ prop->u.pclipdata = allocate(allocate_data, sizeof (CLIPDATA));
prop->u.pclipdata->cbSize = len;
prop->u.pclipdata->ulClipFmt = tag;
- prop->u.pclipdata->pClipData = CoTaskMemAlloc(len - sizeof(prop->u.pclipdata->ulClipFmt));
+ prop->u.pclipdata->pClipData = allocate(allocate_data, len - sizeof(prop->u.pclipdata->ulClipFmt));
memcpy(prop->u.pclipdata->pClipData, data+8, len - sizeof(prop->u.pclipdata->ulClipFmt));
}
else
@@ -1399,8 +1413,9 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
PROPVARIANT prop;
PropVariantInit(&prop);
- if (SUCCEEDED(PropertyStorage_ReadProperty(This, &prop,
- buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
+ if (SUCCEEDED(PropertyStorage_ReadProperty(&prop,
+ buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER),
+ This->codePage, Allocate_CoTaskMemAlloc, NULL)))
{
TRACE("Read property with ID 0x%08x, type %d\n",
idOffset->propid, prop.vt);
@@ -2673,3 +2688,42 @@ HRESULT WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
end:
return hr;
}
+
+#ifdef __i386__ /* thiscall functions are i386-specific */
+
+#define DEFINE_STDCALL_WRAPPER(num,func,args) \
+ __ASM_STDCALL_FUNC(func, args, \
+ "popl %eax\n\t" \
+ "popl %ecx\n\t" \
+ "pushl %eax\n\t" \
+ "movl (%ecx), %eax\n\t" \
+ "jmp *(4*(" #num "))(%eax)" )
+
+DEFINE_STDCALL_WRAPPER(0,Allocate_PMemoryAllocator,8)
+extern void* __thiscall Allocate_PMemoryAllocator(void *this, ULONG cbSize);
+
+#else
+
+static void* __thiscall Allocate_PMemoryAllocator(void *this, ULONG cbSize)
+{
+ void* (__thiscall *fn)(void*,ULONG) = **(void***)this;
+ return fn(this, cbSize);
+}
+
+#endif
+
+BOOLEAN WINAPI StgConvertPropertyToVariant(const SERIALIZEDPROPERTYVALUE* prop,
+ USHORT CodePage, PROPVARIANT* pvar, void* pma)
+{
+ HRESULT hr;
+
+ hr = PropertyStorage_ReadProperty(pvar, (const BYTE*)prop, CodePage, Allocate_PMemoryAllocator, pma);
+
+ if (FAILED(hr))
+ {
+ FIXME("should raise C++ exception on failure\n");
+ PropVariantInit(pvar);
+ }
+
+ return 0;
+}
diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c
index 29fa2f0..ec1dfd7 100644
--- a/dlls/ole32/tests/propvariant.c
+++ b/dlls/ole32/tests/propvariant.c
@@ -365,7 +365,7 @@ static void test_propertytovariant(void)
if (!pStgConvertPropertyToVariant)
{
- todo_wine win_skip("StgConvertPropertyToVariant not available\n");
+ win_skip("StgConvertPropertyToVariant not available\n");
return;
}
@@ -395,16 +395,18 @@ static void test_propertytovariant(void)
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");
+ todo_wine ok(propvar.vt == VT_BSTR, "unexpected vt %x\n", propvar.vt);
+ if (propvar.vt == VT_BSTR)
+ 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");
+ todo_wine ok(propvar.vt == VT_BSTR, "unexpected vt %x\n", propvar.vt);
+ if (propvar.vt == VT_BSTR)
+ ok(!lstrcmpW(U(propvar).bstrVal, test_string), "unexpected string value\n");
PropVariantClear(&propvar);
}
More information about the wine-cvs
mailing list