2 * OLEPICTURE test program
4 * Copyright 2005 Marcus Meissner
5 * Copyright 2012 Dmitry Timoshkov
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.
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.
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
29 #define NONAMELESSUNION
31 #include "wine/test.h"
45 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
47 #define ole_expect(expr, expect) { \
49 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
52 #define ole_check(expr) ole_expect(expr, S_OK);
54 static HMODULE hOleaut32
;
56 static HRESULT (WINAPI
*pOleLoadPicture
)(LPSTREAM
,LONG
,BOOL
,REFIID
,LPVOID
*);
57 static HRESULT (WINAPI
*pOleLoadPictureEx
)(LPSTREAM
,LONG
,BOOL
,REFIID
,DWORD
,DWORD
,DWORD
,LPVOID
*);
59 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
62 static const unsigned char gifimage
[35] = {
63 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
64 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
69 static const unsigned char jpgimage
[285] = {
70 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
71 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
72 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
73 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
74 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
75 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
76 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
77 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
78 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
79 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
80 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
81 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
83 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
84 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
85 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
86 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
87 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
91 static const unsigned char pngimage
[285] = {
92 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
93 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
94 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
95 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
96 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
97 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
98 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
102 static const unsigned char bmpimage
[66] = {
103 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
104 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
105 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
106 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
111 static const unsigned char gif4pixel
[42] = {
112 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
113 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
114 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
117 /* APM with an empty metafile with some padding zeros - looks like under Window the
118 * metafile data should be at least 20 bytes */
119 static const unsigned char apmdata
[] = {
120 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
121 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
122 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
123 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
126 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
127 static const unsigned char metafile
[] = {
128 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
131 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
132 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
133 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
137 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
138 static const unsigned char enhmetafile
[] = {
139 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
144 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
145 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
146 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
149 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
152 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
153 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
154 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
156 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
158 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
159 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
162 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
163 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
164 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
165 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
166 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
167 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
169 0x14, 0x00, 0x00, 0x00
173 typedef struct NoStatStreamImpl
175 IStream IStream_iface
;
178 HGLOBAL supportHandle
;
179 ULARGE_INTEGER streamSize
;
180 ULARGE_INTEGER currentPosition
;
183 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
);
186 test_pic_with_stream(LPSTREAM stream
, unsigned int imgsize
)
188 IPicture
* pic
= NULL
;
191 OLE_HANDLE handle
, hPal
;
192 OLE_XSIZE_HIMETRIC width
;
193 OLE_YSIZE_HIMETRIC height
;
199 hres
= pOleLoadPicture(stream
, imgsize
, TRUE
, &IID_IPicture
, &pvObj
);
202 ok(hres
== S_OK
,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres
);
203 ok(pic
!= NULL
,"OLP (NULL,..) returns NULL, instead of !NULL\n");
208 hres
= IPicture_QueryInterface (pic
, &IID_IPicture
, &pvObj
);
210 ok(hres
== S_OK
,"IPicture_QI does not return S_OK, but 0x%08x\n", hres
);
211 ok(pvObj
!= NULL
,"IPicture_QI does return NULL, instead of a ptr\n");
213 IPicture_Release ((IPicture
*)pvObj
);
216 hres
= IPicture_get_Handle (pic
, &handle
);
217 ok(hres
== S_OK
,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres
);
218 ok(handle
!= 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
223 GetObjectA(UlongToHandle(handle
), sizeof(BITMAP
), &bmp
);
224 todo_wine
ok(bmp
.bmBits
!= 0, "not a dib\n");
228 hres
= IPicture_get_Width (pic
, &width
);
229 ok(hres
== S_OK
,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres
);
230 ok(width
!= 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
233 hres
= IPicture_get_Height (pic
, &height
);
234 ok(hres
== S_OK
,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres
);
235 ok(height
!= 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
238 hres
= IPicture_get_Type (pic
, &type
);
239 ok(hres
== S_OK
,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
240 ok(type
== PICTYPE_BITMAP
, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type
, PICTYPE_BITMAP
);
243 hres
= IPicture_get_Attributes (pic
, &attr
);
244 ok(hres
== S_OK
,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres
);
245 ok(attr
== 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr
);
248 hres
= IPicture_get_hPal (pic
, &hPal
);
249 ok(hres
== S_OK
,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres
);
250 /* a single pixel b/w image has no palette */
251 ok(hPal
== 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal
);
253 res
= IPicture_Release (pic
);
254 ok (res
== 0, "refcount after release is %d, but should be 0?\n", res
);
258 test_pic(const unsigned char *imgdata
, unsigned int imgsize
)
264 LARGE_INTEGER seekto
;
265 ULARGE_INTEGER newpos1
;
269 /* Let the fun begin */
270 hglob
= GlobalAlloc (0, imgsize
);
271 data
= GlobalLock (hglob
);
272 memcpy(data
, imgdata
, imgsize
);
273 GlobalUnlock(hglob
); data
= NULL
;
275 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
276 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
278 memset(&seekto
,0,sizeof(seekto
));
279 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
280 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
281 test_pic_with_stream(stream
, imgsize
);
283 IStream_Release(stream
);
285 /* again with Non Statable and Non Seekable stream */
286 stream
= NoStatStream_Construct(hglob
);
287 hglob
= 0; /* Non-statable impl always deletes on release */
288 test_pic_with_stream(stream
, 0);
290 IStream_Release(stream
);
291 for (i
= 1; i
<= 8; i
++) {
293 hglob
= GlobalAlloc (0, imgsize
+ i
* (2 * sizeof(DWORD
)));
294 data
= GlobalLock (hglob
);
295 header
= (DWORD
*)data
;
297 /* multiple copies of header */
298 memcpy(data
,"lt\0\0",4);
300 for (j
= 2; j
<= i
; j
++) {
301 memcpy(&(header
[2 * (j
- 1)]), header
, 2 * sizeof(DWORD
));
303 memcpy(data
+ i
* (2 * sizeof(DWORD
)), imgdata
, imgsize
);
304 GlobalUnlock(hglob
); data
= NULL
;
306 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
307 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
309 memset(&seekto
,0,sizeof(seekto
));
310 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
311 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
312 test_pic_with_stream(stream
, imgsize
);
314 IStream_Release(stream
);
316 /* again with Non Statable and Non Seekable stream */
317 stream
= NoStatStream_Construct(hglob
);
318 hglob
= 0; /* Non-statable impl always deletes on release */
319 test_pic_with_stream(stream
, 0);
321 IStream_Release(stream
);
325 static void test_empty_image(void) {
328 IPicture
* pic
= NULL
;
333 ULARGE_INTEGER newpos1
;
334 LARGE_INTEGER seekto
;
338 /* Empty image. Happens occasionally in VB programs. */
339 hglob
= GlobalAlloc (0, 8);
340 data
= GlobalLock (hglob
);
341 memcpy(data
,"lt\0\0",4);
342 ((DWORD
*)data
)[1] = 0;
343 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
344 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
346 memset(&seekto
,0,sizeof(seekto
));
347 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
348 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
351 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
353 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
354 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
356 hres
= IPicture_get_Type (pic
, &type
);
357 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
358 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
361 hres
= IPicture_get_Attributes (pic
, &attr
);
362 ok (hres
== S_OK
,"empty picture get attributes failed with hres 0x%08x\n", hres
);
363 ok (attr
== 0,"attr is %d, but should be 0\n", attr
);
365 hres
= IPicture_get_Handle (pic
, &handle
);
366 ok (hres
== S_OK
,"empty picture get handle failed with hres 0x%08x\n", hres
);
367 ok (handle
== 0, "empty picture get handle did not return 0, but 0x%08x\n", handle
);
368 IPicture_Release (pic
);
369 IStream_Release (stream
);
372 static void test_empty_image_2(void) {
375 IPicture
* pic
= NULL
;
379 ULARGE_INTEGER newpos1
;
380 LARGE_INTEGER seekto
;
383 /* Empty image at random stream position. */
384 hglob
= GlobalAlloc (0, 200);
385 data
= GlobalLock (hglob
);
387 memcpy(data
,"lt\0\0",4);
388 ((DWORD
*)data
)[1] = 0;
389 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
390 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
392 memset(&seekto
,0,sizeof(seekto
));
393 seekto
.u
.LowPart
= 42;
394 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
395 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
398 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
400 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
401 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
403 hres
= IPicture_get_Type (pic
, &type
);
404 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
405 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
407 IPicture_Release (pic
);
408 IStream_Release (stream
);
411 static void test_Invoke(void)
413 IPictureDisp
*picdisp
;
415 VARIANTARG vararg
, args
[10];
416 DISPPARAMS dispparams
;
424 hglob
= GlobalAlloc (0, sizeof(gifimage
));
425 data
= GlobalLock(hglob
);
426 memcpy(data
, gifimage
, sizeof(gifimage
));
429 hr
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
430 ok_ole_success(hr
, "CreateStreamOnHGlobal");
432 hr
= pOleLoadPicture(stream
, sizeof(gifimage
), TRUE
, &IID_IPictureDisp
, (void **)&picdisp
);
433 IStream_Release(stream
);
435 ok_ole_success(hr
, "OleLoadPicture");
437 V_VT(&vararg
) = VT_BOOL
;
438 V_BOOL(&vararg
) = VARIANT_FALSE
;
439 dispparams
.cNamedArgs
= 0;
440 dispparams
.rgdispidNamedArgs
= NULL
;
441 dispparams
.cArgs
= 1;
442 dispparams
.rgvarg
= &vararg
;
443 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IPictureDisp
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
444 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
445 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
446 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
448 dispparams
.cArgs
= 0;
449 dispparams
.rgvarg
= NULL
;
450 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
451 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
453 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, NULL
, NULL
, NULL
);
454 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
456 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
457 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
459 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, &varresult
, NULL
, NULL
);
460 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
462 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
463 ok_ole_success(hr
, "IPictureDisp_Invoke");
464 ok(V_VT(&varresult
) == VT_I4
, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult
));
466 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
467 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
469 hr
= IPictureDisp_Invoke(picdisp
, 0xdeadbeef, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
470 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
472 dispparams
.cArgs
= 1;
473 dispparams
.rgvarg
= &vararg
;
474 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
475 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
477 dispparams
.cArgs
= 1;
478 dispparams
.rgvarg
= &vararg
;
479 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
480 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
482 /* DISPID_PICT_RENDER */
485 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
486 V_VT(&args
[i
]) = VT_I4
;
497 V_I4(&args
[9]) = HandleToLong(hdc
);
499 dispparams
.rgvarg
= args
;
500 dispparams
.rgdispidNamedArgs
= NULL
;
501 dispparams
.cArgs
= 10;
502 dispparams
.cNamedArgs
= 0;
504 V_VT(&varresult
) = VT_EMPTY
;
505 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
506 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
508 /* Try with one argument set to VT_I2, it'd still work if coerced. */
509 V_VT(&args
[3]) = VT_I2
;
510 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
511 ok(hr
== DISP_E_TYPEMISMATCH
, "got 0x%08x\n", hr
);
512 V_VT(&args
[3]) = VT_I4
;
514 /* Wrong argument count */
515 dispparams
.cArgs
= 9;
516 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
517 ok(hr
== DISP_E_BADPARAMCOUNT
, "got 0x%08x\n", hr
);
519 ReleaseDC(NULL
, hdc
);
520 IPictureDisp_Release(picdisp
);
523 static void test_OleCreatePictureIndirect(void)
532 /* crashes on native */
533 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, NULL
);
536 hr
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void**)&pict
);
537 ok(hr
== S_OK
, "hr %08x\n", hr
);
540 hr
= IPicture_get_Type(pict
, &type
);
541 ok(hr
== S_OK
, "hr %08x\n", hr
);
542 ok(type
== PICTYPE_UNINITIALIZED
, "type %d\n", type
);
545 hr
= IPicture_get_Handle(pict
, &handle
);
546 ok(hr
== S_OK
, "hr %08x\n", hr
);
547 ok(handle
== 0, "handle %08x\n", handle
);
549 IPicture_Release(pict
);
552 static void test_apm(void)
563 hglob
= GlobalAlloc (0, sizeof(apmdata
));
564 data
= GlobalLock(hglob
);
565 memcpy(data
, apmdata
, sizeof(apmdata
));
567 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
568 ole_check(pOleLoadPictureEx(stream
, sizeof(apmdata
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
));
570 ole_check(IPicture_get_Handle(pict
, &handle
));
571 ok(handle
!= 0, "handle is null\n");
573 ole_check(IPicture_get_Type(pict
, &type
));
574 expect_eq(type
, PICTYPE_METAFILE
, short, "%d");
576 ole_check(IPicture_get_Height(pict
, &cxy
));
577 expect_eq(cxy
, 1667, LONG
, "%d");
579 ole_check(IPicture_get_Width(pict
, &cxy
));
580 expect_eq(cxy
, 1323, LONG
, "%d");
582 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
583 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
585 ole_expect(IPicture_get_hPal(pict
, &handle
), E_FAIL
);
586 IPicture_Release(pict
);
587 IStream_Release(stream
);
590 static void test_metafile(void)
597 hglob
= GlobalAlloc (0, sizeof(metafile
));
598 data
= GlobalLock(hglob
);
599 memcpy(data
, metafile
, sizeof(metafile
));
601 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
602 /* Windows does not load simple metafiles */
603 ole_expect(pOleLoadPictureEx(stream
, sizeof(metafile
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
), E_FAIL
);
605 IStream_Release(stream
);
608 static void test_enhmetafile(void)
619 hglob
= GlobalAlloc (0, sizeof(enhmetafile
));
620 data
= GlobalLock(hglob
);
621 memcpy(data
, enhmetafile
, sizeof(enhmetafile
));
623 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
624 ole_check(pOleLoadPictureEx(stream
, sizeof(enhmetafile
), TRUE
, &IID_IPicture
, 10, 10, 0, (LPVOID
*)&pict
));
626 ole_check(IPicture_get_Handle(pict
, &handle
));
627 ok(handle
!= 0, "handle is null\n");
629 ole_check(IPicture_get_Type(pict
, &type
));
630 expect_eq(type
, PICTYPE_ENHMETAFILE
, short, "%d");
632 ole_check(IPicture_get_Height(pict
, &cxy
));
633 expect_eq(cxy
, -23, LONG
, "%d");
635 ole_check(IPicture_get_Width(pict
, &cxy
));
636 expect_eq(cxy
, -25, LONG
, "%d");
638 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
639 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
641 IPicture_Release(pict
);
642 IStream_Release(stream
);
645 static HRESULT
picture_render(IPicture
*iface
, HDC hdc
, LONG x
, LONG y
, LONG cx
, LONG cy
,
646 OLE_XPOS_HIMETRIC xSrc
,
647 OLE_YPOS_HIMETRIC ySrc
,
648 OLE_XSIZE_HIMETRIC cxSrc
,
649 OLE_YSIZE_HIMETRIC cySrc
,
652 VARIANT ret
, args
[10];
658 hr
= IPicture_Render(iface
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, bounds
);
660 IPicture_QueryInterface(iface
, &IID_IDispatch
, (void**)&disp
);
662 /* This is broken on 64 bits - accepted pointer argument type is still VT_I4 */
663 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
664 V_VT(&args
[i
]) = VT_I4
;
666 /* pack arguments and call */
667 V_INT_PTR(&args
[0]) = (INT_PTR
)bounds
;
668 V_I4(&args
[1]) = cySrc
;
669 V_I4(&args
[2]) = cxSrc
;
670 V_I4(&args
[3]) = ySrc
;
671 V_I4(&args
[4]) = xSrc
;
676 V_I4(&args
[9]) = HandleToLong(hdc
);
678 params
.rgvarg
= args
;
679 params
.rgdispidNamedArgs
= NULL
;
681 params
.cNamedArgs
= 0;
683 V_VT(&ret
) = VT_EMPTY
;
684 hr_disp
= IDispatch_Invoke(disp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
,
685 ¶ms
, &ret
, NULL
, NULL
);
686 ok(hr
== hr_disp
, "DISPID_PICT_RENDER returned wrong code, 0x%08x, expected 0x%08x\n",
689 IDispatch_Release(disp
);
694 static void test_Render(void)
700 OLE_XSIZE_HIMETRIC pWidth
;
701 OLE_YSIZE_HIMETRIC pHeight
;
702 COLORREF result
, expected
;
705 /* test IPicture::Render return code on uninitialized picture */
706 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
707 hres
= IPicture_get_Type(pic
, &type
);
708 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
709 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
710 /* zero dimensions */
711 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
712 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
713 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
714 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
715 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
716 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
717 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
718 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
719 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
720 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
721 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
722 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
723 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
724 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
725 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
726 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 10, NULL
);
727 ole_expect(hres
, S_OK
);
728 IPicture_Release(pic
);
730 desc
.cbSizeofstruct
= sizeof(PICTDESC
);
731 desc
.picType
= PICTYPE_ICON
;
732 desc
.u
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
733 if(!desc
.u
.icon
.hicon
){
734 win_skip("LoadIcon failed. Skipping...\n");
735 ReleaseDC(NULL
, hdc
);
739 OleCreatePictureIndirect(&desc
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
740 /* zero dimensions, PICTYPE_ICON */
741 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
742 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
743 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
744 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
745 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
746 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
747 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
748 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
749 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
750 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
751 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
752 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
753 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
754 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
756 /* Check if target size and position is respected */
757 IPicture_get_Width(pic
, &pWidth
);
758 IPicture_get_Height(pic
, &pHeight
);
760 SetPixelV(hdc
, 0, 0, 0x00223344);
761 SetPixelV(hdc
, 5, 5, 0x00223344);
762 SetPixelV(hdc
, 10, 10, 0x00223344);
763 expected
= GetPixel(hdc
, 0, 0);
765 hres
= picture_render(pic
, hdc
, 1, 1, 9, 9, 0, 0, pWidth
, -pHeight
, NULL
);
766 ole_expect(hres
, S_OK
);
769 IPicture_Release(pic
);
770 ReleaseDC(NULL
, hdc
);
774 /* Evaluate the rendered Icon */
775 result
= GetPixel(hdc
, 0, 0);
776 ok(result
== expected
,
777 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
778 result
= GetPixel(hdc
, 5, 5);
779 ok(result
!= expected
||
780 broken(result
== expected
), /* WinNT 4.0 and older may claim they drew */
781 /* the icon, even if they didn't. */
782 "Color at 5,5 should have changed, but still was 0x%06X\n", expected
);
783 result
= GetPixel(hdc
, 10, 10);
784 ok(result
== expected
,
785 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
787 IPicture_Release(pic
);
788 ReleaseDC(NULL
, hdc
);
791 static void test_get_Attributes(void)
798 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
799 hres
= IPicture_get_Type(pic
, &type
);
800 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
801 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
803 hres
= IPicture_get_Attributes(pic
, NULL
);
804 ole_expect(hres
, E_POINTER
);
807 hres
= IPicture_get_Attributes(pic
, &attr
);
808 ole_expect(hres
, S_OK
);
809 ok(attr
== 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr
);
811 IPicture_Release(pic
);
814 static void test_get_Handle(void)
819 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
821 hres
= IPicture_get_Handle(pic
, NULL
);
822 ole_expect(hres
, E_POINTER
);
824 IPicture_Release(pic
);
827 static void test_get_Type(void)
832 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
834 hres
= IPicture_get_Type(pic
, NULL
);
835 ole_expect(hres
, E_POINTER
);
837 IPicture_Release(pic
);
840 static void test_OleLoadPicturePath(void)
842 static WCHAR emptyW
[] = {0};
847 char temp_path
[MAX_PATH
];
848 char temp_file
[MAX_PATH
];
849 WCHAR temp_fileW
[MAX_PATH
+ 5] = {'f','i','l','e',':','/','/','/'};
856 LPOLESTR szURLorPath
;
859 } invalid_parameters
[] =
863 {NULL
, &IID_IPicture
, NULL
},
864 {NULL
, &IID_IPicture
, &pic
},
865 {emptyW
, NULL
, NULL
},
866 {emptyW
, &IID_IPicture
, NULL
},
869 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
871 pic
= (IPicture
*)0xdeadbeef;
872 hres
= OleLoadPicturePath(invalid_parameters
[i
].szURLorPath
, NULL
, 0, 0,
873 invalid_parameters
[i
].riid
,
874 (void **)invalid_parameters
[i
].pic
);
875 ok(hres
== E_INVALIDARG
,
876 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i
, hres
);
877 ok(pic
== (IPicture
*)0xdeadbeef,
878 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i
, pic
);
881 pic
= (IPicture
*)0xdeadbeef;
882 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, NULL
, (void **)&pic
);
884 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
885 broken(hres
== E_UNEXPECTED
) || /* NT4 */
886 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
887 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
889 "Expected the output interface pointer to be NULL, got %p\n", pic
);
891 pic
= (IPicture
*)0xdeadbeef;
892 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
894 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
895 broken(hres
== E_UNEXPECTED
) || /* NT4 */
896 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
897 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
899 "Expected the output interface pointer to be NULL, got %p\n", pic
);
901 /* Create a local temporary image file for testing. */
902 GetTempPathA(sizeof(temp_path
), temp_path
);
903 GetTempFileNameA(temp_path
, "bmp", 0, temp_file
);
904 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
905 FILE_ATTRIBUTE_NORMAL
, NULL
);
906 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
909 MultiByteToWideChar(CP_ACP
, 0, temp_file
, -1, temp_fileW
+ 8, sizeof(temp_fileW
)/sizeof(WCHAR
) - 8);
911 /* Try a normal DOS path. */
912 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
914 broken(hres
== E_UNEXPECTED
), /* NT4 */
915 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
917 IPicture_Release(pic
);
919 /* Try a DOS path with tacked on "file:". */
920 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
922 broken(hres
== E_UNEXPECTED
), /* NT4 */
923 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
925 IPicture_Release(pic
);
927 DeleteFileA(temp_file
);
929 /* Try with a nonexistent file. */
930 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
931 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
932 broken(hres
== E_UNEXPECTED
) || /* NT4 */
933 broken(hres
== E_FAIL
), /*Win2k */
934 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
936 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
937 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
938 broken(hres
== E_UNEXPECTED
) || /* NT4 */
939 broken(hres
== E_FAIL
), /* Win2k */
940 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
942 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
943 FILE_ATTRIBUTE_NORMAL
, NULL
);
944 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
947 /* Try a "file:" URL with slash separators. */
948 ptr
= temp_fileW
+ 8;
956 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
958 broken(hres
== E_UNEXPECTED
), /* NT4 */
959 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
961 IPicture_Release(pic
);
963 DeleteFileA(temp_file
);
965 /* Try with a nonexistent file. */
966 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
967 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
968 broken(hres
== E_UNEXPECTED
) || /* NT4 */
969 broken(hres
== E_FAIL
), /* Win2k */
970 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
973 static void test_himetric(void)
975 static const BYTE bmp_bits
[1024];
976 OLE_XSIZE_HIMETRIC cx
;
977 OLE_YSIZE_HIMETRIC cy
;
986 desc
.cbSizeofstruct
= sizeof(desc
);
987 desc
.picType
= PICTYPE_BITMAP
;
988 desc
.u
.bmp
.hpal
= NULL
;
990 hdc
= CreateCompatibleDC(0);
992 bmp
= CreateBitmap(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
),
993 1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
), 1, 1, NULL
);
995 desc
.u
.bmp
.hbitmap
= bmp
;
997 /* size in himetric units reported rounded up to next integer value */
998 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
999 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1002 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1003 hr
= IPicture_get_Width(pic
, &cx
);
1004 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1005 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1008 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1009 hr
= IPicture_get_Height(pic
, &cy
);
1010 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1011 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1014 IPicture_Release(pic
);
1016 /* same thing with icon */
1017 icon
= CreateIcon(NULL
, GetSystemMetrics(SM_CXICON
), GetSystemMetrics(SM_CYICON
),
1018 1, 1, bmp_bits
, bmp_bits
);
1019 ok(icon
!= NULL
, "failed to create icon\n");
1021 desc
.picType
= PICTYPE_ICON
;
1022 desc
.u
.icon
.hicon
= icon
;
1024 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1025 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1028 d
= MulDiv(GetSystemMetrics(SM_CXICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1029 hr
= IPicture_get_Width(pic
, &cx
);
1030 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1031 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1034 d
= MulDiv(GetSystemMetrics(SM_CYICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1035 hr
= IPicture_get_Height(pic
, &cy
);
1036 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1037 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1039 IPicture_Release(pic
);
1045 static void test_load_save_bmp(void)
1053 IPersistStream
*src_stream
;
1054 IStream
*dst_stream
;
1055 LARGE_INTEGER offset
;
1059 desc
.cbSizeofstruct
= sizeof(desc
);
1060 desc
.picType
= PICTYPE_BITMAP
;
1061 desc
.u
.bmp
.hpal
= 0;
1062 desc
.u
.bmp
.hbitmap
= CreateBitmap(1, 1, 1, 1, NULL
);
1063 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1064 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1067 hr
= IPicture_get_Type(pic
, &type
);
1068 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1069 ok(type
== PICTYPE_BITMAP
,"expected picture type PICTYPE_BITMAP, got %d\n", type
);
1071 hr
= IPicture_get_Handle(pic
, &handle
);
1072 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1073 ok(IntToPtr(handle
) == desc
.u
.bmp
.hbitmap
, "get_Handle returned wrong handle %#x\n", handle
);
1075 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1076 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1077 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1080 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1081 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1083 ok(size
== 66, "expected 66, got %d\n", size
);
1084 mem
= GlobalLock(hmem
);
1086 ok(!memcmp(&mem
[0], "BM", 2), "got wrong bmp header %04x\n", mem
[0]);
1090 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1092 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1094 ok(size
== -1, "expected -1, got %d\n", size
);
1096 offset
.QuadPart
= 0;
1097 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1098 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1100 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1101 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1103 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1104 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1106 IPersistStream_Release(src_stream
);
1107 IStream_Release(dst_stream
);
1109 mem
= GlobalLock(hmem
);
1110 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1111 ok(mem
[1] == 66, "expected stream size 66, got %u\n", mem
[1]);
1112 ok(!memcmp(&mem
[2], "BM", 2), "got wrong bmp header %04x\n", mem
[2]);
1117 DeleteObject(desc
.u
.bmp
.hbitmap
);
1118 IPicture_Release(pic
);
1121 static void test_load_save_icon(void)
1129 IPersistStream
*src_stream
;
1130 IStream
*dst_stream
;
1131 LARGE_INTEGER offset
;
1135 desc
.cbSizeofstruct
= sizeof(desc
);
1136 desc
.picType
= PICTYPE_ICON
;
1137 desc
.u
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
1138 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1139 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1142 hr
= IPicture_get_Type(pic
, &type
);
1143 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1144 ok(type
== PICTYPE_ICON
,"expected picture type PICTYPE_ICON, got %d\n", type
);
1146 hr
= IPicture_get_Handle(pic
, &handle
);
1147 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1148 ok(IntToPtr(handle
) == desc
.u
.icon
.hicon
, "get_Handle returned wrong handle %#x\n", handle
);
1150 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 8192);
1151 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1152 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
1155 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1156 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1158 ok(size
== 766, "expected 766, got %d\n", size
);
1159 mem
= GlobalLock(hmem
);
1161 ok(mem
[0] == 0x00010000, "got wrong icon header %04x\n", mem
[0]);
1165 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1167 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1169 ok(size
== -1, "expected -1, got %d\n", size
);
1171 offset
.QuadPart
= 0;
1172 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1173 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1175 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1176 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1178 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1179 ok(hr
== S_OK
, "Saveerror %#x\n", hr
);
1181 IPersistStream_Release(src_stream
);
1182 IStream_Release(dst_stream
);
1184 mem
= GlobalLock(hmem
);
1185 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1187 ok(mem
[1] == 766, "expected stream size 766, got %u\n", mem
[1]);
1188 ok(mem
[2] == 0x00010000, "got wrong icon header %04x\n", mem
[2]);
1193 DestroyIcon(desc
.u
.icon
.hicon
);
1194 IPicture_Release(pic
);
1197 static void test_load_save_empty_picture(void)
1205 IPersistStream
*src_stream
;
1206 IStream
*dst_stream
, *stream
;
1207 LARGE_INTEGER offset
;
1211 memset(&pic
, 0, sizeof(pic
));
1212 desc
.cbSizeofstruct
= sizeof(desc
);
1213 desc
.picType
= PICTYPE_NONE
;
1214 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void **)&pic
);
1215 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1218 hr
= IPicture_get_Type(pic
, &type
);
1219 ok(hr
== S_OK
, "get_Type error %#x\n", hr
);
1220 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1222 handle
= (OLE_HANDLE
)0xdeadbeef;
1223 hr
= IPicture_get_Handle(pic
, &handle
);
1224 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1225 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1227 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1228 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1229 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1232 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1233 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1235 ok(size
== -1, "expected -1, got %d\n", size
);
1238 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1239 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1241 ok(size
== -1, "expected -1, got %d\n", size
);
1243 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1244 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1246 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1247 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1249 mem
= GlobalLock(hmem
);
1250 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1251 ok(mem
[1] == 0, "expected stream size 0, got %u\n", mem
[1]);
1254 IPersistStream_Release(src_stream
);
1255 IPicture_Release(pic
);
1257 /* first with statable and seekable stream */
1258 offset
.QuadPart
= 0;
1259 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1260 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1263 hr
= pOleLoadPicture(dst_stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1264 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1265 ok(pic
!= NULL
,"picture should not be not NULL\n");
1269 hr
= IPicture_get_Type(pic
, &type
);
1270 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1271 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1273 handle
= (OLE_HANDLE
)0xdeadbeef;
1274 hr
= IPicture_get_Handle(pic
, &handle
);
1275 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1276 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1278 IPicture_Release(pic
);
1280 IStream_Release(dst_stream
);
1282 /* again with non-statable and non-seekable stream */
1283 stream
= NoStatStream_Construct(hmem
);
1284 ok(stream
!= NULL
, "failed to create empty image stream\n");
1287 hr
= pOleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1288 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1289 ok(pic
!= NULL
,"picture should not be not NULL\n");
1293 hr
= IPicture_get_Type(pic
, &type
);
1294 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1295 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1297 handle
= (OLE_HANDLE
)0xdeadbeef;
1298 hr
= IPicture_get_Handle(pic
, &handle
);
1299 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1300 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1302 IPicture_Release(pic
);
1304 /* Non-statable impl always deletes on release */
1305 IStream_Release(stream
);
1308 START_TEST(olepicture
)
1310 hOleaut32
= GetModuleHandleA("oleaut32.dll");
1311 pOleLoadPicture
= (void*)GetProcAddress(hOleaut32
, "OleLoadPicture");
1312 pOleLoadPictureEx
= (void*)GetProcAddress(hOleaut32
, "OleLoadPictureEx");
1313 if (!pOleLoadPicture
)
1315 win_skip("OleLoadPicture is not available\n");
1319 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
1320 test_pic(gifimage
, sizeof(gifimage
));
1321 test_pic(jpgimage
, sizeof(jpgimage
));
1322 test_pic(bmpimage
, sizeof(bmpimage
));
1323 test_pic(gif4pixel
, sizeof(gif4pixel
));
1324 /* FIXME: No PNG support in Windows... */
1325 if (0) test_pic(pngimage
, sizeof(pngimage
));
1327 test_empty_image_2();
1328 if (pOleLoadPictureEx
)
1335 win_skip("OleLoadPictureEx is not available\n");
1337 test_OleCreatePictureIndirect();
1339 test_get_Attributes();
1342 test_OleLoadPicturePath();
1344 test_load_save_bmp();
1345 test_load_save_icon();
1346 test_load_save_empty_picture();
1350 /* Helper functions only ... */
1353 static inline NoStatStreamImpl
*impl_from_IStream(IStream
*iface
)
1355 return CONTAINING_RECORD(iface
, NoStatStreamImpl
, IStream_iface
);
1358 static void NoStatStreamImpl_Destroy(NoStatStreamImpl
* This
)
1360 GlobalFree(This
->supportHandle
);
1361 This
->supportHandle
=0;
1362 HeapFree(GetProcessHeap(), 0, This
);
1365 static ULONG WINAPI
NoStatStreamImpl_AddRef(
1368 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1369 return InterlockedIncrement(&This
->ref
);
1372 static HRESULT WINAPI
NoStatStreamImpl_QueryInterface(
1374 REFIID riid
, /* [in] */
1375 void** ppvObject
) /* [iid_is][out] */
1377 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1378 if (ppvObject
==0) return E_INVALIDARG
;
1380 if (IsEqualIID(&IID_IUnknown
, riid
))
1384 else if (IsEqualIID(&IID_IStream
, riid
))
1389 if ((*ppvObject
)==0)
1390 return E_NOINTERFACE
;
1391 NoStatStreamImpl_AddRef(iface
);
1395 static ULONG WINAPI
NoStatStreamImpl_Release(
1398 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1399 ULONG newRef
= InterlockedDecrement(&This
->ref
);
1401 NoStatStreamImpl_Destroy(This
);
1405 static HRESULT WINAPI
NoStatStreamImpl_Read(
1407 void* pv
, /* [length_is][size_is][out] */
1408 ULONG cb
, /* [in] */
1409 ULONG
* pcbRead
) /* [out] */
1411 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1412 void* supportBuffer
;
1413 ULONG bytesReadBuffer
;
1414 ULONG bytesToReadFromBuffer
;
1417 pcbRead
= &bytesReadBuffer
;
1418 bytesToReadFromBuffer
= min( This
->streamSize
.u
.LowPart
- This
->currentPosition
.u
.LowPart
, cb
);
1419 supportBuffer
= GlobalLock(This
->supportHandle
);
1420 memcpy(pv
, (char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, bytesToReadFromBuffer
);
1421 This
->currentPosition
.u
.LowPart
+=bytesToReadFromBuffer
;
1422 *pcbRead
= bytesToReadFromBuffer
;
1423 GlobalUnlock(This
->supportHandle
);
1429 static HRESULT WINAPI
NoStatStreamImpl_Write(
1431 const void* pv
, /* [size_is][in] */
1432 ULONG cb
, /* [in] */
1433 ULONG
* pcbWritten
) /* [out] */
1435 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1436 void* supportBuffer
;
1437 ULARGE_INTEGER newSize
;
1438 ULONG bytesWritten
= 0;
1440 if (pcbWritten
== 0)
1441 pcbWritten
= &bytesWritten
;
1444 newSize
.u
.HighPart
= 0;
1445 newSize
.u
.LowPart
= This
->currentPosition
.u
.LowPart
+ cb
;
1446 if (newSize
.u
.LowPart
> This
->streamSize
.u
.LowPart
)
1447 IStream_SetSize(iface
, newSize
);
1449 supportBuffer
= GlobalLock(This
->supportHandle
);
1450 memcpy((char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, pv
, cb
);
1451 This
->currentPosition
.u
.LowPart
+=cb
;
1453 GlobalUnlock(This
->supportHandle
);
1457 static HRESULT WINAPI
NoStatStreamImpl_Seek(
1459 LARGE_INTEGER dlibMove
, /* [in] */
1460 DWORD dwOrigin
, /* [in] */
1461 ULARGE_INTEGER
* plibNewPosition
) /* [out] */
1463 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1464 ULARGE_INTEGER newPosition
;
1467 case STREAM_SEEK_SET
:
1468 newPosition
.u
.HighPart
= 0;
1469 newPosition
.u
.LowPart
= 0;
1471 case STREAM_SEEK_CUR
:
1472 newPosition
= This
->currentPosition
;
1474 case STREAM_SEEK_END
:
1475 newPosition
= This
->streamSize
;
1478 return STG_E_INVALIDFUNCTION
;
1480 if (dlibMove
.QuadPart
< 0 && newPosition
.QuadPart
< -dlibMove
.QuadPart
)
1481 return STG_E_INVALIDFUNCTION
;
1482 newPosition
.QuadPart
+= dlibMove
.QuadPart
;
1483 if (plibNewPosition
) *plibNewPosition
= newPosition
;
1484 This
->currentPosition
= newPosition
;
1488 static HRESULT WINAPI
NoStatStreamImpl_SetSize(
1490 ULARGE_INTEGER libNewSize
) /* [in] */
1492 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1493 HGLOBAL supportHandle
;
1494 if (libNewSize
.u
.HighPart
!= 0)
1495 return STG_E_INVALIDFUNCTION
;
1496 if (This
->streamSize
.u
.LowPart
== libNewSize
.u
.LowPart
)
1498 supportHandle
= GlobalReAlloc(This
->supportHandle
, libNewSize
.u
.LowPart
, 0);
1499 if (supportHandle
== 0)
1500 return STG_E_MEDIUMFULL
;
1501 This
->supportHandle
= supportHandle
;
1502 This
->streamSize
.u
.LowPart
= libNewSize
.u
.LowPart
;
1506 static HRESULT WINAPI
NoStatStreamImpl_CopyTo(
1508 IStream
* pstm
, /* [unique][in] */
1509 ULARGE_INTEGER cb
, /* [in] */
1510 ULARGE_INTEGER
* pcbRead
, /* [out] */
1511 ULARGE_INTEGER
* pcbWritten
) /* [out] */
1514 BYTE tmpBuffer
[128];
1515 ULONG bytesRead
, bytesWritten
, copySize
;
1516 ULARGE_INTEGER totalBytesRead
;
1517 ULARGE_INTEGER totalBytesWritten
;
1520 return STG_E_INVALIDPOINTER
;
1521 totalBytesRead
.u
.LowPart
= totalBytesRead
.u
.HighPart
= 0;
1522 totalBytesWritten
.u
.LowPart
= totalBytesWritten
.u
.HighPart
= 0;
1524 while ( cb
.u
.LowPart
> 0 )
1526 if ( cb
.u
.LowPart
>= 128 )
1529 copySize
= cb
.u
.LowPart
;
1530 IStream_Read(iface
, tmpBuffer
, copySize
, &bytesRead
);
1531 totalBytesRead
.u
.LowPart
+= bytesRead
;
1532 IStream_Write(pstm
, tmpBuffer
, bytesRead
, &bytesWritten
);
1533 totalBytesWritten
.u
.LowPart
+= bytesWritten
;
1534 if (bytesRead
!= bytesWritten
)
1536 hr
= STG_E_MEDIUMFULL
;
1539 if (bytesRead
!=copySize
)
1542 cb
.u
.LowPart
-= bytesRead
;
1546 pcbRead
->u
.LowPart
= totalBytesRead
.u
.LowPart
;
1547 pcbRead
->u
.HighPart
= totalBytesRead
.u
.HighPart
;
1552 pcbWritten
->u
.LowPart
= totalBytesWritten
.u
.LowPart
;
1553 pcbWritten
->u
.HighPart
= totalBytesWritten
.u
.HighPart
;
1558 static HRESULT WINAPI
NoStatStreamImpl_Commit(IStream
* iface
,DWORD grfCommitFlags
)
1562 static HRESULT WINAPI
NoStatStreamImpl_Revert(IStream
* iface
) { return S_OK
; }
1564 static HRESULT WINAPI
NoStatStreamImpl_LockRegion(
1566 ULARGE_INTEGER libOffset
, /* [in] */
1567 ULARGE_INTEGER cb
, /* [in] */
1568 DWORD dwLockType
) /* [in] */
1573 static HRESULT WINAPI
NoStatStreamImpl_UnlockRegion(
1575 ULARGE_INTEGER libOffset
, /* [in] */
1576 ULARGE_INTEGER cb
, /* [in] */
1577 DWORD dwLockType
) /* [in] */
1582 static HRESULT WINAPI
NoStatStreamImpl_Stat(
1584 STATSTG
* pstatstg
, /* [out] */
1585 DWORD grfStatFlag
) /* [in] */
1590 static HRESULT WINAPI
NoStatStreamImpl_Clone(
1592 IStream
** ppstm
) /* [out] */
1596 static const IStreamVtbl NoStatStreamImpl_Vtbl
;
1599 Build an object that implements IStream, without IStream_Stat capabilities.
1600 Receives a memory handle with data buffer. If memory handle is non-null,
1601 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1602 In any case the object takes ownership of memory handle and will free it on
1605 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
)
1607 NoStatStreamImpl
* newStream
;
1609 newStream
= HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl
));
1612 newStream
->IStream_iface
.lpVtbl
= &NoStatStreamImpl_Vtbl
;
1614 newStream
->supportHandle
= hGlobal
;
1616 if (!newStream
->supportHandle
)
1617 newStream
->supportHandle
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
|
1619 newStream
->currentPosition
.u
.HighPart
= 0;
1620 newStream
->currentPosition
.u
.LowPart
= 0;
1621 newStream
->streamSize
.u
.HighPart
= 0;
1622 newStream
->streamSize
.u
.LowPart
= GlobalSize(newStream
->supportHandle
);
1624 return &newStream
->IStream_iface
;
1628 static const IStreamVtbl NoStatStreamImpl_Vtbl
=
1630 NoStatStreamImpl_QueryInterface
,
1631 NoStatStreamImpl_AddRef
,
1632 NoStatStreamImpl_Release
,
1633 NoStatStreamImpl_Read
,
1634 NoStatStreamImpl_Write
,
1635 NoStatStreamImpl_Seek
,
1636 NoStatStreamImpl_SetSize
,
1637 NoStatStreamImpl_CopyTo
,
1638 NoStatStreamImpl_Commit
,
1639 NoStatStreamImpl_Revert
,
1640 NoStatStreamImpl_LockRegion
,
1641 NoStatStreamImpl_UnlockRegion
,
1642 NoStatStreamImpl_Stat
,
1643 NoStatStreamImpl_Clone