Nikolay Sivov : ole32: Add partial support for reading VT_VECTOR properties.

Alexandre Julliard julliard at winehq.org
Mon Jan 27 15:00:21 CST 2020


Module: wine
Branch: master
Commit: 1a9a7d18b83e0e40227dc7a55ff2cb32981a9d65
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1a9a7d18b83e0e40227dc7a55ff2cb32981a9d65

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Jan 27 09:24:18 2020 +0300

ole32: Add partial support for reading VT_VECTOR properties.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ole32/stg_prop.c | 113 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 103 insertions(+), 10 deletions(-)

diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c
index 00ba5ade29..8bab995eb6 100644
--- a/dlls/ole32/stg_prop.c
+++ b/dlls/ole32/stg_prop.c
@@ -1290,24 +1290,18 @@ static HRESULT buffer_read_len(const struct read_buffer *buffer, size_t offset,
     return hr;
 }
 
-static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read_buffer *buffer,
-        size_t offset, UINT codepage, void* (WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
+static HRESULT propertystorage_read_scalar(PROPVARIANT *prop, const struct read_buffer *buffer, size_t offset,
+        UINT codepage, void* (WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
 {
     HRESULT hr;
-    DWORD vt;
-
-    assert(prop);
-    assert(buffer->data);
 
-    if (FAILED(hr = buffer_read_dword(buffer, offset, &vt)))
-        return hr;
+    assert(!(prop->vt & (VT_ARRAY | VT_VECTOR)));
 
-    offset += sizeof(DWORD);
-    prop->vt = vt;
     switch (prop->vt)
     {
     case VT_EMPTY:
     case VT_NULL:
+        hr = S_OK;
         break;
     case VT_I1:
         hr = buffer_read_byte(buffer, offset, (BYTE *)&prop->u.cVal);
@@ -1512,6 +1506,105 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read
         FIXME("unsupported type %d\n", prop->vt);
         hr = STG_E_INVALIDPARAMETER;
     }
+
+    return hr;
+}
+
+static size_t propertystorage_get_elemsize(const PROPVARIANT *prop)
+{
+    if (!(prop->vt & VT_VECTOR))
+        return 0;
+
+    switch (prop->vt & ~VT_VECTOR)
+    {
+        case VT_I1: return sizeof(*prop->u.cac.pElems);
+        case VT_UI1: return sizeof(*prop->u.caub.pElems);
+        case VT_I2: return sizeof(*prop->u.cai.pElems);
+        case VT_UI2: return sizeof(*prop->u.caui.pElems);
+        case VT_BOOL: return sizeof(*prop->u.cabool.pElems);
+        case VT_I4: return sizeof(*prop->u.cal.pElems);
+        case VT_UI4: return sizeof(*prop->u.caul.pElems);
+        case VT_R4: return sizeof(*prop->u.caflt.pElems);
+        case VT_ERROR: return sizeof(*prop->u.cascode.pElems);
+        case VT_I8: return sizeof(*prop->u.cah.pElems);
+        case VT_UI8: return sizeof(*prop->u.cauh.pElems);
+        case VT_R8: return sizeof(*prop->u.cadbl.pElems);
+        case VT_CY: return sizeof(*prop->u.cacy.pElems);
+        case VT_DATE: return sizeof(*prop->u.cadate.pElems);
+        case VT_FILETIME: return sizeof(*prop->u.cafiletime.pElems);
+        case VT_CLSID: return sizeof(*prop->u.cauuid.pElems);
+        case VT_VARIANT: return sizeof(*prop->u.capropvar.pElems);
+        default:
+            FIXME("Unhandled type %#x.\n", prop->vt);
+            return 0;
+    }
+}
+
+static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read_buffer *buffer,
+        size_t offset, UINT codepage, void* (WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
+{
+    HRESULT hr;
+    DWORD vt;
+
+    assert(prop);
+    assert(buffer->data);
+
+    if (FAILED(hr = buffer_read_dword(buffer, offset, &vt)))
+        return hr;
+
+    offset += sizeof(DWORD);
+    prop->vt = vt;
+
+    if (prop->vt & VT_VECTOR)
+    {
+        DWORD count, i;
+
+        switch (prop->vt & VT_VECTOR)
+        {
+            case VT_BSTR:
+            case VT_VARIANT:
+            case VT_LPSTR:
+            case VT_LPWSTR:
+            case VT_CF:
+                FIXME("Vector with variable length elements are not supported.\n");
+                return STG_E_INVALIDPARAMETER;
+            default:
+                ;
+        }
+
+        if (SUCCEEDED(hr = buffer_read_dword(buffer, offset, &count)))
+        {
+            size_t elemsize = propertystorage_get_elemsize(prop);
+            PROPVARIANT elem;
+
+            offset += sizeof(DWORD);
+
+            if ((prop->u.capropvar.pElems = allocate(allocate_data, elemsize * count)))
+            {
+                prop->u.capropvar.cElems = count;
+                elem.vt = prop->vt & ~VT_VECTOR;
+
+                for (i = 0; i < count; ++i)
+                {
+                    if (SUCCEEDED(hr = propertystorage_read_scalar(&elem, buffer, offset + i * elemsize, codepage,
+                            allocate, allocate_data)))
+                    {
+                        memcpy(&prop->u.capropvar.pElems[i], &elem.u.lVal, elemsize);
+                    }
+                }
+            }
+            else
+                hr = STG_E_INSUFFICIENTMEMORY;
+        }
+    }
+    else if (prop->vt & VT_ARRAY)
+    {
+        FIXME("VT_ARRAY properties are not supported.\n");
+        hr = STG_E_INVALIDPARAMETER;
+    }
+    else
+        hr = propertystorage_read_scalar(prop, buffer, offset, codepage, allocate, allocate_data);
+
     return hr;
 }
 




More information about the wine-cvs mailing list