ReactOS  0.4.13-dev-249-gcba1a2f
clipboard.c
Go to the documentation of this file.
1 /*
2  * OLE 2 clipboard support
3  *
4  * Copyright 1999 Noel Borthwick <noel@macadamian.com>
5  * Copyright 2000 Abey George <abey@macadamian.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * NOTES:
22  * This file contains the implementation for the OLE Clipboard and its
23  * internal interfaces. The OLE clipboard interacts with an IDataObject
24  * interface via the OleSetClipboard, OleGetClipboard and
25  * OleIsCurrentClipboard API's. An internal IDataObject delegates
26  * to a client supplied IDataObject or the WIN32 clipboard API depending
27  * on whether OleSetClipboard has been invoked.
28  * Here are some operating scenarios:
29  *
30  * 1. OleSetClipboard called: In this case the internal IDataObject
31  * delegates to the client supplied IDataObject. Additionally OLE takes
32  * ownership of the Windows clipboard and any HGLOCBAL IDataObject
33  * items are placed on the Windows clipboard. This allows non OLE aware
34  * applications to access these. A local WinProc fields WM_RENDERFORMAT
35  * and WM_RENDERALLFORMATS messages in this case.
36  *
37  * 2. OleGetClipboard called without previous OleSetClipboard. Here the internal
38  * IDataObject functionality wraps around the WIN32 clipboard API.
39  *
40  * 3. OleGetClipboard called after previous OleSetClipboard. Here the internal
41  * IDataObject delegates to the source IDataObjects functionality directly,
42  * thereby bypassing the Windows clipboard.
43  *
44  * Implementation references : Inside OLE 2'nd edition by Kraig Brockschmidt
45  *
46  * TODO:
47  * - Support for pasting between different processes. OLE clipboard support
48  * currently works only for in process copy and paste. Since we internally
49  * store a pointer to the source's IDataObject and delegate to that, this
50  * will fail if the IDataObject client belongs to a different process.
51  * - IDataObject::GetDataHere is not implemented
52  * - OleFlushClipboard needs to additionally handle TYMED_IStorage media
53  * by copying the storage into global memory. Subsequently the default
54  * data object exposed through OleGetClipboard must convert this TYMED_HGLOBAL
55  * back to TYMED_IStorage.
56  * - OLE1 compatibility formats to be synthesized from OLE2 formats and put on
57  * clipboard in OleSetClipboard.
58  *
59  */
60 
61 #include <assert.h>
62 #include <stdarg.h>
63 #include <string.h>
64 #include <stdio.h>
65 
66 #define COBJMACROS
67 #define NONAMELESSUNION
68 
69 #include "windef.h"
70 #include "winbase.h"
71 #include "wingdi.h"
72 #include "winuser.h"
73 #include "winerror.h"
74 #include "winnls.h"
75 #include "ole2.h"
76 #include "wine/debug.h"
77 #include "olestd.h"
78 
79 #include "storage32.h"
80 
81 #include "compobj_private.h"
82 
84 
85 /* Structure of 'Ole Private Data' clipboard format */
86 typedef struct
87 {
88  FORMATETC fmtetc;
89  DWORD first_use; /* Has this cf been added to the list already */
90  DWORD unk[2];
92 
93 typedef struct
94 {
96  DWORD size; /* in bytes of the entire structure */
98  DWORD count; /* no. of format entries */
99  DWORD unk3[2];
100  ole_priv_data_entry entries[1]; /* array of size count */
101  /* then follows any DVTARGETDEVICE structures referenced in the FORMATETCs */
102 } ole_priv_data;
103 
104 /*****************************************************************************
105  * td_offs_to_ptr
106  *
107  * Returns a ptr to a target device at a given offset from the
108  * start of the ole_priv_data.
109  *
110  * Used when unpacking ole private data from the clipboard.
111  */
112 static inline DVTARGETDEVICE *td_offs_to_ptr(ole_priv_data *data, DWORD_PTR off)
113 {
114  if(off == 0) return NULL;
115  return (DVTARGETDEVICE*)((char*)data + off);
116 }
117 
118 /*****************************************************************************
119  * td_get_offs
120  *
121  * Get the offset from the start of the ole_priv_data of the idx'th
122  * target device.
123  *
124  * Used when packing ole private data to the clipboard.
125  */
127 {
128  if(data->entries[idx].fmtetc.ptd == NULL) return 0;
129  return (char*)data->entries[idx].fmtetc.ptd - (char*)data;
130 }
131 
132 /****************************************************************************
133  * Consumer snapshot. Represents the state of the ole clipboard
134  * returned by OleGetClipboard().
135  */
136 typedef struct snapshot
137 {
140 
141  DWORD seq_no; /* Clipboard sequence number corresponding to this snapshot */
142 
143  IDataObject *data; /* If we unmarshal a remote data object we hold a ref here */
144 } snapshot;
145 
146 /****************************************************************************
147  * ole_clipbrd
148  */
149 typedef struct ole_clipbrd
150 {
151  snapshot *latest_snapshot; /* Latest consumer snapshot */
152 
153  HWND window; /* Hidden clipboard window */
154  IDataObject *src_data; /* Source object passed to OleSetClipboard */
155  ole_priv_data *cached_enum; /* Cached result from the enumeration of src data object */
156  IStream *marshal_data; /* Stream onto which to marshal src_data */
157 } ole_clipbrd;
158 
160 {
161  return CONTAINING_RECORD(iface, snapshot, IDataObject_iface);
162 }
163 
165 {
171 
172 /*
173  * The one and only ole_clipbrd object which is created by OLEClipbrd_Initialize()
174  */
176 
179 {
180  0, 0, &latest_snapshot_cs,
182  0, 0, { (DWORD_PTR)(__FILE__ ": clipboard last snapshot") }
183 };
184 static CRITICAL_SECTION latest_snapshot_cs = { &latest_snapshot_cs_debug, -1, 0, 0, 0, 0 };
185 
186 static inline HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
187 {
188  struct oletls *info = COM_CurrentInfo();
189  *clipbrd = NULL;
190 
191  if(!info->ole_inits)
192  return CO_E_NOTINITIALIZED;
193  *clipbrd = theOleClipboard;
194 
195  return S_OK;
196 }
197 
198 /*
199  * Name of our registered OLE clipboard window class
200  */
201 static const WCHAR clipbrd_wndclass[] = {'C','L','I','P','B','R','D','W','N','D','C','L','A','S','S',0};
202 
214 
216 
217 static inline const char *dump_fmtetc(FORMATETC *fmt)
218 {
219  if (!fmt) return "(null)";
220  return wine_dbg_sprintf("cf %04x ptd %p aspect %x lindex %d tymed %x",
221  fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
222 }
223 
224 /*---------------------------------------------------------------------*
225  * Implementation of the internal IEnumFORMATETC interface returned by
226  * the OLE clipboard's IDataObject.
227  *---------------------------------------------------------------------*/
228 
229 typedef struct enum_fmtetc
230 {
233 
234  UINT pos; /* current enumerator position */
236 } enum_fmtetc;
237 
239 {
240  return CONTAINING_RECORD(iface, enum_fmtetc, IEnumFORMATETC_iface);
241 }
242 
243 /************************************************************************
244  * OLEClipbrd_IEnumFORMATETC_QueryInterface (IUnknown)
245  *
246  * See Windows documentation for more details on IUnknown methods.
247  */
249  (LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
250 {
252 
253  TRACE("(%p)->(IID: %s, %p)\n", This, debugstr_guid(riid), ppvObj);
254 
255  *ppvObj = NULL;
256 
257  if(IsEqualIID(riid, &IID_IUnknown) ||
259  {
260  *ppvObj = iface;
261  }
262 
263  if(*ppvObj)
264  {
265  IEnumFORMATETC_AddRef((IEnumFORMATETC*)*ppvObj);
266  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
267  return S_OK;
268  }
269 
270  TRACE("-- Interface: E_NOINTERFACE\n");
271  return E_NOINTERFACE;
272 }
273 
274 /************************************************************************
275  * OLEClipbrd_IEnumFORMATETC_AddRef (IUnknown)
276  *
277  */
279 {
281  TRACE("(%p)->(count=%u)\n",This, This->ref);
282 
283  return InterlockedIncrement(&This->ref);
284 }
285 
286 /************************************************************************
287  * OLEClipbrd_IEnumFORMATETC_Release (IUnknown)
288  *
289  * See Windows documentation for more details on IUnknown methods.
290  */
292 {
294  ULONG ref;
295 
296  TRACE("(%p)->(count=%u)\n",This, This->ref);
297 
298  ref = InterlockedDecrement(&This->ref);
299  if (!ref)
300  {
301  TRACE("() - destroying IEnumFORMATETC(%p)\n",This);
302  HeapFree(GetProcessHeap(), 0, This->data);
304  }
305  return ref;
306 }
307 
308 /************************************************************************
309  * OLEClipbrd_IEnumFORMATETC_Next (IEnumFORMATETC)
310  *
311  * Standard enumerator members for IEnumFORMATETC
312  */
314  (LPENUMFORMATETC iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
315 {
317  UINT cfetch, i;
318  HRESULT hres = S_FALSE;
319 
320  TRACE("(%p)->(pos=%u)\n", This, This->pos);
321 
322  if (This->pos < This->data->count)
323  {
324  cfetch = This->data->count - This->pos;
325  if (cfetch >= celt)
326  {
327  cfetch = celt;
328  hres = S_OK;
329  }
330 
331  for(i = 0; i < cfetch; i++)
332  {
333  hres = copy_formatetc(rgelt + i, &This->data->entries[This->pos++].fmtetc);
334  if(FAILED(hres)) return hres;
335  }
336  }
337  else
338  {
339  cfetch = 0;
340  }
341 
342  if (pceltFethed)
343  {
344  *pceltFethed = cfetch;
345  }
346 
347  return hres;
348 }
349 
350 /************************************************************************
351  * OLEClipbrd_IEnumFORMATETC_Skip (IEnumFORMATETC)
352  *
353  * Standard enumerator members for IEnumFORMATETC
354  */
356 {
358  TRACE("(%p)->(num=%u)\n", This, celt);
359 
360  This->pos += celt;
361  if (This->pos > This->data->count)
362  {
363  This->pos = This->data->count;
364  return S_FALSE;
365  }
366  return S_OK;
367 }
368 
369 /************************************************************************
370  * OLEClipbrd_IEnumFORMATETC_Reset (IEnumFORMATETC)
371  *
372  * Standard enumerator members for IEnumFORMATETC
373  */
375 {
377  TRACE("(%p)->()\n", This);
378 
379  This->pos = 0;
380  return S_OK;
381 }
382 
384 
385 /************************************************************************
386  * OLEClipbrd_IEnumFORMATETC_Clone (IEnumFORMATETC)
387  *
388  * Standard enumerator members for IEnumFORMATETC
389  */
392 {
394  ole_priv_data *new_data;
395  DWORD i;
396 
397  TRACE("(%p)->(%p)\n", This, obj);
398 
399  if ( !obj ) return E_INVALIDARG;
400  *obj = NULL;
401 
402  new_data = HeapAlloc(GetProcessHeap(), 0, This->data->size);
403  if(!new_data) return E_OUTOFMEMORY;
404  memcpy(new_data, This->data, This->data->size);
405 
406  /* Fixup any target device ptrs */
407  for(i = 0; i < This->data->count; i++)
408  new_data->entries[i].fmtetc.ptd =
409  td_offs_to_ptr(new_data, td_get_offs(This->data, i));
410 
411  return enum_fmtetc_construct(new_data, This->pos, obj);
412 }
413 
414 static const IEnumFORMATETCVtbl efvt =
415 {
423 };
424 
425 /************************************************************************
426  * enum_fmtetc_construct
427  *
428  * Creates an IEnumFORMATETC enumerator from ole_priv_data which it then owns.
429  */
431 {
432  enum_fmtetc* ef;
433 
434  *obj = NULL;
435  ef = HeapAlloc(GetProcessHeap(), 0, sizeof(*ef));
436  if (!ef) return E_OUTOFMEMORY;
437 
438  ef->ref = 1;
439  ef->IEnumFORMATETC_iface.lpVtbl = &efvt;
440  ef->data = data;
441  ef->pos = pos;
442 
443  TRACE("(%p)->()\n", ef);
444  *obj = &ef->IEnumFORMATETC_iface;
445  return S_OK;
446 }
447 
448 /***********************************************************************
449  * dup_global_mem
450  *
451  * Helper method to duplicate an HGLOBAL chunk of memory
452  */
454 {
455  void *src_ptr, *dst_ptr;
456  DWORD size;
457 
458  *dst = NULL;
459  if ( !src ) return S_FALSE;
460 
461  size = GlobalSize(src);
462 
463  *dst = GlobalAlloc( flags, size );
464  if ( !*dst ) return E_OUTOFMEMORY;
465 
466  src_ptr = GlobalLock(src);
467  dst_ptr = GlobalLock(*dst);
468 
469  memcpy(dst_ptr, src_ptr, size);
470 
471  GlobalUnlock(*dst);
472  GlobalUnlock(src);
473 
474  return S_OK;
475 }
476 
477 /***********************************************************************
478  * dup_metafilepict
479  *
480  * Helper function to duplicate a handle to a METAFILEPICT, and the
481  * contained HMETAFILE.
482  */
484 {
485  HRESULT hr;
486  HGLOBAL dest;
487  METAFILEPICT *dest_ptr;
488 
489  *pdest = NULL;
490 
491  /* Copy the METAFILEPICT structure. */
493  if (FAILED(hr)) return hr;
494 
495  dest_ptr = GlobalLock(dest);
496  if (!dest_ptr) return E_FAIL;
497 
498  /* Give the new METAFILEPICT a separate HMETAFILE. */
499  dest_ptr->hMF = CopyMetaFileW(dest_ptr->hMF, NULL);
500  if (dest_ptr->hMF)
501  {
503  *pdest = dest;
504  return S_OK;
505  }
506  else
507  {
509  GlobalFree(dest);
510  return E_FAIL;
511  }
512 }
513 
514 /***********************************************************************
515  * free_metafilepict
516  *
517  * Helper function to GlobalFree a handle to a METAFILEPICT, and also
518  * free the contained HMETAFILE.
519  */
521 {
522  METAFILEPICT *src_ptr;
523 
524  src_ptr = GlobalLock(src);
525  if (src_ptr)
526  {
527  DeleteMetaFile(src_ptr->hMF);
528  GlobalUnlock(src);
529  }
530  GlobalFree(src);
531 }
532 
533 /***********************************************************************
534  * dup_bitmap
535  *
536  * Helper function to duplicate an HBITMAP.
537  */
539 {
540  HDC src_dc;
541  HGDIOBJ orig_src_bitmap;
542  BITMAP bm;
543  HBITMAP dest;
544 
545  src_dc = CreateCompatibleDC(NULL);
546  orig_src_bitmap = SelectObject(src_dc, src);
547  GetObjectW(src, sizeof bm, &bm);
548  dest = CreateCompatibleBitmap(src_dc, bm.bmWidth, bm.bmHeight);
549  if (dest)
550  {
551  HDC dest_dc = CreateCompatibleDC(NULL);
552  HGDIOBJ orig_dest_bitmap = SelectObject(dest_dc, dest);
553  BitBlt(dest_dc, 0, 0, bm.bmWidth, bm.bmHeight, src_dc, 0, 0, SRCCOPY);
554  SelectObject(dest_dc, orig_dest_bitmap);
555  DeleteDC(dest_dc);
556  }
557  SelectObject(src_dc, orig_src_bitmap);
558  DeleteDC(src_dc);
559  *pdest = dest;
560  return dest ? S_OK : E_FAIL;
561 }
562 
563 /************************************************************
564  * render_embed_source_hack
565  *
566  * This is clearly a hack and has no place in the clipboard code.
567  *
568  */
570 {
571  STGMEDIUM std;
572  HGLOBAL hStorage = 0;
573  HRESULT hr = S_OK;
574  ILockBytes *ptrILockBytes;
575 
576  memset(&std, 0, sizeof(STGMEDIUM));
577  std.tymed = fmt->tymed = TYMED_ISTORAGE;
578 
579  hStorage = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, 0);
580  if (hStorage == NULL) return E_OUTOFMEMORY;
581  hr = CreateILockBytesOnHGlobal(hStorage, FALSE, &ptrILockBytes);
582  if (FAILED(hr))
583  {
584  GlobalFree(hStorage);
585  return hr;
586  }
587 
589  ILockBytes_Release(ptrILockBytes);
590 
591  if (FAILED(hr = IDataObject_GetDataHere(theOleClipboard->src_data, fmt, &std)))
592  {
593  WARN("() : IDataObject_GetDataHere failed to render clipboard data! (%x)\n", hr);
594  GlobalFree(hStorage);
595  return hr;
596  }
597 
598  if (1) /* check whether the presentation data is already -not- present */
599  {
600  FORMATETC fmt2;
601  STGMEDIUM std2;
602  METAFILEPICT *mfp = 0;
603 
604  fmt2.cfFormat = CF_METAFILEPICT;
605  fmt2.ptd = 0;
606  fmt2.dwAspect = DVASPECT_CONTENT;
607  fmt2.lindex = -1;
608  fmt2.tymed = TYMED_MFPICT;
609 
610  memset(&std2, 0, sizeof(STGMEDIUM));
611  std2.tymed = TYMED_MFPICT;
612 
613  /* Get the metafile picture out of it */
614 
615  if (SUCCEEDED(hr = IDataObject_GetData(theOleClipboard->src_data, &fmt2, &std2)))
616  {
617  mfp = GlobalLock(std2.u.hGlobal);
618  }
619 
620  if (mfp)
621  {
622  OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
623  IStream *pStream = 0;
624  void *mfBits;
626  INT nSize;
627  CLSID clsID;
628  LPOLESTR strProgID;
629  CHAR strOleTypeName[51];
630  BYTE OlePresStreamHeader [] =
631  {
632  0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
633  0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
634  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
635  0x00, 0x00, 0x00, 0x00
636  };
637 
638  nSize = GetMetaFileBitsEx(mfp->hMF, 0, NULL);
639 
640  memset(&pdh, 0, sizeof(PresentationDataHeader));
641  memcpy(&pdh, OlePresStreamHeader, sizeof(OlePresStreamHeader));
642 
643  pdh.dwObjectExtentX = mfp->xExt;
644  pdh.dwObjectExtentY = mfp->yExt;
645  pdh.dwSize = nSize;
646 
647  hr = IStorage_CreateStream(std.u.pstg, name, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &pStream);
648 
649  hr = IStream_Write(pStream, &pdh, sizeof(PresentationDataHeader), NULL);
650 
651  mfBits = HeapAlloc(GetProcessHeap(), 0, nSize);
652  nSize = GetMetaFileBitsEx(mfp->hMF, nSize, mfBits);
653 
654  hr = IStream_Write(pStream, mfBits, nSize, NULL);
655 
656  IStream_Release(pStream);
657 
658  HeapFree(GetProcessHeap(), 0, mfBits);
659 
660  GlobalUnlock(std2.u.hGlobal);
661  ReleaseStgMedium(&std2);
662 
663  ReadClassStg(std.u.pstg, &clsID);
664  ProgIDFromCLSID(&clsID, &strProgID);
665 
666  WideCharToMultiByte( CP_ACP, 0, strProgID, -1, strOleTypeName, sizeof(strOleTypeName), NULL, NULL );
667  STORAGE_CreateOleStream(std.u.pstg, 0);
668  OLECONVERT_CreateCompObjStream(std.u.pstg, strOleTypeName);
669  CoTaskMemFree(strProgID);
670  }
671  }
672 
673  if ( !SetClipboardData( fmt->cfFormat, hStorage ) )
674  {
675  WARN("() : Failed to set rendered clipboard data into clipboard!\n");
676  GlobalFree(hStorage);
678  }
679 
681  return hr;
682 }
683 
684 /************************************************************************
685  * find_format_in_list
686  *
687  * Returns the first entry that matches the provided clipboard format.
688  */
690 {
691  DWORD i;
692  for(i = 0; i < num; i++)
693  if(entries[i].fmtetc.cfFormat == cf)
694  return &entries[i];
695 
696  return NULL;
697 }
698 
699 /***************************************************************************
700  * get_data_from_storage
701  *
702  * Returns storage data in an HGLOBAL.
703  */
705 {
706  HGLOBAL h;
707  IStorage *stg;
708  HRESULT hr;
709  FORMATETC stg_fmt;
710  STGMEDIUM med;
711  ILockBytes *lbs;
712 
713  *mem = NULL;
714 
716  if(!h) return E_OUTOFMEMORY;
717 
719  if(SUCCEEDED(hr))
720  {
722  ILockBytes_Release(lbs);
723  }
724  if(FAILED(hr))
725  {
726  GlobalFree(h);
727  return hr;
728  }
729 
730  stg_fmt = *fmt;
731  med.tymed = stg_fmt.tymed = TYMED_ISTORAGE;
732  med.u.pstg = stg;
733  med.pUnkForRelease = NULL;
734 
735  hr = IDataObject_GetDataHere(data, &stg_fmt, &med);
736  if(FAILED(hr))
737  {
738  memset(&med, 0, sizeof(med));
739  hr = IDataObject_GetData(data, &stg_fmt, &med);
740  if(FAILED(hr)) goto end;
741 
742  hr = IStorage_CopyTo(med.u.pstg, 0, NULL, NULL, stg);
743  ReleaseStgMedium(&med);
744  if(FAILED(hr)) goto end;
745  }
746  *mem = h;
747 
748 end:
749  IStorage_Release(stg);
750  if(FAILED(hr)) GlobalFree(h);
751  return hr;
752 }
753 
754 /***************************************************************************
755  * get_data_from_stream
756  *
757  * Returns stream data in an HGLOBAL.
758  */
760 {
761  HGLOBAL h;
762  IStream *stm = NULL;
763  HRESULT hr;
764  FORMATETC stm_fmt;
765  STGMEDIUM med;
766 
767  *mem = NULL;
768 
770  if(!h) return E_OUTOFMEMORY;
771 
772  hr = CreateStreamOnHGlobal(h, FALSE, &stm);
773  if(FAILED(hr)) goto error;
774 
775  stm_fmt = *fmt;
776  med.tymed = stm_fmt.tymed = TYMED_ISTREAM;
777  med.u.pstm = stm;
778  med.pUnkForRelease = NULL;
779 
780  hr = IDataObject_GetDataHere(data, &stm_fmt, &med);
781  if(FAILED(hr))
782  {
783  LARGE_INTEGER offs;
785 
786  memset(&med, 0, sizeof(med));
787  hr = IDataObject_GetData(data, &stm_fmt, &med);
788  if(FAILED(hr)) goto error;
789 
790  offs.QuadPart = 0;
791  IStream_Seek(med.u.pstm, offs, STREAM_SEEK_CUR, &pos);
792  IStream_Seek(med.u.pstm, offs, STREAM_SEEK_SET, NULL);
793  hr = IStream_CopyTo(med.u.pstm, stm, pos, NULL, NULL);
794  ReleaseStgMedium(&med);
795  if(FAILED(hr)) goto error;
796  }
797  *mem = h;
798  IStream_Release(stm);
799  return S_OK;
800 
801 error:
802  if(stm) IStream_Release(stm);
803  GlobalFree(h);
804  return hr;
805 }
806 
807 /***************************************************************************
808  * get_data_from_global
809  *
810  * Returns global data in an HGLOBAL.
811  */
813 {
814  HGLOBAL h;
815  HRESULT hr;
816  FORMATETC mem_fmt;
817  STGMEDIUM med;
818 
819  *mem = NULL;
820 
821  mem_fmt = *fmt;
822  mem_fmt.tymed = TYMED_HGLOBAL;
823  memset(&med, 0, sizeof(med));
824 
825  hr = IDataObject_GetData(data, &mem_fmt, &med);
826  if(FAILED(hr)) return hr;
827 
828  hr = dup_global_mem(med.u.hGlobal, GMEM_DDESHARE|GMEM_MOVEABLE, &h);
829 
830  if(SUCCEEDED(hr)) *mem = h;
831 
832  ReleaseStgMedium(&med);
833 
834  return hr;
835 }
836 
837 /***************************************************************************
838  * get_data_from_enhmetafile
839  */
841 {
842  HENHMETAFILE copy;
843  HRESULT hr;
844  FORMATETC mem_fmt;
845  STGMEDIUM med;
846 
847  *mem = NULL;
848 
849  mem_fmt = *fmt;
850  mem_fmt.tymed = TYMED_ENHMF;
851  memset(&med, 0, sizeof(med));
852 
853  hr = IDataObject_GetData(data, &mem_fmt, &med);
854  if(FAILED(hr)) return hr;
855 
856  copy = CopyEnhMetaFileW(med.u.hEnhMetaFile, NULL);
857  if(copy) *mem = (HGLOBAL)copy;
858  else hr = E_FAIL;
859 
860  ReleaseStgMedium(&med);
861 
862  return hr;
863 }
864 
865 /***************************************************************************
866  * get_data_from_metafilepict
867  */
869 {
870  HGLOBAL copy;
871  HRESULT hr;
872  FORMATETC mem_fmt;
873  STGMEDIUM med;
874 
875  *mem = NULL;
876 
877  mem_fmt = *fmt;
878  mem_fmt.tymed = TYMED_MFPICT;
879  memset(&med, 0, sizeof(med));
880 
881  hr = IDataObject_GetData(data, &mem_fmt, &med);
882  if(FAILED(hr)) return hr;
883 
884  hr = dup_metafilepict(med.u.hMetaFilePict, &copy);
885 
886  if(SUCCEEDED(hr)) *mem = copy;
887 
888  ReleaseStgMedium(&med);
889 
890  return hr;
891 }
892 
893 /***************************************************************************
894  * get_data_from_bitmap
895  *
896  * Returns bitmap in an HBITMAP.
897  */
899 {
900  HBITMAP copy;
901  HRESULT hr;
902  FORMATETC mem_fmt;
903  STGMEDIUM med;
904 
905  *hbm = NULL;
906 
907  mem_fmt = *fmt;
908  mem_fmt.tymed = TYMED_GDI;
909  memset(&med, 0, sizeof(med));
910 
911  hr = IDataObject_GetData(data, &mem_fmt, &med);
912  if(FAILED(hr)) return hr;
913 
914  hr = dup_bitmap(med.u.hBitmap, &copy);
915 
916  if(SUCCEEDED(hr)) *hbm = copy;
917 
918  ReleaseStgMedium(&med);
919 
920  return hr;
921 }
922 
923 /***********************************************************************
924  * render_format
925  *
926  * Render the clipboard data. Note that this call will delegate to the
927  * source data object.
928  */
929 static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
930 {
931  HANDLE clip_data = NULL; /* HGLOBAL unless otherwise specified */
932  HRESULT hr;
933 
934  /* Embed source hack */
935  if(fmt->cfFormat == embed_source_clipboard_format)
936  {
938  }
939 
940  if(fmt->tymed & TYMED_ISTORAGE)
941  {
943  }
944  else if(fmt->tymed & TYMED_ISTREAM)
945  {
947  }
948  else if(fmt->tymed & TYMED_HGLOBAL)
949  {
951  }
952  else if(fmt->tymed & TYMED_ENHMF)
953  {
955  }
956  else if(fmt->tymed & TYMED_MFPICT)
957  {
958  /* Returns global handle to METAFILEPICT, containing a copied HMETAFILE */
960  }
961  else if(fmt->tymed & TYMED_GDI)
962  {
963  /* Returns HBITMAP not HGLOBAL */
965  }
966  else
967  {
968  FIXME("Unhandled tymed %x\n", fmt->tymed);
969  hr = DV_E_FORMATETC;
970  }
971 
972  if(SUCCEEDED(hr))
973  {
974  if ( !SetClipboardData(fmt->cfFormat, clip_data) )
975  {
976  WARN("() : Failed to set rendered clipboard data into clipboard!\n");
977  if(fmt->tymed & TYMED_MFPICT)
979  else if(fmt->tymed & TYMED_GDI)
981  else
984  }
985  }
986 
987  return hr;
988 }
989 
990 /*---------------------------------------------------------------------*
991  * Implementation of the internal IDataObject interface exposed by
992  * the OLE clipboard.
993  *---------------------------------------------------------------------*/
994 
995 
996 /************************************************************************
997  * snapshot_QueryInterface
998  */
1000  REFIID riid, void **ppvObject)
1001 {
1003  TRACE("(%p)->(IID:%s, %p)\n", This, debugstr_guid(riid), ppvObject);
1004 
1005  if ( (This==0) || (ppvObject==0) )
1006  return E_INVALIDARG;
1007 
1008  *ppvObject = 0;
1009 
1010  if (IsEqualIID(&IID_IUnknown, riid) ||
1012  {
1013  *ppvObject = iface;
1014  }
1015  else
1016  {
1017  WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
1018  return E_NOINTERFACE;
1019  }
1020 
1021  IUnknown_AddRef((IUnknown*)*ppvObject);
1022 
1023  return S_OK;
1024 }
1025 
1026 /************************************************************************
1027  * snapshot_AddRef
1028  */
1030 {
1032 
1033  TRACE("(%p)->(count=%u)\n", This, This->ref);
1034 
1035  return InterlockedIncrement(&This->ref);
1036 }
1037 
1038 /************************************************************************
1039  * snapshot_Release
1040  */
1042 {
1044  ULONG ref;
1045 
1046  TRACE("(%p)->(count=%u)\n", This, This->ref);
1047 
1048  ref = InterlockedDecrement(&This->ref);
1049 
1050  if (ref == 0)
1051  {
1053  if (This->ref)
1054  {
1056  return ref;
1057  }
1061 
1062  if(This->data) IDataObject_Release(This->data);
1063  HeapFree(GetProcessHeap(), 0, This);
1064  }
1065 
1066  return ref;
1067 }
1068 
1069 /************************************************************
1070  * get_current_ole_clip_window
1071  *
1072  * Return the window that owns the ole clipboard.
1073  *
1074  * If the clipboard is flushed or not owned by ole this will
1075  * return NULL.
1076  */
1078 {
1079  HGLOBAL h;
1080  HWND *ptr, wnd;
1081 
1083  if(!h) return NULL;
1084  ptr = GlobalLock(h);
1085  if(!ptr) return NULL;
1086  wnd = *ptr;
1087  GlobalUnlock(h);
1088  return wnd;
1089 }
1090 
1091 /************************************************************
1092  * get_current_dataobject
1093  *
1094  * Return an unmarshalled IDataObject if there is a current
1095  * (ie non-flushed) object on the ole clipboard.
1096  */
1098 {
1099  HRESULT hr = S_FALSE;
1101  HGLOBAL h;
1102  void *ptr;
1103  IStream *stm;
1105 
1106  *data = NULL;
1107  if(!wnd) return S_FALSE;
1108 
1110  if(!h) return S_FALSE;
1111  if(GlobalSize(h) <= 1) return S_FALSE;
1112  ptr = GlobalLock(h);
1113  if(!ptr) return S_FALSE;
1114 
1115  hr = CreateStreamOnHGlobal(NULL, TRUE, &stm);
1116  if(FAILED(hr)) goto end;
1117 
1118  hr = IStream_Write(stm, ptr, GlobalSize(h), NULL);
1119  if(SUCCEEDED(hr))
1120  {
1121  pos.QuadPart = 0;
1122  IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
1123  hr = CoUnmarshalInterface(stm, &IID_IDataObject, (void**)data);
1124  }
1125  IStream_Release(stm);
1126 
1127 end:
1128  GlobalUnlock(h);
1129  return hr;
1130 }
1131 
1133 {
1134  if(cf >= 0xc000) return TYMED_ISTREAM | TYMED_HGLOBAL;
1135 
1136  switch(cf)
1137  {
1138  case CF_TEXT:
1139  case CF_OEMTEXT:
1140  case CF_UNICODETEXT:
1141  return TYMED_ISTREAM | TYMED_HGLOBAL;
1142  case CF_ENHMETAFILE:
1143  return TYMED_ENHMF;
1144  case CF_METAFILEPICT:
1145  return TYMED_MFPICT;
1146  case CF_BITMAP:
1147  return TYMED_GDI;
1148  default:
1149  FIXME("returning TYMED_NULL for cf %04x\n", cf);
1150  return TYMED_NULL;
1151  }
1152 }
1153 
1154 /***********************************************************
1155  * get_priv_data
1156  *
1157  * Returns a copy of the Ole Private Data
1158  */
1160 {
1161  HGLOBAL handle;
1162  HRESULT hr = S_OK;
1163  ole_priv_data *ret = NULL;
1164 
1165  *data = NULL;
1166 
1168  if(handle)
1169  {
1171  if(src)
1172  {
1173  DWORD i;
1174 
1175  /* FIXME: sanity check on size */
1176  ret = HeapAlloc(GetProcessHeap(), 0, src->size);
1177  if(!ret)
1178  {
1180  return E_OUTOFMEMORY;
1181  }
1182  memcpy(ret, src, src->size);
1184 
1185  /* Fixup any target device offsets to ptrs */
1186  for(i = 0; i < ret->count; i++)
1187  ret->entries[i].fmtetc.ptd =
1188  td_offs_to_ptr(ret, (DWORD_PTR) ret->entries[i].fmtetc.ptd);
1189  }
1190  }
1191 
1192  if(!ret) /* Non-ole data */
1193  {
1194  UINT cf;
1195  DWORD count = 0, idx, size = FIELD_OFFSET(ole_priv_data, entries);
1196 
1197  for(cf = 0; (cf = EnumClipboardFormats(cf)) != 0; count++)
1198  {
1199  WCHAR buf[256];
1201  TRACE("cf %04x %s\n", cf, debugstr_w(buf));
1202  else
1203  TRACE("cf %04x\n", cf);
1204  }
1205  TRACE("count %d\n", count);
1206  size += count * sizeof(ret->entries[0]);
1207 
1208  /* There are holes in fmtetc so zero init */
1210  if(!ret) return E_OUTOFMEMORY;
1211  ret->size = size;
1212  ret->count = count;
1213 
1214  for(cf = 0, idx = 0; (cf = EnumClipboardFormats(cf)) != 0; idx++)
1215  {
1216  ret->entries[idx].fmtetc.cfFormat = cf;
1217  ret->entries[idx].fmtetc.ptd = NULL;
1218  ret->entries[idx].fmtetc.dwAspect = DVASPECT_CONTENT;
1219  ret->entries[idx].fmtetc.lindex = -1;
1220  ret->entries[idx].fmtetc.tymed = get_tymed_from_nonole_cf(cf);
1221  ret->entries[idx].first_use = 1;
1222  }
1223  }
1224 
1225  *data = ret;
1226  return hr;
1227 }
1228 
1229 /************************************************************************
1230  * get_stgmed_for_global
1231  *
1232  * Returns a stg medium with a copy of the global handle
1233  */
1234 static HRESULT get_stgmed_for_global(HGLOBAL h, STGMEDIUM *med)
1235 {
1236  HRESULT hr;
1237 
1238  med->pUnkForRelease = NULL;
1239  med->tymed = TYMED_NULL;
1240 
1241  hr = dup_global_mem(h, GMEM_MOVEABLE, &med->u.hGlobal);
1242 
1243  if(SUCCEEDED(hr)) med->tymed = TYMED_HGLOBAL;
1244 
1245  return hr;
1246 }
1247 
1248 /************************************************************************
1249  * get_stgmed_for_stream
1250  *
1251  * Returns a stg medium with a stream based on the handle
1252  */
1253 static HRESULT get_stgmed_for_stream(HGLOBAL h, STGMEDIUM *med)
1254 {
1255  HRESULT hr;
1256  HGLOBAL dst;
1257 
1258  med->pUnkForRelease = NULL;
1259  med->tymed = TYMED_NULL;
1260 
1262  if(FAILED(hr)) return hr;
1263 
1264  hr = CreateStreamOnHGlobal(dst, TRUE, &med->u.pstm);
1265  if(FAILED(hr))
1266  {
1267  GlobalFree(dst);
1268  return hr;
1269  }
1270 
1271  med->tymed = TYMED_ISTREAM;
1272  return hr;
1273 }
1274 
1275 /************************************************************************
1276  * get_stgmed_for_storage
1277  *
1278  * Returns a stg medium with a storage based on the handle
1279  */
1280 static HRESULT get_stgmed_for_storage(HGLOBAL h, STGMEDIUM *med)
1281 {
1282  HRESULT hr;
1283  HGLOBAL dst;
1284  ILockBytes *lbs;
1285 
1286  med->pUnkForRelease = NULL;
1287  med->tymed = TYMED_NULL;
1288 
1290  if(FAILED(hr)) return hr;
1291 
1293  if(FAILED(hr))
1294  {
1295  GlobalFree(dst);
1296  return hr;
1297  }
1298 
1299  hr = StgIsStorageILockBytes(lbs);
1300  if(hr!=S_OK)
1301  {
1302  ILockBytes_Release(lbs);
1303  GlobalFree(dst);
1304  return SUCCEEDED(hr) ? E_FAIL : hr;
1305  }
1306 
1308  ILockBytes_Release(lbs);
1309  if(FAILED(hr))
1310  {
1311  GlobalFree(dst);
1312  return hr;
1313  }
1314 
1315  med->tymed = TYMED_ISTORAGE;
1316  return hr;
1317 }
1318 
1319 /************************************************************************
1320  * get_stgmed_for_emf
1321  *
1322  * Returns a stg medium with an enhanced metafile based on the handle
1323  */
1324 static HRESULT get_stgmed_for_emf(HENHMETAFILE hemf, STGMEDIUM *med)
1325 {
1326  med->pUnkForRelease = NULL;
1327  med->tymed = TYMED_NULL;
1328 
1329  med->u.hEnhMetaFile = CopyEnhMetaFileW(hemf, NULL);
1330  if(!med->u.hEnhMetaFile) return E_OUTOFMEMORY;
1331  med->tymed = TYMED_ENHMF;
1332  return S_OK;
1333 }
1334 
1335 /************************************************************************
1336  * get_stgmed_for_bitmap
1337  *
1338  * Returns a stg medium with a bitmap based on the handle
1339  */
1341 {
1342  HRESULT hr;
1343 
1344  med->pUnkForRelease = NULL;
1345  med->tymed = TYMED_NULL;
1346 
1347  hr = dup_bitmap(hbmp, &med->u.hBitmap);
1348 
1349  if (FAILED(hr))
1350  return hr;
1351 
1352  med->tymed = TYMED_GDI;
1353  return S_OK;
1354 }
1355 
1356 static inline BOOL string_off_equal(const DVTARGETDEVICE *t1, WORD off1, const DVTARGETDEVICE *t2, WORD off2)
1357 {
1358  const WCHAR *str1, *str2;
1359 
1360  if(off1 == 0 && off2 == 0) return TRUE;
1361  if(off1 == 0 || off2 == 0) return FALSE;
1362 
1363  str1 = (const WCHAR*)((const char*)t1 + off1);
1364  str2 = (const WCHAR*)((const char*)t2 + off2);
1365 
1366  return !lstrcmpW(str1, str2);
1367 }
1368 
1369 static inline BOOL td_equal(const DVTARGETDEVICE *t1, const DVTARGETDEVICE *t2)
1370 {
1371  if(t1 == NULL && t2 == NULL) return TRUE;
1372  if(t1 == NULL || t2 == NULL) return FALSE;
1373 
1374  if(!string_off_equal(t1, t1->tdDriverNameOffset, t2, t2->tdDriverNameOffset))
1375  return FALSE;
1376  if(!string_off_equal(t1, t1->tdDeviceNameOffset, t2, t2->tdDeviceNameOffset))
1377  return FALSE;
1378  if(!string_off_equal(t1, t1->tdPortNameOffset, t2, t2->tdPortNameOffset))
1379  return FALSE;
1380 
1381  /* FIXME check devmode? */
1382 
1383  return TRUE;
1384 }
1385 
1386 /************************************************************************
1387  * snapshot_GetData
1388  */
1389 static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
1390  STGMEDIUM *med)
1391 {
1393  HANDLE h;
1394  HRESULT hr;
1397  DWORD mask;
1398 
1399  TRACE("(%p, %p {%s}, %p)\n", iface, fmt, dump_fmtetc(fmt), med);
1400 
1401  if ( !fmt || !med ) return E_INVALIDARG;
1402 
1403  memset(med, 0, sizeof(*med));
1404 
1405  if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;
1406 
1407  if(!This->data)
1408  hr = get_current_dataobject(&This->data);
1409 
1410  if(This->data)
1411  {
1412  hr = IDataObject_GetData(This->data, fmt, med);
1413  if(SUCCEEDED(hr))
1414  {
1415  CloseClipboard();
1416  return hr;
1417  }
1418  }
1419  if(fmt->lindex != -1)
1420  {
1421  hr = DV_E_FORMATETC;
1422  goto end;
1423  }
1424 
1425  if(!IsClipboardFormatAvailable(fmt->cfFormat))
1426  {
1427  hr = DV_E_FORMATETC;
1428  goto end;
1429  }
1430 
1432  if(FAILED(hr)) goto end;
1433 
1434  entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
1435  if(entry)
1436  {
1437  if(!td_equal(fmt->ptd, entry->fmtetc.ptd))
1438  {
1439  hr = DV_E_FORMATETC;
1440  goto end;
1441  }
1442  mask = fmt->tymed & entry->fmtetc.tymed;
1443  if(!mask && (entry->fmtetc.tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE)))
1444  mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE);
1445  }
1446  else /* non-Ole format */
1447  mask = fmt->tymed & get_tymed_from_nonole_cf(fmt->cfFormat);
1448 
1449  if(!mask)
1450  {
1451  hr = DV_E_TYMED;
1452  goto end;
1453  }
1454 
1455  h = GetClipboardData(fmt->cfFormat);
1456  if(!h)
1457  {
1458  hr = DV_E_FORMATETC;
1459  goto end;
1460  }
1461 
1462  if(mask & TYMED_HGLOBAL)
1463  hr = get_stgmed_for_global(h, med);
1464  else if(mask & TYMED_ISTREAM)
1465  hr = get_stgmed_for_stream(h, med);
1466  else if(mask & TYMED_ISTORAGE)
1467  hr = get_stgmed_for_storage(h, med);
1468  else if(mask & TYMED_ENHMF)
1469  hr = get_stgmed_for_emf((HENHMETAFILE)h, med);
1470  else if(mask & TYMED_GDI)
1471  hr = get_stgmed_for_bitmap((HBITMAP)h, med);
1472  else
1473  {
1474  FIXME("Unhandled tymed - mask %x req tymed %x\n", mask, fmt->tymed);
1475  hr = E_FAIL;
1476  goto end;
1477  }
1478 
1479 end:
1482  return hr;
1483 }
1484 
1485 /************************************************************************
1486  * snapshot_GetDataHere
1487  */
1489  STGMEDIUM *med)
1490 {
1492  HANDLE h;
1493  HRESULT hr;
1496  TYMED supported;
1497 
1498  if ( !fmt || !med ) return E_INVALIDARG;
1499 
1500  TRACE("(%p, %p {%s}, %p (tymed %x)\n", iface, fmt, dump_fmtetc(fmt), med, med->tymed);
1501 
1502  if ( !OpenClipboard(NULL)) return CLIPBRD_E_CANT_OPEN;
1503 
1504  if(!This->data)
1505  hr = get_current_dataobject(&This->data);
1506 
1507  if(This->data)
1508  {
1509  hr = IDataObject_GetDataHere(This->data, fmt, med);
1510  if(SUCCEEDED(hr))
1511  {
1512  CloseClipboard();
1513  return hr;
1514  }
1515  }
1516 
1517  h = GetClipboardData(fmt->cfFormat);
1518  if(!h)
1519  {
1520  hr = DV_E_FORMATETC;
1521  goto end;
1522  }
1523 
1525  if(FAILED(hr)) goto end;
1526 
1527  entry = find_format_in_list(enum_data->entries, enum_data->count, fmt->cfFormat);
1528  if(entry)
1529  {
1530  if(!td_equal(fmt->ptd, entry->fmtetc.ptd))
1531  {
1532  hr = DV_E_FORMATETC;
1533  goto end;
1534  }
1535  supported = entry->fmtetc.tymed;
1536  }
1537  else /* non-Ole format */
1538  supported = TYMED_HGLOBAL;
1539 
1540  switch(med->tymed)
1541  {
1542  case TYMED_HGLOBAL:
1543  {
1544  DWORD src_size = GlobalSize(h);
1545  DWORD dst_size = GlobalSize(med->u.hGlobal);
1546  hr = E_FAIL;
1547  if(dst_size >= src_size)
1548  {
1549  void *src = GlobalLock(h);
1550  void *dst = GlobalLock(med->u.hGlobal);
1551 
1552  memcpy(dst, src, src_size);
1553  GlobalUnlock(med->u.hGlobal);
1554  GlobalUnlock(h);
1555  hr = S_OK;
1556  }
1557  break;
1558  }
1559  case TYMED_ISTREAM:
1560  {
1561  DWORD src_size = GlobalSize(h);
1562  void *src = GlobalLock(h);
1563  hr = IStream_Write(med->u.pstm, src, src_size, NULL);
1564  GlobalUnlock(h);
1565  break;
1566  }
1567  case TYMED_ISTORAGE:
1568  {
1569  STGMEDIUM copy;
1570  if(!(supported & TYMED_ISTORAGE))
1571  {
1572  hr = E_FAIL;
1573  goto end;
1574  }
1576  if(SUCCEEDED(hr))
1577  {
1578  hr = IStorage_CopyTo(copy.u.pstg, 0, NULL, NULL, med->u.pstg);
1580  }
1581  break;
1582  }
1583  default:
1584  FIXME("Unhandled tymed - supported %x req tymed %x\n", supported, med->tymed);
1585  hr = E_FAIL;
1586  goto end;
1587  }
1588 
1589 end:
1592  return hr;
1593 }
1594 
1595 /************************************************************************
1596  * snapshot_QueryGetData
1597  *
1598  * The OLE Clipboard's implementation of this method delegates to
1599  * a data source if there is one or wraps around the windows clipboard
1600  * function IsClipboardFormatAvailable() otherwise.
1601  *
1602  */
1604 {
1605  FIXME("(%p, %p {%s})\n", iface, fmt, dump_fmtetc(fmt));
1606 
1607  if (!fmt) return E_INVALIDARG;
1608 
1609  if ( fmt->dwAspect != DVASPECT_CONTENT ) return DV_E_FORMATETC;
1610 
1611  if ( fmt->lindex != -1 ) return DV_E_FORMATETC;
1612 
1613  return (IsClipboardFormatAvailable(fmt->cfFormat)) ? S_OK : DV_E_CLIPFORMAT;
1614 }
1615 
1616 /************************************************************************
1617  * snapshot_GetCanonicalFormatEtc
1618  */
1620  FORMATETC *fmt_out)
1621 {
1622  TRACE("(%p, %p, %p)\n", iface, fmt_in, fmt_out);
1623 
1624  if ( !fmt_in || !fmt_out ) return E_INVALIDARG;
1625 
1626  *fmt_out = *fmt_in;
1627  return DATA_S_SAMEFORMATETC;
1628 }
1629 
1630 /************************************************************************
1631  * snapshot_SetData
1632  *
1633  * The OLE Clipboard does not implement this method
1634  */
1635 static HRESULT WINAPI snapshot_SetData(IDataObject *iface, FORMATETC *fmt,
1636  STGMEDIUM *med, BOOL release)
1637 {
1638  TRACE("(%p, %p, %p, %d): not implemented\n", iface, fmt, med, release);
1639  return E_NOTIMPL;
1640 }
1641 
1642 /************************************************************************
1643  * snapshot_EnumFormatEtc
1644  *
1645  */
1647  IEnumFORMATETC **enum_fmt)
1648 {
1649  HRESULT hr;
1650  ole_priv_data *data = NULL;
1651 
1652  TRACE("(%p, %x, %p)\n", iface, dir, enum_fmt);
1653 
1654  *enum_fmt = NULL;
1655 
1656  if ( dir != DATADIR_GET ) return E_NOTIMPL;
1657  if ( !OpenClipboard(NULL) ) return CLIPBRD_E_CANT_OPEN;
1658 
1659  hr = get_priv_data(&data);
1660 
1661  if(FAILED(hr)) goto end;
1662 
1663  hr = enum_fmtetc_construct( data, 0, enum_fmt );
1664 
1665 end:
1667  return hr;
1668 }
1669 
1670 /************************************************************************
1671  * snapshot_DAdvise
1672  *
1673  * The OLE Clipboard does not implement this method
1674  */
1675 static HRESULT WINAPI snapshot_DAdvise(IDataObject *iface, FORMATETC *fmt,
1677  DWORD *conn)
1678 {
1679  TRACE("(%p, %p, %x, %p, %p): not implemented\n", iface, fmt, flags, sink, conn);
1680  return E_NOTIMPL;
1681 }
1682 
1683 /************************************************************************
1684  * snapshot_DUnadvise
1685  *
1686  * The OLE Clipboard does not implement this method
1687  */
1689 {
1690  TRACE("(%p, %d): not implemented\n", iface, conn);
1691  return E_NOTIMPL;
1692 }
1693 
1694 /************************************************************************
1695  * snapshot_EnumDAdvise
1696  *
1697  * The OLE Clipboard does not implement this method
1698  */
1700  IEnumSTATDATA** enum_advise)
1701 {
1702  TRACE("(%p, %p): not implemented\n", iface, enum_advise);
1703  return E_NOTIMPL;
1704 }
1705 
1706 static const IDataObjectVtbl snapshot_vtable =
1707 {
1720 };
1721 
1722 /*---------------------------------------------------------------------*
1723  * Internal implementation methods for the OLE clipboard
1724  *---------------------------------------------------------------------*/
1725 
1727 {
1728  snapshot *This;
1729 
1730  This = HeapAlloc( GetProcessHeap(), 0, sizeof(*This) );
1731  if (!This) return NULL;
1732 
1733  This->IDataObject_iface.lpVtbl = &snapshot_vtable;
1734  This->ref = 0;
1735  This->seq_no = seq_no;
1736  This->data = NULL;
1737 
1738  return This;
1739 }
1740 
1741 /*********************************************************
1742  * register_clipboard_formats
1743  */
1745 {
1746  static const WCHAR OwnerLink[] = {'O','w','n','e','r','L','i','n','k',0};
1747  static const WCHAR FileName[] = {'F','i','l','e','N','a','m','e',0};
1748  static const WCHAR FileNameW[] = {'F','i','l','e','N','a','m','e','W',0};
1749  static const WCHAR DataObject[] = {'D','a','t','a','O','b','j','e','c','t',0};
1750  static const WCHAR EmbeddedObject[] = {'E','m','b','e','d','d','e','d',' ','O','b','j','e','c','t',0};
1751  static const WCHAR EmbedSource[] = {'E','m','b','e','d',' ','S','o','u','r','c','e',0};
1752  static const WCHAR CustomLinkSource[] = {'C','u','s','t','o','m',' ','L','i','n','k',' ','S','o','u','r','c','e',0};
1753  static const WCHAR LinkSource[] = {'L','i','n','k',' ','S','o','u','r','c','e',0};
1754  static const WCHAR ObjectDescriptor[] = {'O','b','j','e','c','t',' ','D','e','s','c','r','i','p','t','o','r',0};
1755  static const WCHAR LinkSourceDescriptor[] = {'L','i','n','k',' ','S','o','u','r','c','e',' ',
1756  'D','e','s','c','r','i','p','t','o','r',0};
1757  static const WCHAR OlePrivateData[] = {'O','l','e',' ','P','r','i','v','a','t','e',' ','D','a','t','a',0};
1758 
1759  static const WCHAR WineMarshalledDataObject[] = {'W','i','n','e',' ','M','a','r','s','h','a','l','l','e','d',' ',
1760  'D','a','t','a','O','b','j','e','c','t',0};
1761 
1773 
1774  wine_marshal_clipboard_format = RegisterClipboardFormatW(WineMarshalledDataObject);
1775 }
1776 
1777 /***********************************************************************
1778  * OLEClipbrd_Initialize()
1779  * Initializes the OLE clipboard.
1780  */
1782 {
1784 
1785  if ( !theOleClipboard )
1786  {
1787  ole_clipbrd* clipbrd;
1788  HGLOBAL h;
1789 
1790  TRACE("()\n");
1791 
1792  clipbrd = HeapAlloc( GetProcessHeap(), 0, sizeof(*clipbrd) );
1793  if (!clipbrd) return;
1794 
1795  clipbrd->latest_snapshot = NULL;
1796  clipbrd->window = NULL;
1797  clipbrd->src_data = NULL;
1798  clipbrd->cached_enum = NULL;
1799 
1801  if(!h)
1802  {
1803  HeapFree(GetProcessHeap(), 0, clipbrd);
1804  return;
1805  }
1806 
1807  if(FAILED(CreateStreamOnHGlobal(h, TRUE, &clipbrd->marshal_data)))
1808  {
1809  GlobalFree(h);
1810  HeapFree(GetProcessHeap(), 0, clipbrd);
1811  return;
1812  }
1813 
1814  theOleClipboard = clipbrd;
1815  }
1816 }
1817 
1818 /*********************************************************************
1819  * set_clipboard_formats
1820  *
1821  * Enumerate all formats supported by the source and make
1822  * those formats available using delayed rendering using SetClipboardData.
1823  * Cache the enumeration list and make that list visible as the
1824  * 'Ole Private Data' format on the clipboard.
1825  *
1826  */
1828 {
1829  HRESULT hr;
1830  FORMATETC fmt;
1831  IEnumFORMATETC *enum_fmt;
1832  HGLOBAL priv_data_handle;
1833  DWORD_PTR target_offset;
1834  ole_priv_data *priv_data;
1835  DWORD count = 0, needed = sizeof(*priv_data), idx;
1836 
1837  hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
1838  if(FAILED(hr)) return hr;
1839 
1840  while(IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL) == S_OK)
1841  {
1842  count++;
1843  needed += sizeof(priv_data->entries[0]);
1844  if(fmt.ptd)
1845  {
1846  needed += fmt.ptd->tdSize;
1847  CoTaskMemFree(fmt.ptd);
1848  }
1849  }
1850 
1851  /* Windows pads the list with two empty ole_priv_data_entries, one
1852  * after the entries array and one after the target device data.
1853  * Allocating with zero init to zero these pads. */
1854 
1855  needed += sizeof(priv_data->entries[0]); /* initialisation of needed includes one of these. */
1856  priv_data_handle = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT, needed);
1857  priv_data = GlobalLock(priv_data_handle);
1858 
1859  priv_data->unk1 = 0;
1860  priv_data->size = needed;
1861  priv_data->unk2 = 1;
1862  priv_data->count = count;
1863  priv_data->unk3[0] = 0;
1864  priv_data->unk3[1] = 0;
1865 
1866  IEnumFORMATETC_Reset(enum_fmt);
1867 
1868  idx = 0;
1869  target_offset = FIELD_OFFSET(ole_priv_data, entries[count + 1]); /* count entries + one pad. */
1870 
1871  while(IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL) == S_OK)
1872  {
1873  TRACE("%s\n", dump_fmtetc(&fmt));
1874 
1875  priv_data->entries[idx].fmtetc = fmt;
1876  if(fmt.ptd)
1877  {
1878  memcpy((char*)priv_data + target_offset, fmt.ptd, fmt.ptd->tdSize);
1879  priv_data->entries[idx].fmtetc.ptd = (DVTARGETDEVICE*)target_offset;
1880  target_offset += fmt.ptd->tdSize;
1881  CoTaskMemFree(fmt.ptd);
1882  }
1883 
1884  priv_data->entries[idx].first_use = !find_format_in_list(priv_data->entries, idx, fmt.cfFormat);
1885  priv_data->entries[idx].unk[0] = 0;
1886  priv_data->entries[idx].unk[1] = 0;
1887 
1888  if (priv_data->entries[idx].first_use)
1889  SetClipboardData(fmt.cfFormat, NULL);
1890 
1891  idx++;
1892  }
1893 
1894  IEnumFORMATETC_Release(enum_fmt);
1895 
1896  /* Cache the list and fixup any target device offsets to ptrs */
1897  clipbrd->cached_enum = HeapAlloc(GetProcessHeap(), 0, needed);
1898  memcpy(clipbrd->cached_enum, priv_data, needed);
1899  for(idx = 0; idx < clipbrd->cached_enum->count; idx++)
1900  clipbrd->cached_enum->entries[idx].fmtetc.ptd =
1901  td_offs_to_ptr(clipbrd->cached_enum, (DWORD_PTR)clipbrd->cached_enum->entries[idx].fmtetc.ptd);
1902 
1903  GlobalUnlock(priv_data_handle);
1904  if(!SetClipboardData(ole_private_data_clipboard_format, priv_data_handle))
1905  {
1906  GlobalFree(priv_data_handle);
1907  return CLIPBRD_E_CANT_SET;
1908  }
1909 
1910  return S_OK;
1911 }
1912 
1913 static HWND create_clipbrd_window(void);
1914 
1915 /***********************************************************************
1916  * get_clipbrd_window
1917  */
1918 static inline HRESULT get_clipbrd_window(ole_clipbrd *clipbrd, HWND *wnd)
1919 {
1920 #ifdef __REACTOS__
1921  /* The clipboard window can get destroyed if the thread that created it dies so we may need to create it again */
1922  if (!IsWindow(clipbrd->window))
1923  clipbrd->window = create_clipbrd_window();
1924 #endif
1925 
1926  if ( !clipbrd->window )
1927  clipbrd->window = create_clipbrd_window();
1928 
1929  *wnd = clipbrd->window;
1930  return *wnd ? S_OK : E_FAIL;
1931 }
1932 
1933 
1934 /**********************************************************************
1935  * release_marshal_data
1936  *
1937  * Releases the data and sets the stream back to zero size.
1938  */
1939 static inline void release_marshal_data(IStream *stm)
1940 {
1943  pos.QuadPart = size.QuadPart = 0;
1944 
1945  IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
1946  CoReleaseMarshalData(stm);
1947  IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
1948  IStream_SetSize(stm, size);
1949 }
1950 
1951 /***********************************************************************
1952  * expose_marshalled_dataobject
1953  *
1954  * Sets the marshalled dataobject to the clipboard. In the flushed case
1955  * we set a zero sized HGLOBAL to clear the old marshalled data.
1956  */
1958 {
1959  HGLOBAL h;
1960 
1961  if(data)
1962  {
1963  HGLOBAL h_stm;
1964  GetHGlobalFromStream(clipbrd->marshal_data, &h_stm);
1966  }
1967  else /* flushed */
1969 
1970  if(!h) return E_OUTOFMEMORY;
1971 
1973  {
1974  GlobalFree(h);
1975  return CLIPBRD_E_CANT_SET;
1976  }
1977  return S_OK;
1978 }
1979 
1980 /***********************************************************************
1981  * set_src_dataobject
1982  *
1983  * Clears and sets the clipboard's src IDataObject.
1984  *
1985  * To marshal the source dataobject we do something rather different from Windows.
1986  * We set a clipboard format which contains the marshalled data.
1987  * Windows sets two window props one of which is an IID, the other is an endpoint number.
1988  */
1990 {
1991  HRESULT hr;
1992  HWND wnd;
1993 
1994  if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
1995 
1996  if(clipbrd->src_data)
1997  {
1999 
2000  IDataObject_Release(clipbrd->src_data);
2001  clipbrd->src_data = NULL;
2002  HeapFree(GetProcessHeap(), 0, clipbrd->cached_enum);
2003  clipbrd->cached_enum = NULL;
2004  }
2005 
2006  if(data)
2007  {
2008  IUnknown *unk;
2009 
2010  IDataObject_AddRef(data);
2011  clipbrd->src_data = data;
2012 
2013  IDataObject_QueryInterface(data, &IID_IUnknown, (void**)&unk);
2015  MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG);
2016  IUnknown_Release(unk); /* Don't hold a ref on IUnknown, we have one on IDataObject. */
2017  if(FAILED(hr)) return hr;
2018  hr = set_clipboard_formats(clipbrd, data);
2019  }
2020  return hr;
2021 }
2022 
2023 /***********************************************************************
2024  * OLEClipbrd_UnInitialize()
2025  * Un-Initializes the OLE clipboard
2026  */
2028 {
2029  ole_clipbrd *clipbrd = theOleClipboard;
2030 
2031  TRACE("()\n");
2032 
2033  if ( clipbrd )
2034  {
2035  static const WCHAR ole32W[] = {'o','l','e','3','2',0};
2036  HINSTANCE hinst = GetModuleHandleW(ole32W);
2037 
2038  /* OleUninitialize() does not release the reference to the dataobject, so
2039  take an additional reference here. This reference is then leaked. */
2040  if (clipbrd->src_data)
2041  {
2042  IDataObject_AddRef(clipbrd->src_data);
2043  set_src_dataobject(clipbrd, NULL);
2044  }
2045 
2046  if ( clipbrd->window )
2047  {
2048  DestroyWindow(clipbrd->window);
2050  }
2051 
2052  IStream_Release(clipbrd->marshal_data);
2053  HeapFree(GetProcessHeap(), 0, clipbrd);
2055  }
2056 }
2057 
2058 /***********************************************************************
2059  * clipbrd_wndproc
2060  */
2062 {
2063  ole_clipbrd *clipbrd;
2064 
2065  get_ole_clipbrd(&clipbrd);
2066 #ifdef __REACTOS__
2067  if(clipbrd == NULL)
2069 #endif
2070 
2071  switch (message)
2072  {
2073  case WM_RENDERFORMAT:
2074  {
2075 #ifdef __REACTOS__
2076  if (clipbrd->cached_enum)
2077  {
2078 #endif
2079  UINT cf = wparam;
2081 
2082  TRACE("(): WM_RENDERFORMAT(cfFormat=%x)\n", cf);
2083  entry = find_format_in_list(clipbrd->cached_enum->entries, clipbrd->cached_enum->count, cf);
2084 
2085  if(entry)
2086  render_format(clipbrd->src_data, &entry->fmtetc);
2087 #ifdef __REACTOS__
2088  }
2089 #endif
2090  break;
2091  }
2092 
2093  case WM_RENDERALLFORMATS:
2094  {
2095  DWORD i;
2096  ole_priv_data_entry *entries;
2097 
2098  TRACE("(): WM_RENDERALLFORMATS\n");
2099 
2100  if (!clipbrd || !clipbrd->cached_enum) break;
2101  entries = clipbrd->cached_enum->entries;
2102  for(i = 0; i < clipbrd->cached_enum->count; i++)
2103  {
2104  if(entries[i].first_use)
2105  render_format(clipbrd->src_data, &entries[i].fmtetc);
2106  }
2107  break;
2108  }
2109 
2110  case WM_DESTROYCLIPBOARD:
2111  {
2112  TRACE("(): WM_DESTROYCLIPBOARD\n");
2113 
2114  set_src_dataobject(clipbrd, NULL);
2115  break;
2116  }
2117 
2118  default:
2120  }
2121 
2122  return 0;
2123 }
2124 
2125 
2126 /***********************************************************************
2127  * create_clipbrd_window
2128  */
2130 {
2131  WNDCLASSEXW class;
2132  static const WCHAR ole32W[] = {'o','l','e','3','2',0};
2133  static const WCHAR title[] = {'C','l','i','p','b','o','a','r','d','W','i','n','d','o','w',0};
2134  HINSTANCE hinst = GetModuleHandleW(ole32W);
2135 
2136  class.cbSize = sizeof(class);
2137  class.style = 0;
2138  class.lpfnWndProc = clipbrd_wndproc;
2139  class.cbClsExtra = 0;
2140  class.cbWndExtra = 0;
2141  class.hInstance = hinst;
2142  class.hIcon = 0;
2143  class.hCursor = 0;
2144  class.hbrBackground = 0;
2145  class.lpszMenuName = NULL;
2146  class.lpszClassName = clipbrd_wndclass;
2147  class.hIconSm = NULL;
2148 
2149  RegisterClassExW(&class);
2150 
2152  0, 0, 0, 0, HWND_MESSAGE, NULL, hinst, 0);
2153 }
2154 
2155 /*********************************************************************
2156  * set_dataobject_format
2157  *
2158  * Windows creates a 'DataObject' clipboard format that contains the
2159  * clipboard window's HWND or NULL if the Ole clipboard has been flushed.
2160  */
2162 {
2164  HWND *data;
2165 
2166  if(!h) return E_OUTOFMEMORY;
2167 
2168  data = GlobalLock(h);
2169  *data = hwnd;
2170  GlobalUnlock(h);
2171 
2173  {
2174  GlobalFree(h);
2175  return CLIPBRD_E_CANT_SET;
2176  }
2177 
2178  return S_OK;
2179 }
2180 
2181 /*---------------------------------------------------------------------*
2182  * Win32 OLE clipboard API
2183  *---------------------------------------------------------------------*/
2184 
2185 /***********************************************************************
2186  * OleSetClipboard [OLE32.@]
2187  * Places a pointer to the specified data object onto the clipboard,
2188  * making the data object accessible to the OleGetClipboard function.
2189  *
2190  * RETURNS
2191  *
2192  * S_OK IDataObject pointer placed on the clipboard
2193  * CLIPBRD_E_CANT_OPEN OpenClipboard failed
2194  * CLIPBRD_E_CANT_EMPTY EmptyClipboard failed
2195  * CLIPBRD_E_CANT_CLOSE CloseClipboard failed
2196  * CLIPBRD_E_CANT_SET SetClipboard failed
2197  */
2198 
2200 {
2201  HRESULT hr;
2202  ole_clipbrd *clipbrd;
2203  HWND wnd;
2204 
2205  TRACE("(%p)\n", data);
2206 
2207  if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
2208 
2209  if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
2210 
2211  if ( !OpenClipboard(wnd) ) return CLIPBRD_E_CANT_OPEN;
2212 
2213  if ( !EmptyClipboard() )
2214  {
2216  goto end;
2217  }
2218 
2219  hr = set_src_dataobject(clipbrd, data);
2220  if(FAILED(hr)) goto end;
2221 
2222  if(data)
2223  {
2224  hr = expose_marshalled_dataobject(clipbrd, data);
2225  if(FAILED(hr)) goto end;
2226  hr = set_dataobject_format(wnd);
2227  }
2228 
2229 end:
2230 
2232 
2233  if ( FAILED(hr) )
2234  {
2236  set_src_dataobject(clipbrd, NULL);
2237  }
2238 
2239  return hr;
2240 }
2241 
2242 
2243 /***********************************************************************
2244  * OleGetClipboard [OLE32.@]
2245  * Returns a pointer to our internal IDataObject which represents the conceptual
2246  * state of the Windows clipboard. If the current clipboard already contains
2247  * an IDataObject, our internal IDataObject will delegate to this object.
2248  */
2250 {
2251  HRESULT hr;
2252  ole_clipbrd *clipbrd;
2253  DWORD seq_no;
2254 
2255  TRACE("(%p)\n", obj);
2256 
2257  if(!obj) return E_INVALIDARG;
2258  *obj = NULL;
2259 
2260  if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
2261 
2262  seq_no = GetClipboardSequenceNumber();
2264  if(clipbrd->latest_snapshot && clipbrd->latest_snapshot->seq_no != seq_no)
2265  clipbrd->latest_snapshot = NULL;
2266 
2267  if(!clipbrd->latest_snapshot)
2268  {
2269  clipbrd->latest_snapshot = snapshot_construct(seq_no);
2270  if(!clipbrd->latest_snapshot)
2271  {
2273  return E_OUTOFMEMORY;
2274  }
2275  }
2276 
2277  *obj = &clipbrd->latest_snapshot->IDataObject_iface;
2278  IDataObject_AddRef(*obj);
2280 
2281  return S_OK;
2282 }
2283 
2284 /******************************************************************************
2285  * OleFlushClipboard [OLE32.@]
2286  * Renders the data from the source IDataObject into the windows clipboard
2287  *
2288  * TODO: OleFlushClipboard needs to additionally handle TYMED_IStorage media
2289  * by copying the storage into global memory. Subsequently the default
2290  * data object exposed through OleGetClipboard must convert this TYMED_HGLOBAL
2291  * back to TYMED_IStorage.
2292  */
2294 {
2295  HRESULT hr;
2296  ole_clipbrd *clipbrd;
2297  HWND wnd;
2298 
2299  TRACE("()\n");
2300 
2301  if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
2302 
2303  if(FAILED(hr = get_clipbrd_window(clipbrd, &wnd))) return hr;
2304 
2305  /*
2306  * Already flushed or no source DataObject? Nothing to do.
2307  */
2308  if (!clipbrd->src_data) return S_OK;
2309 
2310  if (!OpenClipboard(wnd)) return CLIPBRD_E_CANT_OPEN;
2311 
2312  SendMessageW(wnd, WM_RENDERALLFORMATS, 0, 0);
2313 
2315 
2317  set_src_dataobject(clipbrd, NULL);
2318 
2320 
2321  return hr;
2322 }
2323 
2324 
2325 /***********************************************************************
2326  * OleIsCurrentClipboard [OLE32.@]
2327  */
2329 {
2330  HRESULT hr;
2331  ole_clipbrd *clipbrd;
2332  TRACE("()\n");
2333 
2334  if(FAILED(hr = get_ole_clipbrd(&clipbrd))) return hr;
2335 
2336  if (data == NULL) return S_FALSE;
2337 
2338  return (data == clipbrd->src_data) ? S_OK : S_FALSE;
2339 }
HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
Definition: marshal.c:2056
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
static IClassFactory * cf
HANDLE HGLOBAL
Definition: windef.h:243
WCHAR OLECHAR
Definition: compat.h:1933
static ULONG WINAPI snapshot_AddRef(IDataObject *iface)
Definition: clipboard.c:1029
static HRESULT WINAPI snapshot_QueryInterface(IDataObject *iface, REFIID riid, void **ppvObject)
Definition: clipboard.c:999
UINT ownerlink_clipboard_format
Definition: clipboard.c:203
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
Definition: marshal.c:1982
HMETAFILE hMF
Definition: wingdi.h:2586
static HRESULT WINAPI snapshot_QueryGetData(IDataObject *iface, FORMATETC *fmt)
Definition: clipboard.c:1603
static CRITICAL_SECTION_DEBUG latest_snapshot_cs_debug
Definition: clipboard.c:178
void OLEClipbrd_UnInitialize(void)
Definition: clipboard.c:2027
Definition: tftpd.h:59
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2199
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
static HRESULT WINAPI snapshot_DAdvise(IDataObject *iface, FORMATETC *fmt, DWORD flags, IAdviseSink *sink, DWORD *conn)
Definition: clipboard.c:1675
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
UINT filename_clipboard_format
Definition: clipboard.c:204
HRESULT WINAPI GetHGlobalFromStream(IStream *pstm, HGLOBAL *phglobal)
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT expose_marshalled_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
Definition: clipboard.c:1957
static HRESULT get_stgmed_for_storage(HGLOBAL h, STGMEDIUM *med)
Definition: clipboard.c:1280
#define WM_RENDERFORMAT
Definition: winuser.h:1827
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL global, BOOL delete_on_release, ILockBytes **ret)
Definition: memlockbytes.c:100
BOOL WINAPI IsClipboardFormatAvailable(_In_ UINT)
void OLEClipbrd_Initialize(void)
Definition: clipboard.c:1781
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
#define DWORD_PTR
Definition: treelist.c:76
#define WideCharToMultiByte
Definition: compat.h:101
#define CF_ENHMETAFILE
Definition: constants.h:409
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
#define DATA_S_SAMEFORMATETC
Definition: winerror.h:2674
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:922
static HRESULT WINAPI snapshot_GetDataHere(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med)
Definition: clipboard.c:1488
IEnumFORMATETC IEnumFORMATETC_iface
Definition: clipboard.c:231
static HRESULT enum_fmtetc_construct(ole_priv_data *data, UINT pos, IEnumFORMATETC **obj)
Definition: clipboard.c:430
static BOOL string_off_equal(const DVTARGETDEVICE *t1, WORD off1, const DVTARGETDEVICE *t2, WORD off2)
Definition: clipboard.c:1356
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2036
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
UINT custom_link_source_clipboard_format
Definition: clipboard.c:209
struct PresentationDataHeader PresentationDataHeader
#define WM_RENDERALLFORMATS
Definition: winuser.h:1828
LONG ref
Definition: clipboard.c:139
REFIID riid
Definition: precomp.h:44
static HRESULT render_format(IDataObject *data, LPFORMATETC fmt)
Definition: clipboard.c:929
static IDataObject DataObject
Definition: dragdrop.c:565
FORMATETC fmtetc
Definition: clipboard.c:88
static DVTARGETDEVICE * td_offs_to_ptr(ole_priv_data *data, DWORD_PTR off)
Definition: clipboard.c:112
#define CP_ACP
Definition: compat.h:99
static HRESULT dup_bitmap(HBITMAP src, HBITMAP *pdest)
Definition: clipboard.c:538
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
UINT link_source_descriptor_clipboard_format
Definition: clipboard.c:212
GLuint GLuint GLsizei count
Definition: gl.h:1545
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:111
static ole_priv_data_entry * find_format_in_list(ole_priv_data_entry *entries, DWORD num, UINT cf)
Definition: clipboard.c:689
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2024
#define STGM_CREATE
Definition: objbase.h:925
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
const char * fmt
Definition: wsprintf.c:30
static void free_metafilepict(HGLOBAL src)
Definition: clipboard.c:520
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
HANDLE WINAPI GetClipboardData(UINT uFormat)
Definition: clipboard.c:194
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
static UINT wine_marshal_clipboard_format
Definition: clipboard.c:215
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
const GUID IID_IDataObject
UINT embedded_object_clipboard_format
Definition: clipboard.c:207
#define DV_E_CLIPFORMAT
Definition: winerror.h:2639
UINT_PTR WPARAM
Definition: windef.h:207
GLuint GLuint end
Definition: gl.h:1545
#define HWND_MESSAGE
Definition: winuser.h:1196
Definition: clipboard.c:86
#define GMEM_SHARE
Definition: winbase.h:302
#define CF_METAFILEPICT
Definition: constants.h:398
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
HWND window
Definition: clipboard.c:153
Definition: features.h:417
static LPDATAOBJECT clip_data
Definition: clipboard.c:1034
static LPOLESTR
Definition: stg_prop.c:27
#define E_FAIL
Definition: ddrawi.h:102
BOOL WINAPI DestroyWindow(_In_ HWND)
static const IEnumFORMATETCVtbl efvt
Definition: clipboard.c:414
static VOID NTAPI BitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer, IN ULONG BitsPerPixel, IN ULONG Delta)
Definition: vga.c:416
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4185
int32_t INT
Definition: typedefs.h:56
Definition: send.c:47
static HRESULT WINAPI snapshot_DUnadvise(IDataObject *iface, DWORD conn)
Definition: clipboard.c:1688
static struct oletls * COM_CurrentInfo(void)
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
struct snapshot snapshot
IDataObject * src_data
Definition: clipboard.c:154
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
static const char * dump_fmtetc(FORMATETC *fmt)
Definition: clipboard.c:217
#define CO_E_NOTINITIALIZED
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:271
static enum_fmtetc * impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
Definition: clipboard.c:238
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *)
HRESULT WINAPI OleIsCurrentClipboard(IDataObject *data)
Definition: clipboard.c:2328
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UINT ole_private_data_clipboard_format
Definition: clipboard.c:213
HRESULT WINAPI DECLSPEC_HOTPATCH ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID)
Definition: compobj.c:2439
GLenum GLint GLuint mask
Definition: glext.h:6028
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static HRESULT get_data_from_storage(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
Definition: clipboard.c:704
static CRITICAL_SECTION latest_snapshot_cs
Definition: clipboard.c:177
DWORD unk3[2]
Definition: clipboard.c:99
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
#define debugstr_w
Definition: kernel32.h:32
HRESULT WINAPI StgCreateDocfileOnILockBytes(ILockBytes *plkbyt, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8947
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
UINT WINAPI RegisterClipboardFormatW(LPCWSTR lpszFormat)
Definition: clipboard.c:125
HRESULT STORAGE_CreateOleStream(IStorage *storage, DWORD flags)
Definition: storage32.c:9208
static PVOID ptr
Definition: dispmode.c:27
IStream * marshal_data
Definition: clipboard.c:156
unsigned int idx
Definition: utils.c:41
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_BITMAP
Definition: constants.h:397
DWORD first_use
Definition: clipboard.c:89
static HRESULT copy_formatetc(FORMATETC *dst, const FORMATETC *src)
UINT dataobject_clipboard_format
Definition: clipboard.c:206
smooth NULL
Definition: ftsmooth.c:416
static HRESULT get_current_dataobject(IDataObject **data)
Definition: clipboard.c:1097
struct ole_clipbrd ole_clipbrd
LONG_PTR LPARAM
Definition: windef.h:208
WINE_DEFAULT_DEBUG_CHANNEL(ole)
DWORD seq_no
Definition: clipboard.c:141
unsigned int dir
Definition: maze.c:112
static void release_marshal_data(IStream *stm)
Definition: clipboard.c:1939
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT get_data_from_stream(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
Definition: clipboard.c:759
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define CF_TEXT
Definition: constants.h:396
static HRESULT WINAPI snapshot_SetData(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med, BOOL release)
Definition: clipboard.c:1635
INT WINAPI GetClipboardFormatNameW(UINT uFormat, LPWSTR lpszFormatName, INT cchMaxCount)
Definition: clipboard.c:80
HBITMAP hbmp
static HRESULT set_clipboard_formats(ole_clipbrd *clipbrd, IDataObject *data)
Definition: clipboard.c:1827
static HRESULT render_embed_source_hack(IDataObject *data, LPFORMATETC fmt)
Definition: clipboard.c:569
HANDLE WINAPI SetClipboardData(UINT uFormat, HANDLE hMem)
Definition: clipboard.c:285
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
IDataObject IDataObject_iface
Definition: clipboard.c:138
BOOL WINAPI OpenClipboard(HWND hWndNewOwner)
Definition: clipboard.c:23
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
DWORD size
Definition: clipboard.c:96
#define DV_E_FORMATETC
Definition: winerror.h:2633
#define WS_OVERLAPPED
Definition: pedump.c:615
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static ULONG WINAPI OLEClipbrd_IEnumFORMATETC_AddRef(LPENUMFORMATETC iface)
Definition: clipboard.c:278
__wchar_t WCHAR
Definition: xmlstorage.h:180
static UINT count
Definition: clipboard.c:35
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
static HWND create_clipbrd_window(void)
Definition: clipboard.c:2129
#define WINAPI
Definition: msvc.h:8
static HRESULT get_stgmed_for_stream(HGLOBAL h, STGMEDIUM *med)
Definition: clipboard.c:1253
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static BOOL td_equal(const DVTARGETDEVICE *t1, const DVTARGETDEVICE *t2)
Definition: clipboard.c:1369
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
static HRESULT WINAPI snapshot_EnumFormatEtc(IDataObject *iface, DWORD dir, IEnumFORMATETC **enum_fmt)
Definition: clipboard.c:1646
struct enum_fmtetc enum_fmtetc
const GUID IID_IEnumFORMATETC
HRESULT WINAPI StgOpenStorageOnILockBytes(ILockBytes *plkbyt, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8985
HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt)
Definition: storage32.c:9057
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
#define DV_E_TYMED
Definition: winerror.h:2638
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
IDataObject * data
Definition: clipboard.c:143
HENHMETAFILE WINAPI CopyEnhMetaFileW(_In_ HENHMETAFILE hemfSrc, _In_opt_ LPCWSTR pszFile)
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Skip(LPENUMFORMATETC iface, ULONG celt)
Definition: clipboard.c:355
UINT link_source_clipboard_format
Definition: clipboard.c:210
DWORD unk2
Definition: clipboard.c:97
interface IEnumFORMATETC * LPENUMFORMATETC
Definition: objfwd.h:24
int ret
ole_priv_data * data
Definition: clipboard.c:235
static LRESULT CALLBACK clipbrd_wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: clipboard.c:2061
DWORD unk1
Definition: clipboard.c:95
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define InterlockedDecrement
Definition: armddk.h:52
HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName)
Definition: storage32.c:10029
static HRESULT get_data_from_enhmetafile(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
Definition: clipboard.c:840
static HRESULT get_data_from_metafilepict(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
Definition: clipboard.c:868
uint32_t entry
Definition: isohybrid.c:63
DWORD count
Definition: clipboard.c:98
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
REFIID LPVOID * ppvObject
Definition: precomp.h:44
GLenum src
Definition: glext.h:6340
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define STGM_READWRITE
Definition: objbase.h:918
static HRESULT get_clipbrd_window(ole_clipbrd *clipbrd, HWND *wnd)
Definition: clipboard.c:1918
EXTINLINE DWORD WINAPI GetClipboardSequenceNumber(VOID)
Definition: ntwrapper.h:202
static HRESULT set_src_dataobject(ole_clipbrd *clipbrd, IDataObject *data)
Definition: clipboard.c:1989
static DWORD_PTR td_get_offs(ole_priv_data *data, DWORD idx)
Definition: clipboard.c:126
DWORD unk[2]
Definition: clipboard.c:90
#define CLIPBRD_E_CANT_CLOSE
Definition: winerror.h:2770
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Next(LPENUMFORMATETC iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
Definition: clipboard.c:314
snapshot * latest_snapshot
Definition: clipboard.c:151
static snapshot * impl_from_IDataObject(IDataObject *iface)
Definition: clipboard.c:159
#define S_OK
Definition: intsafe.h:59
ole_priv_data * cached_enum
Definition: clipboard.c:155
static ULONG WINAPI OLEClipbrd_IEnumFORMATETC_Release(LPENUMFORMATETC iface)
Definition: clipboard.c:291
static HRESULT set_dataobject_format(HWND hwnd)
Definition: clipboard.c:2161
static ULONG WINAPI snapshot_Release(IDataObject *iface)
Definition: clipboard.c:1041
#define InterlockedIncrement
Definition: armddk.h:53
#define CF_OEMTEXT
Definition: constants.h:402
BOOL WINAPI DeleteDC(_In_ HDC)
static DWORD get_tymed_from_nonole_cf(UINT cf)
Definition: clipboard.c:1132
#define ARRAY_SIZE(a)
Definition: main.h:24
static snapshot * snapshot_construct(DWORD seq_no)
Definition: clipboard.c:1726
static HRESULT get_ole_clipbrd(ole_clipbrd **clipbrd)
Definition: clipboard.c:186
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
Definition: bl.h:1331
#define E_NOTIMPL
Definition: ddrawi.h:99
GLenum GLenum dst
Definition: glext.h:6340
HMETAFILE WINAPI CopyMetaFileW(_In_ HMETAFILE hmfSrc, _In_opt_ LPCWSTR pszFile)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
HRESULT WINAPI ReadClassStg(IStorage *pstg, CLSID *pclsid)
Definition: storage32.c:9104
UINT object_descriptor_clipboard_format
Definition: clipboard.c:211
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
static HRESULT get_stgmed_for_global(HGLOBAL h, STGMEDIUM *med)
Definition: clipboard.c:1234
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
UINT WINAPI EnumClipboardFormats(UINT format)
Definition: clipboard.c:33
#define GMEM_DDESHARE
Definition: winbase.h:295
static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med)
Definition: clipboard.c:1389
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Clone(LPENUMFORMATETC iface, LPENUMFORMATETC *obj)
Definition: clipboard.c:391
#define CLIPBRD_E_CANT_SET
Definition: winerror.h:2768
#define CLIPBRD_E_CANT_EMPTY
Definition: winerror.h:2767
Definition: mem.c:156
#define CLIPBRD_E_CANT_OPEN
Definition: winerror.h:2766
static HRESULT get_data_from_global(IDataObject *data, FORMATETC *fmt, HGLOBAL *mem)
Definition: clipboard.c:812
Definition: name.c:36
UINT embed_source_clipboard_format
Definition: clipboard.c:208
#define WM_DESTROYCLIPBOARD
Definition: winuser.h:1829
static HMODULE pdh
Definition: pdh.c:30
unsigned int ULONG
Definition: retypes.h:1
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
static const WCHAR clipbrd_wndclass[]
Definition: clipboard.c:201
static HINSTANCE hinst
Definition: edit.c:551
static HRESULT get_priv_data(ole_priv_data **data)
Definition: clipboard.c:1159
static void register_clipboard_formats(void)
Definition: clipboard.c:1744
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
static HRESULT dup_metafilepict(HGLOBAL src, HGLOBAL *pdest)
Definition: clipboard.c:483
ole_priv_data_entry entries[1]
Definition: clipboard.c:100
static char * dest
Definition: rtl.c:135
static HBITMAP
Definition: button.c:44
UINT filenameW_clipboard_format
Definition: clipboard.c:205
static HRESULT get_data_from_bitmap(IDataObject *data, FORMATETC *fmt, HBITMAP *hbm)
Definition: clipboard.c:898
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
HRESULT WINAPI OleFlushClipboard(void)
Definition: clipboard.c:2293
static HRESULT WINAPI snapshot_EnumDAdvise(IDataObject *iface, IEnumSTATDATA **enum_advise)
Definition: clipboard.c:1699
LONG_PTR LRESULT
Definition: windef.h:209
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, DWORD dwDestContext, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:1877
UINT WINAPI GetMetaFileBitsEx(_In_ HMETAFILE hMF, _In_ UINT cbBuffer, _Out_writes_bytes_opt_(cbBuffer) LPVOID lpData)
static const IDataObjectVtbl snapshot_vtable
Definition: clipboard.c:1706
#define memset(x, y, z)
Definition: compat.h:39
static HRESULT get_stgmed_for_bitmap(HBITMAP hbmp, STGMEDIUM *med)
Definition: clipboard.c:1340
static ole_clipbrd * theOleClipboard
Definition: clipboard.c:175
static char title[]
Definition: ps.c:92
Definition: dsound.c:943
#define HeapFree(x, y, z)
Definition: compat.h:394
#define GMEM_MOVEABLE
Definition: winbase.h:291
#define SRCCOPY
Definition: wingdi.h:332
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_Reset(LPENUMFORMATETC iface)
Definition: clipboard.c:374
#define GMEM_ZEROINIT
Definition: winbase.h:303
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
static HRESULT dup_global_mem(HGLOBAL src, DWORD flags, HGLOBAL *dst)
Definition: clipboard.c:453
static HWND get_current_ole_clip_window(void)
Definition: clipboard.c:1077
static HRESULT WINAPI snapshot_GetCanonicalFormatEtc(IDataObject *iface, FORMATETC *fmt_in, FORMATETC *fmt_out)
Definition: clipboard.c:1619
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static UINT WPARAM wparam
Definition: combo.c:716
LONGLONG QuadPart
Definition: typedefs.h:112
static HRESULT get_stgmed_for_emf(HENHMETAFILE hemf, STGMEDIUM *med)
Definition: clipboard.c:1324
off
Definition: i386-dis.c:3909
static HRESULT WINAPI OLEClipbrd_IEnumFORMATETC_QueryInterface(LPENUMFORMATETC iface, REFIID riid, LPVOID *ppvObj)
Definition: clipboard.c:249