[3/4] ole32: Move the propvariant serialization into a helper function.

Vincent Povirk madewokherd at gmail.com
Thu Oct 4 17:12:10 CDT 2012


-------------- next part --------------
From eb900b2807167f25ad8f4e97c558dec8b71b070c Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 4 Oct 2012 16:58:48 -0500
Subject: [PATCH 3/4] ole32: Move the propvariant serialization into a helper
 function.

---
 dlls/ole32/stg_prop.c |  211 ++++++++++++++++++++++++++-----------------------
 1 file changed, 112 insertions(+), 99 deletions(-)

diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c
index b582654..be901e6 100644
--- a/dlls/ole32/stg_prop.c
+++ b/dlls/ole32/stg_prop.c
@@ -1689,155 +1689,168 @@ end:
     return hr;
 }
 
-static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
- DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
+static HRESULT PropertyStorage_WriteProperty(const PROPVARIANT *var,
+    USHORT CodePage, BYTE* buffer, ULONG buffer_size, ULONG *actual_size,
+    PROPID pid, ULONG *pcIndirect)
 {
-    HRESULT hr;
-    LARGE_INTEGER seek;
-    PROPERTYIDOFFSET propIdOffset;
-    ULONG count;
-    DWORD dwType, bytesWritten;
-
-    assert(var);
-    assert(sectionOffset);
-
-    TRACE("%p, %d, 0x%08x, (%d), (%d)\n", This, propNum, propid, var->vt,
-     *sectionOffset);
-
-    seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER) +
-     propNum * sizeof(PROPERTYIDOFFSET);
-    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
-    if (FAILED(hr))
-        goto end;
-    PropertyStorage_MakePropertyIdOffset(propid, *sectionOffset, &propIdOffset);
-    hr = IStream_Write(This->stm, &propIdOffset, sizeof(propIdOffset), &count);
-    if (FAILED(hr))
-        goto end;
-
-    seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
-    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
-    if (FAILED(hr))
-        goto end;
-    StorageUtl_WriteDWord((LPBYTE)&dwType, 0, var->vt);
-    hr = IStream_Write(This->stm, &dwType, sizeof(dwType), &count);
-    if (FAILED(hr))
-        goto end;
-    *sectionOffset += sizeof(dwType);
+    DWORD size;
 
     switch (var->vt)
     {
     case VT_EMPTY:
     case VT_NULL:
-        bytesWritten = 0;
+        size = 0;
         break;
     case VT_I1:
     case VT_UI1:
-        hr = IStream_Write(This->stm, &var->u.cVal, sizeof(var->u.cVal),
-         &count);
-        bytesWritten = count;
+        size = 1;
+        if (buffer_size >= 8)
+            buffer[4] = var->u.cVal;
         break;
     case VT_I2:
     case VT_UI2:
-    {
-        WORD wTemp;
-
-        StorageUtl_WriteWord((LPBYTE)&wTemp, 0, var->u.iVal);
-        hr = IStream_Write(This->stm, &wTemp, sizeof(wTemp), &count);
-        bytesWritten = count;
+        size = 2;
+        if (buffer_size >= 8)
+            StorageUtl_WriteWord(&buffer[4], 0, var->u.iVal);
         break;
-    }
     case VT_I4:
     case VT_UI4:
-    {
-        DWORD dwTemp;
-
-        StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, var->u.lVal);
-        hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
-        bytesWritten = count;
+        size = 4;
+        if (buffer_size >= 8)
+            StorageUtl_WriteDWord(&buffer[4], 0, var->u.lVal);
         break;
-    }
     case VT_LPSTR:
     {
-        DWORD len, dwTemp;
+        DWORD len;
 
-        if (This->codePage == CP_UNICODE)
+        if (CodePage == CP_UNICODE)
             len = (lstrlenW(var->u.pwszVal) + 1) * sizeof(WCHAR);
         else
             len = lstrlenA(var->u.pszVal) + 1;
-        StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, len);
-        hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
-        if (FAILED(hr))
-            goto end;
-        hr = IStream_Write(This->stm, var->u.pszVal, len, &count);
-        bytesWritten = count + sizeof(DWORD);
+        if (buffer_size >= len + 8)
+        {
+            StorageUtl_WriteDWord(&buffer[4], 0, len);
+            memcpy(&buffer[8], var->u.pszVal, len);
+        }
+        size = len + sizeof(DWORD);
         break;
     }
     case VT_LPWSTR:
     {
-        DWORD len = lstrlenW(var->u.pwszVal) + 1, dwTemp;
+        DWORD len = lstrlenW(var->u.pwszVal) + 1;
 
-        StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, len);
-        hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
-        if (FAILED(hr))
-            goto end;
-        hr = IStream_Write(This->stm, var->u.pwszVal, len * sizeof(WCHAR),
-         &count);
-        bytesWritten = count + sizeof(DWORD);
+        if (buffer_size >= len*sizeof(WCHAR) + 8)
+        {
+            StorageUtl_WriteDWord(&buffer[4], 0, len);
+            memcpy(&buffer[8], var->u.pszVal, len*sizeof(WCHAR));
+        }
+        size = len + sizeof(DWORD);
         break;
     }
     case VT_FILETIME:
-    {
-        FILETIME temp;
-
-        StorageUtl_WriteULargeInteger((BYTE *)&temp, 0,
-         (const ULARGE_INTEGER *)&var->u.filetime);
-        hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
-        bytesWritten = count;
+        if (buffer_size >= 12)
+            StorageUtl_WriteULargeInteger(&buffer[4], 0,
+             (const ULARGE_INTEGER *)&var->u.filetime);
+        size = 8;
         break;
-    }
     case VT_CF:
     {
-        DWORD cf_hdr[2], len;
+        DWORD len;
 
         len = var->u.pclipdata->cbSize;
-        StorageUtl_WriteDWord((LPBYTE)&cf_hdr[0], 0, len + 8);
-        StorageUtl_WriteDWord((LPBYTE)&cf_hdr[1], 0, var->u.pclipdata->ulClipFmt);
-        hr = IStream_Write(This->stm, cf_hdr, sizeof(cf_hdr), &count);
-        if (FAILED(hr))
-            goto end;
-        hr = IStream_Write(This->stm, var->u.pclipdata->pClipData,
-                           len - sizeof(var->u.pclipdata->ulClipFmt), &count);
-        if (FAILED(hr))
-            goto end;
-        bytesWritten = count + sizeof cf_hdr;
+        if (buffer_size >= len+8)
+        {
+            StorageUtl_WriteDWord(&buffer[4], 0, len + 8);
+            StorageUtl_WriteDWord(&buffer[8], 0, var->u.pclipdata->ulClipFmt);
+            memcpy(&buffer[12], var->u.pclipdata->pClipData, len - sizeof(var->u.pclipdata->ulClipFmt));
+        }
+        size = len + 4;
         break;
     }
     case VT_CLSID:
-    {
-        CLSID temp;
-
-        StorageUtl_WriteGUID((BYTE *)&temp, 0, var->u.puuid);
-        hr = IStream_Write(This->stm, &temp, sizeof(temp), &count);
-        bytesWritten = count;
+        if (buffer_size >= sizeof(CLSID)+4)
+            StorageUtl_WriteGUID(&buffer[4], 0, var->u.puuid);
+        size = sizeof(CLSID);
         break;
-    }
     default:
         FIXME("unsupported type: %d\n", var->vt);
         return STG_E_INVALIDPARAMETER;
     }
 
-    if (SUCCEEDED(hr))
+    *actual_size = (size + 7)&(~3); /* Pad to a multiple of 4 bytes */
+
+    if (buffer_size >= *actual_size)
     {
-        *sectionOffset += bytesWritten;
-        if (bytesWritten % sizeof(DWORD))
+        StorageUtl_WriteDWord(buffer, 0, var->vt);
+        memset(&buffer[size+4], 0, *actual_size - size);
+    }
+
+    return S_OK;
+}
+
+static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
+ DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
+{
+    HRESULT hr;
+    LARGE_INTEGER seek;
+    PROPERTYIDOFFSET propIdOffset;
+    ULONG count;
+    DWORD bytesWritten, size;
+    BYTE static_buffer[64], *dynamic_buffer=NULL, *buffer;
+
+    assert(var);
+    assert(sectionOffset);
+
+    TRACE("%p, %d, 0x%08x, (%d), (%d)\n", This, propNum, propid, var->vt,
+     *sectionOffset);
+
+    seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER) +
+     propNum * sizeof(PROPERTYIDOFFSET);
+    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
+    if (FAILED(hr))
+        goto end;
+    PropertyStorage_MakePropertyIdOffset(propid, *sectionOffset, &propIdOffset);
+    hr = IStream_Write(This->stm, &propIdOffset, sizeof(propIdOffset), &count);
+    if (FAILED(hr))
+        goto end;
+
+    seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
+    hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
+    if (FAILED(hr))
+        goto end;
+
+    buffer = static_buffer;
+
+    hr = PropertyStorage_WriteProperty(var, This->codePage, buffer, sizeof(static_buffer),
+        &size, 0, NULL);
+
+    if (FAILED(hr))
+        goto end;
+
+    if (size > sizeof(static_buffer))
+    {
+        dynamic_buffer = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!dynamic_buffer)
         {
-            DWORD padding = sizeof(DWORD) - bytesWritten % sizeof(DWORD);
-            TRACE("adding %d bytes of padding\n", padding);
-            *sectionOffset += padding;
+            hr = E_OUTOFMEMORY;
+            goto end;
         }
+
+        buffer = dynamic_buffer;
+        hr = PropertyStorage_WriteProperty(var, This->codePage, buffer, size,
+            &size, 0, NULL);
+
+        if (FAILED(hr))
+            goto end;
     }
 
+    hr = IStream_Write(This->stm, buffer, size, &bytesWritten);
+
+    if (SUCCEEDED(hr))
+        *sectionOffset += bytesWritten;
+
 end:
+    HeapFree(GetProcessHeap(), 0, dynamic_buffer);
     return hr;
 }
 
-- 
1.7.9.5


More information about the wine-patches mailing list