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