*
*/
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-
-//#include <assert.h>
-//#include <stdarg.h>
-//#include <string.h>
-#include <stdio.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include <windef.h>
-#include <winbase.h>
-#include <wingdi.h>
-//#include "winuser.h"
-//#include "winerror.h"
-#include <winnls.h>
-#include <ole2.h>
-#include <wine/debug.h>
-//#include "olestd.h"
-
+#include "precomp.h"
#include "storage32.h"
-#include "compobj_private.h"
-
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-#define HANDLE_ERROR(err) do { hr = err; TRACE("(HRESULT=%x)\n", (HRESULT)err); goto CLEANUP; } while (0)
-
/* Structure of 'Ole Private Data' clipboard format */
typedef struct
{
*/
static ole_clipbrd* theOleClipboard;
+static CRITICAL_SECTION latest_snapshot_cs;
+static CRITICAL_SECTION_DEBUG latest_snapshot_cs_debug =
+{
+ 0, 0, &latest_snapshot_cs,
+ { &latest_snapshot_cs_debug.ProcessLocksList, &latest_snapshot_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": clipboard last snapshot") }
+};
+static CRITICAL_SECTION latest_snapshot_cs = { &latest_snapshot_cs_debug, -1, 0, 0, 0, 0 };
+
static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
{
struct oletls *info = COM_CurrentInfo();
*/
static const WCHAR clipbrd_wndclass[] = {'C','L','I','P','B','R','D','W','N','D','C','L','A','S','S',0};
-static const WCHAR wine_marshal_dataobject[] = {'W','i','n','e',' ','m','a','r','s','h','a','l',' ','d','a','t','a','o','b','j','e','c','t',0};
-
UINT ownerlink_clipboard_format = 0;
UINT filename_clipboard_format = 0;
UINT filenameW_clipboard_format = 0;
static UINT wine_marshal_clipboard_format;
-static inline char *dump_fmtetc(FORMATETC *fmt)
+static inline const char *dump_fmtetc(FORMATETC *fmt)
{
- static char buf[100];
-
- snprintf(buf, sizeof(buf), "cf %04x ptd %p aspect %x lindex %d tymed %x",
- fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
- return buf;
+ if (!fmt) return "(null)";
+ return wine_dbg_sprintf("cf %04x ptd %p aspect %x lindex %d tymed %x",
+ fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
}
/*---------------------------------------------------------------------*
hStorage = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, 0);
if (hStorage == NULL) return E_OUTOFMEMORY;
hr = CreateILockBytesOnHGlobal(hStorage, FALSE, &ptrILockBytes);
+ if (FAILED(hr))
+ {
+ GlobalFree(hStorage);
+ return hr;
+ }
+
hr = StgCreateDocfileOnILockBytes(ptrILockBytes, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &std.u.pstg);
ILockBytes_Release(ptrILockBytes);
mem_fmt = *fmt;
mem_fmt.tymed = TYMED_HGLOBAL;
+#ifdef __REACTOS__
+ med.pUnkForRelease = NULL;
+#endif
hr = IDataObject_GetData(data, &mem_fmt, &med);
if(FAILED(hr)) return hr;
if (ref == 0)
{
- ole_clipbrd *clipbrd;
- HRESULT hr = get_ole_clipbrd(&clipbrd);
+ EnterCriticalSection(&latest_snapshot_cs);
+ if (This->ref)
+ {
+ LeaveCriticalSection(&latest_snapshot_cs);
+ return ref;
+ }
+ if (theOleClipboard->latest_snapshot == This)
+ theOleClipboard->latest_snapshot = NULL;
+ LeaveCriticalSection(&latest_snapshot_cs);
if(This->data) IDataObject_Release(This->data);
-
- if(SUCCEEDED(hr) && clipbrd->latest_snapshot == This)
- clipbrd->latest_snapshot = NULL;
HeapFree(GetProcessHeap(), 0, This);
}
return TYMED_ENHMF;
case CF_METAFILEPICT:
return TYMED_MFPICT;
+ case CF_BITMAP:
+ return TYMED_GDI;
default:
FIXME("returning TYMED_NULL for cf %04x\n", cf);
return TYMED_NULL;
return S_OK;
}
+/************************************************************************
+ * get_stgmed_for_bitmap
+ *
+ * Returns a stg medium with a bitmap based on the handle
+ */
+static HRESULT get_stgmed_for_bitmap(HBITMAP hbmp, STGMEDIUM *med)
+{
+ HRESULT hr;
+
+ med->pUnkForRelease = NULL;
+ med->tymed = TYMED_NULL;
+
+ hr = dup_bitmap(hbmp, &med->u.hBitmap);
+
+ if (FAILED(hr))
+ return hr;
+
+ med->tymed = TYMED_GDI;
+ return S_OK;
+}
+
static inline BOOL string_off_equal(const DVTARGETDEVICE *t1, WORD off1, const DVTARGETDEVICE *t2, WORD off2)
{
const WCHAR *str1, *str2;
hr = get_stgmed_for_stream(h, med);
else if(mask & TYMED_ENHMF)
hr = get_stgmed_for_emf((HENHMETAFILE)h, med);
+ else if(mask & TYMED_GDI)
+ hr = get_stgmed_for_bitmap((HBITMAP)h, med);
else
{
FIXME("Unhandled tymed - mask %x req tymed %x\n", mask, fmt->tymed);
*
* Enumerate all formats supported by the source and make
* those formats available using delayed rendering using SetClipboardData.
- * Cache the enumeration list and make that list visibile as the
+ * Cache the enumeration list and make that list visible as the
* 'Ole Private Data' format on the clipboard.
*
*/
ole_clipbrd *clipbrd;
get_ole_clipbrd(&clipbrd);
+#ifdef __REACTOS__
+ if(clipbrd == NULL)
+ return DefWindowProcW(hwnd, message, wparam, lparam);
+#endif
switch (message)
{
case WM_RENDERALLFORMATS:
{
DWORD i;
- ole_priv_data_entry *entries = clipbrd->cached_enum->entries;
+ ole_priv_data_entry *entries;
TRACE("(): WM_RENDERALLFORMATS\n");
+ if (!clipbrd || !clipbrd->cached_enum) break;
+ entries = clipbrd->cached_enum->entries;
for(i = 0; i < clipbrd->cached_enum->count; i++)
{
if(entries[i].first_use)
TRACE("(%p)\n", obj);
if(!obj) return E_INVALIDARG;
+ *obj = NULL;
if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
seq_no = GetClipboardSequenceNumber();
+ EnterCriticalSection(&latest_snapshot_cs);
if(clipbrd->latest_snapshot && clipbrd->latest_snapshot->seq_no != seq_no)
clipbrd->latest_snapshot = NULL;
if(!clipbrd->latest_snapshot)
{
clipbrd->latest_snapshot = snapshot_construct(seq_no);
- if(!clipbrd->latest_snapshot) return E_OUTOFMEMORY;
+ if(!clipbrd->latest_snapshot)
+ {
+ LeaveCriticalSection(&latest_snapshot_cs);
+ return E_OUTOFMEMORY;
+ }
}
*obj = &clipbrd->latest_snapshot->IDataObject_iface;
IDataObject_AddRef(*obj);
+ LeaveCriticalSection(&latest_snapshot_cs);
return S_OK;
}