[PATCH 4/4] ole32: Support reading and writing custom clipformats
in the data cache.
Robert Shearman
rob at codeweavers.com
Mon Dec 4 09:51:15 CST 2006
---
dlls/ole32/datacache.c | 105
+++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 90 insertions(+), 15 deletions(-)
-------------- next part --------------
diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index 01c18f8..81c5951 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -67,13 +67,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
*
* This structure represents the header of the \002OlePresXXX stream in
* the OLE object strorage.
- *
- * Most fields are still unknown.
*/
typedef struct PresentationDataHeader
{
- DWORD unknown1; /* -1 */
- DWORD clipformat;
+ /* clipformat:
+ * - standard clipformat:
+ * DWORD length = 0xffffffff;
+ * DWORD cfFormat;
+ * - or custom clipformat:
+ * DWORD length;
+ * CHAR format_name[length]; (null-terminated)
+ */
DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
DVASPECT dvAspect;
DWORD lindex;
@@ -355,7 +359,6 @@ static BOOL DataCache_IsPresentationStre
LPCWSTR name = elem->pwcsName;
return (elem->type == STGTY_STREAM)
- && (elem->cbSize.u.LowPart >= sizeof(PresentationDataHeader))
&& (strlenW(name) == 11)
&& (strncmpW(name, OlePres, 8) == 0)
&& (name[8] >= '0') && (name[8] <= '9')
@@ -363,6 +366,70 @@ static BOOL DataCache_IsPresentationStre
&& (name[10] >= '0') && (name[10] <= '9');
}
+static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat)
+{
+ DWORD length;
+ HRESULT hr;
+ ULONG read;
+
+ *clipformat = 0;
+
+ hr = IStream_Read(stream, &length, sizeof(length), &read);
+ if (hr != S_OK || read != sizeof(length))
+ return DV_E_CLIPFORMAT;
+ if (length == -1)
+ {
+ DWORD cf;
+ hr = IStream_Read(stream, &cf, sizeof(cf), 0);
+ if (hr != S_OK || read != sizeof(cf))
+ return DV_E_CLIPFORMAT;
+ *clipformat = cf;
+ }
+ else
+ {
+ char *format_name = HeapAlloc(GetProcessHeap(), 0, length);
+ if (!format_name)
+ return E_OUTOFMEMORY;
+ hr = IStream_Read(stream, format_name, length, &read);
+ if (hr != S_OK || read != length || format_name[length - 1] != '\0')
+ {
+ HeapFree(GetProcessHeap(), 0, format_name);
+ return DV_E_CLIPFORMAT;
+ }
+ *clipformat = RegisterClipboardFormatA(format_name);
+ HeapFree(GetProcessHeap(), 0, format_name);
+ }
+ return S_OK;
+}
+
+static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
+{
+ DWORD length;
+ HRESULT hr;
+
+ if (clipformat < 0xc000)
+ length = -1;
+ else
+ length = GetClipboardFormatNameA(clipformat, NULL, 0);
+ hr = IStream_Write(stream, &length, sizeof(length), NULL);
+ if (FAILED(hr))
+ return hr;
+ if (clipformat < 0xc000)
+ {
+ DWORD cf = clipformat;
+ hr = IStream_Write(stream, &cf, sizeof(cf), NULL);
+ }
+ else
+ {
+ char *format_name = HeapAlloc(GetProcessHeap(), 0, length);
+ if (!format_name)
+ return E_OUTOFMEMORY;
+ GetClipboardFormatNameA(clipformat, format_name, length);
+ hr = IStream_Write(stream, format_name, length, NULL);
+ }
+ return hr;
+}
+
/************************************************************************
* DataCacheEntry_OpenPresStream
*
@@ -414,8 +481,12 @@ static HRESULT DataCacheEntry_OpenPresSt
{
PresentationDataHeader header;
ULONG actual_read;
+ CLIPFORMAT clipformat;
+
+ hr = read_clipformat(pStm, &clipformat);
- hr = IStream_Read(pStm, &header, sizeof(header), &actual_read);
+ if (hr == S_OK)
+ hr = IStream_Read(pStm, &header, sizeof(header), &actual_read);
/* can't use SUCCEEDED(hr): S_FALSE counts as an error */
if (hr == S_OK && actual_read == sizeof(header)
@@ -586,11 +657,10 @@ static HRESULT DataCacheEntry_Save(DataC
if (FAILED(hr))
return hr;
- /* custom clipformat */
- if (This->data_cf > 0xc000)
- FIXME("custom clipboard format not serialized properly\n");
- header.unknown1 = -1;
- header.clipformat = This->data_cf;
+ hr = write_clipformat(pres_stream, This->data_cf);
+ if (FAILED(hr))
+ return hr;
+
if (This->fmtetc.ptd)
FIXME("ptd not serialized\n");
header.unknown3 = 4;
@@ -1251,10 +1321,15 @@ static HRESULT WINAPI DataCache_Load(
&pStm);
if (SUCCEEDED(hr))
{
- PresentationDataHeader header;
- ULONG actual_read;
+ PresentationDataHeader header;
+ ULONG actual_read;
+ CLIPFORMAT clipformat;
+
+ hr = read_clipformat(pStm, &clipformat);
- hr = IStream_Read(pStm, &header, sizeof(header), &actual_read);
+ if (hr == S_OK)
+ hr = IStream_Read(pStm, &header, sizeof(header),
+ &actual_read);
/* can't use SUCCEEDED(hr): S_FALSE counts as an error */
if (hr == S_OK && actual_read == sizeof(header))
@@ -1262,7 +1337,7 @@ static HRESULT WINAPI DataCache_Load(
DataCacheEntry *cache_entry;
FORMATETC fmtetc;
- fmtetc.cfFormat = header.clipformat;
+ fmtetc.cfFormat = clipformat;
fmtetc.ptd = NULL; /* FIXME */
fmtetc.dwAspect = header.dvAspect;
fmtetc.lindex = header.lindex;
More information about the wine-patches
mailing list