- Sync ole32 and oleaut32 regtests to Wine-1.3.
[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 COBJMACROS
22 #define CONST_VTABLE
23
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #include "shlguid.h"
30
31 #include "wine/test.h"
32
33 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
34
35 static IPersistStorage OleObjectPersistStg;
36 static IOleCache *cache;
37 static IRunnableObject *runnable;
38
39 static const CLSID CLSID_WineTest =
40 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
41 0x9474ba1a,
42 0x258b,
43 0x490b,
44 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
45 };
46
47 #define TEST_OPTIONAL 0x1
48
49 struct expected_method
50 {
51 const char *method;
52 unsigned int flags;
53 };
54
55 static const struct expected_method *expected_method_list;
56
57 BOOL g_showRunnable = TRUE;
58 BOOL g_isRunning = TRUE;
59
60 #define CHECK_EXPECTED_METHOD(method_name) \
61 do { \
62 trace("%s\n", method_name); \
63 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
64 if (expected_method_list->method) \
65 { \
66 while (expected_method_list->flags & TEST_OPTIONAL && \
67 strcmp(expected_method_list->method, method_name) != 0) \
68 expected_method_list++; \
69 ok(!strcmp(expected_method_list->method, method_name), "Expected %s to be called instead of %s\n", \
70 expected_method_list->method, method_name); \
71 expected_method_list++; \
72 } \
73 } while(0)
74
75 #define CHECK_NO_EXTRA_METHODS() \
76 do { \
77 while (expected_method_list->flags & TEST_OPTIONAL) \
78 expected_method_list++; \
79 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
80 } while (0)
81
82 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
83 {
84 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
85
86 *ppv = NULL;
87
88 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
89 *ppv = iface;
90 else if (IsEqualIID(riid, &IID_IPersistStorage))
91 *ppv = &OleObjectPersistStg;
92 else if (IsEqualIID(riid, &IID_IOleCache))
93 *ppv = cache;
94 else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
95 *ppv = runnable;
96
97 if(*ppv) {
98 IUnknown_AddRef((IUnknown*)*ppv);
99 return S_OK;
100 }
101
102 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
103 return E_NOINTERFACE;
104 }
105
106 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
107 {
108 CHECK_EXPECTED_METHOD("OleObject_AddRef");
109 return 2;
110 }
111
112 static ULONG WINAPI OleObject_Release(IOleObject *iface)
113 {
114 CHECK_EXPECTED_METHOD("OleObject_Release");
115 return 1;
116 }
117
118 static HRESULT WINAPI OleObject_SetClientSite
119 (
120 IOleObject *iface,
121 IOleClientSite *pClientSite
122 )
123 {
124 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
125 return S_OK;
126 }
127
128 static HRESULT WINAPI OleObject_GetClientSite
129 (
130 IOleObject *iface,
131 IOleClientSite **ppClientSite
132 )
133 {
134 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
135 return E_NOTIMPL;
136 }
137
138 static HRESULT WINAPI OleObject_SetHostNames
139 (
140 IOleObject *iface,
141 LPCOLESTR szContainerApp,
142 LPCOLESTR szContainerObj
143 )
144 {
145 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
146 return S_OK;
147 }
148
149 static HRESULT WINAPI OleObject_Close
150 (
151 IOleObject *iface,
152 DWORD dwSaveOption
153 )
154 {
155 CHECK_EXPECTED_METHOD("OleObject_Close");
156 return S_OK;
157 }
158
159 static HRESULT WINAPI OleObject_SetMoniker
160 (
161 IOleObject *iface,
162 DWORD dwWhichMoniker,
163 IMoniker *pmk
164 )
165 {
166 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
167 return S_OK;
168 }
169
170 static HRESULT WINAPI OleObject_GetMoniker
171 (
172 IOleObject *iface,
173 DWORD dwAssign,
174 DWORD dwWhichMoniker,
175 IMoniker **ppmk
176 )
177 {
178 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
179 return S_OK;
180 }
181
182 static HRESULT WINAPI OleObject_InitFromData
183 (
184 IOleObject *iface,
185 IDataObject *pDataObject,
186 BOOL fCreation,
187 DWORD dwReserved
188 )
189 {
190 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
191 return S_OK;
192 }
193
194 static HRESULT WINAPI OleObject_GetClipboardData
195 (
196 IOleObject *iface,
197 DWORD dwReserved,
198 IDataObject **ppDataObject
199 )
200 {
201 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
202 return E_NOTIMPL;
203 }
204
205 static HRESULT WINAPI OleObject_DoVerb
206 (
207 IOleObject *iface,
208 LONG iVerb,
209 LPMSG lpmsg,
210 IOleClientSite *pActiveSite,
211 LONG lindex,
212 HWND hwndParent,
213 LPCRECT lprcPosRect
214 )
215 {
216 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
217 return S_OK;
218 }
219
220 static HRESULT WINAPI OleObject_EnumVerbs
221 (
222 IOleObject *iface,
223 IEnumOLEVERB **ppEnumOleVerb
224 )
225 {
226 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
227 return E_NOTIMPL;
228 }
229
230 static HRESULT WINAPI OleObject_Update
231 (
232 IOleObject *iface
233 )
234 {
235 CHECK_EXPECTED_METHOD("OleObject_Update");
236 return S_OK;
237 }
238
239 static HRESULT WINAPI OleObject_IsUpToDate
240 (
241 IOleObject *iface
242 )
243 {
244 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
245 return S_OK;
246 }
247
248 static HRESULT WINAPI OleObject_GetUserClassID
249 (
250 IOleObject *iface,
251 CLSID *pClsid
252 )
253 {
254 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
255 return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI OleObject_GetUserType
259 (
260 IOleObject *iface,
261 DWORD dwFormOfType,
262 LPOLESTR *pszUserType
263 )
264 {
265 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
266 return E_NOTIMPL;
267 }
268
269 static HRESULT WINAPI OleObject_SetExtent
270 (
271 IOleObject *iface,
272 DWORD dwDrawAspect,
273 SIZEL *psizel
274 )
275 {
276 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
277 return S_OK;
278 }
279
280 static HRESULT WINAPI OleObject_GetExtent
281 (
282 IOleObject *iface,
283 DWORD dwDrawAspect,
284 SIZEL *psizel
285 )
286 {
287 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
288 return E_NOTIMPL;
289 }
290
291 static HRESULT WINAPI OleObject_Advise
292 (
293 IOleObject *iface,
294 IAdviseSink *pAdvSink,
295 DWORD *pdwConnection
296 )
297 {
298 CHECK_EXPECTED_METHOD("OleObject_Advise");
299 return S_OK;
300 }
301
302 static HRESULT WINAPI OleObject_Unadvise
303 (
304 IOleObject *iface,
305 DWORD dwConnection
306 )
307 {
308 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
309 return S_OK;
310 }
311
312 static HRESULT WINAPI OleObject_EnumAdvise
313 (
314 IOleObject *iface,
315 IEnumSTATDATA **ppenumAdvise
316 )
317 {
318 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
319 return E_NOTIMPL;
320 }
321
322 static HRESULT WINAPI OleObject_GetMiscStatus
323 (
324 IOleObject *iface,
325 DWORD dwAspect,
326 DWORD *pdwStatus
327 )
328 {
329 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
330 *pdwStatus = DVASPECT_CONTENT;
331 return S_OK;
332 }
333
334 static HRESULT WINAPI OleObject_SetColorScheme
335 (
336 IOleObject *iface,
337 LOGPALETTE *pLogpal
338 )
339 {
340 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
341 return E_NOTIMPL;
342 }
343
344 static const IOleObjectVtbl OleObjectVtbl =
345 {
346 OleObject_QueryInterface,
347 OleObject_AddRef,
348 OleObject_Release,
349 OleObject_SetClientSite,
350 OleObject_GetClientSite,
351 OleObject_SetHostNames,
352 OleObject_Close,
353 OleObject_SetMoniker,
354 OleObject_GetMoniker,
355 OleObject_InitFromData,
356 OleObject_GetClipboardData,
357 OleObject_DoVerb,
358 OleObject_EnumVerbs,
359 OleObject_Update,
360 OleObject_IsUpToDate,
361 OleObject_GetUserClassID,
362 OleObject_GetUserType,
363 OleObject_SetExtent,
364 OleObject_GetExtent,
365 OleObject_Advise,
366 OleObject_Unadvise,
367 OleObject_EnumAdvise,
368 OleObject_GetMiscStatus,
369 OleObject_SetColorScheme
370 };
371
372 static IOleObject OleObject = { &OleObjectVtbl };
373
374 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
375 {
376 trace("OleObjectPersistStg_QueryInterface\n");
377 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
378 }
379
380 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
381 {
382 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
383 return 2;
384 }
385
386 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
387 {
388 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
389 return 1;
390 }
391
392 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
393 {
394 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
395 return E_NOTIMPL;
396 }
397
398 static HRESULT WINAPI OleObjectPersistStg_IsDirty
399 (
400 IPersistStorage *iface
401 )
402 {
403 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
404 return S_OK;
405 }
406
407 static HRESULT WINAPI OleObjectPersistStg_InitNew
408 (
409 IPersistStorage *iface,
410 IStorage *pStg
411 )
412 {
413 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
414 return S_OK;
415 }
416
417 static HRESULT WINAPI OleObjectPersistStg_Load
418 (
419 IPersistStorage *iface,
420 IStorage *pStg
421 )
422 {
423 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
424 return S_OK;
425 }
426
427 static HRESULT WINAPI OleObjectPersistStg_Save
428 (
429 IPersistStorage *iface,
430 IStorage *pStgSave,
431 BOOL fSameAsLoad
432 )
433 {
434 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
435 return S_OK;
436 }
437
438 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
439 (
440 IPersistStorage *iface,
441 IStorage *pStgNew
442 )
443 {
444 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
445 return S_OK;
446 }
447
448 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
449 (
450 IPersistStorage *iface
451 )
452 {
453 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
454 return S_OK;
455 }
456
457 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
458 {
459 OleObjectPersistStg_QueryInterface,
460 OleObjectPersistStg_AddRef,
461 OleObjectPersistStg_Release,
462 OleObjectPersistStg_GetClassId,
463 OleObjectPersistStg_IsDirty,
464 OleObjectPersistStg_InitNew,
465 OleObjectPersistStg_Load,
466 OleObjectPersistStg_Save,
467 OleObjectPersistStg_SaveCompleted,
468 OleObjectPersistStg_HandsOffStorage
469 };
470
471 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
472
473 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
474 {
475 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
476 }
477
478 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
479 {
480 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
481 return 2;
482 }
483
484 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
485 {
486 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
487 return 1;
488 }
489
490 static HRESULT WINAPI OleObjectCache_Cache
491 (
492 IOleCache *iface,
493 FORMATETC *pformatetc,
494 DWORD advf,
495 DWORD *pdwConnection
496 )
497 {
498 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
499 return S_OK;
500 }
501
502 static HRESULT WINAPI OleObjectCache_Uncache
503 (
504 IOleCache *iface,
505 DWORD dwConnection
506 )
507 {
508 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
509 return S_OK;
510 }
511
512 static HRESULT WINAPI OleObjectCache_EnumCache
513 (
514 IOleCache *iface,
515 IEnumSTATDATA **ppenumSTATDATA
516 )
517 {
518 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
519 return S_OK;
520 }
521
522
523 static HRESULT WINAPI OleObjectCache_InitCache
524 (
525 IOleCache *iface,
526 IDataObject *pDataObject
527 )
528 {
529 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
530 return S_OK;
531 }
532
533
534 static HRESULT WINAPI OleObjectCache_SetData
535 (
536 IOleCache *iface,
537 FORMATETC *pformatetc,
538 STGMEDIUM *pmedium,
539 BOOL fRelease
540 )
541 {
542 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
543 return S_OK;
544 }
545
546
547 static const IOleCacheVtbl OleObjectCacheVtbl =
548 {
549 OleObjectCache_QueryInterface,
550 OleObjectCache_AddRef,
551 OleObjectCache_Release,
552 OleObjectCache_Cache,
553 OleObjectCache_Uncache,
554 OleObjectCache_EnumCache,
555 OleObjectCache_InitCache,
556 OleObjectCache_SetData
557 };
558
559 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
560
561 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
562 {
563 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
564 {
565 *ppv = iface;
566 IUnknown_AddRef(iface);
567 return S_OK;
568 }
569 *ppv = NULL;
570 return E_NOINTERFACE;
571 }
572
573 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
574 {
575 return 2;
576 }
577
578 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
579 {
580 return 1;
581 }
582
583 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
584 {
585 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
586 }
587
588 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
589 {
590 return S_OK;
591 }
592
593 static const IClassFactoryVtbl OleObjectCFVtbl =
594 {
595 OleObjectCF_QueryInterface,
596 OleObjectCF_AddRef,
597 OleObjectCF_Release,
598 OleObjectCF_CreateInstance,
599 OleObjectCF_LockServer
600 };
601
602 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
603
604 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
605 {
606 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
607 }
608
609 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
610 {
611 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
612 return 2;
613 }
614
615 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
616 {
617 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
618 return 1;
619 }
620
621 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
622 IRunnableObject *iface,
623 LPCLSID lpClsid)
624 {
625 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
626 return E_NOTIMPL;
627 }
628
629 static HRESULT WINAPI OleObjectRunnable_Run(
630 IRunnableObject *iface,
631 LPBINDCTX pbc)
632 {
633 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
634 return S_OK;
635 }
636
637 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
638 {
639 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
640 return g_isRunning;
641 }
642
643 static HRESULT WINAPI OleObjectRunnable_LockRunning(
644 IRunnableObject *iface,
645 BOOL fLock,
646 BOOL fLastUnlockCloses)
647 {
648 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
649 return S_OK;
650 }
651
652 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
653 IRunnableObject *iface,
654 BOOL fContained)
655 {
656 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
657 return S_OK;
658 }
659
660 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
661 {
662 OleObjectRunnable_QueryInterface,
663 OleObjectRunnable_AddRef,
664 OleObjectRunnable_Release,
665 OleObjectRunnable_GetRunningClass,
666 OleObjectRunnable_Run,
667 OleObjectRunnable_IsRunning,
668 OleObjectRunnable_LockRunning,
669 OleObjectRunnable_SetContainedObject
670 };
671
672 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
673
674 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
675
676 static void test_OleCreate(IStorage *pStorage)
677 {
678 HRESULT hr;
679 IOleObject *pObject;
680 FORMATETC formatetc;
681 static const struct expected_method methods_olerender_none[] =
682 {
683 { "OleObject_QueryInterface", 0 },
684 { "OleObject_AddRef", 0 },
685 { "OleObject_QueryInterface", 0 },
686 { "OleObject_AddRef", TEST_OPTIONAL },
687 { "OleObject_Release", TEST_OPTIONAL },
688 { "OleObject_QueryInterface", TEST_OPTIONAL },
689 { "OleObjectPersistStg_AddRef", 0 },
690 { "OleObjectPersistStg_InitNew", 0 },
691 { "OleObjectPersistStg_Release", 0 },
692 { "OleObject_Release", 0 },
693 { "OleObject_Release", TEST_OPTIONAL },
694 { NULL, 0 }
695 };
696 static const struct expected_method methods_olerender_draw[] =
697 {
698 { "OleObject_QueryInterface", 0 },
699 { "OleObject_AddRef", 0 },
700 { "OleObject_QueryInterface", 0 },
701 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
702 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
703 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
704 { "OleObjectPersistStg_AddRef", 0 },
705 { "OleObjectPersistStg_InitNew", 0 },
706 { "OleObjectPersistStg_Release", 0 },
707 { "OleObject_QueryInterface", 0 },
708 { "OleObjectRunnable_AddRef", 0 },
709 { "OleObjectRunnable_Run", 0 },
710 { "OleObjectRunnable_Release", 0 },
711 { "OleObject_QueryInterface", 0 },
712 { "OleObjectCache_AddRef", 0 },
713 { "OleObjectCache_Cache", 0 },
714 { "OleObjectCache_Release", 0 },
715 { "OleObject_Release", 0 },
716 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
717 { NULL, 0 }
718 };
719 static const struct expected_method methods_olerender_format[] =
720 {
721 { "OleObject_QueryInterface", 0 },
722 { "OleObject_AddRef", 0 },
723 { "OleObject_QueryInterface", 0 },
724 { "OleObject_AddRef", 0 },
725 { "OleObject_GetMiscStatus", 0 },
726 { "OleObject_QueryInterface", 0 },
727 { "OleObjectPersistStg_AddRef", 0 },
728 { "OleObjectPersistStg_InitNew", 0 },
729 { "OleObjectPersistStg_Release", 0 },
730 { "OleObject_SetClientSite", 0 },
731 { "OleObject_Release", 0 },
732 { "OleObject_QueryInterface", 0 },
733 { "OleObjectRunnable_AddRef", 0 },
734 { "OleObjectRunnable_Run", 0 },
735 { "OleObjectRunnable_Release", 0 },
736 { "OleObject_QueryInterface", 0 },
737 { "OleObjectCache_AddRef", 0 },
738 { "OleObjectCache_Cache", 0 },
739 { "OleObjectCache_Release", 0 },
740 { "OleObject_Release", 0 },
741 { NULL, 0 }
742 };
743 static const struct expected_method methods_olerender_asis[] =
744 {
745 { "OleObject_QueryInterface", 0 },
746 { "OleObject_AddRef", 0 },
747 { "OleObject_QueryInterface", 0 },
748 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
749 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
750 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
751 { "OleObjectPersistStg_AddRef", 0 },
752 { "OleObjectPersistStg_InitNew", 0 },
753 { "OleObjectPersistStg_Release", 0 },
754 { "OleObject_Release", 0 },
755 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
756 { NULL, 0 }
757 };
758 static const struct expected_method methods_olerender_draw_no_runnable[] =
759 {
760 { "OleObject_QueryInterface", 0 },
761 { "OleObject_AddRef", 0 },
762 { "OleObject_QueryInterface", 0 },
763 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
764 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
765 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
766 { "OleObjectPersistStg_AddRef", 0 },
767 { "OleObjectPersistStg_InitNew", 0 },
768 { "OleObjectPersistStg_Release", 0 },
769 { "OleObject_QueryInterface", 0 },
770 { "OleObject_QueryInterface", 0 },
771 { "OleObjectCache_AddRef", 0 },
772 { "OleObjectCache_Cache", 0 },
773 { "OleObjectCache_Release", 0 },
774 { "OleObject_Release", 0 },
775 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
776 { NULL, 0 },
777 };
778 static const struct expected_method methods_olerender_draw_no_cache[] =
779 {
780 { "OleObject_QueryInterface", 0 },
781 { "OleObject_AddRef", 0 },
782 { "OleObject_QueryInterface", 0 },
783 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
784 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
785 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
786 { "OleObjectPersistStg_AddRef", 0 },
787 { "OleObjectPersistStg_InitNew", 0 },
788 { "OleObjectPersistStg_Release", 0 },
789 { "OleObject_QueryInterface", 0 },
790 { "OleObjectRunnable_AddRef", 0 },
791 { "OleObjectRunnable_Run", 0 },
792 { "OleObjectRunnable_Release", 0 },
793 { "OleObject_QueryInterface", 0 },
794 { "OleObject_Release", 0 },
795 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
796 { NULL, 0 }
797 };
798
799 runnable = &OleObjectRunnable;
800 cache = &OleObjectCache;
801 expected_method_list = methods_olerender_none;
802 trace("OleCreate with OLERENDER_NONE:\n");
803 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
804 ok_ole_success(hr, "OleCreate");
805 IOleObject_Release(pObject);
806 CHECK_NO_EXTRA_METHODS();
807
808 expected_method_list = methods_olerender_draw;
809 trace("OleCreate with OLERENDER_DRAW:\n");
810 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
811 ok_ole_success(hr, "OleCreate");
812 IOleObject_Release(pObject);
813 CHECK_NO_EXTRA_METHODS();
814
815 formatetc.cfFormat = CF_TEXT;
816 formatetc.ptd = NULL;
817 formatetc.dwAspect = DVASPECT_CONTENT;
818 formatetc.lindex = -1;
819 formatetc.tymed = TYMED_HGLOBAL;
820 expected_method_list = methods_olerender_format;
821 trace("OleCreate with OLERENDER_FORMAT:\n");
822 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
823 ok(hr == S_OK ||
824 broken(hr == E_INVALIDARG), /* win2k */
825 "OleCreate failed with error 0x%08x\n", hr);
826 if (pObject)
827 {
828 IOleObject_Release(pObject);
829 CHECK_NO_EXTRA_METHODS();
830 }
831
832 expected_method_list = methods_olerender_asis;
833 trace("OleCreate with OLERENDER_ASIS:\n");
834 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
835 ok_ole_success(hr, "OleCreate");
836 IOleObject_Release(pObject);
837 CHECK_NO_EXTRA_METHODS();
838
839 runnable = NULL;
840 expected_method_list = methods_olerender_draw_no_runnable;
841 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
842 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
843 ok_ole_success(hr, "OleCreate");
844 IOleObject_Release(pObject);
845 CHECK_NO_EXTRA_METHODS();
846
847 runnable = &OleObjectRunnable;
848 cache = NULL;
849 expected_method_list = methods_olerender_draw_no_cache;
850 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
851 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
852 ok_ole_success(hr, "OleCreate");
853 IOleObject_Release(pObject);
854 CHECK_NO_EXTRA_METHODS();
855 trace("end\n");
856 }
857
858 static void test_OleLoad(IStorage *pStorage)
859 {
860 HRESULT hr;
861 IOleObject *pObject;
862
863 static const struct expected_method methods_oleload[] =
864 {
865 { "OleObject_QueryInterface", 0 },
866 { "OleObject_AddRef", 0 },
867 { "OleObject_QueryInterface", 0 },
868 { "OleObject_AddRef", 0 },
869 { "OleObject_GetMiscStatus", 0 },
870 { "OleObject_QueryInterface", 0 },
871 { "OleObjectPersistStg_AddRef", 0 },
872 { "OleObjectPersistStg_Load", 0 },
873 { "OleObjectPersistStg_Release", 0 },
874 { "OleObject_SetClientSite", 0 },
875 { "OleObject_Release", 0 },
876 { "OleObject_QueryInterface", 0 },
877 { "OleObject_Release", 0 },
878 { NULL, 0 }
879 };
880
881 expected_method_list = methods_oleload;
882 trace("OleLoad:\n");
883 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
884 ok(hr == S_OK ||
885 broken(hr == E_INVALIDARG), /* win98 and win2k */
886 "OleLoad failed with error 0x%08x\n", hr);
887 if (pObject)
888 {
889 IOleObject_Release(pObject);
890 CHECK_NO_EXTRA_METHODS();
891 }
892 }
893
894 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
895 {
896 CHECK_EXPECTED_METHOD("draw_continue");
897 return TRUE;
898 }
899
900 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
901 {
902 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
903 {
904 *ppv = iface;
905 IUnknown_AddRef(iface);
906 return S_OK;
907 }
908 *ppv = NULL;
909 return E_NOINTERFACE;
910 }
911
912 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
913 {
914 return 2;
915 }
916
917 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
918 {
919 return 1;
920 }
921
922
923 static void WINAPI AdviseSink_OnDataChange(
924 IAdviseSink *iface,
925 FORMATETC *pFormatetc,
926 STGMEDIUM *pStgmed)
927 {
928 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
929 }
930
931 static void WINAPI AdviseSink_OnViewChange(
932 IAdviseSink *iface,
933 DWORD dwAspect,
934 LONG lindex)
935 {
936 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
937 }
938
939 static void WINAPI AdviseSink_OnRename(
940 IAdviseSink *iface,
941 IMoniker *pmk)
942 {
943 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
944 }
945
946 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
947 {
948 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
949 }
950
951 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
952 {
953 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
954 }
955
956 static const IAdviseSinkVtbl AdviseSinkVtbl =
957 {
958 AdviseSink_QueryInterface,
959 AdviseSink_AddRef,
960 AdviseSink_Release,
961 AdviseSink_OnDataChange,
962 AdviseSink_OnViewChange,
963 AdviseSink_OnRename,
964 AdviseSink_OnSave,
965 AdviseSink_OnClose
966 };
967
968 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
969
970 static HRESULT WINAPI DataObject_QueryInterface(
971 IDataObject* iface,
972 REFIID riid,
973 void** ppvObject)
974 {
975 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
976 {
977 *ppvObject = iface;
978 return S_OK;
979 }
980 *ppvObject = NULL;
981 return S_OK;
982 }
983
984 static ULONG WINAPI DataObject_AddRef(
985 IDataObject* iface)
986 {
987 return 2;
988 }
989
990 static ULONG WINAPI DataObject_Release(
991 IDataObject* iface)
992 {
993 return 1;
994 }
995
996 static HRESULT WINAPI DataObject_GetData(
997 IDataObject* iface,
998 LPFORMATETC pformatetcIn,
999 STGMEDIUM* pmedium)
1000 {
1001 CHECK_EXPECTED_METHOD("DataObject_GetData");
1002 return E_NOTIMPL;
1003 }
1004
1005 static HRESULT WINAPI DataObject_GetDataHere(
1006 IDataObject* iface,
1007 LPFORMATETC pformatetc,
1008 STGMEDIUM* pmedium)
1009 {
1010 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1011 return E_NOTIMPL;
1012 }
1013
1014 static HRESULT WINAPI DataObject_QueryGetData(
1015 IDataObject* iface,
1016 LPFORMATETC pformatetc)
1017 {
1018 CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1019 return S_OK;
1020 }
1021
1022 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1023 IDataObject* iface,
1024 LPFORMATETC pformatectIn,
1025 LPFORMATETC pformatetcOut)
1026 {
1027 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1028 return E_NOTIMPL;
1029 }
1030
1031 static HRESULT WINAPI DataObject_SetData(
1032 IDataObject* iface,
1033 LPFORMATETC pformatetc,
1034 STGMEDIUM* pmedium,
1035 BOOL fRelease)
1036 {
1037 CHECK_EXPECTED_METHOD("DataObject_SetData");
1038 return E_NOTIMPL;
1039 }
1040
1041 static HRESULT WINAPI DataObject_EnumFormatEtc(
1042 IDataObject* iface,
1043 DWORD dwDirection,
1044 IEnumFORMATETC** ppenumFormatEtc)
1045 {
1046 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1047 return E_NOTIMPL;
1048 }
1049
1050 static HRESULT WINAPI DataObject_DAdvise(
1051 IDataObject* iface,
1052 FORMATETC* pformatetc,
1053 DWORD advf,
1054 IAdviseSink* pAdvSink,
1055 DWORD* pdwConnection)
1056 {
1057 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1058 *pdwConnection = 1;
1059 return S_OK;
1060 }
1061
1062 static HRESULT WINAPI DataObject_DUnadvise(
1063 IDataObject* iface,
1064 DWORD dwConnection)
1065 {
1066 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1067 return S_OK;
1068 }
1069
1070 static HRESULT WINAPI DataObject_EnumDAdvise(
1071 IDataObject* iface,
1072 IEnumSTATDATA** ppenumAdvise)
1073 {
1074 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1075 return OLE_E_ADVISENOTSUPPORTED;
1076 }
1077
1078 static IDataObjectVtbl DataObjectVtbl =
1079 {
1080 DataObject_QueryInterface,
1081 DataObject_AddRef,
1082 DataObject_Release,
1083 DataObject_GetData,
1084 DataObject_GetDataHere,
1085 DataObject_QueryGetData,
1086 DataObject_GetCanonicalFormatEtc,
1087 DataObject_SetData,
1088 DataObject_EnumFormatEtc,
1089 DataObject_DAdvise,
1090 DataObject_DUnadvise,
1091 DataObject_EnumDAdvise
1092 };
1093
1094 static IDataObject DataObject = { &DataObjectVtbl };
1095
1096 static void test_data_cache(void)
1097 {
1098 HRESULT hr;
1099 IOleCache2 *pOleCache;
1100 IStorage *pStorage;
1101 IPersistStorage *pPS;
1102 IViewObject *pViewObject;
1103 IOleCacheControl *pOleCacheControl;
1104 FORMATETC fmtetc;
1105 STGMEDIUM stgmedium;
1106 DWORD dwConnection;
1107 DWORD dwFreeze;
1108 RECTL rcBounds;
1109 HDC hdcMem;
1110 CLSID clsid;
1111 char szSystemDir[MAX_PATH];
1112 WCHAR wszPath[MAX_PATH];
1113 static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1114
1115 static const struct expected_method methods_cacheinitnew[] =
1116 {
1117 { "AdviseSink_OnViewChange", 0 },
1118 { "AdviseSink_OnViewChange", 0 },
1119 { "draw_continue", 0 },
1120 { "DataObject_DAdvise", 0 },
1121 { "DataObject_DAdvise", 0 },
1122 { "DataObject_DUnadvise", 0 },
1123 { "DataObject_DUnadvise", 0 },
1124 { NULL, 0 }
1125 };
1126 static const struct expected_method methods_cacheload[] =
1127 {
1128 { "AdviseSink_OnViewChange", 0 },
1129 { "draw_continue", 0 },
1130 { "draw_continue", 0 },
1131 { "draw_continue", 0 },
1132 { "DataObject_GetData", 0 },
1133 { "DataObject_GetData", 0 },
1134 { "DataObject_GetData", 0 },
1135 { NULL, 0 }
1136 };
1137
1138 GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1139
1140 expected_method_list = methods_cacheinitnew;
1141
1142 fmtetc.cfFormat = CF_METAFILEPICT;
1143 fmtetc.dwAspect = DVASPECT_ICON;
1144 fmtetc.lindex = -1;
1145 fmtetc.ptd = NULL;
1146 fmtetc.tymed = TYMED_MFPICT;
1147
1148 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1149 ok_ole_success(hr, "StgCreateDocfile");
1150
1151 /* Test with new data */
1152
1153 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1154 ok_ole_success(hr, "CreateDataCache");
1155
1156 hr = IOleCache_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1157 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1158 hr = IOleCache_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1159 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1160 hr = IOleCache_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1161 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1162
1163 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1164 ok_ole_success(hr, "IViewObject_SetAdvise");
1165
1166 hr = IPersistStorage_InitNew(pPS, pStorage);
1167 ok_ole_success(hr, "IPersistStorage_InitNew");
1168
1169 hr = IPersistStorage_IsDirty(pPS);
1170 ok_ole_success(hr, "IPersistStorage_IsDirty");
1171
1172 hr = IPersistStorage_GetClassID(pPS, &clsid);
1173 ok_ole_success(hr, "IPersistStorage_GetClassID");
1174 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1175
1176 hr = IOleCache_Uncache(pOleCache, 0xdeadbeef);
1177 ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1178
1179 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1180 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1181 {
1182 hr = IOleCache_Cache(pOleCache, NULL, 0, &dwConnection);
1183 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1184
1185 hr = IOleCache_Cache(pOleCache, NULL, 0, NULL);
1186 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1187 }
1188 else
1189 {
1190 skip("tests with NULL parameters will crash on NT4 and below\n");
1191 }
1192
1193 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1194 {
1195 int i;
1196 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1197 for (i = 0; i < 7; i++)
1198 {
1199 fmtetc.tymed = 1 << i;
1200 hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1201 if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1202 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1203 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1204 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1205 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1206 fmtetc.cfFormat, fmtetc.tymed, hr);
1207 else if (fmtetc.tymed == TYMED_HGLOBAL)
1208 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED ||
1209 broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1210 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1211 fmtetc.cfFormat, fmtetc.tymed, hr);
1212 else
1213 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1214 fmtetc.cfFormat, fmtetc.tymed, hr);
1215 if (SUCCEEDED(hr))
1216 {
1217 hr = IOleCache_Uncache(pOleCache, dwConnection);
1218 ok_ole_success(hr, "IOleCache_Uncache");
1219 }
1220 }
1221 }
1222
1223 fmtetc.cfFormat = CF_BITMAP;
1224 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1225 fmtetc.tymed = TYMED_GDI;
1226 hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1227 ok_ole_success(hr, "IOleCache_Cache");
1228
1229 fmtetc.cfFormat = 0;
1230 fmtetc.dwAspect = DVASPECT_ICON;
1231 fmtetc.tymed = TYMED_MFPICT;
1232 hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1233 ok_ole_success(hr, "IOleCache_Cache");
1234
1235 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1236 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1237
1238 fmtetc.cfFormat = CF_METAFILEPICT;
1239 stgmedium.tymed = TYMED_MFPICT;
1240 U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1241 LoadIcon(NULL, IDI_APPLICATION), wszPath, wszPath, 0);
1242 stgmedium.pUnkForRelease = NULL;
1243
1244 fmtetc.dwAspect = DVASPECT_CONTENT;
1245 hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1246 ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1247
1248 fmtetc.dwAspect = DVASPECT_ICON;
1249 hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1250 ok_ole_success(hr, "IOleCache_SetData");
1251
1252 hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1253 todo_wine {
1254 ok_ole_success(hr, "IViewObject_Freeze");
1255 hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1256 ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1257 }
1258
1259 rcBounds.left = 0;
1260 rcBounds.top = 0;
1261 rcBounds.right = 100;
1262 rcBounds.bottom = 100;
1263 hdcMem = CreateCompatibleDC(NULL);
1264
1265 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1266 ok_ole_success(hr, "IViewObject_Draw");
1267
1268 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1269 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1270
1271 DeleteDC(hdcMem);
1272
1273 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1274 todo_wine {
1275 ok_ole_success(hr, "IOleCacheControl_OnRun");
1276 }
1277
1278 hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1279 ok_ole_success(hr, "IPersistStorage_Save");
1280
1281 hr = IPersistStorage_SaveCompleted(pPS, NULL);
1282 ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1283
1284 hr = IPersistStorage_IsDirty(pPS);
1285 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1286
1287 IPersistStorage_Release(pPS);
1288 IViewObject_Release(pViewObject);
1289 IOleCache_Release(pOleCache);
1290 IOleCacheControl_Release(pOleCacheControl);
1291
1292 todo_wine {
1293 CHECK_NO_EXTRA_METHODS();
1294 }
1295
1296 /* Test with loaded data */
1297 trace("Testing loaded data with CreateDataCache:\n");
1298 expected_method_list = methods_cacheload;
1299
1300 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1301 ok_ole_success(hr, "CreateDataCache");
1302
1303 hr = IOleCache_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1304 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1305 hr = IOleCache_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1306 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1307
1308 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1309 ok_ole_success(hr, "IViewObject_SetAdvise");
1310
1311 hr = IPersistStorage_Load(pPS, pStorage);
1312 ok_ole_success(hr, "IPersistStorage_Load");
1313
1314 hr = IPersistStorage_IsDirty(pPS);
1315 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1316
1317 fmtetc.cfFormat = 0;
1318 fmtetc.dwAspect = DVASPECT_ICON;
1319 fmtetc.lindex = -1;
1320 fmtetc.ptd = NULL;
1321 fmtetc.tymed = TYMED_MFPICT;
1322 hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1323 ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1324
1325 rcBounds.left = 0;
1326 rcBounds.top = 0;
1327 rcBounds.right = 100;
1328 rcBounds.bottom = 100;
1329 hdcMem = CreateCompatibleDC(NULL);
1330
1331 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1332 ok_ole_success(hr, "IViewObject_Draw");
1333
1334 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1335 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1336
1337 /* unload the cached storage object, causing it to be reloaded */
1338 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1339 ok_ole_success(hr, "IOleCache2_DiscardCache");
1340 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1341 ok_ole_success(hr, "IViewObject_Draw");
1342
1343 /* unload the cached storage object, but don't allow it to be reloaded */
1344 hr = IPersistStorage_HandsOffStorage(pPS);
1345 ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1346 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1347 ok_ole_success(hr, "IViewObject_Draw");
1348 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1349 ok_ole_success(hr, "IOleCache2_DiscardCache");
1350 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1351 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1352
1353 DeleteDC(hdcMem);
1354
1355 todo_wine {
1356 hr = IOleCache_InitCache(pOleCache, &DataObject);
1357 ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1358 }
1359
1360 IPersistStorage_Release(pPS);
1361 IViewObject_Release(pViewObject);
1362 IOleCache_Release(pOleCache);
1363
1364 todo_wine {
1365 CHECK_NO_EXTRA_METHODS();
1366 }
1367
1368 IStorage_Release(pStorage);
1369 ReleaseStgMedium(&stgmedium);
1370 }
1371
1372 static void test_default_handler(void)
1373 {
1374 HRESULT hr;
1375 IOleObject *pObject;
1376 IRunnableObject *pRunnableObject;
1377 IOleClientSite *pClientSite;
1378 IDataObject *pDataObject;
1379 SIZEL sizel;
1380 DWORD dwStatus;
1381 CLSID clsid;
1382 LPOLESTR pszUserType;
1383 LOGPALETTE palette;
1384 DWORD dwAdvConn;
1385 IMoniker *pMoniker;
1386 FORMATETC fmtetc;
1387 IOleInPlaceObject *pInPlaceObj;
1388 IEnumOLEVERB *pEnumVerbs;
1389 static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
1390 static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
1391 static const WCHAR wszDelim[] = {'!',0};
1392
1393 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
1394 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1395
1396 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
1397 ok_ole_success(hr, "OleCreateDefaultHandler");
1398
1399 hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
1400 ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
1401
1402 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
1403 ok_ole_success(hr, "IOleObject_Advise");
1404
1405 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1406 ok_ole_success(hr, "IOleObject_Close");
1407
1408 /* FIXME: test IOleObject_EnumAdvise */
1409
1410 hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
1411 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1412
1413 hr = IOleObject_GetClientSite(pObject, &pClientSite);
1414 ok_ole_success(hr, "IOleObject_GetClientSite");
1415
1416 hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
1417 ok(hr == OLE_E_NOTRUNNING,
1418 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
1419 hr);
1420
1421 hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
1422 ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
1423 hr);
1424
1425 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1426 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1427
1428 hr = IOleObject_GetUserClassID(pObject, &clsid);
1429 ok_ole_success(hr, "IOleObject_GetUserClassID");
1430 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
1431
1432 hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
1433 todo_wine {
1434 ok_ole_success(hr, "IOleObject_GetUserType");
1435 ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
1436 }
1437
1438 hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
1439 ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1440
1441 hr = IOleObject_IsUpToDate(pObject);
1442 ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1443
1444 palette.palNumEntries = 1;
1445 palette.palVersion = 2;
1446 memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
1447 hr = IOleObject_SetColorScheme(pObject, &palette);
1448 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1449
1450 sizel.cx = sizel.cy = 0;
1451 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
1452
1453 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
1454 ok_ole_success(hr, "IOleObject_SetHostNames");
1455
1456 hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
1457 ok_ole_success(hr, "CreateItemMoniker");
1458 hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
1459 ok_ole_success(hr, "IOleObject_SetMoniker");
1460 IMoniker_Release(pMoniker);
1461
1462 hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
1463 ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
1464
1465 hr = IOleObject_Update(pObject);
1466 todo_wine
1467 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1468
1469 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
1470 ok_ole_success(hr, "IOleObject_QueryInterface");
1471
1472 fmtetc.cfFormat = CF_TEXT;
1473 fmtetc.ptd = NULL;
1474 fmtetc.dwAspect = DVASPECT_CONTENT;
1475 fmtetc.lindex = -1;
1476 fmtetc.tymed = TYMED_NULL;
1477 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
1478 ok_ole_success(hr, "IDataObject_DAdvise");
1479
1480 fmtetc.cfFormat = CF_ENHMETAFILE;
1481 fmtetc.ptd = NULL;
1482 fmtetc.dwAspect = DVASPECT_CONTENT;
1483 fmtetc.lindex = -1;
1484 fmtetc.tymed = TYMED_ENHMF;
1485 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
1486 ok_ole_success(hr, "IDataObject_DAdvise");
1487
1488 fmtetc.cfFormat = CF_ENHMETAFILE;
1489 fmtetc.ptd = NULL;
1490 fmtetc.dwAspect = DVASPECT_CONTENT;
1491 fmtetc.lindex = -1;
1492 fmtetc.tymed = TYMED_ENHMF;
1493 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
1494 todo_wine
1495 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1496
1497 fmtetc.cfFormat = CF_TEXT;
1498 fmtetc.ptd = NULL;
1499 fmtetc.dwAspect = DVASPECT_CONTENT;
1500 fmtetc.lindex = -1;
1501 fmtetc.tymed = TYMED_NULL;
1502 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
1503 todo_wine
1504 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1505
1506 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
1507 ok_ole_success(hr, "IOleObject_QueryInterface");
1508
1509 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
1510 ok_ole_success(hr, "IRunnableObject_SetContainedObject");
1511
1512 hr = IRunnableObject_Run(pRunnableObject, NULL);
1513 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1514
1515 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1516 ok_ole_success(hr, "IOleObject_Close");
1517
1518 IRunnableObject_Release(pRunnableObject);
1519 IOleObject_Release(pObject);
1520 }
1521
1522 static void test_runnable(void)
1523 {
1524 static const struct expected_method methods_query_runnable[] =
1525 {
1526 { "OleObject_QueryInterface", 0 },
1527 { "OleObjectRunnable_AddRef", 0 },
1528 { "OleObjectRunnable_IsRunning", 0 },
1529 { "OleObjectRunnable_Release", 0 },
1530 { NULL, 0 }
1531 };
1532
1533 static const struct expected_method methods_no_runnable[] =
1534 {
1535 { "OleObject_QueryInterface", 0 },
1536 { NULL, 0 }
1537 };
1538
1539 IOleObject *object = &OleObject;
1540
1541 expected_method_list = methods_query_runnable;
1542 ok(OleIsRunning(object), "Object should be running\n");
1543 CHECK_NO_EXTRA_METHODS();
1544
1545 g_isRunning = FALSE;
1546 expected_method_list = methods_query_runnable;
1547 ok(OleIsRunning(object) == FALSE, "Object should not be running\n");
1548 CHECK_NO_EXTRA_METHODS();
1549
1550 g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */
1551 expected_method_list = methods_no_runnable;
1552 ok(OleIsRunning(object), "Object without IRunnableObject should be running\n");
1553 CHECK_NO_EXTRA_METHODS();
1554
1555 g_isRunning = TRUE;
1556 g_showRunnable = TRUE;
1557 }
1558
1559 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1560 {
1561 *ppv = NULL;
1562 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1563 if (*ppv)
1564 {
1565 IUnknown_AddRef((IUnknown *)*ppv);
1566 return S_OK;
1567 }
1568 return E_NOINTERFACE;
1569 }
1570
1571 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
1572 {
1573 return 2;
1574 }
1575
1576 static ULONG WINAPI Unknown_Release(IUnknown *iface)
1577 {
1578 return 1;
1579 }
1580
1581 static const IUnknownVtbl UnknownVtbl =
1582 {
1583 Unknown_QueryInterface,
1584 Unknown_AddRef,
1585 Unknown_Release
1586 };
1587
1588 static IUnknown Unknown = { &UnknownVtbl };
1589
1590 static void test_OleLockRunning(void)
1591 {
1592 HRESULT hr;
1593
1594 hr = OleLockRunning((LPUNKNOWN)&Unknown, TRUE, FALSE);
1595 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
1596 }
1597
1598 START_TEST(ole2)
1599 {
1600 DWORD dwRegister;
1601 IStorage *pStorage;
1602 STATSTG statstg;
1603 HRESULT hr;
1604
1605 CoInitialize(NULL);
1606
1607 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
1608 ok_ole_success(hr, "CoRegisterClassObject");
1609
1610 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1611 ok_ole_success(hr, "StgCreateDocfile");
1612
1613 test_OleCreate(pStorage);
1614
1615 hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
1616 ok_ole_success(hr, "IStorage_Stat");
1617 ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
1618
1619 test_OleLoad(pStorage);
1620
1621 IStorage_Release(pStorage);
1622
1623 hr = CoRevokeClassObject(dwRegister);
1624 ok_ole_success(hr, "CoRevokeClassObject");
1625
1626 test_data_cache();
1627 test_default_handler();
1628 test_runnable();
1629 test_OleLockRunning();
1630
1631 CoUninitialize();
1632 }