1 /*
2  * Object Linking and Embedding Tests
3  *
4  * Copyright 2005 Robert Shearman
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "precomp.h"
22 
23 #ifndef __REACTOS__
24 #include "initguid.h"
25 
26 DEFINE_GUID(CLSID_Picture_Metafile,0x315,0,0,0xc0,0,0,0,0,0,0,0x46);
27 DEFINE_GUID(CLSID_Picture_Dib,0x316,0,0,0xc0,0,0,0,0,0,0,0x46);
28 DEFINE_GUID(CLSID_Picture_EnhMetafile,0x319,0,0,0xc0,0,0,0,0,0,0,0x46);
29 #endif
30 
31 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
32 
33 #define DEFINE_EXPECT(func) \
34     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 
36 #define SET_EXPECT(func) \
37     expect_ ## func = TRUE
38 
39 #define CHECK_EXPECT2(func) \
40     do { \
41         ok(expect_ ##func, "unexpected call " #func "\n"); \
42         called_ ## func = TRUE; \
43     }while(0)
44 
45 #define CHECK_EXPECT(func) \
46     do { \
47         CHECK_EXPECT2(func); \
48         expect_ ## func = FALSE; \
49     }while(0)
50 
51 #define CHECK_CALLED(func) \
52     do { \
53         ok(called_ ## func, "expected " #func "\n"); \
54         expect_ ## func = called_ ## func = FALSE; \
55     }while(0)
56 
57 DEFINE_EXPECT(Storage_Stat);
58 DEFINE_EXPECT(Storage_OpenStream_CompObj);
59 DEFINE_EXPECT(Storage_SetClass);
60 DEFINE_EXPECT(Storage_CreateStream_CompObj);
61 DEFINE_EXPECT(Storage_OpenStream_Ole);
62 
63 static IPersistStorage OleObjectPersistStg;
64 static IOleCache *cache;
65 static IRunnableObject *runnable;
66 
67 static const CLSID CLSID_WineTestOld =
68 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */
69     0x9474ba1a,
70     0x258b,
71     0x490b,
72     {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0}
73 };
74 
75 static const CLSID CLSID_WineTest =
76 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
77     0x9474ba1a,
78     0x258b,
79     0x490b,
80     {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
81 };
82 
83 static const IID IID_WineTest =
84 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
85     0x9474ba1a,
86     0x258b,
87     0x490b,
88     {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
89 };
90 
91 #define TEST_OPTIONAL 0x1
92 #define TEST_TODO     0x2
93 
94 struct expected_method
95 {
96     const char *method;
97     unsigned int flags;
98 };
99 
100 static const struct expected_method *expected_method_list;
101 static FORMATETC *g_expected_fetc = NULL;
102 
103 static BOOL g_showRunnable = TRUE;
104 static BOOL g_isRunning = TRUE;
105 static HRESULT g_GetMiscStatusFailsWith = S_OK;
106 static HRESULT g_QIFailsWith;
107 
108 static UINT cf_test_1, cf_test_2, cf_test_3;
109 
110 /****************************************************************************
111  * PresentationDataHeader
112  *
113  * This structure represents the header of the \002OlePresXXX stream in
114  * the OLE object storage.
115  */
116 typedef struct PresentationDataHeader
117 {
118     /* clipformat:
119      *  - standard clipformat:
120      *  DWORD length = 0xffffffff;
121      *  DWORD cfFormat;
122      *  - or custom clipformat:
123      *  DWORD length;
124      *  CHAR format_name[length]; (null-terminated)
125      */
126     DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
127     DVASPECT dvAspect;
128     DWORD lindex;
129     DWORD advf;
130     DWORD unknown7; /* 0 */
131     DWORD dwObjectExtentX;
132     DWORD dwObjectExtentY;
133     DWORD dwSize;
134 } PresentationDataHeader;
135 
136 #define CHECK_EXPECTED_METHOD(method_name) \
137     do { \
138         trace("%s\n", method_name); \
139         ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
140         if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
141         { \
142             todo_wine ok(0, "Too many method calls.\n"); \
143             break; \
144         } \
145         if (expected_method_list->method) \
146         { \
147             while (expected_method_list->flags & TEST_OPTIONAL && \
148                    strcmp(expected_method_list->method, method_name) != 0) \
149                 expected_method_list++; \
150             todo_wine_if (expected_method_list->flags & TEST_TODO) \
151                 ok(!strcmp(expected_method_list->method, method_name), \
152                    "Expected %s to be called instead of %s\n", \
153                    expected_method_list->method, method_name); \
154             expected_method_list++; \
155         } \
156     } while(0)
157 
158 #define CHECK_NO_EXTRA_METHODS() \
159     do { \
160         while (expected_method_list->flags & TEST_OPTIONAL) \
161             expected_method_list++; \
162         ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
163     } while (0)
164 
165 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
166 {
167     CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
168 
169     *ppv = NULL;
170 
171     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
172         *ppv = iface;
173     else if (IsEqualIID(riid, &IID_IPersistStorage))
174         *ppv = &OleObjectPersistStg;
175     else if (IsEqualIID(riid, &IID_IOleCache))
176         *ppv = cache;
177     else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
178         *ppv = runnable;
179     else if (IsEqualIID(riid, &IID_WineTest))
180         return g_QIFailsWith;
181 
182     if(*ppv) {
183         IUnknown_AddRef((IUnknown*)*ppv);
184         return S_OK;
185     }
186 
187     trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
188     return E_NOINTERFACE;
189 }
190 
191 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
192 {
193     CHECK_EXPECTED_METHOD("OleObject_AddRef");
194     return 2;
195 }
196 
197 static ULONG WINAPI OleObject_Release(IOleObject *iface)
198 {
199     CHECK_EXPECTED_METHOD("OleObject_Release");
200     return 1;
201 }
202 
203 static HRESULT WINAPI OleObject_SetClientSite
204     (
205         IOleObject *iface,
206         IOleClientSite *pClientSite
207     )
208 {
209     CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
210     return S_OK;
211 }
212 
213 static HRESULT WINAPI OleObject_GetClientSite
214     (
215         IOleObject *iface,
216         IOleClientSite **ppClientSite
217     )
218 {
219     CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
220     return E_NOTIMPL;
221 }
222 
223 static HRESULT WINAPI OleObject_SetHostNames
224     (
225         IOleObject *iface,
226         LPCOLESTR szContainerApp,
227         LPCOLESTR szContainerObj
228     )
229 {
230     CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
231     return S_OK;
232 }
233 
234 static HRESULT WINAPI OleObject_Close
235     (
236         IOleObject *iface,
237         DWORD dwSaveOption
238     )
239 {
240     CHECK_EXPECTED_METHOD("OleObject_Close");
241     return S_OK;
242 }
243 
244 static HRESULT WINAPI OleObject_SetMoniker
245     (
246         IOleObject *iface,
247         DWORD dwWhichMoniker,
248         IMoniker *pmk
249     )
250 {
251     CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
252     return S_OK;
253 }
254 
255 static HRESULT WINAPI OleObject_GetMoniker
256     (
257         IOleObject *iface,
258         DWORD dwAssign,
259         DWORD dwWhichMoniker,
260         IMoniker **ppmk
261     )
262 {
263     CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
264     return S_OK;
265 }
266 
267 static HRESULT WINAPI OleObject_InitFromData
268     (
269         IOleObject *iface,
270         IDataObject *pDataObject,
271         BOOL fCreation,
272         DWORD dwReserved
273     )
274 {
275     CHECK_EXPECTED_METHOD("OleObject_InitFromData");
276     return S_OK;
277 }
278 
279 static HRESULT WINAPI OleObject_GetClipboardData
280     (
281         IOleObject *iface,
282         DWORD dwReserved,
283         IDataObject **ppDataObject
284     )
285 {
286     CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
287     return E_NOTIMPL;
288 }
289 
290 static HRESULT WINAPI OleObject_DoVerb
291     (
292         IOleObject *iface,
293         LONG iVerb,
294         LPMSG lpmsg,
295         IOleClientSite *pActiveSite,
296         LONG lindex,
297         HWND hwndParent,
298         LPCRECT lprcPosRect
299     )
300 {
301     CHECK_EXPECTED_METHOD("OleObject_DoVerb");
302     return S_OK;
303 }
304 
305 static HRESULT WINAPI OleObject_EnumVerbs
306     (
307         IOleObject *iface,
308         IEnumOLEVERB **ppEnumOleVerb
309     )
310 {
311     CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
312     return E_NOTIMPL;
313 }
314 
315 static HRESULT WINAPI OleObject_Update
316     (
317         IOleObject *iface
318     )
319 {
320     CHECK_EXPECTED_METHOD("OleObject_Update");
321     return S_OK;
322 }
323 
324 static HRESULT WINAPI OleObject_IsUpToDate
325     (
326         IOleObject *iface
327     )
328 {
329     CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
330     return S_OK;
331 }
332 
333 static HRESULT WINAPI OleObject_GetUserClassID
334 (
335     IOleObject *iface,
336     CLSID *pClsid
337 )
338 {
339     CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
340     return E_NOTIMPL;
341 }
342 
343 static HRESULT WINAPI OleObject_GetUserType
344 (
345     IOleObject *iface,
346     DWORD dwFormOfType,
347     LPOLESTR *pszUserType
348 )
349 {
350     CHECK_EXPECTED_METHOD("OleObject_GetUserType");
351     return E_NOTIMPL;
352 }
353 
354 static HRESULT WINAPI OleObject_SetExtent
355 (
356     IOleObject *iface,
357     DWORD dwDrawAspect,
358     SIZEL *psizel
359 )
360 {
361     CHECK_EXPECTED_METHOD("OleObject_SetExtent");
362     return S_OK;
363 }
364 
365 static HRESULT WINAPI OleObject_GetExtent
366 (
367     IOleObject *iface,
368     DWORD dwDrawAspect,
369     SIZEL *psizel
370 )
371 {
372     CHECK_EXPECTED_METHOD("OleObject_GetExtent");
373     return E_NOTIMPL;
374 }
375 
376 static HRESULT WINAPI OleObject_Advise
377 (
378     IOleObject *iface,
379     IAdviseSink *pAdvSink,
380     DWORD *pdwConnection
381 )
382 {
383     CHECK_EXPECTED_METHOD("OleObject_Advise");
384     return S_OK;
385 }
386 
387 static HRESULT WINAPI OleObject_Unadvise
388 (
389     IOleObject *iface,
390     DWORD dwConnection
391 )
392 {
393     CHECK_EXPECTED_METHOD("OleObject_Unadvise");
394     return S_OK;
395 }
396 
397 static HRESULT WINAPI OleObject_EnumAdvise
398 (
399     IOleObject *iface,
400     IEnumSTATDATA **ppenumAdvise
401 )
402 {
403     CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
404     return E_NOTIMPL;
405 }
406 
407 static HRESULT WINAPI OleObject_GetMiscStatus
408 (
409     IOleObject *iface,
410     DWORD aspect,
411     DWORD *pdwStatus
412 )
413 {
414     CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
415 
416     ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect);
417 
418     if (g_GetMiscStatusFailsWith == S_OK)
419     {
420         *pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
421         return S_OK;
422     }
423     else
424     {
425         *pdwStatus = 0x1234;
426         return g_GetMiscStatusFailsWith;
427     }
428 }
429 
430 static HRESULT WINAPI OleObject_SetColorScheme
431 (
432     IOleObject *iface,
433     LOGPALETTE *pLogpal
434 )
435 {
436     CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
437     return E_NOTIMPL;
438 }
439 
440 static const IOleObjectVtbl OleObjectVtbl =
441 {
442     OleObject_QueryInterface,
443     OleObject_AddRef,
444     OleObject_Release,
445     OleObject_SetClientSite,
446     OleObject_GetClientSite,
447     OleObject_SetHostNames,
448     OleObject_Close,
449     OleObject_SetMoniker,
450     OleObject_GetMoniker,
451     OleObject_InitFromData,
452     OleObject_GetClipboardData,
453     OleObject_DoVerb,
454     OleObject_EnumVerbs,
455     OleObject_Update,
456     OleObject_IsUpToDate,
457     OleObject_GetUserClassID,
458     OleObject_GetUserType,
459     OleObject_SetExtent,
460     OleObject_GetExtent,
461     OleObject_Advise,
462     OleObject_Unadvise,
463     OleObject_EnumAdvise,
464     OleObject_GetMiscStatus,
465     OleObject_SetColorScheme
466 };
467 
468 static IOleObject OleObject = { &OleObjectVtbl };
469 
470 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
471 {
472     trace("OleObjectPersistStg_QueryInterface\n");
473     return IOleObject_QueryInterface(&OleObject, riid, ppv);
474 }
475 
476 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
477 {
478     CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
479     return 2;
480 }
481 
482 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
483 {
484     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
485     return 1;
486 }
487 
488 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
489 {
490     CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
491     return E_NOTIMPL;
492 }
493 
494 static HRESULT WINAPI OleObjectPersistStg_IsDirty
495 (
496     IPersistStorage *iface
497 )
498 {
499     CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
500     return S_OK;
501 }
502 
503 static HRESULT WINAPI OleObjectPersistStg_InitNew
504 (
505     IPersistStorage *iface,
506     IStorage *pStg
507 )
508 {
509     CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
510     return S_OK;
511 }
512 
513 static HRESULT WINAPI OleObjectPersistStg_Load
514 (
515     IPersistStorage *iface,
516     IStorage *pStg
517 )
518 {
519     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
520     return S_OK;
521 }
522 
523 static HRESULT WINAPI OleObjectPersistStg_Save
524 (
525     IPersistStorage *iface,
526     IStorage *pStgSave,
527     BOOL fSameAsLoad
528 )
529 {
530     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
531     return S_OK;
532 }
533 
534 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
535 (
536     IPersistStorage *iface,
537     IStorage *pStgNew
538 )
539 {
540     CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
541     return S_OK;
542 }
543 
544 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
545 (
546     IPersistStorage *iface
547 )
548 {
549     CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
550     return S_OK;
551 }
552 
553 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
554 {
555     OleObjectPersistStg_QueryInterface,
556     OleObjectPersistStg_AddRef,
557     OleObjectPersistStg_Release,
558     OleObjectPersistStg_GetClassId,
559     OleObjectPersistStg_IsDirty,
560     OleObjectPersistStg_InitNew,
561     OleObjectPersistStg_Load,
562     OleObjectPersistStg_Save,
563     OleObjectPersistStg_SaveCompleted,
564     OleObjectPersistStg_HandsOffStorage
565 };
566 
567 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
568 
569 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
570 {
571     return IOleObject_QueryInterface(&OleObject, riid, ppv);
572 }
573 
574 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
575 {
576     CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
577     return 2;
578 }
579 
580 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
581 {
582     CHECK_EXPECTED_METHOD("OleObjectCache_Release");
583     return 1;
584 }
585 
586 static HRESULT WINAPI OleObjectCache_Cache
587 (
588     IOleCache *iface,
589     FORMATETC *pformatetc,
590     DWORD advf,
591     DWORD *pdwConnection
592 )
593 {
594     CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
595     if (g_expected_fetc) {
596         ok(pformatetc != NULL, "pformatetc should not be NULL\n");
597         if (pformatetc) {
598             ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
599                     "cfFormat: %x\n", pformatetc->cfFormat);
600             ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
601                     "ptd: %p\n", pformatetc->ptd);
602             ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
603                     "dwAspect: %x\n", pformatetc->dwAspect);
604             ok(pformatetc->lindex == g_expected_fetc->lindex,
605                     "lindex: %x\n", pformatetc->lindex);
606             ok(pformatetc->tymed == g_expected_fetc->tymed,
607                     "tymed: %x\n", pformatetc->tymed);
608         }
609     } else
610         ok(pformatetc == NULL, "pformatetc should be NULL\n");
611     return S_OK;
612 }
613 
614 static HRESULT WINAPI OleObjectCache_Uncache
615 (
616     IOleCache *iface,
617     DWORD dwConnection
618 )
619 {
620     CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
621     return S_OK;
622 }
623 
624 static HRESULT WINAPI OleObjectCache_EnumCache
625 (
626     IOleCache *iface,
627     IEnumSTATDATA **ppenumSTATDATA
628 )
629 {
630     CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
631     return S_OK;
632 }
633 
634 
635 static HRESULT WINAPI OleObjectCache_InitCache
636 (
637     IOleCache *iface,
638     IDataObject *pDataObject
639 )
640 {
641     CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
642     return S_OK;
643 }
644 
645 
646 static HRESULT WINAPI OleObjectCache_SetData
647 (
648     IOleCache *iface,
649     FORMATETC *pformatetc,
650     STGMEDIUM *pmedium,
651     BOOL fRelease
652 )
653 {
654     CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
655     return S_OK;
656 }
657 
658 
659 static const IOleCacheVtbl OleObjectCacheVtbl =
660 {
661     OleObjectCache_QueryInterface,
662     OleObjectCache_AddRef,
663     OleObjectCache_Release,
664     OleObjectCache_Cache,
665     OleObjectCache_Uncache,
666     OleObjectCache_EnumCache,
667     OleObjectCache_InitCache,
668     OleObjectCache_SetData
669 };
670 
671 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
672 
673 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
674 {
675     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
676     {
677         *ppv = iface;
678         IClassFactory_AddRef(iface);
679         return S_OK;
680     }
681     *ppv = NULL;
682     return E_NOINTERFACE;
683 }
684 
685 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
686 {
687     return 2;
688 }
689 
690 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
691 {
692     return 1;
693 }
694 
695 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
696 {
697     return IOleObject_QueryInterface(&OleObject, riid, ppv);
698 }
699 
700 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
701 {
702     return S_OK;
703 }
704 
705 static const IClassFactoryVtbl OleObjectCFVtbl =
706 {
707     OleObjectCF_QueryInterface,
708     OleObjectCF_AddRef,
709     OleObjectCF_Release,
710     OleObjectCF_CreateInstance,
711     OleObjectCF_LockServer
712 };
713 
714 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
715 
716 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
717 {
718     return IOleObject_QueryInterface(&OleObject, riid, ppv);
719 }
720 
721 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
722 {
723     CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
724     return 2;
725 }
726 
727 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
728 {
729     CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
730     return 1;
731 }
732 
733 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
734     IRunnableObject *iface,
735     LPCLSID lpClsid)
736 {
737     CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
738     return E_NOTIMPL;
739 }
740 
741 static HRESULT WINAPI OleObjectRunnable_Run(
742     IRunnableObject *iface,
743     LPBINDCTX pbc)
744 {
745     CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
746     return S_OK;
747 }
748 
749 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
750 {
751     CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
752     return g_isRunning;
753 }
754 
755 static HRESULT WINAPI OleObjectRunnable_LockRunning(
756     IRunnableObject *iface,
757     BOOL fLock,
758     BOOL fLastUnlockCloses)
759 {
760     CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
761     return S_OK;
762 }
763 
764 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
765     IRunnableObject *iface,
766     BOOL fContained)
767 {
768     CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
769     return S_OK;
770 }
771 
772 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
773 {
774     OleObjectRunnable_QueryInterface,
775     OleObjectRunnable_AddRef,
776     OleObjectRunnable_Release,
777     OleObjectRunnable_GetRunningClass,
778     OleObjectRunnable_Run,
779     OleObjectRunnable_IsRunning,
780     OleObjectRunnable_LockRunning,
781     OleObjectRunnable_SetContainedObject
782 };
783 
784 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
785 
786 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
787 
788 static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj)
789 {
790     if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject))
791     {
792         *obj = iface;
793         return S_OK;
794     }
795 
796     *obj = NULL;
797     return E_NOINTERFACE;
798 }
799 
800 static ULONG WINAPI viewobject_AddRef(IViewObject *iface)
801 {
802     return 2;
803 }
804 
805 static ULONG WINAPI viewobject_Release(IViewObject *iface)
806 {
807     return 1;
808 }
809 
810 static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index,
811     void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw,
812     LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue),
813     ULONG_PTR dwContinue)
814 {
815     ok(index == -1, "index=%d\n", index);
816     return S_OK;
817 }
818 
819 static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index,
820     void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset)
821 {
822     ok(0, "unexpected call GetColorSet\n");
823     return E_NOTIMPL;
824 }
825 
826 static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index,
827     void *aspect, DWORD *freeze)
828 {
829     ok(0, "unexpected call Freeze\n");
830     return E_NOTIMPL;
831 }
832 
833 static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze)
834 {
835     ok(0, "unexpected call Unfreeze\n");
836     return E_NOTIMPL;
837 }
838 
839 static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink)
840 {
841     ok(0, "unexpected call SetAdvise\n");
842     return E_NOTIMPL;
843 }
844 
845 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf,
846     IAdviseSink **sink)
847 {
848     ok(0, "unexpected call GetAdvise\n");
849     return E_NOTIMPL;
850 }
851 
852 static const struct IViewObjectVtbl viewobjectvtbl = {
853     viewobject_QueryInterface,
854     viewobject_AddRef,
855     viewobject_Release,
856     viewobject_Draw,
857     viewobject_GetColorSet,
858     viewobject_Freeze,
859     viewobject_Unfreeze,
860     viewobject_SetAdvise,
861     viewobject_GetAdvise
862 };
863 
864 static IViewObject viewobject = { &viewobjectvtbl };
865 
866 static void test_OleCreate(IStorage *pStorage)
867 {
868     HRESULT hr;
869     IOleObject *pObject;
870     FORMATETC formatetc;
871     static const struct expected_method methods_olerender_none[] =
872     {
873         { "OleObject_QueryInterface", 0 },
874         { "OleObject_AddRef", 0 },
875         { "OleObject_QueryInterface", 0 },
876         { "OleObject_AddRef", TEST_OPTIONAL },
877         { "OleObject_Release", TEST_OPTIONAL },
878         { "OleObject_QueryInterface", TEST_OPTIONAL },
879         { "OleObjectPersistStg_AddRef", 0 },
880         { "OleObjectPersistStg_InitNew", 0 },
881         { "OleObjectPersistStg_Release", 0 },
882         { "OleObject_Release", 0 },
883         { "OleObject_Release", TEST_OPTIONAL },
884         { NULL, 0 }
885     };
886     static const struct expected_method methods_olerender_draw[] =
887     {
888         { "OleObject_QueryInterface", 0 },
889         { "OleObject_AddRef", 0 },
890         { "OleObject_QueryInterface", 0 },
891         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
892         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
893         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
894         { "OleObjectPersistStg_AddRef", 0 },
895         { "OleObjectPersistStg_InitNew", 0 },
896         { "OleObjectPersistStg_Release", 0 },
897         { "OleObject_QueryInterface", 0 },
898         { "OleObjectRunnable_AddRef", 0 },
899         { "OleObjectRunnable_Run", 0 },
900         { "OleObjectRunnable_Release", 0 },
901         { "OleObject_QueryInterface", 0 },
902         { "OleObjectCache_AddRef", 0 },
903         { "OleObjectCache_Cache", 0 },
904         { "OleObjectCache_Release", 0 },
905         { "OleObject_Release", 0 },
906         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
907         { NULL, 0 }
908     };
909     static const struct expected_method methods_olerender_draw_with_site[] =
910     {
911         { "OleObject_QueryInterface", 0 },
912         { "OleObject_AddRef", 0 },
913         { "OleObject_QueryInterface", 0 },
914         { "OleObject_AddRef", 0 },
915         { "OleObject_GetMiscStatus", 0 },
916         { "OleObject_QueryInterface", 0 },
917         { "OleObjectPersistStg_AddRef", 0 },
918         { "OleObjectPersistStg_InitNew", 0 },
919         { "OleObjectPersistStg_Release", 0 },
920         { "OleObject_SetClientSite", 0 },
921         { "OleObject_Release", 0 },
922         { "OleObject_QueryInterface", 0 },
923         { "OleObjectRunnable_AddRef", 0 },
924         { "OleObjectRunnable_Run", 0 },
925         { "OleObjectRunnable_Release", 0 },
926         { "OleObject_QueryInterface", 0 },
927         { "OleObjectCache_AddRef", 0 },
928         { "OleObjectCache_Cache", 0 },
929         { "OleObjectCache_Release", 0 },
930         { "OleObject_Release", 0 },
931         { NULL, 0 }
932     };
933     static const struct expected_method methods_olerender_format[] =
934     {
935         { "OleObject_QueryInterface", 0 },
936         { "OleObject_AddRef", 0 },
937         { "OleObject_QueryInterface", 0 },
938         { "OleObject_AddRef", 0 },
939         { "OleObject_GetMiscStatus", 0 },
940         { "OleObject_QueryInterface", 0 },
941         { "OleObjectPersistStg_AddRef", 0 },
942         { "OleObjectPersistStg_InitNew", 0 },
943         { "OleObjectPersistStg_Release", 0 },
944         { "OleObject_SetClientSite", 0 },
945         { "OleObject_Release", 0 },
946         { "OleObject_QueryInterface", 0 },
947         { "OleObjectRunnable_AddRef", 0 },
948         { "OleObjectRunnable_Run", 0 },
949         { "OleObjectRunnable_Release", 0 },
950         { "OleObject_QueryInterface", 0 },
951         { "OleObjectCache_AddRef", 0 },
952         { "OleObjectCache_Cache", 0 },
953         { "OleObjectCache_Release", 0 },
954         { "OleObject_Release", 0 },
955         { NULL, 0 }
956     };
957     static const struct expected_method methods_olerender_asis[] =
958     {
959         { "OleObject_QueryInterface", 0 },
960         { "OleObject_AddRef", 0 },
961         { "OleObject_QueryInterface", 0 },
962         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
963         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
964         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
965         { "OleObjectPersistStg_AddRef", 0 },
966         { "OleObjectPersistStg_InitNew", 0 },
967         { "OleObjectPersistStg_Release", 0 },
968         { "OleObject_Release", 0 },
969         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
970         { NULL, 0 }
971     };
972     static const struct expected_method methods_olerender_draw_no_runnable[] =
973     {
974         { "OleObject_QueryInterface", 0 },
975         { "OleObject_AddRef", 0 },
976         { "OleObject_QueryInterface", 0 },
977         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
978         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
979         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
980         { "OleObjectPersistStg_AddRef", 0 },
981         { "OleObjectPersistStg_InitNew", 0 },
982         { "OleObjectPersistStg_Release", 0 },
983         { "OleObject_QueryInterface", 0 },
984         { "OleObject_QueryInterface", 0 },
985         { "OleObjectCache_AddRef", 0 },
986         { "OleObjectCache_Cache", 0 },
987         { "OleObjectCache_Release", 0 },
988         { "OleObject_Release", 0 },
989         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
990         { NULL, 0 },
991     };
992     static const struct expected_method methods_olerender_draw_no_cache[] =
993     {
994         { "OleObject_QueryInterface", 0 },
995         { "OleObject_AddRef", 0 },
996         { "OleObject_QueryInterface", 0 },
997         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
998         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
999         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1000         { "OleObjectPersistStg_AddRef", 0 },
1001         { "OleObjectPersistStg_InitNew", 0 },
1002         { "OleObjectPersistStg_Release", 0 },
1003         { "OleObject_QueryInterface", 0 },
1004         { "OleObjectRunnable_AddRef", 0 },
1005         { "OleObjectRunnable_Run", 0 },
1006         { "OleObjectRunnable_Release", 0 },
1007         { "OleObject_QueryInterface", 0 },
1008         { "OleObject_Release", 0 },
1009         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1010         { NULL, 0 }
1011     };
1012 
1013     g_expected_fetc = &formatetc;
1014     formatetc.cfFormat = 0;
1015     formatetc.ptd = NULL;
1016     formatetc.dwAspect = DVASPECT_CONTENT;
1017     formatetc.lindex = -1;
1018     formatetc.tymed = TYMED_NULL;
1019     runnable = &OleObjectRunnable;
1020     cache = &OleObjectCache;
1021     expected_method_list = methods_olerender_none;
1022     trace("OleCreate with OLERENDER_NONE:\n");
1023     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
1024     ok_ole_success(hr, "OleCreate");
1025     IOleObject_Release(pObject);
1026     CHECK_NO_EXTRA_METHODS();
1027 
1028     expected_method_list = methods_olerender_draw;
1029     trace("OleCreate with OLERENDER_DRAW:\n");
1030     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1031     ok_ole_success(hr, "OleCreate");
1032     IOleObject_Release(pObject);
1033     CHECK_NO_EXTRA_METHODS();
1034 
1035     expected_method_list = methods_olerender_draw_with_site;
1036     trace("OleCreate with OLERENDER_DRAW, with site:\n");
1037     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1038     ok_ole_success(hr, "OleCreate");
1039     IOleObject_Release(pObject);
1040     CHECK_NO_EXTRA_METHODS();
1041 
1042     /* GetMiscStatus fails */
1043     g_GetMiscStatusFailsWith = 0x8fafefaf;
1044     expected_method_list = methods_olerender_draw_with_site;
1045     trace("OleCreate with OLERENDER_DRAW, with site:\n");
1046     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1047     ok_ole_success(hr, "OleCreate");
1048     IOleObject_Release(pObject);
1049     CHECK_NO_EXTRA_METHODS();
1050     g_GetMiscStatusFailsWith = S_OK;
1051 
1052     formatetc.cfFormat = CF_TEXT;
1053     formatetc.ptd = NULL;
1054     formatetc.dwAspect = DVASPECT_CONTENT;
1055     formatetc.lindex = -1;
1056     formatetc.tymed = TYMED_HGLOBAL;
1057     expected_method_list = methods_olerender_format;
1058     trace("OleCreate with OLERENDER_FORMAT:\n");
1059     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
1060     ok(hr == S_OK ||
1061        broken(hr == E_INVALIDARG), /* win2k */
1062        "OleCreate failed with error 0x%08x\n", hr);
1063     if (pObject)
1064     {
1065         IOleObject_Release(pObject);
1066         CHECK_NO_EXTRA_METHODS();
1067     }
1068 
1069     expected_method_list = methods_olerender_asis;
1070     trace("OleCreate with OLERENDER_ASIS:\n");
1071     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
1072     ok_ole_success(hr, "OleCreate");
1073     IOleObject_Release(pObject);
1074     CHECK_NO_EXTRA_METHODS();
1075 
1076     formatetc.cfFormat = 0;
1077     formatetc.tymed = TYMED_NULL;
1078     runnable = NULL;
1079     expected_method_list = methods_olerender_draw_no_runnable;
1080     trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1081     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1082     ok_ole_success(hr, "OleCreate");
1083     IOleObject_Release(pObject);
1084     CHECK_NO_EXTRA_METHODS();
1085 
1086     runnable = &OleObjectRunnable;
1087     cache = NULL;
1088     expected_method_list = methods_olerender_draw_no_cache;
1089     trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1090     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1091     ok_ole_success(hr, "OleCreate");
1092     IOleObject_Release(pObject);
1093     CHECK_NO_EXTRA_METHODS();
1094     trace("end\n");
1095     g_expected_fetc = NULL;
1096 }
1097 
1098 static void test_OleLoad(IStorage *pStorage)
1099 {
1100     HRESULT hr;
1101     IOleObject *pObject;
1102     DWORD fmt;
1103 
1104     static const struct expected_method methods_oleload[] =
1105     {
1106         { "OleObject_QueryInterface", 0 },
1107         { "OleObject_AddRef", 0 },
1108         { "OleObject_QueryInterface", 0 },
1109         { "OleObject_AddRef", 0 },
1110         { "OleObject_GetMiscStatus", 0 },
1111         { "OleObject_QueryInterface", 0 },
1112         { "OleObjectPersistStg_AddRef", 0 },
1113         { "OleObjectPersistStg_Load", 0 },
1114         { "OleObjectPersistStg_Release", 0 },
1115         { "OleObject_SetClientSite", 0 },
1116         { "OleObject_Release", 0 },
1117         { "OleObject_QueryInterface", 0 },
1118         { "OleObject_GetMiscStatus", 0 },
1119         { "OleObject_Release", 0 },
1120         { NULL, 0 }
1121     };
1122 
1123     /* Test once with IOleObject_GetMiscStatus failing */
1124     expected_method_list = methods_oleload;
1125     g_GetMiscStatusFailsWith = E_FAIL;
1126     trace("OleLoad:\n");
1127     hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1128     ok(hr == S_OK ||
1129        broken(hr == E_INVALIDARG), /* win98 and win2k */
1130        "OleLoad failed with error 0x%08x\n", hr);
1131     if(pObject)
1132     {
1133         DWORD dwStatus = 0xdeadbeef;
1134         hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1135         ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1136         ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
1137 
1138         IOleObject_Release(pObject);
1139         CHECK_NO_EXTRA_METHODS();
1140     }
1141     g_GetMiscStatusFailsWith = S_OK;
1142 
1143     /* Test again, let IOleObject_GetMiscStatus succeed. */
1144     expected_method_list = methods_oleload;
1145     trace("OleLoad:\n");
1146     hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1147     ok(hr == S_OK ||
1148        broken(hr == E_INVALIDARG), /* win98 and win2k */
1149        "OleLoad failed with error 0x%08x\n", hr);
1150     if (pObject)
1151     {
1152         DWORD dwStatus = 0xdeadbeef;
1153         hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1154         ok(hr == S_OK, "Got 0x%08x\n", hr);
1155         ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
1156 
1157         IOleObject_Release(pObject);
1158         CHECK_NO_EXTRA_METHODS();
1159     }
1160 
1161     for (fmt = CF_TEXT; fmt < CF_MAX; fmt++)
1162     {
1163         static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1164         IStorage *stg;
1165         IStream *stream;
1166         IUnknown *obj;
1167         DWORD data, i, data_size;
1168         PresentationDataHeader header;
1169         HDC hdc;
1170         HGDIOBJ hobj;
1171         RECT rc;
1172         char buf[256];
1173 
1174         for (i = 0; i < 7; i++)
1175         {
1176             hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg);
1177             ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr);
1178 
1179             hr = IStorage_SetClass(stg, &CLSID_WineTest);
1180             ok(hr == S_OK, "SetClass error %#x\n", hr);
1181 
1182             hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream);
1183             ok(hr == S_OK, "CreateStream error %#x\n", hr);
1184 
1185             data = ~0;
1186             hr = IStream_Write(stream, &data, sizeof(data), NULL);
1187             ok(hr == S_OK, "Write error %#x\n", hr);
1188 
1189             data = fmt;
1190             hr = IStream_Write(stream, &data, sizeof(data), NULL);
1191             ok(hr == S_OK, "Write error %#x\n", hr);
1192 
1193             switch (fmt)
1194             {
1195             case CF_BITMAP:
1196                 /* FIXME: figure out stream format */
1197                 hobj = CreateBitmap(1, 1, 1, 1, NULL);
1198                 data_size = GetBitmapBits(hobj, sizeof(buf), buf);
1199                 DeleteObject(hobj);
1200                 break;
1201 
1202             case CF_METAFILEPICT:
1203             case CF_ENHMETAFILE:
1204                 hdc = CreateMetaFileA(NULL);
1205                 hobj = CloseMetaFile(hdc);
1206                 data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf);
1207                 DeleteMetaFile(hobj);
1208                 break;
1209 
1210             default:
1211                 data_size = sizeof(buf);
1212                 memset(buf, 'A', sizeof(buf));
1213                 break;
1214             }
1215 
1216             header.unknown3 = 4;
1217             header.dvAspect = DVASPECT_CONTENT;
1218             header.lindex = -1;
1219             header.advf = 1 << i;
1220             header.unknown7 = 0;
1221             header.dwObjectExtentX = 1;
1222             header.dwObjectExtentY = 1;
1223             header.dwSize = data_size;
1224             hr = IStream_Write(stream, &header, sizeof(header), NULL);
1225             ok(hr == S_OK, "Write error %#x\n", hr);
1226 
1227             hr = IStream_Write(stream, buf, data_size, NULL);
1228             ok(hr == S_OK, "Write error %#x\n", hr);
1229 
1230             IStream_Release(stream);
1231 
1232             hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj);
1233             /* FIXME: figure out stream format */
1234             if (fmt == CF_BITMAP && hr != S_OK)
1235             {
1236                 IStorage_Release(stg);
1237                 continue;
1238             }
1239             ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1240 
1241             hdc = CreateCompatibleDC(0);
1242             SetRect(&rc, 0, 0, 100, 100);
1243             hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc);
1244             DeleteDC(hdc);
1245             if (fmt == CF_METAFILEPICT)
1246                 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1247             else if (fmt == CF_ENHMETAFILE)
1248 todo_wine
1249                 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1250             else
1251                 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);
1252 
1253             IUnknown_Release(obj);
1254             IStorage_Release(stg);
1255         }
1256     }
1257 }
1258 
1259 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
1260 {
1261     CHECK_EXPECTED_METHOD("draw_continue");
1262     return TRUE;
1263 }
1264 
1265 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param)
1266 {
1267     CHECK_EXPECTED_METHOD("draw_continue_false");
1268     return FALSE;
1269 }
1270 
1271 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
1272 {
1273     if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
1274     {
1275         *ppv = iface;
1276         IAdviseSink_AddRef(iface);
1277         return S_OK;
1278     }
1279     *ppv = NULL;
1280     return E_NOINTERFACE;
1281 }
1282 
1283 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
1284 {
1285     return 2;
1286 }
1287 
1288 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
1289 {
1290     return 1;
1291 }
1292 
1293 
1294 static void WINAPI AdviseSink_OnDataChange(
1295     IAdviseSink *iface,
1296     FORMATETC *pFormatetc,
1297     STGMEDIUM *pStgmed)
1298 {
1299     CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1300 }
1301 
1302 static void WINAPI AdviseSink_OnViewChange(
1303     IAdviseSink *iface,
1304     DWORD dwAspect,
1305     LONG lindex)
1306 {
1307     CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1308 }
1309 
1310 static void WINAPI AdviseSink_OnRename(
1311     IAdviseSink *iface,
1312     IMoniker *pmk)
1313 {
1314     CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1315 }
1316 
1317 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
1318 {
1319     CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1320 }
1321 
1322 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
1323 {
1324     CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1325 }
1326 
1327 static const IAdviseSinkVtbl AdviseSinkVtbl =
1328 {
1329     AdviseSink_QueryInterface,
1330     AdviseSink_AddRef,
1331     AdviseSink_Release,
1332     AdviseSink_OnDataChange,
1333     AdviseSink_OnViewChange,
1334     AdviseSink_OnRename,
1335     AdviseSink_OnSave,
1336     AdviseSink_OnClose
1337 };
1338 
1339 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
1340 
1341 static HRESULT WINAPI DataObject_QueryInterface(
1342             IDataObject*     iface,
1343             REFIID           riid,
1344             void**           ppvObject)
1345 {
1346     CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1347 
1348     if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
1349     {
1350         *ppvObject = iface;
1351         return S_OK;
1352     }
1353     *ppvObject = NULL;
1354     return S_OK;
1355 }
1356 
1357 static ULONG WINAPI DataObject_AddRef(
1358             IDataObject*     iface)
1359 {
1360     CHECK_EXPECTED_METHOD("DataObject_AddRef");
1361     return 2;
1362 }
1363 
1364 static ULONG WINAPI DataObject_Release(
1365             IDataObject*     iface)
1366 {
1367     CHECK_EXPECTED_METHOD("DataObject_Release");
1368     return 1;
1369 }
1370 
1371 static HRESULT WINAPI DataObject_GetData(
1372         IDataObject*     iface,
1373         LPFORMATETC      pformatetcIn,
1374         STGMEDIUM*       pmedium)
1375 {
1376     CHECK_EXPECTED_METHOD("DataObject_GetData");
1377     return E_NOTIMPL;
1378 }
1379 
1380 static HRESULT WINAPI DataObject_GetDataHere(
1381         IDataObject*     iface,
1382         LPFORMATETC      pformatetc,
1383         STGMEDIUM*       pmedium)
1384 {
1385     CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1386     return E_NOTIMPL;
1387 }
1388 
1389 static HRESULT WINAPI DataObject_QueryGetData(
1390         IDataObject*     iface,
1391         LPFORMATETC      pformatetc)
1392 {
1393     CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1394     return S_OK;
1395 }
1396 
1397 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1398         IDataObject*     iface,
1399         LPFORMATETC      pformatectIn,
1400         LPFORMATETC      pformatetcOut)
1401 {
1402     CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1403     return E_NOTIMPL;
1404 }
1405 
1406 static HRESULT WINAPI DataObject_SetData(
1407         IDataObject*     iface,
1408         LPFORMATETC      pformatetc,
1409         STGMEDIUM*       pmedium,
1410         BOOL             fRelease)
1411 {
1412     CHECK_EXPECTED_METHOD("DataObject_SetData");
1413     return E_NOTIMPL;
1414 }
1415 
1416 static HRESULT WINAPI DataObject_EnumFormatEtc(
1417         IDataObject*     iface,
1418         DWORD            dwDirection,
1419         IEnumFORMATETC** ppenumFormatEtc)
1420 {
1421     CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1422     return E_NOTIMPL;
1423 }
1424 
1425 static HRESULT WINAPI DataObject_DAdvise(
1426         IDataObject*     iface,
1427         FORMATETC*       pformatetc,
1428         DWORD            advf,
1429         IAdviseSink*     pAdvSink,
1430         DWORD*           pdwConnection)
1431 {
1432     STGMEDIUM stgmedium;
1433 
1434     CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1435     *pdwConnection = 1;
1436 
1437     if(advf & ADVF_PRIMEFIRST)
1438     {
1439         ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
1440         stgmedium.tymed = TYMED_HGLOBAL;
1441         U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
1442         stgmedium.pUnkForRelease = NULL;
1443         IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
1444     }
1445 
1446     return S_OK;
1447 }
1448 
1449 static HRESULT WINAPI DataObject_DUnadvise(
1450         IDataObject*     iface,
1451         DWORD            dwConnection)
1452 {
1453     CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1454     return S_OK;
1455 }
1456 
1457 static HRESULT WINAPI DataObject_EnumDAdvise(
1458         IDataObject*     iface,
1459         IEnumSTATDATA**  ppenumAdvise)
1460 {
1461     CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1462     return OLE_E_ADVISENOTSUPPORTED;
1463 }
1464 
1465 static IDataObjectVtbl DataObjectVtbl =
1466 {
1467     DataObject_QueryInterface,
1468     DataObject_AddRef,
1469     DataObject_Release,
1470     DataObject_GetData,
1471     DataObject_GetDataHere,
1472     DataObject_QueryGetData,
1473     DataObject_GetCanonicalFormatEtc,
1474     DataObject_SetData,
1475     DataObject_EnumFormatEtc,
1476     DataObject_DAdvise,
1477     DataObject_DUnadvise,
1478     DataObject_EnumDAdvise
1479 };
1480 
1481 static IDataObject DataObject = { &DataObjectVtbl };
1482 
1483 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1484 {
1485     *ppv = NULL;
1486     if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1487     if (*ppv)
1488     {
1489         IUnknown_AddRef((IUnknown *)*ppv);
1490         return S_OK;
1491     }
1492     return E_NOINTERFACE;
1493 }
1494 
1495 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
1496 {
1497     return 2;
1498 }
1499 
1500 static ULONG WINAPI Unknown_Release(IUnknown *iface)
1501 {
1502     return 1;
1503 }
1504 
1505 static const IUnknownVtbl UnknownVtbl =
1506 {
1507     Unknown_QueryInterface,
1508     Unknown_AddRef,
1509     Unknown_Release
1510 };
1511 
1512 static IUnknown unknown = { &UnknownVtbl };
1513 
1514 static void check_enum_cache(IOleCache2 *cache, const STATDATA *expect, int num)
1515 {
1516     IEnumSTATDATA *enum_stat;
1517     STATDATA stat;
1518     HRESULT hr;
1519 
1520     hr = IOleCache2_EnumCache( cache, &enum_stat );
1521     ok( hr == S_OK, "got %08x\n", hr );
1522 
1523     while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK)
1524     {
1525         ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n",
1526             stat.formatetc.cfFormat, expect->formatetc.cfFormat );
1527         ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n",
1528             stat.formatetc.ptd, expect->formatetc.ptd );
1529         ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n",
1530             stat.formatetc.dwAspect, expect->formatetc.dwAspect );
1531         ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n",
1532             stat.formatetc.lindex, expect->formatetc.lindex );
1533         ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n",
1534             stat.formatetc.tymed, expect->formatetc.tymed );
1535         ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf );
1536         ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink );
1537         ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection );
1538         num--;
1539         expect++;
1540     }
1541 
1542     ok( num == 0, "incorrect number. num %d\n", num );
1543 
1544     IEnumSTATDATA_Release( enum_stat );
1545 }
1546 
1547 static void test_data_cache(void)
1548 {
1549     HRESULT hr;
1550     IOleCache2 *pOleCache;
1551     IOleCache *olecache;
1552     IStorage *pStorage;
1553     IUnknown *unk;
1554     IPersistStorage *pPS;
1555     IViewObject *pViewObject;
1556     IOleCacheControl *pOleCacheControl;
1557     IDataObject *pCacheDataObject;
1558     FORMATETC fmtetc;
1559     STGMEDIUM stgmedium;
1560     DWORD dwConnection;
1561     DWORD dwFreeze;
1562     RECTL rcBounds;
1563     HDC hdcMem;
1564     CLSID clsid;
1565     char szSystemDir[MAX_PATH];
1566     WCHAR wszPath[MAX_PATH];
1567     static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1568 
1569     static const struct expected_method methods_cacheinitnew[] =
1570     {
1571         { "AdviseSink_OnViewChange", 0 },
1572         { "AdviseSink_OnViewChange", 0 },
1573         { "draw_continue", 1 },
1574         { "draw_continue_false", 1 },
1575         { "DataObject_DAdvise", 0 },
1576         { "DataObject_DAdvise", 0 },
1577         { "DataObject_DUnadvise", 0 },
1578         { "DataObject_DUnadvise", 0 },
1579         { NULL, 0 }
1580     };
1581     static const struct expected_method methods_cacheload[] =
1582     {
1583         { "AdviseSink_OnViewChange", 0 },
1584         { "draw_continue", 1 },
1585         { "draw_continue", 1 },
1586         { "draw_continue", 1 },
1587         { "DataObject_GetData", 0 },
1588         { "DataObject_GetData", 0 },
1589         { "DataObject_GetData", 0 },
1590         { NULL, 0 }
1591     };
1592     static const struct expected_method methods_cachethenrun[] =
1593     {
1594         { "DataObject_DAdvise", 0 },
1595         { "DataObject_DAdvise", 0 },
1596         { "DataObject_DAdvise", 0 },
1597         { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
1598         { "DataObject_DAdvise", 0 },
1599         { "DataObject_DUnadvise", 0 },
1600         { "DataObject_DUnadvise", 0 },
1601         { "DataObject_DUnadvise", 0 },
1602         { "DataObject_DUnadvise", 0 },
1603         { NULL, 0 }
1604     };
1605 
1606     GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1607 
1608     expected_method_list = methods_cacheinitnew;
1609 
1610     fmtetc.cfFormat = CF_METAFILEPICT;
1611     fmtetc.dwAspect = DVASPECT_ICON;
1612     fmtetc.lindex = -1;
1613     fmtetc.ptd = NULL;
1614     fmtetc.tymed = TYMED_MFPICT;
1615 
1616     hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1617     ok_ole_success(hr, "StgCreateDocfile");
1618 
1619     /* aggregation */
1620 
1621     /* requested is not IUnknown */
1622     hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache);
1623     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1624 
1625     hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1626     ok(hr == S_OK, "got 0x%08x\n", hr);
1627 
1628     hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1629     ok(hr == S_OK, "got 0x%08x\n", hr);
1630     hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1631     ok(hr == S_OK, "got 0x%08x\n", hr);
1632     ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1633     ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1634     IOleCache2_Release(pOleCache);
1635     IOleCache_Release(olecache);
1636     IUnknown_Release(unk);
1637 
1638     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1639     ok(hr == S_OK, "got 0x%08x\n", hr);
1640     hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1641     ok(hr == S_OK, "got 0x%08x\n", hr);
1642     hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1643     ok(hr == S_OK, "got 0x%08x\n", hr);
1644 todo_wine {
1645     ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1646     ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1647 }
1648     IOleCache2_Release(pOleCache);
1649     IOleCache_Release(olecache);
1650     IUnknown_Release(unk);
1651 
1652     /* Test with new data */
1653 
1654     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1655     ok_ole_success(hr, "CreateDataCache");
1656 
1657     hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1658     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1659     hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1660     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1661     hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1662     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1663 
1664     hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1665     ok_ole_success(hr, "IViewObject_SetAdvise");
1666 
1667     hr = IPersistStorage_InitNew(pPS, pStorage);
1668     ok_ole_success(hr, "IPersistStorage_InitNew");
1669 
1670     hr = IPersistStorage_IsDirty(pPS);
1671     ok_ole_success(hr, "IPersistStorage_IsDirty");
1672 
1673     hr = IPersistStorage_GetClassID(pPS, &clsid);
1674     ok_ole_success(hr, "IPersistStorage_GetClassID");
1675     ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1676 
1677     hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef);
1678     ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1679 
1680     /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1681     if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1682     {
1683         hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection);
1684         ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1685 
1686         hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL);
1687         ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1688     }
1689     else
1690     {
1691         skip("tests with NULL parameters will crash on NT4 and below\n");
1692     }
1693 
1694     for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1695     {
1696         int i;
1697         fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1698         for (i = 0; i < 7; i++)
1699         {
1700             fmtetc.tymed = 1 << i;
1701             hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1702             if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1703                 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1704                 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1705                 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1706                 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1707                     fmtetc.cfFormat, fmtetc.tymed, hr);
1708             else if (fmtetc.tymed == TYMED_HGLOBAL)
1709                 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED ||
1710                    broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1711                     "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1712                     fmtetc.cfFormat, fmtetc.tymed, hr);
1713             else
1714                 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1715                     fmtetc.cfFormat, fmtetc.tymed, hr);
1716             if (SUCCEEDED(hr))
1717             {
1718                 hr = IOleCache2_Uncache(pOleCache, dwConnection);
1719                 ok_ole_success(hr, "IOleCache_Uncache");
1720             }
1721         }
1722     }
1723 
1724     fmtetc.cfFormat = CF_BITMAP;
1725     fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1726     fmtetc.tymed = TYMED_GDI;
1727     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1728     ok_ole_success(hr, "IOleCache_Cache");
1729 
1730     fmtetc.cfFormat = 0;
1731     fmtetc.dwAspect = DVASPECT_ICON;
1732     fmtetc.tymed = TYMED_MFPICT;
1733     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1734     ok_ole_success(hr, "IOleCache_Cache");
1735 
1736     MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1737     memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1738 
1739     fmtetc.cfFormat = CF_METAFILEPICT;
1740     stgmedium.tymed = TYMED_MFPICT;
1741     U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1742         LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0);
1743     stgmedium.pUnkForRelease = NULL;
1744 
1745     fmtetc.dwAspect = DVASPECT_CONTENT;
1746     hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1747     ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1748 
1749     fmtetc.dwAspect = DVASPECT_ICON;
1750     hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1751     ok_ole_success(hr, "IOleCache_SetData");
1752     ReleaseStgMedium(&stgmedium);
1753 
1754     hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1755     todo_wine {
1756     ok_ole_success(hr, "IViewObject_Freeze");
1757     hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1758     ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1759     }
1760 
1761     rcBounds.left = 0;
1762     rcBounds.top = 0;
1763     rcBounds.right = 100;
1764     rcBounds.bottom = 100;
1765     hdcMem = CreateCompatibleDC(NULL);
1766 
1767     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1768     ok_ole_success(hr, "IViewObject_Draw");
1769 
1770     hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1771     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1772 
1773     /* a NULL draw_continue fn ptr */
1774     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
1775     ok_ole_success(hr, "IViewObject_Draw");
1776 
1777     /* draw_continue that returns FALSE to abort drawing */
1778     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
1779     ok(hr == E_ABORT ||
1780        broken(hr == S_OK), /* win9x may skip the callbacks */
1781        "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
1782 
1783     DeleteDC(hdcMem);
1784 
1785     hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1786     ok_ole_success(hr, "IOleCacheControl_OnRun");
1787 
1788     hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1789     ok_ole_success(hr, "IPersistStorage_Save");
1790 
1791     hr = IPersistStorage_SaveCompleted(pPS, NULL);
1792     ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1793 
1794     hr = IPersistStorage_IsDirty(pPS);
1795     ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1796 
1797     IPersistStorage_Release(pPS);
1798     IViewObject_Release(pViewObject);
1799     IOleCache2_Release(pOleCache);
1800     IOleCacheControl_Release(pOleCacheControl);
1801 
1802     CHECK_NO_EXTRA_METHODS();
1803 
1804     /* Test with loaded data */
1805     trace("Testing loaded data with CreateDataCache:\n");
1806     expected_method_list = methods_cacheload;
1807 
1808     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1809     ok_ole_success(hr, "CreateDataCache");
1810 
1811     hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1812     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1813     hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1814     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1815 
1816     hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1817     ok_ole_success(hr, "IViewObject_SetAdvise");
1818 
1819     hr = IPersistStorage_Load(pPS, pStorage);
1820     ok_ole_success(hr, "IPersistStorage_Load");
1821 
1822     hr = IPersistStorage_IsDirty(pPS);
1823     ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1824 
1825     fmtetc.cfFormat = 0;
1826     fmtetc.dwAspect = DVASPECT_ICON;
1827     fmtetc.lindex = -1;
1828     fmtetc.ptd = NULL;
1829     fmtetc.tymed = TYMED_MFPICT;
1830     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1831     ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1832 
1833     rcBounds.left = 0;
1834     rcBounds.top = 0;
1835     rcBounds.right = 100;
1836     rcBounds.bottom = 100;
1837     hdcMem = CreateCompatibleDC(NULL);
1838 
1839     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1840     ok_ole_success(hr, "IViewObject_Draw");
1841 
1842     hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1843     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1844 
1845     /* unload the cached storage object, causing it to be reloaded */
1846     hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1847     ok_ole_success(hr, "IOleCache2_DiscardCache");
1848     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1849     ok_ole_success(hr, "IViewObject_Draw");
1850 
1851     /* unload the cached storage object, but don't allow it to be reloaded */
1852     hr = IPersistStorage_HandsOffStorage(pPS);
1853     ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1854     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1855     ok_ole_success(hr, "IViewObject_Draw");
1856     hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1857     ok_ole_success(hr, "IOleCache2_DiscardCache");
1858     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1859     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1860 
1861     DeleteDC(hdcMem);
1862 
1863     todo_wine {
1864     hr = IOleCache2_InitCache(pOleCache, &DataObject);
1865     ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1866     }
1867 
1868     IPersistStorage_Release(pPS);
1869     IViewObject_Release(pViewObject);
1870     IOleCache2_Release(pOleCache);
1871 
1872     todo_wine {
1873     CHECK_NO_EXTRA_METHODS();
1874     }
1875 
1876     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1877     ok_ole_success(hr, "CreateDataCache");
1878 
1879     expected_method_list = methods_cachethenrun;
1880 
1881     hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
1882     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
1883     hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1884     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1885 
1886     fmtetc.cfFormat = CF_METAFILEPICT;
1887     fmtetc.dwAspect = DVASPECT_CONTENT;
1888     fmtetc.tymed = TYMED_MFPICT;
1889 
1890     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1891     ok_ole_success(hr, "IOleCache_Cache");
1892 
1893     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1894     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1895 
1896     fmtetc.cfFormat = cf_test_1;
1897     fmtetc.dwAspect = DVASPECT_CONTENT;
1898     fmtetc.tymed = TYMED_HGLOBAL;
1899 
1900     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1901     ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1902 
1903     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1904     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1905 
1906     fmtetc.cfFormat = cf_test_2;
1907     hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
1908     ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1909 
1910     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1911     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1912 
1913     hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1914     ok_ole_success(hr, "IOleCacheControl_OnRun");
1915 
1916     fmtetc.cfFormat = cf_test_3;
1917     hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1918     ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1919 
1920     fmtetc.cfFormat = cf_test_1;
1921     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1922     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1923 
1924     fmtetc.cfFormat = cf_test_2;
1925     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1926     ok(hr == S_OK, "got %08x\n", hr);
1927     ReleaseStgMedium(&stgmedium);
1928 
1929     fmtetc.cfFormat = cf_test_3;
1930     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1931     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1932 
1933     IOleCacheControl_Release(pOleCacheControl);
1934     IDataObject_Release(pCacheDataObject);
1935     IOleCache2_Release(pOleCache);
1936 
1937     CHECK_NO_EXTRA_METHODS();
1938 
1939     IStorage_Release(pStorage);
1940 }
1941 
1942 
1943 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
1944 
1945 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
1946 static BYTE dib[] =
1947 {
1948     0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
1949     0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
1950 
1951     0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
1952     0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
1953 
1954     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
1955     0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
1956 
1957     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1958     0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1959 };
1960 
1961 static IStorage *create_storage( int num )
1962 {
1963     IStorage *stg;
1964     IStream *stm;
1965     HRESULT hr;
1966     ULONG written;
1967 
1968     hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg );
1969     ok( hr == S_OK, "got %08x\n", hr);
1970     hr = IStorage_SetClass( stg, &CLSID_Picture_Dib );
1971     ok( hr == S_OK, "got %08x\n", hr);
1972     hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm );
1973     ok( hr == S_OK, "got %08x\n", hr);
1974     if (num == 1) /* Set biXPelsPerMeter = 0 */
1975     {
1976         dib[0x26] = 0;
1977         dib[0x27] = 0;
1978     }
1979     hr = IStream_Write( stm, dib, sizeof(dib), &written );
1980     ok( hr == S_OK, "got %08x\n", hr);
1981     IStream_Release( stm );
1982     return stg;
1983 }
1984 
1985 static HGLOBAL create_dib( void )
1986 {
1987     HGLOBAL h;
1988     void *ptr;
1989 
1990     h = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) );
1991     ptr = GlobalLock( h );
1992     memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) );
1993     GlobalUnlock( h );
1994     return h;
1995 }
1996 
1997 static void test_data_cache_dib_contents_stream(int num)
1998 {
1999     HRESULT hr;
2000     IUnknown *unk;
2001     IPersistStorage *persist;
2002     IDataObject *data;
2003     IViewObject2 *view;
2004     IStorage *stg;
2005     IOleCache2 *cache;
2006     FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
2007     STGMEDIUM med;
2008     CLSID cls;
2009     SIZEL sz;
2010     BYTE *ptr;
2011     BITMAPINFOHEADER expect_info;
2012     STATDATA enum_expect[] =
2013     {
2014         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2015         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 1 },
2016     };
2017 
2018     hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk );
2019     ok( SUCCEEDED(hr), "got %08x\n", hr );
2020     hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist );
2021     ok( SUCCEEDED(hr), "got %08x\n", hr );
2022     hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data );
2023     ok( SUCCEEDED(hr), "got %08x\n", hr );
2024     hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view );
2025     ok( SUCCEEDED(hr), "got %08x\n", hr );
2026     hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache );
2027     ok( SUCCEEDED(hr), "got %08x\n", hr );
2028 
2029     stg = create_storage( num );
2030 
2031     hr = IPersistStorage_Load( persist, stg );
2032     ok( SUCCEEDED(hr), "got %08x\n", hr );
2033     IStorage_Release( stg );
2034 
2035     hr = IPersistStorage_GetClassID( persist, &cls );
2036     ok( SUCCEEDED(hr), "got %08x\n", hr );
2037     ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" );
2038 
2039     hr = IDataObject_GetData( data, &fmt, &med );
2040     ok( SUCCEEDED(hr), "got %08x\n", hr );
2041     ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed );
2042     ok( GlobalSize( U(med).hGlobal ) >= sizeof(dib) - sizeof(BITMAPFILEHEADER),
2043         "got %lu\n", GlobalSize( U(med).hGlobal ) );
2044     ptr = GlobalLock( U(med).hGlobal );
2045 
2046     expect_info = *(BITMAPINFOHEADER *)(dib + sizeof(BITMAPFILEHEADER));
2047     if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0)
2048     {
2049         HDC hdc = GetDC( 0 );
2050         expect_info.biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 );
2051         expect_info.biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 );
2052         ReleaseDC( 0, hdc );
2053     }
2054     ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" );
2055     ok( !memcmp( ptr + sizeof(expect_info), dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info),
2056                  sizeof(dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" );
2057     GlobalUnlock( U(med).hGlobal );
2058     ReleaseStgMedium( &med );
2059 
2060     check_enum_cache( cache, enum_expect, 2 );
2061 
2062     hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
2063     ok( SUCCEEDED(hr), "got %08x\n", hr );
2064     if (num == 0)
2065     {
2066         ok( sz.cx == 1000, "got %d\n", sz.cx );
2067         ok( sz.cy == 250, "got %d\n", sz.cy );
2068     }
2069     else
2070     {
2071         HDC hdc = GetDC( 0 );
2072         LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
2073         LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );
2074         ok( sz.cx == x, "got %d %d\n", sz.cx, x );
2075         ok( sz.cy == y, "got %d %d\n", sz.cy, y );
2076 
2077         ReleaseDC( 0, hdc );
2078     }
2079 
2080     IOleCache2_Release( cache );
2081     IViewObject2_Release( view );
2082     IDataObject_Release( data );
2083     IPersistStorage_Release( persist );
2084     IUnknown_Release( unk );
2085 }
2086 
2087 static void check_bitmap_size( HBITMAP h, int cx, int cy )
2088 {
2089     BITMAP bm;
2090 
2091     GetObjectW( h, sizeof(bm), &bm );
2092     ok( bm.bmWidth == cx, "got %d expect %d\n", bm.bmWidth, cx );
2093     ok( bm.bmHeight == cy, "got %d expect %d\n", bm.bmHeight, cy );
2094 }
2095 
2096 static void check_dib_size( HGLOBAL h, int cx, int cy )
2097 {
2098     BITMAPINFO *info;
2099 
2100     info = GlobalLock( h );
2101     ok( info->bmiHeader.biWidth == cx, "got %d expect %d\n", info->bmiHeader.biWidth, cx );
2102     ok( info->bmiHeader.biHeight == cy, "got %d expect %d\n", info->bmiHeader.biHeight, cy );
2103     GlobalUnlock( h );
2104 }
2105 
2106 static void test_data_cache_bitmap(void)
2107 {
2108     HRESULT hr;
2109     IOleCache2 *cache;
2110     IDataObject *data;
2111     FORMATETC fmt;
2112     DWORD conn;
2113     STGMEDIUM med;
2114     STATDATA expect[] =
2115     {
2116         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
2117         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 0 },
2118         {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },  0, NULL, 0 },
2119         {{ CF_ENHMETAFILE,  0, DVASPECT_CONTENT, -1, TYMED_ENHMF },   0, NULL, 0 }
2120     };
2121 
2122     hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache );
2123     ok( hr == S_OK, "got %08x\n", hr );
2124 
2125     /* create a dib entry which will also create a bitmap entry too */
2126     fmt.cfFormat = CF_DIB;
2127     fmt.ptd = NULL;
2128     fmt.dwAspect = DVASPECT_CONTENT;
2129     fmt.lindex = -1;
2130     fmt.tymed = TYMED_HGLOBAL;
2131 
2132     hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2133     ok( hr == S_OK, "got %08x\n", hr );
2134     ok( conn == 2, "got %d\n", conn );
2135     expect[0].dwConnection = conn;
2136     expect[1].dwConnection = conn;
2137 
2138     check_enum_cache( cache, expect, 2 );
2139 
2140     /* now try to add a bitmap */
2141     fmt.cfFormat = CF_BITMAP;
2142     fmt.tymed = TYMED_GDI;
2143 
2144     hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2145     ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr );
2146 
2147     /* metafile */
2148     fmt.cfFormat = CF_METAFILEPICT;
2149     fmt.tymed = TYMED_MFPICT;
2150 
2151     hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2152     ok( hr == S_OK, "got %08x\n", hr );
2153     ok( conn == 3, "got %d\n", conn );
2154     expect[2].dwConnection = conn;
2155 
2156     check_enum_cache( cache, expect,  3);
2157 
2158     /* enhmetafile */
2159     fmt.cfFormat = CF_ENHMETAFILE;
2160     fmt.tymed = TYMED_ENHMF;
2161 
2162     hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2163     ok( hr == S_OK, "got %08x\n", hr );
2164     ok( conn == 4, "got %d\n", conn );
2165     expect[3].dwConnection = conn;
2166 
2167     check_enum_cache( cache, expect, 4 );
2168 
2169     /* uncache everything */
2170     hr = IOleCache2_Uncache( cache, expect[3].dwConnection );
2171     ok( hr == S_OK, "got %08x\n", hr );
2172     hr = IOleCache2_Uncache( cache, expect[2].dwConnection );
2173     ok( hr == S_OK, "got %08x\n", hr );
2174     hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
2175     ok( hr == S_OK, "got %08x\n", hr );
2176     hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
2177     ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr );
2178 
2179     check_enum_cache( cache, expect, 0 );
2180 
2181     /* just create a bitmap entry which again adds both dib and bitmap */
2182     fmt.cfFormat = CF_BITMAP;
2183     fmt.tymed = TYMED_GDI;
2184 
2185     hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2186     ok( hr == S_OK, "got %08x\n", hr );
2187 
2188     expect[0].dwConnection = conn;
2189     expect[1].dwConnection = conn;
2190 
2191     check_enum_cache( cache, expect, 2 );
2192 
2193     /* Try setting a 1x1 bitmap */
2194     hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data );
2195     ok( hr == S_OK, "got %08x\n", hr );
2196 
2197     med.tymed = TYMED_GDI;
2198     U(med).hBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
2199     med.pUnkForRelease = NULL;
2200 
2201     hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
2202     ok( hr == S_OK, "got %08x\n", hr );
2203 
2204     hr = IDataObject_GetData( data, &fmt, &med );
2205     ok( hr == S_OK, "got %08x\n", hr );
2206     ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed );
2207     check_bitmap_size( U(med).hBitmap, 1, 1 );
2208     ReleaseStgMedium( &med );
2209 
2210     fmt.cfFormat = CF_DIB;
2211     fmt.tymed = TYMED_HGLOBAL;
2212     hr = IDataObject_GetData( data, &fmt, &med );
2213     ok( hr == S_OK, "got %08x\n", hr );
2214     ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed );
2215     check_dib_size( U(med).hGlobal, 1, 1 );
2216     ReleaseStgMedium( &med );
2217 
2218     /* Now set a 2x1 dib */
2219     fmt.cfFormat = CF_DIB;
2220     fmt.tymed = TYMED_HGLOBAL;
2221     med.tymed = TYMED_HGLOBAL;
2222     U(med).hGlobal = create_dib();
2223 
2224     hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
2225     ok( hr == S_OK, "got %08x\n", hr );
2226 
2227     fmt.cfFormat = CF_BITMAP;
2228     fmt.tymed = TYMED_GDI;
2229     hr = IDataObject_GetData( data, &fmt, &med );
2230     ok( hr == S_OK, "got %08x\n", hr );
2231     ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed );
2232     check_bitmap_size( U(med).hBitmap, 2, 1 );
2233     ReleaseStgMedium( &med );
2234 
2235     fmt.cfFormat = CF_DIB;
2236     fmt.tymed = TYMED_HGLOBAL;
2237     hr = IDataObject_GetData( data, &fmt, &med );
2238     ok( hr == S_OK, "got %08x\n", hr );
2239     ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed );
2240     check_dib_size( U(med).hGlobal, 2, 1 );
2241     ReleaseStgMedium( &med );
2242 
2243     IDataObject_Release( data );
2244     IOleCache2_Release( cache );
2245 }
2246 
2247 /* The CLSID_Picture_ classes automatically create appropriate cache entries */
2248 static void test_data_cache_init(void)
2249 {
2250     HRESULT hr;
2251     IOleCache2 *cache;
2252     IPersistStorage *persist;
2253     int i;
2254     CLSID clsid;
2255     static const STATDATA enum_expect[] =
2256     {
2257         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2258         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 1 },
2259         {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },  0, NULL, 1 },
2260         {{ CF_ENHMETAFILE,  0, DVASPECT_CONTENT, -1, TYMED_ENHMF },   0, NULL, 1 }
2261     };
2262     static const struct
2263     {
2264         const CLSID *clsid;
2265         int enum_start, enum_num;
2266     } data[] =
2267     {
2268         { &CLSID_NULL, 0, 0 },
2269         { &CLSID_WineTestOld, 0, 0 },
2270         { &CLSID_Picture_Dib, 0, 2 },
2271         { &CLSID_Picture_Metafile, 2, 1 },
2272         { &CLSID_Picture_EnhMetafile, 3, 1 }
2273     };
2274 
2275     for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
2276     {
2277         hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache );
2278         ok( hr == S_OK, "got %08x\n", hr );
2279 
2280         check_enum_cache( cache, enum_expect + data[i].enum_start , data[i].enum_num );
2281 
2282         IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist );
2283         hr = IPersistStorage_GetClassID( persist, &clsid );
2284         ok( hr == S_OK, "got %08x\n", hr );
2285         ok( IsEqualCLSID( &clsid, data[i].clsid ), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid ),
2286             wine_dbgstr_guid( data[i].clsid ) );
2287 
2288         IPersistStorage_Release( persist );
2289         IOleCache2_Release( cache );
2290     }
2291 }
2292 
2293 static void test_data_cache_initnew(void)
2294 {
2295     HRESULT hr;
2296     IOleCache2 *cache;
2297     IPersistStorage *persist;
2298     IStorage *stg_dib, *stg_mf, *stg_wine;
2299     CLSID clsid;
2300     static const STATDATA initnew_expect[] =
2301     {
2302         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2303         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 1 },
2304     };
2305     static const STATDATA initnew2_expect[] =
2306     {
2307         {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },  0, NULL, 1 },
2308         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2309         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 2 },
2310     };
2311     static const STATDATA initnew3_expect[] =
2312     {
2313         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2314         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 1 },
2315         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2316         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 2 },
2317         {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },  0, NULL, 3 },
2318     };
2319     static const STATDATA initnew4_expect[] =
2320     {
2321         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2322         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 2 },
2323         {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },  0, NULL, 3 },
2324         {{ CF_DIB,          0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 4 },
2325         {{ CF_BITMAP,       0, DVASPECT_CONTENT, -1, TYMED_GDI },     0, NULL, 4 },
2326     };
2327 
2328     hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_dib );
2329     ok( hr == S_OK, "got %08x\n", hr);
2330     hr = IStorage_SetClass( stg_dib, &CLSID_Picture_Dib );
2331     ok( hr == S_OK, "got %08x\n", hr);
2332 
2333     hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_mf );
2334     ok( hr == S_OK, "got %08x\n", hr);
2335     hr = IStorage_SetClass( stg_mf, &CLSID_Picture_Metafile );
2336     ok( hr == S_OK, "got %08x\n", hr);
2337 
2338     hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_wine );
2339     ok( hr == S_OK, "got %08x\n", hr);
2340     hr = IStorage_SetClass( stg_wine, &CLSID_WineTestOld );
2341     ok( hr == S_OK, "got %08x\n", hr);
2342 
2343     hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache );
2344     ok( hr == S_OK, "got %08x\n", hr );
2345     IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist );
2346 
2347     hr = IPersistStorage_InitNew( persist, stg_dib );
2348     ok( hr == S_OK, "got %08x\n", hr);
2349 
2350     hr = IPersistStorage_GetClassID( persist, &clsid );
2351     ok( hr == S_OK, "got %08x\n", hr );
2352     ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2353 
2354     check_enum_cache( cache, initnew_expect, 2 );
2355 
2356     hr = IPersistStorage_InitNew( persist, stg_mf );
2357     ok( hr == CO_E_ALREADYINITIALIZED, "got %08x\n", hr);
2358 
2359     hr = IPersistStorage_HandsOffStorage( persist );
2360     ok( hr == S_OK, "got %08x\n", hr);
2361 
2362     hr = IPersistStorage_GetClassID( persist, &clsid );
2363     ok( hr == S_OK, "got %08x\n", hr );
2364     ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2365 
2366     hr = IPersistStorage_InitNew( persist, stg_mf );
2367     ok( hr == S_OK, "got %08x\n", hr);
2368 
2369     hr = IPersistStorage_GetClassID( persist, &clsid );
2370     ok( hr == S_OK, "got %08x\n", hr );
2371     ok( IsEqualCLSID( &clsid, &CLSID_Picture_Metafile ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2372 
2373     check_enum_cache( cache, initnew2_expect, 3 );
2374 
2375     hr = IPersistStorage_HandsOffStorage( persist );
2376     ok( hr == S_OK, "got %08x\n", hr);
2377 
2378     hr = IPersistStorage_InitNew( persist, stg_dib );
2379     ok( hr == S_OK, "got %08x\n", hr);
2380 
2381     hr = IPersistStorage_GetClassID( persist, &clsid );
2382     ok( hr == S_OK, "got %08x\n", hr );
2383     ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2384 
2385     check_enum_cache( cache, initnew3_expect, 5 );
2386 
2387     hr = IPersistStorage_HandsOffStorage( persist );
2388     ok( hr == S_OK, "got %08x\n", hr);
2389 
2390     hr = IPersistStorage_InitNew( persist, stg_wine );
2391     ok( hr == S_OK, "got %08x\n", hr);
2392 
2393     hr = IPersistStorage_GetClassID( persist, &clsid );
2394     ok( hr == S_OK, "got %08x\n", hr );
2395     ok( IsEqualCLSID( &clsid, &CLSID_WineTestOld ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2396 
2397     check_enum_cache( cache, initnew4_expect, 5 );
2398 
2399     IStorage_Release( stg_wine );
2400     IStorage_Release( stg_mf );
2401     IStorage_Release( stg_dib );
2402 
2403     IPersistStorage_Release( persist );
2404     IOleCache2_Release( cache );
2405 }
2406 
2407 static void test_default_handler(void)
2408 {
2409     HRESULT hr;
2410     IOleObject *pObject;
2411     IRunnableObject *pRunnableObject;
2412     IOleClientSite *pClientSite;
2413     IDataObject *pDataObject;
2414     SIZEL sizel;
2415     DWORD dwStatus;
2416     CLSID clsid;
2417     LPOLESTR pszUserType;
2418     LOGPALETTE palette;
2419     DWORD dwAdvConn;
2420     IMoniker *pMoniker;
2421     FORMATETC fmtetc;
2422     IOleInPlaceObject *pInPlaceObj;
2423     IEnumOLEVERB *pEnumVerbs;
2424     DWORD dwRegister;
2425     static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
2426     static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2427     static const WCHAR wszDelim[] = {'!',0};
2428 
2429     static const struct expected_method methods_embeddinghelper[] =
2430     {
2431         { "OleObject_QueryInterface", 0 },
2432         { "OleObject_AddRef", 0 },
2433         { "OleObject_QueryInterface", 0 },
2434         { "OleObject_QueryInterface", TEST_TODO },
2435         { "OleObject_QueryInterface", 0 },
2436         { "OleObject_QueryInterface", 0 },
2437         { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
2438         { "OleObject_Release", TEST_TODO },
2439         { "WINE_EXTRA", TEST_OPTIONAL },
2440         { NULL, 0 }
2441     };
2442 
2443     hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
2444     ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2445 
2446     hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
2447     ok_ole_success(hr, "OleCreateDefaultHandler");
2448 
2449     hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
2450     ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
2451 
2452     hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
2453     ok_ole_success(hr, "IOleObject_Advise");
2454 
2455     hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2456     ok_ole_success(hr, "IOleObject_Close");
2457 
2458     /* FIXME: test IOleObject_EnumAdvise */
2459 
2460     hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
2461     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2462 
2463     hr = IOleObject_GetClientSite(pObject, &pClientSite);
2464     ok_ole_success(hr, "IOleObject_GetClientSite");
2465 
2466     hr = IOleObject_SetClientSite(pObject, pClientSite);
2467     ok_ole_success(hr, "IOleObject_SetClientSite");
2468 
2469     hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
2470     ok(hr == OLE_E_NOTRUNNING,
2471        "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
2472        hr);
2473 
2474     hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
2475     ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
2476        hr);
2477 
2478     hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
2479     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2480 
2481     hr = IOleObject_GetUserClassID(pObject, &clsid);
2482     ok_ole_success(hr, "IOleObject_GetUserClassID");
2483     ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
2484 
2485     hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
2486     todo_wine {
2487     ok_ole_success(hr, "IOleObject_GetUserType");
2488     ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
2489     }
2490 
2491     hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
2492     ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2493 
2494     hr = IOleObject_IsUpToDate(pObject);
2495     ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2496 
2497     palette.palNumEntries = 1;
2498     palette.palVersion = 2;
2499     memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
2500     hr = IOleObject_SetColorScheme(pObject, &palette);
2501     ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2502 
2503     sizel.cx = sizel.cy = 0;
2504     hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
2505     ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2506 
2507     hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
2508     ok_ole_success(hr, "IOleObject_SetHostNames");
2509 
2510     hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
2511     ok_ole_success(hr, "CreateItemMoniker");
2512     hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
2513     ok_ole_success(hr, "IOleObject_SetMoniker");
2514     IMoniker_Release(pMoniker);
2515 
2516     hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
2517     ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
2518 
2519     hr = IOleObject_Update(pObject);
2520     todo_wine
2521     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2522 
2523     hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
2524     ok_ole_success(hr, "IOleObject_QueryInterface");
2525 
2526     fmtetc.cfFormat = CF_TEXT;
2527     fmtetc.ptd = NULL;
2528     fmtetc.dwAspect = DVASPECT_CONTENT;
2529     fmtetc.lindex = -1;
2530     fmtetc.tymed = TYMED_NULL;
2531     hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2532     ok_ole_success(hr, "IDataObject_DAdvise");
2533 
2534     fmtetc.cfFormat = CF_ENHMETAFILE;
2535     fmtetc.ptd = NULL;
2536     fmtetc.dwAspect = DVASPECT_CONTENT;
2537     fmtetc.lindex = -1;
2538     fmtetc.tymed = TYMED_ENHMF;
2539     hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2540     ok_ole_success(hr, "IDataObject_DAdvise");
2541 
2542     fmtetc.cfFormat = CF_ENHMETAFILE;
2543     fmtetc.ptd = NULL;
2544     fmtetc.dwAspect = DVASPECT_CONTENT;
2545     fmtetc.lindex = -1;
2546     fmtetc.tymed = TYMED_ENHMF;
2547     hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2548     ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2549 
2550     fmtetc.cfFormat = CF_TEXT;
2551     fmtetc.ptd = NULL;
2552     fmtetc.dwAspect = DVASPECT_CONTENT;
2553     fmtetc.lindex = -1;
2554     fmtetc.tymed = TYMED_NULL;
2555     hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2556     ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2557 
2558     hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
2559     ok_ole_success(hr, "IOleObject_QueryInterface");
2560 
2561     hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
2562     ok_ole_success(hr, "IRunnableObject_SetContainedObject");
2563 
2564     hr = IRunnableObject_Run(pRunnableObject, NULL);
2565     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2566 
2567     hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2568     ok_ole_success(hr, "IOleObject_Close");
2569 
2570     IRunnableObject_Release(pRunnableObject);
2571     IOleObject_Release(pObject);
2572 
2573     /* Test failure propagation from delegate ::QueryInterface */
2574     hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF,
2575                                CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
2576     ok_ole_success(hr, "CoRegisterClassObject");
2577     if(SUCCEEDED(hr))
2578     {
2579         expected_method_list = methods_embeddinghelper;
2580         hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER,
2581                                       &OleObjectCF, &IID_IOleObject, (void**)&pObject);
2582         ok_ole_success(hr, "OleCreateEmbeddingHelper");
2583         if(SUCCEEDED(hr))
2584         {
2585             IUnknown *punk;
2586 
2587             g_QIFailsWith = E_FAIL;
2588             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2589             ok(hr == E_FAIL, "Got 0x%08x\n", hr);
2590 
2591             g_QIFailsWith = E_NOINTERFACE;
2592             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2593             ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
2594 
2595             g_QIFailsWith = CO_E_OBJNOTCONNECTED;
2596             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2597             ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
2598 
2599             g_QIFailsWith = 0x87654321;
2600             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2601             ok(hr == 0x87654321, "Got 0x%08x\n", hr);
2602 
2603             IOleObject_Release(pObject);
2604         }
2605 
2606         CHECK_NO_EXTRA_METHODS();
2607 
2608         hr = CoRevokeClassObject(dwRegister);
2609         ok_ole_success(hr, "CoRevokeClassObject");
2610     }
2611 }
2612 
2613 static void test_runnable(void)
2614 {
2615     static const struct expected_method methods_query_runnable[] =
2616     {
2617         { "OleObject_QueryInterface", 0 },
2618         { "OleObjectRunnable_AddRef", 0 },
2619         { "OleObjectRunnable_IsRunning", 0 },
2620         { "OleObjectRunnable_Release", 0 },
2621         { NULL, 0 }
2622     };
2623 
2624     static const struct expected_method methods_no_runnable[] =
2625     {
2626         { "OleObject_QueryInterface", 0 },
2627         { NULL, 0 }
2628     };
2629 
2630     BOOL ret;
2631     IOleObject *object = &OleObject;
2632 
2633     /* null argument */
2634     ret = OleIsRunning(NULL);
2635     ok(ret == FALSE, "got %d\n", ret);
2636 
2637     expected_method_list = methods_query_runnable;
2638     ret = OleIsRunning(object);
2639     ok(ret == TRUE, "Object should be running\n");
2640     CHECK_NO_EXTRA_METHODS();
2641 
2642     g_isRunning = FALSE;
2643     expected_method_list = methods_query_runnable;
2644     ret = OleIsRunning(object);
2645     ok(ret == FALSE, "Object should not be running\n");
2646     CHECK_NO_EXTRA_METHODS();
2647 
2648     g_showRunnable = FALSE;  /* QueryInterface(IID_IRunnableObject, ...) will fail */
2649     expected_method_list = methods_no_runnable;
2650     ret = OleIsRunning(object);
2651     ok(ret == TRUE, "Object without IRunnableObject should be running\n");
2652     CHECK_NO_EXTRA_METHODS();
2653 
2654     g_isRunning = TRUE;
2655     g_showRunnable = TRUE;
2656 }
2657 
2658 
2659 static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
2660 {
2661     *ppv = NULL;
2662 
2663     if (IsEqualIID(riid, &IID_IUnknown) ||
2664         IsEqualIID(riid, &IID_IRunnableObject)) {
2665         *ppv = iface;
2666     }
2667 
2668     if (*ppv)
2669     {
2670         IUnknown_AddRef((IUnknown *)*ppv);
2671         return S_OK;
2672     }
2673 
2674     return E_NOINTERFACE;
2675 }
2676 
2677 static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface)
2678 {
2679     return 2;
2680 }
2681 
2682 static ULONG WINAPI OleRun_Release(IRunnableObject *iface)
2683 {
2684     return 1;
2685 }
2686 
2687 static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid)
2688 {
2689     ok(0, "unexpected\n");
2690     return E_NOTIMPL;
2691 }
2692 
2693 static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx)
2694 {
2695     ok(ctx == NULL, "got %p\n", ctx);
2696     return 0xdeadc0de;
2697 }
2698 
2699 static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface)
2700 {
2701     ok(0, "unexpected\n");
2702     return FALSE;
2703 }
2704 
2705 static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock,
2706     BOOL last_unlock_closes)
2707 {
2708     ok(0, "unexpected\n");
2709     return E_NOTIMPL;
2710 }
2711 
2712 static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained)
2713 {
2714     ok(0, "unexpected\n");
2715     return E_NOTIMPL;
2716 }
2717 
2718 static const IRunnableObjectVtbl oleruntestvtbl =
2719 {
2720     OleRun_QueryInterface,
2721     OleRun_AddRef,
2722     OleRun_Release,
2723     OleRun_GetRunningClass,
2724     OleRun_Run,
2725     OleRun_IsRunning,
2726     OleRun_LockRunning,
2727     OleRun_SetContainedObject
2728 };
2729 
2730 static IRunnableObject testrunnable = { &oleruntestvtbl };
2731 
2732 static void test_OleRun(void)
2733 {
2734     HRESULT hr;
2735 
2736     /* doesn't support IRunnableObject */
2737     hr = OleRun(&unknown);
2738     ok(hr == S_OK, "OleRun failed 0x%08x\n", hr);
2739 
2740     hr = OleRun((IUnknown*)&testrunnable);
2741     ok(hr == 0xdeadc0de, "got 0x%08x\n", hr);
2742 }
2743 
2744 static void test_OleLockRunning(void)
2745 {
2746     HRESULT hr;
2747 
2748     hr = OleLockRunning(&unknown, TRUE, FALSE);
2749     ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
2750 }
2751 
2752 static void test_OleDraw(void)
2753 {
2754     HRESULT hr;
2755     RECT rect;
2756 
2757     hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL);
2758     ok(hr == S_OK, "got 0x%08x\n", hr);
2759 
2760     hr = OleDraw(NULL, 0, (HDC)0x1, NULL);
2761     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2762 
2763     hr = OleDraw(NULL, 0, (HDC)0x1, &rect);
2764     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2765 }
2766 
2767 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0};
2768 static IStream *comp_obj_stream;
2769 static IStream *ole_stream;
2770 
2771 static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject)
2772 {
2773     ok(0, "unexpected call to QueryInterface\n");
2774     return E_NOTIMPL;
2775 }
2776 
2777 static ULONG WINAPI Storage_AddRef(IStorage *iface)
2778 {
2779     ok(0, "unexpected call to AddRef\n");
2780     return 2;
2781 }
2782 
2783 static ULONG WINAPI Storage_Release(IStorage *iface)
2784 {
2785     ok(0, "unexpected call to Release\n");
2786     return 1;
2787 }
2788 
2789 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
2790 {
2791     ULARGE_INTEGER size = {{0}};
2792     LARGE_INTEGER pos = {{0}};
2793     HRESULT hr;
2794 
2795     CHECK_EXPECT(Storage_CreateStream_CompObj);
2796     ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName));
2797     todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2798     ok(!reserved1, "reserved1 = %x\n", reserved1);
2799     ok(!reserved2, "reserved2 = %x\n", reserved2);
2800     ok(!!ppstm, "ppstm = NULL\n");
2801 
2802     *ppstm = comp_obj_stream;
2803     IStream_AddRef(comp_obj_stream);
2804     hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2805     ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2806     hr = IStream_SetSize(comp_obj_stream, size);
2807     ok(hr == S_OK, "IStream_SetSize returned %x\n", hr);
2808     return S_OK;
2809 }
2810 
2811 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
2812 {
2813     static  const WCHAR ole1W[] = {1,'O','l','e',0};
2814 
2815     LARGE_INTEGER pos = {{0}};
2816     HRESULT hr;
2817 
2818     ok(!reserved1, "reserved1 = %p\n", reserved1);
2819     ok(!reserved2, "reserved2 = %x\n", reserved2);
2820     ok(!!ppstm, "ppstm = NULL\n");
2821 
2822     if(!lstrcmpW(pwcsName, comp_objW)) {
2823         CHECK_EXPECT2(Storage_OpenStream_CompObj);
2824         ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode);
2825 
2826         *ppstm = comp_obj_stream;
2827         IStream_AddRef(comp_obj_stream);
2828         hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2829         ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2830         return S_OK;
2831     }else if(!lstrcmpW(pwcsName, ole1W)) {
2832         CHECK_EXPECT(Storage_OpenStream_Ole);
2833         ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2834 
2835         *ppstm = ole_stream;
2836         IStream_AddRef(ole_stream);
2837         hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
2838         ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2839         return S_OK;
2840     }
2841 
2842     ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName));
2843     return E_NOTIMPL;
2844 }
2845 
2846 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg)
2847 {
2848     ok(0, "unexpected call to CreateStorage\n");
2849     return E_NOTIMPL;
2850 }
2851 
2852 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
2853 {
2854     ok(0, "unexpected call to OpenStorage\n");
2855     return E_NOTIMPL;
2856 }
2857 
2858 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest)
2859 {
2860     ok(0, "unexpected call to CopyTo\n");
2861     return E_NOTIMPL;
2862 }
2863 
2864 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags)
2865 {
2866     ok(0, "unexpected call to MoveElementTo\n");
2867     return E_NOTIMPL;
2868 }
2869 
2870 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags)
2871 {
2872     ok(0, "unexpected call to Commit\n");
2873     return E_NOTIMPL;
2874 }
2875 
2876 static HRESULT WINAPI Storage_Revert(IStorage *iface)
2877 {
2878     ok(0, "unexpected call to Revert\n");
2879     return E_NOTIMPL;
2880 }
2881 
2882 static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum)
2883 {
2884     ok(0, "unexpected call to EnumElements\n");
2885     return E_NOTIMPL;
2886 }
2887 
2888 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName)
2889 {
2890     ok(0, "unexpected call to DestroyElement\n");
2891     return E_NOTIMPL;
2892 }
2893 
2894 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName)
2895 {
2896     ok(0, "unexpected call to RenameElement\n");
2897     return E_NOTIMPL;
2898 }
2899 
2900 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
2901 {
2902     ok(0, "unexpected call to SetElementTimes\n");
2903     return E_NOTIMPL;
2904 }
2905 
2906 static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid)
2907 {
2908     CHECK_EXPECT(Storage_SetClass);
2909     ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid));
2910     return S_OK;
2911 }
2912 
2913 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask)
2914 {
2915     ok(0, "unexpected call to SetStateBits\n");
2916     return E_NOTIMPL;
2917 }
2918 
2919 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag)
2920 {
2921     CHECK_EXPECT2(Storage_Stat);
2922     ok(pstatstg != NULL, "pstatstg = NULL\n");
2923     ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag);
2924 
2925     memset(pstatstg, 0, sizeof(STATSTG));
2926     pstatstg->type = STGTY_STORAGE;
2927     pstatstg->clsid = CLSID_WineTestOld;
2928     return S_OK;
2929 }
2930 
2931 static IStorageVtbl StorageVtbl =
2932 {
2933     Storage_QueryInterface,
2934     Storage_AddRef,
2935     Storage_Release,
2936     Storage_CreateStream,
2937     Storage_OpenStream,
2938     Storage_CreateStorage,
2939     Storage_OpenStorage,
2940     Storage_CopyTo,
2941     Storage_MoveElementTo,
2942     Storage_Commit,
2943     Storage_Revert,
2944     Storage_EnumElements,
2945     Storage_DestroyElement,
2946     Storage_RenameElement,
2947     Storage_SetElementTimes,
2948     Storage_SetClass,
2949     Storage_SetStateBits,
2950     Storage_Stat
2951 };
2952 
2953 static IStorage Storage = { &StorageVtbl };
2954 
2955 static void test_OleDoAutoConvert(void)
2956 {
2957     static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
2958     static struct {
2959         DWORD reserved1;
2960         DWORD version;
2961         DWORD reserved2[5];
2962         DWORD ansi_user_type_len;
2963         DWORD ansi_clipboard_format_len;
2964         DWORD reserved3;
2965         DWORD unicode_marker;
2966         DWORD unicode_user_type_len;
2967         DWORD unicode_clipboard_format_len;
2968         DWORD reserved4;
2969     } comp_obj_data;
2970     static struct {
2971         DWORD version;
2972         DWORD flags;
2973         DWORD link_update_option;
2974         DWORD reserved1;
2975         DWORD reserved_moniker_stream_size;
2976         DWORD relative_source_moniker_stream_size;
2977         DWORD absolute_source_moniker_stream_size;
2978         DWORD clsid_indicator;
2979         CLSID clsid;
2980         DWORD reserved_display_name;
2981         DWORD reserved2;
2982         DWORD local_update_time;
2983         DWORD local_check_update_time;
2984         DWORD remote_update_time;
2985     } ole_data;
2986 
2987     LARGE_INTEGER pos = {{0}};
2988     WCHAR buf[39+6];
2989     DWORD i, ret;
2990     HKEY root;
2991     CLSID clsid;
2992     HRESULT hr;
2993 
2994     hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream);
2995     ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
2996     hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL);
2997     ok(hr == S_OK, "IStream_Write returned %x\n", hr);
2998 
2999     hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream);
3000     ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
3001     hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL);
3002     ok(hr == S_OK, "IStream_Write returned %x\n", hr);
3003 
3004     clsid = IID_WineTest;
3005     hr = OleDoAutoConvert(NULL, &clsid);
3006     ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr);
3007     ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3008 
3009     if(0) /* crashes on Win7 */
3010         OleDoAutoConvert(&Storage, NULL);
3011 
3012     clsid = IID_WineTest;
3013     SET_EXPECT(Storage_Stat);
3014     hr = OleDoAutoConvert(&Storage, &clsid);
3015     ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr);
3016     CHECK_CALLED(Storage_Stat);
3017     ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3018 
3019     lstrcpyW(buf, clsidW);
3020     StringFromGUID2(&CLSID_WineTestOld, buf+6, 39);
3021 
3022     ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
3023             KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL);
3024     if(ret != ERROR_SUCCESS) {
3025         win_skip("not enough permissions to create CLSID key (%u)\n", ret);
3026         return;
3027     }
3028 
3029     clsid = IID_WineTest;
3030     SET_EXPECT(Storage_Stat);
3031     hr = OleDoAutoConvert(&Storage, &clsid);
3032     ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr);
3033     CHECK_CALLED(Storage_Stat);
3034     ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3035 
3036     hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest);
3037     ok_ole_success(hr, "OleSetAutoConvert");
3038 
3039     hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid);
3040     ok_ole_success(hr, "OleGetAutoConvert");
3041     ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid));
3042 
3043     clsid = IID_WineTest;
3044     SET_EXPECT(Storage_Stat);
3045     SET_EXPECT(Storage_OpenStream_CompObj);
3046     SET_EXPECT(Storage_SetClass);
3047     SET_EXPECT(Storage_CreateStream_CompObj);
3048     SET_EXPECT(Storage_OpenStream_Ole);
3049     hr = OleDoAutoConvert(&Storage, &clsid);
3050     ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr);
3051     CHECK_CALLED(Storage_Stat);
3052     CHECK_CALLED(Storage_OpenStream_CompObj);
3053     CHECK_CALLED(Storage_SetClass);
3054     CHECK_CALLED(Storage_CreateStream_CompObj);
3055     CHECK_CALLED(Storage_OpenStream_Ole);
3056     ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3057 
3058     hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3059     ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3060     hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
3061     ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3062     ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
3063     ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
3064     ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
3065     ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
3066     ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
3067     ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
3068     ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
3069     ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
3070     ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
3071     ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
3072     ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
3073 
3074     hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
3075     ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3076     hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL);
3077     ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3078     ok(ole_data.version == 0, "version = %x\n", ole_data.version);
3079     ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags);
3080     for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++)
3081         ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]);
3082 
3083     SET_EXPECT(Storage_OpenStream_Ole);
3084     hr = SetConvertStg(&Storage, TRUE);
3085     ok(hr == S_OK, "SetConvertStg returned %x\n", hr);
3086     CHECK_CALLED(Storage_OpenStream_Ole);
3087 
3088     SET_EXPECT(Storage_OpenStream_CompObj);
3089     SET_EXPECT(Storage_Stat);
3090     SET_EXPECT(Storage_CreateStream_CompObj);
3091     hr = WriteFmtUserTypeStg(&Storage, 0, NULL);
3092     ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr);
3093     todo_wine CHECK_CALLED(Storage_OpenStream_CompObj);
3094     CHECK_CALLED(Storage_Stat);
3095     CHECK_CALLED(Storage_CreateStream_CompObj);
3096     hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3097     ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3098     hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
3099     ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3100     ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
3101     ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
3102     ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
3103     ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
3104     ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
3105     ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
3106     ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
3107     ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
3108     ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
3109     ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
3110     ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
3111 
3112     ret = IStream_Release(comp_obj_stream);
3113     ok(!ret, "comp_obj_stream was not freed\n");
3114     ret = IStream_Release(ole_stream);
3115     ok(!ret, "ole_stream was not freed\n");
3116 
3117     ret = RegDeleteKeyA(root, "AutoConvertTo");
3118     ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
3119     ret = RegDeleteKeyA(root, "");
3120     ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
3121     RegCloseKey(root);
3122 }
3123 
3124 START_TEST(ole2)
3125 {
3126     DWORD dwRegister;
3127     IStorage *pStorage;
3128     STATSTG statstg;
3129     HRESULT hr;
3130 
3131     cf_test_1 = RegisterClipboardFormatA("cf_winetest_1");
3132     cf_test_2 = RegisterClipboardFormatA("cf_winetest_2");
3133     cf_test_3 = RegisterClipboardFormatA("cf_winetest_3");
3134 
3135     CoInitialize(NULL);
3136 
3137     hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
3138     ok_ole_success(hr, "CoRegisterClassObject");
3139 
3140     hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
3141     ok_ole_success(hr, "StgCreateDocfile");
3142 
3143     test_OleCreate(pStorage);
3144 
3145     hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
3146     ok_ole_success(hr, "IStorage_Stat");
3147     ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
3148 
3149     test_OleLoad(pStorage);
3150 
3151     IStorage_Release(pStorage);
3152 
3153     hr = CoRevokeClassObject(dwRegister);
3154     ok_ole_success(hr, "CoRevokeClassObject");
3155 
3156     test_data_cache();
3157     test_data_cache_dib_contents_stream( 0 );
3158     test_data_cache_dib_contents_stream( 1 );
3159     test_data_cache_bitmap();
3160     test_data_cache_init();
3161     test_data_cache_initnew();
3162     test_default_handler();
3163     test_runnable();
3164     test_OleRun();
3165     test_OleLockRunning();
3166     test_OleDraw();
3167     test_OleDoAutoConvert();
3168 
3169     CoUninitialize();
3170 }
3171