ReactOS  0.4.14-dev-583-g2a1ba2c
ole2.c
Go to the documentation of this file.
1 /*
2  * Object Linking and Embedding Tests
3  *
4  * Copyright 2005 Robert Shearman
5  * Copyright 2017 Dmitry Timoshkov
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 
22 #define COBJMACROS
23 #define CONST_VTABLE
24 #define WIN32_LEAN_AND_MEAN
25 
26 #include <stdarg.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "objbase.h"
32 #include "shlguid.h"
33 
34 #include "wine/test.h"
35 
36 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
37 
38 #define DEFINE_EXPECT(func) \
39  static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
40 
41 #define SET_EXPECT(func) \
42  expect_ ## func = TRUE
43 
44 #define CHECK_EXPECT2(func) \
45  do { \
46  ok(expect_ ##func, "unexpected call " #func "\n"); \
47  called_ ## func = TRUE; \
48  }while(0)
49 
50 #define CHECK_EXPECT(func) \
51  do { \
52  CHECK_EXPECT2(func); \
53  expect_ ## func = FALSE; \
54  }while(0)
55 
56 #define CHECK_CALLED(func) \
57  do { \
58  ok(called_ ## func, "expected " #func "\n"); \
59  expect_ ## func = called_ ## func = FALSE; \
60  }while(0)
61 
63 DEFINE_EXPECT(Storage_OpenStream_CompObj);
64 DEFINE_EXPECT(Storage_OpenStream_OlePres);
66 DEFINE_EXPECT(Storage_CreateStream_CompObj);
67 DEFINE_EXPECT(Storage_CreateStream_OlePres);
68 DEFINE_EXPECT(Storage_OpenStream_Ole);
70 
73 
75 static IOleCache *cache;
77 
78 static const CLSID CLSID_WineTestOld =
79 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */
80  0x9474ba1a,
81  0x258b,
82  0x490b,
83  {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0}
84 };
85 
86 static const CLSID CLSID_WineTest =
87 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
88  0x9474ba1a,
89  0x258b,
90  0x490b,
91  {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
92 };
93 
94 static const IID IID_WineTest =
95 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
96  0x9474ba1a,
97  0x258b,
98  0x490b,
99  {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
100 };
101 
102 #define TEST_OPTIONAL 0x1
103 #define TEST_TODO 0x2
104 
106 {
107  const char *method;
108  unsigned int flags;
109  FORMATETC fmt;
110 };
111 
113 static FORMATETC *g_expected_fetc = NULL;
114 
119 
121 
122 static FORMATETC *g_dataobject_fmts;
123 
124 /****************************************************************************
125  * PresentationDataHeader
126  *
127  * This structure represents the header of the \002OlePresXXX stream in
128  * the OLE object storage.
129  */
130 typedef struct PresentationDataHeader
131 {
132  /* clipformat:
133  * - standard clipformat:
134  * DWORD length = 0xffffffff;
135  * DWORD cfFormat;
136  * - or custom clipformat:
137  * DWORD length;
138  * CHAR format_name[length]; (null-terminated)
139  */
140  DWORD tdSize; /* This is actually a truncated DVTARGETDEVICE, if tdSize > sizeof(DWORD)
141  then there are tdSize - sizeof(DWORD) more bytes before dvAspect */
142  DVASPECT dvAspect;
143  DWORD lindex;
144  DWORD advf;
145  DWORD unknown7; /* 0 */
148  DWORD dwSize;
150 
151 #ifdef __REACTOS__
152 static inline void check_expected_method_fmt(const char *method_name, const FORMATETC *fmt)
153 #else
154 static void inline check_expected_method_fmt(const char *method_name, const FORMATETC *fmt)
155 #endif
156 {
157  trace("%s\n", method_name);
158  ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name);
159  if (!strcmp(expected_method_list->method, "WINE_EXTRA"))
160  {
161  todo_wine ok(0, "Too many method calls.\n");
162  return;
163  }
164  if (expected_method_list->method)
165  {
166  while (expected_method_list->flags & TEST_OPTIONAL &&
167  strcmp(expected_method_list->method, method_name) != 0)
170  {
171  ok(!strcmp(expected_method_list->method, method_name),
172  "Expected %s to be called instead of %s\n",
173  expected_method_list->method, method_name);
174  if (fmt)
175  {
176  ok(fmt->cfFormat == expected_method_list->fmt.cfFormat, "got cf %04x vs %04x\n",
177  fmt->cfFormat, expected_method_list->fmt.cfFormat );
178  ok(fmt->dwAspect == expected_method_list->fmt.dwAspect, "got aspect %d vs %d\n",
179  fmt->dwAspect, expected_method_list->fmt.dwAspect );
180  ok(fmt->lindex == expected_method_list->fmt.lindex, "got lindex %d vs %d\n",
181  fmt->lindex, expected_method_list->fmt.lindex );
182  ok(fmt->tymed == expected_method_list->fmt.tymed, "got tymed %d vs %d\n",
183  fmt->tymed, expected_method_list->fmt.tymed );
184  }
185  }
187  }
188 }
189 
190 #define CHECK_EXPECTED_METHOD(method_name) check_expected_method_fmt(method_name, NULL)
191 #define CHECK_EXPECTED_METHOD_FMT(method_name, fmt) check_expected_method_fmt(method_name, fmt)
192 
193 #define CHECK_NO_EXTRA_METHODS() \
194  do { \
195  while (expected_method_list->flags & TEST_OPTIONAL) \
196  expected_method_list++; \
197  ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
198  } while (0)
199 
200 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
201 static const BYTE dib[] =
202 {
203  0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
204  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00,
205  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206  0xc8, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
207  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
209 };
210 
211 static void create_dib( STGMEDIUM *med )
212 {
213  void *ptr;
214 
215  med->tymed = TYMED_HGLOBAL;
216  U(med)->hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) );
217  ptr = GlobalLock( U(med)->hGlobal );
218  memcpy( ptr, dib, sizeof(dib) );
219  GlobalUnlock( U(med)->hGlobal );
220  med->pUnkForRelease = NULL;
221 }
222 
223 static void create_bitmap( STGMEDIUM *med )
224 {
225  med->tymed = TYMED_GDI;
226  U(med)->hBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
227  med->pUnkForRelease = NULL;
228 }
229 
230 static void create_emf(STGMEDIUM *med)
231 {
233 
234  Rectangle(hdc, 0, 0, 150, 300);
235  med->tymed = TYMED_ENHMF;
236  U(med)->hEnhMetaFile = CloseEnhMetaFile(hdc);
237  med->pUnkForRelease = NULL;
238 }
239 
240 static void create_mfpict(STGMEDIUM *med)
241 {
242  METAFILEPICT *mf;
244 
245  Rectangle(hdc, 0, 0, 100, 200);
246 
247  med->tymed = TYMED_MFPICT;
248  U(med)->hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
249  mf = GlobalLock(U(med)->hMetaFilePict);
250  mf->mm = MM_ANISOTROPIC;
251  mf->xExt = 100;
252  mf->yExt = 200;
253  mf->hMF = CloseMetaFile(hdc);
254  GlobalUnlock(U(med)->hMetaFilePict);
255  med->pUnkForRelease = NULL;
256 }
257 
258 static void create_text(STGMEDIUM *med)
259 {
260  HGLOBAL handle;
261  char *p;
262 
264  p = GlobalLock(handle);
265  strcpy(p, "test");
267 
268  med->tymed = TYMED_HGLOBAL;
269  U(med)->hGlobal = handle;
270  med->pUnkForRelease = NULL;
271 }
272 
274 {
275  CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
276 
277  *ppv = NULL;
278 
280  *ppv = iface;
281  else if (IsEqualIID(riid, &IID_IPersistStorage))
283  else if (IsEqualIID(riid, &IID_IOleCache))
284  *ppv = cache;
286  *ppv = runnable;
287  else if (IsEqualIID(riid, &IID_WineTest))
288  return g_QIFailsWith;
289 
290  if(*ppv) {
291  IUnknown_AddRef((IUnknown*)*ppv);
292  return S_OK;
293  }
294 
295  trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
296  return E_NOINTERFACE;
297 }
298 
300 {
301  CHECK_EXPECTED_METHOD("OleObject_AddRef");
302  return 2;
303 }
304 
306 {
307  CHECK_EXPECTED_METHOD("OleObject_Release");
308  return 1;
309 }
310 
312  (
313  IOleObject *iface,
314  IOleClientSite *pClientSite
315  )
316 {
317  CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
318  return S_OK;
319 }
320 
322  (
323  IOleObject *iface,
324  IOleClientSite **ppClientSite
325  )
326 {
327  CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
328  return E_NOTIMPL;
329 }
330 
332  (
333  IOleObject *iface,
334  LPCOLESTR szContainerApp,
335  LPCOLESTR szContainerObj
336  )
337 {
338  CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
339  return S_OK;
340 }
341 
343  (
344  IOleObject *iface,
345  DWORD dwSaveOption
346  )
347 {
348  CHECK_EXPECTED_METHOD("OleObject_Close");
349  return S_OK;
350 }
351 
353  (
354  IOleObject *iface,
355  DWORD dwWhichMoniker,
356  IMoniker *pmk
357  )
358 {
359  CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
360  return S_OK;
361 }
362 
364  (
365  IOleObject *iface,
366  DWORD dwAssign,
367  DWORD dwWhichMoniker,
368  IMoniker **ppmk
369  )
370 {
371  CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
372  return S_OK;
373 }
374 
376  (
377  IOleObject *iface,
378  IDataObject *pDataObject,
379  BOOL fCreation,
381  )
382 {
383  CHECK_EXPECTED_METHOD("OleObject_InitFromData");
384  return S_OK;
385 }
386 
388  (
389  IOleObject *iface,
391  IDataObject **ppDataObject
392  )
393 {
394  CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
395  return E_NOTIMPL;
396 }
397 
399  (
400  IOleObject *iface,
401  LONG iVerb,
402  LPMSG lpmsg,
403  IOleClientSite *pActiveSite,
404  LONG lindex,
406  LPCRECT lprcPosRect
407  )
408 {
409  CHECK_EXPECTED_METHOD("OleObject_DoVerb");
410  return S_OK;
411 }
412 
414  (
415  IOleObject *iface,
416  IEnumOLEVERB **ppEnumOleVerb
417  )
418 {
419  CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
420  return E_NOTIMPL;
421 }
422 
424  (
425  IOleObject *iface
426  )
427 {
428  CHECK_EXPECTED_METHOD("OleObject_Update");
429  return S_OK;
430 }
431 
433  (
434  IOleObject *iface
435  )
436 {
437  CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
438  return S_OK;
439 }
440 
442 (
443  IOleObject *iface,
444  CLSID *pClsid
445 )
446 {
447  CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
448  return E_NOTIMPL;
449 }
450 
452 (
453  IOleObject *iface,
454  DWORD dwFormOfType,
455  LPOLESTR *pszUserType
456 )
457 {
458  CHECK_EXPECTED_METHOD("OleObject_GetUserType");
459  return E_NOTIMPL;
460 }
461 
463 (
464  IOleObject *iface,
465  DWORD dwDrawAspect,
466  SIZEL *psizel
467 )
468 {
469  CHECK_EXPECTED_METHOD("OleObject_SetExtent");
470  return S_OK;
471 }
472 
474 (
475  IOleObject *iface,
476  DWORD dwDrawAspect,
477  SIZEL *psizel
478 )
479 {
480  CHECK_EXPECTED_METHOD("OleObject_GetExtent");
481  return E_NOTIMPL;
482 }
483 
485 (
486  IOleObject *iface,
487  IAdviseSink *pAdvSink,
488  DWORD *pdwConnection
489 )
490 {
491  CHECK_EXPECTED_METHOD("OleObject_Advise");
492  return S_OK;
493 }
494 
496 (
497  IOleObject *iface,
498  DWORD dwConnection
499 )
500 {
501  CHECK_EXPECTED_METHOD("OleObject_Unadvise");
502  return S_OK;
503 }
504 
506 (
507  IOleObject *iface,
508  IEnumSTATDATA **ppenumAdvise
509 )
510 {
511  CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
512  return E_NOTIMPL;
513 }
514 
516 (
517  IOleObject *iface,
518  DWORD aspect,
519  DWORD *pdwStatus
520 )
521 {
522  CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
523 
524  ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect);
525 
527  {
528  *pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
529  return S_OK;
530  }
531  else
532  {
533  *pdwStatus = 0x1234;
535  }
536 }
537 
539 (
540  IOleObject *iface,
541  LOGPALETTE *pLogpal
542 )
543 {
544  CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
545  return E_NOTIMPL;
546 }
547 
548 static const IOleObjectVtbl OleObjectVtbl =
549 {
574 };
575 
577 
579 {
580  trace("OleObjectPersistStg_QueryInterface\n");
581  return IOleObject_QueryInterface(&OleObject, riid, ppv);
582 }
583 
585 {
586  CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
587  return 2;
588 }
589 
591 {
592  CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
593  return 1;
594 }
595 
597 {
598  CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
599  return E_NOTIMPL;
600 }
601 
603 (
604  IPersistStorage *iface
605 )
606 {
607  CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
608  return S_OK;
609 }
610 
612 (
613  IPersistStorage *iface,
614  IStorage *pStg
615 )
616 {
617  CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
618  return S_OK;
619 }
620 
622 (
623  IPersistStorage *iface,
624  IStorage *pStg
625 )
626 {
627  CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
628  return S_OK;
629 }
630 
632 (
633  IPersistStorage *iface,
634  IStorage *pStgSave,
635  BOOL fSameAsLoad
636 )
637 {
638  CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
639  return S_OK;
640 }
641 
643 (
644  IPersistStorage *iface,
645  IStorage *pStgNew
646 )
647 {
648  CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
649  return S_OK;
650 }
651 
653 (
654  IPersistStorage *iface
655 )
656 {
657  CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
658  return S_OK;
659 }
660 
661 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
662 {
673 };
674 
676 
678 {
679  return IOleObject_QueryInterface(&OleObject, riid, ppv);
680 }
681 
683 {
684  CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
685  return 2;
686 }
687 
689 {
690  CHECK_EXPECTED_METHOD("OleObjectCache_Release");
691  return 1;
692 }
693 
695 (
696  IOleCache *iface,
697  FORMATETC *pformatetc,
698  DWORD advf,
699  DWORD *pdwConnection
700 )
701 {
702  CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
703  if (g_expected_fetc) {
704  ok(pformatetc != NULL, "pformatetc should not be NULL\n");
705  if (pformatetc) {
706  ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
707  "cfFormat: %x\n", pformatetc->cfFormat);
708  ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
709  "ptd: %p\n", pformatetc->ptd);
710  ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
711  "dwAspect: %x\n", pformatetc->dwAspect);
712  ok(pformatetc->lindex == g_expected_fetc->lindex,
713  "lindex: %x\n", pformatetc->lindex);
714  ok(pformatetc->tymed == g_expected_fetc->tymed,
715  "tymed: %x\n", pformatetc->tymed);
716  }
717  } else
718  ok(pformatetc == NULL, "pformatetc should be NULL\n");
719  return S_OK;
720 }
721 
723 (
724  IOleCache *iface,
725  DWORD dwConnection
726 )
727 {
728  CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
729  return S_OK;
730 }
731 
733 (
734  IOleCache *iface,
735  IEnumSTATDATA **ppenumSTATDATA
736 )
737 {
738  CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
739  return S_OK;
740 }
741 
742 
744 (
745  IOleCache *iface,
746  IDataObject *pDataObject
747 )
748 {
749  CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
750  return S_OK;
751 }
752 
753 
755 (
756  IOleCache *iface,
757  FORMATETC *pformatetc,
758  STGMEDIUM *pmedium,
759  BOOL fRelease
760 )
761 {
762  CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
763  return S_OK;
764 }
765 
766 
767 static const IOleCacheVtbl OleObjectCacheVtbl =
768 {
777 };
778 
780 
782 {
784  {
785  *ppv = iface;
786  IClassFactory_AddRef(iface);
787  return S_OK;
788  }
789  *ppv = NULL;
790  return E_NOINTERFACE;
791 }
792 
794 {
795  return 2;
796 }
797 
799 {
800  return 1;
801 }
802 
804 {
805  return IOleObject_QueryInterface(&OleObject, riid, ppv);
806 }
807 
809 {
810  return S_OK;
811 }
812 
813 static const IClassFactoryVtbl OleObjectCFVtbl =
814 {
820 };
821 
823 
825 {
826  return IOleObject_QueryInterface(&OleObject, riid, ppv);
827 }
828 
830 {
831  CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
832  return 2;
833 }
834 
836 {
837  CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
838  return 1;
839 }
840 
842  IRunnableObject *iface,
843  LPCLSID lpClsid)
844 {
845  CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
846  return E_NOTIMPL;
847 }
848 
850  IRunnableObject *iface,
851  LPBINDCTX pbc)
852 {
853  CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
854  return S_OK;
855 }
856 
858 {
859  CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
860  return g_isRunning;
861 }
862 
864  IRunnableObject *iface,
865  BOOL fLock,
866  BOOL fLastUnlockCloses)
867 {
868  CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
869  return S_OK;
870 }
871 
873  IRunnableObject *iface,
874  BOOL fContained)
875 {
876  CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
877  return S_OK;
878 }
879 
880 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
881 {
890 };
891 
893 
894 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
895 
897 {
899  {
900  *obj = iface;
901  return S_OK;
902  }
903 
904  *obj = NULL;
905  return E_NOINTERFACE;
906 }
907 
909 {
910  return 2;
911 }
912 
914 {
915  return 1;
916 }
917 
919  void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw,
920  LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue),
921  ULONG_PTR dwContinue)
922 {
923  ok(index == -1, "index=%d\n", index);
924  return S_OK;
925 }
926 
928  void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset)
929 {
930  ok(0, "unexpected call GetColorSet\n");
931  return E_NOTIMPL;
932 }
933 
935  void *aspect, DWORD *freeze)
936 {
937  ok(0, "unexpected call Freeze\n");
938  return E_NOTIMPL;
939 }
940 
942 {
943  ok(0, "unexpected call Unfreeze\n");
944  return E_NOTIMPL;
945 }
946 
948 {
949  ok(0, "unexpected call SetAdvise\n");
950  return E_NOTIMPL;
951 }
952 
953 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf,
954  IAdviseSink **sink)
955 {
956  ok(0, "unexpected call GetAdvise\n");
957  return E_NOTIMPL;
958 }
959 
960 static const struct IViewObjectVtbl viewobjectvtbl = {
970 };
971 
973 
974 static void test_OleCreate(IStorage *pStorage)
975 {
976  HRESULT hr;
977  IOleObject *pObject;
978  FORMATETC formatetc;
979  static const struct expected_method methods_olerender_none[] =
980  {
981  { "OleObject_QueryInterface", 0 },
982  { "OleObject_AddRef", 0 },
983  { "OleObject_QueryInterface", 0 },
984  { "OleObject_AddRef", TEST_OPTIONAL },
985  { "OleObject_Release", TEST_OPTIONAL },
986  { "OleObject_QueryInterface", TEST_OPTIONAL },
987  { "OleObjectPersistStg_AddRef", 0 },
988  { "OleObjectPersistStg_InitNew", 0 },
989  { "OleObjectPersistStg_Release", 0 },
990  { "OleObject_Release", 0 },
991  { "OleObject_Release", TEST_OPTIONAL },
992  { NULL, 0 }
993  };
994  static const struct expected_method methods_olerender_draw[] =
995  {
996  { "OleObject_QueryInterface", 0 },
997  { "OleObject_AddRef", 0 },
998  { "OleObject_QueryInterface", 0 },
999  { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
1000  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1001  { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1002  { "OleObjectPersistStg_AddRef", 0 },
1003  { "OleObjectPersistStg_InitNew", 0 },
1004  { "OleObjectPersistStg_Release", 0 },
1005  { "OleObject_QueryInterface", 0 },
1006  { "OleObjectRunnable_AddRef", 0 },
1007  { "OleObjectRunnable_Run", 0 },
1008  { "OleObjectRunnable_Release", 0 },
1009  { "OleObject_QueryInterface", 0 },
1010  { "OleObjectCache_AddRef", 0 },
1011  { "OleObjectCache_Cache", 0 },
1012  { "OleObjectCache_Release", 0 },
1013  { "OleObject_Release", 0 },
1014  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1015  { NULL, 0 }
1016  };
1017  static const struct expected_method methods_olerender_draw_with_site[] =
1018  {
1019  { "OleObject_QueryInterface", 0 },
1020  { "OleObject_AddRef", 0 },
1021  { "OleObject_QueryInterface", 0 },
1022  { "OleObject_AddRef", 0 },
1023  { "OleObject_GetMiscStatus", 0 },
1024  { "OleObject_QueryInterface", 0 },
1025  { "OleObjectPersistStg_AddRef", 0 },
1026  { "OleObjectPersistStg_InitNew", 0 },
1027  { "OleObjectPersistStg_Release", 0 },
1028  { "OleObject_SetClientSite", 0 },
1029  { "OleObject_Release", 0 },
1030  { "OleObject_QueryInterface", 0 },
1031  { "OleObjectRunnable_AddRef", 0 },
1032  { "OleObjectRunnable_Run", 0 },
1033  { "OleObjectRunnable_Release", 0 },
1034  { "OleObject_QueryInterface", 0 },
1035  { "OleObjectCache_AddRef", 0 },
1036  { "OleObjectCache_Cache", 0 },
1037  { "OleObjectCache_Release", 0 },
1038  { "OleObject_Release", 0 },
1039  { NULL, 0 }
1040  };
1041  static const struct expected_method methods_olerender_format[] =
1042  {
1043  { "OleObject_QueryInterface", 0 },
1044  { "OleObject_AddRef", 0 },
1045  { "OleObject_QueryInterface", 0 },
1046  { "OleObject_AddRef", 0 },
1047  { "OleObject_GetMiscStatus", 0 },
1048  { "OleObject_QueryInterface", 0 },
1049  { "OleObjectPersistStg_AddRef", 0 },
1050  { "OleObjectPersistStg_InitNew", 0 },
1051  { "OleObjectPersistStg_Release", 0 },
1052  { "OleObject_SetClientSite", 0 },
1053  { "OleObject_Release", 0 },
1054  { "OleObject_QueryInterface", 0 },
1055  { "OleObjectRunnable_AddRef", 0 },
1056  { "OleObjectRunnable_Run", 0 },
1057  { "OleObjectRunnable_Release", 0 },
1058  { "OleObject_QueryInterface", 0 },
1059  { "OleObjectCache_AddRef", 0 },
1060  { "OleObjectCache_Cache", 0 },
1061  { "OleObjectCache_Release", 0 },
1062  { "OleObject_Release", 0 },
1063  { NULL, 0 }
1064  };
1065  static const struct expected_method methods_olerender_asis[] =
1066  {
1067  { "OleObject_QueryInterface", 0 },
1068  { "OleObject_AddRef", 0 },
1069  { "OleObject_QueryInterface", 0 },
1070  { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
1071  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1072  { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1073  { "OleObjectPersistStg_AddRef", 0 },
1074  { "OleObjectPersistStg_InitNew", 0 },
1075  { "OleObjectPersistStg_Release", 0 },
1076  { "OleObject_Release", 0 },
1077  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1078  { NULL, 0 }
1079  };
1080  static const struct expected_method methods_olerender_draw_no_runnable[] =
1081  {
1082  { "OleObject_QueryInterface", 0 },
1083  { "OleObject_AddRef", 0 },
1084  { "OleObject_QueryInterface", 0 },
1085  { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
1086  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1087  { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1088  { "OleObjectPersistStg_AddRef", 0 },
1089  { "OleObjectPersistStg_InitNew", 0 },
1090  { "OleObjectPersistStg_Release", 0 },
1091  { "OleObject_QueryInterface", 0 },
1092  { "OleObject_QueryInterface", 0 },
1093  { "OleObjectCache_AddRef", 0 },
1094  { "OleObjectCache_Cache", 0 },
1095  { "OleObjectCache_Release", 0 },
1096  { "OleObject_Release", 0 },
1097  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1098  { NULL, 0 },
1099  };
1100  static const struct expected_method methods_olerender_draw_no_cache[] =
1101  {
1102  { "OleObject_QueryInterface", 0 },
1103  { "OleObject_AddRef", 0 },
1104  { "OleObject_QueryInterface", 0 },
1105  { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
1106  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1107  { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1108  { "OleObjectPersistStg_AddRef", 0 },
1109  { "OleObjectPersistStg_InitNew", 0 },
1110  { "OleObjectPersistStg_Release", 0 },
1111  { "OleObject_QueryInterface", 0 },
1112  { "OleObjectRunnable_AddRef", 0 },
1113  { "OleObjectRunnable_Run", 0 },
1114  { "OleObjectRunnable_Release", 0 },
1115  { "OleObject_QueryInterface", 0 },
1116  { "OleObject_Release", 0 },
1117  { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1118  { NULL, 0 }
1119  };
1120 
1121  g_expected_fetc = &formatetc;
1122  formatetc.cfFormat = 0;
1123  formatetc.ptd = NULL;
1124  formatetc.dwAspect = DVASPECT_CONTENT;
1125  formatetc.lindex = -1;
1126  formatetc.tymed = TYMED_NULL;
1128  cache = &OleObjectCache;
1129  expected_method_list = methods_olerender_none;
1130  trace("OleCreate with OLERENDER_NONE:\n");
1131  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
1132  ok_ole_success(hr, "OleCreate");
1133  IOleObject_Release(pObject);
1135 
1136  expected_method_list = methods_olerender_draw;
1137  trace("OleCreate with OLERENDER_DRAW:\n");
1138  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1139  ok_ole_success(hr, "OleCreate");
1140  IOleObject_Release(pObject);
1142 
1143  expected_method_list = methods_olerender_draw_with_site;
1144  trace("OleCreate with OLERENDER_DRAW, with site:\n");
1145  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1146  ok_ole_success(hr, "OleCreate");
1147  IOleObject_Release(pObject);
1149 
1150  /* GetMiscStatus fails */
1151  g_GetMiscStatusFailsWith = 0x8fafefaf;
1152  expected_method_list = methods_olerender_draw_with_site;
1153  trace("OleCreate with OLERENDER_DRAW, with site:\n");
1154  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1155  ok_ole_success(hr, "OleCreate");
1156  IOleObject_Release(pObject);
1159 
1160  formatetc.cfFormat = CF_TEXT;
1161  formatetc.ptd = NULL;
1162  formatetc.dwAspect = DVASPECT_CONTENT;
1163  formatetc.lindex = -1;
1164  formatetc.tymed = TYMED_HGLOBAL;
1165  expected_method_list = methods_olerender_format;
1166  trace("OleCreate with OLERENDER_FORMAT:\n");
1167  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
1168  ok(hr == S_OK ||
1169  broken(hr == E_INVALIDARG), /* win2k */
1170  "OleCreate failed with error 0x%08x\n", hr);
1171  if (pObject)
1172  {
1173  IOleObject_Release(pObject);
1175  }
1176 
1177  expected_method_list = methods_olerender_asis;
1178  trace("OleCreate with OLERENDER_ASIS:\n");
1179  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
1180  ok_ole_success(hr, "OleCreate");
1181  IOleObject_Release(pObject);
1183 
1184  formatetc.cfFormat = 0;
1185  formatetc.tymed = TYMED_NULL;
1186  runnable = NULL;
1187  expected_method_list = methods_olerender_draw_no_runnable;
1188  trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1189  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1190  ok_ole_success(hr, "OleCreate");
1191  IOleObject_Release(pObject);
1193 
1195  cache = NULL;
1196  expected_method_list = methods_olerender_draw_no_cache;
1197  trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1198  hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1199  ok_ole_success(hr, "OleCreate");
1200  IOleObject_Release(pObject);
1202  trace("end\n");
1204 }
1205 
1206 static void test_OleLoad(IStorage *pStorage)
1207 {
1208  HRESULT hr;
1209  IOleObject *pObject;
1210  DWORD fmt;
1211 
1212  static const struct expected_method methods_oleload[] =
1213  {
1214  { "OleObject_QueryInterface", 0 },
1215  { "OleObject_AddRef", 0 },
1216  { "OleObject_QueryInterface", 0 },
1217  { "OleObject_AddRef", 0 },
1218  { "OleObject_GetMiscStatus", 0 },
1219  { "OleObject_QueryInterface", 0 },
1220  { "OleObjectPersistStg_AddRef", 0 },
1221  { "OleObjectPersistStg_Load", 0 },
1222  { "OleObjectPersistStg_Release", 0 },
1223  { "OleObject_SetClientSite", 0 },
1224  { "OleObject_Release", 0 },
1225  { "OleObject_QueryInterface", 0 },
1226  { "OleObject_GetMiscStatus", 0 },
1227  { "OleObject_Release", 0 },
1228  { NULL, 0 }
1229  };
1230 
1231  /* Test once with IOleObject_GetMiscStatus failing */
1232  expected_method_list = methods_oleload;
1234  trace("OleLoad:\n");
1235  hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1236  ok(hr == S_OK ||
1237  broken(hr == E_INVALIDARG), /* win98 and win2k */
1238  "OleLoad failed with error 0x%08x\n", hr);
1239  if(pObject)
1240  {
1241  DWORD dwStatus = 0xdeadbeef;
1242  hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1243  ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1244  ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
1245 
1246  IOleObject_Release(pObject);
1248  }
1250 
1251  /* Test again, let IOleObject_GetMiscStatus succeed. */
1252  expected_method_list = methods_oleload;
1253  trace("OleLoad:\n");
1254  hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1255  ok(hr == S_OK ||
1256  broken(hr == E_INVALIDARG), /* win98 and win2k */
1257  "OleLoad failed with error 0x%08x\n", hr);
1258  if (pObject)
1259  {
1260  DWORD dwStatus = 0xdeadbeef;
1261  hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1262  ok(hr == S_OK, "Got 0x%08x\n", hr);
1263  ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
1264 
1265  IOleObject_Release(pObject);
1267  }
1268 
1269  for (fmt = CF_TEXT; fmt < CF_MAX; fmt++)
1270  {
1271  static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1272  IStorage *stg;
1273  IStream *stream;
1274  IUnknown *obj;
1275  DWORD data, i, data_size;
1277  HDC hdc;
1278  HGDIOBJ hobj;
1279  RECT rc;
1280  char buf[256];
1281 
1282  for (i = 0; i < 7; i++)
1283  {
1285  ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr);
1286 
1287  hr = IStorage_SetClass(stg, &CLSID_WineTest);
1288  ok(hr == S_OK, "SetClass error %#x\n", hr);
1289 
1290  hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream);
1291  ok(hr == S_OK, "CreateStream error %#x\n", hr);
1292 
1293  data = ~0;
1294  hr = IStream_Write(stream, &data, sizeof(data), NULL);
1295  ok(hr == S_OK, "Write error %#x\n", hr);
1296 
1297  data = fmt;
1298  hr = IStream_Write(stream, &data, sizeof(data), NULL);
1299  ok(hr == S_OK, "Write error %#x\n", hr);
1300 
1301  switch (fmt)
1302  {
1303  case CF_BITMAP:
1304  /* FIXME: figure out stream format */
1305  hobj = CreateBitmap(1, 1, 1, 1, NULL);
1306  data_size = GetBitmapBits(hobj, sizeof(buf), buf);
1307  DeleteObject(hobj);
1308  break;
1309 
1310  case CF_METAFILEPICT:
1311  case CF_ENHMETAFILE:
1313  hobj = CloseMetaFile(hdc);
1314  data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf);
1315  DeleteMetaFile(hobj);
1316  break;
1317 
1318  default:
1319  data_size = sizeof(buf);
1320  memset(buf, 'A', sizeof(buf));
1321  break;
1322  }
1323 
1324  header.tdSize = sizeof(header.tdSize);
1325  header.dvAspect = DVASPECT_CONTENT;
1326  header.lindex = -1;
1327  header.advf = 1 << i;
1328  header.unknown7 = 0;
1329  header.dwObjectExtentX = 1;
1330  header.dwObjectExtentY = 1;
1331  header.dwSize = data_size;
1332  hr = IStream_Write(stream, &header, sizeof(header), NULL);
1333  ok(hr == S_OK, "Write error %#x\n", hr);
1334 
1335  hr = IStream_Write(stream, buf, data_size, NULL);
1336  ok(hr == S_OK, "Write error %#x\n", hr);
1337 
1338  IStream_Release(stream);
1339 
1340  hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj);
1341  /* FIXME: figure out stream format */
1342  if (fmt == CF_BITMAP && hr != S_OK)
1343  {
1344  IStorage_Release(stg);
1345  continue;
1346  }
1347  ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1348 
1349  hdc = CreateCompatibleDC(0);
1350  SetRect(&rc, 0, 0, 100, 100);
1351  hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc);
1352  DeleteDC(hdc);
1353  if (fmt == CF_METAFILEPICT)
1354  ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1355  else if (fmt == CF_ENHMETAFILE)
1356 todo_wine
1357  ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1358  else
1359  ok(hr == OLE_E_BLANK || hr == OLE_E_NOTRUNNING || hr == E_FAIL, "OleDraw should fail: %#x, cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1360 
1361  IUnknown_Release(obj);
1362  IStorage_Release(stg);
1363  }
1364  }
1365 }
1366 
1368 {
1369  CHECK_EXPECTED_METHOD("draw_continue");
1370  return TRUE;
1371 }
1372 
1374 {
1375  CHECK_EXPECTED_METHOD("draw_continue_false");
1376  return FALSE;
1377 }
1378 
1380 {
1382  {
1383  *ppv = iface;
1384  IAdviseSink_AddRef(iface);
1385  return S_OK;
1386  }
1387  *ppv = NULL;
1388  return E_NOINTERFACE;
1389 }
1390 
1392 {
1393  return 2;
1394 }
1395 
1397 {
1398  return 1;
1399 }
1400 
1401 
1403  IAdviseSink *iface,
1404  FORMATETC *pFormatetc,
1405  STGMEDIUM *pStgmed)
1406 {
1407  CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1408 }
1409 
1411  IAdviseSink *iface,
1412  DWORD dwAspect,
1413  LONG lindex)
1414 {
1415  CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1416 }
1417 
1419  IAdviseSink *iface,
1420  IMoniker *pmk)
1421 {
1422  CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1423 }
1424 
1426 {
1427  CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1428 }
1429 
1431 {
1432  CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1433 }
1434 
1435 static const IAdviseSinkVtbl AdviseSinkVtbl =
1436 {
1445 };
1446 
1448 
1450  IDataObject* iface,
1451  REFIID riid,
1452  void** ppvObject)
1453 {
1454  CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1455 
1457  {
1458  *ppvObject = iface;
1459  return S_OK;
1460  }
1461  *ppvObject = NULL;
1462  return S_OK;
1463 }
1464 
1466  IDataObject* iface)
1467 {
1468  CHECK_EXPECTED_METHOD("DataObject_AddRef");
1469  return 2;
1470 }
1471 
1473  IDataObject* iface)
1474 {
1475  CHECK_EXPECTED_METHOD("DataObject_Release");
1476  return 1;
1477 }
1478 
1479 static inline BOOL fmtetc_equal( const FORMATETC *a, const FORMATETC *b )
1480 {
1481  /* FIXME ptd */
1482  return a->cfFormat == b->cfFormat && a->dwAspect == b->dwAspect &&
1483  a->lindex == b->lindex && a->tymed == b->tymed;
1484 
1485 }
1486 
1487 static HRESULT WINAPI DataObject_GetData( IDataObject *iface, FORMATETC *fmt_in,
1488  STGMEDIUM *med )
1489 {
1490  FORMATETC *fmt;
1491 
1492  CHECK_EXPECTED_METHOD_FMT("DataObject_GetData", fmt_in);
1493 
1494  for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++)
1495  {
1496  if (fmtetc_equal( fmt_in, fmt ))
1497  {
1498  switch (fmt->cfFormat)
1499  {
1500  case CF_DIB:
1501  create_dib( med );
1502  return S_OK;
1503  case CF_BITMAP:
1504  create_bitmap( med );
1505  return S_OK;
1506  case CF_ENHMETAFILE:
1507  create_emf( med );
1508  return S_OK;
1509  case CF_TEXT:
1510  create_text( med );
1511  return S_OK;
1512  default:
1513  trace( "unhandled fmt %d\n", fmt->cfFormat );
1514  }
1515  }
1516  }
1517 
1518  return S_FALSE;
1519 }
1520 
1522  IDataObject* iface,
1523  LPFORMATETC pformatetc,
1524  STGMEDIUM* pmedium)
1525 {
1526  CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1527  return E_NOTIMPL;
1528 }
1529 
1530 static HRESULT WINAPI DataObject_QueryGetData( IDataObject *iface, FORMATETC *fmt_in )
1531 {
1532  FORMATETC *fmt;
1533 
1534  CHECK_EXPECTED_METHOD_FMT("DataObject_QueryGetData", fmt_in);
1535 
1536  for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++)
1537  if (fmtetc_equal( fmt_in, fmt )) return S_OK;
1538 
1539  return S_FALSE;
1540 }
1541 
1543  IDataObject* iface,
1544  LPFORMATETC pformatectIn,
1545  LPFORMATETC pformatetcOut)
1546 {
1547  CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1548  return E_NOTIMPL;
1549 }
1550 
1552  IDataObject* iface,
1553  LPFORMATETC pformatetc,
1554  STGMEDIUM* pmedium,
1555  BOOL fRelease)
1556 {
1557  CHECK_EXPECTED_METHOD("DataObject_SetData");
1558  return E_NOTIMPL;
1559 }
1560 
1562  IDataObject* iface,
1563  DWORD dwDirection,
1564  IEnumFORMATETC** ppenumFormatEtc)
1565 {
1566  CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1567  return E_NOTIMPL;
1568 }
1569 
1571  IDataObject* iface,
1572  FORMATETC* pformatetc,
1573  DWORD advf,
1574  IAdviseSink* pAdvSink,
1575  DWORD* pdwConnection)
1576 {
1577  STGMEDIUM stgmedium;
1578 
1579  CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1580  *pdwConnection = 1;
1581 
1582  if(advf & ADVF_PRIMEFIRST)
1583  {
1584  ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
1585  stgmedium.tymed = TYMED_HGLOBAL;
1586  U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
1587  stgmedium.pUnkForRelease = NULL;
1588  IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
1589  }
1590 
1591  return S_OK;
1592 }
1593 
1595  IDataObject* iface,
1596  DWORD dwConnection)
1597 {
1598  CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1599  return S_OK;
1600 }
1601 
1603  IDataObject* iface,
1604  IEnumSTATDATA** ppenumAdvise)
1605 {
1606  CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1607  return OLE_E_ADVISENOTSUPPORTED;
1608 }
1609 
1610 static IDataObjectVtbl DataObjectVtbl =
1611 {
1624 };
1625 
1627 
1629 {
1630  *ppv = NULL;
1631  if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1632  if (*ppv)
1633  {
1634  IUnknown_AddRef((IUnknown *)*ppv);
1635  return S_OK;
1636  }
1637  return E_NOINTERFACE;
1638 }
1639 
1641 {
1642  return 2;
1643 }
1644 
1646 {
1647  return 1;
1648 }
1649 
1650 static const IUnknownVtbl UnknownVtbl =
1651 {
1655 };
1656 
1658 
1659 static void check_enum_cache(IOleCache2 *cache, const STATDATA *expect, int num)
1660 {
1661  IEnumSTATDATA *enum_stat;
1662  STATDATA stat;
1663  HRESULT hr;
1664 
1665  hr = IOleCache2_EnumCache( cache, &enum_stat );
1666  ok( hr == S_OK, "got %08x\n", hr );
1667 
1668  while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK)
1669  {
1670  ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n",
1671  stat.formatetc.cfFormat, expect->formatetc.cfFormat );
1672  ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n",
1673  stat.formatetc.ptd, expect->formatetc.ptd );
1674  ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n",
1675  stat.formatetc.dwAspect, expect->formatetc.dwAspect );
1676  ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n",
1677  stat.formatetc.lindex, expect->formatetc.lindex );
1678  ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n",
1679  stat.formatetc.tymed, expect->formatetc.tymed );
1680  ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf );
1681  ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink );
1682  ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection );
1683  num--;
1684  expect++;
1685  }
1686 
1687  ok( num == 0, "incorrect number. num %d\n", num );
1688 
1689  IEnumSTATDATA_Release( enum_stat );
1690 }
1691 
1692 static void test_data_cache(void)
1693 {
1694  HRESULT hr;
1695  IOleCache2 *pOleCache;
1696  IOleCache *olecache;
1697  IStorage *pStorage;
1698  IUnknown *unk, *unk2;
1699  IPersistStorage *pPS;
1700  IViewObject *pViewObject;
1701  IOleCacheControl *pOleCacheControl;
1702  IDataObject *pCacheDataObject;
1703  FORMATETC fmtetc;
1704  STGMEDIUM stgmedium;
1705  DWORD dwConnection;
1706  DWORD dwFreeze;
1707  RECTL rcBounds;
1708  HDC hdcMem;
1709  CLSID clsid;
1710  char szSystemDir[MAX_PATH];
1711  WCHAR wszPath[MAX_PATH];
1712  static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1713 
1714  static const struct expected_method methods_cacheinitnew[] =
1715  {
1716  { "AdviseSink_OnViewChange", 0 },
1717  { "AdviseSink_OnViewChange", 0 },
1718  { "draw_continue", 1 },
1719  { "draw_continue_false", 1 },
1720  { "DataObject_DAdvise", 0 },
1721  { "DataObject_DAdvise", 0 },
1722  { "DataObject_DUnadvise", 0 },
1723  { "DataObject_DUnadvise", 0 },
1724  { NULL, 0 }
1725  };
1726  static const struct expected_method methods_cacheload[] =
1727  {
1728  { "AdviseSink_OnViewChange", 0 },
1729  { "draw_continue", 1 },
1730  { "draw_continue", 1 },
1731  { "draw_continue", 1 },
1732  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL} },
1733  { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_THUMBNAIL, -1, TYMED_GDI} },
1734  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_ICON, -1, TYMED_MFPICT} },
1735  { NULL, 0 }
1736  };
1737  static const struct expected_method methods_cachethenrun[] =
1738  {
1739  { "DataObject_DAdvise", 0 },
1740  { "DataObject_DAdvise", 0 },
1741  { "DataObject_DAdvise", 0 },
1742  { "DataObject_DAdvise", 0 },
1743  { "DataObject_DUnadvise", 0 },
1744  { "DataObject_DUnadvise", 0 },
1745  { "DataObject_DUnadvise", 0 },
1746  { "DataObject_DUnadvise", 0 },
1747  { NULL, 0 }
1748  };
1749 
1750  GetSystemDirectoryA(szSystemDir, ARRAY_SIZE(szSystemDir));
1751 
1752  expected_method_list = methods_cacheinitnew;
1753 
1754  fmtetc.cfFormat = CF_METAFILEPICT;
1755  fmtetc.dwAspect = DVASPECT_ICON;
1756  fmtetc.lindex = -1;
1757  fmtetc.ptd = NULL;
1758  fmtetc.tymed = TYMED_MFPICT;
1759 
1761  ok_ole_success(hr, "StgCreateDocfile");
1762 
1763  /* aggregation */
1764 
1765  /* requested is not IUnknown */
1766  hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache);
1767  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1768 
1769  hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1770  ok(hr == S_OK, "got 0x%08x\n", hr);
1771 
1772  hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1773  ok(hr == S_OK, "got 0x%08x\n", hr);
1774  hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1775  ok(hr == S_OK, "got 0x%08x\n", hr);
1776  ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1777  ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1778  IOleCache2_Release(pOleCache);
1779  IOleCache_Release(olecache);
1780  IUnknown_Release(unk);
1781 
1782  hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1783  ok(hr == S_OK, "got 0x%08x\n", hr);
1784  hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1785  ok(hr == S_OK, "got 0x%08x\n", hr);
1786  hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1787  ok(hr == S_OK, "got 0x%08x\n", hr);
1788  hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2);
1789  ok(hr == S_OK, "got 0x%08x\n", hr);
1790  ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1791  ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1792  ok(unk == unk2, "got %p, expected %p\n", unk2, unk);
1793  IUnknown_Release(unk2);
1794  IOleCache2_Release(pOleCache);
1795  IOleCache_Release(olecache);
1796  IUnknown_Release(unk);
1797 
1798  /* Test with new data */
1799 
1800  hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1801  ok_ole_success(hr, "CreateDataCache");
1802 
1803  hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1804  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1805  hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1806  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1807  hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1808  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1809 
1810  hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1811  ok_ole_success(hr, "IViewObject_SetAdvise");
1812 
1813  hr = IPersistStorage_InitNew(pPS, pStorage);
1814  ok_ole_success(hr, "IPersistStorage_InitNew");
1815 
1816  hr = IPersistStorage_IsDirty(pPS);
1817  ok_ole_success(hr, "IPersistStorage_IsDirty");
1818 
1819  hr = IPersistStorage_GetClassID(pPS, &clsid);
1820  ok_ole_success(hr, "IPersistStorage_GetClassID");
1821  ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1822 
1823  hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef);
1824  ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1825 
1826  /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1827  if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1828  {
1829  hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection);
1830  ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1831 
1832  hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL);
1833  ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1834  }
1835  else
1836  {
1837  skip("tests with NULL parameters will crash on NT4 and below\n");
1838  }
1839 
1840  for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1841  {
1842  int i;
1843  fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1844  for (i = 0; i < 7; i++)
1845  {
1846  fmtetc.tymed = 1 << i;
1847  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1848  if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1849  (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1850  (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1851  (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1852  ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1853  fmtetc.cfFormat, fmtetc.tymed, hr);
1854  else if (fmtetc.tymed == TYMED_HGLOBAL)
1856  broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1857  "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1858  fmtetc.cfFormat, fmtetc.tymed, hr);
1859  else
1860  ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1861  fmtetc.cfFormat, fmtetc.tymed, hr);
1862  if (SUCCEEDED(hr))
1863  {
1864  hr = IOleCache2_Uncache(pOleCache, dwConnection);
1865  ok_ole_success(hr, "IOleCache_Uncache");
1866  }
1867  }
1868  }
1869 
1870  fmtetc.cfFormat = CF_BITMAP;
1871  fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1872  fmtetc.tymed = TYMED_GDI;
1873  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1874  ok_ole_success(hr, "IOleCache_Cache");
1875 
1876  fmtetc.cfFormat = 0;
1877  fmtetc.dwAspect = DVASPECT_ICON;
1878  fmtetc.tymed = TYMED_MFPICT;
1879  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1880  ok_ole_success(hr, "IOleCache_Cache");
1881 
1882  MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, ARRAY_SIZE(wszPath));
1883  memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1884 
1885  fmtetc.cfFormat = CF_METAFILEPICT;
1886  stgmedium.tymed = TYMED_MFPICT;
1887  U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1888  LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0);
1889  stgmedium.pUnkForRelease = NULL;
1890 
1891  fmtetc.dwAspect = DVASPECT_CONTENT;
1892  hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1893  ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1894 
1895  fmtetc.dwAspect = DVASPECT_ICON;
1896  hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1897  ok_ole_success(hr, "IOleCache_SetData");
1898  ReleaseStgMedium(&stgmedium);
1899 
1900  hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1901  todo_wine {
1902  ok_ole_success(hr, "IViewObject_Freeze");
1903  hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1904  ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1905  }
1906 
1907  rcBounds.left = 0;
1908  rcBounds.top = 0;
1909  rcBounds.right = 100;
1910  rcBounds.bottom = 100;
1912 
1913  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1914  ok_ole_success(hr, "IViewObject_Draw");
1915 
1916  hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1917  ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1918 
1919  /* a NULL draw_continue fn ptr */
1920  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
1921  ok_ole_success(hr, "IViewObject_Draw");
1922 
1923  /* draw_continue that returns FALSE to abort drawing */
1924  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
1925  ok(hr == E_ABORT ||
1926  broken(hr == S_OK), /* win9x may skip the callbacks */
1927  "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
1928 
1929  DeleteDC(hdcMem);
1930 
1931  hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1932  ok_ole_success(hr, "IOleCacheControl_OnRun");
1933 
1934  hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1935  ok_ole_success(hr, "IPersistStorage_Save");
1936 
1937  hr = IPersistStorage_SaveCompleted(pPS, NULL);
1938  ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1939 
1940  hr = IPersistStorage_IsDirty(pPS);
1941  ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1942 
1943  IPersistStorage_Release(pPS);
1944  IViewObject_Release(pViewObject);
1945  IOleCache2_Release(pOleCache);
1946  IOleCacheControl_Release(pOleCacheControl);
1947 
1949 
1950  /* Test with loaded data */
1951  trace("Testing loaded data with CreateDataCache:\n");
1952  expected_method_list = methods_cacheload;
1953 
1954  hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1955  ok_ole_success(hr, "CreateDataCache");
1956 
1957  hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1958  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1959  hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1960  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1961 
1962  hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1963  ok_ole_success(hr, "IViewObject_SetAdvise");
1964 
1965  hr = IPersistStorage_Load(pPS, pStorage);
1966  ok_ole_success(hr, "IPersistStorage_Load");
1967 
1968  hr = IPersistStorage_IsDirty(pPS);
1969  ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1970 
1971  fmtetc.cfFormat = 0;
1972  fmtetc.dwAspect = DVASPECT_ICON;
1973  fmtetc.lindex = -1;
1974  fmtetc.ptd = NULL;
1975  fmtetc.tymed = TYMED_MFPICT;
1976  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1977  ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1978 
1979  rcBounds.left = 0;
1980  rcBounds.top = 0;
1981  rcBounds.right = 100;
1982  rcBounds.bottom = 100;
1984 
1985  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1986  ok_ole_success(hr, "IViewObject_Draw");
1987 
1988  hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1989  ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1990 
1991  /* unload the cached storage object, causing it to be reloaded */
1992  hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1993  ok_ole_success(hr, "IOleCache2_DiscardCache");
1994  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1995  ok_ole_success(hr, "IViewObject_Draw");
1996 
1997  /* unload the cached storage object, but don't allow it to be reloaded */
1998  hr = IPersistStorage_HandsOffStorage(pPS);
1999  ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
2000  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
2001  ok_ole_success(hr, "IViewObject_Draw");
2002  hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
2003  ok_ole_success(hr, "IOleCache2_DiscardCache");
2004  hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
2005  ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
2006 
2007  DeleteDC(hdcMem);
2008 
2009  hr = IOleCache2_InitCache(pOleCache, &DataObject);
2010  ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
2011 
2012  IPersistStorage_Release(pPS);
2013  IViewObject_Release(pViewObject);
2014  IOleCache2_Release(pOleCache);
2015 
2017 
2018  hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
2019  ok_ole_success(hr, "CreateDataCache");
2020 
2021  expected_method_list = methods_cachethenrun;
2022 
2023  hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
2024  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
2025  hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
2026  ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
2027 
2028  fmtetc.cfFormat = CF_METAFILEPICT;
2029  fmtetc.dwAspect = DVASPECT_CONTENT;
2030  fmtetc.tymed = TYMED_MFPICT;
2031 
2032  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
2033  ok_ole_success(hr, "IOleCache_Cache");
2034 
2035  hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
2036  ok(hr == OLE_E_BLANK, "got %08x\n", hr);
2037 
2038  fmtetc.cfFormat = cf_test_1;
2039  fmtetc.dwAspect = DVASPECT_CONTENT;
2040  fmtetc.tymed = TYMED_HGLOBAL;
2041 
2042  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
2043  ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
2044 
2045  hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
2046  ok(hr == OLE_E_BLANK, "got %08x\n", hr);
2047 
2048  fmtetc.cfFormat = cf_test_2;
2049  hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
2050  ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
2051 
2052  hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
2053  ok(hr == OLE_E_BLANK, "got %08x\n", hr);
2054 
2055  hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
2056  ok_ole_success(hr, "IOleCacheControl_OnRun");
2057 
2058  fmtetc.cfFormat = cf_test_3;
2059  hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
2060  ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
2061 
2062  fmtetc.cfFormat = cf_test_1;
2063  hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
2064  ok(hr == OLE_E_BLANK, "got %08x\n", hr);
2065 
2066  fmtetc.cfFormat = cf_test_2;
2067  hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
2068  ok(hr == S_OK, "got %08x\n", hr);
2069  ReleaseStgMedium(&stgmedium);
2070 
2071  fmtetc.cfFormat = cf_test_3;
2072  hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
2073  ok(hr == OLE_E_BLANK, "got %08x\n", hr);
2074 
2075  IOleCacheControl_Release(pOleCacheControl);
2076  IDataObject_Release(pCacheDataObject);
2077  IOleCache2_Release(pOleCache);
2078 
2080 
2081  IStorage_Release(pStorage);
2082 }
2083 
2084 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
2085 
2086 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
2087 static BYTE file_dib[] =
2088 {
2089  0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
2090  0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
2091  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
2092  0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
2093  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
2094  0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
2095  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
2096  0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2097 };
2098 
2100 {
2101  IStorage *stg;
2102  IStream *stm;
2103  HRESULT hr;
2104  ULONG written;
2105 
2107  ok( hr == S_OK, "got %08x\n", hr);
2108  hr = IStorage_SetClass( stg, &CLSID_Picture_Dib );
2109  ok( hr == S_OK, "got %08x\n", hr);
2110  hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm );
2111  ok( hr == S_OK, "got %08x\n", hr);
2112  if (num == 1) /* Set biXPelsPerMeter = 0 */
2113  {
2114  file_dib[0x26] = 0;
2115  file_dib[0x27] = 0;
2116  }
2117  hr = IStream_Write( stm, file_dib, sizeof(file_dib), &written );
2118  ok( hr == S_OK, "got %08x\n", hr);
2119  IStream_Release( stm );
2120  return stg;
2121 }
2122 
2124 {
2125  HRESULT hr;
2126  IUnknown *unk;
2127  IPersistStorage *persist;
2128  IDataObject *data;
2129  IViewObject2 *view;
2130  IStorage *stg;
2131  IOleCache2 *cache;
2132  FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
2133  STGMEDIUM med;
2134  CLSID cls;
2135  SIZEL sz;
2136  BYTE *ptr;
2137  BITMAPINFOHEADER expect_info;
2138  STATDATA enum_expect[] =
2139  {
2140  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2141  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2142  };
2143 
2144  hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk );
2145  ok( SUCCEEDED(hr), "got %08x\n", hr );
2146  hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist );
2147  ok( SUCCEEDED(hr), "got %08x\n", hr );
2148  hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data );
2149  ok( SUCCEEDED(hr), "got %08x\n", hr );
2150  hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view );
2151  ok( SUCCEEDED(hr), "got %08x\n", hr );
2152  hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache );
2153  ok( SUCCEEDED(hr), "got %08x\n", hr );
2154 
2155  stg = create_storage( num );
2156 
2157  hr = IPersistStorage_Load( persist, stg );
2158  ok( SUCCEEDED(hr), "got %08x\n", hr );
2159  IStorage_Release( stg );
2160 
2161  hr = IPersistStorage_GetClassID( persist, &cls );
2162  ok( SUCCEEDED(hr), "got %08x\n", hr );
2163  ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" );
2164 
2165  hr = IDataObject_GetData( data, &fmt, &med );
2166  ok( SUCCEEDED(hr), "got %08x\n", hr );
2167  ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed );
2168  ok( GlobalSize( U(med).hGlobal ) >= sizeof(dib) - sizeof(BITMAPFILEHEADER),
2169  "got %lu\n", GlobalSize( U(med).hGlobal ) );
2170  ptr = GlobalLock( U(med).hGlobal );
2171 
2172  expect_info = *(BITMAPINFOHEADER *)(file_dib + sizeof(BITMAPFILEHEADER));
2173  if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0)
2174  {
2175  HDC hdc = GetDC( 0 );
2176  expect_info.biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 );
2177  expect_info.biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 );
2178  ReleaseDC( 0, hdc );
2179  }
2180  ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" );
2181  ok( !memcmp( ptr + sizeof(expect_info), file_dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info),
2182  sizeof(file_dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" );
2183  GlobalUnlock( U(med).hGlobal );
2184  ReleaseStgMedium( &med );
2185 
2186  check_enum_cache( cache, enum_expect, 2 );
2187 
2188  hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
2189  ok( SUCCEEDED(hr), "got %08x\n", hr );
2190  if (num == 0)
2191  {
2192  ok( sz.cx == 1000, "got %d\n", sz.cx );
2193  ok( sz.cy == 250, "got %d\n", sz.cy );
2194  }
2195  else
2196  {
2197  HDC hdc = GetDC( 0 );
2198  LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
2199  LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );
2200  ok( sz.cx == x, "got %d %d\n", sz.cx, x );
2201  ok( sz.cy == y, "got %d %d\n", sz.cy, y );
2202 
2203  ReleaseDC( 0, hdc );
2204  }
2205 
2206  IOleCache2_Release( cache );
2207  IViewObject2_Release( view );
2208  IDataObject_Release( data );
2209  IPersistStorage_Release( persist );
2210  IUnknown_Release( unk );
2211 }
2212 
2213 static void check_bitmap_size( HBITMAP h, int cx, int cy )
2214 {
2215  BITMAP bm;
2216 
2217  GetObjectW( h, sizeof(bm), &bm );
2218  ok( bm.bmWidth == cx, "got %d expect %d\n", bm.bmWidth, cx );
2219  ok( bm.bmHeight == cy, "got %d expect %d\n", bm.bmHeight, cy );
2220 }
2221 
2222 static void check_dib_size( HGLOBAL h, int cx, int cy )
2223 {
2224  BITMAPINFO *info;
2225 
2226  info = GlobalLock( h );
2227  ok( info->bmiHeader.biWidth == cx, "got %d expect %d\n", info->bmiHeader.biWidth, cx );
2228  ok( info->bmiHeader.biHeight == cy, "got %d expect %d\n", info->bmiHeader.biHeight, cy );
2229  GlobalUnlock( h );
2230 }
2231 
2232 static void test_data_cache_cache(void)
2233 {
2234  HRESULT hr;
2235  IOleCache2 *cache;
2236  IDataObject *data;
2237  FORMATETC fmt;
2238  DWORD conn;
2239  STGMEDIUM med;
2240  STATDATA expect[] =
2241  {
2242  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
2243  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 },
2244  {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 },
2245  {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 }
2246  };
2247  STATDATA view_caching[] =
2248  {
2249  {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 },
2250  {{ 0, 0, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
2251  {{ 0, 0, DVASPECT_DOCPRINT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
2252  {{ CF_METAFILEPICT, 0, DVASPECT_ICON, -1, TYMED_MFPICT }, 0, NULL, 0 }
2253  };
2254 
2255  hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache );
2256  ok( hr == S_OK, "got %08x\n", hr );
2257 
2258  /* create a dib entry which will also create a bitmap entry too */
2259  fmt.cfFormat = CF_DIB;
2260  fmt.ptd = NULL;
2261  fmt.dwAspect = DVASPECT_CONTENT;
2262  fmt.lindex = -1;
2263  fmt.tymed = TYMED_HGLOBAL;
2264 
2265  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2266  ok( hr == S_OK, "got %08x\n", hr );
2267  ok( conn == 2, "got %d\n", conn );
2268  expect[0].dwConnection = conn;
2269  expect[1].dwConnection = conn;
2270 
2271  check_enum_cache( cache, expect, 2 );
2272 
2273  /* now try to add a bitmap */
2274  fmt.cfFormat = CF_BITMAP;
2275  fmt.tymed = TYMED_GDI;
2276 
2277  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2278  ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr );
2279 
2280  /* metafile */
2281  fmt.cfFormat = CF_METAFILEPICT;
2282  fmt.tymed = TYMED_MFPICT;
2283 
2284  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2285  ok( hr == S_OK, "got %08x\n", hr );
2286  ok( conn == 3, "got %d\n", conn );
2287  expect[2].dwConnection = conn;
2288 
2290 
2291  /* enhmetafile */
2292  fmt.cfFormat = CF_ENHMETAFILE;
2293  fmt.tymed = TYMED_ENHMF;
2294 
2295  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2296  ok( hr == S_OK, "got %08x\n", hr );
2297  ok( conn == 4, "got %d\n", conn );
2298  expect[3].dwConnection = conn;
2299 
2300  check_enum_cache( cache, expect, 4 );
2301 
2302  /* uncache everything */
2303  hr = IOleCache2_Uncache( cache, expect[3].dwConnection );
2304  ok( hr == S_OK, "got %08x\n", hr );
2305  hr = IOleCache2_Uncache( cache, expect[2].dwConnection );
2306  ok( hr == S_OK, "got %08x\n", hr );
2307  hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
2308  ok( hr == S_OK, "got %08x\n", hr );
2309  hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
2310  ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr );
2311 
2312  check_enum_cache( cache, expect, 0 );
2313 
2314  /* just create a bitmap entry which again adds both dib and bitmap */
2315  fmt.cfFormat = CF_BITMAP;
2316  fmt.tymed = TYMED_GDI;
2317 
2318  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2319  ok( hr == S_OK, "got %08x\n", hr );
2320 
2321  expect[0].dwConnection = conn;
2322  expect[1].dwConnection = conn;
2323 
2324  check_enum_cache( cache, expect, 2 );
2325 
2326  /* Try setting a 1x1 bitmap */
2327  hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data );
2328  ok( hr == S_OK, "got %08x\n", hr );
2329 
2330  create_bitmap( &med );
2331 
2332  hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
2333  ok( hr == S_OK, "got %08x\n", hr );
2334 
2335  hr = IDataObject_GetData( data, &fmt, &med );
2336  ok( hr == S_OK, "got %08x\n", hr );
2337  ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed );
2338  check_bitmap_size( U(med).hBitmap, 1, 1 );
2339  ReleaseStgMedium( &med );
2340 
2341  fmt.cfFormat = CF_DIB;
2342  fmt.tymed = TYMED_HGLOBAL;
2343  hr = IDataObject_GetData( data, &fmt, &med );
2344  ok( hr == S_OK, "got %08x\n", hr );
2345  ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed );
2346  check_dib_size( U(med).hGlobal, 1, 1 );
2347  ReleaseStgMedium( &med );
2348 
2349  /* Now set a 2x1 dib */
2350  fmt.cfFormat = CF_DIB;
2351  fmt.tymed = TYMED_HGLOBAL;
2352  create_dib( &med );
2353 
2354  hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
2355  ok( hr == S_OK, "got %08x\n", hr );
2356 
2357  fmt.cfFormat = CF_BITMAP;
2358  fmt.tymed = TYMED_GDI;
2359  hr = IDataObject_GetData( data, &fmt, &med );
2360  ok( hr == S_OK, "got %08x\n", hr );
2361  ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed );
2362  check_bitmap_size( U(med).hBitmap, 2, 1 );
2363  ReleaseStgMedium( &med );
2364 
2365  fmt.cfFormat = CF_DIB;
2366  fmt.tymed = TYMED_HGLOBAL;
2367  hr = IDataObject_GetData( data, &fmt, &med );
2368  ok( hr == S_OK, "got %08x\n", hr );
2369  ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed );
2370  check_dib_size( U(med).hGlobal, 2, 1 );
2371  ReleaseStgMedium( &med );
2372 
2373  /* uncache everything */
2374  hr = IOleCache2_Uncache( cache, conn );
2375  ok( hr == S_OK, "got %08x\n", hr );
2376 
2377  /* view caching */
2378  fmt.cfFormat = 0;
2379  fmt.tymed = TYMED_ENHMF;
2380  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2381  ok( hr == S_OK, "got %08x\n", hr );
2382  view_caching[0].dwConnection = conn;
2383 
2384  fmt.tymed = TYMED_HGLOBAL;
2385  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2386  ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr );
2387 
2388  fmt.dwAspect = DVASPECT_THUMBNAIL;
2389  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2390  ok( hr == S_OK, "got %08x\n", hr );
2391  view_caching[1].dwConnection = conn;
2392 
2393  fmt.dwAspect = DVASPECT_DOCPRINT;
2394  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2395  ok( hr == S_OK, "got %08x\n", hr );
2396  view_caching[2].dwConnection = conn;
2397 
2398  /* DVASPECT_ICON view cache gets mapped to CF_METAFILEPICT */
2399  fmt.dwAspect = DVASPECT_ICON;
2400  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2401  ok( hr == S_OK, "got %08x\n", hr );
2402  view_caching[3].dwConnection = conn;
2403 
2404  check_enum_cache( cache, view_caching, 4 );
2405 
2406  /* uncache everything */
2407  hr = IOleCache2_Uncache( cache, view_caching[3].dwConnection );
2408  ok( hr == S_OK, "got %08x\n", hr );
2409  hr = IOleCache2_Uncache( cache, view_caching[2].dwConnection );
2410  ok( hr == S_OK, "got %08x\n", hr );
2411  hr = IOleCache2_Uncache( cache, view_caching[1].dwConnection );
2412  ok( hr == S_OK, "got %08x\n", hr );
2413  hr = IOleCache2_Uncache( cache, view_caching[0].dwConnection );
2414  ok( hr == S_OK, "got %08x\n", hr );
2415 
2416  /* Only able to set cfFormat == CF_METAFILEPICT (or == 0, see above) for DVASPECT_ICON */
2417  fmt.dwAspect = DVASPECT_ICON;
2418  fmt.cfFormat = CF_DIB;
2419  fmt.tymed = TYMED_HGLOBAL;
2420  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2421  ok( hr == DV_E_FORMATETC, "got %08x\n", hr );
2422  fmt.cfFormat = CF_BITMAP;
2423  fmt.tymed = TYMED_GDI;
2424  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2425  ok( hr == DV_E_FORMATETC, "got %08x\n", hr );
2426  fmt.cfFormat = CF_ENHMETAFILE;
2427  fmt.tymed = TYMED_ENHMF;
2428  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2429  ok( hr == DV_E_FORMATETC, "got %08x\n", hr );
2430  fmt.cfFormat = CF_METAFILEPICT;
2431  fmt.tymed = TYMED_MFPICT;
2432  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2433  ok( hr == S_OK, "got %08x\n", hr );
2434 
2435  /* uncache everything */
2436  hr = IOleCache2_Uncache( cache, conn );
2437  ok( hr == S_OK, "got %08x\n", hr );
2438 
2439  /* tymed == 0 */
2440  fmt.cfFormat = CF_ENHMETAFILE;
2441  fmt.dwAspect = DVASPECT_CONTENT;
2442  fmt.tymed = 0;
2443  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2444  ok( hr == DV_E_TYMED, "got %08x\n", hr );
2445 
2446  IDataObject_Release( data );
2447  IOleCache2_Release( cache );
2448 
2449  /* tests for a static class cache */
2451 
2452  fmt.cfFormat = CF_DIB;
2453  fmt.dwAspect = DVASPECT_CONTENT;
2454  fmt.tymed = TYMED_HGLOBAL;
2455  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2456  ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr );
2457 
2458  /* aspect other than DVASPECT_CONTENT should fail */
2459  fmt.dwAspect = DVASPECT_THUMBNAIL;
2460  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2461  ok( FAILED(hr), "got %08x\n", hr );
2462 
2463  fmt.dwAspect = DVASPECT_DOCPRINT;
2464  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2465  ok( FAILED(hr), "got %08x\n", hr );
2466 
2467  /* try caching another clip format */
2468  fmt.cfFormat = CF_METAFILEPICT;
2469  fmt.dwAspect = DVASPECT_CONTENT;
2470  fmt.tymed = TYMED_MFPICT;
2471  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2472  ok( FAILED(hr), "got %08x\n", hr );
2473 
2474  /* As an exception, it's possible to add an icon aspect */
2475  fmt.cfFormat = CF_METAFILEPICT;
2476  fmt.dwAspect = DVASPECT_ICON;
2477  fmt.tymed = TYMED_MFPICT;
2478  hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2479  ok( hr == S_OK, "got %08x\n", hr );
2480 
2481  IOleCache2_Release( cache );
2482 }
2483 
2484 /* The CLSID_Picture_ classes automatically create appropriate cache entries */
2485 static void test_data_cache_init(void)
2486 {
2487  HRESULT hr;
2488  IOleCache2 *cache;
2489  IPersistStorage *persist;
2490  int i;
2491  CLSID clsid;
2492  static const STATDATA enum_expect[] =
2493  {
2494  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2495  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2496  {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 },
2497  {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 1 }
2498  };
2499  static const struct
2500  {
2501  const CLSID *clsid;
2502  int enum_start, enum_num;
2503  } data[] =
2504  {
2505  { &CLSID_NULL, 0, 0 },
2506  { &CLSID_WineTestOld, 0, 0 },
2507  { &CLSID_Picture_Dib, 0, 2 },
2508  { &CLSID_Picture_Metafile, 2, 1 },
2509  { &CLSID_Picture_EnhMetafile, 3, 1 }
2510  };
2511 
2512  for (i = 0; i < ARRAY_SIZE(data); i++)
2513  {
2514  hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache );
2515  ok( hr == S_OK, "got %08x\n", hr );
2516 
2517  check_enum_cache( cache, enum_expect + data[i].enum_start , data[i].enum_num );
2518 
2519  IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist );
2520  hr = IPersistStorage_GetClassID( persist, &clsid );
2521  ok( hr == S_OK, "got %08x\n", hr );
2522  ok( IsEqualCLSID( &clsid, data[i].clsid ), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid ),
2523  wine_dbgstr_guid( data[i].clsid ) );
2524 
2525  IPersistStorage_Release( persist );
2526  IOleCache2_Release( cache );
2527  }
2528 }
2529 
2530 static void test_data_cache_initnew(void)
2531 {
2532  HRESULT hr;
2533  IOleCache2 *cache;
2534  IPersistStorage *persist;
2535  IStorage *stg_dib, *stg_mf, *stg_wine;
2536  CLSID clsid;
2537  static const STATDATA initnew_expect[] =
2538  {
2539  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2540  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2541  };
2542  static const STATDATA initnew2_expect[] =
2543  {
2544  {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 },
2545  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2546  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 },
2547  };
2548  static const STATDATA initnew3_expect[] =
2549  {
2550  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2551  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2552  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2553  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 },
2554  {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 },
2555  };
2556  static const STATDATA initnew4_expect[] =
2557  {
2558  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2559  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 },
2560  {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 },
2561  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 4 },
2562  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 4 },
2563  };
2564 
2566  ok( hr == S_OK, "got %08x\n", hr);
2567  hr = IStorage_SetClass( stg_dib, &CLSID_Picture_Dib );
2568  ok( hr == S_OK, "got %08x\n", hr);
2569 
2571  ok( hr == S_OK, "got %08x\n", hr);
2572  hr = IStorage_SetClass( stg_mf, &CLSID_Picture_Metafile );
2573  ok( hr == S_OK, "got %08x\n", hr);
2574 
2576  ok( hr == S_OK, "got %08x\n", hr);
2577  hr = IStorage_SetClass( stg_wine, &CLSID_WineTestOld );
2578  ok( hr == S_OK, "got %08x\n", hr);
2579 
2581  ok( hr == S_OK, "got %08x\n", hr );
2582  IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist );
2583 
2584  hr = IPersistStorage_InitNew( persist, stg_dib );
2585  ok( hr == S_OK, "got %08x\n", hr);
2586 
2587  hr = IPersistStorage_GetClassID( persist, &clsid );
2588  ok( hr == S_OK, "got %08x\n", hr );
2589  ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2590 
2591  check_enum_cache( cache, initnew_expect, 2 );
2592 
2593  hr = IPersistStorage_InitNew( persist, stg_mf );
2594  ok( hr == CO_E_ALREADYINITIALIZED, "got %08x\n", hr);
2595 
2596  hr = IPersistStorage_HandsOffStorage( persist );
2597  ok( hr == S_OK, "got %08x\n", hr);
2598 
2599  hr = IPersistStorage_GetClassID( persist, &clsid );
2600  ok( hr == S_OK, "got %08x\n", hr );
2601  ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2602 
2603  hr = IPersistStorage_InitNew( persist, stg_mf );
2604  ok( hr == S_OK, "got %08x\n", hr);
2605 
2606  hr = IPersistStorage_GetClassID( persist, &clsid );
2607  ok( hr == S_OK, "got %08x\n", hr );
2609 
2610  check_enum_cache( cache, initnew2_expect, 3 );
2611 
2612  hr = IPersistStorage_HandsOffStorage( persist );
2613  ok( hr == S_OK, "got %08x\n", hr);
2614 
2615  hr = IPersistStorage_InitNew( persist, stg_dib );
2616  ok( hr == S_OK, "got %08x\n", hr);
2617 
2618  hr = IPersistStorage_GetClassID( persist, &clsid );
2619  ok( hr == S_OK, "got %08x\n", hr );
2620  ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2621 
2622  check_enum_cache( cache, initnew3_expect, 5 );
2623 
2624  hr = IPersistStorage_HandsOffStorage( persist );
2625  ok( hr == S_OK, "got %08x\n", hr);
2626 
2627  hr = IPersistStorage_InitNew( persist, stg_wine );
2628  ok( hr == S_OK, "got %08x\n", hr);
2629 
2630  hr = IPersistStorage_GetClassID( persist, &clsid );
2631  ok( hr == S_OK, "got %08x\n", hr );
2632  ok( IsEqualCLSID( &clsid, &CLSID_WineTestOld ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2633 
2634  check_enum_cache( cache, initnew4_expect, 5 );
2635 
2636  IStorage_Release( stg_wine );
2637  IStorage_Release( stg_mf );
2638  IStorage_Release( stg_dib );
2639 
2640  IPersistStorage_Release( persist );
2641  IOleCache2_Release( cache );
2642 }
2643 
2644 static void test_data_cache_updatecache( void )
2645 {
2646  HRESULT hr;
2647  IOleCache2 *cache;
2648  FORMATETC fmt;
2649  DWORD conn[4];
2650 
2651  static const struct expected_method methods_dib[] =
2652  {
2653  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2654  { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } },
2655  { NULL }
2656  };
2657 
2658  static const struct expected_method methods_dib_emf[] =
2659  {
2660  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2661  { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
2662  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2663  { NULL }
2664  };
2665  static const struct expected_method methods_dib_wmf[] =
2666  {
2667  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2668  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2669  { NULL }
2670  };
2671  static const struct expected_method methods_viewcache[] =
2672  {
2673  { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2674  { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
2675  { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2676  { "DataObject_QueryGetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } },
2677  { NULL }
2678  };
2679  static const struct expected_method methods_viewcache_with_dib[] =
2680  {
2681  { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2682  { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
2683  { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2684  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2685  { NULL }
2686  };
2687  static const struct expected_method methods_flags_all[] =
2688  {
2689  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2690  { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } },
2691  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2692  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2693  { NULL }
2694  };
2695  static const struct expected_method methods_flags_ifblank_1[] =
2696  {
2697  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2698  { NULL }
2699  };
2700  static const struct expected_method methods_flags_ifblank_2[] =
2701  {
2702  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2703  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2704  { NULL }
2705  };
2706  static const struct expected_method methods_flags_normal[] =
2707  {
2708  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2709  { NULL }
2710  };
2711  static const struct expected_method methods_initcache[] =
2712  {
2713  { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } },
2714  { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } },
2715  { NULL }
2716  };
2717  static const struct expected_method methods_empty[] =
2718  {
2719  { NULL }
2720  };
2721 
2722  static STATDATA view_cache[] =
2723  {
2724  {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }
2725  };
2726  static STATDATA view_cache_after_dib[] =
2727  {
2728  {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
2729  {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 }
2730  };
2731 
2732  static FORMATETC dib_fmt[] =
2733  {
2734  { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
2735  { 0 }
2736  };
2737 
2739  ok( hr == S_OK, "got %08x\n", hr );
2740 
2741  /* No cache slots */
2744 
2745  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2746  ok( hr == S_OK, "got %08x\n", hr );
2747 
2748  /* A dib cache slot */
2749  fmt.cfFormat = CF_DIB;
2750  fmt.ptd = NULL;
2751  fmt.dwAspect = DVASPECT_CONTENT;
2752  fmt.lindex = -1;
2753  fmt.tymed = TYMED_HGLOBAL;
2754 
2755  hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] );
2756  ok( hr == S_OK, "got %08x\n", hr );
2757 
2758  expected_method_list = methods_dib;
2759 
2760  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2761  ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr );
2762 
2764 
2765  /* Now with a dib available */
2766  g_dataobject_fmts = dib_fmt;
2767  expected_method_list = methods_dib;
2768 
2769  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2770  ok( hr == S_OK, "got %08x\n", hr );
2771 
2772  /* Add an EMF cache slot */
2773  fmt.cfFormat = CF_ENHMETAFILE;
2774  fmt.ptd = NULL;
2775  fmt.dwAspect = DVASPECT_CONTENT;
2776  fmt.lindex = -1;
2777  fmt.tymed = TYMED_ENHMF;
2778 
2779  hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] );
2780  ok( hr == S_OK, "got %08x\n", hr );
2781 
2782  g_dataobject_fmts = dib_fmt;
2783  expected_method_list = methods_dib_emf;
2784 
2785  /* Two slots to fill, only the dib will succeed */
2786  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2787  ok( hr == S_OK, "got %08x\n", hr );
2788 
2790 
2791  /* Replace the emf slot with a wmf */
2792  hr = IOleCache2_Uncache( cache, conn[1] );
2793  ok( hr == S_OK, "got %08x\n", hr );
2794 
2795  fmt.cfFormat = CF_METAFILEPICT;
2796  fmt.ptd = NULL;
2797  fmt.dwAspect = DVASPECT_CONTENT;
2798  fmt.lindex = -1;
2799  fmt.tymed = TYMED_MFPICT;
2800 
2801  hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] );
2802  ok( hr == S_OK, "got %08x\n", hr );
2803 
2804  g_dataobject_fmts = dib_fmt;
2805  expected_method_list = methods_dib_wmf;
2806 
2807  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2808  ok( hr == S_OK, "got %08x\n", hr );
2809 
2810  hr = IOleCache2_Uncache( cache, conn[1] );
2811  ok( hr == S_OK, "got %08x\n", hr );
2812  hr = IOleCache2_Uncache( cache, conn[0] );
2813  ok( hr == S_OK, "got %08x\n", hr );
2814 
2815  /* View caching */
2816  fmt.cfFormat = 0;
2817  fmt.ptd = NULL;
2818  fmt.dwAspect = DVASPECT_CONTENT;
2819  fmt.lindex = -1;
2820  fmt.tymed = TYMED_HGLOBAL;
2821 
2822  hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] );
2823  ok( hr == S_OK, "got %08x\n", hr );
2824  view_cache[0].dwConnection = conn[0];
2825 
2827  expected_method_list = methods_viewcache;
2828 
2829  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2830  ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr );
2831 
2833  check_enum_cache( cache, view_cache, 1 );
2834 
2835  g_dataobject_fmts = dib_fmt;
2836  expected_method_list = methods_viewcache_with_dib;
2837 
2838  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2839  ok( hr == S_OK, "got %08x\n", hr );
2840 
2842  view_cache_after_dib[0].dwConnection = view_cache_after_dib[1].dwConnection = view_cache[0].dwConnection;
2843  check_enum_cache( cache, view_cache_after_dib, 2 );
2844 
2845  hr = IOleCache2_Uncache( cache, conn[0] );
2846  ok( hr == S_OK, "got %08x\n", hr );
2847 
2848  /* Try some different flags */
2849 
2850  fmt.cfFormat = CF_DIB;
2851  fmt.ptd = NULL;
2852  fmt.dwAspect = DVASPECT_CONTENT;
2853  fmt.lindex = -1;
2854  fmt.tymed = TYMED_HGLOBAL;
2855 
2856  hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] );
2857  ok( hr == S_OK, "got %08x\n", hr );
2858 
2859  fmt.cfFormat = CF_ENHMETAFILE;
2860  fmt.ptd = NULL;
2861  fmt.dwAspect = DVASPECT_CONTENT;
2862  fmt.lindex = -1;
2863  fmt.tymed = TYMED_ENHMF;
2864 
2865  hr = IOleCache2_Cache( cache, &fmt, ADVF_NODATA, &conn[1] );
2866  ok( hr == S_OK, "got %08x\n", hr );
2867 
2868  fmt.cfFormat = CF_METAFILEPICT;
2869  fmt.ptd = NULL;
2870  fmt.dwAspect = DVASPECT_CONTENT;
2871  fmt.lindex = -1;
2872  fmt.tymed = TYMED_MFPICT;
2873 
2874  hr = IOleCache2_Cache( cache, &fmt, ADVFCACHE_ONSAVE, &conn[2] );
2875  ok( hr == S_OK, "got %08x\n", hr );
2876 
2877  g_dataobject_fmts = dib_fmt;
2878  expected_method_list = methods_flags_all;
2879 
2880  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2881 
2883 
2884  expected_method_list = methods_flags_all;
2885 
2886  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL );
2887  ok( hr == S_OK, "got %08x\n", hr );
2888 
2890 
2891  expected_method_list = methods_flags_ifblank_1;
2892 
2893  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL );
2894  ok( hr == S_OK, "got %08x\n", hr );
2895 
2897 
2898  hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE );
2899  ok( hr == S_OK, "got %08x\n", hr );
2900 
2901  expected_method_list = methods_flags_ifblank_2;
2902 
2903  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL );
2904  ok( hr == S_OK, "got %08x\n", hr );
2905 
2907 
2908  hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE );
2909  ok( hr == S_OK, "got %08x\n", hr );
2910 
2911  expected_method_list = methods_flags_all;
2912 
2913  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK | UPDFCACHE_NODATACACHE, NULL );
2914  ok( hr == S_OK, "got %08x\n", hr );
2915 
2917 
2918  expected_method_list = methods_empty;
2919 
2920  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL );
2921  ok( hr == S_OK, "got %08x\n", hr );
2922 
2924 
2925  hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE );
2926  ok( hr == S_OK, "got %08x\n", hr );
2927 
2928  expected_method_list = methods_flags_normal;
2929 
2930  hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL );
2931  ok( hr == S_OK, "got %08x\n", hr );
2932 
2934 
2935  expected_method_list = methods_initcache;
2936 
2937  hr = IOleCache2_InitCache( cache, &DataObject );
2938  ok( hr == S_OK, "got %08x\n", hr );
2939 
2941 
2942  IOleCache2_Release( cache );
2943 }
2944 
2945 static void test_default_handler(void)
2946 {
2947  HRESULT hr;
2948  IOleObject *pObject;
2949  IRunnableObject *pRunnableObject;
2950  IOleClientSite *pClientSite;
2951  IDataObject *pDataObject;
2952  SIZEL sizel;
2953  DWORD dwStatus;
2954  CLSID clsid;
2955  LPOLESTR pszUserType;
2957  DWORD dwAdvConn;
2958  IMoniker *pMoniker;
2959  FORMATETC fmtetc;
2960  IOleInPlaceObject *pInPlaceObj;
2961  IEnumOLEVERB *pEnumVerbs;
2962  DWORD dwRegister;
2963  static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
2964  static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2965  static const WCHAR wszDelim[] = {'!',0};
2966 
2967  static const struct expected_method methods_embeddinghelper[] =
2968  {
2969  { "OleObject_QueryInterface", 0 },
2970  { "OleObject_AddRef", 0 },
2971  { "OleObject_QueryInterface", 0 },
2972  { "OleObject_QueryInterface", TEST_TODO },
2973  { "OleObject_QueryInterface", 0 },
2974  { "OleObject_QueryInterface", 0 },
2975  { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
2976  { "OleObject_Release", TEST_TODO },
2977  { "WINE_EXTRA", TEST_OPTIONAL },
2978  { NULL, 0 }
2979  };
2980 
2981  hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
2982  ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2983 
2984  hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
2985  ok_ole_success(hr, "OleCreateDefaultHandler");
2986 
2987  hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
2988  ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
2989 
2990  hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
2991  ok_ole_success(hr, "IOleObject_Advise");
2992 
2993  hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2994  ok_ole_success(hr, "IOleObject_Close");
2995 
2996  /* FIXME: test IOleObject_EnumAdvise */
2997 
2998  hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
2999  ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
3000 
3001  hr = IOleObject_GetClientSite(pObject, &pClientSite);
3002  ok_ole_success(hr, "IOleObject_GetClientSite");
3003 
3004  hr = IOleObject_SetClientSite(pObject, pClientSite);
3005  ok_ole_success(hr, "IOleObject_SetClientSite");
3006 
3007  hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
3008  ok(hr == OLE_E_NOTRUNNING,
3009  "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
3010  hr);
3011 
3012  hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
3013  ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
3014  hr);
3015 
3016  hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
3017  ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
3018 
3019  hr = IOleObject_GetUserClassID(pObject, &clsid);
3020  ok_ole_success(hr, "IOleObject_GetUserClassID");
3021  ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
3022 
3023  hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
3024  todo_wine {
3025  ok_ole_success(hr, "IOleObject_GetUserType");
3026  ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
3027  }
3028 
3029  hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
3030  ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
3031 
3032  hr = IOleObject_IsUpToDate(pObject);
3033  ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
3034 
3035  palette.palNumEntries = 1;
3036  palette.palVersion = 2;
3037  memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
3038  hr = IOleObject_SetColorScheme(pObject, &palette);
3039  ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
3040 
3041  sizel.cx = sizel.cy = 0;
3042  hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
3043  ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
3044 
3045  hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
3046  ok_ole_success(hr, "IOleObject_SetHostNames");
3047 
3048  hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
3049  ok_ole_success(hr, "CreateItemMoniker");
3050  hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
3051  ok_ole_success(hr, "IOleObject_SetMoniker");
3052  IMoniker_Release(pMoniker);
3053 
3054  hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
3055  ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
3056 
3057  hr = IOleObject_Update(pObject);
3058  todo_wine
3059  ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
3060 
3061  hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
3062  ok_ole_success(hr, "IOleObject_QueryInterface");
3063 
3064  fmtetc.cfFormat = CF_TEXT;
3065  fmtetc.ptd = NULL;
3066  fmtetc.dwAspect = DVASPECT_CONTENT;
3067  fmtetc.lindex = -1;
3068  fmtetc.tymed = TYMED_NULL;
3069  hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
3070  ok_ole_success(hr, "IDataObject_DAdvise");
3071 
3072  fmtetc.cfFormat = CF_ENHMETAFILE;
3073  fmtetc.ptd = NULL;
3074  fmtetc.dwAspect = DVASPECT_CONTENT;
3075  fmtetc.lindex = -1;
3076  fmtetc.tymed = TYMED_ENHMF;
3077  hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
3078  ok_ole_success(hr, "IDataObject_DAdvise");
3079 
3080  fmtetc.cfFormat = CF_ENHMETAFILE;
3081  fmtetc.ptd = NULL;
3082  fmtetc.dwAspect = DVASPECT_CONTENT;
3083  fmtetc.lindex = -1;
3084  fmtetc.tymed = TYMED_ENHMF;
3085  hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
3086  ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
3087 
3088  fmtetc.cfFormat = CF_TEXT;
3089  fmtetc.ptd = NULL;
3090  fmtetc.dwAspect = DVASPECT_CONTENT;
3091  fmtetc.lindex = -1;
3092  fmtetc.tymed = TYMED_NULL;
3093  hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
3094  ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
3095 
3096  hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
3097  ok_ole_success(hr, "IOleObject_QueryInterface");
3098 
3099  hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
3100  ok_ole_success(hr, "IRunnableObject_SetContainedObject");
3101 
3102  hr = IRunnableObject_Run(pRunnableObject, NULL);
3103  ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
3104 
3105  hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
3106  ok_ole_success(hr, "IOleObject_Close");
3107 
3108  IRunnableObject_Release(pRunnableObject);
3109  IOleObject_Release(pObject);
3110 
3111  /* Test failure propagation from delegate ::QueryInterface */
3113  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
3114  ok_ole_success(hr, "CoRegisterClassObject");
3115  if(SUCCEEDED(hr))
3116  {
3117  expected_method_list = methods_embeddinghelper;
3119  &OleObjectCF, &IID_IOleObject, (void**)&pObject);
3120  ok_ole_success(hr, "OleCreateEmbeddingHelper");
3121  if(SUCCEEDED(hr))
3122  {
3123  IUnknown *punk;
3124 
3126  hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
3127  ok(hr == E_FAIL, "Got 0x%08x\n", hr);
3128 
3130  hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
3131  ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
3132 
3134  hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
3135  ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
3136 
3137  g_QIFailsWith = 0x87654321;
3138  hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
3139  ok(hr == 0x87654321, "Got 0x%08x\n", hr);
3140 
3141  IOleObject_Release(pObject);
3142  }
3143 
3145 
3146  hr = CoRevokeClassObject(dwRegister);
3147  ok_ole_success(hr, "CoRevokeClassObject");
3148  }
3149 }
3150 
3151 static void test_runnable(void)
3152 {
3153  static const struct expected_method methods_query_runnable[] =
3154  {
3155  { "OleObject_QueryInterface", 0 },
3156  { "OleObjectRunnable_AddRef", 0 },
3157  { "OleObjectRunnable_IsRunning", 0 },
3158  { "OleObjectRunnable_Release", 0 },
3159  { NULL, 0 }
3160  };
3161 
3162  static const struct expected_method methods_no_runnable[] =
3163  {
3164  { "OleObject_QueryInterface", 0 },
3165  { NULL, 0 }
3166  };
3167 
3168  BOOL ret;
3169  IOleObject *object = &OleObject;
3170 
3171  /* null argument */
3172  ret = OleIsRunning(NULL);
3173  ok(ret == FALSE, "got %d\n", ret);
3174 
3175  expected_method_list = methods_query_runnable;
3176  ret = OleIsRunning(object);
3177  ok(ret == TRUE, "Object should be running\n");
3179 
3180  g_isRunning = FALSE;
3181  expected_method_list = methods_query_runnable;
3182  ret = OleIsRunning(object);
3183  ok(ret == FALSE, "Object should not be running\n");
3185 
3186  g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */
3187  expected_method_list = methods_no_runnable;
3188  ret = OleIsRunning(object);
3189  ok(ret == TRUE, "Object without IRunnableObject should be running\n");
3191 
3192  g_isRunning = TRUE;
3193  g_showRunnable = TRUE;
3194 }
3195 
3196 
3198 {
3199  *ppv = NULL;
3200 
3201  if (IsEqualIID(riid, &IID_IUnknown) ||
3203  *ppv = iface;
3204  }
3205 
3206  if (*ppv)
3207  {
3208  IUnknown_AddRef((IUnknown *)*ppv);
3209  return S_OK;
3210  }
3211 
3212  return E_NOINTERFACE;
3213 }
3214 
3216 {
3217  return 2;
3218 }
3219 
3221 {
3222  return 1;
3223 }
3224 
3226 {
3227  ok(0, "unexpected\n");
3228  return E_NOTIMPL;
3229 }
3230 
3232 {
3233  ok(ctx == NULL, "got %p\n", ctx);
3234  return 0xdeadc0de;
3235 }
3236 
3238 {
3239  ok(0, "unexpected\n");
3240  return FALSE;
3241 }
3242 
3244  BOOL last_unlock_closes)
3245 {
3246  ok(0, "unexpected\n");
3247  return E_NOTIMPL;
3248 }
3249 
3251 {
3252  ok(0, "unexpected\n");
3253  return E_NOTIMPL;
3254 }
3255 
3256 static const IRunnableObjectVtbl oleruntestvtbl =
3257 {
3259  OleRun_AddRef,
3262  OleRun_Run,
3266 };
3267 
3269 
3270 static void test_OleRun(void)
3271 {
3272  HRESULT hr;
3273 
3274  /* doesn't support IRunnableObject */
3275  hr = OleRun(&unknown);
3276  ok(hr == S_OK, "OleRun failed 0x%08x\n", hr);
3277 
3279  ok(hr == 0xdeadc0de, "got 0x%08x\n", hr);
3280 }
3281 
3282 static void test_OleLockRunning(void)
3283 {
3284  HRESULT hr;
3285 
3287  ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
3288 }
3289 
3290 static void test_OleDraw(void)
3291 {
3292  HRESULT hr;
3293  RECT rect;
3294 
3295  hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL);
3296  ok(hr == S_OK, "got 0x%08x\n", hr);
3297 
3298  hr = OleDraw(NULL, 0, (HDC)0x1, NULL);
3299  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3300 
3301  hr = OleDraw(NULL, 0, (HDC)0x1, &rect);
3302  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3303 }
3304 
3305 static const WCHAR olepres0W[] = {2,'O','l','e','P','r','e','s','0','0','0',0};
3306 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0};
3311 
3313 {
3314  ok(0, "unexpected call to QueryInterface\n");
3315  return E_NOTIMPL;
3316 }
3317 
3319 {
3320  ok(0, "unexpected call to AddRef\n");
3321  return 2;
3322 }
3323 
3325 {
3326  ok(0, "unexpected call to Release\n");
3327  return 1;
3328 }
3329 
3330 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
3331 {
3332  ULARGE_INTEGER size = {{0}};
3333  LARGE_INTEGER pos = {{0}};
3334  HRESULT hr;
3335 
3336  if (!lstrcmpW(pwcsName, comp_objW))
3337  {
3338  CHECK_EXPECT(Storage_CreateStream_CompObj);
3339  *ppstm = comp_obj_stream;
3340 
3341  todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
3342  }
3343  else if (!lstrcmpW(pwcsName, olepres0W))
3344  {
3345  CHECK_EXPECT(Storage_CreateStream_OlePres);
3346  *ppstm = olepres_stream;
3347 
3348  todo_wine ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
3349  }
3350  else
3351  {
3352 todo_wine
3353  ok(0, "unexpected stream name %s\n", wine_dbgstr_w(pwcsName));
3354 #if 0 /* FIXME: return NULL once Wine is fixed */
3355  *ppstm = NULL;
3356  return E_NOTIMPL;
3357 #else
3358  *ppstm = contents_stream;
3359 #endif
3360  }
3361 
3362  ok(!reserved1, "reserved1 = %x\n", reserved1);
3363  ok(!reserved2, "reserved2 = %x\n", reserved2);
3364  ok(!!ppstm, "ppstm = NULL\n");
3365 
3366  IStream_AddRef(*ppstm);
3367  hr = IStream_Seek(*ppstm, pos, STREAM_SEEK_SET, NULL);
3368  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3369  hr = IStream_SetSize(*ppstm, size);
3370  ok(hr == S_OK, "IStream_SetSize returned %x\n", hr);
3371  return S_OK;
3372 }
3373 
3374 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
3375 {
3376  static const WCHAR ole1W[] = {1,'O','l','e',0};
3377 
3378  LARGE_INTEGER pos = {{0}};
3379  HRESULT hr;
3380 
3381  ok(!reserved1, "reserved1 = %p\n", reserved1);
3382  ok(!reserved2, "reserved2 = %x\n", reserved2);
3383  ok(!!ppstm, "ppstm = NULL\n");
3384 
3385  if(!lstrcmpW(pwcsName, comp_objW)) {
3386  CHECK_EXPECT2(Storage_OpenStream_CompObj);
3387  ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode);
3388 
3389  *ppstm = comp_obj_stream;
3390  IStream_AddRef(comp_obj_stream);
3391  hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3392  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3393  return S_OK;
3394  }else if(!lstrcmpW(pwcsName, ole1W)) {
3395  CHECK_EXPECT(Storage_OpenStream_Ole);
3396 
3397  if (!ole_stream)
3398  {
3399  ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READ), "grfMode = %x\n", grfMode);
3400 
3401  *ppstm = NULL;
3402  return STG_E_FILENOTFOUND;
3403  }
3404 
3405  ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
3406 
3407  *ppstm = ole_stream;
3408  IStream_AddRef(ole_stream);
3409  hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
3410  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3411  return S_OK;
3412 
3413  }else if(!lstrcmpW(pwcsName, olepres0W)) {
3414  CHECK_EXPECT(Storage_OpenStream_OlePres);
3415  ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
3416 
3417  *ppstm = olepres_stream;
3418  IStream_AddRef(olepres_stream);
3419  hr = IStream_Seek(olepres_stream, pos, STREAM_SEEK_SET, NULL);
3420  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3421  return S_OK;
3422  }
3423 
3424  ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName));
3425  return E_NOTIMPL;
3426 }
3427 
3428 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg)
3429 {
3430  ok(0, "unexpected call to CreateStorage\n");
3431  return E_NOTIMPL;
3432 }
3433 
3434 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
3435 {
3436  ok(0, "unexpected call to OpenStorage\n");
3437  return E_NOTIMPL;
3438 }
3439 
3440 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest)
3441 {
3442  ok(0, "unexpected call to CopyTo\n");
3443  return E_NOTIMPL;
3444 }
3445 
3446 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags)
3447 {
3448  ok(0, "unexpected call to MoveElementTo\n");
3449  return E_NOTIMPL;
3450 }
3451 
3452 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags)
3453 {
3454  ok(0, "unexpected call to Commit\n");
3455  return E_NOTIMPL;
3456 }
3457 
3459 {
3460  ok(0, "unexpected call to Revert\n");
3461  return E_NOTIMPL;
3462 }
3463 
3465 {
3466  ok(0, "unexpected call to EnumElements\n");
3467  return E_NOTIMPL;
3468 }
3469 
3470 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName)
3471 {
3472  char name[32];
3473  int stream_n, cmp;
3474 
3476  cmp = CompareStringW(LOCALE_NEUTRAL, 0, pwcsName, 8, olepres0W, 8);
3477  ok(cmp == CSTR_EQUAL,
3478  "unexpected call to DestroyElement(%s)\n", wine_dbgstr_w(pwcsName));
3479 
3480  WideCharToMultiByte(CP_ACP, 0, pwcsName, -1, name, sizeof(name), NULL, NULL);
3481  stream_n = atol(name + 8);
3482  if (stream_n <= Storage_DestroyElement_limit)
3483  return S_OK;
3484 
3485  return STG_E_FILENOTFOUND;
3486 }
3487 
3488 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName)
3489 {
3490  ok(0, "unexpected call to RenameElement\n");
3491  return E_NOTIMPL;
3492 }
3493 
3494 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
3495 {
3496  ok(0, "unexpected call to SetElementTimes\n");
3497  return E_NOTIMPL;
3498 }
3499 
3501 {
3503  ok(IsEqualIID(clsid, Storage_SetClass_CLSID), "expected %s, got %s\n",
3505  return S_OK;
3506 }
3507 
3508 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask)
3509 {
3510  ok(0, "unexpected call to SetStateBits\n");
3511  return E_NOTIMPL;
3512 }
3513 
3514 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag)
3515 {
3517  ok(pstatstg != NULL, "pstatstg = NULL\n");
3518  ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag);
3519 
3520  memset(pstatstg, 0, sizeof(STATSTG));
3521  pstatstg->type = STGTY_STORAGE;
3522  pstatstg->clsid = CLSID_WineTestOld;
3523  return S_OK;
3524 }
3525 
3526 static IStorageVtbl StorageVtbl =
3527 {
3545  Storage_Stat
3546 };
3547 
3549 
3550 static void test_OleDoAutoConvert(void)
3551 {
3552  static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
3553  static struct {
3554  DWORD reserved1;
3555  DWORD version;
3556  DWORD reserved2[5];
3557  DWORD ansi_user_type_len;
3558  DWORD ansi_clipboard_format_len;
3559  DWORD reserved3;
3560  DWORD unicode_marker;
3561  DWORD unicode_user_type_len;
3562  DWORD unicode_clipboard_format_len;
3563  DWORD reserved4;
3564  } comp_obj_data;
3565  static struct {
3566  DWORD version;
3567  DWORD flags;
3568  DWORD link_update_option;
3569  DWORD reserved1;
3570  DWORD reserved_moniker_stream_size;
3571  DWORD relative_source_moniker_stream_size;
3572  DWORD absolute_source_moniker_stream_size;
3573  DWORD clsid_indicator;
3574  CLSID clsid;
3575  DWORD reserved_display_name;
3576  DWORD reserved2;
3577  DWORD local_update_time;
3578  DWORD local_check_update_time;
3579  DWORD remote_update_time;
3580  } ole_data;
3581 
3582  LARGE_INTEGER pos = {{0}};
3583  WCHAR buf[39+6];
3584  DWORD i, ret;
3585  HKEY root;
3586  CLSID clsid;
3587  HRESULT hr;
3588 
3590  ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
3591  hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL);
3592  ok(hr == S_OK, "IStream_Write returned %x\n", hr);
3593 
3595  ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
3596  hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL);
3597  ok(hr == S_OK, "IStream_Write returned %x\n", hr);
3598 
3599  clsid = IID_WineTest;
3601  ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr);
3602  ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3603 
3604  if(0) /* crashes on Win7 */
3606 
3607  clsid = IID_WineTest;
3610  ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr);
3612  ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3613 
3614  lstrcpyW(buf, clsidW);
3616 
3619  if(ret != ERROR_SUCCESS) {
3620  win_skip("not enough permissions to create CLSID key (%u)\n", ret);
3621  return;
3622  }
3623 
3624  clsid = IID_WineTest;
3627  ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr);
3629  ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3630 
3632  ok_ole_success(hr, "OleSetAutoConvert");
3633 
3635  ok_ole_success(hr, "OleGetAutoConvert");
3636  ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid));
3637 
3638  clsid = IID_WineTest;
3640  SET_EXPECT(Storage_OpenStream_CompObj);
3642  SET_EXPECT(Storage_CreateStream_CompObj);
3643  SET_EXPECT(Storage_OpenStream_Ole);
3645  ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr);
3647  CHECK_CALLED(Storage_OpenStream_CompObj);
3649  CHECK_CALLED(Storage_CreateStream_CompObj);
3650  CHECK_CALLED(Storage_OpenStream_Ole);
3651  ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3652 
3653  hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3654  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3655  hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
3656  ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3657  ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
3658  ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
3659  ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
3660  ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
3661  ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
3662  ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
3663  ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
3664  ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
3665  ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
3666  ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
3667  ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
3668 
3669  hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
3670  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3671  hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL);
3672  ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3673  ok(ole_data.version == 0, "version = %x\n", ole_data.version);
3674  ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags);
3675  for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++)
3676  ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]);
3677 
3678  SET_EXPECT(Storage_OpenStream_Ole);
3680  ok(hr == S_OK, "SetConvertStg returned %x\n", hr);
3681  CHECK_CALLED(Storage_OpenStream_Ole);
3682 
3683  SET_EXPECT(Storage_OpenStream_CompObj);
3685  SET_EXPECT(Storage_CreateStream_CompObj);
3687  ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr);
3688  todo_wine CHECK_CALLED(Storage_OpenStream_CompObj);
3690  CHECK_CALLED(Storage_CreateStream_CompObj);
3691  hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3692  ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3693  hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
3694  ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3695  ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
3696  ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
3697  ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
3698  ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
3699  ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
3700  ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
3701  ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
3702  ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
3703  ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
3704  ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
3705  ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
3706 
3707  ret = IStream_Release(comp_obj_stream);
3708  ok(!ret, "comp_obj_stream was not freed\n");
3709  ret = IStream_Release(ole_stream);
3710  ok(!ret, "ole_stream was not freed\n");
3711 
3712  ret = RegDeleteKeyA(root, "AutoConvertTo");
3713  ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
3714  ret = RegDeleteKeyA(root, "");
3715  ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
3716  RegCloseKey(root);
3717 }
3718 
3719 /* 1x1 pixel bmp */
3720 static const unsigned char bmpimage[] =
3721 {
3722  0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,
3723  0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
3724  0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
3725  0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
3726  0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,
3727  0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
3728  0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,
3729  0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
3730  0x00,0x00
3731 };
3732 
3733 static const unsigned char mf_blank_bits[] =
3734 {
3735  0x01,0x00,0x09,0x00,0x00,0x03,0x0c,0x00,
3736  0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
3737  0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00
3738 };
3739 
3740 static void test_data_cache_save(void)
3741 {
3742  static const WCHAR contentsW[] = { 'C','o','n','t','e','n','t','s',0 };
3743  HRESULT hr;
3744  ILockBytes *ilb;
3745  IStorage *doc;
3746  IStream *stm;
3747  IOleCache2 *cache;
3748  IPersistStorage *stg;
3749  DWORD clipformat[2];
3751 
3752  hr = CreateILockBytesOnHGlobal(0, TRUE, &ilb);
3753  ok(hr == S_OK, "unexpected %#x\n", hr);
3755  ok(hr == S_OK, "unexpected %#x\n", hr);
3756 
3757  ILockBytes_Release(ilb);
3758 
3759  hr = IStorage_SetClass(doc, &CLSID_WineTest);
3760  ok(hr == S_OK, "unexpected %#x\n", hr);
3761 
3762  hr = IStorage_CreateStream(doc, contentsW, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3763  ok(hr == S_OK, "unexpected %#x\n", hr);
3764  hr = IStream_Write(stm, bmpimage, sizeof(bmpimage), NULL);
3765  ok(hr == S_OK, "unexpected %#x\n", hr);
3766  IStream_Release(stm);
3767 
3768  hr = IStorage_CreateStream(doc, olepres0W, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3769  ok(hr == S_OK, "unexpected %#x\n", hr);
3770 
3771  clipformat[0] = -1;
3772  clipformat[1] = CF_METAFILEPICT;
3773  hr = IStream_Write(stm, clipformat, sizeof(clipformat), NULL);
3774  ok(hr == S_OK, "unexpected %#x\n", hr);
3775 
3776  hdr.tdSize = sizeof(hdr.tdSize);
3777  hdr.dvAspect = DVASPECT_CONTENT;
3778  hdr.lindex = -1;
3779  hdr.advf = ADVF_PRIMEFIRST;
3780  hdr.unknown7 = 0;
3781  hdr.dwObjectExtentX = 0;
3782  hdr.dwObjectExtentY = 0;
3783  hdr.dwSize = sizeof(mf_blank_bits);
3784  hr = IStream_Write(stm, &hdr, sizeof(hdr), NULL);
3785  ok(hr == S_OK, "unexpected %#x\n", hr);
3786  hr = IStream_Write(stm, mf_blank_bits, sizeof(mf_blank_bits), NULL);
3787  ok(hr == S_OK, "unexpected %#x\n", hr);
3788 
3789  IStream_Release(stm);
3790 
3791  hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void **)&cache);
3792  ok(hr == S_OK, "unexpected %#x\n", hr);
3793  hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&stg);
3794  ok(hr == S_OK, "unexpected %#x\n", hr);
3795  hr = IPersistStorage_Load(stg, doc);
3796  ok(hr == S_OK, "unexpected %#x\n", hr);
3797 
3798  IStorage_Release(doc);
3799 
3800  hr = IPersistStorage_IsDirty(stg);
3801  ok(hr == S_FALSE, "unexpected %#x\n", hr);
3802 
3803  ole_stream = NULL;
3805  ok(hr == S_OK, "unexpected %#x\n", hr);
3806 
3807  /* FIXME: remove this stream once Wine is fixed */
3809  ok(hr == S_OK, "unexpected %#x\n", hr);
3810 
3811  SET_EXPECT(Storage_CreateStream_OlePres);
3812  SET_EXPECT(Storage_OpenStream_OlePres);
3813  SET_EXPECT(Storage_OpenStream_Ole);
3817  trace("IPersistStorage_Save:\n");
3818  hr = IPersistStorage_Save(stg, &Storage, FALSE);
3819  ok(hr == S_OK, "unexpected %#x\n", hr);
3820  CHECK_CALLED(Storage_CreateStream_OlePres);
3821 todo_wine
3822  CHECK_CALLED(Storage_OpenStream_OlePres);
3823 todo_wine
3824  CHECK_CALLED(Storage_OpenStream_Ole);
3825 todo_wine
3827 
3828  IStream_Release(olepres_stream);
3829  IStream_Release(contents_stream);
3830 
3831  IPersistStorage_Release(stg);
3832  IOleCache2_Release(cache);
3833 }
3834 
3835 #define MAX_STREAM 16
3836 
3838 {
3839  const char *name;
3840  int cf;
3841  DVASPECT dvAspect;
3842  ADVF advf;
3843  const void *data;
3844  size_t data_size;
3845 };
3846 
3848 {
3849  const CLSID *clsid;
3852 };
3853 
3854 static const struct storage_def stg_def_0 =
3855 {
3856  &CLSID_NULL, 1,
3857  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }}
3858 };
3859 static const struct storage_def stg_def_0_saved =
3860 {
3861  &CLSID_NULL, 0, {{ 0 }}
3862 };
3863 static const struct storage_def stg_def_1 =
3864 {
3865  &CLSID_NULL, 2,
3866  {{ "Contents", -1, 0, 0, NULL, 0 },
3867  { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3868 };
3869 static const struct storage_def stg_def_1_saved =
3870 {
3871  &CLSID_NULL, 1,
3872  {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3873 };
3874 static const struct storage_def stg_def_2 =
3875 {
3877  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) },
3878  { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3879 };
3880 static const struct storage_def stg_def_2_saved =
3881 {
3882  &CLSID_NULL, 1,
3883  {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3884 };
3885 static const struct storage_def stg_def_3 =
3886 {
3887  &CLSID_NULL, 5,
3888  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) },
3889  { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 },
3890  { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) },
3891  { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) },
3892  { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3893 };
3894 static const struct storage_def stg_def_3_saved =
3895 {
3896  &CLSID_NULL, 3,
3897  {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 },
3898  { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) },
3899  { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }}
3900 };
3901 static const struct storage_def stg_def_4 =
3902 {
3904  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) },
3905  { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 },
3906  { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) },
3907  { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) },
3908  { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3909 };
3910 static const struct storage_def stg_def_4_saved =
3911 {
3912  &CLSID_NULL, 1,
3913  {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3914 };
3915 static const struct storage_def stg_def_5 =
3916 {
3917  &CLSID_Picture_Dib, 5,
3918  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) },
3919  { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) },
3920  { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) },
3921  { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 },
3922  { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3923 };
3924 static const struct storage_def stg_def_5_saved =
3925 {
3926  &CLSID_NULL, 1,
3927  {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3928 };
3929 static const struct storage_def stg_def_6 =
3930 {
3932  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) },
3933  { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) },
3934  { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 },
3935  { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) },
3936  { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3937 };
3938 static const struct storage_def stg_def_6_saved =
3939 {
3940  &CLSID_NULL, 1,
3941  {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }}
3942 };
3943 static const struct storage_def stg_def_7 =
3944 {
3945  &CLSID_Picture_Dib, 1,
3946  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }}
3947 };
3948 static const struct storage_def stg_def_7_saved =
3949 {
3950  &CLSID_NULL, 0, {{ 0 }}
3951 };
3952 static const struct storage_def stg_def_8 =
3953 {
3955  {{ "Contents", -1, 0, 0, mf_blank_bits, sizeof(mf_blank_bits) }}
3956 };
3957 static const struct storage_def stg_def_8_saved =
3958 {
3959  &CLSID_NULL, 0, {{ 0 }}
3960 };
3961 static const struct storage_def stg_def_9 =
3962 {
3964  {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }}
3965 };
3966 static const struct storage_def stg_def_9_saved =
3967 {
3968  &CLSID_NULL, 0, {{ 0 }}
3969 };
3970 
3972 {
3973  HRESULT hr;
3974  ULONG bytes;
3975  int length, clipformat = -2;
3976 
3977  hr = IStream_Read(stream, &length, sizeof(length), &bytes);
3978  if (hr != S_OK || bytes != sizeof(length))
3979  return -2;
3980  if (length == 0)
3981  return 0;
3982  if (length == -1)
3983  {
3984  hr = IStream_Read(stream, &clipformat, sizeof(clipformat), &bytes);
3985  if (hr != S_OK || bytes != sizeof(clipformat))
3986  return -2;
3987  }
3988  else
3989  ok(0, "unhandled clipformat length %d\n", length);
3990 
3991  return clipformat;
3992 }
3993 
3994 static void check_storage_contents(IStorage *stg, const struct storage_def *stg_def,
3995  int *enumerated_streams, int *matched_streams)
3996 {
3997  HRESULT hr;
3998  IEnumSTATSTG *enumstg;
3999  IStream *stream;
4000  STATSTG stat;
4001  int i, seen_stream[MAX_STREAM] = { 0 };
4002 
4003  if (winetest_debug > 1)
4004  trace("check_storage_contents:\n=============================================\n");
4005 
4006  *enumerated_streams = 0;
4007  *matched_streams = 0;
4008 
4009  hr = IStorage_Stat(stg, &stat, STATFLAG_NONAME);
4010  ok(hr == S_OK, "unexpected %#x\n", hr);
4011  ok(IsEqualCLSID(stg_def->clsid, &stat.clsid), "expected %s, got %s\n",
4012  wine_dbgstr_guid(stg_def->clsid), wine_dbgstr_guid(&stat.clsid));
4013 
4014  hr = IStorage_EnumElements(stg, 0, NULL, 0, &enumstg);
4015  ok(hr == S_OK, "unexpected %#x\n", hr);
4016 
4017  for (;;)
4018  {
4019  ULONG bytes;
4020  int clipformat = -1;
4022  char name[32];
4023  BYTE data[1024];
4024 
4025  memset(&header, 0, sizeof(header));
4026 
4027  hr = IEnumSTATSTG_Next(enumstg, 1, &stat, NULL);
4028  if(hr == S_FALSE) break;
4029  ok(hr == S_OK, "unexpected %#x\n", hr);
4030 
4031  if (winetest_debug > 1)
4032  trace("name %s, type %u, size %d, clsid %s\n",
4033  wine_dbgstr_w(stat.pwcsName), stat.type, stat.cbSize.u.LowPart, wine_dbgstr_guid(&stat.clsid));
4034 
4035  ok(stat.type == STGTY_STREAM, "unexpected %#x\n", stat.type);
4036 
4037