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