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
30 #include <wine/test.h>
43 static HMODULE hOleaut32;
45 static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
47 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
50 static const unsigned char gifimage[35] = {
51 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
52 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
57 static const unsigned char jpgimage[285] = {
58 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
59 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
60 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
61 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
62 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
63 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
64 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
65 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
66 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
67 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
68 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
69 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
70 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
71 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
72 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
73 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
74 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
75 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
78 #if 0 /* no png support yet */
80 static const unsigned char pngimage[285] = {
81 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
82 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
83 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
84 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
85 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
86 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
87 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
92 static const unsigned char bmpimage[66] = {
93 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
94 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
95 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
96 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
101 static const unsigned char gif4pixel[42] = {
102 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
103 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
104 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
107 struct NoStatStreamImpl
109 const IStreamVtbl *lpVtbl;
112 HGLOBAL supportHandle;
113 ULARGE_INTEGER streamSize;
114 ULARGE_INTEGER currentPosition;
116 typedef struct NoStatStreamImpl NoStatStreamImpl;
117 static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal);
120 test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
122 IPicture* pic = NULL;
125 OLE_HANDLE handle, hPal;
126 OLE_XSIZE_HIMETRIC width;
127 OLE_YSIZE_HIMETRIC height;
133 hres = pOleLoadPicture(stream, imgsize, TRUE, &IID_IPicture, &pvObj);
136 ok(hres == S_OK,"OLP (NULL,..) does not return 0, but 0x%08x\n",hres);
137 ok(pic != NULL,"OLP (NULL,..) returns NULL, instead of !NULL\n");
142 hres = IPicture_QueryInterface (pic, &IID_IPicture, &pvObj);
144 ok(hres == S_OK,"IPicture_QI does not return S_OK, but 0x%08x\n", hres);
145 ok(pvObj != NULL,"IPicture_QI does return NULL, instead of a ptr\n");
147 IPicture_Release ((IPicture*)pvObj);
150 hres = IPicture_get_Handle (pic, &handle);
151 ok(hres == S_OK,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres);
152 ok(handle != 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
155 hres = IPicture_get_Width (pic, &width);
156 ok(hres == S_OK,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres);
157 ok(width != 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
160 hres = IPicture_get_Height (pic, &height);
161 ok(hres == S_OK,"IPicture_get_Height does not return S_OK, but 0x%08x\n", hres);
162 ok(height != 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
165 hres = IPicture_get_Type (pic, &type);
166 ok(hres == S_OK,"IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
167 ok(type == PICTYPE_BITMAP, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type, PICTYPE_BITMAP);
170 hres = IPicture_get_Attributes (pic, &attr);
171 ok(hres == S_OK,"IPicture_get_Attributes does not return S_OK, but 0x%08x\n", hres);
172 ok(attr == 0, "IPicture_get_Attributes returns %d, but it should be 0.\n", attr);
175 hres = IPicture_get_hPal (pic, &hPal);
176 ok(hres == S_OK,"IPicture_get_hPal does not return S_OK, but 0x%08x\n", hres);
177 /* a single pixel b/w image has no palette */
178 ok(hPal == 0, "IPicture_get_hPal returns %d, but it should be 0.\n", hPal);
180 res = IPicture_Release (pic);
181 ok (res == 0, "refcount after release is %d, but should be 0?\n", res);
185 test_pic(const unsigned char *imgdata, unsigned int imgsize)
191 LARGE_INTEGER seekto;
192 ULARGE_INTEGER newpos1;
196 /* Let the fun begin */
197 hglob = GlobalAlloc (0, imgsize);
198 data = GlobalLock (hglob);
199 memcpy(data, imgdata, imgsize);
201 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
202 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
204 memset(&seekto,0,sizeof(seekto));
205 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
206 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
207 test_pic_with_stream(stream, imgsize);
209 IStream_Release(stream);
211 /* again with Non Statable and Non Seekable stream */
212 stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
213 test_pic_with_stream(stream, 0);
215 IStream_Release(stream);
222 hglob = GlobalAlloc (0, imgsize + 8 * (2 * sizeof(DWORD)));
223 data = GlobalLock (hglob);
224 header = (DWORD *)data;
226 /* multiple copies of header */
227 memcpy(data,"lt\0\0",4);
229 memcpy(&(header[2]), header, 2 * sizeof(DWORD));
230 memcpy(&(header[4]), header, 4 * sizeof(DWORD));
231 memcpy(&(header[8]), header, 8 * sizeof(DWORD));
233 memcpy(data + 8 * (2 * sizeof(DWORD)), imgdata, imgsize);
235 for (i = 1; i <= 8; i++) {
236 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
237 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
239 memset(&seekto,0,sizeof(seekto));
240 seekto.u.LowPart = (8 - i) * (2 * sizeof(DWORD));
241 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
242 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
243 test_pic_with_stream(stream, imgsize);
245 IStream_Release(stream);
247 /* again with Non Statable and Non Seekable stream */
248 stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
249 test_pic_with_stream(stream, 0);
251 IStream_Release(stream);
259 static void test_empty_image(void) {
262 IPicture* pic = NULL;
267 ULARGE_INTEGER newpos1;
268 LARGE_INTEGER seekto;
271 /* Empty image. Happens occasionally in VB programs. */
272 hglob = GlobalAlloc (0, 8);
273 data = GlobalLock (hglob);
274 memcpy(data,"lt\0\0",4);
275 ((DWORD*)data)[1] = 0;
276 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
277 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
279 memset(&seekto,0,sizeof(seekto));
280 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
281 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
284 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
286 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
287 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
289 hres = IPicture_get_Type (pic, &type);
290 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
291 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
293 hres = IPicture_get_Handle (pic, &handle);
294 ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres);
295 ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
296 IPicture_Release (pic);
299 static void test_empty_image_2(void) {
302 IPicture* pic = NULL;
306 ULARGE_INTEGER newpos1;
307 LARGE_INTEGER seekto;
310 /* Empty image at random stream position. */
311 hglob = GlobalAlloc (0, 200);
312 data = GlobalLock (hglob);
314 memcpy(data,"lt\0\0",4);
315 ((DWORD*)data)[1] = 0;
316 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
317 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
319 memset(&seekto,0,sizeof(seekto));
320 seekto.u.LowPart = 42;
321 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
322 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
325 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
327 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
328 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
330 hres = IPicture_get_Type (pic, &type);
331 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
332 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
334 IPicture_Release (pic);
337 static void test_Invoke(void)
339 IPictureDisp *picdisp;
342 DISPPARAMS dispparams;
348 hglob = GlobalAlloc (0, sizeof(gifimage));
349 data = GlobalLock(hglob);
350 memcpy(data, gifimage, sizeof(gifimage));
353 hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
354 ok_ole_success(hr, "CreateStreamOnHGlobal");
356 hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
357 IStream_Release(stream);
358 ok_ole_success(hr, "OleLoadPicture");
360 V_VT(&vararg) = VT_BOOL;
361 V_BOOL(&vararg) = VARIANT_FALSE;
362 dispparams.cNamedArgs = 0;
363 dispparams.rgdispidNamedArgs = NULL;
364 dispparams.cArgs = 1;
365 dispparams.rgvarg = &vararg;
366 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
367 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
368 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
369 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
371 dispparams.cArgs = 0;
372 dispparams.rgvarg = NULL;
373 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
374 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
376 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
377 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
379 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
380 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
382 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
383 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
385 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
386 ok_ole_success(hr, "IPictureDisp_Invoke");
387 ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult));
389 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
390 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
392 hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
393 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
395 dispparams.cArgs = 1;
396 dispparams.rgvarg = &vararg;
397 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
398 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
400 dispparams.cArgs = 1;
401 dispparams.rgvarg = &vararg;
402 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
403 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
405 IPictureDisp_Release(picdisp);
408 START_TEST(olepicture)
410 hOleaut32 = LoadLibraryA("oleaut32.dll");
411 pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
412 if (!pOleLoadPicture)
415 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
416 test_pic(gifimage, sizeof(gifimage));
417 test_pic(jpgimage, sizeof(jpgimage));
418 test_pic(bmpimage, sizeof(bmpimage));
419 test_pic(gif4pixel, sizeof(gif4pixel));
420 /* No PNG support yet here or in older Windows...
421 test_pic(pngimage, sizeof(pngimage));
424 test_empty_image_2();
430 /* Helper functions only ... */
433 static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
435 GlobalFree(This->supportHandle);
436 This->supportHandle=0;
437 HeapFree(GetProcessHeap(), 0, This);
440 static ULONG WINAPI NoStatStreamImpl_AddRef(
443 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
444 return InterlockedIncrement(&This->ref);
447 static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
449 REFIID riid, /* [in] */
450 void** ppvObject) /* [iid_is][out] */
452 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
453 if (ppvObject==0) return E_INVALIDARG;
455 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
457 *ppvObject = (IStream*)This;
459 else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
461 *ppvObject = (IStream*)This;
465 return E_NOINTERFACE;
466 NoStatStreamImpl_AddRef(iface);
470 static ULONG WINAPI NoStatStreamImpl_Release(
473 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
474 ULONG newRef = InterlockedDecrement(&This->ref);
476 NoStatStreamImpl_Destroy(This);
480 static HRESULT WINAPI NoStatStreamImpl_Read(
482 void* pv, /* [length_is][size_is][out] */
484 ULONG* pcbRead) /* [out] */
486 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
488 ULONG bytesReadBuffer;
489 ULONG bytesToReadFromBuffer;
492 pcbRead = &bytesReadBuffer;
493 bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
494 supportBuffer = GlobalLock(This->supportHandle);
495 memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
496 This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
497 *pcbRead = bytesToReadFromBuffer;
498 GlobalUnlock(This->supportHandle);
504 static HRESULT WINAPI NoStatStreamImpl_Write(
506 const void* pv, /* [size_is][in] */
508 ULONG* pcbWritten) /* [out] */
510 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
512 ULARGE_INTEGER newSize;
513 ULONG bytesWritten = 0;
516 pcbWritten = &bytesWritten;
519 newSize.u.HighPart = 0;
520 newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
521 if (newSize.u.LowPart > This->streamSize.u.LowPart)
522 IStream_SetSize(iface, newSize);
524 supportBuffer = GlobalLock(This->supportHandle);
525 memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
526 This->currentPosition.u.LowPart+=cb;
528 GlobalUnlock(This->supportHandle);
532 static HRESULT WINAPI NoStatStreamImpl_Seek(
534 LARGE_INTEGER dlibMove, /* [in] */
535 DWORD dwOrigin, /* [in] */
536 ULARGE_INTEGER* plibNewPosition) /* [out] */
538 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
539 ULARGE_INTEGER newPosition;
542 case STREAM_SEEK_SET:
543 newPosition.u.HighPart = 0;
544 newPosition.u.LowPart = 0;
546 case STREAM_SEEK_CUR:
547 newPosition = This->currentPosition;
549 case STREAM_SEEK_END:
550 newPosition = This->streamSize;
553 return STG_E_INVALIDFUNCTION;
555 if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart)
556 return STG_E_INVALIDFUNCTION;
557 newPosition.QuadPart += dlibMove.QuadPart;
558 if (plibNewPosition) *plibNewPosition = newPosition;
559 This->currentPosition = newPosition;
563 static HRESULT WINAPI NoStatStreamImpl_SetSize(
565 ULARGE_INTEGER libNewSize) /* [in] */
567 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
568 HGLOBAL supportHandle;
569 if (libNewSize.u.HighPart != 0)
570 return STG_E_INVALIDFUNCTION;
571 if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
573 supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
574 if (supportHandle == 0)
575 return STG_E_MEDIUMFULL;
576 This->supportHandle = supportHandle;
577 This->streamSize.u.LowPart = libNewSize.u.LowPart;
581 static HRESULT WINAPI NoStatStreamImpl_CopyTo(
583 IStream* pstm, /* [unique][in] */
584 ULARGE_INTEGER cb, /* [in] */
585 ULARGE_INTEGER* pcbRead, /* [out] */
586 ULARGE_INTEGER* pcbWritten) /* [out] */
590 ULONG bytesRead, bytesWritten, copySize;
591 ULARGE_INTEGER totalBytesRead;
592 ULARGE_INTEGER totalBytesWritten;
595 return STG_E_INVALIDPOINTER;
596 totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
597 totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
599 while ( cb.u.LowPart > 0 )
601 if ( cb.u.LowPart >= 128 )
604 copySize = cb.u.LowPart;
605 IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
606 totalBytesRead.u.LowPart += bytesRead;
607 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
608 totalBytesWritten.u.LowPart += bytesWritten;
609 if (bytesRead != bytesWritten)
611 hr = STG_E_MEDIUMFULL;
614 if (bytesRead!=copySize)
617 cb.u.LowPart -= bytesRead;
621 pcbRead->u.LowPart = totalBytesRead.u.LowPart;
622 pcbRead->u.HighPart = totalBytesRead.u.HighPart;
627 pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
628 pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
633 static HRESULT WINAPI NoStatStreamImpl_Commit(IStream* iface,DWORD grfCommitFlags)
637 static HRESULT WINAPI NoStatStreamImpl_Revert(IStream* iface) { return S_OK; }
639 static HRESULT WINAPI NoStatStreamImpl_LockRegion(
641 ULARGE_INTEGER libOffset, /* [in] */
642 ULARGE_INTEGER cb, /* [in] */
643 DWORD dwLockType) /* [in] */
648 static HRESULT WINAPI NoStatStreamImpl_UnlockRegion(
650 ULARGE_INTEGER libOffset, /* [in] */
651 ULARGE_INTEGER cb, /* [in] */
652 DWORD dwLockType) /* [in] */
657 static HRESULT WINAPI NoStatStreamImpl_Stat(
659 STATSTG* pstatstg, /* [out] */
660 DWORD grfStatFlag) /* [in] */
665 static HRESULT WINAPI NoStatStreamImpl_Clone(
667 IStream** ppstm) /* [out] */
671 static const IStreamVtbl NoStatStreamImpl_Vtbl;
673 static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
675 NoStatStreamImpl* newStream;
677 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
680 newStream->lpVtbl = &NoStatStreamImpl_Vtbl;
682 newStream->supportHandle = hGlobal;
684 if (!newStream->supportHandle)
685 newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
687 newStream->currentPosition.u.HighPart = 0;
688 newStream->currentPosition.u.LowPart = 0;
689 newStream->streamSize.u.HighPart = 0;
690 newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
696 static const IStreamVtbl NoStatStreamImpl_Vtbl =
698 NoStatStreamImpl_QueryInterface,
699 NoStatStreamImpl_AddRef,
700 NoStatStreamImpl_Release,
701 NoStatStreamImpl_Read,
702 NoStatStreamImpl_Write,
703 NoStatStreamImpl_Seek,
704 NoStatStreamImpl_SetSize,
705 NoStatStreamImpl_CopyTo,
706 NoStatStreamImpl_Commit,
707 NoStatStreamImpl_Revert,
708 NoStatStreamImpl_LockRegion,
709 NoStatStreamImpl_UnlockRegion,
710 NoStatStreamImpl_Stat,
711 NoStatStreamImpl_Clone