push 5b1efc32b5a8acb1d5b5e60584746392dd0c436e
[wine/hacks.git] / dlls / oleaut32 / tests / olepicture.c
blobc8ddc8a7348b986b59134818ee4571c7dc614e8a
1 /*
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
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <float.h>
27 #define COBJMACROS
28 #define NONAMELESSUNION
30 #include "wine/test.h"
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winuser.h>
34 #include <wingdi.h>
35 #include <winnls.h>
36 #include <winerror.h>
37 #include <winnt.h>
39 #include <wtypes.h>
40 #include <olectl.h>
41 #include <objidl.h>
43 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
45 #define ole_expect(expr, expect) { \
46 HRESULT r = expr; \
47 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
50 #define ole_check(expr) ole_expect(expr, S_OK);
52 static HMODULE hOleaut32;
54 static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
55 static HRESULT (WINAPI *pOleCreatePictureIndirect)(PICTDESC*,REFIID,BOOL,LPVOID*);
57 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
59 /* 1x1 pixel gif */
60 static const unsigned char gifimage[35] = {
61 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
62 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
63 0x01,0x00,0x3b
66 /* 1x1 pixel jpg */
67 static const unsigned char jpgimage[285] = {
68 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
69 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
70 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
71 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
72 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
73 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
74 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
75 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,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,0xff,0xc0,
78 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
79 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
81 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
82 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
83 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
84 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
85 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
88 /* 1x1 pixel png */
89 static const unsigned char pngimage[285] = {
90 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
91 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
92 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
93 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
94 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
95 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
96 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
99 /* 1x1 pixel bmp */
100 static const unsigned char bmpimage[66] = {
101 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
102 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
103 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
104 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
105 0x00,0x00
108 /* 2x2 pixel gif */
109 static const unsigned char gif4pixel[42] = {
110 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
111 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
112 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
115 /* APM with an empty metafile with some padding zeros - looks like under Window the
116 * metafile data should be at least 20 bytes */
117 static const unsigned char apmdata[] = {
118 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
119 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
120 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
121 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
124 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
125 static const unsigned char metafile[] = {
126 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
129 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
130 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
131 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
132 0x00, 0x00
135 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
136 static const unsigned char enhmetafile[] = {
137 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
142 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
143 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
144 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
147 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
150 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
151 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
152 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
156 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
157 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
161 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
162 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
163 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
164 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
165 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
167 0x14, 0x00, 0x00, 0x00
171 struct NoStatStreamImpl
173 const IStreamVtbl *lpVtbl;
174 LONG ref;
176 HGLOBAL supportHandle;
177 ULARGE_INTEGER streamSize;
178 ULARGE_INTEGER currentPosition;
180 typedef struct NoStatStreamImpl NoStatStreamImpl;
181 static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal);
183 static void
184 test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
186 IPicture* pic = NULL;
187 HRESULT hres;
188 LPVOID pvObj = NULL;
189 OLE_HANDLE handle, hPal;
190 OLE_XSIZE_HIMETRIC width;
191 OLE_YSIZE_HIMETRIC height;
192 short type;
193 DWORD attr;
194 ULONG res;
196 pvObj = NULL;
197 hres = pOleLoadPicture(stream, imgsize, TRUE, &IID_IPicture, &pvObj);
198 pic = 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");
202 if (pic == NULL)
203 return;
205 pvObj = NULL;
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);
213 handle = 0;
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");
218 width = 0;
219 hres = IPicture_get_Width (pic, &width);
220 ok(hres == S_OK,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres);
221 ok(width != 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
223 height = 0;
224 hres = IPicture_get_Height (pic, &height);
225 ok(hres == S_OK,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres);
226 ok(height != 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
228 type = 0;
229 hres = IPicture_get_Type (pic, &type);
230 ok(hres == S_OK,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
231 ok(type == PICTYPE_BITMAP, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type, PICTYPE_BITMAP);
233 attr = 0;
234 hres = IPicture_get_Attributes (pic, &attr);
235 ok(hres == S_OK,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres);
236 ok(attr == 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr);
238 hPal = 0;
239 hres = IPicture_get_hPal (pic, &hPal);
240 ok(hres == S_OK,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres);
241 /* a single pixel b/w image has no palette */
242 ok(hPal == 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal);
244 res = IPicture_Release (pic);
245 ok (res == 0, "refcount after release is %d, but should be 0?\n", res);
248 static void
249 test_pic(const unsigned char *imgdata, unsigned int imgsize)
251 LPSTREAM stream;
252 HGLOBAL hglob;
253 LPBYTE data;
254 HRESULT hres;
255 LARGE_INTEGER seekto;
256 ULARGE_INTEGER newpos1;
257 DWORD * header;
258 unsigned int i,j;
260 /* Let the fun begin */
261 hglob = GlobalAlloc (0, imgsize);
262 data = GlobalLock (hglob);
263 memcpy(data, imgdata, imgsize);
264 GlobalUnlock(hglob); data = NULL;
266 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
267 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
269 memset(&seekto,0,sizeof(seekto));
270 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
271 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
272 test_pic_with_stream(stream, imgsize);
274 IStream_Release(stream);
276 /* again with Non Statable and Non Seekable stream */
277 stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
278 hglob = 0; /* Non-statable impl always deletes on release */
279 test_pic_with_stream(stream, 0);
281 IStream_Release(stream);
282 for (i = 1; i <= 8; i++) {
283 /* more fun!!! */
284 hglob = GlobalAlloc (0, imgsize + i * (2 * sizeof(DWORD)));
285 data = GlobalLock (hglob);
286 header = (DWORD *)data;
288 /* multiple copies of header */
289 memcpy(data,"lt\0\0",4);
290 header[1] = imgsize;
291 for (j = 2; j <= i; j++) {
292 memcpy(&(header[2 * (j - 1)]), header, 2 * sizeof(DWORD));
294 memcpy(data + i * (2 * sizeof(DWORD)), imgdata, imgsize);
295 GlobalUnlock(hglob); data = NULL;
297 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
298 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
300 memset(&seekto,0,sizeof(seekto));
301 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
302 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
303 test_pic_with_stream(stream, imgsize);
305 IStream_Release(stream);
307 /* again with Non Statable and Non Seekable stream */
308 stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
309 hglob = 0; /* Non-statable impl always deletes on release */
310 test_pic_with_stream(stream, 0);
312 IStream_Release(stream);
316 static void test_empty_image(void) {
317 LPBYTE data;
318 LPSTREAM stream;
319 IPicture* pic = NULL;
320 HRESULT hres;
321 LPVOID pvObj = NULL;
322 HGLOBAL hglob;
323 OLE_HANDLE handle;
324 ULARGE_INTEGER newpos1;
325 LARGE_INTEGER seekto;
326 short type;
327 DWORD attr;
329 /* Empty image. Happens occasionally in VB programs. */
330 hglob = GlobalAlloc (0, 8);
331 data = GlobalLock (hglob);
332 memcpy(data,"lt\0\0",4);
333 ((DWORD*)data)[1] = 0;
334 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
335 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
337 memset(&seekto,0,sizeof(seekto));
338 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
339 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
341 pvObj = NULL;
342 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
343 pic = pvObj;
344 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
345 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
347 hres = IPicture_get_Type (pic, &type);
348 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
349 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
351 attr = 0xdeadbeef;
352 hres = IPicture_get_Attributes (pic, &attr);
353 ok (hres == S_OK,"empty picture get attributes failed with hres 0x%08x\n", hres);
354 ok (attr == 0,"attr is %d, but should be 0\n", attr);
356 hres = IPicture_get_Handle (pic, &handle);
357 ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres);
358 ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
359 IPicture_Release (pic);
360 IStream_Release (stream);
363 static void test_empty_image_2(void) {
364 LPBYTE data;
365 LPSTREAM stream;
366 IPicture* pic = NULL;
367 HRESULT hres;
368 LPVOID pvObj = NULL;
369 HGLOBAL hglob;
370 ULARGE_INTEGER newpos1;
371 LARGE_INTEGER seekto;
372 short type;
374 /* Empty image at random stream position. */
375 hglob = GlobalAlloc (0, 200);
376 data = GlobalLock (hglob);
377 data += 42;
378 memcpy(data,"lt\0\0",4);
379 ((DWORD*)data)[1] = 0;
380 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
381 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
383 memset(&seekto,0,sizeof(seekto));
384 seekto.u.LowPart = 42;
385 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
386 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
388 pvObj = NULL;
389 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
390 pic = pvObj;
391 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
392 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
394 hres = IPicture_get_Type (pic, &type);
395 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
396 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
398 IPicture_Release (pic);
399 IStream_Release (stream);
402 static void test_Invoke(void)
404 IPictureDisp *picdisp;
405 HRESULT hr;
406 VARIANTARG vararg;
407 DISPPARAMS dispparams;
408 VARIANT varresult;
409 IStream *stream;
410 HGLOBAL hglob;
411 void *data;
413 hglob = GlobalAlloc (0, sizeof(gifimage));
414 data = GlobalLock(hglob);
415 memcpy(data, gifimage, sizeof(gifimage));
416 GlobalUnlock(hglob);
418 hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
419 ok_ole_success(hr, "CreateStreamOnHGlobal");
421 hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
422 IStream_Release(stream);
423 GlobalFree(hglob);
424 ok_ole_success(hr, "OleLoadPicture");
426 V_VT(&vararg) = VT_BOOL;
427 V_BOOL(&vararg) = VARIANT_FALSE;
428 dispparams.cNamedArgs = 0;
429 dispparams.rgdispidNamedArgs = NULL;
430 dispparams.cArgs = 1;
431 dispparams.rgvarg = &vararg;
432 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
433 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
434 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
435 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
437 dispparams.cArgs = 0;
438 dispparams.rgvarg = NULL;
439 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
440 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
442 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
443 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
445 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
446 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
448 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
449 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
451 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
452 ok_ole_success(hr, "IPictureDisp_Invoke");
453 ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult));
455 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
456 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
458 hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
459 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
461 dispparams.cArgs = 1;
462 dispparams.rgvarg = &vararg;
463 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
464 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
466 dispparams.cArgs = 1;
467 dispparams.rgvarg = &vararg;
468 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
469 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
471 IPictureDisp_Release(picdisp);
474 static void test_OleCreatePictureIndirect(void)
476 IPicture *pict;
477 HRESULT hr;
478 short type;
479 OLE_HANDLE handle;
481 if(!pOleCreatePictureIndirect)
483 win_skip("Skipping OleCreatePictureIndirect tests\n");
484 return;
487 hr = pOleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict);
488 ok(hr == S_OK, "hr %08x\n", hr);
490 hr = IPicture_get_Type(pict, &type);
491 ok(hr == S_OK, "hr %08x\n", hr);
492 ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type);
494 hr = IPicture_get_Handle(pict, &handle);
495 ok(hr == S_OK, "hr %08x\n", hr);
496 ok(handle == 0, "handle %08x\n", handle);
498 IPicture_Release(pict);
501 static void test_apm(void)
503 OLE_HANDLE handle;
504 LPSTREAM stream;
505 IPicture *pict;
506 HGLOBAL hglob;
507 LPBYTE *data;
508 LONG cxy;
509 BOOL keep;
510 short type;
512 hglob = GlobalAlloc (0, sizeof(apmdata));
513 data = GlobalLock(hglob);
514 memcpy(data, apmdata, sizeof(apmdata));
516 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
517 ole_check(OleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
519 ole_check(IPicture_get_Handle(pict, &handle));
520 ok(handle != 0, "handle is null\n");
522 ole_check(IPicture_get_Type(pict, &type));
523 expect_eq(type, PICTYPE_METAFILE, short, "%d");
525 ole_check(IPicture_get_Height(pict, &cxy));
526 expect_eq(cxy, 1667, LONG, "%d");
528 ole_check(IPicture_get_Width(pict, &cxy));
529 expect_eq(cxy, 1323, LONG, "%d");
531 ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
532 todo_wine expect_eq(keep, FALSE, LONG, "%d");
534 ole_expect(IPicture_get_hPal(pict, &handle), E_FAIL);
535 IPicture_Release(pict);
536 IStream_Release(stream);
539 static void test_metafile(void)
541 LPSTREAM stream;
542 IPicture *pict;
543 HGLOBAL hglob;
544 LPBYTE *data;
546 hglob = GlobalAlloc (0, sizeof(metafile));
547 data = GlobalLock(hglob);
548 memcpy(data, metafile, sizeof(metafile));
550 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
551 /* Windows does not load simple metafiles */
552 ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
554 IStream_Release(stream);
557 static void test_enhmetafile(void)
559 OLE_HANDLE handle;
560 LPSTREAM stream;
561 IPicture *pict;
562 HGLOBAL hglob;
563 LPBYTE *data;
564 LONG cxy;
565 BOOL keep;
566 short type;
568 hglob = GlobalAlloc (0, sizeof(enhmetafile));
569 data = GlobalLock(hglob);
570 memcpy(data, enhmetafile, sizeof(enhmetafile));
572 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
573 ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
575 ole_check(IPicture_get_Handle(pict, &handle));
576 ok(handle != 0, "handle is null\n");
578 ole_check(IPicture_get_Type(pict, &type));
579 expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
581 ole_check(IPicture_get_Height(pict, &cxy));
582 expect_eq(cxy, -23, LONG, "%d");
584 ole_check(IPicture_get_Width(pict, &cxy));
585 expect_eq(cxy, -25, LONG, "%d");
587 ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
588 todo_wine expect_eq(keep, FALSE, LONG, "%d");
590 IPicture_Release(pict);
591 IStream_Release(stream);
594 static void test_Render(void)
596 IPicture *pic;
597 HRESULT hres;
598 short type;
599 PICTDESC desc;
600 OLE_XSIZE_HIMETRIC pWidth;
601 OLE_YSIZE_HIMETRIC pHeight;
602 COLORREF result, expected;
603 HDC hdc = GetDC(0);
605 /* test IPicture::Render return code on uninitialized picture */
606 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
607 hres = IPicture_get_Type(pic, &type);
608 ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
609 ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
610 /* zero dimensions */
611 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
612 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
613 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
614 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
615 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
616 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
617 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
618 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
619 hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
620 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
621 hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
622 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
623 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
624 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
625 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
626 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL);
627 ole_expect(hres, S_OK);
628 IPicture_Release(pic);
630 desc.cbSizeofstruct = sizeof(PICTDESC);
631 desc.picType = PICTYPE_ICON;
632 desc.u.icon.hicon = LoadIcon(NULL, IDI_APPLICATION);
633 if(!desc.u.icon.hicon){
634 win_skip("LoadIcon failed. Skipping...\n");
635 ReleaseDC(NULL, hdc);
636 return;
639 OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic);
640 /* zero dimensions, PICTYPE_ICON */
641 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
642 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
643 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
644 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
645 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
646 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
647 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
648 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
649 hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
650 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
651 hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
652 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
653 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
654 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
656 /* Check if target size and position is respected */
657 IPicture_get_Width(pic, &pWidth);
658 IPicture_get_Height(pic, &pHeight);
660 SetPixelV(hdc, 0, 0, 0x00F0F0F0);
661 SetPixelV(hdc, 5, 5, 0x00F0F0F0);
662 SetPixelV(hdc, 10, 10, 0x00F0F0F0);
663 expected = GetPixel(hdc, 0, 0);
665 hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL);
666 ole_expect(hres, S_OK);
668 if(hres != S_OK) {
669 IPicture_Release(pic);
670 ReleaseDC(NULL, hdc);
671 return;
674 /* Evaluate the rendered Icon */
675 result = GetPixel(hdc, 0, 0);
676 ok(result == expected,
677 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
678 result = GetPixel(hdc, 5, 5);
679 ok(result != expected ||
680 broken(result == expected), /* WinNT 4.0 and older may claim they drew */
681 /* the icon, even if they didn't. */
682 "Color at 5,5 should have changed, but still was 0x%06X\n", expected);
683 result = GetPixel(hdc, 10, 10);
684 ok(result == expected,
685 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
687 IPicture_Release(pic);
688 ReleaseDC(NULL, hdc);
691 static void test_get_Attributes(void)
693 IPicture *pic;
694 HRESULT hres;
695 short type;
696 DWORD attr;
698 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
699 hres = IPicture_get_Type(pic, &type);
700 ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
701 ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
703 hres = IPicture_get_Attributes(pic, NULL);
704 ole_expect(hres, E_POINTER);
706 attr = 0xdeadbeef;
707 hres = IPicture_get_Attributes(pic, &attr);
708 ole_expect(hres, S_OK);
709 ok(attr == 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr);
711 IPicture_Release(pic);
714 static void test_get_Handle(void)
716 IPicture *pic;
717 HRESULT hres;
719 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
721 hres = IPicture_get_Handle(pic, NULL);
722 ole_expect(hres, E_POINTER);
724 IPicture_Release(pic);
727 static void test_get_Type(void)
729 IPicture *pic;
730 HRESULT hres;
732 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
734 hres = IPicture_get_Type(pic, NULL);
735 ole_expect(hres, E_POINTER);
737 IPicture_Release(pic);
740 START_TEST(olepicture)
742 hOleaut32 = GetModuleHandleA("oleaut32.dll");
743 pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
744 pOleCreatePictureIndirect = (void*)GetProcAddress(hOleaut32, "OleCreatePictureIndirect");
745 if (!pOleLoadPicture)
747 win_skip("OleLoadPicture is not available\n");
748 return;
751 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
752 test_pic(gifimage, sizeof(gifimage));
753 test_pic(jpgimage, sizeof(jpgimage));
754 test_pic(bmpimage, sizeof(bmpimage));
755 test_pic(gif4pixel, sizeof(gif4pixel));
756 /* FIXME: No PNG support yet in Wine or in older Windows... */
757 if (0) test_pic(pngimage, sizeof(pngimage));
758 test_empty_image();
759 test_empty_image_2();
760 test_apm();
761 test_metafile();
762 test_enhmetafile();
764 test_Invoke();
765 test_OleCreatePictureIndirect();
766 test_Render();
767 test_get_Attributes();
768 test_get_Handle();
769 test_get_Type();
773 /* Helper functions only ... */
776 static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
778 GlobalFree(This->supportHandle);
779 This->supportHandle=0;
780 HeapFree(GetProcessHeap(), 0, This);
783 static ULONG WINAPI NoStatStreamImpl_AddRef(
784 IStream* iface)
786 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
787 return InterlockedIncrement(&This->ref);
790 static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
791 IStream* iface,
792 REFIID riid, /* [in] */
793 void** ppvObject) /* [iid_is][out] */
795 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
796 if (ppvObject==0) return E_INVALIDARG;
797 *ppvObject = 0;
798 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
800 *ppvObject = This;
802 else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
804 *ppvObject = This;
807 if ((*ppvObject)==0)
808 return E_NOINTERFACE;
809 NoStatStreamImpl_AddRef(iface);
810 return S_OK;
813 static ULONG WINAPI NoStatStreamImpl_Release(
814 IStream* iface)
816 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
817 ULONG newRef = InterlockedDecrement(&This->ref);
818 if (newRef==0)
819 NoStatStreamImpl_Destroy(This);
820 return newRef;
823 static HRESULT WINAPI NoStatStreamImpl_Read(
824 IStream* iface,
825 void* pv, /* [length_is][size_is][out] */
826 ULONG cb, /* [in] */
827 ULONG* pcbRead) /* [out] */
829 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
830 void* supportBuffer;
831 ULONG bytesReadBuffer;
832 ULONG bytesToReadFromBuffer;
834 if (pcbRead==0)
835 pcbRead = &bytesReadBuffer;
836 bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
837 supportBuffer = GlobalLock(This->supportHandle);
838 memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
839 This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
840 *pcbRead = bytesToReadFromBuffer;
841 GlobalUnlock(This->supportHandle);
842 if(*pcbRead == cb)
843 return S_OK;
844 return S_FALSE;
847 static HRESULT WINAPI NoStatStreamImpl_Write(
848 IStream* iface,
849 const void* pv, /* [size_is][in] */
850 ULONG cb, /* [in] */
851 ULONG* pcbWritten) /* [out] */
853 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
854 void* supportBuffer;
855 ULARGE_INTEGER newSize;
856 ULONG bytesWritten = 0;
858 if (pcbWritten == 0)
859 pcbWritten = &bytesWritten;
860 if (cb == 0)
861 return S_OK;
862 newSize.u.HighPart = 0;
863 newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
864 if (newSize.u.LowPart > This->streamSize.u.LowPart)
865 IStream_SetSize(iface, newSize);
867 supportBuffer = GlobalLock(This->supportHandle);
868 memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
869 This->currentPosition.u.LowPart+=cb;
870 *pcbWritten = cb;
871 GlobalUnlock(This->supportHandle);
872 return S_OK;
875 static HRESULT WINAPI NoStatStreamImpl_Seek(
876 IStream* iface,
877 LARGE_INTEGER dlibMove, /* [in] */
878 DWORD dwOrigin, /* [in] */
879 ULARGE_INTEGER* plibNewPosition) /* [out] */
881 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
882 ULARGE_INTEGER newPosition;
883 switch (dwOrigin)
885 case STREAM_SEEK_SET:
886 newPosition.u.HighPart = 0;
887 newPosition.u.LowPart = 0;
888 break;
889 case STREAM_SEEK_CUR:
890 newPosition = This->currentPosition;
891 break;
892 case STREAM_SEEK_END:
893 newPosition = This->streamSize;
894 break;
895 default:
896 return STG_E_INVALIDFUNCTION;
898 if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart)
899 return STG_E_INVALIDFUNCTION;
900 newPosition.QuadPart += dlibMove.QuadPart;
901 if (plibNewPosition) *plibNewPosition = newPosition;
902 This->currentPosition = newPosition;
903 return S_OK;
906 static HRESULT WINAPI NoStatStreamImpl_SetSize(
907 IStream* iface,
908 ULARGE_INTEGER libNewSize) /* [in] */
910 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
911 HGLOBAL supportHandle;
912 if (libNewSize.u.HighPart != 0)
913 return STG_E_INVALIDFUNCTION;
914 if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
915 return S_OK;
916 supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
917 if (supportHandle == 0)
918 return STG_E_MEDIUMFULL;
919 This->supportHandle = supportHandle;
920 This->streamSize.u.LowPart = libNewSize.u.LowPart;
921 return S_OK;
924 static HRESULT WINAPI NoStatStreamImpl_CopyTo(
925 IStream* iface,
926 IStream* pstm, /* [unique][in] */
927 ULARGE_INTEGER cb, /* [in] */
928 ULARGE_INTEGER* pcbRead, /* [out] */
929 ULARGE_INTEGER* pcbWritten) /* [out] */
931 HRESULT hr = S_OK;
932 BYTE tmpBuffer[128];
933 ULONG bytesRead, bytesWritten, copySize;
934 ULARGE_INTEGER totalBytesRead;
935 ULARGE_INTEGER totalBytesWritten;
937 if ( pstm == 0 )
938 return STG_E_INVALIDPOINTER;
939 totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
940 totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
942 while ( cb.u.LowPart > 0 )
944 if ( cb.u.LowPart >= 128 )
945 copySize = 128;
946 else
947 copySize = cb.u.LowPart;
948 IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
949 totalBytesRead.u.LowPart += bytesRead;
950 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
951 totalBytesWritten.u.LowPart += bytesWritten;
952 if (bytesRead != bytesWritten)
954 hr = STG_E_MEDIUMFULL;
955 break;
957 if (bytesRead!=copySize)
958 cb.u.LowPart = 0;
959 else
960 cb.u.LowPart -= bytesRead;
962 if (pcbRead)
964 pcbRead->u.LowPart = totalBytesRead.u.LowPart;
965 pcbRead->u.HighPart = totalBytesRead.u.HighPart;
968 if (pcbWritten)
970 pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
971 pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
973 return hr;
976 static HRESULT WINAPI NoStatStreamImpl_Commit(IStream* iface,DWORD grfCommitFlags)
978 return S_OK;
980 static HRESULT WINAPI NoStatStreamImpl_Revert(IStream* iface) { return S_OK; }
982 static HRESULT WINAPI NoStatStreamImpl_LockRegion(
983 IStream* iface,
984 ULARGE_INTEGER libOffset, /* [in] */
985 ULARGE_INTEGER cb, /* [in] */
986 DWORD dwLockType) /* [in] */
988 return S_OK;
991 static HRESULT WINAPI NoStatStreamImpl_UnlockRegion(
992 IStream* iface,
993 ULARGE_INTEGER libOffset, /* [in] */
994 ULARGE_INTEGER cb, /* [in] */
995 DWORD dwLockType) /* [in] */
997 return S_OK;
1000 static HRESULT WINAPI NoStatStreamImpl_Stat(
1001 IStream* iface,
1002 STATSTG* pstatstg, /* [out] */
1003 DWORD grfStatFlag) /* [in] */
1005 return E_NOTIMPL;
1008 static HRESULT WINAPI NoStatStreamImpl_Clone(
1009 IStream* iface,
1010 IStream** ppstm) /* [out] */
1012 return E_NOTIMPL;
1014 static const IStreamVtbl NoStatStreamImpl_Vtbl;
1017 Build an object that implements IStream, without IStream_Stat capabilities.
1018 Receives a memory handle with data buffer. If memory handle is non-null,
1019 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1020 In any case the object takes ownership of memory handle and will free it on
1021 object release.
1023 static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
1025 NoStatStreamImpl* newStream;
1027 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
1028 if (newStream!=0)
1030 newStream->lpVtbl = &NoStatStreamImpl_Vtbl;
1031 newStream->ref = 1;
1032 newStream->supportHandle = hGlobal;
1034 if (!newStream->supportHandle)
1035 newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
1036 GMEM_SHARE, 0);
1037 newStream->currentPosition.u.HighPart = 0;
1038 newStream->currentPosition.u.LowPart = 0;
1039 newStream->streamSize.u.HighPart = 0;
1040 newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
1042 return newStream;
1046 static const IStreamVtbl NoStatStreamImpl_Vtbl =
1048 NoStatStreamImpl_QueryInterface,
1049 NoStatStreamImpl_AddRef,
1050 NoStatStreamImpl_Release,
1051 NoStatStreamImpl_Read,
1052 NoStatStreamImpl_Write,
1053 NoStatStreamImpl_Seek,
1054 NoStatStreamImpl_SetSize,
1055 NoStatStreamImpl_CopyTo,
1056 NoStatStreamImpl_Commit,
1057 NoStatStreamImpl_Revert,
1058 NoStatStreamImpl_LockRegion,
1059 NoStatStreamImpl_UnlockRegion,
1060 NoStatStreamImpl_Stat,
1061 NoStatStreamImpl_Clone