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