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