Huw Davies : ole32: Make get_priv_data return target device ptrs ( rather than offsets) and add a couple of helper functions to simplify this process.

Alexandre Julliard julliard at winehq.org
Tue Apr 21 11:45:44 CDT 2009


Module: wine
Branch: master
Commit: bdca138d5aac6a37df540c613b80136176b1ed84
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bdca138d5aac6a37df540c613b80136176b1ed84

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Apr 16 15:27:24 2009 +0100

ole32: Make get_priv_data return target device ptrs (rather than offsets) and add a couple of helper functions to simplify this process.

---

 dlls/ole32/clipboard.c |   51 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/dlls/ole32/clipboard.c b/dlls/ole32/clipboard.c
index eaffb77..8aa14dc 100644
--- a/dlls/ole32/clipboard.c
+++ b/dlls/ole32/clipboard.c
@@ -105,6 +105,34 @@ typedef struct
 } ole_priv_data;
 
 /*****************************************************************************
+ *           td_offs_to_ptr
+ *
+ * Returns a ptr to a target device at a given offset from the
+ * start of the ole_priv_data.
+ *
+ * Used when unpacking ole private data from the clipboard.
+ */
+static inline DVTARGETDEVICE *td_offs_to_ptr(ole_priv_data *data, DWORD_PTR off)
+{
+    if(off == 0) return NULL;
+    return (DVTARGETDEVICE*)((char*)data + off);
+}
+
+/*****************************************************************************
+ *           td_get_offs
+ *
+ * Get the offset from the start of the ole_priv_data of the idx'th
+ * target device.
+ *
+ * Used when packing ole private data to the clipboard.
+ */
+static inline DWORD_PTR td_get_offs(ole_priv_data *data, DWORD idx)
+{
+    if(data->entries[idx].fmtetc.ptd == NULL) return 0;
+    return (char*)data->entries[idx].fmtetc.ptd - (char*)data;
+}
+
+/*****************************************************************************
  *           create_empty_priv_data
  *
  * Create an empty data structure.  The only thing that really matters
@@ -313,7 +341,7 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Next
       rgelt[i] = This->data->entries[This->pos++].fmtetc;
       if(rgelt[i].ptd)
       {
-        DVTARGETDEVICE *target = (DVTARGETDEVICE *)((char *)This->data + (DWORD)rgelt[i].ptd);
+        DVTARGETDEVICE *target = rgelt[i].ptd;
         rgelt[i].ptd = CoTaskMemAlloc(target->tdSize);
         if(!rgelt[i].ptd) return E_OUTOFMEMORY;
         memcpy(rgelt[i].ptd, target, target->tdSize);
@@ -378,6 +406,7 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Clone
 {
   enum_fmtetc *This = impl_from_IEnumFORMATETC(iface);
   ole_priv_data *new_data;
+  DWORD i;
 
   TRACE("(%p)->(%p)\n", This, obj);
 
@@ -386,6 +415,12 @@ static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Clone
 
   new_data = HeapAlloc(GetProcessHeap(), 0, This->data->size);
   if(!new_data) return E_OUTOFMEMORY;
+  memcpy(new_data, This->data, This->data->size);
+
+  /* Fixup any target device ptrs */
+  for(i = 0; i < This->data->count; i++)
+      new_data->entries[i].fmtetc.ptd =
+          td_offs_to_ptr(new_data, td_get_offs(This->data, i));
 
   return enum_fmtetc_construct(new_data, This->pos, obj);
 }
@@ -922,6 +957,8 @@ static HRESULT get_priv_data(ole_priv_data **data)
         ole_priv_data *src = GlobalLock(handle);
         if(src)
         {
+            DWORD i;
+
             /* FIXME: sanity check on size */
             *data = HeapAlloc(GetProcessHeap(), 0, src->size);
             if(!*data)
@@ -931,6 +968,11 @@ static HRESULT get_priv_data(ole_priv_data **data)
             }
             memcpy(*data, src, src->size);
             GlobalUnlock(handle);
+
+            /* Fixup any target device offsets to ptrs */
+            for(i = 0; i < (*data)->count; i++)
+                (*data)->entries[i].fmtetc.ptd =
+                    td_offs_to_ptr(*data, (DWORD_PTR)(*data)->entries[i].fmtetc.ptd);
         }
     }
 
@@ -1343,7 +1385,7 @@ static HRESULT set_clipboard_formats(ole_clipbrd *clipbrd, IDataObject *data)
     FORMATETC fmt;
     IEnumFORMATETC *enum_fmt;
     HGLOBAL priv_data_handle;
-    DWORD target_offset;
+    DWORD_PTR target_offset;
     ole_priv_data *priv_data;
     DWORD count = 0, needed = sizeof(*priv_data), idx;
 
@@ -1410,9 +1452,8 @@ static HRESULT set_clipboard_formats(ole_clipbrd *clipbrd, IDataObject *data)
     clipbrd->cached_enum = HeapAlloc(GetProcessHeap(), 0, needed);
     memcpy(clipbrd->cached_enum, priv_data, needed);
     for(idx = 0; idx < clipbrd->cached_enum->count; idx++)
-        if(clipbrd->cached_enum->entries[idx].fmtetc.ptd)
-            clipbrd->cached_enum->entries[idx].fmtetc.ptd =
-                (DVTARGETDEVICE *)((char*)clipbrd->cached_enum + (DWORD)clipbrd->cached_enum->entries[idx].fmtetc.ptd);
+        clipbrd->cached_enum->entries[idx].fmtetc.ptd =
+            td_offs_to_ptr(clipbrd->cached_enum, (DWORD_PTR)clipbrd->cached_enum->entries[idx].fmtetc.ptd);
 
     GlobalUnlock(priv_data_handle);
     SetClipboardData(ole_priv_data_clipboard_format, priv_data_handle);




More information about the wine-cvs mailing list