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;
194 /* Let the fun begin */
195 hglob = GlobalAlloc (0, imgsize);
196 data = GlobalLock (hglob);
197 memcpy(data, imgdata, imgsize);
199 hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
200 ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
202 memset(&seekto,0,sizeof(seekto));
203 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
204 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
205 test_pic_with_stream(stream, imgsize);
207 /* again with Non Statable and Non Seekable stream */
208 stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
209 test_pic_with_stream(stream, 0);
212 static void test_empty_image(void) {
215 IPicture* pic = NULL;
220 ULARGE_INTEGER newpos1;
221 LARGE_INTEGER seekto;
224 /* Empty image. Happens occasionally in VB programs. */
225 hglob = GlobalAlloc (0, 8);
226 data = GlobalLock (hglob);
227 memcpy(data,"lt\0\0",4);
228 ((DWORD*)data)[1] = 0;
229 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
230 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
232 memset(&seekto,0,sizeof(seekto));
233 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
234 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
237 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
239 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
240 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
242 hres = IPicture_get_Type (pic, &type);
243 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
244 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
246 hres = IPicture_get_Handle (pic, &handle);
247 ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres);
248 ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
249 IPicture_Release (pic);
252 static void test_empty_image_2(void) {
255 IPicture* pic = NULL;
259 ULARGE_INTEGER newpos1;
260 LARGE_INTEGER seekto;
263 /* Empty image at random stream position. */
264 hglob = GlobalAlloc (0, 200);
265 data = GlobalLock (hglob);
267 memcpy(data,"lt\0\0",4);
268 ((DWORD*)data)[1] = 0;
269 hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
270 ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08x\n", hres);
272 memset(&seekto,0,sizeof(seekto));
273 seekto.u.LowPart = 42;
274 hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
275 ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
278 hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
280 ok(hres == S_OK,"empty picture not loaded, hres 0x%08x\n", hres);
281 ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
283 hres = IPicture_get_Type (pic, &type);
284 ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
285 ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
287 IPicture_Release (pic);
290 static void test_Invoke(void)
292 IPictureDisp *picdisp;
295 DISPPARAMS dispparams;
301 hglob = GlobalAlloc (0, sizeof(gifimage));
302 data = GlobalLock(hglob);
303 memcpy(data, gifimage, sizeof(gifimage));
306 hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
307 ok_ole_success(hr, "CreateStreamOnHGlobal");
309 hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
310 IStream_Release(stream);
311 ok_ole_success(hr, "OleLoadPicture");
313 V_VT(&vararg) = VT_BOOL;
314 V_BOOL(&vararg) = VARIANT_FALSE;
315 dispparams.cNamedArgs = 0;
316 dispparams.rgdispidNamedArgs = NULL;
317 dispparams.cArgs = 1;
318 dispparams.rgvarg = &vararg;
319 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IPictureDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
320 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
321 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
322 ok(hr == DISP_E_UNKNOWNNAME, "IPictureDisp_Invoke should have returned DISP_E_UNKNOWNNAME instead of 0x%08x\n", hr);
324 dispparams.cArgs = 0;
325 dispparams.rgvarg = NULL;
326 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
327 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
329 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
330 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
332 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
333 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
335 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
336 ok(hr == DISP_E_PARAMNOTOPTIONAL, "IPictureDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
338 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
339 ok_ole_success(hr, "IPictureDisp_Invoke");
340 ok(V_VT(&varresult) == VT_I4, "V_VT(&varresult) should have been VT_UINT instead of %d\n", V_VT(&varresult));
342 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
343 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
345 hr = IPictureDisp_Invoke(picdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
346 ok(hr == DISP_E_MEMBERNOTFOUND, "IPictureDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
348 dispparams.cArgs = 1;
349 dispparams.rgvarg = &vararg;
350 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
351 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
353 dispparams.cArgs = 1;
354 dispparams.rgvarg = &vararg;
355 hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_HPAL, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
356 ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
358 IPictureDisp_Release(picdisp);
361 START_TEST(olepicture)
363 hOleaut32 = LoadLibraryA("oleaut32.dll");
364 pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
365 if (!pOleLoadPicture)
368 /* Test regular 1x1 pixel images of gif, jpg, bmp type */
369 test_pic(gifimage, sizeof(gifimage));
370 test_pic(jpgimage, sizeof(jpgimage));
371 test_pic(bmpimage, sizeof(bmpimage));
372 test_pic(gif4pixel, sizeof(gif4pixel));
373 /* No PNG support yet here or in older Windows...
374 test_pic(pngimage, sizeof(pngimage));
377 test_empty_image_2();
383 /* Helper functions only ... */
386 static void NoStatStreamImpl_Destroy(NoStatStreamImpl* This)
388 GlobalFree(This->supportHandle);
389 This->supportHandle=0;
390 HeapFree(GetProcessHeap(), 0, This);
393 static ULONG WINAPI NoStatStreamImpl_AddRef(
396 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
397 return InterlockedIncrement(&This->ref);
400 static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
402 REFIID riid, /* [in] */
403 void** ppvObject) /* [iid_is][out] */
405 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
406 if (ppvObject==0) return E_INVALIDARG;
408 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
410 *ppvObject = (IStream*)This;
412 else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
414 *ppvObject = (IStream*)This;
418 return E_NOINTERFACE;
419 NoStatStreamImpl_AddRef(iface);
423 static ULONG WINAPI NoStatStreamImpl_Release(
426 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
427 ULONG newRef = InterlockedDecrement(&This->ref);
429 NoStatStreamImpl_Destroy(This);
433 static HRESULT WINAPI NoStatStreamImpl_Read(
435 void* pv, /* [length_is][size_is][out] */
437 ULONG* pcbRead) /* [out] */
439 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
441 ULONG bytesReadBuffer;
442 ULONG bytesToReadFromBuffer;
445 pcbRead = &bytesReadBuffer;
446 bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
447 supportBuffer = GlobalLock(This->supportHandle);
448 memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
449 This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
450 *pcbRead = bytesToReadFromBuffer;
451 GlobalUnlock(This->supportHandle);
457 static HRESULT WINAPI NoStatStreamImpl_Write(
459 const void* pv, /* [size_is][in] */
461 ULONG* pcbWritten) /* [out] */
463 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
465 ULARGE_INTEGER newSize;
466 ULONG bytesWritten = 0;
469 pcbWritten = &bytesWritten;
472 newSize.u.HighPart = 0;
473 newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
474 if (newSize.u.LowPart > This->streamSize.u.LowPart)
475 IStream_SetSize(iface, newSize);
477 supportBuffer = GlobalLock(This->supportHandle);
478 memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
479 This->currentPosition.u.LowPart+=cb;
481 GlobalUnlock(This->supportHandle);
485 static HRESULT WINAPI NoStatStreamImpl_Seek(
487 LARGE_INTEGER dlibMove, /* [in] */
488 DWORD dwOrigin, /* [in] */
489 ULARGE_INTEGER* plibNewPosition) /* [out] */
491 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
492 ULARGE_INTEGER newPosition;
495 case STREAM_SEEK_SET:
496 newPosition.u.HighPart = 0;
497 newPosition.u.LowPart = 0;
499 case STREAM_SEEK_CUR:
500 newPosition = This->currentPosition;
502 case STREAM_SEEK_END:
503 newPosition = This->streamSize;
506 return STG_E_INVALIDFUNCTION;
508 if (dlibMove.QuadPart < 0 && newPosition.QuadPart < -dlibMove.QuadPart)
509 return STG_E_INVALIDFUNCTION;
510 newPosition.QuadPart += dlibMove.QuadPart;
511 if (plibNewPosition) *plibNewPosition = newPosition;
512 This->currentPosition = newPosition;
516 static HRESULT WINAPI NoStatStreamImpl_SetSize(
518 ULARGE_INTEGER libNewSize) /* [in] */
520 NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
521 HGLOBAL supportHandle;
522 if (libNewSize.u.HighPart != 0)
523 return STG_E_INVALIDFUNCTION;
524 if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
526 supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
527 if (supportHandle == 0)
528 return STG_E_MEDIUMFULL;
529 This->supportHandle = supportHandle;
530 This->streamSize.u.LowPart = libNewSize.u.LowPart;
534 static HRESULT WINAPI NoStatStreamImpl_CopyTo(
536 IStream* pstm, /* [unique][in] */
537 ULARGE_INTEGER cb, /* [in] */
538 ULARGE_INTEGER* pcbRead, /* [out] */
539 ULARGE_INTEGER* pcbWritten) /* [out] */
543 ULONG bytesRead, bytesWritten, copySize;
544 ULARGE_INTEGER totalBytesRead;
545 ULARGE_INTEGER totalBytesWritten;
548 return STG_E_INVALIDPOINTER;
549 totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0;
550 totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0;
552 while ( cb.u.LowPart > 0 )
554 if ( cb.u.LowPart >= 128 )
557 copySize = cb.u.LowPart;
558 IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
559 totalBytesRead.u.LowPart += bytesRead;
560 IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
561 totalBytesWritten.u.LowPart += bytesWritten;
562 if (bytesRead != bytesWritten)
564 hr = STG_E_MEDIUMFULL;
567 if (bytesRead!=copySize)
570 cb.u.LowPart -= bytesRead;
574 pcbRead->u.LowPart = totalBytesRead.u.LowPart;
575 pcbRead->u.HighPart = totalBytesRead.u.HighPart;
580 pcbWritten->u.LowPart = totalBytesWritten.u.LowPart;
581 pcbWritten->u.HighPart = totalBytesWritten.u.HighPart;
586 static HRESULT WINAPI NoStatStreamImpl_Commit(IStream* iface,DWORD grfCommitFlags)
590 static HRESULT WINAPI NoStatStreamImpl_Revert(IStream* iface) { return S_OK; }
592 static HRESULT WINAPI NoStatStreamImpl_LockRegion(
594 ULARGE_INTEGER libOffset, /* [in] */
595 ULARGE_INTEGER cb, /* [in] */
596 DWORD dwLockType) /* [in] */
601 static HRESULT WINAPI NoStatStreamImpl_UnlockRegion(
603 ULARGE_INTEGER libOffset, /* [in] */
604 ULARGE_INTEGER cb, /* [in] */
605 DWORD dwLockType) /* [in] */
610 static HRESULT WINAPI NoStatStreamImpl_Stat(
612 STATSTG* pstatstg, /* [out] */
613 DWORD grfStatFlag) /* [in] */
618 static HRESULT WINAPI NoStatStreamImpl_Clone(
620 IStream** ppstm) /* [out] */
624 static const IStreamVtbl NoStatStreamImpl_Vtbl;
626 static NoStatStreamImpl* NoStatStreamImpl_Construct(HGLOBAL hGlobal)
628 NoStatStreamImpl* newStream;
630 newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(NoStatStreamImpl));
633 newStream->lpVtbl = &NoStatStreamImpl_Vtbl;
635 newStream->supportHandle = hGlobal;
637 if (!newStream->supportHandle)
638 newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
640 newStream->currentPosition.u.HighPart = 0;
641 newStream->currentPosition.u.LowPart = 0;
642 newStream->streamSize.u.HighPart = 0;
643 newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
649 static const IStreamVtbl NoStatStreamImpl_Vtbl =
651 NoStatStreamImpl_QueryInterface,
652 NoStatStreamImpl_AddRef,
653 NoStatStreamImpl_Release,
654 NoStatStreamImpl_Read,
655 NoStatStreamImpl_Write,
656 NoStatStreamImpl_Seek,
657 NoStatStreamImpl_SetSize,
658 NoStatStreamImpl_CopyTo,
659 NoStatStreamImpl_Commit,
660 NoStatStreamImpl_Revert,
661 NoStatStreamImpl_LockRegion,
662 NoStatStreamImpl_UnlockRegion,
663 NoStatStreamImpl_Stat,
664 NoStatStreamImpl_Clone