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