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