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