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