From ac016925236cc731f0d9e7c5d0b0cc4e61e02801 Mon Sep 17 00:00:00 2001
From: Mike McCormack <mike@codeweavers.com>
Date: Wed, 12 Jul 2006 18:23:30 +0900
Subject: [PATCH] ole32: Fix and test reading and writing of VT_CF properties.

---
 dlls/ole32/stg_prop.c       | 27 +++++++++++++++++++++------
 dlls/ole32/tests/stg_prop.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c
index e0567c825d8..64a825d6fd9 100644
--- a/dlls/ole32/stg_prop.c
+++ b/dlls/ole32/stg_prop.c
@@ -1142,19 +1142,18 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
         break;
     case VT_CF:
         {
-            DWORD len = 0, type = 0, tag = 0;
+            DWORD len = 0, tag = 0;
 
             StorageUtl_ReadDWord(data, 0, &len);
             StorageUtl_ReadDWord(data, 4, &tag);
-            StorageUtl_ReadDWord(data, 8, &type);
-            if (tag == CFTAG_WINDOWS && len > 12)
+            if (len > 8)
             {
+                len -= 8;
                 prop->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA));
                 prop->u.pclipdata->cbSize = len;
-                prop->u.pclipdata->ulClipFmt = type;
+                prop->u.pclipdata->ulClipFmt = tag;
                 prop->u.pclipdata->pClipData = CoTaskMemAlloc(len);
-                memcpy(prop->u.pclipdata->pClipData, data+12, len - 12);
-                TRACE("returning %p, len %ld\n", prop->u.pclipdata->pClipData, len - 12);
+                memcpy(prop->u.pclipdata->pClipData, data+8, len);
             }
             else
                 hr = STG_E_INVALIDPARAMETER;
@@ -1727,6 +1726,22 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
         bytesWritten = count;
         break;
     }
+    case VT_CF:
+    {
+        DWORD cf_hdr[2], 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, &count);
+        if (FAILED(hr))
+            goto end;
+        bytesWritten = count + sizeof cf_hdr;
+        break;
+    }
     default:
         FIXME("unsupported type: %d\n", var->vt);
         return STG_E_INVALIDPARAMETER;
diff --git a/dlls/ole32/tests/stg_prop.c b/dlls/ole32/tests/stg_prop.c
index 19fd5930195..169ee0974fe 100644
--- a/dlls/ole32/tests/stg_prop.c
+++ b/dlls/ole32/tests/stg_prop.c
@@ -55,6 +55,8 @@ static void testProps(void)
     IPropertyStorage *propertyStorage = NULL;
     PROPSPEC spec;
     PROPVARIANT var;
+    CLIPDATA clipdata;
+    unsigned char clipcontent[] = "foobar";
 
     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
         return;
@@ -134,6 +136,18 @@ static void testProps(void)
     hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
     ok(SUCCEEDED(hr), "WriteMultiple failed: 0x%08lx\n", hr);
 
+    /* set a clipboard value */
+    spec.ulKind = PRSPEC_PROPID;
+    U(spec).propid = PIDSI_THUMBNAIL;
+    var.vt = VT_CF;
+    clipdata.cbSize = sizeof clipcontent + sizeof (ULONG);
+    clipdata.ulClipFmt = CF_ENHMETAFILE;
+    clipdata.pClipData = clipcontent;
+    U(var).pclipdata = &clipdata;
+    hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
+    ok(SUCCEEDED(hr), "WriteMultiple failed: 0x%08lx\n", hr);
+
+
     /* check reading */
     hr = IPropertyStorage_ReadMultiple(propertyStorage, 0, NULL, NULL);
     ok(SUCCEEDED(hr), "ReadMultiple with 0 args failed: 0x%08lx\n", hr);
@@ -164,6 +178,20 @@ static void testProps(void)
      "Didn't get expected type or value for property (got type %d, value %s)\n",
      var.vt, U(var).pszVal);
 
+    /* read clipboard format */
+    spec.ulKind = PRSPEC_PROPID;
+    U(spec).propid = PIDSI_THUMBNAIL;
+    hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
+    ok(hr == S_OK, "ReadMultiple failed: 0x%08lx\n", hr);
+    ok(var.vt == VT_CF, "variant type wrong\n");
+    ok(U(var).pclipdata->ulClipFmt == CF_ENHMETAFILE,
+        "clipboard type wrong\n");
+    ok(U(var).pclipdata->cbSize == sizeof clipcontent + sizeof (ULONG),
+        "clipboard size wrong\n");
+    ok(!memcmp(U(var).pclipdata->pClipData, clipcontent, sizeof clipcontent),
+        "clipboard contents wrong\n");
+    ok(S_OK == PropVariantClear(&var), "failed to clear variant\n");
+
     /* check deleting */
     hr = IPropertyStorage_DeleteMultiple(propertyStorage, 0, NULL);
     ok(SUCCEEDED(hr), "DeleteMultiple with 0 args failed: 0x%08lx\n", hr);