ReactOS  0.4.14-dev-49-gfb4591c
clipboard.c
Go to the documentation of this file.
1 /*
2  * Clipboard unit tests
3  *
4  * Copyright 2006 Kevin Koltzau
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 #define CONST_VTABLE
23 #ifndef __REACTOS__
24 #define NONAMELESSUNION
25 #endif
26 
27 #include <stdarg.h>
28 #include <stdio.h>
29 
30 #include "windef.h"
31 #include "winbase.h"
32 #include "objbase.h"
33 
34 #include "wine/test.h"
35 
36 #define InitFormatEtc(fe, cf, med) \
37  {\
38  (fe).cfFormat=cf;\
39  (fe).dwAspect=DVASPECT_CONTENT;\
40  (fe).ptd=NULL;\
41  (fe).tymed=med;\
42  (fe).lindex=-1;\
43  };
44 
45 static inline char *dump_fmtetc(FORMATETC *fmt)
46 {
47  static char buf[100];
48 
49  snprintf(buf, sizeof(buf), "cf %04x ptd %p aspect %x lindex %d tymed %x",
50  fmt->cfFormat, fmt->ptd, fmt->dwAspect, fmt->lindex, fmt->tymed);
51  return buf;
52 }
53 
54 typedef struct DataObjectImpl {
56  LONG ref;
57 
58  FORMATETC *fmtetc;
60 
64  HMETAFILEPICT hmfp;
66 
67 typedef struct EnumFormatImpl {
69  LONG ref;
70 
71  FORMATETC *fmtetc;
73 
74  UINT cur;
76 
81 
83 
84 static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);
85 
86 static HMETAFILE create_mf(void)
87 {
88  RECT rect = {0, 0, 100, 100};
90  ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
91  return CloseMetaFile(hdc);
92 }
93 
94 static HMETAFILEPICT create_metafilepict(void)
95 {
98  mf->mm = MM_ANISOTROPIC;
99  mf->xExt = 100;
100  mf->yExt = 200;
101  mf->hMF = create_mf();
102  GlobalUnlock(ret);
103  return ret;
104 }
105 
107 {
108  return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface);
109 }
110 
112 {
113  return CONTAINING_RECORD(iface, EnumFormatImpl, IEnumFORMATETC_iface);
114 }
115 
117 {
119 
121  IEnumFORMATETC_AddRef(iface);
122  *ppvObj = &This->IEnumFORMATETC_iface;
123  return S_OK;
124  }
125  *ppvObj = NULL;
126  return E_NOINTERFACE;
127 }
128 
130 {
133  return ref;
134 }
135 
137 {
140 
141  if(!ref) {
142  HeapFree(GetProcessHeap(), 0, This->fmtetc);
144  }
145 
146  return ref;
147 }
148 
150  FORMATETC *rgelt, ULONG *pceltFetched)
151 {
153  ULONG count, i;
154 
155  if (winetest_debug > 1)
156  trace("next: count %d cur %d\n", celt, This->cur);
157 
158  if(!rgelt)
159  return E_INVALIDARG;
160 
161  count = min(celt, This->fmtetc_cnt - This->cur);
162  for(i = 0; i < count; i++, This->cur++, rgelt++)
163  {
164  *rgelt = This->fmtetc[This->cur];
165  if(rgelt->ptd)
166  {
167  DWORD size = This->fmtetc[This->cur].ptd->tdSize;
168  rgelt->ptd = CoTaskMemAlloc(size);
169  memcpy(rgelt->ptd, This->fmtetc[This->cur].ptd, size);
170  }
171  }
172  if(pceltFetched)
173  *pceltFetched = count;
174  return count == celt ? S_OK : S_FALSE;
175 }
176 
178 {
179  ok(0, "unexpected call\n");
180  return E_NOTIMPL;
181 }
182 
184 {
186 
187  This->cur = 0;
188  return S_OK;
189 }
190 
192 {
193  ok(0, "unexpected call\n");
194  return E_NOTIMPL;
195 }
196 
197 static const IEnumFORMATETCVtbl VT_EnumFormatImpl = {
205 };
206 
207 static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFORMATETC **lplpformatetc)
208 {
210 
211  ret = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumFormatImpl));
212  ret->IEnumFORMATETC_iface.lpVtbl = &VT_EnumFormatImpl;
213  ret->ref = 1;
214  ret->cur = 0;
215  ret->fmtetc_cnt = fmtetc_cnt;
216  ret->fmtetc = HeapAlloc(GetProcessHeap(), 0, fmtetc_cnt*sizeof(FORMATETC));
217  memcpy(ret->fmtetc, fmtetc, fmtetc_cnt*sizeof(FORMATETC));
218  *lplpformatetc = &ret->IEnumFORMATETC_iface;
219  return S_OK;
220 }
221 
223 {
225 
227  IDataObject_AddRef(iface);
228  *ppvObj = &This->IDataObject_iface;
229  return S_OK;
230  }
231  *ppvObj = NULL;
232  return E_NOINTERFACE;
233 }
234 
236 {
239  return ref;
240 }
241 
243 {
246 
247  if(!ref)
248  {
249  int i;
250  if(This->text) GlobalFree(This->text);
251  for(i = 0; i < This->fmtetc_cnt; i++)
252  HeapFree(GetProcessHeap(), 0, This->fmtetc[i].ptd);
253  HeapFree(GetProcessHeap(), 0, This->fmtetc);
254  if(This->stm) IStream_Release(This->stm);
255  if(This->stg) IStorage_Release(This->stg);
256  if(This->hmfp) {
257  METAFILEPICT *mfp = GlobalLock(This->hmfp);
258  DeleteMetaFile(mfp->hMF);
259  GlobalUnlock(This->hmfp);
260  GlobalFree(This->hmfp);
261  }
263  }
264 
265  return ref;
266 }
267 
268 static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
269 {
271  UINT i;
272 
273  trace("getdata: %s\n", dump_fmtetc(pformatetc));
274 
276 
277  ok(pmedium->tymed == 0, "pmedium->tymed = %u\n", pmedium->tymed);
278  ok(U(*pmedium).hGlobal == NULL, "pmedium->hGlobal = %p\n", U(*pmedium).hGlobal);
279  ok(pmedium->pUnkForRelease == NULL, "pmedium->pUnkForRelease = %p\n", pmedium->pUnkForRelease);
280 
281  if(pformatetc->lindex != -1)
282  return DV_E_FORMATETC;
283 
284  for(i = 0; i < This->fmtetc_cnt; i++)
285  {
286  if(This->fmtetc[i].cfFormat == pformatetc->cfFormat)
287  {
288  if(This->fmtetc[i].tymed & pformatetc->tymed)
289  {
290  pmedium->pUnkForRelease = (LPUNKNOWN)iface;
291  IUnknown_AddRef(pmedium->pUnkForRelease);
292 
293  if(pformatetc->cfFormat == CF_TEXT || pformatetc->cfFormat == cf_global)
294  {
295  pmedium->tymed = TYMED_HGLOBAL;
296  U(*pmedium).hGlobal = This->text;
297  }
298  else if(pformatetc->cfFormat == cf_stream)
299  {
300  pmedium->tymed = TYMED_ISTREAM;
301  IStream_AddRef(This->stm);
302  U(*pmedium).pstm = This->stm;
303  }
304  else if(pformatetc->cfFormat == cf_storage || pformatetc->cfFormat == cf_another)
305  {
306  pmedium->tymed = TYMED_ISTORAGE;
307  IStorage_AddRef(This->stg);
308  U(*pmedium).pstg = This->stg;
309  }
310  else if(pformatetc->cfFormat == CF_METAFILEPICT)
311  {
312  pmedium->tymed = TYMED_MFPICT;
313  U(*pmedium).hMetaFilePict = This->hmfp;
314  }
315  return S_OK;
316  }
317  }
318  }
319 
320  return E_FAIL;
321 }
322 
323 static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
324 {
325  trace("getdatahere: %s\n", dump_fmtetc(pformatetc));
327 
328  return E_NOTIMPL;
329 }
330 
331 static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC *pformatetc)
332 {
334  UINT i;
335  BOOL foundFormat = FALSE;
336 
337  trace("querygetdata: %s\n", dump_fmtetc(pformatetc));
339  ok(0, "unexpected call to DataObjectImpl_QueryGetData\n");
340 
341  if(pformatetc->lindex != -1)
342  return DV_E_LINDEX;
343 
344  for(i=0; i<This->fmtetc_cnt; i++) {
345  if(This->fmtetc[i].cfFormat == pformatetc->cfFormat) {
346  foundFormat = TRUE;
347  if(This->fmtetc[i].tymed == pformatetc->tymed)
348  return S_OK;
349  }
350  }
351  return foundFormat?DV_E_FORMATETC:DV_E_TYMED;
352 }
353 
354 static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject* iface, FORMATETC *pformatectIn,
355  FORMATETC *pformatetcOut)
356 {
357  ok(0, "unexpected call\n");
358  return E_NOTIMPL;
359 }
360 
361 static HRESULT WINAPI DataObjectImpl_SetData(IDataObject* iface, FORMATETC *pformatetc,
362  STGMEDIUM *pmedium, BOOL fRelease)
363 {
364  ok(0, "unexpected call\n");
365  return E_NOTIMPL;
366 }
367 
369  IEnumFORMATETC **ppenumFormatEtc)
370 {
372 
374 
375  if(dwDirection != DATADIR_GET) {
376  ok(0, "unexpected direction %d\n", dwDirection);
377  return E_NOTIMPL;
378  }
379  return EnumFormatImpl_Create(This->fmtetc, This->fmtetc_cnt, ppenumFormatEtc);
380 }
381 
382 static HRESULT WINAPI DataObjectImpl_DAdvise(IDataObject* iface, FORMATETC *pformatetc, DWORD advf,
383  IAdviseSink *pAdvSink, DWORD *pdwConnection)
384 {
385  ok(0, "unexpected call\n");
386  return E_NOTIMPL;
387 }
388 
390 {
391  ok(0, "unexpected call\n");
392  return E_NOTIMPL;
393 }
394 
396 {
397  ok(0, "unexpected call\n");
398  return E_NOTIMPL;
399 }
400 
401 static const IDataObjectVtbl VT_DataObjectImpl =
402 {
415 };
416 
418 {
420 
421  obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
423  obj->ref = 1;
424  obj->text = text;
425  obj->stm = NULL;
426  obj->stg = NULL;
427  obj->hmfp = NULL;
428 
429  obj->fmtetc_cnt = 1;
430  obj->fmtetc = HeapAlloc(GetProcessHeap(), 0, obj->fmtetc_cnt*sizeof(FORMATETC));
431  InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
432 
433  *dataobj = &obj->IDataObject_iface;
434  return S_OK;
435 }
436 
438 {
440  strcpy(GlobalLock(h), text);
441  GlobalUnlock(h);
442  return DataObjectImpl_CreateFromHGlobal(h, lplpdataobj);
443 }
444 
445 static const char *cmpl_stm_data = "complex stream";
446 static const char *cmpl_text_data = "complex text";
447 static const WCHAR device_name[] = {'m','y','d','e','v',0};
448 
450 {
452  ILockBytes *lbs;
453  DEVMODEW dm;
454 
455  obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl));
457  obj->ref = 1;
460  GlobalUnlock(obj->text);
462  IStream_Write(obj->stm, cmpl_stm_data, strlen(cmpl_stm_data), NULL);
463 
466  ILockBytes_Release(lbs);
467 
468  obj->hmfp = create_metafilepict();
469 
470  obj->fmtetc_cnt = 9;
471  /* zeroing here since FORMATETC has a hole in it, and it's confusing to have this uninitialised. */
472  obj->fmtetc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, obj->fmtetc_cnt*sizeof(FORMATETC));
473  InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
474  InitFormatEtc(obj->fmtetc[1], cf_stream, TYMED_ISTREAM);
475  InitFormatEtc(obj->fmtetc[2], cf_storage, TYMED_ISTORAGE);
476  InitFormatEtc(obj->fmtetc[3], cf_another, TYMED_ISTORAGE|TYMED_ISTREAM|TYMED_HGLOBAL);
477  if (0) /* Causes crashes on both Wine and Windows */
478  {
479  memset(&dm, 0, sizeof(dm));
480  dm.dmSize = sizeof(dm);
481  dm.dmDriverExtra = 0;
483  obj->fmtetc[3].ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
484  obj->fmtetc[3].ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
485  obj->fmtetc[3].ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
486  obj->fmtetc[3].ptd->tdDeviceNameOffset = 0;
487  obj->fmtetc[3].ptd->tdPortNameOffset = 0;
488  obj->fmtetc[3].ptd->tdExtDevmodeOffset = obj->fmtetc[3].ptd->tdDriverNameOffset + sizeof(device_name);
489  lstrcpyW((WCHAR*)obj->fmtetc[3].ptd->tdData, device_name);
490  memcpy(obj->fmtetc[3].ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
491  }
492 
493  InitFormatEtc(obj->fmtetc[4], cf_global, TYMED_HGLOBAL);
494  InitFormatEtc(obj->fmtetc[5], cf_another, TYMED_HGLOBAL);
495  InitFormatEtc(obj->fmtetc[6], cf_another, 0xfffff);
496  InitFormatEtc(obj->fmtetc[7], cf_another, 0xfffff);
497  obj->fmtetc[7].dwAspect = DVASPECT_ICON;
498  InitFormatEtc(obj->fmtetc[8], CF_METAFILEPICT, TYMED_MFPICT);
499 
500  *lplpdataobj = &obj->IDataObject_iface;
501  return S_OK;
502 }
503 
505 {
506  HRESULT hr;
507  IDataObject *pDObj;
508 
509  pDObj = (IDataObject *)0xdeadbeef;
510  hr = OleGetClipboard(&pDObj);
511  todo_wine ok(hr == S_OK, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, S_OK);
512  if (pDObj && pDObj != (IDataObject *)0xdeadbeef) IDataObject_Release(pDObj);
513 }
514 
515 static void test_get_clipboard(void)
516 {
517  HRESULT hr;
518  IDataObject *data_obj;
519  FORMATETC fmtetc;
520  STGMEDIUM stgmedium;
521 
523  ok(hr == E_INVALIDARG, "OleGetClipboard(NULL) should return E_INVALIDARG instead of 0x%08x\n", hr);
524 
525  hr = OleGetClipboard(&data_obj);
526  ok(hr == S_OK, "OleGetClipboard failed with error 0x%08x\n", hr);
527 
528  /* test IDataObject_QueryGetData */
529 
530  /* clipboard's IDataObject_QueryGetData shouldn't defer to our IDataObject_QueryGetData */
532 
533  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
534  hr = IDataObject_QueryGetData(data_obj, &fmtetc);
535  ok(hr == S_OK, "IDataObject_QueryGetData failed with error 0x%08x\n", hr);
536 
537  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
538  fmtetc.dwAspect = 0xdeadbeef;
539  hr = IDataObject_QueryGetData(data_obj, &fmtetc);
540  ok(hr == DV_E_FORMATETC, "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
541 
542  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
543  fmtetc.dwAspect = DVASPECT_THUMBNAIL;
544  hr = IDataObject_QueryGetData(data_obj, &fmtetc);
545  ok(hr == DV_E_FORMATETC, "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
546 
547  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
548  fmtetc.lindex = 256;
549  hr = IDataObject_QueryGetData(data_obj, &fmtetc);
550  ok(hr == DV_E_FORMATETC || broken(hr == S_OK),
551  "IDataObject_QueryGetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
552 
553  InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL);
554  hr = IDataObject_QueryGetData(data_obj, &fmtetc);
555  ok(hr == DV_E_CLIPFORMAT, "IDataObject_QueryGetData should have failed with DV_E_CLIPFORMAT instead of 0x%08x\n", hr);
556 
557  InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE);
558  hr = IDataObject_QueryGetData(data_obj, &fmtetc);
559  ok(hr == S_OK, "IDataObject_QueryGetData failed with error 0x%08x\n", hr);
560 
562 
563  /* test IDataObject_GetData */
564 
566 
567  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
568  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
569  ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
570  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
571 
572  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
573  fmtetc.dwAspect = 0xdeadbeef;
574  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
575  ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
576  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
577 
578  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
579  fmtetc.dwAspect = DVASPECT_THUMBNAIL;
580  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
581  ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
582  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
583 
584  InitFormatEtc(fmtetc, CF_TEXT, TYMED_HGLOBAL);
585  fmtetc.lindex = 256;
586  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
587  ok(hr == DV_E_FORMATETC || broken(hr == S_OK), "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
588  if (hr == S_OK)
589  {
590  /* undo the unexpected success */
592  ReleaseStgMedium(&stgmedium);
593  }
594 
595  InitFormatEtc(fmtetc, CF_RIFF, TYMED_HGLOBAL);
596  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
597  ok(hr == DV_E_FORMATETC, "IDataObject_GetData should have failed with DV_E_FORMATETC instead of 0x%08x\n", hr);
598  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
599 
600  InitFormatEtc(fmtetc, CF_TEXT, TYMED_FILE);
601  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
602  ok(hr == DV_E_TYMED, "IDataObject_GetData should have failed with DV_E_TYMED instead of 0x%08x\n", hr);
603  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
604 
605  ok(DataObjectImpl_GetData_calls == 6, "DataObjectImpl_GetData should have been called 6 times instead of %d times\n", DataObjectImpl_GetData_calls);
606 
607  IDataObject_Release(data_obj);
608 }
609 
611 {
612  HRESULT hr;
613  IDataObject *data;
614  IEnumFORMATETC *enum_fmt, *src_enum;
615  FORMATETC fmt, src_fmt;
616  DWORD count = 0;
617 
618  hr = OleGetClipboard(&data);
619  ok(hr == S_OK, "OleGetClipboard failed with error 0x%08x\n", hr);
620 
621  hr = IDataObject_EnumFormatEtc(data, DATADIR_SET, &enum_fmt);
622  ok(hr == E_NOTIMPL ||
623  broken(hr == E_INVALIDARG), /* win98 (not win98SE) */
624  "got %08x\n", hr);
625 
627  hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
628  ok(hr == S_OK, "got %08x\n", hr);
629  ok(DataObjectImpl_EnumFormatEtc_calls == 0, "EnumFormatEtc was called\n");
630  if (FAILED(hr))
631  {
632  skip("EnumFormatEtc failed, skipping tests.\n");
633  return;
634  }
635 
636  if(src) IDataObject_EnumFormatEtc(src, DATADIR_GET, &src_enum);
637 
638  while((hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL)) == S_OK)
639  {
640  ok(src != NULL, "shouldn't be here\n");
641  hr = IEnumFORMATETC_Next(src_enum, 1, &src_fmt, NULL);
642  ok(hr == S_OK, "%d: got %08x\n", count, hr);
643  trace("%d: %s\n", count, dump_fmtetc(&fmt));
644  ok(fmt.cfFormat == src_fmt.cfFormat, "%d: %04x %04x\n", count, fmt.cfFormat, src_fmt.cfFormat);
645  ok(fmt.dwAspect == src_fmt.dwAspect, "%d: %08x %08x\n", count, fmt.dwAspect, src_fmt.dwAspect);
646  ok(fmt.lindex == src_fmt.lindex, "%d: %08x %08x\n", count, fmt.lindex, src_fmt.lindex);
647  ok(fmt.tymed == src_fmt.tymed, "%d: %08x %08x\n", count, fmt.tymed, src_fmt.tymed);
648  if(fmt.ptd)
649  {
650  ok(src_fmt.ptd != NULL, "%d: expected non-NULL\n", count);
651  CoTaskMemFree(fmt.ptd);
652  CoTaskMemFree(src_fmt.ptd);
653  }
654  count++;
655  }
656 
657  ok(hr == S_FALSE, "%d: got %08x\n", count, hr);
658 
659  if(src)
660  {
661  hr = IEnumFORMATETC_Next(src_enum, 1, &src_fmt, NULL);
662  ok(hr == S_FALSE, "%d: got %08x\n", count, hr);
663  IEnumFORMATETC_Release(src_enum);
664  }
665 
666  hr = IEnumFORMATETC_Reset(enum_fmt);
667  ok(hr == S_OK, "got %08x\n", hr);
668 
669  if(src) /* Exercise the enumerator a bit */
670  {
671  IEnumFORMATETC *clone;
672  FORMATETC third_fmt;
673 
674  hr = IEnumFORMATETC_Next(enum_fmt, 1, &third_fmt, NULL);
675  ok(hr == S_OK, "got %08x\n", hr);
676  hr = IEnumFORMATETC_Next(enum_fmt, 1, &third_fmt, NULL);
677  ok(hr == S_OK, "got %08x\n", hr);
678  hr = IEnumFORMATETC_Next(enum_fmt, 1, &third_fmt, NULL);
679  ok(hr == S_OK, "got %08x\n", hr);
680 
681  hr = IEnumFORMATETC_Reset(enum_fmt);
682  ok(hr == S_OK, "got %08x\n", hr);
683  hr = IEnumFORMATETC_Skip(enum_fmt, 2);
684  ok(hr == S_OK, "got %08x\n", hr);
685 
686  hr = IEnumFORMATETC_Clone(enum_fmt, &clone);
687  ok(hr == S_OK, "got %08x\n", hr);
688  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
689  ok(hr == S_OK, "got %08x\n", hr);
690  ok(fmt.cfFormat == third_fmt.cfFormat, "formats don't match\n");
691  hr = IEnumFORMATETC_Next(clone, 1, &fmt, NULL);
692  ok(hr == S_OK, "got %08x\n", hr);
693  ok(fmt.cfFormat == third_fmt.cfFormat, "formats don't match\n");
694  IEnumFORMATETC_Release(clone);
695  }
696 
697  IEnumFORMATETC_Release(enum_fmt);
698  IDataObject_Release(data);
699 }
700 
701 static void test_no_cf_dataobject(void)
702 {
703  UINT cf_dataobject = RegisterClipboardFormatA("DataObject");
704  UINT cf_ole_priv_data = RegisterClipboardFormatA("Ole Private Data");
705  HANDLE h;
707 
708  h = GetClipboardData(cf_dataobject);
709  ok(!h, "got %p\n", h);
710  h = GetClipboardData(cf_ole_priv_data);
711  ok(!h, "got %p\n", h);
712 
713  CloseClipboard();
714 }
715 
717 {
718  UINT cf = 0;
719  UINT cf_dataobject = RegisterClipboardFormatA("DataObject");
720  UINT cf_ole_priv_data = RegisterClipboardFormatA("Ole Private Data");
721  BOOL found_dataobject = FALSE, found_priv_data = FALSE;
722 
724  do
725  {
727  if(cf == cf_dataobject)
728  {
730  HWND *ptr = GlobalLock(h);
731  DWORD size = GlobalSize(h);
732  HWND clip_owner = GetClipboardOwner();
733 
734  found_dataobject = TRUE;
735  ok(size >= sizeof(*ptr), "size %d\n", size);
736  if(data)
737  ok(*ptr == clip_owner, "hwnd %p clip_owner %p\n", *ptr, clip_owner);
738  else /* ole clipboard flushed */
739  ok(*ptr == NULL, "hwnd %p\n", *ptr);
740  GlobalUnlock(h);
741  }
742  else if(cf == cf_ole_priv_data)
743  {
744  found_priv_data = TRUE;
745  if(data)
746  {
748  DWORD *ptr = GlobalLock(h);
749  DWORD size = GlobalSize(h);
750 
751  if(size != ptr[1])
752  win_skip("Ole Private Data in win9x format\n");
753  else
754  {
755  HRESULT hr;
756  IEnumFORMATETC *enum_fmt;
757  DWORD count = 0;
758  FORMATETC fmt;
759  struct formatetcetc
760  {
761  FORMATETC fmt;
762  BOOL first_use_of_cf;
763  DWORD res[2];
764  } *fmt_ptr;
765  struct priv_data
766  {
767  DWORD res1;
768  DWORD size;
769  DWORD res2;
770  DWORD count;
771  DWORD res3[2];
772  struct formatetcetc fmts[1];
773  } *priv = (struct priv_data*)ptr;
774  CLIPFORMAT cfs_seen[10];
775 
776  hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt);
777  ok(hr == S_OK, "got %08x\n", hr);
778  fmt_ptr = priv->fmts;
779 
780  while(IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL) == S_OK)
781  {
782  int i;
783  BOOL seen_cf = FALSE;
784 
785  ok(fmt_ptr->fmt.cfFormat == fmt.cfFormat,
786  "got %08x expected %08x\n", fmt_ptr->fmt.cfFormat, fmt.cfFormat);
787  ok(fmt_ptr->fmt.dwAspect == fmt.dwAspect, "got %08x expected %08x\n",
788  fmt_ptr->fmt.dwAspect, fmt.dwAspect);
789  ok(fmt_ptr->fmt.lindex == fmt.lindex, "got %08x expected %08x\n",
790  fmt_ptr->fmt.lindex, fmt.lindex);
791  ok(fmt_ptr->fmt.tymed == fmt.tymed, "got %08x expected %08x\n",
792  fmt_ptr->fmt.tymed, fmt.tymed);
793  for(i = 0; i < count; i++)
794  if(fmt_ptr->fmt.cfFormat == cfs_seen[i])
795  {
796  seen_cf = TRUE;
797  break;
798  }
799  cfs_seen[count] = fmt.cfFormat;
800  ok(fmt_ptr->first_use_of_cf != seen_cf, "got %08x expected %08x\n",
801  fmt_ptr->first_use_of_cf, !seen_cf);
802  ok(fmt_ptr->res[0] == 0, "got %08x\n", fmt_ptr->res[0]);
803  ok(fmt_ptr->res[1] == 0, "got %08x\n", fmt_ptr->res[1]);
804  if(fmt.ptd)
805  {
806  DVTARGETDEVICE *target;
807 
808  ok(fmt_ptr->fmt.ptd != NULL, "target device offset zero\n");
809  target = (DVTARGETDEVICE*)((char*)priv + (DWORD_PTR)fmt_ptr->fmt.ptd);
810  ok(!memcmp(target, fmt.ptd, fmt.ptd->tdSize), "target devices differ\n");
811  CoTaskMemFree(fmt.ptd);
812  }
813  fmt_ptr++;
814  count++;
815  }
816  ok(priv->res1 == 0, "got %08x\n", priv->res1);
817  ok(priv->res2 == 1, "got %08x\n", priv->res2);
818  ok(priv->count == count, "got %08x expected %08x\n", priv->count, count);
819  ok(priv->res3[0] == 0, "got %08x\n", priv->res3[0]);
820 
821  /* win64 sets the lsb */
822  if(sizeof(fmt_ptr->fmt.ptd) == 8)
823  todo_wine ok(priv->res3[1] == 1, "got %08x\n", priv->res3[1]);
824  else
825  ok(priv->res3[1] == 0, "got %08x\n", priv->res3[1]);
826 
827  GlobalUnlock(h);
828  IEnumFORMATETC_Release(enum_fmt);
829  }
830  }
831  }
832  else if(cf == cf_stream)
833  {
834  HGLOBAL h;
835  void *ptr;
836  DWORD size;
837 
839  h = GetClipboardData(cf);
841  ptr = GlobalLock(h);
842  size = GlobalSize(h);
844  "expected %d got %d\n", lstrlenA(cmpl_stm_data), size);
845  ok(!memcmp(ptr, cmpl_stm_data, strlen(cmpl_stm_data)), "mismatch\n");
846  GlobalUnlock(h);
847  }
848  else if(cf == cf_global)
849  {
850  HGLOBAL h;
851  void *ptr;
852  DWORD size;
853 
855  h = GetClipboardData(cf);
857  ptr = GlobalLock(h);
858  size = GlobalSize(h);
859  ok(size == strlen(cmpl_text_data) + 1,
860  "expected %d got %d\n", lstrlenA(cmpl_text_data) + 1, size);
861  ok(!memcmp(ptr, cmpl_text_data, strlen(cmpl_text_data) + 1), "mismatch\n");
862  GlobalUnlock(h);
863  }
864  } while(cf);
865  CloseClipboard();
866  ok(found_dataobject, "didn't find cf_dataobject\n");
867  ok(found_priv_data, "didn't find cf_ole_priv_data\n");
868 }
869 
870 static void test_complex_get_clipboard(void)
871 {
872  HRESULT hr;
873  IDataObject *data_obj;
874  FORMATETC fmtetc;
875  STGMEDIUM stgmedium;
876 
877  hr = OleGetClipboard(&data_obj);
878  ok(hr == S_OK, "OleGetClipboard failed with error 0x%08x\n", hr);
879 
881 
882  InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_MFPICT);
883  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
884  ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
885  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
886 
887  InitFormatEtc(fmtetc, CF_METAFILEPICT, TYMED_HGLOBAL);
888  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
889  ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr);
890  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
891 
892  InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_HGLOBAL);
893  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
894  ok(hr == DV_E_TYMED, "IDataObject_GetData failed with error 0x%08x\n", hr);
895  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
896 
897  InitFormatEtc(fmtetc, CF_ENHMETAFILE, TYMED_ENHMF);
898  hr = IDataObject_GetData(data_obj, &fmtetc, &stgmedium);
899  ok(hr == S_OK, "IDataObject_GetData failed with error 0x%08x\n", hr);
900  if(SUCCEEDED(hr)) ReleaseStgMedium(&stgmedium);
901 
903  "DataObjectImpl_GetData called 5 times instead of %d times\n",
905  IDataObject_Release(data_obj);
906 }
907 
908 static void test_set_clipboard(void)
909 {
910  HRESULT hr;
911  ULONG ref;
912  LPDATAOBJECT data1, data2, data_cmpl;
913  HGLOBAL hblob, h;
914  void *ptr;
915 
916  cf_stream = RegisterClipboardFormatA("stream format");
917  cf_storage = RegisterClipboardFormatA("storage format");
918  cf_global = RegisterClipboardFormatA("global format");
919  cf_another = RegisterClipboardFormatA("another format");
920  cf_onemore = RegisterClipboardFormatA("one more format");
921 
922  hr = DataObjectImpl_CreateText("data1", &data1);
923  ok(hr == S_OK, "Failed to create data1 object: 0x%08x\n", hr);
924  if(FAILED(hr))
925  return;
926  hr = DataObjectImpl_CreateText("data2", &data2);
927  ok(hr == S_OK, "Failed to create data2 object: 0x%08x\n", hr);
928  if(FAILED(hr))
929  return;
930  hr = DataObjectImpl_CreateComplex(&data_cmpl);
931  ok(hr == S_OK, "Failed to create complex data object: 0x%08x\n", hr);
932  if(FAILED(hr))
933  return;
934 
936  ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard should have failed with CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
937 
940  ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard failed with 0x%08x\n", hr);
941  CoUninitialize();
942 
943  hr = OleInitialize(NULL);
944  ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
945 
947  ok(hr == S_OK, "failed to set clipboard to data1, hr = 0x%08x\n", hr);
948 
950 
952  ok(hr == S_OK, "expected current clipboard to be data1, hr = 0x%08x\n", hr);
954  ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08x\n", hr);
956  ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr);
957 
959 
961  ok(hr == S_OK, "failed to set clipboard to data2, hr = 0x%08x\n", hr);
963  ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08x\n", hr);
965  ok(hr == S_OK, "expected current clipboard to be data2, hr = 0x%08x\n", hr);
967  ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr);
968 
969  /* put a format directly onto the clipboard to show
970  OleFlushClipboard doesn't empty the clipboard */
972  ptr = GlobalLock( hblob );
973  ok( ptr && ptr != hblob, "got fixed block %p / %p\n", ptr, hblob );
974  GlobalUnlock( hblob );
975  ok( OpenClipboard(NULL), "OpenClipboard failed\n" );
976  h = SetClipboardData(cf_onemore, hblob);
977  ok(h == hblob, "got %p\n", h);
979  ok(h == hblob, "got %p / %p\n", h, hblob);
980  ptr = GlobalLock( h );
981  ok( ptr && ptr != h, "got fixed block %p / %p\n", ptr, h );
982  GlobalUnlock( hblob );
983  ok( CloseClipboard(), "CloseClipboard failed\n" );
984 
985  hr = OleFlushClipboard();
986  ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
988  ok(hr == S_FALSE, "did not expect current clipboard to be data1, hr = 0x%08x\n", hr);
990  ok(hr == S_FALSE, "did not expect current clipboard to be data2, hr = 0x%08x\n", hr);
992  ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr);
993 
994  /* format should survive the flush */
995  ok( OpenClipboard(NULL), "OpenClipboard failed\n" );
997  ok(h == hblob, "got %p\n", h);
998  ptr = GlobalLock( h );
999  ok( ptr && ptr != h, "got fixed block %p / %p\n", ptr, h );
1000  GlobalUnlock( hblob );
1001  ok( CloseClipboard(), "CloseClipboard failed\n" );
1002 
1004 
1005  ok(OleSetClipboard(NULL) == S_OK, "failed to clear clipboard, hr = 0x%08x\n", hr);
1006 
1009  ok(h == NULL, "got %p\n", h);
1010  CloseClipboard();
1011 
1012  trace("setting complex\n");
1013  hr = OleSetClipboard(data_cmpl);
1014  ok(hr == S_OK, "failed to set clipboard to complex data, hr = 0x%08x\n", hr);
1016  test_cf_dataobject(data_cmpl);
1017  test_enum_fmtetc(data_cmpl);
1018 
1019  ok(OleSetClipboard(NULL) == S_OK, "failed to clear clipboard, hr = 0x%08x\n", hr);
1020 
1023 
1024  ref = IDataObject_Release(data1);
1025  ok(ref == 0, "expected data1 ref=0, got %d\n", ref);
1026  ref = IDataObject_Release(data2);
1027  ok(ref == 0, "expected data2 ref=0, got %d\n", ref);
1028  ref = IDataObject_Release(data_cmpl);
1029  ok(ref == 0, "expected data_cmpl ref=0, got %d\n", ref);
1030 
1031  OleUninitialize();
1032 }
1033 
1037 
1039 {
1040  LRESULT ret;
1041 
1042  switch (msg)
1043  {
1044  case WM_DRAWCLIPBOARD:
1045  wm_drawclipboard++;
1046  if (clip_data)
1047  {
1048  /* if this is the WM_DRAWCLIPBOARD of a previous change, the data isn't current yet */
1049  /* this demonstrates an issue in Qt where it will free the data while it's being set */
1051  ok( hr == (wm_drawclipboard > 1) ? S_OK : S_FALSE,
1052  "OleIsCurrentClipboard returned %x\n", hr );
1053  }
1054  break;
1055  case WM_CHANGECBCHAIN:
1056  if (next_wnd == (HWND)wp) next_wnd = (HWND)lp;
1057  else if (next_wnd) SendMessageA( next_wnd, msg, wp, lp );
1058  break;
1059  case WM_USER:
1061  wm_drawclipboard = 0;
1062  return ret;
1063  }
1064 
1065  return DefWindowProcA(hwnd, msg, wp, lp);
1066 }
1067 
1069 {
1071  EmptyClipboard();
1072  SetClipboardData( CF_WAVE, 0 );
1073  CloseClipboard();
1074  return 0;
1075 }
1076 
1077 /* test that WM_DRAWCLIPBOARD can be delivered for a previous change during OleSetClipboard */
1079 {
1081  HRESULT hr;
1082  WNDCLASSA cls;
1083  HWND viewer;
1084  int ret;
1085  HANDLE thread;
1086 
1087  hr = DataObjectImpl_CreateText("data", &data);
1088  ok(hr == S_OK, "Failed to create data object: 0x%08x\n", hr);
1089 
1090  memset(&cls, 0, sizeof(cls));
1093  cls.lpszClassName = "clipboard_test";
1094  RegisterClassA(&cls);
1095 
1096  viewer = CreateWindowA("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0);
1097  ok(viewer != NULL, "CreateWindow failed: %d\n", GetLastError());
1098  next_wnd = SetClipboardViewer( viewer );
1099 
1100  ret = SendMessageA( viewer, WM_USER, 0, 0 );
1101  ok( ret == 1, "%u WM_DRAWCLIPBOARD received\n", ret );
1102 
1103  hr = OleInitialize(NULL);
1104  ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
1105 
1106  ret = SendMessageA( viewer, WM_USER, 0, 0 );
1107  ok( !ret, "%u WM_DRAWCLIPBOARD received\n", ret );
1108 
1110  ok(thread != NULL, "CreateThread failed (%d)\n", GetLastError());
1111  ret = WaitForSingleObject(thread, 5000);
1112  ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
1113 
1114  clip_data = data;
1115  hr = OleSetClipboard(data);
1116  ok(hr == S_OK, "failed to set clipboard to data, hr = 0x%08x\n", hr);
1117 
1118  ret = SendMessageA( viewer, WM_USER, 0, 0 );
1119  ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
1120 
1121  clip_data = NULL;
1122  hr = OleFlushClipboard();
1123  ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
1124  ret = IDataObject_Release(data);
1125  ok(ret == 0, "got %d\n", ret);
1126 
1127  OleUninitialize();
1128  ChangeClipboardChain( viewer, next_wnd );
1129  DestroyWindow( viewer );
1130 }
1131 
1133 {
1134  IDataObject_AddRef(d);
1135  return IDataObject_Release(d);
1136 }
1137 
1138 static void test_consumer_refs(void)
1139 {
1140  HRESULT hr;
1141  IDataObject *src, *src2, *get1, *get2, *get3;
1142  ULONG refs, old_refs;
1143  FORMATETC fmt;
1144  STGMEDIUM med;
1145 
1146  InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
1147 
1149 
1150  /* First show that each clipboard state results in
1151  a different data object */
1152 
1153  hr = DataObjectImpl_CreateText("data1", &src);
1154  ok(hr == S_OK, "got %08x\n", hr);
1155  hr = DataObjectImpl_CreateText("data2", &src2);
1156  ok(hr == S_OK, "got %08x\n", hr);
1157 
1158  hr = OleSetClipboard(src);
1159  ok(hr == S_OK, "got %08x\n", hr);
1160 
1161  hr = OleGetClipboard(&get1);
1162  ok(hr == S_OK, "got %08x\n", hr);
1163 
1164  hr = OleGetClipboard(&get2);
1165  ok(hr == S_OK, "got %08x\n", hr);
1166 
1167  ok(get1 == get2, "data objects differ\n");
1168  refs = IDataObject_Release(get2);
1169  ok(refs == (get1 == get2 ? 1 : 0), "got %d\n", refs);
1170 
1172 
1174  hr = IDataObject_GetData(get1, &fmt, &med);
1175  ok(hr == S_OK, "got %08x\n", hr);
1176  ok(DataObjectImpl_GetData_calls == 0, "GetData called\n");
1177  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1178 
1179  hr = OleGetClipboard(&get2);
1180  ok(hr == S_OK, "got %08x\n", hr);
1181 
1182  ok(get1 != get2, "data objects match\n");
1183 
1185 
1186  hr = OleGetClipboard(&get3);
1187  ok(hr == S_OK, "got %08x\n", hr);
1188 
1189  ok(get1 != get3, "data objects match\n");
1190  ok(get2 != get3, "data objects match\n");
1191 
1192  IDataObject_Release(get3);
1193  IDataObject_Release(get2);
1194  IDataObject_Release(get1);
1195 
1196  /* Now call GetData before the flush and show that this
1197  takes a ref on our src data obj. */
1198 
1199  hr = OleSetClipboard(src);
1200  ok(hr == S_OK, "got %08x\n", hr);
1201 
1202  old_refs = count_refs(src);
1203 
1204  hr = OleGetClipboard(&get1);
1205  ok(hr == S_OK, "got %08x\n", hr);
1206 
1207  refs = count_refs(src);
1208  ok(refs == old_refs, "%d %d\n", refs, old_refs);
1209 
1211  hr = IDataObject_GetData(get1, &fmt, &med);
1212  ok(hr == S_OK, "got %08x\n", hr);
1213  ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
1214  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1215  refs = count_refs(src);
1216  ok(refs == old_refs + 1, "%d %d\n", refs, old_refs);
1217 
1219 
1221  hr = IDataObject_GetData(get1, &fmt, &med);
1222  ok(hr == S_OK, "got %08x\n", hr);
1223  ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
1224  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1225 
1226  refs = count_refs(src);
1227  ok(refs == 2, "%d\n", refs);
1228 
1229  IDataObject_Release(get1);
1230 
1231  refs = count_refs(src);
1232  ok(refs == 1, "%d\n", refs);
1233 
1234  /* Now set a second src object before the call to GetData
1235  and show that GetData calls that second src. */
1236 
1237  hr = OleSetClipboard(src);
1238  ok(hr == S_OK, "got %08x\n", hr);
1239 
1240  old_refs = count_refs(src);
1241 
1242  hr = OleGetClipboard(&get1);
1243  ok(hr == S_OK, "got %08x\n", hr);
1244 
1245  refs = count_refs(src);
1246  ok(refs == old_refs, "%d %d\n", refs, old_refs);
1247 
1248  hr = OleSetClipboard(src2);
1249  ok(hr == S_OK, "got %08x\n", hr);
1250 
1251  old_refs = count_refs(src2);
1252 
1254  hr = IDataObject_GetData(get1, &fmt, &med);
1255  ok(hr == S_OK, "got %08x\n", hr);
1256  ok(DataObjectImpl_GetData_calls == 1, "GetData not called\n");
1257  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1258 
1259  refs = count_refs(src);
1260  ok(refs == 1, "%d\n", refs);
1261  refs = count_refs(src2);
1262  ok(refs == old_refs + 1, "%d %d\n", refs, old_refs);
1263 
1265 
1266  refs = count_refs(src2);
1267  ok(refs == 2, "%d\n", refs);
1268 
1269  IDataObject_Release(get1);
1270 
1271  IDataObject_Release(src2);
1272 
1273  /* Show that OleUninitialize() doesn't release the
1274  dataobject's ref, and thus the object is leaked. */
1275  old_refs = count_refs(src);
1276  ok(old_refs == 1, "%d\n", old_refs);
1277 
1279  refs = count_refs(src);
1280  ok(refs > old_refs, "%d %d\n", refs, old_refs);
1281 
1282  OleUninitialize();
1283  refs = count_refs(src);
1284  ok(refs == 2, "%d\n", refs);
1285 
1286  IDataObject_Release(src);
1287 }
1288 
1290 {
1291  ILockBytes *ilb;
1292  IStorage *stg;
1293  HGLOBAL hg;
1294  HRESULT hr;
1295 
1297  ok(hr == S_OK, "got %08x\n", hr);
1299  ok(hr == S_OK, "got %08x\n", hr);
1300  IStorage_Release(stg);
1301  hr = GetHGlobalFromILockBytes(ilb, &hg);
1302  ok(hr == S_OK, "got %08x\n", hr);
1303  ILockBytes_Release(ilb);
1304  return hg;
1305 }
1306 
1307 static void test_flushed_getdata(void)
1308 {
1309  HRESULT hr;
1310  IDataObject *src, *get;
1311  FORMATETC fmt;
1312  STGMEDIUM med;
1313  STATSTG stat;
1314  DEVMODEW dm;
1315 
1317 
1319  ok(hr == S_OK, "got %08x\n", hr);
1320 
1321  hr = OleSetClipboard(src);
1322  ok(hr == S_OK, "got %08x\n", hr);
1323 
1324  hr = OleFlushClipboard();
1325  ok(hr == S_OK, "got %08x\n", hr);
1326 
1327  hr = OleGetClipboard(&get);
1328  ok(hr == S_OK, "got %08x\n", hr);
1329 
1330  /* global format -> global & stream */
1331 
1332  InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
1333  hr = IDataObject_GetData(get, &fmt, &med);
1334  ok(hr == S_OK, "got %08x\n", hr);
1335  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1336  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1337 
1338  InitFormatEtc(fmt, CF_TEXT, TYMED_ISTREAM);
1339  hr = IDataObject_GetData(get, &fmt, &med);
1340  ok(hr == S_OK, "got %08x\n", hr);
1341  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1342  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1343 
1344  InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
1345  hr = IDataObject_GetData(get, &fmt, &med);
1346  ok(hr == E_FAIL, "got %08x\n", hr);
1347  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1348 
1349  InitFormatEtc(fmt, CF_TEXT, 0xffff);
1350  hr = IDataObject_GetData(get, &fmt, &med);
1351  ok(hr == S_OK, "got %08x\n", hr);
1352  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1353  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1354 
1355  /* stream format -> global & stream */
1356 
1357  InitFormatEtc(fmt, cf_stream, TYMED_ISTREAM);
1358  hr = IDataObject_GetData(get, &fmt, &med);
1359  ok(hr == S_OK, "got %08x\n", hr);
1360  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1361  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1362 
1363  InitFormatEtc(fmt, cf_stream, TYMED_ISTORAGE);
1364  hr = IDataObject_GetData(get, &fmt, &med);
1365  ok(hr == E_FAIL, "got %08x\n", hr);
1366  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1367 
1368  InitFormatEtc(fmt, cf_stream, TYMED_HGLOBAL);
1369  hr = IDataObject_GetData(get, &fmt, &med);
1370  ok(hr == S_OK, "got %08x\n", hr);
1371  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1372  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1373 
1374  InitFormatEtc(fmt, cf_stream, 0xffff);
1375  hr = IDataObject_GetData(get, &fmt, &med);
1376  ok(hr == S_OK, "got %08x\n", hr);
1377  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1378  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1379 
1380  /* storage format -> global, stream & storage */
1381 
1382  InitFormatEtc(fmt, cf_storage, TYMED_ISTORAGE);
1383  hr = IDataObject_GetData(get, &fmt, &med);
1384  ok(hr == S_OK, "got %08x\n", hr);
1385  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1386  if(SUCCEEDED(hr)) {
1387  hr = IStorage_Stat(med.pstg, &stat, STATFLAG_NONAME);
1388  ok(hr == S_OK, "got %08x\n", hr);
1389  ok(stat.grfMode == (STGM_SHARE_EXCLUSIVE | STGM_READWRITE), "got %08x\n", stat.grfMode);
1390  ReleaseStgMedium(&med);
1391  }
1392 
1393  InitFormatEtc(fmt, cf_storage, TYMED_ISTREAM);
1394  hr = IDataObject_GetData(get, &fmt, &med);
1395  ok(hr == S_OK, "got %08x\n", hr);
1396  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1397  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1398 
1399  InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL);
1400  hr = IDataObject_GetData(get, &fmt, &med);
1401  ok(hr == S_OK, "got %08x\n", hr);
1402  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1403  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1404 
1405  InitFormatEtc(fmt, cf_storage, TYMED_HGLOBAL | TYMED_ISTREAM);
1406  hr = IDataObject_GetData(get, &fmt, &med);
1407  ok(hr == S_OK, "got %08x\n", hr);
1408  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1409  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1410 
1411  InitFormatEtc(fmt, cf_storage, 0xffff);
1412  hr = IDataObject_GetData(get, &fmt, &med);
1413  ok(hr == S_OK, "got %08x\n", hr);
1414  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1415  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1416 
1417  /* complex format with target device */
1418 
1419  InitFormatEtc(fmt, cf_another, 0xffff);
1420  hr = IDataObject_GetData(get, &fmt, &med);
1421  ok(hr == S_OK, "got %08x\n", hr);
1422  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1423 
1424  if (0) /* Causes crashes on both Wine and Windows */
1425  {
1426  InitFormatEtc(fmt, cf_another, 0xffff);
1427  memset(&dm, 0, sizeof(dm));
1428  dm.dmSize = sizeof(dm);
1429  dm.dmDriverExtra = 0;
1431  fmt.ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra);
1432  fmt.ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra;
1433  fmt.ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData);
1434  fmt.ptd->tdDeviceNameOffset = 0;
1435  fmt.ptd->tdPortNameOffset = 0;
1436  fmt.ptd->tdExtDevmodeOffset = fmt.ptd->tdDriverNameOffset + sizeof(device_name);
1437  lstrcpyW((WCHAR*)fmt.ptd->tdData, device_name);
1438  memcpy(fmt.ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra);
1439 
1440  hr = IDataObject_GetData(get, &fmt, &med);
1441  ok(hr == S_OK, "got %08x\n", hr);
1442  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1443  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1444 
1445  HeapFree(GetProcessHeap(), 0, fmt.ptd);
1446  }
1447 
1448  /* CF_ENHMETAFILE format */
1449  InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF);
1450  hr = IDataObject_GetData(get, &fmt, &med);
1451  ok(hr == S_OK, "got %08x\n", hr);
1452  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1453 
1454  IDataObject_Release(get);
1455  IDataObject_Release(src);
1456 
1458  ok(hr == S_OK, "got %08x\n", hr);
1459 
1460  hr = OleSetClipboard(src);
1461  ok(hr == S_OK, "got %08x\n", hr);
1462 
1463  hr = OleGetClipboard(&get);
1464  ok(hr == S_OK, "got %08x\n", hr);
1465  InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
1466  hr = IDataObject_GetData(get, &fmt, &med);
1467  ok(hr == S_OK, "got %08x\n", hr);
1468  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1469  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1470  IDataObject_Release(get);
1471 
1472  hr = OleFlushClipboard();
1473  ok(hr == S_OK, "got %08x\n", hr);
1474 
1475  hr = OleGetClipboard(&get);
1476  ok(hr == S_OK, "got %08x\n", hr);
1477 
1478  InitFormatEtc(fmt, CF_TEXT, TYMED_ISTORAGE);
1479  hr = IDataObject_GetData(get, &fmt, &med);
1480  ok(hr == S_OK, "got %08x\n", hr);
1481  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1482  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1483 
1484  InitFormatEtc(fmt, CF_TEXT, 0xffff);
1485  hr = IDataObject_GetData(get, &fmt, &med);
1486  ok(hr == S_OK, "got %08x\n", hr);
1487  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1488  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1489 
1490  IDataObject_Release(get);
1491  IDataObject_Release(src);
1492 
1493  OleUninitialize();
1494 }
1495 
1496 static HGLOBAL create_text(void)
1497 {
1499  char *p = GlobalLock(h);
1500  strcpy(p, "test");
1501  GlobalUnlock(h);
1502  return h;
1503 }
1504 
1505 static HENHMETAFILE create_emf(void)
1506 {
1507  const RECT rect = {0, 0, 100, 100};
1508  HDC hdc = CreateEnhMetaFileA(NULL, NULL, &rect, "HENHMETAFILE Ole Clipboard Test\0Test\0\0");
1509  ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rect, "Test String", strlen("Test String"), NULL);
1510  return CloseEnhMetaFile(hdc);
1511 }
1512 
1513 static void test_nonole_clipboard(void)
1514 {
1515  HRESULT hr;
1516  BOOL r;
1517  IDataObject *get;
1518  IEnumFORMATETC *enum_fmt;
1519  FORMATETC fmt;
1520  HGLOBAL h, hblob, htext, hstorage;
1521  HENHMETAFILE emf;
1522  STGMEDIUM med;
1523  DWORD obj_type;
1524 
1525  r = OpenClipboard(NULL);
1526  ok(r, "gle %d\n", GetLastError());
1527  r = EmptyClipboard();
1528  ok(r, "gle %d\n", GetLastError());
1529  r = CloseClipboard();
1530  ok(r, "gle %d\n", GetLastError());
1531 
1533 
1534  /* empty clipboard */
1535  hr = OleGetClipboard(&get);
1536  ok(hr == S_OK, "got %08x\n", hr);
1537  hr = IDataObject_EnumFormatEtc(get, DATADIR_GET, &enum_fmt);
1538  ok(hr == S_OK, "got %08x\n", hr);
1539 
1540  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1541  ok(hr == S_FALSE, "got %08x\n", hr);
1542  IEnumFORMATETC_Release(enum_fmt);
1543 
1544  IDataObject_Release(get);
1545 
1546  /* set a user defined clipboard type */
1547 
1548  htext = create_text();
1550  emf = create_emf();
1551  hstorage = create_storage();
1552 
1553  r = OpenClipboard(NULL);
1554  ok(r, "gle %d\n", GetLastError());
1555  h = SetClipboardData(CF_TEXT, htext);
1556  ok(h == htext, "got %p\n", h);
1557  h = SetClipboardData(cf_onemore, hblob);
1558  ok(h == hblob, "got %p\n", h);
1560  ok(h == emf, "got %p\n", h);
1561  h = SetClipboardData(cf_storage, hstorage);
1562  ok(h == hstorage, "got %p\n", h);
1563  r = CloseClipboard();
1564  ok(r, "gle %d\n", GetLastError());
1565 
1566  hr = OleGetClipboard(&get);
1567  ok(hr == S_OK, "got %08x\n", hr);
1568  hr = IDataObject_EnumFormatEtc(get, DATADIR_GET, &enum_fmt);
1569  ok(hr == S_OK, "got %08x\n", hr);
1570  if (FAILED(hr))
1571  {
1572  skip("EnumFormatEtc failed, skipping tests.\n");
1573  return;
1574  }
1575 
1576  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1577  ok(hr == S_OK, "got %08x\n", hr);
1578  ok(fmt.cfFormat == CF_TEXT, "cf %04x\n", fmt.cfFormat);
1579  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1580  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1581  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1582  ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
1583 
1584  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1585  ok(hr == S_OK, "got %08x\n", hr);
1586  ok(fmt.cfFormat == cf_onemore, "cf %04x\n", fmt.cfFormat);
1587  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1588  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1589  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1590  ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
1591 
1592  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1593  ok(hr == S_OK, "got %08x\n", hr);
1594  ok(fmt.cfFormat == CF_ENHMETAFILE, "cf %04x\n", fmt.cfFormat);
1595  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1596  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1597  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1598  ok(fmt.tymed == TYMED_ENHMF, "tymed %x\n", fmt.tymed);
1599 
1600  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1601  ok(hr == S_OK, "got %08x\n", hr);
1602  ok(fmt.cfFormat == cf_storage, "cf %04x\n", fmt.cfFormat);
1603  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1604  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1605  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1606  ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
1607 
1608  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1609  ok(hr == S_OK, "got %08x\n", hr); /* User32 adds some synthesised formats */
1610 
1611  ok(fmt.cfFormat == CF_LOCALE, "cf %04x\n", fmt.cfFormat);
1612  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1613  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1614  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1615  todo_wine ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
1616 
1617  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1618  ok(hr == S_OK, "got %08x\n", hr);
1619 
1620  ok(fmt.cfFormat == CF_OEMTEXT, "cf %04x\n", fmt.cfFormat);
1621  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1622  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1623  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1624  ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
1625 
1626  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1627  ok(hr == S_OK, "got %08x\n", hr);
1628  ok(fmt.cfFormat == CF_UNICODETEXT, "cf %04x\n", fmt.cfFormat);
1629  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1630  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1631  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1632  ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
1633 
1634  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1635  ok(hr == S_OK, "got %08x\n", hr);
1636  ok(fmt.cfFormat == CF_METAFILEPICT, "cf %04x\n", fmt.cfFormat);
1637  ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
1638  ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
1639  ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
1640  ok(fmt.tymed == TYMED_MFPICT, "tymed %x\n", fmt.tymed);
1641 
1642  hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
1643  ok(hr == S_FALSE, "got %08x\n", hr);
1644  IEnumFORMATETC_Release(enum_fmt);
1645 
1646  InitFormatEtc(fmt, CF_ENHMETAFILE, TYMED_ENHMF);
1647  hr = IDataObject_GetData(get, &fmt, &med);
1648  ok(hr == S_OK, "got %08x\n", hr);
1649  obj_type = GetObjectType(U(med).hEnhMetaFile);
1650  ok(obj_type == OBJ_ENHMETAFILE, "got %d\n", obj_type);
1651  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1652 
1653  InitFormatEtc(fmt, cf_storage, TYMED_ISTORAGE);
1654  hr = IDataObject_GetData(get, &fmt, &med);
1655  ok(hr == S_OK, "got %08x\n", hr);
1656  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1657  if(SUCCEEDED(hr)) ReleaseStgMedium(&med);
1658 
1659  IDataObject_Release(get);
1660 
1661  r = OpenClipboard(NULL);
1662  ok(r, "gle %d\n", GetLastError());
1663  r = EmptyClipboard();
1664  ok(r, "gle %d\n", GetLastError());
1665  r = CloseClipboard();
1666  ok(r, "gle %d\n", GetLastError());
1667 
1668  OleUninitialize();
1669 }
1670 
1671 static void test_getdatahere(void)
1672 {
1673  HRESULT hr;
1674  IDataObject *src, *get;
1675  FORMATETC fmt;
1676  STGMEDIUM med;
1677 
1679 
1681  ok(hr == S_OK, "got %08x\n", hr);
1682 
1683  hr = OleSetClipboard(src);
1684  ok(hr == S_OK, "got %08x\n", hr);
1685 
1686  hr = OleGetClipboard(&get);
1687  ok(hr == S_OK, "got %08x\n", hr);
1688 
1689  /* global format -> global & stream */
1690 
1693 
1694  InitFormatEtc(fmt, CF_TEXT, TYMED_HGLOBAL);
1695 
1696  med.pUnkForRelease = NULL;
1697  med.tymed = TYMED_HGLOBAL;
1698  U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
1699  hr = IDataObject_GetDataHere(get, &fmt, &med);
1700  ok(hr == S_OK, "got %08x\n", hr);
1701  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1702  ReleaseStgMedium(&med);
1705 
1706  InitFormatEtc(fmt, CF_TEXT, 0);
1707 
1708  med.pUnkForRelease = NULL;
1709  med.tymed = TYMED_HGLOBAL;
1710  U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
1711  hr = IDataObject_GetDataHere(get, &fmt, &med);
1712  ok(hr == S_OK, "got %08x\n", hr);
1713  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1714  ReleaseStgMedium(&med);
1717 
1718  med.pUnkForRelease = NULL;
1719  med.tymed = TYMED_HGLOBAL;
1720  U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 1);
1721  hr = IDataObject_GetDataHere(get, &fmt, &med);
1722  ok(hr == E_FAIL, "got %08x\n", hr);
1723  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1724  ReleaseStgMedium(&med);
1727 
1728  med.pUnkForRelease = NULL;
1729  med.tymed = TYMED_ISTREAM;
1730  CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm);
1731  hr = IDataObject_GetDataHere(get, &fmt, &med);
1732  ok(hr == S_OK, "got %08x\n", hr);
1733  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1734  ReleaseStgMedium(&med);
1737 
1738  med.pUnkForRelease = NULL;
1739  med.tymed = TYMED_ISTORAGE;
1741  hr = IDataObject_GetDataHere(get, &fmt, &med);
1742  ok(hr == E_FAIL, "got %08x\n", hr);
1743  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1744  ReleaseStgMedium(&med);
1747 
1749 
1750  med.pUnkForRelease = NULL;
1751  med.tymed = TYMED_HGLOBAL;
1752  U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 100);
1753  hr = IDataObject_GetDataHere(get, &fmt, &med);
1754  ok(hr == S_OK, "got %08x\n", hr);
1755  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1756  ReleaseStgMedium(&med);
1759 
1760  med.pUnkForRelease = NULL;
1761  med.tymed = TYMED_ISTREAM;
1762  CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm);
1763  hr = IDataObject_GetDataHere(get, &fmt, &med);
1764  ok(hr == S_OK, "got %08x\n", hr);
1765  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1766  ReleaseStgMedium(&med);
1769 
1770  med.pUnkForRelease = NULL;
1771  med.tymed = TYMED_ISTORAGE;
1773  hr = IDataObject_GetDataHere(get, &fmt, &med);
1774  ok(hr == E_FAIL, "got %08x\n", hr);
1775  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1776  ReleaseStgMedium(&med);
1779 
1781 
1782  med.pUnkForRelease = NULL;
1783  med.tymed = TYMED_HGLOBAL;
1784  U(med).hGlobal = GlobalAlloc(GMEM_MOVEABLE, 3000);
1785  hr = IDataObject_GetDataHere(get, &fmt, &med);
1786  ok(hr == S_OK, "got %08x\n", hr);
1787  ok(med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed);
1788  ReleaseStgMedium(&med);
1791 
1792  med.pUnkForRelease = NULL;
1793  med.tymed = TYMED_ISTREAM;
1794  CreateStreamOnHGlobal(NULL, TRUE, &U(med).pstm);
1795  hr = IDataObject_GetDataHere(get, &fmt, &med);
1796  ok(hr == S_OK, "got %08x\n", hr);
1797  ok(med.tymed == TYMED_ISTREAM, "got %x\n", med.tymed);
1798  ReleaseStgMedium(&med);
1801 
1802  med.pUnkForRelease = NULL;
1803  med.tymed = TYMED_ISTORAGE;
1805  hr = IDataObject_GetDataHere(get, &fmt, &med);
1806  ok(hr == S_OK, "got %08x\n", hr);
1807  ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed);
1808  ReleaseStgMedium(&med);
1811 
1812 
1813  IDataObject_Release(get);
1814  IDataObject_Release(src);
1815 
1816  OleUninitialize();
1817 
1818 }
1819 
1821 {
1822  IDataObject *data_obj = arg;
1823 
1824  IDataObject_Release(data_obj);
1825  return 0;
1826 }
1827 
1829 {
1830  IDataObject *data_obj;
1831  HANDLE thread;
1832  HRESULT hr;
1833  DWORD ret;
1834 
1836 
1837  hr = OleGetClipboard(&data_obj);
1838  ok(hr == S_OK, "OleGetClipboard returned %x\n", hr);
1839 
1840  thread = CreateThread(NULL, 0, test_data_obj, data_obj, 0, NULL);
1841  ok(thread != NULL, "CreateThread failed (%d)\n", GetLastError());
1842  ret = WaitForSingleObject(thread, 5000);
1843  ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
1844 
1845  hr = OleGetClipboard(&data_obj);
1846  ok(hr == S_OK, "OleGetClipboard returned %x\n", hr);
1847  IDataObject_Release(data_obj);
1848 
1849  OleUninitialize();
1850 }
1851 
1852 static void test_get_clipboard_locked(void)
1853 {
1854  HRESULT hr;
1855  IDataObject *pDObj;
1856 
1858 
1859  pDObj = (IDataObject *)0xdeadbeef;
1860  /* lock clipboard */
1862  hr = OleGetClipboard(&pDObj);
1863  todo_wine ok(hr == CLIPBRD_E_CANT_OPEN, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, CLIPBRD_E_CANT_OPEN);
1864  todo_wine ok(pDObj == NULL, "OleGetClipboard() got 0x%p instead of NULL\n",pDObj);
1865  if (pDObj) IDataObject_Release(pDObj);
1866  CloseClipboard();
1867 
1868  OleUninitialize();
1869 }
1870 
1871 START_TEST(clipboard)
1872 {
1879  test_getdatahere();
1882 }
#define WM_CHANGECBCHAIN
Definition: winuser.h:1856
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HMETAFILE hMF
Definition: wingdi.h:2603
static DataObjectImpl * impl_from_IDataObject(IDataObject *iface)
Definition: clipboard.c:106
static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject *iface, FORMATETC *pformatectIn, FORMATETC *pformatetcOut)
Definition: clipboard.c:354
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2199
static void test_get_clipboard_uninitialized(void)
Definition: clipboard.c:504
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
IDataObject IDataObject_iface
Definition: clipboard.c:30
#define E_NOINTERFACE
Definition: winerror.h:2364
HWND WINAPI SetClipboardViewer(_In_ HWND)
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL global, BOOL delete_on_release, ILockBytes **ret)
Definition: memlockbytes.c:100
static DWORD CALLBACK set_clipboard_thread(void *arg)
Definition: clipboard.c:1068
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
static HRESULT WINAPI DataObjectImpl_EnumFormatEtc(IDataObject *iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
Definition: clipboard.c:368
UINT fmtetc_cnt
Definition: clipboard.c:34
#define DWORD_PTR
Definition: treelist.c:76
#define CF_ENHMETAFILE
Definition: constants.h:409
HRESULT hr
Definition: shlfolder.c:183
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:922
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2036
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static HRESULT WINAPI DataObjectImpl_DUnadvise(IDataObject *iface, DWORD dwConnection)
Definition: clipboard.c:389
REFIID riid
Definition: precomp.h:44
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const WCHAR * text
Definition: package.c:1827
GLuint GLuint GLsizei count
Definition: gl.h:1545
HDC WINAPI CreateMetaFileA(_In_opt_ LPCSTR)
#define U(x)
Definition: wordpad.c:44
static const char * cmpl_stm_data
Definition: clipboard.c:445
static UINT wm_drawclipboard
Definition: clipboard.c:1036
HMETAFILEPICT hmfp
Definition: clipboard.c:64
#define STGM_CREATE
Definition: objbase.h:925
static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc)
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
const char * fmt
Definition: wsprintf.c:30
static HRESULT WINAPI DataObjectImpl_GetData(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
Definition: clipboard.c:268
HANDLE HWND
Definition: compat.h:13
static ULONG DataObjectImpl_GetData_calls
Definition: clipboard.c:78
WORD dmDriverExtra
Definition: wingdi.h:1616
#define snprintf
Definition: wintirpc.h:48
HANDLE WINAPI GetClipboardData(UINT uFormat)
Definition: clipboard.c:198
struct DataObjectImpl DataObjectImpl
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
Definition: tftpd.h:125
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
const GUID IID_IDataObject
static HENHMETAFILE create_emf(void)
Definition: clipboard.c:1505
void * arg
Definition: msvc.h:12
#define DV_E_CLIPFORMAT
Definition: winerror.h:2639
BOOL WINAPI ChangeClipboardChain(_In_ HWND, _In_ HWND)
UINT_PTR WPARAM
Definition: windef.h:207
#define CF_METAFILEPICT
Definition: constants.h:398
static LPDATAOBJECT clip_data
Definition: clipboard.c:1034
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: clipboard.c:1038
static HRESULT WINAPI DataObjectImpl_DAdvise(IDataObject *iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
Definition: clipboard.c:382
#define E_FAIL
Definition: ddrawi.h:102
static void test_consumer_refs(void)
Definition: clipboard.c:1138
BOOL WINAPI DestroyWindow(_In_ HWND)
int winetest_debug
Definition: send.c:47
static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, LPVOID *ppvObj)
Definition: clipboard.c:222
& rect
Definition: startmenu.cpp:1413
UINT fmtetc_cnt
Definition: clipboard.c:45
#define CO_E_NOTINITIALIZED
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
#define InitFormatEtc(fe, cf, med)
Definition: clipboard.c:36
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
static HRESULT WINAPI DataObjectImpl_EnumDAdvise(IDataObject *iface, IEnumSTATDATA **ppenumAdvise)
Definition: clipboard.c:395
static const IEnumFORMATETCVtbl VT_EnumFormatImpl
Definition: clipboard.c:197
static void test_nonole_clipboard(void)
Definition: clipboard.c:1513
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject *iface, FORMATETC *pformatetc)
Definition: clipboard.c:331
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
static const WCHAR device_name[]
Definition: clipboard.c:447
#define OBJ_ENHMETAFILE
Definition: objidl.idl:1421
#define ETO_OPAQUE
Definition: wingdi.h:646
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static HRESULT DataObjectImpl_CreateFromHGlobal(HGLOBAL text, LPDATAOBJECT *dataobj)
Definition: clipboard.c:417
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
static LPUNKNOWN
Definition: ndr_ole.c:49
static HRESULT WINAPI DataObjectImpl_SetData(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
Definition: clipboard.c:361
static UINT cf_stream
Definition: clipboard.c:82
HRESULT WINAPI StgCreateDocfileOnILockBytes(ILockBytes *plkbyt, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8947
static ULONG count_refs(IDataObject *d)
Definition: clipboard.c:1132
GLenum GLint ref
Definition: glext.h:6028
static PVOID ptr
Definition: dispmode.c:27
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4216
#define S_FALSE
Definition: winerror.h:2357
static struct fmt fmts[]
#define E_INVALIDARG
Definition: ddrawi.h:101
#define CF_UNICODETEXT
Definition: constants.h:408
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
HDC WINAPI CreateEnhMetaFileA(_In_opt_ HDC, _In_opt_ LPCSTR, _In_opt_ LPCRECT, _In_opt_ LPCSTR)
#define STGM_DELETEONRELEASE
Definition: objbase.h:924
FORMATETC * fmtetc
Definition: clipboard.c:44
FORMATETC * fmtetc
Definition: clipboard.c:33
LONG_PTR LPARAM
Definition: windef.h:208
static UINT cf_onemore
Definition: clipboard.c:82
static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched)
Definition: clipboard.c:149
HMETAFILE WINAPI CloseMetaFile(_In_ HDC hdc)
const char * LPCSTR
Definition: xmlstorage.h:183
static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject *iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
Definition: clipboard.c:323
static ULONG WINAPI DataObjectImpl_Release(IDataObject *iface)
Definition: clipboard.c:242
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 void test_no_cf_dataobject(void)
Definition: clipboard.c:701
HANDLE WINAPI SetClipboardData(UINT uFormat, HANDLE hMem)
Definition: clipboard.c:299
void get(int argc, const char *argv[])
Definition: cmds.c:480
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
BOOL WINAPI OpenClipboard(HWND hWndNewOwner)
Definition: clipboard.c:29
static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
Definition: clipboard.c:437
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
_In_ FONTOBJ _In_ ULONG _In_ HGLYPH hg
Definition: winddi.h:3869
#define DV_E_FORMATETC
Definition: winerror.h:2633
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define d
Definition: ke_i.h:81
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HGLOBAL create_storage(void)
Definition: clipboard.c:1289
static UINT count
Definition: clipboard.c:35
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
WORD dmSize
Definition: wingdi.h:1615
static HWND next_wnd
Definition: clipboard.c:1035
#define WINAPI
Definition: msvc.h:8
static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
Definition: clipboard.c:449
static HRESULT WINAPI EnumFormatImpl_Reset(IEnumFORMATETC *iface)
Definition: clipboard.c:183
unsigned long DWORD
Definition: ntddk_ex.h:95
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
const GUID IID_IEnumFORMATETC
HANDLE text
Definition: clipboard.c:61
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
static void test_get_clipboard(void)
Definition: clipboard.c:515
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1612
#define DV_E_TYMED
Definition: winerror.h:2638
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
static void test_complex_get_clipboard(void)
Definition: clipboard.c:870
static HANDLE thread
Definition: service.c:33
interface IEnumFORMATETC * LPENUMFORMATETC
Definition: objfwd.h:24
int ret
HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes *iface, HGLOBAL *phglobal)
Definition: memlockbytes.c:147
static HMETAFILEPICT create_metafilepict(void)
Definition: clipboard.c:94
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
#define todo_wine
Definition: test.h:154
#define InterlockedDecrement
Definition: armddk.h:52
HDC hdc
Definition: main.c:9
#define MM_ANISOTROPIC
Definition: wingdi.h:866
#define WM_DRAWCLIPBOARD
Definition: winuser.h:1851
static HRESULT WINAPI EnumFormatImpl_Clone(IEnumFORMATETC *iface, IEnumFORMATETC **ppenum)
Definition: clipboard.c:191
Definition: stat.h:55
static HGLOBAL create_text(void)
Definition: clipboard.c:1496
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8637
static void test_set_clipboard_DRAWCLIPBOARD(void)
Definition: clipboard.c:1078
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
#define CF_WAVE
Definition: constants.h:407
#define DV_E_LINDEX
Definition: winerror.h:2637
interface IDataObject * LPDATAOBJECT
Definition: objfwd.h:21
GLenum src
Definition: glext.h:6340
IEnumFORMATETC IEnumFORMATETC_iface
Definition: clipboard.c:41
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPCSTR lpszClassName
Definition: winuser.h:3146
#define STGM_READWRITE
Definition: objbase.h:918
static ULONG DataObjectImpl_GetDataHere_calls
Definition: clipboard.c:79
#define WM_USER
Definition: winuser.h:1877
UINT WINAPI RegisterClipboardFormatA(LPCSTR lpszFormat)
Definition: clipboard.c:98
#define CF_LOCALE
Definition: constants.h:411
#define broken(x)
Definition: _sntprintf.h:21
static char * dump_fmtetc(FORMATETC *fmt)
Definition: clipboard.c:45
IDataObject IDataObject_iface
Definition: usrmarshal.c:1273
static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFIID riid, LPVOID *ppvObj)
Definition: clipboard.c:116
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:172
static const IDataObjectVtbl VT_DataObjectImpl
Definition: clipboard.c:401
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
HWND WINAPI GetClipboardOwner(void)
Definition: ntwrapper.h:196
#define S_OK
Definition: intsafe.h:59
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define InterlockedIncrement
Definition: armddk.h:53
static void test_multithreaded_clipboard(void)
Definition: clipboard.c:1828
#define CF_OEMTEXT
Definition: constants.h:402
#define lstrcpyW
Definition: compat.h:406
HINSTANCE hInstance
Definition: winuser.h:3141
static const WCHAR data1[]
Definition: db.c:2967
static const WCHAR data2[]
Definition: db.c:2971
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
static HMETAFILE create_mf(void)
Definition: clipboard.c:86
#define ok(value,...)
Definition: atltest.h:57
#define E_NOTIMPL
Definition: ddrawi.h:99
static const char * cmpl_text_data
Definition: clipboard.c:446
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static void test_flushed_getdata(void)
Definition: clipboard.c:1307
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
static ULONG WINAPI EnumFormatImpl_AddRef(IEnumFORMATETC *iface)
Definition: clipboard.c:129
static POBJECT_TYPE GetObjectType(IN PCWSTR TypeName)
Definition: ObTypes.c:15
#define CF_RIFF
Definition: constants.h:406
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
IStorage * stg
Definition: clipboard.c:63
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
UINT WINAPI EnumClipboardFormats(UINT format)
Definition: clipboard.c:39
static ULONG WINAPI DataObjectImpl_AddRef(IDataObject *iface)
Definition: clipboard.c:235
#define GMEM_DDESHARE
Definition: winbase.h:295
WNDPROC lpfnWndProc
Definition: winuser.h:3138
static void test_cf_dataobject(IDataObject *data)
Definition: clipboard.c:716
#define skip(...)
Definition: atltest.h:64
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1897
#define msg(x)
Definition: auth_time.c:54
#define CLIPBRD_E_CANT_OPEN
Definition: winerror.h:2766
static void test_set_clipboard(void)
Definition: clipboard.c:908
GLuint res
Definition: glext.h:9613
START_TEST(clipboard)
Definition: clipboard.c:1871
static void test_get_clipboard_locked(void)
Definition: clipboard.c:1852
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static ULONG DataObjectImpl_EnumFormatEtc_calls
Definition: clipboard.c:80
IStream * stm
Definition: clipboard.c:62
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
Definition: clipboard.c:136
static void test_enum_fmtetc(IDataObject *src)
Definition: clipboard.c:610
static DWORD CALLBACK test_data_obj(void *arg)
Definition: clipboard.c:1820
HRESULT WINAPI OleFlushClipboard(void)
Definition: clipboard.c:2293
GLfloat GLfloat p
Definition: glext.h:8902
LONG_PTR LRESULT
Definition: windef.h:209
static EnumFormatImpl * impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
Definition: clipboard.c:111
static UINT cf_another
Definition: clipboard.c:82
static BOOL expect_DataObjectImpl_QueryGetData
Definition: clipboard.c:77
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:233
#define memset(x, y, z)
Definition: compat.h:39
static UINT cf_storage
Definition: clipboard.c:82
static HRESULT WINAPI EnumFormatImpl_Skip(IEnumFORMATETC *iface, ULONG celt)
Definition: clipboard.c:177
#define win_skip
Definition: test.h:141
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
Definition: dsound.c:943
static UINT cf_global
Definition: clipboard.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define GMEM_MOVEABLE
Definition: winbase.h:291
#define GMEM_ZEROINIT
Definition: winbase.h:303
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static void test_getdatahere(void)
Definition: clipboard.c:1671
struct EnumFormatImpl EnumFormatImpl
Definition: tftpd.h:137