2 * OLEPICTURE test program
4 * Copyright 2005 Marcus Meissner
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
28 #define NONAMELESSUNION
30 #include "wine/test.h"
44 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
46 #define ole_expect(expr, expect) { \
48 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
51 #define ole_check(expr) ole_expect(expr, S_OK);
53 static HMODULE hOleaut32
;
55 static HRESULT (WINAPI
*pOleLoadPicture
)(LPSTREAM
,LONG
,BOOL
,REFIID
,LPVOID
*);
56 static HRESULT (WINAPI
*pOleCreatePictureIndirect
)(PICTDESC
*,REFIID
,BOOL
,LPVOID
*);
58 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
61 static const unsigned char gifimage
[35] = {
62 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
63 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
68 static const unsigned char jpgimage
[285] = {
69 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
70 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
71 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
72 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
73 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
74 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
75 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
76 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,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,0xff,0xc0,
79 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
80 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
81 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
83 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
85 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
86 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
90 static const unsigned char pngimage
[285] = {
91 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
92 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
93 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
94 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
95 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
96 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
97 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
101 static const unsigned char bmpimage
[66] = {
102 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
103 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
104 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
105 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
110 static const unsigned char gif4pixel
[42] = {
111 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
112 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
113 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
116 /* APM with an empty metafile with some padding zeros - looks like under Window the
117 * metafile data should be at least 20 bytes */
118 static const unsigned char apmdata
[] = {
119 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
120 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
121 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
122 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
125 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
126 static const unsigned char metafile
[] = {
127 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
130 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
131 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
132 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
136 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
137 static const unsigned char enhmetafile
[] = {
138 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
143 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
144 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
145 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
148 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
151 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
152 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
153 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
157 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
158 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
161 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
162 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
163 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
164 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
165 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
166 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
168 0x14, 0x00, 0x00, 0x00
172 struct NoStatStreamImpl
174 const IStreamVtbl
*lpVtbl
;
177 HGLOBAL supportHandle
;
178 ULARGE_INTEGER streamSize
;
179 ULARGE_INTEGER currentPosition
;
181 typedef struct NoStatStreamImpl NoStatStreamImpl
;
182 static NoStatStreamImpl
* NoStatStreamImpl_Construct(HGLOBAL hGlobal
);
185 test_pic_with_stream(LPSTREAM stream
, unsigned int imgsize
)
187 IPicture
* pic
= NULL
;
190 OLE_HANDLE handle
, hPal
;
191 OLE_XSIZE_HIMETRIC width
;
192 OLE_YSIZE_HIMETRIC height
;
198 hres
= pOleLoadPicture(stream
, imgsize
, TRUE
, &IID_IPicture
, &pvObj
);
201 ok(hres
== S_OK
,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres
);
202 ok(pic
!= NULL
,"OLP (NULL,..) returns NULL, instead of !NULL\n");
207 hres
= IPicture_QueryInterface (pic
, &IID_IPicture
, &pvObj
);
209 ok(hres
== S_OK
,"IPicture_QI does not return S_OK, but 0x%08x\n", hres
);
210 ok(pvObj
!= NULL
,"IPicture_QI does return NULL, instead of a ptr\n");
212 IPicture_Release ((IPicture
*)pvObj
);
215 hres
= IPicture_get_Handle (pic
, &handle
);
216 ok(hres
== S_OK
,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres
);
217 ok(handle
!= 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
220 hres
= IPicture_get_Width (pic
, &width
);
221 ok(hres
== S_OK
,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres
);
222 ok(width
!= 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
225 hres
= IPicture_get_Height (pic
, &height
);
226 ok(hres
== S_OK
,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres
);
227 ok(height
!= 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
230 hres
= IPicture_get_Type (pic
, &type
);
231 ok(hres
== S_OK
,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
232 ok(type
== PICTYPE_BITMAP
, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type
, PICTYPE_BITMAP
);
235 hres
= IPicture_get_Attributes (pic
, &attr
);
236 ok(hres
== S_OK
,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres
);
237 ok(attr
== 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr
);
240 hres
= IPicture_get_hPal (pic
, &hPal
);
241 ok(hres
== S_OK
,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres
);
242 /* a single pixel b/w image has no palette */
243 ok(hPal
== 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal
);
245 res
= IPicture_Release (pic
);
246 ok (res
== 0, "refcount after release is %d, but should be 0?\n", res
);
250 test_pic(const unsigned char *imgdata
, unsigned int imgsize
)
256 LARGE_INTEGER seekto
;
257 ULARGE_INTEGER newpos1
;
261 /* Let the fun begin */
262 hglob
= GlobalAlloc (0, imgsize
);
263 data
= GlobalLock (hglob
);
264 memcpy(data
, imgdata
, imgsize
);
265 GlobalUnlock(hglob
); data
= NULL
;
267 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
268 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
270 memset(&seekto
,0,sizeof(seekto
));
271 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
272 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
273 test_pic_with_stream(stream
, imgsize
);
275 IStream_Release(stream
);
277 /* again with Non Statable and Non Seekable stream */
278 stream
= (LPSTREAM
)NoStatStreamImpl_Construct(hglob
);
279 hglob
= 0; /* Non-statable impl always deletes on release */
280 test_pic_with_stream(stream
, 0);
282 IStream_Release(stream
);
283 for (i
= 1; i
<= 8; i
++) {
285 hglob
= GlobalAlloc (0, imgsize
+ i
* (2 * sizeof(DWORD
)));
286 data
= GlobalLock (hglob
);
287 header
= (DWORD
*)data
;
289 /* multiple copies of header */
290 memcpy(data
,"lt\0\0",4);
292 for (j
= 2; j
<= i
; j
++) {
293 memcpy(&(header
[2 * (j
- 1)]), header
, 2 * sizeof(DWORD
));
295 memcpy(data
+ i
* (2 * sizeof(DWORD
)), imgdata
, imgsize
);
296 GlobalUnlock(hglob
); data
= NULL
;
298 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
299 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
301 memset(&seekto
,0,sizeof(seekto
));
302 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
303 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
304 test_pic_with_stream(stream
, imgsize
);
306 IStream_Release(stream
);
308 /* again with Non Statable and Non Seekable stream */
309 stream
= (LPSTREAM
)NoStatStreamImpl_Construct(hglob
);
310 hglob
= 0; /* Non-statable impl always deletes on release */
311 test_pic_with_stream(stream
, 0);
313 IStream_Release(stream
);
317 static void test_empty_image(void) {
320 IPicture
* pic
= NULL
;
325 ULARGE_INTEGER newpos1
;
326 LARGE_INTEGER seekto
;
330 /* Empty image. Happens occasionally in VB programs. */
331 hglob
= GlobalAlloc (0, 8);
332 data
= GlobalLock (hglob
);
333 memcpy(data
,"lt\0\0",4);
334 ((DWORD
*)data
)[1] = 0;
335 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
336 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
338 memset(&seekto
,0,sizeof(seekto
));
339 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
340 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
343 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
345 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
346 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
348 hres
= IPicture_get_Type (pic
, &type
);
349 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
350 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
353 hres
= IPicture_get_Attributes (pic
, &attr
);
354 ok (hres
== S_OK
,"empty picture get attributes failed with hres 0x%08x\n", hres
);
355 ok (attr
== 0,"attr is %d, but should be 0\n", attr
);
357 hres
= IPicture_get_Handle (pic
, &handle
);
358 ok (hres
== S_OK
,"empty picture get handle failed with hres 0x%08x\n", hres
);
359 ok (handle
== 0, "empty picture get handle did not return 0, but 0x%08x\n", handle
);
360 IPicture_Release (pic
);
361 IStream_Release (stream
);
364 static void test_empty_image_2(void) {
367 IPicture
* pic
= NULL
;
371 ULARGE_INTEGER newpos1
;
372 LARGE_INTEGER seekto
;
375 /* Empty image at random stream position. */
376 hglob
= GlobalAlloc (0, 200);
377 data
= GlobalLock (hglob
);
379 memcpy(data
,"lt\0\0",4);
380 ((DWORD
*)data
)[1] = 0;
381 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
382 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
384 memset(&seekto
,0,sizeof(seekto
));
385 seekto
.u
.LowPart
= 42;
386 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
387 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
390 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
392 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
393 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
395 hres
= IPicture_get_Type (pic
, &type
);
396 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
397 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
399 IPicture_Release (pic
);
400 IStream_Release (stream
);
403 static void test_Invoke(void)
405 IPictureDisp
*picdisp
;
408 DISPPARAMS dispparams
;
414 hglob
= GlobalAlloc (0, sizeof(gifimage
));
415 data
= GlobalLock(hglob
);
416 memcpy(data
, gifimage
, sizeof(gifimage
));
419 hr
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
420 ok_ole_success(hr
, "CreateStreamOnHGlobal");
422 hr
= pOleLoadPicture(stream
, sizeof(gifimage
), TRUE
, &IID_IPictureDisp
, (void **)&picdisp
);
423 IStream_Release(stream
);
425 ok_ole_success(hr
, "OleLoadPicture");
427 V_VT(&vararg
) = VT_BOOL
;
428 V_BOOL(&vararg
) = VARIANT_FALSE
;
429 dispparams
.cNamedArgs
= 0;
430 dispparams
.rgdispidNamedArgs
= NULL
;
431 dispparams
.cArgs
= 1;
432 dispparams
.rgvarg
= &vararg
;
433 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IPictureDisp
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
434 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
435 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IUnknown
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
436 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
438 dispparams
.cArgs
= 0;
439 dispparams
.rgvarg
= NULL
;
440 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
441 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
443 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, NULL
, NULL
, NULL
);
444 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
446 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
447 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
449 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, &varresult
, NULL
, NULL
);
450 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
452 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
453 ok_ole_success(hr
, "IPictureDisp_Invoke");
454 ok(V_VT(&varresult
) == VT_I4
, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult
));
456 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
457 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
459 hr
= IPictureDisp_Invoke(picdisp
, 0xdeadbeef, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
460 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
462 dispparams
.cArgs
= 1;
463 dispparams
.rgvarg
= &vararg
;
464 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
465 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
467 dispparams
.cArgs
= 1;
468 dispparams
.rgvarg
= &vararg
;
469 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
470 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
472 IPictureDisp_Release(picdisp
);
475 static void test_OleCreatePictureIndirect(void)
482 if(!pOleCreatePictureIndirect
)
484 win_skip("Skipping OleCreatePictureIndirect tests\n");
488 hr
= pOleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void**)&pict
);
489 ok(hr
== S_OK
, "hr %08x\n", hr
);
491 hr
= IPicture_get_Type(pict
, &type
);
492 ok(hr
== S_OK
, "hr %08x\n", hr
);
493 ok(type
== PICTYPE_UNINITIALIZED
, "type %d\n", type
);
495 hr
= IPicture_get_Handle(pict
, &handle
);
496 ok(hr
== S_OK
, "hr %08x\n", hr
);
497 ok(handle
== 0, "handle %08x\n", handle
);
499 IPicture_Release(pict
);
502 static void test_apm(void)
513 hglob
= GlobalAlloc (0, sizeof(apmdata
));
514 data
= GlobalLock(hglob
);
515 memcpy(data
, apmdata
, sizeof(apmdata
));
517 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
518 ole_check(OleLoadPictureEx(stream
, sizeof(apmdata
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
));
520 ole_check(IPicture_get_Handle(pict
, &handle
));
521 ok(handle
!= 0, "handle is null\n");
523 ole_check(IPicture_get_Type(pict
, &type
));
524 expect_eq(type
, PICTYPE_METAFILE
, short, "%d");
526 ole_check(IPicture_get_Height(pict
, &cxy
));
527 expect_eq(cxy
, 1667, LONG
, "%d");
529 ole_check(IPicture_get_Width(pict
, &cxy
));
530 expect_eq(cxy
, 1323, LONG
, "%d");
532 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
533 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
535 ole_expect(IPicture_get_hPal(pict
, &handle
), E_FAIL
);
536 IPicture_Release(pict
);
537 IStream_Release(stream
);
540 static void test_metafile(void)
547 hglob
= GlobalAlloc (0, sizeof(metafile
));
548 data
= GlobalLock(hglob
);
549 memcpy(data
, metafile
, sizeof(metafile
));
551 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
552 /* Windows does not load simple metafiles */
553 ole_expect(OleLoadPictureEx(stream
, sizeof(metafile
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
), E_FAIL
);
555 IStream_Release(stream
);
558 static void test_enhmetafile(void)
569 hglob
= GlobalAlloc (0, sizeof(enhmetafile
));
570 data
= GlobalLock(hglob
);
571 memcpy(data
, enhmetafile
, sizeof(enhmetafile
));
573 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
574 ole_check(OleLoadPictureEx(stream
, sizeof(enhmetafile
), TRUE
, &IID_IPicture
, 10, 10, 0, (LPVOID
*)&pict
));
576 ole_check(IPicture_get_Handle(pict
, &handle
));
577 ok(handle
!= 0, "handle is null\n");
579 ole_check(IPicture_get_Type(pict
, &type
));
580 expect_eq(type
, PICTYPE_ENHMETAFILE
, short, "%d");
582 ole_check(IPicture_get_Height(pict
, &cxy
));
583 expect_eq(cxy
, -23, LONG
, "%d");
585 ole_check(IPicture_get_Width(pict
, &cxy
));
586 expect_eq(cxy
, -25, LONG
, "%d");
588 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
589 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
591 IPicture_Release(pict
);
592 IStream_Release(stream
);
595 static void test_Render(void)
601 OLE_XSIZE_HIMETRIC pWidth
;
602 OLE_YSIZE_HIMETRIC pHeight
;
603 COLORREF result
, expected
;
606 /* test IPicture::Render return code on uninitialized picture */
607 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
608 hres
= IPicture_get_Type(pic
, &type
);
609 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
610 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
611 /* zero dimensions */
612 hres
= IPicture_Render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
613 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
614 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
615 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
616 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
617 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
618 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
619 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
620 hres
= IPicture_Render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
621 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
622 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
623 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
624 hres
= IPicture_Render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
625 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
626 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
627 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 10, NULL
);
628 ole_expect(hres
, S_OK
);
629 IPicture_Release(pic
);
631 desc
.cbSizeofstruct
= sizeof(PICTDESC
);
632 desc
.picType
= PICTYPE_ICON
;
633 desc
.u
.icon
.hicon
= LoadIcon(NULL
, IDI_APPLICATION
);
634 if(!desc
.u
.icon
.hicon
){
635 win_skip("LoadIcon failed. Skipping...\n");
636 ReleaseDC(NULL
, hdc
);
640 OleCreatePictureIndirect(&desc
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
641 /* zero dimensions, PICTYPE_ICON */
642 hres
= IPicture_Render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
643 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
644 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
645 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
646 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
647 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
648 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
649 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
650 hres
= IPicture_Render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
651 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
652 hres
= IPicture_Render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
653 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
654 hres
= IPicture_Render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
655 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
657 /* Check if target size and position is respected */
658 IPicture_get_Width(pic
, &pWidth
);
659 IPicture_get_Height(pic
, &pHeight
);
661 SetPixelV(hdc
, 0, 0, 0x00F0F0F0);
662 SetPixelV(hdc
, 5, 5, 0x00F0F0F0);
663 SetPixelV(hdc
, 10, 10, 0x00F0F0F0);
664 expected
= GetPixel(hdc
, 0, 0);
666 hres
= IPicture_Render(pic
, hdc
, 1, 1, 9, 9, 0, 0, pWidth
, -pHeight
, NULL
);
667 ole_expect(hres
, S_OK
);
670 IPicture_Release(pic
);
671 ReleaseDC(NULL
, hdc
);
675 /* Evaluate the rendered Icon */
676 result
= GetPixel(hdc
, 0, 0);
677 ok(result
== expected
,
678 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
679 result
= GetPixel(hdc
, 5, 5);
680 ok(result
!= expected
||
681 broken(result
== expected
), /* WinNT 4.0 and older may claim they drew */
682 /* the icon, even if they didn't. */
683 "Color at 5,5 should have changed, but still was 0x%06X\n", expected
);
684 result
= GetPixel(hdc
, 10, 10);
685 ok(result
== expected
,
686 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
688 IPicture_Release(pic
);
689 ReleaseDC(NULL
, hdc
);
692 static void test_get_Attributes(void)
699 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
700 hres
= IPicture_get_Type(pic
, &type
);
701 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
702 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
704 hres
= IPicture_get_Attributes(pic
, NULL
);
705 ole_expect(hres
, E_POINTER
);
708 hres
= IPicture_get_Attributes(pic
, &attr
);
709 ole_expect(hres
, S_OK
);
710 ok(attr
== 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr
);
712 IPicture_Release(pic
);
715 static void test_get_Handle(void)
720 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
722 hres
= IPicture_get_Handle(pic
, NULL
);
723 ole_expect(hres
, E_POINTER
);
725 IPicture_Release(pic
);
728 static void test_get_Type(void)
733 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (VOID
**)&pic
);
735 hres
= IPicture_get_Type(pic
, NULL
);
736 ole_expect(hres
, E_POINTER
);
738 IPicture_Release(pic
);
741 static void test_OleLoadPicturePath(void)
743 static WCHAR emptyW
[] = {0};
748 char temp_path
[MAX_PATH
];
749 char temp_file
[MAX_PATH
];
750 WCHAR temp_fileW
[MAX_PATH
+ 5] = {'f','i','l','e',':','/','/','/'};
757 LPOLESTR szURLorPath
;
760 } invalid_parameters
[] =
764 {NULL
, &IID_IPicture
, NULL
},
765 {NULL
, &IID_IPicture
, &pic
},
766 {emptyW
, NULL
, NULL
},
767 {emptyW
, &IID_IPicture
, NULL
},
770 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
772 pic
= (IPicture
*)0xdeadbeef;
773 hres
= OleLoadPicturePath(invalid_parameters
[i
].szURLorPath
, NULL
, 0, 0,
774 invalid_parameters
[i
].riid
,
775 (void **)invalid_parameters
[i
].pic
);
776 ok(hres
== E_INVALIDARG
,
777 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i
, hres
);
778 ok(pic
== (IPicture
*)0xdeadbeef,
779 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i
, pic
);
782 pic
= (IPicture
*)0xdeadbeef;
783 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, NULL
, (void **)&pic
);
785 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
786 hres
== E_UNEXPECTED
|| /* NT4/Win95 */
787 hres
== E_FAIL
|| /* Win95 OSR2 */
788 hres
== E_OUTOFMEMORY
, /* Win98/Win2k/Win2k3 */
789 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
791 "Expected the output interface pointer to be NULL, got %p\n", pic
);
793 pic
= (IPicture
*)0xdeadbeef;
794 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
796 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
797 hres
== E_UNEXPECTED
|| /* NT4/Win95 */
798 hres
== E_FAIL
|| /* Win95 OSR2 */
799 hres
== E_OUTOFMEMORY
, /* Win98/Win2k/Win2k3 */
800 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
802 "Expected the output interface pointer to be NULL, got %p\n", pic
);
804 /* Create a local temporary image file for testing. */
805 GetTempPathA(sizeof(temp_path
), temp_path
);
806 GetTempFileNameA(temp_path
, "bmp", 0, temp_file
);
807 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
808 FILE_ATTRIBUTE_NORMAL
, NULL
);
809 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
812 MultiByteToWideChar(CP_ACP
, 0, temp_file
, -1, temp_fileW
+ 8, sizeof(temp_fileW
)/sizeof(WCHAR
) - 8);
814 /* Try a normal DOS path. */
815 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
818 broken(hres
== E_UNEXPECTED
), /* NT4/Win95 */
819 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
821 IPicture_Release(pic
);
823 /* Try a DOS path with tacked on "file:". */
824 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
827 broken(hres
== E_UNEXPECTED
), /* NT4/Win95 */
828 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
830 IPicture_Release(pic
);
832 DeleteFileA(temp_file
);
834 /* Try with a non-existent file. */
835 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
836 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
837 hres
== E_UNEXPECTED
|| /* NT4/Win95 */
838 hres
== E_FAIL
, /* Win9x/Win2k */
839 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
841 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
842 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
843 hres
== E_UNEXPECTED
|| /* NT4/Win95 */
844 hres
== E_FAIL
, /* Win9x/Win2k */
845 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
847 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
848 FILE_ATTRIBUTE_NORMAL
, NULL
);
849 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
852 /* Try a "file:" URL with slash separators. */
853 ptr
= temp_fileW
+ 8;
861 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
864 broken(hres
== E_UNEXPECTED
), /* NT4/Win95 */
865 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
867 IPicture_Release(pic
);
869 DeleteFileA(temp_file
);
871 /* Try with a non-existent file. */
872 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
873 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
874 hres
== E_UNEXPECTED
|| /* NT4/Win95 */
875 hres
== E_FAIL
, /* Win9x/Win2k */
876 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
879 START_TEST(olepicture
)
881 hOleaut32
= GetModuleHandleA("oleaut32.dll");
882 pOleLoadPicture
= (void*)GetProcAddress(hOleaut32
, "OleLoadPicture");
883 pOleCreatePictureIndirect
= (void*)GetProcAddress(hOleaut32
, "OleCreatePictureIndirect");
884 if (!pOleLoadPicture
)
886 win_skip("OleLoadPicture is not available\n");
890 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
891 test_pic(gifimage
, sizeof(gifimage
));
892 test_pic(jpgimage
, sizeof(jpgimage
));
893 test_pic(bmpimage
, sizeof(bmpimage
));
894 test_pic(gif4pixel
, sizeof(gif4pixel
));
895 /* FIXME: No PNG support yet in Wine or in older Windows... */
896 if (0) test_pic(pngimage
, sizeof(pngimage
));
898 test_empty_image_2();
904 test_OleCreatePictureIndirect();
906 test_get_Attributes();
909 test_OleLoadPicturePath();
913 /* Helper functions only ... */
916 static void NoStatStreamImpl_Destroy(NoStatStreamImpl
* This
)
918 GlobalFree(This
->supportHandle
);
919 This
->supportHandle
=0;
920 HeapFree(GetProcessHeap(), 0, This
);
923 static ULONG WINAPI
NoStatStreamImpl_AddRef(
926 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
927 return InterlockedIncrement(&This
->ref
);
930 static HRESULT WINAPI
NoStatStreamImpl_QueryInterface(
932 REFIID riid
, /* [in] */
933 void** ppvObject
) /* [iid_is][out] */
935 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
936 if (ppvObject
==0) return E_INVALIDARG
;
938 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
942 else if (memcmp(&IID_IStream
, riid
, sizeof(IID_IStream
)) == 0)
948 return E_NOINTERFACE
;
949 NoStatStreamImpl_AddRef(iface
);
953 static ULONG WINAPI
NoStatStreamImpl_Release(
956 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
957 ULONG newRef
= InterlockedDecrement(&This
->ref
);
959 NoStatStreamImpl_Destroy(This
);
963 static HRESULT WINAPI
NoStatStreamImpl_Read(
965 void* pv
, /* [length_is][size_is][out] */
967 ULONG
* pcbRead
) /* [out] */
969 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
971 ULONG bytesReadBuffer
;
972 ULONG bytesToReadFromBuffer
;
975 pcbRead
= &bytesReadBuffer
;
976 bytesToReadFromBuffer
= min( This
->streamSize
.u
.LowPart
- This
->currentPosition
.u
.LowPart
, cb
);
977 supportBuffer
= GlobalLock(This
->supportHandle
);
978 memcpy(pv
, (char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, bytesToReadFromBuffer
);
979 This
->currentPosition
.u
.LowPart
+=bytesToReadFromBuffer
;
980 *pcbRead
= bytesToReadFromBuffer
;
981 GlobalUnlock(This
->supportHandle
);
987 static HRESULT WINAPI
NoStatStreamImpl_Write(
989 const void* pv
, /* [size_is][in] */
991 ULONG
* pcbWritten
) /* [out] */
993 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
995 ULARGE_INTEGER newSize
;
996 ULONG bytesWritten
= 0;
999 pcbWritten
= &bytesWritten
;
1002 newSize
.u
.HighPart
= 0;
1003 newSize
.u
.LowPart
= This
->currentPosition
.u
.LowPart
+ cb
;
1004 if (newSize
.u
.LowPart
> This
->streamSize
.u
.LowPart
)
1005 IStream_SetSize(iface
, newSize
);
1007 supportBuffer
= GlobalLock(This
->supportHandle
);
1008 memcpy((char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, pv
, cb
);
1009 This
->currentPosition
.u
.LowPart
+=cb
;
1011 GlobalUnlock(This
->supportHandle
);
1015 static HRESULT WINAPI
NoStatStreamImpl_Seek(
1017 LARGE_INTEGER dlibMove
, /* [in] */
1018 DWORD dwOrigin
, /* [in] */
1019 ULARGE_INTEGER
* plibNewPosition
) /* [out] */
1021 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
1022 ULARGE_INTEGER newPosition
;
1025 case STREAM_SEEK_SET
:
1026 newPosition
.u
.HighPart
= 0;
1027 newPosition
.u
.LowPart
= 0;
1029 case STREAM_SEEK_CUR
:
1030 newPosition
= This
->currentPosition
;
1032 case STREAM_SEEK_END
:
1033 newPosition
= This
->streamSize
;
1036 return STG_E_INVALIDFUNCTION
;
1038 if (dlibMove
.QuadPart
< 0 && newPosition
.QuadPart
< -dlibMove
.QuadPart
)
1039 return STG_E_INVALIDFUNCTION
;
1040 newPosition
.QuadPart
+= dlibMove
.QuadPart
;
1041 if (plibNewPosition
) *plibNewPosition
= newPosition
;
1042 This
->currentPosition
= newPosition
;
1046 static HRESULT WINAPI
NoStatStreamImpl_SetSize(
1048 ULARGE_INTEGER libNewSize
) /* [in] */
1050 NoStatStreamImpl
* const This
=(NoStatStreamImpl
*)iface
;
1051 HGLOBAL supportHandle
;
1052 if (libNewSize
.u
.HighPart
!= 0)
1053 return STG_E_INVALIDFUNCTION
;
1054 if (This
->streamSize
.u
.LowPart
== libNewSize
.u
.LowPart
)
1056 supportHandle
= GlobalReAlloc(This
->supportHandle
, libNewSize
.u
.LowPart
, 0);
1057 if (supportHandle
== 0)
1058 return STG_E_MEDIUMFULL
;
1059 This
->supportHandle
= supportHandle
;
1060 This
->streamSize
.u
.LowPart
= libNewSize
.u
.LowPart
;
1064 static HRESULT WINAPI
NoStatStreamImpl_CopyTo(
1066 IStream
* pstm
, /* [unique][in] */
1067 ULARGE_INTEGER cb
, /* [in] */
1068 ULARGE_INTEGER
* pcbRead
, /* [out] */
1069 ULARGE_INTEGER
* pcbWritten
) /* [out] */
1072 BYTE tmpBuffer
[128];
1073 ULONG bytesRead
, bytesWritten
, copySize
;
1074 ULARGE_INTEGER totalBytesRead
;
1075 ULARGE_INTEGER totalBytesWritten
;
1078 return STG_E_INVALIDPOINTER
;
1079 totalBytesRead
.u
.LowPart
= totalBytesRead
.u
.HighPart
= 0;
1080 totalBytesWritten
.u
.LowPart
= totalBytesWritten
.u
.HighPart
= 0;
1082 while ( cb
.u
.LowPart
> 0 )
1084 if ( cb
.u
.LowPart
>= 128 )
1087 copySize
= cb
.u
.LowPart
;
1088 IStream_Read(iface
, tmpBuffer
, copySize
, &bytesRead
);
1089 totalBytesRead
.u
.LowPart
+= bytesRead
;
1090 IStream_Write(pstm
, tmpBuffer
, bytesRead
, &bytesWritten
);
1091 totalBytesWritten
.u
.LowPart
+= bytesWritten
;
1092 if (bytesRead
!= bytesWritten
)
1094 hr
= STG_E_MEDIUMFULL
;
1097 if (bytesRead
!=copySize
)
1100 cb
.u
.LowPart
-= bytesRead
;
1104 pcbRead
->u
.LowPart
= totalBytesRead
.u
.LowPart
;
1105 pcbRead
->u
.HighPart
= totalBytesRead
.u
.HighPart
;
1110 pcbWritten
->u
.LowPart
= totalBytesWritten
.u
.LowPart
;
1111 pcbWritten
->u
.HighPart
= totalBytesWritten
.u
.HighPart
;
1116 static HRESULT WINAPI
NoStatStreamImpl_Commit(IStream
* iface
,DWORD grfCommitFlags
)
1120 static HRESULT WINAPI
NoStatStreamImpl_Revert(IStream
* iface
) { return S_OK
; }
1122 static HRESULT WINAPI
NoStatStreamImpl_LockRegion(
1124 ULARGE_INTEGER libOffset
, /* [in] */
1125 ULARGE_INTEGER cb
, /* [in] */
1126 DWORD dwLockType
) /* [in] */
1131 static HRESULT WINAPI
NoStatStreamImpl_UnlockRegion(
1133 ULARGE_INTEGER libOffset
, /* [in] */
1134 ULARGE_INTEGER cb
, /* [in] */
1135 DWORD dwLockType
) /* [in] */
1140 static HRESULT WINAPI
NoStatStreamImpl_Stat(
1142 STATSTG
* pstatstg
, /* [out] */
1143 DWORD grfStatFlag
) /* [in] */
1148 static HRESULT WINAPI
NoStatStreamImpl_Clone(
1150 IStream
** ppstm
) /* [out] */
1154 static const IStreamVtbl NoStatStreamImpl_Vtbl
;
1157 Build an object that implements IStream, without IStream_Stat capabilities.
1158 Receives a memory handle with data buffer. If memory handle is non-null,
1159 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1160 In any case the object takes ownership of memory handle and will free it on
1163 static NoStatStreamImpl
* NoStatStreamImpl_Construct(HGLOBAL hGlobal
)
1165 NoStatStreamImpl
* newStream
;
1167 newStream
= HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl
));
1170 newStream
->lpVtbl
= &NoStatStreamImpl_Vtbl
;
1172 newStream
->supportHandle
= hGlobal
;
1174 if (!newStream
->supportHandle
)
1175 newStream
->supportHandle
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
|
1177 newStream
->currentPosition
.u
.HighPart
= 0;
1178 newStream
->currentPosition
.u
.LowPart
= 0;
1179 newStream
->streamSize
.u
.HighPart
= 0;
1180 newStream
->streamSize
.u
.LowPart
= GlobalSize(newStream
->supportHandle
);
1186 static const IStreamVtbl NoStatStreamImpl_Vtbl
=
1188 NoStatStreamImpl_QueryInterface
,
1189 NoStatStreamImpl_AddRef
,
1190 NoStatStreamImpl_Release
,
1191 NoStatStreamImpl_Read
,
1192 NoStatStreamImpl_Write
,
1193 NoStatStreamImpl_Seek
,
1194 NoStatStreamImpl_SetSize
,
1195 NoStatStreamImpl_CopyTo
,
1196 NoStatStreamImpl_Commit
,
1197 NoStatStreamImpl_Revert
,
1198 NoStatStreamImpl_LockRegion
,
1199 NoStatStreamImpl_UnlockRegion
,
1200 NoStatStreamImpl_Stat
,
1201 NoStatStreamImpl_Clone