[REACTOS]
[reactos.git] / rostests / winetests / oleaut32 / olepicture.c
1 /*
2 * OLEPICTURE test program
3 *
4 * Copyright 2005 Marcus Meissner
5 * Copyright 2012 Dmitry Timoshkov
6 *
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.
11 *
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.
16 *
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
20 */
21
22 #define WIN32_NO_STATUS
23 #define _INC_WINDOWS
24 #define COM_NO_WINDOWS_H
25
26 //#include <stdarg.h>
27 #include <stdio.h>
28 //#include <math.h>
29 //#include <float.h>
30
31 #define COBJMACROS
32 #define CONST_VTABLE
33 #define NONAMELESSUNION
34
35 #include <wine/test.h>
36 //#include <windef.h>
37 //#include <winbase.h>
38 //#include <winuser.h>
39 #include <wingdi.h>
40 #include <winnls.h>
41 //#include <winerror.h>
42 //#include <winnt.h>
43 #include <ole2.h>
44 //#include <urlmon.h>
45 //#include <wtypes.h>
46 #include <olectl.h>
47 //#include <objidl.h>
48
49 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
50
51 #define ole_expect(expr, expect) { \
52 HRESULT r = expr; \
53 ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \
54 }
55
56 #define ole_check(expr) ole_expect(expr, S_OK);
57
58 static HMODULE hOleaut32;
59
60 static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
61 static HRESULT (WINAPI *pOleLoadPictureEx)(LPSTREAM,LONG,BOOL,REFIID,DWORD,DWORD,DWORD,LPVOID*);
62
63 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
64
65 /* 1x1 pixel gif */
66 static const unsigned char gifimage[35] = {
67 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
68 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
69 0x01,0x00,0x3b
70 };
71
72 /* 1x1 pixel jpg */
73 static const unsigned char jpgimage[285] = {
74 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
75 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
76 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
77 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
78 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
79 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
80 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
81 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
82 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
83 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
84 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
85 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
86 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
87 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
88 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
90 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
91 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
92 };
93
94 /* 1x1 pixel png */
95 static const unsigned char pngimage[285] = {
96 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
97 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
98 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
99 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
100 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
101 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
102 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
103 };
104
105 /* 1x1 pixel bmp */
106 static const unsigned char bmpimage[66] = {
107 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
108 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
109 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
110 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
111 0x00,0x00
112 };
113
114 /* 2x2 pixel gif */
115 static const unsigned char gif4pixel[42] = {
116 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
117 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
118 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
119 };
120
121 /* APM with an empty metafile with some padding zeros - looks like under Window the
122 * metafile data should be at least 20 bytes */
123 static const unsigned char apmdata[] = {
124 0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05,
125 0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00,
126 0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
127 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
128 };
129
130 /* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
131 static const unsigned char metafile[] = {
132 0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
135 0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
136 0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
137 0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
138 0x00, 0x00
139 };
140
141 /* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
142 static const unsigned char enhmetafile[] = {
143 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
148 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
149 0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
150 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
153 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
156 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
157 0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
158 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
160 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
162 0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
163 0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
166 0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
167 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
168 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
169 0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
170 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
171 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
173 0x14, 0x00, 0x00, 0x00
174 };
175
176
177 typedef struct NoStatStreamImpl
178 {
179 IStream IStream_iface;
180 LONG ref;
181
182 HGLOBAL supportHandle;
183 ULARGE_INTEGER streamSize;
184 ULARGE_INTEGER currentPosition;
185 } NoStatStreamImpl;
186
187 static IStream* NoStatStream_Construct(HGLOBAL hGlobal);
188
189 static void
190 test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
191 {
192 IPicture* pic = NULL;
193 HRESULT hres;
194 LPVOID pvObj = NULL;
195 OLE_HANDLE handle, hPal;
196 OLE_XSIZE_HIMETRIC width;
197 OLE_YSIZE_HIMETRIC height;
198 short type;
199 DWORD attr;
200 ULONG res;
201
202 pvObj = NULL;
203 hres = pOleLoadPicture(stream, imgsize, TRUE, &IID_IPicture, &pvObj);
204 pic = pvObj;
205
206 ok(hres == S_OK,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres);
207 ok(pic != NULL,"OLP (NULL,..) returns NULL, instead of !NULL\n");
208 if (pic == NULL)
209 return;
210
211 pvObj = NULL;
212 hres = IPicture_QueryInterface (pic, &IID_IPicture, &pvObj);
213
214 ok(hres == S_OK,"IPicture_QI does not return S_OK, but 0x%08x\n", hres);
215 ok(pvObj != NULL,"IPicture_QI does return NULL, instead of a ptr\n");
216
217 IPicture_Release ((IPicture*)pvObj);
218
219 handle = 0;
220 hres = IPicture_get_Handle (pic, &handle);
221 ok(hres == S_OK,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres);
222 ok(handle != 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
223
224 if (handle)
225 {
226 BITMAP bmp;
227 GetObject(UlongToHandle(handle), sizeof(BITMAP), &bmp);
228 todo_wine ok(bmp.bmBits != 0, "not a dib\n");
229 }
230
231 width = 0;
232 hres = IPicture_get_Width (pic, &width);
233 ok(hres == S_OK,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres);
234 ok(width != 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
235
236 height = 0;
237 hres = IPicture_get_Height (pic, &height);
238 ok(hres == S_OK,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres);
239 ok(height != 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
240
241 type = 0;
242 hres = IPicture_get_Type (pic, &type);
243 ok(hres == S_OK,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
244 ok(type == PICTYPE_BITMAP, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type, PICTYPE_BITMAP);
245
246 attr = 0;
247 hres = IPicture_get_Attributes (pic, &attr);
248 ok(hres == S_OK,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres);
249 ok(attr == 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr);
250
251 hPal = 0;
252 hres = IPicture_get_hPal (pic, &hPal);
253 ok(hres == S_OK,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres);
254 /* a single pixel b/w image has no palette */
255 ok(hPal == 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal);
256
257 res = IPicture_Release (pic);
258 ok (res == 0, "refcount after release is %d, but should be 0?\n", res);
259 }
260
261 static void
262 test_pic(const unsigned char *imgdata, unsigned int imgsize)
263 {
264 LPSTREAM stream;
265 HGLOBAL hglob;
266 LPBYTE data;
267 HRESULT hres;
268 LARGE_INTEGER seekto;
269 ULARGE_INTEGER newpos1;
270 DWORD * header;
271 unsigned int i,j;
272
273 /* Let the fun begin */
274 hglob = GlobalAlloc (0, imgsize);
275 data = GlobalLock (hglob);
276 memcpy(data, imgdata, imgsize);
277 GlobalUnlock(hglob); data = NULL;
278
279 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
280 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
281
282 memset(&seekto,0,sizeof(seekto));
283 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
284 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
285 test_pic_with_stream(stream, imgsize);
286
287 IStream_Release(stream);
288
289 /* again with Non Statable and Non Seekable stream */
290 stream = NoStatStream_Construct(hglob);
291 hglob = 0; /* Non-statable impl always deletes on release */
292 test_pic_with_stream(stream, 0);
293
294 IStream_Release(stream);
295 for (i = 1; i <= 8; i++) {
296 /* more fun!!! */
297 hglob = GlobalAlloc (0, imgsize + i * (2 * sizeof(DWORD)));
298 data = GlobalLock (hglob);
299 header = (DWORD *)data;
300
301 /* multiple copies of header */
302 memcpy(data,"lt\0\0",4);
303 header[1] = imgsize;
304 for (j = 2; j <= i; j++) {
305 memcpy(&(header[2 * (j - 1)]), header, 2 * sizeof(DWORD));
306 }
307 memcpy(data + i * (2 * sizeof(DWORD)), imgdata, imgsize);
308 GlobalUnlock(hglob); data = NULL;
309
310 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
311 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
312
313 memset(&seekto,0,sizeof(seekto));
314 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
315 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
316 test_pic_with_stream(stream, imgsize);
317
318 IStream_Release(stream);
319
320 /* again with Non Statable and Non Seekable stream */
321 stream = NoStatStream_Construct(hglob);
322 hglob = 0; /* Non-statable impl always deletes on release */
323 test_pic_with_stream(stream, 0);
324
325 IStream_Release(stream);
326 }
327 }
328
329 static void test_empty_image(void) {
330 LPBYTE data;
331 LPSTREAM stream;
332 IPicture* pic = NULL;
333 HRESULT hres;
334 LPVOID pvObj = NULL;
335 HGLOBAL hglob;
336 OLE_HANDLE handle;
337 ULARGE_INTEGER newpos1;
338 LARGE_INTEGER seekto;
339 short type;
340 DWORD attr;
341
342 /* Empty image. Happens occasionally in VB programs. */
343 hglob = GlobalAlloc (0, 8);
344 data = GlobalLock (hglob);
345 memcpy(data,"lt\0\0",4);
346 ((DWORD*)data)[1] = 0;
347 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
348 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
349
350 memset(&seekto,0,sizeof(seekto));
351 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
352 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
353
354 pvObj = NULL;
355 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
356 pic = pvObj;
357 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
358 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
359
360 hres = IPicture_get_Type (pic, &type);
361 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
362 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
363
364 attr = 0xdeadbeef;
365 hres = IPicture_get_Attributes (pic, &attr);
366 ok (hres == S_OK,"empty picture get attributes failed with hres 0x%08x\n", hres);
367 ok (attr == 0,"attr is %d, but should be 0\n", attr);
368
369 hres = IPicture_get_Handle (pic, &handle);
370 ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres);
371 ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
372 IPicture_Release (pic);
373 IStream_Release (stream);
374 }
375
376 static void test_empty_image_2(void) {
377 LPBYTE data;
378 LPSTREAM stream;
379 IPicture* pic = NULL;
380 HRESULT hres;
381 LPVOID pvObj = NULL;
382 HGLOBAL hglob;
383 ULARGE_INTEGER newpos1;
384 LARGE_INTEGER seekto;
385 short type;
386
387 /* Empty image at random stream position. */
388 hglob = GlobalAlloc (0, 200);
389 data = GlobalLock (hglob);
390 data += 42;
391 memcpy(data,"lt\0\0",4);
392 ((DWORD*)data)[1] = 0;
393 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
394 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
395
396 memset(&seekto,0,sizeof(seekto));
397 seekto.u.LowPart = 42;
398 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
399 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
400
401 pvObj = NULL;
402 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
403 pic = pvObj;
404 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
405 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
406
407 hres = IPicture_get_Type (pic, &type);
408 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
409 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
410
411 IPicture_Release (pic);
412 IStream_Release (stream);
413 }
414
415 static void test_Invoke(void)
416 {
417 IPictureDisp *picdisp;
418 HRESULT hr;
419 VARIANTARG vararg;
420 DISPPARAMS dispparams;
421 VARIANT varresult;
422 IStream *stream;
423 HGLOBAL hglob;
424 void *data;
425
426 hglob = GlobalAlloc (0, sizeof(gifimage));
427 data = GlobalLock(hglob);
428 memcpy(data, gifimage, sizeof(gifimage));
429 GlobalUnlock(hglob);
430
431 hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
432 ok_ole_success(hr, "CreateStreamOnHGlobal");
433
434 hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
435 IStream_Release(stream);
436 GlobalFree(hglob);
437 ok_ole_success(hr, "OleLoadPicture");
438
439 V_VT(&vararg) = VT_BOOL;
440 V_BOOL(&vararg) = VARIANT_FALSE;
441 dispparams.cNamedArgs = 0;
442 dispparams.rgdispidNamedArgs = NULL;
443 dispparams.cArgs = 1;
444 dispparams.rgvarg = &vararg;
445 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
446 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
447 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
448 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
449
450 dispparams.cArgs = 0;
451 dispparams.rgvarg = NULL;
452 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
453 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
454
455 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
456 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
457
458 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
459 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
460
461 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
462 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
463
464 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
465 ok_ole_success(hr, "IPictureDisp_Invoke");
466 ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult));
467
468 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
469 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
470
471 hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
472 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
473
474 dispparams.cArgs = 1;
475 dispparams.rgvarg = &vararg;
476 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
477 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
478
479 dispparams.cArgs = 1;
480 dispparams.rgvarg = &vararg;
481 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
482 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
483
484 IPictureDisp_Release(picdisp);
485 }
486
487 static void test_OleCreatePictureIndirect(void)
488 {
489 OLE_HANDLE handle;
490 IPicture *pict;
491 HRESULT hr;
492 short type;
493
494 if (0)
495 {
496 /* crashes on native */
497 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, NULL);
498 }
499
500 hr = OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (void**)&pict);
501 ok(hr == S_OK, "hr %08x\n", hr);
502
503 type = PICTYPE_NONE;
504 hr = IPicture_get_Type(pict, &type);
505 ok(hr == S_OK, "hr %08x\n", hr);
506 ok(type == PICTYPE_UNINITIALIZED, "type %d\n", type);
507
508 handle = 0xdeadbeef;
509 hr = IPicture_get_Handle(pict, &handle);
510 ok(hr == S_OK, "hr %08x\n", hr);
511 ok(handle == 0, "handle %08x\n", handle);
512
513 IPicture_Release(pict);
514 }
515
516 static void test_apm(void)
517 {
518 OLE_HANDLE handle;
519 LPSTREAM stream;
520 IPicture *pict;
521 HGLOBAL hglob;
522 LPBYTE *data;
523 LONG cxy;
524 BOOL keep;
525 short type;
526
527 if(!winetest_interactive) {
528 skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n");
529 return;
530 }
531
532 hglob = GlobalAlloc (0, sizeof(apmdata));
533 data = GlobalLock(hglob);
534 memcpy(data, apmdata, sizeof(apmdata));
535
536 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
537 ole_check(pOleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict));
538
539 ole_check(IPicture_get_Handle(pict, &handle));
540 ok(handle != 0, "handle is null\n");
541
542 ole_check(IPicture_get_Type(pict, &type));
543 expect_eq(type, PICTYPE_METAFILE, short, "%d");
544
545 ole_check(IPicture_get_Height(pict, &cxy));
546 expect_eq(cxy, 1667, LONG, "%d");
547
548 ole_check(IPicture_get_Width(pict, &cxy));
549 expect_eq(cxy, 1323, LONG, "%d");
550
551 ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
552 todo_wine expect_eq(keep, FALSE, LONG, "%d");
553
554 ole_expect(IPicture_get_hPal(pict, &handle), E_FAIL);
555 IPicture_Release(pict);
556 IStream_Release(stream);
557 }
558
559 static void test_metafile(void)
560 {
561 LPSTREAM stream;
562 IPicture *pict;
563 HGLOBAL hglob;
564 LPBYTE *data;
565
566 hglob = GlobalAlloc (0, sizeof(metafile));
567 data = GlobalLock(hglob);
568 memcpy(data, metafile, sizeof(metafile));
569
570 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
571 /* Windows does not load simple metafiles */
572 ole_expect(pOleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
573
574 IStream_Release(stream);
575 }
576
577 static void test_enhmetafile(void)
578 {
579 OLE_HANDLE handle;
580 LPSTREAM stream;
581 IPicture *pict;
582 HGLOBAL hglob;
583 LPBYTE *data;
584 LONG cxy;
585 BOOL keep;
586 short type;
587
588 if(!winetest_interactive) {
589 skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n");
590 return;
591 }
592
593 hglob = GlobalAlloc (0, sizeof(enhmetafile));
594 data = GlobalLock(hglob);
595 memcpy(data, enhmetafile, sizeof(enhmetafile));
596
597 ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
598 ole_check(pOleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
599
600 ole_check(IPicture_get_Handle(pict, &handle));
601 ok(handle != 0, "handle is null\n");
602
603 ole_check(IPicture_get_Type(pict, &type));
604 expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
605
606 ole_check(IPicture_get_Height(pict, &cxy));
607 expect_eq(cxy, -23, LONG, "%d");
608
609 ole_check(IPicture_get_Width(pict, &cxy));
610 expect_eq(cxy, -25, LONG, "%d");
611
612 ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
613 todo_wine expect_eq(keep, FALSE, LONG, "%d");
614
615 IPicture_Release(pict);
616 IStream_Release(stream);
617 }
618
619 static void test_Render(void)
620 {
621 IPicture *pic;
622 HRESULT hres;
623 short type;
624 PICTDESC desc;
625 OLE_XSIZE_HIMETRIC pWidth;
626 OLE_YSIZE_HIMETRIC pHeight;
627 COLORREF result, expected;
628 HDC hdc = GetDC(0);
629
630 /* test IPicture::Render return code on uninitialized picture */
631 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
632 hres = IPicture_get_Type(pic, &type);
633 ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
634 ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
635 /* zero dimensions */
636 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
637 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
638 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
639 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
640 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
641 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
642 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
643 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
644 hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
645 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
646 hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
647 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
648 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
649 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
650 /* nonzero dimensions, PICTYPE_UNINITIALIZED */
651 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL);
652 ole_expect(hres, S_OK);
653 IPicture_Release(pic);
654
655 desc.cbSizeofstruct = sizeof(PICTDESC);
656 desc.picType = PICTYPE_ICON;
657 desc.u.icon.hicon = LoadIcon(NULL, IDI_APPLICATION);
658 if(!desc.u.icon.hicon){
659 win_skip("LoadIcon failed. Skipping...\n");
660 ReleaseDC(NULL, hdc);
661 return;
662 }
663
664 OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic);
665 /* zero dimensions, PICTYPE_ICON */
666 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
667 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
668 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
669 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
670 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
671 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
672 hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
673 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
674 hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
675 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
676 hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
677 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
678 hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
679 ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
680
681 /* Check if target size and position is respected */
682 IPicture_get_Width(pic, &pWidth);
683 IPicture_get_Height(pic, &pHeight);
684
685 SetPixelV(hdc, 0, 0, 0x00223344);
686 SetPixelV(hdc, 5, 5, 0x00223344);
687 SetPixelV(hdc, 10, 10, 0x00223344);
688 expected = GetPixel(hdc, 0, 0);
689
690 hres = IPicture_Render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL);
691 ole_expect(hres, S_OK);
692
693 if(hres != S_OK) {
694 IPicture_Release(pic);
695 ReleaseDC(NULL, hdc);
696 return;
697 }
698
699 /* Evaluate the rendered Icon */
700 result = GetPixel(hdc, 0, 0);
701 ok(result == expected,
702 "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
703 result = GetPixel(hdc, 5, 5);
704 ok(result != expected ||
705 broken(result == expected), /* WinNT 4.0 and older may claim they drew */
706 /* the icon, even if they didn't. */
707 "Color at 5,5 should have changed, but still was 0x%06X\n", expected);
708 result = GetPixel(hdc, 10, 10);
709 ok(result == expected,
710 "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
711
712 IPicture_Release(pic);
713 ReleaseDC(NULL, hdc);
714 }
715
716 static void test_get_Attributes(void)
717 {
718 IPicture *pic;
719 HRESULT hres;
720 short type;
721 DWORD attr;
722
723 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
724 hres = IPicture_get_Type(pic, &type);
725 ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
726 ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
727
728 hres = IPicture_get_Attributes(pic, NULL);
729 ole_expect(hres, E_POINTER);
730
731 attr = 0xdeadbeef;
732 hres = IPicture_get_Attributes(pic, &attr);
733 ole_expect(hres, S_OK);
734 ok(attr == 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr);
735
736 IPicture_Release(pic);
737 }
738
739 static void test_get_Handle(void)
740 {
741 IPicture *pic;
742 HRESULT hres;
743
744 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
745
746 hres = IPicture_get_Handle(pic, NULL);
747 ole_expect(hres, E_POINTER);
748
749 IPicture_Release(pic);
750 }
751
752 static void test_get_Type(void)
753 {
754 IPicture *pic;
755 HRESULT hres;
756
757 OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
758
759 hres = IPicture_get_Type(pic, NULL);
760 ole_expect(hres, E_POINTER);
761
762 IPicture_Release(pic);
763 }
764
765 static void test_OleLoadPicturePath(void)
766 {
767 static WCHAR emptyW[] = {0};
768
769 IPicture *pic;
770 HRESULT hres;
771 int i;
772 char temp_path[MAX_PATH];
773 char temp_file[MAX_PATH];
774 WCHAR temp_fileW[MAX_PATH + 5] = {'f','i','l','e',':','/','/','/'};
775 HANDLE file;
776 DWORD size;
777 WCHAR *ptr;
778
779 const struct
780 {
781 LPOLESTR szURLorPath;
782 REFIID riid;
783 IPicture **pic;
784 } invalid_parameters[] =
785 {
786 {NULL, NULL, NULL},
787 {NULL, NULL, &pic},
788 {NULL, &IID_IPicture, NULL},
789 {NULL, &IID_IPicture, &pic},
790 {emptyW, NULL, NULL},
791 {emptyW, &IID_IPicture, NULL},
792 };
793
794 for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
795 {
796 pic = (IPicture *)0xdeadbeef;
797 hres = OleLoadPicturePath(invalid_parameters[i].szURLorPath, NULL, 0, 0,
798 invalid_parameters[i].riid,
799 (void **)invalid_parameters[i].pic);
800 ok(hres == E_INVALIDARG,
801 "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i, hres);
802 ok(pic == (IPicture *)0xdeadbeef,
803 "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i, pic);
804 }
805
806 pic = (IPicture *)0xdeadbeef;
807 hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic);
808 todo_wine
809 ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
810 broken(hres == E_UNEXPECTED) || /* NT4 */
811 broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */
812 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
813 ok(pic == NULL,
814 "Expected the output interface pointer to be NULL, got %p\n", pic);
815
816 pic = (IPicture *)0xdeadbeef;
817 hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
818 todo_wine
819 ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
820 broken(hres == E_UNEXPECTED) || /* NT4 */
821 broken(hres == E_OUTOFMEMORY), /* Win2k/Win2k3 */
822 "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
823 ok(pic == NULL,
824 "Expected the output interface pointer to be NULL, got %p\n", pic);
825
826 /* Create a local temporary image file for testing. */
827 GetTempPathA(sizeof(temp_path), temp_path);
828 GetTempFileNameA(temp_path, "bmp", 0, temp_file);
829 file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
830 FILE_ATTRIBUTE_NORMAL, NULL);
831 WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
832 CloseHandle(file);
833
834 MultiByteToWideChar(CP_ACP, 0, temp_file, -1, temp_fileW + 8, sizeof(temp_fileW)/sizeof(WCHAR) - 8);
835
836 /* Try a normal DOS path. */
837 hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
838 ok(hres == S_OK ||
839 broken(hres == E_UNEXPECTED), /* NT4 */
840 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
841 if (pic)
842 IPicture_Release(pic);
843
844 /* Try a DOS path with tacked on "file:". */
845 hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
846 ok(hres == S_OK ||
847 broken(hres == E_UNEXPECTED), /* NT4 */
848 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
849 if (pic)
850 IPicture_Release(pic);
851
852 DeleteFileA(temp_file);
853
854 /* Try with a nonexistent file. */
855 hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
856 ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
857 broken(hres == E_UNEXPECTED) || /* NT4 */
858 broken(hres == E_FAIL), /*Win2k */
859 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
860
861 hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
862 ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
863 broken(hres == E_UNEXPECTED) || /* NT4 */
864 broken(hres == E_FAIL), /* Win2k */
865 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
866
867 file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
868 FILE_ATTRIBUTE_NORMAL, NULL);
869 WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
870 CloseHandle(file);
871
872 /* Try a "file:" URL with slash separators. */
873 ptr = temp_fileW + 8;
874 while (*ptr)
875 {
876 if (*ptr == '\\')
877 *ptr = '/';
878 ptr++;
879 }
880
881 hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
882 ok(hres == S_OK ||
883 broken(hres == E_UNEXPECTED), /* NT4 */
884 "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
885 if (pic)
886 IPicture_Release(pic);
887
888 DeleteFileA(temp_file);
889
890 /* Try with a nonexistent file. */
891 hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
892 ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
893 broken(hres == E_UNEXPECTED) || /* NT4 */
894 broken(hres == E_FAIL), /* Win2k */
895 "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
896 }
897
898 static void test_himetric(void)
899 {
900 static const BYTE bmp_bits[1024];
901 OLE_XSIZE_HIMETRIC cx;
902 OLE_YSIZE_HIMETRIC cy;
903 IPicture *pic;
904 PICTDESC desc;
905 HBITMAP bmp;
906 HRESULT hr;
907 HICON icon;
908 HDC hdc;
909 INT d;
910
911 desc.cbSizeofstruct = sizeof(desc);
912 desc.picType = PICTYPE_BITMAP;
913 desc.u.bmp.hpal = NULL;
914
915 hdc = CreateCompatibleDC(0);
916
917 bmp = CreateBitmap(1.9 * GetDeviceCaps(hdc, LOGPIXELSX),
918 1.9 * GetDeviceCaps(hdc, LOGPIXELSY), 1, 1, NULL);
919
920 desc.u.bmp.hbitmap = bmp;
921
922 /* size in himetric units reported rounded up to next integer value */
923 hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
924 ok(hr == S_OK, "got 0x%08x\n", hr);
925
926 cx = 0;
927 d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSX)), 2540, GetDeviceCaps(hdc, LOGPIXELSX));
928 hr = IPicture_get_Width(pic, &cx);
929 ok(hr == S_OK, "got 0x%08x\n", hr);
930 ok(cx == d, "got %d, expected %d\n", cx, d);
931
932 cy = 0;
933 d = MulDiv((INT)(1.9 * GetDeviceCaps(hdc, LOGPIXELSY)), 2540, GetDeviceCaps(hdc, LOGPIXELSY));
934 hr = IPicture_get_Height(pic, &cy);
935 ok(hr == S_OK, "got 0x%08x\n", hr);
936 ok(cy == d, "got %d, expected %d\n", cy, d);
937
938 DeleteObject(bmp);
939 IPicture_Release(pic);
940
941 /* same thing with icon */
942 icon = CreateIcon(NULL, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
943 1, 1, bmp_bits, bmp_bits);
944 ok(icon != NULL, "failed to create icon\n");
945
946 desc.picType = PICTYPE_ICON;
947 desc.u.icon.hicon = icon;
948
949 hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
950 ok(hr == S_OK, "got 0x%08x\n", hr);
951
952 cx = 0;
953 d = MulDiv(GetSystemMetrics(SM_CXICON), 2540, GetDeviceCaps(hdc, LOGPIXELSX));
954 hr = IPicture_get_Width(pic, &cx);
955 ok(hr == S_OK, "got 0x%08x\n", hr);
956 ok(cx == d, "got %d, expected %d\n", cx, d);
957
958 cy = 0;
959 d = MulDiv(GetSystemMetrics(SM_CYICON), 2540, GetDeviceCaps(hdc, LOGPIXELSY));
960 hr = IPicture_get_Height(pic, &cy);
961 ok(hr == S_OK, "got 0x%08x\n", hr);
962 ok(cy == d, "got %d, expected %d\n", cy, d);
963
964 IPicture_Release(pic);
965 DestroyIcon(icon);
966
967 DeleteDC(hdc);
968 }
969
970 static void test_load_save_bmp(void)
971 {
972 IPicture *pic;
973 PICTDESC desc;
974 short type;
975 OLE_HANDLE handle;
976 HGLOBAL hmem;
977 DWORD *mem;
978 IPersistStream *src_stream;
979 IStream *dst_stream;
980 HRESULT hr;
981
982 desc.cbSizeofstruct = sizeof(desc);
983 desc.picType = PICTYPE_BITMAP;
984 desc.u.bmp.hpal = 0;
985 desc.u.bmp.hbitmap = CreateBitmap(1, 1, 1, 1, NULL);
986 hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
987 ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
988
989 type = -1;
990 hr = IPicture_get_Type(pic, &type);
991 ok(hr == S_OK,"get_Type error %#8x\n", hr);
992 ok(type == PICTYPE_BITMAP,"expected picture type PICTYPE_BITMAP, got %d\n", type);
993
994 hr = IPicture_get_Handle(pic, &handle);
995 ok(hr == S_OK,"get_Handle error %#8x\n", hr);
996 ok(IntToPtr(handle) == desc.u.bmp.hbitmap, "get_Handle returned wrong handle %#x\n", handle);
997
998 hmem = GlobalAlloc(GMEM_ZEROINIT, 4096);
999 hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
1000 ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
1001
1002 hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
1003 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1004
1005 hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
1006 ok(hr == S_OK, "Save error %#x\n", hr);
1007
1008 IPersistStream_Release(src_stream);
1009 IStream_Release(dst_stream);
1010
1011 mem = GlobalLock(hmem);
1012 ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
1013 ok(mem[1] == 66, "expected stream size 66, got %u\n", mem[1]);
1014 ok(!memcmp(&mem[2], "BM", 2), "got wrong bmp header %04x\n", mem[2]);
1015
1016 GlobalUnlock(hmem);
1017 GlobalFree(hmem);
1018
1019 DeleteObject(desc.u.bmp.hbitmap);
1020 IPicture_Release(pic);
1021 }
1022
1023 static void test_load_save_icon(void)
1024 {
1025 IPicture *pic;
1026 PICTDESC desc;
1027 short type;
1028 OLE_HANDLE handle;
1029 HGLOBAL hmem;
1030 DWORD *mem;
1031 IPersistStream *src_stream;
1032 IStream *dst_stream;
1033 HRESULT hr;
1034
1035 desc.cbSizeofstruct = sizeof(desc);
1036 desc.picType = PICTYPE_ICON;
1037 desc.u.icon.hicon = LoadIcon(0, IDI_APPLICATION);
1038 hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
1039 ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
1040
1041 type = -1;
1042 hr = IPicture_get_Type(pic, &type);
1043 ok(hr == S_OK,"get_Type error %#8x\n", hr);
1044 ok(type == PICTYPE_ICON,"expected picture type PICTYPE_ICON, got %d\n", type);
1045
1046 hr = IPicture_get_Handle(pic, &handle);
1047 ok(hr == S_OK,"get_Handle error %#8x\n", hr);
1048 ok(IntToPtr(handle) == desc.u.icon.hicon, "get_Handle returned wrong handle %#x\n", handle);
1049
1050 hmem = GlobalAlloc(GMEM_ZEROINIT, 8192);
1051 hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
1052 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
1053
1054 hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
1055 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1056
1057 hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
1058 ok(hr == S_OK, "Saveerror %#x\n", hr);
1059
1060 IPersistStream_Release(src_stream);
1061 IStream_Release(dst_stream);
1062
1063 mem = GlobalLock(hmem);
1064 ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
1065 todo_wine
1066 ok(mem[1] == 766, "expected stream size 766, got %u\n", mem[1]);
1067 ok(mem[2] == 0x00010000, "got wrong icon header %04x\n", mem[2]);
1068
1069 GlobalUnlock(hmem);
1070 GlobalFree(hmem);
1071
1072 DestroyIcon(desc.u.icon.hicon);
1073 IPicture_Release(pic);
1074 }
1075
1076 static void test_load_save_empty_picture(void)
1077 {
1078 IPicture *pic;
1079 PICTDESC desc;
1080 short type;
1081 OLE_HANDLE handle;
1082 HGLOBAL hmem;
1083 DWORD *mem;
1084 IPersistStream *src_stream;
1085 IStream *dst_stream;
1086 HRESULT hr;
1087
1088 memset(&pic, 0, sizeof(pic));
1089 desc.cbSizeofstruct = sizeof(desc);
1090 desc.picType = PICTYPE_NONE;
1091 hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void **)&pic);
1092 ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
1093
1094 type = -1;
1095 hr = IPicture_get_Type(pic, &type);
1096 ok(hr == S_OK,"get_Type error %#8x\n", hr);
1097 ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
1098
1099 handle = (OLE_HANDLE)0xdeadbeef;
1100 hr = IPicture_get_Handle(pic, &handle);
1101 ok(hr == S_OK,"get_Handle error %#8x\n", hr);
1102 ok(!handle, "get_Handle returned wrong handle %#x\n", handle);
1103
1104 hmem = GlobalAlloc(GMEM_ZEROINIT, 4096);
1105 hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
1106 ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
1107
1108 hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
1109 ok(hr == S_OK, "QueryInterface error %#x\n", hr);
1110
1111 hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
1112 ok(hr == S_OK, "Save error %#x\n", hr);
1113
1114 mem = GlobalLock(hmem);
1115 ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
1116 ok(mem[1] == 0, "expected stream size 0, got %u\n", mem[1]);
1117 GlobalUnlock(hmem);
1118
1119 IPersistStream_Release(src_stream);
1120 IStream_Release(dst_stream);
1121
1122 GlobalFree(hmem);
1123 IPicture_Release(pic);
1124 }
1125
1126 START_TEST(olepicture)
1127 {
1128 hOleaut32 = GetModuleHandleA("oleaut32.dll");
1129 pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
1130 pOleLoadPictureEx = (void*)GetProcAddress(hOleaut32, "OleLoadPictureEx");
1131 if (!pOleLoadPicture)
1132 {
1133 win_skip("OleLoadPicture is not available\n");
1134 return;
1135 }
1136
1137 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
1138 test_pic(gifimage, sizeof(gifimage));
1139 test_pic(jpgimage, sizeof(jpgimage));
1140 test_pic(bmpimage, sizeof(bmpimage));
1141 test_pic(gif4pixel, sizeof(gif4pixel));
1142 /* FIXME: No PNG support in Windows... */
1143 if (0) test_pic(pngimage, sizeof(pngimage));
1144 test_empty_image();
1145 test_empty_image_2();
1146 if (pOleLoadPictureEx)
1147 {
1148 test_apm();
1149 test_metafile();
1150 test_enhmetafile();
1151 }
1152 else
1153 win_skip("OleLoadPictureEx is not available\n");
1154 test_Invoke();
1155 test_OleCreatePictureIndirect();
1156 test_Render();
1157 test_get_Attributes();
1158 test_get_Handle();
1159 test_get_Type();
1160 test_OleLoadPicturePath();
1161 test_himetric();
1162 test_load_save_bmp();
1163 test_load_save_icon();
1164 test_load_save_empty_picture();
1165 }
1166
1167
1168 /* Helper functions only ... */
1169
1170
1171 static inline NoStatStreamImpl *impl_from_IStream(IStream *iface)
1172 {
1173 return CONTAINING_RECORD(iface, NoStatStreamImpl, IStream_iface);
1174 }
1175
1176 static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
1177 {
1178 GlobalFree(This->supportHandle);
1179 This->supportHandle=0;
1180 HeapFree(GetProcessHeap(), 0, This);
1181 }
1182
1183 static ULONG WINAPI NoStatStreamImpl_AddRef(
1184 IStream* iface)
1185 {
1186 NoStatStreamImpl* const This = impl_from_IStream(iface);
1187 return InterlockedIncrement(&This->ref);
1188 }
1189
1190 static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
1191 IStream* iface,
1192 REFIID riid, /* [in] */
1193 void** ppvObject) /* [iid_is][out] */
1194 {
1195 NoStatStreamImpl* const This = impl_from_IStream(iface);
1196 if (ppvObject==0) return E_INVALIDARG;
1197 *ppvObject = 0;
1198 if (IsEqualIID(&IID_IUnknown, riid))
1199 {
1200 *ppvObject = This;
1201 }
1202 else if (IsEqualIID(&IID_IStream, riid))
1203 {
1204 *ppvObject = This;
1205 }
1206
1207 if ((*ppvObject)==0)
1208 return E_NOINTERFACE;
1209 NoStatStreamImpl_AddRef(iface);
1210 return S_OK;
1211 }
1212
1213 static ULONG WINAPI NoStatStreamImpl_Release(
1214 IStream* iface)
1215 {
1216 NoStatStreamImpl* const This = impl_from_IStream(iface);
1217 ULONG newRef = InterlockedDecrement(&This->ref);
1218 if (newRef==0)
1219 NoStatStreamImpl_Destroy(This);
1220 return newRef;
1221 }
1222
1223 static HRESULT WINAPI NoStatStreamImpl_Read(
1224 IStream* iface,
1225 void* pv, /* [length_is][size_is][out] */
1226 ULONG cb, /* [in] */
1227 ULONG* pcbRead) /* [out] */
1228 {
1229 NoStatStreamImpl* const This = impl_from_IStream(iface);
1230 void* supportBuffer;
1231 ULONG bytesReadBuffer;
1232 ULONG bytesToReadFromBuffer;
1233
1234 if (pcbRead==0)
1235 pcbRead = &bytesReadBuffer;
1236 bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
1237 supportBuffer = GlobalLock(This->supportHandle);
1238 memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
1239 This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
1240 *pcbRead = bytesToReadFromBuffer;
1241 GlobalUnlock(This->supportHandle);
1242 if(*pcbRead == cb)
1243 return S_OK;
1244 return S_FALSE;
1245 }
1246
1247 static HRESULT WINAPI NoStatStreamImpl_Write(
1248 IStream* iface,
1249 const void* pv, /* [size_is][in] */
1250 ULONG cb, /* [in] */
1251 ULONG* pcbWritten) /* [out] */
1252 {
1253 NoStatStreamImpl* const This = impl_from_IStream(iface);
1254 void* supportBuffer;
1255 ULARGE_INTEGER newSize;
1256 ULONG bytesWritten = 0;
1257
1258 if (pcbWritten == 0)
1259 pcbWritten = &bytesWritten;
1260 if (cb == 0)
1261 return S_OK;
1262 newSize.u.HighPart = 0;
1263 newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
1264 if (newSize.u.LowPart > This->streamSize.u.LowPart)
1265 IStream_SetSize(iface, newSize);
1266
1267 supportBuffer = GlobalLock(This->supportHandle);
1268 memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
1269 This->currentPosition.u.LowPart+=cb;
1270 *pcbWritten = cb;
1271 GlobalUnlock(This->supportHandle);
1272 return S_OK;
1273 }
1274
1275 static HRESULT WINAPI NoStatStreamImpl_Seek(
1276 IStream* iface,
1277 LARGE_INTEGER dlibMove, /* [in] */
1278 DWORD dwOrigin, /* [in] */
1279 ULARGE_INTEGER* plibNewPosition) /* [out] */
1280 {
1281 NoStatStreamImpl* const This = impl_from_IStream(iface);
1282 ULARGE_INTEGER newPosition;
1283 switch (dwOrigin)
1284 {
1285 case STREAM_SEEK_SET:
1286 newPosition.u.HighPart = 0;
1287 newPosition.u.LowPart = 0;
1288 break;
1289 case STREAM_SEEK_CUR:
1290 newPosition = This->currentPosition;
1291 break;
1292 case STREAM_SEEK_END:
1293 newPosition = This->streamSize;
1294 break;
1295 default:
1296 return STG_E_INVALIDFUNCTION;
1297 }
1298 if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart)
1299 return STG_E_INVALIDFUNCTION;
1300 newPosition.QuadPart += dlibMove.QuadPart;
1301 if (plibNewPosition) *plibNewPosition = newPosition;
1302 This->currentPosition = newPosition;
1303 return S_OK;
1304 }
1305
1306 static HRESULT WINAPI NoStatStreamImpl_SetSize(
1307 IStream* iface,
1308 ULARGE_INTEGER libNewSize) /* [in] */
1309 {
1310 NoStatStreamImpl* const This = impl_from_IStream(iface);
1311 HGLOBAL supportHandle;
1312 if (libNewSize.u.HighPart != 0)
1313 return STG_E_INVALIDFUNCTION;
1314 if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
1315 return S_OK;
1316 supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
1317 if (supportHandle == 0)
1318 return STG_E_MEDIUMFULL;
1319 This->supportHandle = supportHandle;
1320 This->streamSize.u.LowPart = libNewSize.u.LowPart;
1321 return S_OK;
1322 }
1323
1324 static HRESULT WINAPI NoStatStreamImpl_CopyTo(
1325 IStream* iface,
1326 IStream* pstm, /* [unique][in] */
1327 ULARGE_INTEGER cb, /* [in] */
1328 ULARGE_INTEGER* pcbRead, /* [out] */
1329 ULARGE_INTEGER* pcbWritten) /* [out] */
1330 {
1331 HRESULT hr = S_OK;
1332 BYTE tmpBuffer[128];
1333 ULONG bytesRead, bytesWritten, copySize;
1334 ULARGE_INTEGER totalBytesRead;
1335 ULARGE_INTEGER totalBytesWritten;
1336
1337 if ( pstm == 0 )
1338 return STG_E_INVALIDPOINTER;
1339 totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
1340 totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
1341
1342 while ( cb.u.LowPart > 0 )
1343 {
1344 if ( cb.u.LowPart >= 128 )
1345 copySize = 128;
1346 else
1347 copySize = cb.u.LowPart;
1348 IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
1349 totalBytesRead.u.LowPart += bytesRead;
1350 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
1351 totalBytesWritten.u.LowPart += bytesWritten;
1352 if (bytesRead != bytesWritten)
1353 {
1354 hr = STG_E_MEDIUMFULL;
1355 break;
1356 }
1357 if (bytesRead!=copySize)
1358 cb.u.LowPart = 0;
1359 else
1360 cb.u.LowPart -= bytesRead;
1361 }
1362 if (pcbRead)
1363 {
1364 pcbRead->u.LowPart = totalBytesRead.u.LowPart;
1365 pcbRead->u.HighPart = totalBytesRead.u.HighPart;
1366 }
1367
1368 if (pcbWritten)
1369 {
1370 pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
1371 pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
1372 }
1373 return hr;
1374 }
1375
1376 static HRESULT WINAPI NoStatStreamImpl_Commit(IStream* iface,DWORD grfCommitFlags)
1377 {
1378 return S_OK;
1379 }
1380 static HRESULT WINAPI NoStatStreamImpl_Revert(IStream* iface) { return S_OK; }
1381
1382 static HRESULT WINAPI NoStatStreamImpl_LockRegion(
1383 IStream* iface,
1384 ULARGE_INTEGER libOffset, /* [in] */
1385 ULARGE_INTEGER cb, /* [in] */
1386 DWORD dwLockType) /* [in] */
1387 {
1388 return S_OK;
1389 }
1390
1391 static HRESULT WINAPI NoStatStreamImpl_UnlockRegion(
1392 IStream* iface,
1393 ULARGE_INTEGER libOffset, /* [in] */
1394 ULARGE_INTEGER cb, /* [in] */
1395 DWORD dwLockType) /* [in] */
1396 {
1397 return S_OK;
1398 }
1399
1400 static HRESULT WINAPI NoStatStreamImpl_Stat(
1401 IStream* iface,
1402 STATSTG* pstatstg, /* [out] */
1403 DWORD grfStatFlag) /* [in] */
1404 {
1405 return E_NOTIMPL;
1406 }
1407
1408 static HRESULT WINAPI NoStatStreamImpl_Clone(
1409 IStream* iface,
1410 IStream** ppstm) /* [out] */
1411 {
1412 return E_NOTIMPL;
1413 }
1414 static const IStreamVtbl NoStatStreamImpl_Vtbl;
1415
1416 /*
1417 Build an object that implements IStream, without IStream_Stat capabilities.
1418 Receives a memory handle with data buffer. If memory handle is non-null,
1419 it is assumed to be unlocked, otherwise an internal memory handle is allocated.
1420 In any case the object takes ownership of memory handle and will free it on
1421 object release.
1422 */
1423 static IStream* NoStatStream_Construct(HGLOBAL hGlobal)
1424 {
1425 NoStatStreamImpl* newStream;
1426
1427 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
1428 if (newStream!=0)
1429 {
1430 newStream->IStream_iface.lpVtbl = &NoStatStreamImpl_Vtbl;
1431 newStream->ref = 1;
1432 newStream->supportHandle = hGlobal;
1433
1434 if (!newStream->supportHandle)
1435 newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
1436 GMEM_SHARE, 0);
1437 newStream->currentPosition.u.HighPart = 0;
1438 newStream->currentPosition.u.LowPart = 0;
1439 newStream->streamSize.u.HighPart = 0;
1440 newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
1441 }
1442 return &newStream->IStream_iface;
1443 }
1444
1445
1446 static const IStreamVtbl NoStatStreamImpl_Vtbl =
1447 {
1448 NoStatStreamImpl_QueryInterface,
1449 NoStatStreamImpl_AddRef,
1450 NoStatStreamImpl_Release,
1451 NoStatStreamImpl_Read,
1452 NoStatStreamImpl_Write,
1453 NoStatStreamImpl_Seek,
1454 NoStatStreamImpl_SetSize,
1455 NoStatStreamImpl_CopyTo,
1456 NoStatStreamImpl_Commit,
1457 NoStatStreamImpl_Revert,
1458 NoStatStreamImpl_LockRegion,
1459 NoStatStreamImpl_UnlockRegion,
1460 NoStatStreamImpl_Stat,
1461 NoStatStreamImpl_Clone
1462 };