push 8b07bf1f08b23b9893a622b47d2be359556765b1
[wine/hacks.git] / dlls / oleaut32 / tests / olepicture.c
blob42f58ae02c8ea1ae77dea1b27616daa3f275cf64
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);
362 static void test_empty_image_2(void) {
363 LPBYTE data;
364 LPSTREAM stream;
365 IPicture* pic = NULL;
366 HRESULT hres;
367 LPVOID pvObj = NULL;
368 HGLOBAL hglob;
369 ULARGE_INTEGER newpos1;
370 LARGE_INTEGER seekto;
371 short type;
373 /* Empty image at random stream position. */
374 hglob = GlobalAlloc (0, 200);
375 data = GlobalLock (hglob);
376 data += 42;
377 memcpy(data,"lt\0\0",4);
378 ((DWORD*)data)[1] = 0;
379 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
380 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
382 memset(&seekto,0,sizeof(seekto));
383 seekto.u.LowPart = 42;
384 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
385 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
387 pvObj = NULL;
388 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
389 pic = pvObj;
390 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
391 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
393 hres = IPicture_get_Type (pic, &type);
394 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
395 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
397 IPicture_Release (pic);
400 static void test_Invoke(void)
402 IPictureDisp *picdisp;
403 HRESULT hr;
404 VARIANTARG vararg;
405 DISPPARAMS dispparams;
406 VARIANT varresult;
407 IStream *stream;
408 HGLOBAL hglob;
409 void *data;
411 hglob = GlobalAlloc (0, sizeof(gifimage));
412 data = GlobalLock(hglob);
413 memcpy(data, gifimage, sizeof(gifimage));
414 GlobalUnlock(hglob);
416 hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
417 ok_ole_success(hr, "CreateStreamOnHGlobal");
419 hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
420 IStream_Release(stream);
421 ok_ole_success(hr, "OleLoadPicture");
423 V_VT(&vararg) = VT_BOOL;
424 V_BOOL(&vararg) = VARIANT_FALSE;
425 dispparams.cNamedArgs = 0;
426 dispparams.rgdispidNamedArgs = NULL;
427 dispparams.cArgs = 1;
428 dispparams.rgvarg = &vararg;
429 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
430 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
431 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
432 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
434 dispparams.cArgs = 0;
435 dispparams.rgvarg = NULL;
436 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
437 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
439 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
440 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
442 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, 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, &varresult, 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, &dispparams, &varresult, NULL, NULL);
449 ok_ole_success(hr, "IPictureDisp_Invoke");
450 ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult));
452 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
453 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
455 hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &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 dispparams.cArgs = 1;
459 dispparams.rgvarg = &vararg;
460 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
461 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
463 dispparams.cArgs = 1;
464 dispparams.rgvarg = &vararg;
465 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
466 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
468 IPictureDisp_Release(picdisp);
471 static void test_OleCreatePictureIndirect(void)
473 IPicture *pict;
474 HRESULT hr;
475 short type;
476 OLE_HANDLE handle;
478 if(!pOleCreatePictureIndirect)
480 win_skip("Skipping OleCreatePictureIndirect tests\n");
481 return;
484 hr = pOleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict);
485 ok(hr == S_OK, "hr %08x\n", hr);
487 hr = IPicture_get_Type(pict, &type);
488 ok(hr == S_OK, "hr %08x\n", hr);
489 ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type);
491 hr = IPicture_get_Handle(pict, &handle);
492 ok(hr == S_OK, "hr %08x\n", hr);
493 ok(handle == 0, "handle %08x\n", handle);
495 IPicture_Release(pict);
498 static void test_apm(void)
500 OLE_HANDLE handle;
501 LPSTREAM stream;
502 IPicture *pict;
503 HGLOBAL hglob;
504 LPBYTE *data;
505 LONG cxy;
506 BOOL keep;
507 short type;
509 hglob = GlobalAlloc (0, sizeof(apmdata));
510 data = GlobalLock(hglob);
511 memcpy(data, apmdata, sizeof(apmdata));
513 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
514 ole_check(OleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
516 ole_check(IPicture_get_Handle(pict, &handle));
517 ok(handle != 0, "handle is null\n");
519 ole_check(IPicture_get_Type(pict, &type));
520 expect_eq(type, PICTYPE_METAFILE, short, "%d");
522 ole_check(IPicture_get_Height(pict, &cxy));
523 expect_eq(cxy, 1667, LONG, "%d");
525 ole_check(IPicture_get_Width(pict, &cxy));
526 expect_eq(cxy, 1323, LONG, "%d");
528 ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
529 todo_wine expect_eq(keep, FALSE, LONG, "%d");
531 ole_expect(IPicture_get_hPal(pict, &handle), E_FAIL);
532 IPicture_Release(pict);
533 IStream_Release(stream);
536 static void test_metafile(void)
538 LPSTREAM stream;
539 IPicture *pict;
540 HGLOBAL hglob;
541 LPBYTE *data;
543 hglob = GlobalAlloc (0, sizeof(metafile));
544 data = GlobalLock(hglob);
545 memcpy(data, metafile, sizeof(metafile));
547 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
548 /* Windows does not load simple metafiles */
549 ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
551 IStream_Release(stream);
554 static void test_enhmetafile(void)
556 OLE_HANDLE handle;
557 LPSTREAM stream;
558 IPicture *pict;
559 HGLOBAL hglob;
560 LPBYTE *data;
561 LONG cxy;
562 BOOL keep;
563 short type;
565 hglob = GlobalAlloc (0, sizeof(enhmetafile));
566 data = GlobalLock(hglob);
567 memcpy(data, enhmetafile, sizeof(enhmetafile));
569 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
570 ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
572 ole_check(IPicture_get_Handle(pict, &handle));
573 ok(handle != 0, "handle is null\n");
575 ole_check(IPicture_get_Type(pict, &type));
576 expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
578 ole_check(IPicture_get_Height(pict, &cxy));
579 expect_eq(cxy, -23, LONG, "%d");
581 ole_check(IPicture_get_Width(pict, &cxy));
582 expect_eq(cxy, -25, LONG, "%d");
584 ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
585 todo_wine expect_eq(keep, FALSE, LONG, "%d");
587 IPicture_Release(pict);
588 IStream_Release(stream);
591 static void test_Render(void)
593 IPicture *pic;
594 HRESULT hres;
595 short type;
596 PICTDESC desc;
597 OLE_XSIZE_HIMETRIC pWidth;
598 OLE_YSIZE_HIMETRIC pHeight;
599 COLORREF result;
600 HDC hdc = GetDC(0);
602 /* test IPicture::Render return code on uninitialized picture */
603 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
604 hres = IPicture_get_Type(pic, &type);
605 ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
606 ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
607 /* zero dimensions */
608 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
609 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
610 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
611 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
612 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
613 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
614 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
615 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
616 hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
617 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
618 hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
619 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
620 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
621 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
622 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
623 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL);
624 ole_expect(hres, S_OK);
625 IPicture_Release(pic);
627 desc.cbSizeofstruct = sizeof(PICTDESC);
628 desc.picType = PICTYPE_ICON;
629 desc.u.icon.hicon = LoadIcon(NULL, IDI_APPLICATION);
630 if(!desc.u.icon.hicon){
631 win_skip("LoadIcon failed. Skipping...\n");
632 ReleaseDC(NULL, hdc);
633 return;
636 OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic);
637 /* zero dimensions, PICTYPE_ICON */
638 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
639 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
640 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
641 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
642 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
643 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
644 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
645 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
646 hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
647 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
648 hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
649 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
650 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
651 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
653 /* Check if target size and position is respected */
654 IPicture_get_Width(pic, &pWidth);
655 IPicture_get_Height(pic, &pHeight);
657 SetPixelV(hdc, 0, 0, 0x00F0F0F0);
658 SetPixelV(hdc, 5, 5, 0x00F0F0F0);
659 SetPixelV(hdc, 10, 10, 0x00F0F0F0);
661 IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL);
663 result = GetPixel(hdc, 0, 0);
664 ok(result == 0x00F0F0F0,
665 "Color at 0,0 should be unchanged 0xF0F0F0, but was 0x%06X\n", result);
666 result = GetPixel(hdc, 5, 5);
667 ok(result != 0x00F0F0F0,
668 "Color at 5,5 should have changed, but still was 0x%06X\n", result);
669 result = GetPixel(hdc, 10, 10);
670 ok(result == 0x00F0F0F0,
671 "Color at 10,10 should be unchanged 0xF0F0F0, but was 0x%06X\n", result);
673 IPicture_Release(pic);
674 ReleaseDC(NULL, hdc);
677 static void test_get_Attributes(void)
679 IPicture *pic;
680 HRESULT hres;
681 short type;
682 DWORD attr;
684 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
685 hres = IPicture_get_Type(pic, &type);
686 ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
687 ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
689 hres = IPicture_get_Attributes(pic, NULL);
690 ole_expect(hres, E_POINTER);
692 attr = 0xdeadbeef;
693 hres = IPicture_get_Attributes(pic, &attr);
694 ole_expect(hres, S_OK);
695 ok(attr == 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr);
697 IPicture_Release(pic);
700 static void test_get_Handle(void)
702 IPicture *pic;
703 HRESULT hres;
705 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
707 hres = IPicture_get_Handle(pic, NULL);
708 ole_expect(hres, E_POINTER);
710 IPicture_Release(pic);
713 static void test_get_Type(void)
715 IPicture *pic;
716 HRESULT hres;
718 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
720 hres = IPicture_get_Type(pic, NULL);
721 ole_expect(hres, E_POINTER);
723 IPicture_Release(pic);
726 START_TEST(olepicture)
728 hOleaut32 = GetModuleHandleA("oleaut32.dll");
729 pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
730 pOleCreatePictureIndirect = (void*)GetProcAddress(hOleaut32, "OleCreatePictureIndirect");
731 if (!pOleLoadPicture)
733 win_skip("OleLoadPicture is not available\n");
734 return;
737 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
738 test_pic(gifimage, sizeof(gifimage));
739 test_pic(jpgimage, sizeof(jpgimage));
740 test_pic(bmpimage, sizeof(bmpimage));
741 test_pic(gif4pixel, sizeof(gif4pixel));
742 /* FIXME: No PNG support yet in Wine or in older Windows... */
743 if (0) test_pic(pngimage, sizeof(pngimage));
744 test_empty_image();
745 test_empty_image_2();
746 test_apm();
747 test_metafile();
748 test_enhmetafile();
750 test_Invoke();
751 test_OleCreatePictureIndirect();
752 test_Render();
753 test_get_Attributes();
754 test_get_Handle();
755 test_get_Type();
759 /* Helper functions only ... */
762 static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
764 GlobalFree(This->supportHandle);
765 This->supportHandle=0;
766 HeapFree(GetProcessHeap(), 0, This);
769 static ULONG WINAPI NoStatStreamImpl_AddRef(
770 IStream* iface)
772 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
773 return InterlockedIncrement(&This->ref);
776 static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
777 IStream* iface,
778 REFIID riid, /* [in] */
779 void** ppvObject) /* [iid_is][out] */
781 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
782 if (ppvObject==0) return E_INVALIDARG;
783 *ppvObject = 0;
784 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
786 *ppvObject = This;
788 else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
790 *ppvObject = This;
793 if ((*ppvObject)==0)
794 return E_NOINTERFACE;
795 NoStatStreamImpl_AddRef(iface);
796 return S_OK;
799 static ULONG WINAPI NoStatStreamImpl_Release(
800 IStream* iface)
802 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
803 ULONG newRef = InterlockedDecrement(&This->ref);
804 if (newRef==0)
805 NoStatStreamImpl_Destroy(This);
806 return newRef;
809 static HRESULT WINAPI NoStatStreamImpl_Read(
810 IStream* iface,
811 void* pv, /* [length_is][size_is][out] */
812 ULONG cb, /* [in] */
813 ULONG* pcbRead) /* [out] */
815 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
816 void* supportBuffer;
817 ULONG bytesReadBuffer;
818 ULONG bytesToReadFromBuffer;
820 if (pcbRead==0)
821 pcbRead = &bytesReadBuffer;
822 bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
823 supportBuffer = GlobalLock(This->supportHandle);
824 memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
825 This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
826 *pcbRead = bytesToReadFromBuffer;
827 GlobalUnlock(This->supportHandle);
828 if(*pcbRead == cb)
829 return S_OK;
830 return S_FALSE;
833 static HRESULT WINAPI NoStatStreamImpl_Write(
834 IStream* iface,
835 const void* pv, /* [size_is][in] */
836 ULONG cb, /* [in] */
837 ULONG* pcbWritten) /* [out] */
839 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
840 void* supportBuffer;
841 ULARGE_INTEGER newSize;
842 ULONG bytesWritten = 0;
844 if (pcbWritten == 0)
845 pcbWritten = &bytesWritten;
846 if (cb == 0)
847 return S_OK;
848 newSize.u.HighPart = 0;
849 newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
850 if (newSize.u.LowPart > This->streamSize.u.LowPart)
851 IStream_SetSize(iface, newSize);
853 supportBuffer = GlobalLock(This->supportHandle);
854 memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
855 This->currentPosition.u.LowPart+=cb;
856 *pcbWritten = cb;
857 GlobalUnlock(This->supportHandle);
858 return S_OK;
861 static HRESULT WINAPI NoStatStreamImpl_Seek(
862 IStream* iface,
863 LARGE_INTEGER dlibMove, /* [in] */
864 DWORD dwOrigin, /* [in] */
865 ULARGE_INTEGER* plibNewPosition) /* [out] */
867 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
868 ULARGE_INTEGER newPosition;
869 switch (dwOrigin)
871 case STREAM_SEEK_SET:
872 newPosition.u.HighPart = 0;
873 newPosition.u.LowPart = 0;
874 break;
875 case STREAM_SEEK_CUR:
876 newPosition = This->currentPosition;
877 break;
878 case STREAM_SEEK_END:
879 newPosition = This->streamSize;
880 break;
881 default:
882 return STG_E_INVALIDFUNCTION;
884 if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart)
885 return STG_E_INVALIDFUNCTION;
886 newPosition.QuadPart += dlibMove.QuadPart;
887 if (plibNewPosition) *plibNewPosition = newPosition;
888 This->currentPosition = newPosition;
889 return S_OK;
892 static HRESULT WINAPI NoStatStreamImpl_SetSize(
893 IStream* iface,
894 ULARGE_INTEGER libNewSize) /* [in] */
896 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
897 HGLOBAL supportHandle;
898 if (libNewSize.u.HighPart != 0)
899 return STG_E_INVALIDFUNCTION;
900 if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
901 return S_OK;
902 supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
903 if (supportHandle == 0)
904 return STG_E_MEDIUMFULL;
905 This->supportHandle = supportHandle;
906 This->streamSize.u.LowPart = libNewSize.u.LowPart;
907 return S_OK;
910 static HRESULT WINAPI NoStatStreamImpl_CopyTo(
911 IStream* iface,
912 IStream* pstm, /* [unique][in] */
913 ULARGE_INTEGER cb, /* [in] */
914 ULARGE_INTEGER* pcbRead, /* [out] */
915 ULARGE_INTEGER* pcbWritten) /* [out] */
917 HRESULT hr = S_OK;
918 BYTE tmpBuffer[128];
919 ULONG bytesRead, bytesWritten, copySize;
920 ULARGE_INTEGER totalBytesRead;
921 ULARGE_INTEGER totalBytesWritten;
923 if ( pstm == 0 )
924 return STG_E_INVALIDPOINTER;
925 totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
926 totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
928 while ( cb.u.LowPart > 0 )
930 if ( cb.u.LowPart >= 128 )
931 copySize = 128;
932 else
933 copySize = cb.u.LowPart;
934 IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
935 totalBytesRead.u.LowPart += bytesRead;
936 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
937 totalBytesWritten.u.LowPart += bytesWritten;
938 if (bytesRead != bytesWritten)
940 hr = STG_E_MEDIUMFULL;
941 break;
943 if (bytesRead!=copySize)
944 cb.u.LowPart = 0;
945 else
946 cb.u.LowPart -= bytesRead;
948 if (pcbRead)
950 pcbRead->u.LowPart = totalBytesRead.u.LowPart;
951 pcbRead->u.HighPart = totalBytesRead.u.HighPart;
954 if (pcbWritten)
956 pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
957 pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
959 return hr;
962 static HRESULT WINAPI NoStatStreamImpl_Commit(IStream* iface,DWORD grfCommitFlags)
964 return S_OK;
966 static HRESULT WINAPI NoStatStreamImpl_Revert(IStream* iface) { return S_OK; }
968 static HRESULT WINAPI NoStatStreamImpl_LockRegion(
969 IStream* iface,
970 ULARGE_INTEGER libOffset, /* [in] */
971 ULARGE_INTEGER cb, /* [in] */
972 DWORD dwLockType) /* [in] */
974 return S_OK;
977 static HRESULT WINAPI NoStatStreamImpl_UnlockRegion(
978 IStream* iface,
979 ULARGE_INTEGER libOffset, /* [in] */
980 ULARGE_INTEGER cb, /* [in] */
981 DWORD dwLockType) /* [in] */
983 return S_OK;
986 static HRESULT WINAPI NoStatStreamImpl_Stat(
987 IStream* iface,
988 STATSTG* pstatstg, /* [out] */
989 DWORD grfStatFlag) /* [in] */
991 return E_NOTIMPL;
994 static HRESULT WINAPI NoStatStreamImpl_Clone(
995 IStream* iface,
996 IStream** ppstm) /* [out] */
998 return E_NOTIMPL;
1000 static const IStreamVtbl NoStatStreamImpl_Vtbl;
1003 Build an object that implements IStream, without IStream_Stat capabilities.
1004 Receives a memory handle with data buffer. If memory handle is non-null,
1005 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1006 In any case the object takes ownership of memory handle and will free it on
1007 object release.
1009 static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
1011 NoStatStreamImpl* newStream;
1013 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
1014 if (newStream!=0)
1016 newStream->lpVtbl = &NoStatStreamImpl_Vtbl;
1017 newStream->ref = 1;
1018 newStream->supportHandle = hGlobal;
1020 if (!newStream->supportHandle)
1021 newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
1022 GMEM_SHARE, 0);
1023 newStream->currentPosition.u.HighPart = 0;
1024 newStream->currentPosition.u.LowPart = 0;
1025 newStream->streamSize.u.HighPart = 0;
1026 newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
1028 return newStream;
1032 static const IStreamVtbl NoStatStreamImpl_Vtbl =
1034 NoStatStreamImpl_QueryInterface,
1035 NoStatStreamImpl_AddRef,
1036 NoStatStreamImpl_Release,
1037 NoStatStreamImpl_Read,
1038 NoStatStreamImpl_Write,
1039 NoStatStreamImpl_Seek,
1040 NoStatStreamImpl_SetSize,
1041 NoStatStreamImpl_CopyTo,
1042 NoStatStreamImpl_Commit,
1043 NoStatStreamImpl_Revert,
1044 NoStatStreamImpl_LockRegion,
1045 NoStatStreamImpl_UnlockRegion,
1046 NoStatStreamImpl_Stat,
1047 NoStatStreamImpl_Clone