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