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
24 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
26 #define ole_expect(expr, expect) { \
28 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
31 #define ole_check(expr) ole_expect(expr, S_OK);
33 static HMODULE hOleaut32
;
35 static HRESULT (WINAPI
*pOleLoadPicture
)(LPSTREAM
,LONG
,BOOL
,REFIID
,LPVOID
*);
36 static HRESULT (WINAPI
*pOleLoadPictureEx
)(LPSTREAM
,LONG
,BOOL
,REFIID
,DWORD
,DWORD
,DWORD
,LPVOID
*);
38 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
41 static const unsigned char gifimage
[35] = {
42 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
43 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
48 static const unsigned char jpgimage
[285] = {
49 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
50 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
51 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
52 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
53 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
54 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
55 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
56 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
57 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
58 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
59 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
60 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
61 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
63 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
64 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
65 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
66 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
70 static const unsigned char pngimage
[285] = {
71 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
72 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
73 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
74 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
75 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
76 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
77 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
81 static const unsigned char bmpimage
[66] = {
82 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
83 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
84 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
85 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
90 static const unsigned char gif4pixel
[42] = {
91 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
92 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
93 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
96 /* APM with an empty metafile with some padding zeros - looks like under Window the
97 * metafile data should be at least 20 bytes */
98 static const unsigned char apmdata
[] = {
99 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
100 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
101 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
102 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
105 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
106 static const unsigned char metafile
[] = {
107 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
110 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
111 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
112 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
116 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
117 static const unsigned char enhmetafile
[] = {
118 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
123 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
124 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
125 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
128 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
131 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
132 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
133 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
135 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
137 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
138 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
141 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
142 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
143 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
144 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
145 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
146 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
148 0x14, 0x00, 0x00, 0x00
151 static HBITMAP stock_bm
;
153 static HDC
create_render_dc( void )
155 HDC dc
= CreateCompatibleDC( NULL
);
156 BITMAPINFO info
= {{sizeof(info
.bmiHeader
), 100, 100, 1, 32, BI_RGB
}};
158 HBITMAP dib
= CreateDIBSection( NULL
, &info
, DIB_RGB_COLORS
, &bits
, NULL
, 0 );
160 stock_bm
= SelectObject( dc
, dib
);
164 static void delete_render_dc( HDC dc
)
166 HBITMAP dib
= SelectObject( dc
, stock_bm
);
171 typedef struct NoStatStreamImpl
173 IStream IStream_iface
;
176 HGLOBAL supportHandle
;
177 ULARGE_INTEGER streamSize
;
178 ULARGE_INTEGER currentPosition
;
181 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
);
184 test_pic_with_stream(LPSTREAM stream
, unsigned int imgsize
)
186 IPicture
* pic
= NULL
;
189 OLE_HANDLE handle
, hPal
;
190 OLE_XSIZE_HIMETRIC width
;
191 OLE_YSIZE_HIMETRIC height
;
197 hres
= pOleLoadPicture(stream
, imgsize
, TRUE
, &IID_IPicture
, &pvObj
);
200 ok(hres
== S_OK
,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres
);
201 ok(pic
!= NULL
,"OLP (NULL,..) returns NULL, instead of !NULL\n");
206 hres
= IPicture_QueryInterface (pic
, &IID_IPicture
, &pvObj
);
208 ok(hres
== S_OK
,"IPicture_QI does not return S_OK, but 0x%08x\n", hres
);
209 ok(pvObj
!= NULL
,"IPicture_QI does return NULL, instead of a ptr\n");
211 IPicture_Release ((IPicture
*)pvObj
);
214 hres
= IPicture_get_Handle (pic
, &handle
);
215 ok(hres
== S_OK
,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres
);
216 ok(handle
!= 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
221 GetObjectA(UlongToHandle(handle
), sizeof(BITMAP
), &bmp
);
222 todo_wine
ok(bmp
.bmBits
!= 0, "not a dib\n");
226 hres
= IPicture_get_Width (pic
, &width
);
227 ok(hres
== S_OK
,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres
);
228 ok(width
!= 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
231 hres
= IPicture_get_Height (pic
, &height
);
232 ok(hres
== S_OK
,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres
);
233 ok(height
!= 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
236 hres
= IPicture_get_Type (pic
, &type
);
237 ok(hres
== S_OK
,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
238 ok(type
== PICTYPE_BITMAP
, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type
, PICTYPE_BITMAP
);
241 hres
= IPicture_get_Attributes (pic
, &attr
);
242 ok(hres
== S_OK
,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres
);
243 ok(attr
== 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr
);
246 hres
= IPicture_get_hPal (pic
, &hPal
);
247 ok(hres
== S_OK
,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres
);
248 /* a single pixel b/w image has no palette */
249 ok(hPal
== 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal
);
251 res
= IPicture_Release (pic
);
252 ok (res
== 0, "refcount after release is %d, but should be 0?\n", res
);
256 test_pic(const unsigned char *imgdata
, unsigned int imgsize
)
262 LARGE_INTEGER seekto
;
263 ULARGE_INTEGER newpos1
;
267 /* Let the fun begin */
268 hglob
= GlobalAlloc (0, imgsize
);
269 data
= GlobalLock (hglob
);
270 memcpy(data
, imgdata
, imgsize
);
271 GlobalUnlock(hglob
); data
= NULL
;
273 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
274 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
276 memset(&seekto
,0,sizeof(seekto
));
277 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
278 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
279 test_pic_with_stream(stream
, imgsize
);
281 IStream_Release(stream
);
283 /* again with Non Statable and Non Seekable stream */
284 stream
= NoStatStream_Construct(hglob
);
285 hglob
= 0; /* Non-statable impl always deletes on release */
286 test_pic_with_stream(stream
, 0);
288 IStream_Release(stream
);
289 for (i
= 1; i
<= 8; i
++) {
291 hglob
= GlobalAlloc (0, imgsize
+ i
* (2 * sizeof(DWORD
)));
292 data
= GlobalLock (hglob
);
293 header
= (DWORD
*)data
;
295 /* multiple copies of header */
296 memcpy(data
,"lt\0\0",4);
298 for (j
= 2; j
<= i
; j
++) {
299 memcpy(&(header
[2 * (j
- 1)]), header
, 2 * sizeof(DWORD
));
301 memcpy(data
+ i
* (2 * sizeof(DWORD
)), imgdata
, imgsize
);
302 GlobalUnlock(hglob
); data
= NULL
;
304 hres
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
305 ok (hres
== S_OK
, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres
);
307 memset(&seekto
,0,sizeof(seekto
));
308 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
309 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
310 test_pic_with_stream(stream
, imgsize
);
312 IStream_Release(stream
);
314 /* again with Non Statable and Non Seekable stream */
315 stream
= NoStatStream_Construct(hglob
);
316 hglob
= 0; /* Non-statable impl always deletes on release */
317 test_pic_with_stream(stream
, 0);
319 IStream_Release(stream
);
323 static void test_empty_image(void) {
326 IPicture
* pic
= NULL
;
331 ULARGE_INTEGER newpos1
;
332 LARGE_INTEGER seekto
;
336 /* Empty image. Happens occasionally in VB programs. */
337 hglob
= GlobalAlloc (0, 8);
338 data
= GlobalLock (hglob
);
339 memcpy(data
,"lt\0\0",4);
340 ((DWORD
*)data
)[1] = 0;
341 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
342 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
344 memset(&seekto
,0,sizeof(seekto
));
345 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
346 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
349 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
351 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
352 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
354 hres
= IPicture_get_Type (pic
, &type
);
355 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
356 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
359 hres
= IPicture_get_Attributes (pic
, &attr
);
360 ok (hres
== S_OK
,"empty picture get attributes failed with hres 0x%08x\n", hres
);
361 ok (attr
== 0,"attr is %d, but should be 0\n", attr
);
363 hres
= IPicture_get_Handle (pic
, &handle
);
364 ok (hres
== S_OK
,"empty picture get handle failed with hres 0x%08x\n", hres
);
365 ok (handle
== 0, "empty picture get handle did not return 0, but 0x%08x\n", handle
);
366 IPicture_Release (pic
);
367 IStream_Release (stream
);
370 static void test_empty_image_2(void) {
373 IPicture
* pic
= NULL
;
377 ULARGE_INTEGER newpos1
;
378 LARGE_INTEGER seekto
;
381 /* Empty image at random stream position. */
382 hglob
= GlobalAlloc (0, 200);
383 data
= GlobalLock (hglob
);
385 memcpy(data
,"lt\0\0",4);
386 ((DWORD
*)data
)[1] = 0;
387 hres
= CreateStreamOnHGlobal (hglob
, TRUE
, &stream
);
388 ok (hres
== S_OK
, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres
);
390 memset(&seekto
,0,sizeof(seekto
));
391 seekto
.u
.LowPart
= 42;
392 hres
= IStream_Seek(stream
,seekto
,SEEK_CUR
,&newpos1
);
393 ok (hres
== S_OK
, "istream seek failed? doubt it... hres 0x%08x\n", hres
);
396 hres
= pOleLoadPicture(stream
, 8, TRUE
, &IID_IPicture
, &pvObj
);
398 ok(hres
== S_OK
,"empty picture not loaded, hres 0x%08x\n", hres
);
399 ok(pic
!= NULL
,"empty picture not loaded, pic is NULL\n");
401 hres
= IPicture_get_Type (pic
, &type
);
402 ok (hres
== S_OK
,"empty picture get type failed with hres 0x%08x\n", hres
);
403 ok (type
== PICTYPE_NONE
,"type is %d, but should be PICTYPE_NONE(0)\n", type
);
405 IPicture_Release (pic
);
406 IStream_Release (stream
);
409 static void test_Invoke(void)
411 IPictureDisp
*picdisp
;
413 VARIANTARG vararg
, args
[10];
414 DISPPARAMS dispparams
;
422 hglob
= GlobalAlloc (0, sizeof(gifimage
));
423 data
= GlobalLock(hglob
);
424 memcpy(data
, gifimage
, sizeof(gifimage
));
427 hr
= CreateStreamOnHGlobal (hglob
, FALSE
, &stream
);
428 ok_ole_success(hr
, "CreateStreamOnHGlobal");
430 hr
= pOleLoadPicture(stream
, sizeof(gifimage
), TRUE
, &IID_IPictureDisp
, (void **)&picdisp
);
431 IStream_Release(stream
);
433 ok_ole_success(hr
, "OleLoadPicture");
435 V_VT(&vararg
) = VT_BOOL
;
436 V_BOOL(&vararg
) = VARIANT_FALSE
;
437 dispparams
.cNamedArgs
= 0;
438 dispparams
.rgdispidNamedArgs
= NULL
;
439 dispparams
.cArgs
= 1;
440 dispparams
.rgvarg
= &vararg
;
441 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IPictureDisp
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
442 ok(hr
== DISP_E_UNKNOWNNAME
, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr
);
443 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_IUnknown
, 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
);
446 dispparams
.cArgs
= 0;
447 dispparams
.rgvarg
= NULL
;
448 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, &dispparams
, NULL
, NULL
, NULL
);
449 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
451 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYPUT
, NULL
, NULL
, NULL
, NULL
);
452 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
454 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, NULL
, NULL
, NULL
);
455 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
457 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, NULL
, &varresult
, NULL
, NULL
);
458 ok(hr
== DISP_E_PARAMNOTOPTIONAL
, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr
);
460 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
461 ok_ole_success(hr
, "IPictureDisp_Invoke");
462 ok(V_VT(&varresult
) == VT_I4
, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult
));
464 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
465 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
467 hr
= IPictureDisp_Invoke(picdisp
, 0xdeadbeef, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
468 ok(hr
== DISP_E_MEMBERNOTFOUND
, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr
);
470 dispparams
.cArgs
= 1;
471 dispparams
.rgvarg
= &vararg
;
472 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
473 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
475 dispparams
.cArgs
= 1;
476 dispparams
.rgvarg
= &vararg
;
477 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_HPAL
, &IID_NULL
, 0, DISPATCH_PROPERTYGET
, &dispparams
, &varresult
, NULL
, NULL
);
478 ok(hr
== DISP_E_BADPARAMCOUNT
, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr
);
480 /* DISPID_PICT_RENDER */
481 hdc
= create_render_dc();
483 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
484 V_VT(&args
[i
]) = VT_I4
;
495 V_I4(&args
[9]) = HandleToLong(hdc
);
497 dispparams
.rgvarg
= args
;
498 dispparams
.rgdispidNamedArgs
= NULL
;
499 dispparams
.cArgs
= 10;
500 dispparams
.cNamedArgs
= 0;
502 V_VT(&varresult
) = VT_EMPTY
;
503 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
504 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
506 /* Try with one argument set to VT_I2, it'd still work if coerced. */
507 V_VT(&args
[3]) = VT_I2
;
508 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
509 ok(hr
== DISP_E_TYPEMISMATCH
, "got 0x%08x\n", hr
);
510 V_VT(&args
[3]) = VT_I4
;
512 /* Wrong argument count */
513 dispparams
.cArgs
= 9;
514 hr
= IPictureDisp_Invoke(picdisp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
, &dispparams
, &varresult
, NULL
, NULL
);
515 ok(hr
== DISP_E_BADPARAMCOUNT
, "got 0x%08x\n", hr
);
517 delete_render_dc(hdc
);
518 IPictureDisp_Release(picdisp
);
521 static void test_OleCreatePictureIndirect(void)
530 /* crashes on native */
531 OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, NULL
);
534 hr
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void**)&pict
);
535 ok(hr
== S_OK
, "hr %08x\n", hr
);
538 hr
= IPicture_get_Type(pict
, &type
);
539 ok(hr
== S_OK
, "hr %08x\n", hr
);
540 ok(type
== PICTYPE_UNINITIALIZED
, "type %d\n", type
);
543 hr
= IPicture_get_Handle(pict
, &handle
);
544 ok(hr
== S_OK
, "hr %08x\n", hr
);
545 ok(handle
== 0, "handle %08x\n", handle
);
547 IPicture_Release(pict
);
550 static void test_apm(void)
561 hglob
= GlobalAlloc (0, sizeof(apmdata
));
562 data
= GlobalLock(hglob
);
563 memcpy(data
, apmdata
, sizeof(apmdata
));
565 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
566 ole_check(pOleLoadPictureEx(stream
, sizeof(apmdata
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
));
568 ole_check(IPicture_get_Handle(pict
, &handle
));
569 ok(handle
!= 0, "handle is null\n");
571 ole_check(IPicture_get_Type(pict
, &type
));
572 expect_eq(type
, PICTYPE_METAFILE
, short, "%d");
574 ole_check(IPicture_get_Height(pict
, &cxy
));
575 expect_eq(cxy
, 1667, LONG
, "%d");
577 ole_check(IPicture_get_Width(pict
, &cxy
));
578 expect_eq(cxy
, 1323, LONG
, "%d");
580 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
581 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
583 ole_expect(IPicture_get_hPal(pict
, &handle
), E_FAIL
);
584 IPicture_Release(pict
);
585 IStream_Release(stream
);
588 static void test_metafile(void)
595 hglob
= GlobalAlloc (0, sizeof(metafile
));
596 data
= GlobalLock(hglob
);
597 memcpy(data
, metafile
, sizeof(metafile
));
599 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
600 /* Windows does not load simple metafiles */
601 ole_expect(pOleLoadPictureEx(stream
, sizeof(metafile
), TRUE
, &IID_IPicture
, 100, 100, 0, (LPVOID
*)&pict
), E_FAIL
);
603 IStream_Release(stream
);
606 static void test_enhmetafile(void)
617 hglob
= GlobalAlloc (0, sizeof(enhmetafile
));
618 data
= GlobalLock(hglob
);
619 memcpy(data
, enhmetafile
, sizeof(enhmetafile
));
621 ole_check(CreateStreamOnHGlobal(hglob
, TRUE
, &stream
));
622 ole_check(pOleLoadPictureEx(stream
, sizeof(enhmetafile
), TRUE
, &IID_IPicture
, 10, 10, 0, (LPVOID
*)&pict
));
624 ole_check(IPicture_get_Handle(pict
, &handle
));
625 ok(handle
!= 0, "handle is null\n");
627 ole_check(IPicture_get_Type(pict
, &type
));
628 expect_eq(type
, PICTYPE_ENHMETAFILE
, short, "%d");
630 ole_check(IPicture_get_Height(pict
, &cxy
));
631 expect_eq(cxy
, -23, LONG
, "%d");
633 ole_check(IPicture_get_Width(pict
, &cxy
));
634 expect_eq(cxy
, -25, LONG
, "%d");
636 ole_check(IPicture_get_KeepOriginalFormat(pict
, &keep
));
637 todo_wine
expect_eq(keep
, FALSE
, LONG
, "%d");
639 IPicture_Release(pict
);
640 IStream_Release(stream
);
643 static HRESULT
picture_render(IPicture
*iface
, HDC hdc
, LONG x
, LONG y
, LONG cx
, LONG cy
,
644 OLE_XPOS_HIMETRIC xSrc
,
645 OLE_YPOS_HIMETRIC ySrc
,
646 OLE_XSIZE_HIMETRIC cxSrc
,
647 OLE_YSIZE_HIMETRIC cySrc
,
650 VARIANT ret
, args
[10];
656 hr
= IPicture_Render(iface
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, bounds
);
658 IPicture_QueryInterface(iface
, &IID_IDispatch
, (void**)&disp
);
660 /* This is broken on 64 bits - accepted pointer argument type is still VT_I4 */
661 for (i
= 0; i
< sizeof(args
)/sizeof(args
[0]); i
++)
662 V_VT(&args
[i
]) = VT_I4
;
664 /* pack arguments and call */
665 V_INT_PTR(&args
[0]) = (INT_PTR
)bounds
;
666 V_I4(&args
[1]) = cySrc
;
667 V_I4(&args
[2]) = cxSrc
;
668 V_I4(&args
[3]) = ySrc
;
669 V_I4(&args
[4]) = xSrc
;
674 V_I4(&args
[9]) = HandleToLong(hdc
);
676 params
.rgvarg
= args
;
677 params
.rgdispidNamedArgs
= NULL
;
679 params
.cNamedArgs
= 0;
681 V_VT(&ret
) = VT_EMPTY
;
682 hr_disp
= IDispatch_Invoke(disp
, DISPID_PICT_RENDER
, &GUID_NULL
, 0, DISPATCH_METHOD
,
683 ¶ms
, &ret
, NULL
, NULL
);
684 ok(hr
== hr_disp
, "DISPID_PICT_RENDER returned wrong code, 0x%08x, expected 0x%08x\n",
687 IDispatch_Release(disp
);
692 static void test_Render(void)
698 OLE_XSIZE_HIMETRIC pWidth
;
699 OLE_YSIZE_HIMETRIC pHeight
;
700 COLORREF result
, expected
;
701 HDC hdc
= create_render_dc();
703 /* test IPicture::Render return code on uninitialized picture */
704 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
705 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
706 hres
= IPicture_get_Type(pic
, &type
);
707 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
708 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
709 /* zero dimensions */
710 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 0, 0, NULL
);
711 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
712 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 0, NULL
);
713 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
714 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 10, NULL
);
715 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
716 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 0, 0, NULL
);
717 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
718 hres
= picture_render(pic
, hdc
, 0, 0, 0, 10, 0, 0, 10, 10, NULL
);
719 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
720 hres
= picture_render(pic
, hdc
, 0, 0, 10, 0, 0, 0, 10, 10, NULL
);
721 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
722 hres
= picture_render(pic
, hdc
, 0, 0, 0, 0, 0, 0, 10, 10, NULL
);
723 ole_expect(hres
, CTL_E_INVALIDPROPERTYVALUE
);
724 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
725 hres
= picture_render(pic
, hdc
, 0, 0, 10, 10, 0, 0, 10, 10, NULL
);
726 ole_expect(hres
, S_OK
);
727 IPicture_Release(pic
);
729 desc
.cbSizeofstruct
= sizeof(PICTDESC
);
730 desc
.picType
= PICTYPE_ICON
;
731 desc
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
732 if(!desc
.icon
.hicon
){
733 win_skip("LoadIcon failed. Skipping...\n");
734 delete_render_dc(hdc
);
738 hres
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, TRUE
, (void **)&pic
);
739 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
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
);
768 if(hres
!= S_OK
) goto done
;
770 /* Evaluate the rendered Icon */
771 result
= GetPixel(hdc
, 0, 0);
772 ok(result
== expected
,
773 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
774 result
= GetPixel(hdc
, 5, 5);
775 ok(result
!= expected
,
776 "Color at 5,5 should have changed, but still was 0x%06X\n", expected
);
777 result
= GetPixel(hdc
, 10, 10);
778 ok(result
== expected
,
779 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected
, result
);
782 IPicture_Release(pic
);
783 delete_render_dc(hdc
);
786 static void test_get_Attributes(void)
793 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
794 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
795 hres
= IPicture_get_Type(pic
, &type
);
796 ok(hres
== S_OK
, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres
);
797 ok(type
== PICTYPE_UNINITIALIZED
, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type
);
799 hres
= IPicture_get_Attributes(pic
, NULL
);
800 ole_expect(hres
, E_POINTER
);
803 hres
= IPicture_get_Attributes(pic
, &attr
);
804 ole_expect(hres
, S_OK
);
805 ok(attr
== 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr
);
807 IPicture_Release(pic
);
810 static void test_get_Handle(void)
815 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
816 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
817 hres
= IPicture_get_Handle(pic
, NULL
);
818 ole_expect(hres
, E_POINTER
);
820 IPicture_Release(pic
);
823 static void test_get_Type(void)
828 hres
= OleCreatePictureIndirect(NULL
, &IID_IPicture
, TRUE
, (void **)&pic
);
829 ok(hres
== S_OK
, "Failed to create a picture, hr %#x.\n", hres
);
831 hres
= IPicture_get_Type(pic
, NULL
);
832 ole_expect(hres
, E_POINTER
);
834 IPicture_Release(pic
);
837 static void test_OleLoadPicturePath(void)
839 static WCHAR emptyW
[] = {0};
844 char temp_path
[MAX_PATH
];
845 char temp_file
[MAX_PATH
];
846 WCHAR temp_fileW
[MAX_PATH
+ 5] = {'f','i','l','e',':','/','/','/'};
853 LPOLESTR szURLorPath
;
856 } invalid_parameters
[] =
860 {NULL
, &IID_IPicture
, NULL
},
861 {NULL
, &IID_IPicture
, &pic
},
862 {emptyW
, NULL
, NULL
},
863 {emptyW
, &IID_IPicture
, NULL
},
866 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
868 pic
= (IPicture
*)0xdeadbeef;
869 hres
= OleLoadPicturePath(invalid_parameters
[i
].szURLorPath
, NULL
, 0, 0,
870 invalid_parameters
[i
].riid
,
871 (void **)invalid_parameters
[i
].pic
);
872 ok(hres
== E_INVALIDARG
,
873 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i
, hres
);
874 ok(pic
== (IPicture
*)0xdeadbeef,
875 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i
, pic
);
878 pic
= (IPicture
*)0xdeadbeef;
879 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, NULL
, (void **)&pic
);
881 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
882 broken(hres
== E_UNEXPECTED
) || /* NT4 */
883 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
884 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
886 "Expected the output interface pointer to be NULL, got %p\n", pic
);
888 pic
= (IPicture
*)0xdeadbeef;
889 hres
= OleLoadPicturePath(emptyW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
891 ok(hres
== INET_E_UNKNOWN_PROTOCOL
|| /* XP/Vista+ */
892 broken(hres
== E_UNEXPECTED
) || /* NT4 */
893 broken(hres
== E_OUTOFMEMORY
), /* Win2k/Win2k3 */
894 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres
);
896 "Expected the output interface pointer to be NULL, got %p\n", pic
);
898 /* Create a local temporary image file for testing. */
899 GetTempPathA(sizeof(temp_path
), temp_path
);
900 GetTempFileNameA(temp_path
, "bmp", 0, temp_file
);
901 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
902 FILE_ATTRIBUTE_NORMAL
, NULL
);
903 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
906 MultiByteToWideChar(CP_ACP
, 0, temp_file
, -1, temp_fileW
+ 8, sizeof(temp_fileW
)/sizeof(WCHAR
) - 8);
908 /* Try a normal DOS path. */
909 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
911 broken(hres
== E_UNEXPECTED
), /* NT4 */
912 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
914 IPicture_Release(pic
);
916 /* Try a DOS path with tacked on "file:". */
917 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
919 broken(hres
== E_UNEXPECTED
), /* NT4 */
920 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
922 IPicture_Release(pic
);
924 DeleteFileA(temp_file
);
926 /* Try with a nonexistent file. */
927 hres
= OleLoadPicturePath(temp_fileW
+ 8, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
928 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
929 broken(hres
== E_UNEXPECTED
) || /* NT4 */
930 broken(hres
== E_FAIL
), /*Win2k */
931 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
933 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
934 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
935 broken(hres
== E_UNEXPECTED
) || /* NT4 */
936 broken(hres
== E_FAIL
), /* Win2k */
937 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
939 file
= CreateFileA(temp_file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
940 FILE_ATTRIBUTE_NORMAL
, NULL
);
941 WriteFile(file
, bmpimage
, sizeof(bmpimage
), &size
, NULL
);
944 /* Try a "file:" URL with slash separators. */
945 ptr
= temp_fileW
+ 8;
953 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
955 broken(hres
== E_UNEXPECTED
), /* NT4 */
956 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres
);
958 IPicture_Release(pic
);
960 DeleteFileA(temp_file
);
962 /* Try with a nonexistent file. */
963 hres
= OleLoadPicturePath(temp_fileW
, NULL
, 0, 0, &IID_IPicture
, (void **)&pic
);
964 ok(hres
== INET_E_RESOURCE_NOT_FOUND
|| /* XP+ */
965 broken(hres
== E_UNEXPECTED
) || /* NT4 */
966 broken(hres
== E_FAIL
), /* Win2k */
967 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres
);
970 static void test_himetric(void)
972 static const BYTE bmp_bits
[1024];
973 OLE_XSIZE_HIMETRIC cx
;
974 OLE_YSIZE_HIMETRIC cy
;
983 desc
.cbSizeofstruct
= sizeof(desc
);
984 desc
.picType
= PICTYPE_BITMAP
;
985 desc
.bmp
.hpal
= NULL
;
987 hdc
= CreateCompatibleDC(0);
989 bmp
= CreateBitmap(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
),
990 1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
), 1, 1, NULL
);
992 desc
.bmp
.hbitmap
= bmp
;
994 /* size in himetric units reported rounded up to next integer value */
995 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
996 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
999 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSX
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1000 hr
= IPicture_get_Width(pic
, &cx
);
1001 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1002 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1005 d
= MulDiv((INT
)(1.9 * GetDeviceCaps(hdc
, LOGPIXELSY
)), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1006 hr
= IPicture_get_Height(pic
, &cy
);
1007 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1008 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1011 IPicture_Release(pic
);
1013 /* same thing with icon */
1014 icon
= CreateIcon(NULL
, GetSystemMetrics(SM_CXICON
), GetSystemMetrics(SM_CYICON
),
1015 1, 1, bmp_bits
, bmp_bits
);
1016 ok(icon
!= NULL
, "failed to create icon\n");
1018 desc
.picType
= PICTYPE_ICON
;
1019 desc
.icon
.hicon
= icon
;
1021 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1022 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1025 d
= MulDiv(GetSystemMetrics(SM_CXICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSX
));
1026 hr
= IPicture_get_Width(pic
, &cx
);
1027 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1028 ok(cx
== d
, "got %d, expected %d\n", cx
, d
);
1031 d
= MulDiv(GetSystemMetrics(SM_CYICON
), 2540, GetDeviceCaps(hdc
, LOGPIXELSY
));
1032 hr
= IPicture_get_Height(pic
, &cy
);
1033 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1034 ok(cy
== d
, "got %d, expected %d\n", cy
, d
);
1036 IPicture_Release(pic
);
1042 static void test_load_save_bmp(void)
1050 IPersistStream
*src_stream
;
1051 IStream
*dst_stream
;
1052 LARGE_INTEGER offset
;
1056 desc
.cbSizeofstruct
= sizeof(desc
);
1057 desc
.picType
= PICTYPE_BITMAP
;
1059 desc
.bmp
.hbitmap
= CreateBitmap(1, 1, 1, 1, NULL
);
1060 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1061 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1064 hr
= IPicture_get_Type(pic
, &type
);
1065 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1066 ok(type
== PICTYPE_BITMAP
,"expected picture type PICTYPE_BITMAP, got %d\n", type
);
1068 hr
= IPicture_get_Handle(pic
, &handle
);
1069 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1070 ok(IntToPtr(handle
) == desc
.bmp
.hbitmap
, "get_Handle returned wrong handle %#x\n", handle
);
1072 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1073 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1074 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1077 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1078 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1080 ok(size
== 66, "expected 66, got %d\n", size
);
1081 mem
= GlobalLock(hmem
);
1083 ok(!memcmp(&mem
[0], "BM", 2), "got wrong bmp header %04x\n", mem
[0]);
1087 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1089 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1091 ok(size
== -1, "expected -1, got %d\n", size
);
1093 offset
.QuadPart
= 0;
1094 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1095 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1097 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1098 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1100 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1101 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1103 IPersistStream_Release(src_stream
);
1104 IStream_Release(dst_stream
);
1106 mem
= GlobalLock(hmem
);
1107 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1108 ok(mem
[1] == 66, "expected stream size 66, got %u\n", mem
[1]);
1109 ok(!memcmp(&mem
[2], "BM", 2), "got wrong bmp header %04x\n", mem
[2]);
1114 DeleteObject(desc
.bmp
.hbitmap
);
1115 IPicture_Release(pic
);
1118 static void test_load_save_icon(void)
1126 IPersistStream
*src_stream
;
1127 IStream
*dst_stream
;
1128 LARGE_INTEGER offset
;
1132 desc
.cbSizeofstruct
= sizeof(desc
);
1133 desc
.picType
= PICTYPE_ICON
;
1134 desc
.icon
.hicon
= LoadIconA(NULL
, (LPCSTR
)IDI_APPLICATION
);
1135 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void**)&pic
);
1136 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1139 hr
= IPicture_get_Type(pic
, &type
);
1140 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1141 ok(type
== PICTYPE_ICON
,"expected picture type PICTYPE_ICON, got %d\n", type
);
1143 hr
= IPicture_get_Handle(pic
, &handle
);
1144 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1145 ok(IntToPtr(handle
) == desc
.icon
.hicon
, "get_Handle returned wrong handle %#x\n", handle
);
1147 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 8192);
1148 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1149 ok(hr
== S_OK
, "CreateStreamOnHGlobal error %#x\n", hr
);
1152 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1153 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1155 ok(size
== 766, "expected 766, got %d\n", size
);
1156 mem
= GlobalLock(hmem
);
1158 ok(mem
[0] == 0x00010000, "got wrong icon header %04x\n", mem
[0]);
1162 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1164 ok(hr
== E_FAIL
, "expected E_FAIL, got %#x\n", hr
);
1166 ok(size
== -1, "expected -1, got %d\n", size
);
1168 offset
.QuadPart
= 0;
1169 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1170 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1172 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1173 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1175 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1176 ok(hr
== S_OK
, "Saveerror %#x\n", hr
);
1178 IPersistStream_Release(src_stream
);
1179 IStream_Release(dst_stream
);
1181 mem
= GlobalLock(hmem
);
1182 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1184 ok(mem
[1] == 766, "expected stream size 766, got %u\n", mem
[1]);
1185 ok(mem
[2] == 0x00010000, "got wrong icon header %04x\n", mem
[2]);
1190 DestroyIcon(desc
.icon
.hicon
);
1191 IPicture_Release(pic
);
1194 static void test_load_save_empty_picture(void)
1202 IPersistStream
*src_stream
;
1203 IStream
*dst_stream
, *stream
;
1204 LARGE_INTEGER offset
;
1208 memset(&pic
, 0, sizeof(pic
));
1209 desc
.cbSizeofstruct
= sizeof(desc
);
1210 desc
.picType
= PICTYPE_NONE
;
1211 hr
= OleCreatePictureIndirect(&desc
, &IID_IPicture
, FALSE
, (void **)&pic
);
1212 ok(hr
== S_OK
, "OleCreatePictureIndirect error %#x\n", hr
);
1215 hr
= IPicture_get_Type(pic
, &type
);
1216 ok(hr
== S_OK
, "get_Type error %#x\n", hr
);
1217 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1219 handle
= (OLE_HANDLE
)0xdeadbeef;
1220 hr
= IPicture_get_Handle(pic
, &handle
);
1221 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1222 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1224 hmem
= GlobalAlloc(GMEM_ZEROINIT
, 4096);
1225 hr
= CreateStreamOnHGlobal(hmem
, FALSE
, &dst_stream
);
1226 ok(hr
== S_OK
, "createstreamonhglobal error %#x\n", hr
);
1229 hr
= IPicture_SaveAsFile(pic
, dst_stream
, TRUE
, &size
);
1230 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1232 ok(size
== -1, "expected -1, got %d\n", size
);
1235 hr
= IPicture_SaveAsFile(pic
, dst_stream
, FALSE
, &size
);
1236 ok(hr
== S_OK
, "IPicture_SaveasFile error %#x\n", hr
);
1238 ok(size
== -1, "expected -1, got %d\n", size
);
1240 hr
= IPicture_QueryInterface(pic
, &IID_IPersistStream
, (void **)&src_stream
);
1241 ok(hr
== S_OK
, "QueryInterface error %#x\n", hr
);
1243 hr
= IPersistStream_Save(src_stream
, dst_stream
, TRUE
);
1244 ok(hr
== S_OK
, "Save error %#x\n", hr
);
1246 mem
= GlobalLock(hmem
);
1247 ok(!memcmp(mem
, "lt\0\0", 4), "got wrong stream header %04x\n", mem
[0]);
1248 ok(mem
[1] == 0, "expected stream size 0, got %u\n", mem
[1]);
1251 IPersistStream_Release(src_stream
);
1252 IPicture_Release(pic
);
1254 /* first with statable and seekable stream */
1255 offset
.QuadPart
= 0;
1256 hr
= IStream_Seek(dst_stream
, offset
, SEEK_SET
, NULL
);
1257 ok(hr
== S_OK
, "IStream_Seek %#x\n", hr
);
1260 hr
= pOleLoadPicture(dst_stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1261 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1262 ok(pic
!= NULL
,"picture should not be not NULL\n");
1266 hr
= IPicture_get_Type(pic
, &type
);
1267 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1268 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1270 handle
= (OLE_HANDLE
)0xdeadbeef;
1271 hr
= IPicture_get_Handle(pic
, &handle
);
1272 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1273 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1275 IPicture_Release(pic
);
1277 IStream_Release(dst_stream
);
1279 /* again with non-statable and non-seekable stream */
1280 stream
= NoStatStream_Construct(hmem
);
1281 ok(stream
!= NULL
, "failed to create empty image stream\n");
1284 hr
= pOleLoadPicture(stream
, 0, FALSE
, &IID_IPicture
, (void **)&pic
);
1285 ok(hr
== S_OK
, "OleLoadPicture error %#x\n", hr
);
1286 ok(pic
!= NULL
,"picture should not be not NULL\n");
1290 hr
= IPicture_get_Type(pic
, &type
);
1291 ok(hr
== S_OK
,"get_Type error %#8x\n", hr
);
1292 ok(type
== PICTYPE_NONE
,"expected picture type PICTYPE_NONE, got %d\n", type
);
1294 handle
= (OLE_HANDLE
)0xdeadbeef;
1295 hr
= IPicture_get_Handle(pic
, &handle
);
1296 ok(hr
== S_OK
,"get_Handle error %#8x\n", hr
);
1297 ok(!handle
, "get_Handle returned wrong handle %#x\n", handle
);
1299 IPicture_Release(pic
);
1301 /* Non-statable impl always deletes on release */
1302 IStream_Release(stream
);
1305 START_TEST(olepicture
)
1307 hOleaut32
= GetModuleHandleA("oleaut32.dll");
1308 pOleLoadPicture
= (void*)GetProcAddress(hOleaut32
, "OleLoadPicture");
1309 pOleLoadPictureEx
= (void*)GetProcAddress(hOleaut32
, "OleLoadPictureEx");
1310 if (!pOleLoadPicture
)
1312 win_skip("OleLoadPicture is not available\n");
1316 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
1317 test_pic(gifimage
, sizeof(gifimage
));
1318 test_pic(jpgimage
, sizeof(jpgimage
));
1319 test_pic(bmpimage
, sizeof(bmpimage
));
1320 test_pic(gif4pixel
, sizeof(gif4pixel
));
1321 /* FIXME: No PNG support in Windows... */
1322 if (0) test_pic(pngimage
, sizeof(pngimage
));
1324 test_empty_image_2();
1325 if (pOleLoadPictureEx
)
1332 win_skip("OleLoadPictureEx is not available\n");
1334 test_OleCreatePictureIndirect();
1336 test_get_Attributes();
1339 test_OleLoadPicturePath();
1341 test_load_save_bmp();
1342 test_load_save_icon();
1343 test_load_save_empty_picture();
1347 /* Helper functions only ... */
1350 static inline NoStatStreamImpl
*impl_from_IStream(IStream
*iface
)
1352 return CONTAINING_RECORD(iface
, NoStatStreamImpl
, IStream_iface
);
1355 static void NoStatStreamImpl_Destroy(NoStatStreamImpl
* This
)
1357 GlobalFree(This
->supportHandle
);
1358 This
->supportHandle
=0;
1359 HeapFree(GetProcessHeap(), 0, This
);
1362 static ULONG WINAPI
NoStatStreamImpl_AddRef(
1365 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1366 return InterlockedIncrement(&This
->ref
);
1369 static HRESULT WINAPI
NoStatStreamImpl_QueryInterface(
1371 REFIID riid
, /* [in] */
1372 void** ppvObject
) /* [iid_is][out] */
1374 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1375 if (ppvObject
==0) return E_INVALIDARG
;
1378 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IStream
, riid
))
1379 *ppvObject
= &This
->IStream_iface
;
1381 if ((*ppvObject
)==0)
1382 return E_NOINTERFACE
;
1383 NoStatStreamImpl_AddRef(iface
);
1387 static ULONG WINAPI
NoStatStreamImpl_Release(
1390 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1391 ULONG newRef
= InterlockedDecrement(&This
->ref
);
1393 NoStatStreamImpl_Destroy(This
);
1397 static HRESULT WINAPI
NoStatStreamImpl_Read(
1399 void* pv
, /* [length_is][size_is][out] */
1400 ULONG cb
, /* [in] */
1401 ULONG
* pcbRead
) /* [out] */
1403 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1404 void* supportBuffer
;
1405 ULONG bytesReadBuffer
;
1406 ULONG bytesToReadFromBuffer
;
1409 pcbRead
= &bytesReadBuffer
;
1410 bytesToReadFromBuffer
= min( This
->streamSize
.u
.LowPart
- This
->currentPosition
.u
.LowPart
, cb
);
1411 supportBuffer
= GlobalLock(This
->supportHandle
);
1412 memcpy(pv
, (char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, bytesToReadFromBuffer
);
1413 This
->currentPosition
.u
.LowPart
+=bytesToReadFromBuffer
;
1414 *pcbRead
= bytesToReadFromBuffer
;
1415 GlobalUnlock(This
->supportHandle
);
1421 static HRESULT WINAPI
NoStatStreamImpl_Write(
1423 const void* pv
, /* [size_is][in] */
1424 ULONG cb
, /* [in] */
1425 ULONG
* pcbWritten
) /* [out] */
1427 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1428 void* supportBuffer
;
1429 ULARGE_INTEGER newSize
;
1430 ULONG bytesWritten
= 0;
1432 if (pcbWritten
== 0)
1433 pcbWritten
= &bytesWritten
;
1436 newSize
.u
.HighPart
= 0;
1437 newSize
.u
.LowPart
= This
->currentPosition
.u
.LowPart
+ cb
;
1438 if (newSize
.u
.LowPart
> This
->streamSize
.u
.LowPart
)
1439 IStream_SetSize(iface
, newSize
);
1441 supportBuffer
= GlobalLock(This
->supportHandle
);
1442 memcpy((char *) supportBuffer
+This
->currentPosition
.u
.LowPart
, pv
, cb
);
1443 This
->currentPosition
.u
.LowPart
+=cb
;
1445 GlobalUnlock(This
->supportHandle
);
1449 static HRESULT WINAPI
NoStatStreamImpl_Seek(
1451 LARGE_INTEGER dlibMove
, /* [in] */
1452 DWORD dwOrigin
, /* [in] */
1453 ULARGE_INTEGER
* plibNewPosition
) /* [out] */
1455 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1456 ULARGE_INTEGER newPosition
;
1459 case STREAM_SEEK_SET
:
1460 newPosition
.u
.HighPart
= 0;
1461 newPosition
.u
.LowPart
= 0;
1463 case STREAM_SEEK_CUR
:
1464 newPosition
= This
->currentPosition
;
1466 case STREAM_SEEK_END
:
1467 newPosition
= This
->streamSize
;
1470 return STG_E_INVALIDFUNCTION
;
1472 if (dlibMove
.QuadPart
< 0 && newPosition
.QuadPart
< -dlibMove
.QuadPart
)
1473 return STG_E_INVALIDFUNCTION
;
1474 newPosition
.QuadPart
+= dlibMove
.QuadPart
;
1475 if (plibNewPosition
) *plibNewPosition
= newPosition
;
1476 This
->currentPosition
= newPosition
;
1480 static HRESULT WINAPI
NoStatStreamImpl_SetSize(
1482 ULARGE_INTEGER libNewSize
) /* [in] */
1484 NoStatStreamImpl
* const This
= impl_from_IStream(iface
);
1485 HGLOBAL supportHandle
;
1486 if (libNewSize
.u
.HighPart
!= 0)
1487 return STG_E_INVALIDFUNCTION
;
1488 if (This
->streamSize
.u
.LowPart
== libNewSize
.u
.LowPart
)
1490 supportHandle
= GlobalReAlloc(This
->supportHandle
, libNewSize
.u
.LowPart
, 0);
1491 if (supportHandle
== 0)
1492 return STG_E_MEDIUMFULL
;
1493 This
->supportHandle
= supportHandle
;
1494 This
->streamSize
.u
.LowPart
= libNewSize
.u
.LowPart
;
1498 static HRESULT WINAPI
NoStatStreamImpl_CopyTo(
1500 IStream
* pstm
, /* [unique][in] */
1501 ULARGE_INTEGER cb
, /* [in] */
1502 ULARGE_INTEGER
* pcbRead
, /* [out] */
1503 ULARGE_INTEGER
* pcbWritten
) /* [out] */
1506 BYTE tmpBuffer
[128];
1507 ULONG bytesRead
, bytesWritten
, copySize
;
1508 ULARGE_INTEGER totalBytesRead
;
1509 ULARGE_INTEGER totalBytesWritten
;
1512 return STG_E_INVALIDPOINTER
;
1513 totalBytesRead
.u
.LowPart
= totalBytesRead
.u
.HighPart
= 0;
1514 totalBytesWritten
.u
.LowPart
= totalBytesWritten
.u
.HighPart
= 0;
1516 while ( cb
.u
.LowPart
> 0 )
1518 if ( cb
.u
.LowPart
>= 128 )
1521 copySize
= cb
.u
.LowPart
;
1522 IStream_Read(iface
, tmpBuffer
, copySize
, &bytesRead
);
1523 totalBytesRead
.u
.LowPart
+= bytesRead
;
1524 IStream_Write(pstm
, tmpBuffer
, bytesRead
, &bytesWritten
);
1525 totalBytesWritten
.u
.LowPart
+= bytesWritten
;
1526 if (bytesRead
!= bytesWritten
)
1528 hr
= STG_E_MEDIUMFULL
;
1531 if (bytesRead
!=copySize
)
1534 cb
.u
.LowPart
-= bytesRead
;
1538 pcbRead
->u
.LowPart
= totalBytesRead
.u
.LowPart
;
1539 pcbRead
->u
.HighPart
= totalBytesRead
.u
.HighPart
;
1544 pcbWritten
->u
.LowPart
= totalBytesWritten
.u
.LowPart
;
1545 pcbWritten
->u
.HighPart
= totalBytesWritten
.u
.HighPart
;
1550 static HRESULT WINAPI
NoStatStreamImpl_Commit(IStream
* iface
,DWORD grfCommitFlags
)
1554 static HRESULT WINAPI
NoStatStreamImpl_Revert(IStream
* iface
) { return S_OK
; }
1556 static HRESULT WINAPI
NoStatStreamImpl_LockRegion(
1558 ULARGE_INTEGER libOffset
, /* [in] */
1559 ULARGE_INTEGER cb
, /* [in] */
1560 DWORD dwLockType
) /* [in] */
1565 static HRESULT WINAPI
NoStatStreamImpl_UnlockRegion(
1567 ULARGE_INTEGER libOffset
, /* [in] */
1568 ULARGE_INTEGER cb
, /* [in] */
1569 DWORD dwLockType
) /* [in] */
1574 static HRESULT WINAPI
NoStatStreamImpl_Stat(
1576 STATSTG
* pstatstg
, /* [out] */
1577 DWORD grfStatFlag
) /* [in] */
1582 static HRESULT WINAPI
NoStatStreamImpl_Clone(
1584 IStream
** ppstm
) /* [out] */
1588 static const IStreamVtbl NoStatStreamImpl_Vtbl
;
1591 Build an object that implements IStream, without IStream_Stat capabilities.
1592 Receives a memory handle with data buffer. If memory handle is non-null,
1593 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1594 In any case the object takes ownership of memory handle and will free it on
1597 static IStream
* NoStatStream_Construct(HGLOBAL hGlobal
)
1599 NoStatStreamImpl
* newStream
;
1601 newStream
= HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl
));
1604 newStream
->IStream_iface
.lpVtbl
= &NoStatStreamImpl_Vtbl
;
1606 newStream
->supportHandle
= hGlobal
;
1608 if (!newStream
->supportHandle
)
1609 newStream
->supportHandle
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_NODISCARD
|
1611 newStream
->currentPosition
.u
.HighPart
= 0;
1612 newStream
->currentPosition
.u
.LowPart
= 0;
1613 newStream
->streamSize
.u
.HighPart
= 0;
1614 newStream
->streamSize
.u
.LowPart
= GlobalSize(newStream
->supportHandle
);
1616 return &newStream
->IStream_iface
;
1620 static const IStreamVtbl NoStatStreamImpl_Vtbl
=
1622 NoStatStreamImpl_QueryInterface
,
1623 NoStatStreamImpl_AddRef
,
1624 NoStatStreamImpl_Release
,
1625 NoStatStreamImpl_Read
,
1626 NoStatStreamImpl_Write
,
1627 NoStatStreamImpl_Seek
,
1628 NoStatStreamImpl_SetSize
,
1629 NoStatStreamImpl_CopyTo
,
1630 NoStatStreamImpl_Commit
,
1631 NoStatStreamImpl_Revert
,
1632 NoStatStreamImpl_LockRegion
,
1633 NoStatStreamImpl_UnlockRegion
,
1634 NoStatStreamImpl_Stat
,
1635 NoStatStreamImpl_Clone