gdiplus: Add GdipGetPenCompoundCount implementation.
[wine.git] / dlls / windowscodecs / tests / stream.c
blob2a1b3e3092829d6d9a5beee91911f9fd09984634
1 /*
2 * Copyright 2009 Tony Wasserka
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "wine/test.h"
21 #define COBJMACROS
22 #include "wincodec.h"
24 #define CHECK_CUR_POS(a, b) _check_cur_pos((IStream *)a, b, FALSE, __LINE__)
25 #define CHECK_CUR_POS_TODO(a, b) _check_cur_pos((IStream *)a, b, TRUE, __LINE__)
26 static void _check_cur_pos(IStream *stream, ULONGLONG expected_pos, BOOL todo, unsigned int line)
28 LARGE_INTEGER offset;
29 ULARGE_INTEGER pos;
30 HRESULT hr;
32 offset.QuadPart = 0;
33 hr = IStream_Seek(stream, offset, STREAM_SEEK_CUR, &pos);
34 ok_(__FILE__, line)(hr == S_OK, "Failed to get current position, hr %#lx.\n", hr);
35 todo_wine_if(todo)
36 ok_(__FILE__, line)(pos.QuadPart == expected_pos, "Unexpected stream position %s.\n",
37 wine_dbgstr_longlong(pos.QuadPart));
40 static void test_StreamOnMemory(void)
42 IWICImagingFactory *pFactory;
43 IWICStream *pStream, *pBufStream;
44 const BYTE CmpMem[] = {
45 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
46 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
47 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
48 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
50 const BYTE CmpMemOverlap[] = {
51 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
52 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
53 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
54 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
56 const BYTE ZeroMem[10] = {0};
57 BYTE Memory[64], MemBuf[64];
58 LARGE_INTEGER LargeNull, LargeInt, SeekPos;
59 ULARGE_INTEGER uLargeNull, uNewPos;
60 ULONG uBytesRead, uBytesWritten;
61 HRESULT hr;
62 STATSTG Stats;
64 LargeNull.QuadPart = 0;
65 uLargeNull.QuadPart = 0;
66 SeekPos.QuadPart = 5;
68 memcpy(Memory, CmpMem, sizeof(CmpMem));
70 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
71 if(FAILED(hr)) {
72 skip("CoCreateInstance returned with %#lx, expected %#lx\n", hr, S_OK);
73 return;
76 hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
77 ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK);
78 if(FAILED(hr)) {
79 skip("Failed to create stream\n");
80 return;
83 /* InitializeFromMemory */
84 hr = IWICStream_InitializeFromMemory(pStream, NULL, sizeof(Memory)); /* memory = NULL */
85 ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
87 hr = IWICStream_InitializeFromMemory(pStream, Memory, 0); /* size = 0 */
88 ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK);
90 hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); /* stream already initialized */
91 ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_WRONGSTATE);
93 /* recreate stream */
94 IWICStream_Release(pStream);
95 hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
96 ok(hr == S_OK, "CreateStream failed with %#lx\n", hr);
98 hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
99 ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK);
101 /* IWICStream does not maintain an independent copy of the backing memory buffer. */
102 memcpy(Memory, ZeroMem, sizeof(ZeroMem));
103 hr = IWICStream_Read(pStream, MemBuf, sizeof(ZeroMem), &uBytesRead);
104 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
105 if(SUCCEEDED(hr)) {
106 ok(uBytesRead == sizeof(ZeroMem), "Read %lu bytes\n", uBytesRead);
107 ok(memcmp(MemBuf, ZeroMem, sizeof(ZeroMem)) == 0, "Read returned invalid data!\n");
110 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
112 hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten);
113 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
115 /* Seek */
116 hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
117 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
118 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
120 hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
121 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
123 LargeInt.u.HighPart = 1;
124 LargeInt.u.LowPart = 0;
125 uNewPos.u.HighPart = 0xdeadbeef;
126 uNewPos.u.LowPart = 0xdeadbeef;
127 hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
128 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
129 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
130 CHECK_CUR_POS(pStream, 0);
132 LargeInt.QuadPart = sizeof(Memory) + 10;
133 uNewPos.u.HighPart = 0xdeadbeef;
134 uNewPos.u.LowPart = 0xdeadbeef;
135 hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
136 ok(hr == E_INVALIDARG, "Seek returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
137 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
138 CHECK_CUR_POS(pStream, 0);
140 LargeInt.QuadPart = 1;
141 uNewPos.u.HighPart = 0xdeadbeef;
142 uNewPos.u.LowPart = 0xdeadbeef;
143 hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
144 ok(hr == E_INVALIDARG, "Seek returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
145 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
146 CHECK_CUR_POS(pStream, 0);
148 LargeInt.QuadPart = -1;
149 hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
150 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
151 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%lu;%lu)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
153 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
154 LargeInt.QuadPart = -(LONGLONG)sizeof(Memory) - 5;
155 uNewPos.u.HighPart = 0xdeadbeef;
156 uNewPos.u.LowPart = 0xdeadbeef;
157 hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
158 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW),
159 "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
160 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
161 CHECK_CUR_POS(pStream, 0);
162 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
164 /* Read */
165 hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead);
166 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
167 if(SUCCEEDED(hr)) {
168 ok(uBytesRead == 12, "Read %lu bytes, expected %u\n", uBytesRead, 12);
169 ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n");
171 /* check whether the seek pointer has moved correctly */
172 CHECK_CUR_POS(pStream, uBytesRead);
175 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
177 hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source = dest */
178 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
179 if(SUCCEEDED(hr)) {
180 ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10);
181 ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
184 IWICStream_Seek(pStream, SeekPos, STREAM_SEEK_SET, NULL);
186 hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source and dest overlap */
187 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
188 if(SUCCEEDED(hr)) {
189 ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10);
190 ok(memcmp(Memory, CmpMemOverlap, uBytesRead) == 0, "Read returned invalid data!\n");
193 memcpy(Memory, CmpMem, sizeof(CmpMem));
195 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
197 hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead); /* request too many bytes */
198 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
199 if(SUCCEEDED(hr)) {
200 ok(uBytesRead == sizeof(Memory), "Read %lu bytes\n", uBytesRead);
201 ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
204 hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */
205 ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
207 hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */
208 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
210 hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead);
211 ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
213 hr = IWICStream_Read(pStream, NULL, 0, NULL);
214 ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
216 hr = IWICStream_Read(pStream, MemBuf, 1, NULL);
217 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
219 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
220 ZeroMemory(MemBuf, sizeof(MemBuf));
221 hr = IWICStream_Read(pStream, MemBuf, sizeof(Memory) + 10, &uBytesRead);
222 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
223 if(SUCCEEDED(hr)) {
224 ok(uBytesRead == sizeof(Memory), "Read %lu bytes\n", uBytesRead);
225 ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n");
227 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
230 /* Write */
231 MemBuf[0] = CmpMem[0] + 1;
232 MemBuf[1] = CmpMem[1] + 1;
233 MemBuf[2] = CmpMem[2] + 1;
234 hr = IWICStream_Write(pStream, MemBuf, 3, &uBytesWritten);
235 ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK);
236 if(SUCCEEDED(hr)) {
237 ok(uBytesWritten == 3, "Wrote %lu bytes, expected %u\n", uBytesWritten, 3);
238 ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
240 /* check whether the seek pointer has moved correctly */
241 CHECK_CUR_POS(pStream, uBytesWritten);
243 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
245 hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten);
246 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
248 /* Restore the original contents of the memory stream. */
249 hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten);
250 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
252 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
254 /* Source and destination overlap. */
255 hr = IWICStream_Write(pStream, Memory + 5, 10, &uBytesWritten);
256 ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK);
257 if(SUCCEEDED(hr)) {
258 ok(uBytesWritten == 10, "Wrote %lu bytes, expected %u\n", uBytesWritten, 10);
259 ok(memcmp(CmpMemOverlap, Memory, sizeof(CmpMemOverlap)) == 0, "Wrote returned invalid data!\n");
262 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
264 uBytesWritten = 0xdeadbeef;
265 hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten);
266 ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
267 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten);
268 CHECK_CUR_POS(pStream, 0);
270 uBytesWritten = 0xdeadbeef;
271 hr = IWICStream_Write(pStream, NULL, 0, &uBytesWritten);
272 ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
273 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten);
274 CHECK_CUR_POS(pStream, 0);
276 uBytesWritten = 0xdeadbeef;
277 hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten);
278 ok(hr == STG_E_MEDIUMFULL, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL);
279 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten);
280 CHECK_CUR_POS(pStream, 0);
281 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
284 /* SetSize */
285 uNewPos.u.HighPart = 0;
286 uNewPos.u.LowPart = sizeof(Memory) + 10;
287 hr = IWICStream_SetSize(pStream, uNewPos);
288 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
290 uNewPos.u.HighPart = 0;
291 uNewPos.u.LowPart = sizeof(Memory);
292 hr = IWICStream_SetSize(pStream, uNewPos);
293 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
295 uNewPos.u.HighPart = 0;
296 uNewPos.u.LowPart = sizeof(Memory) - 10;
297 hr = IWICStream_SetSize(pStream, uNewPos);
298 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
300 uNewPos.u.HighPart = 0;
301 uNewPos.u.LowPart = 0;
302 hr = IWICStream_SetSize(pStream, uNewPos);
303 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
305 uNewPos.QuadPart = -10;
306 hr = IWICStream_SetSize(pStream, uNewPos);
307 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
310 /* CopyTo */
311 uNewPos.u.HighPart = 0;
312 uNewPos.u.LowPart = 5;
313 hr = IWICStream_CopyTo(pStream, NULL, uNewPos, NULL, NULL);
314 ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
316 hr = IWICImagingFactory_CreateStream(pFactory, &pBufStream);
317 ok(hr == S_OK, "CreateStream failed with %#lx\n", hr);
319 hr = IWICStream_InitializeFromMemory(pBufStream, Memory, sizeof(Memory));
320 ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK);
322 hr = IWICStream_CopyTo(pStream, (IStream*)pBufStream, uNewPos, NULL, NULL);
323 ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
324 IWICStream_Release(pBufStream);
327 /* Commit */
328 hr = IWICStream_Commit(pStream, STGC_DEFAULT);
329 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
331 hr = IWICStream_Commit(pStream, STGC_OVERWRITE);
332 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
334 hr = IWICStream_Commit(pStream, STGC_ONLYIFCURRENT);
335 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
337 hr = IWICStream_Commit(pStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
338 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
340 hr = IWICStream_Commit(pStream, STGC_CONSOLIDATE);
341 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
344 /* Revert */
345 IWICStream_Write(pStream, &MemBuf[5], 6, NULL);
346 hr = IWICStream_Revert(pStream);
347 ok(hr == E_NOTIMPL, "Revert returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
348 memcpy(Memory, CmpMem, sizeof(Memory));
351 /* LockRegion/UnlockRegion */
352 hr = IWICStream_LockRegion(pStream, uLargeNull, uLargeNull, 0);
353 ok(hr == E_NOTIMPL, "LockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
355 hr = IWICStream_UnlockRegion(pStream, uLargeNull, uLargeNull, 0);
356 ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
359 /* Stat */
360 hr = IWICStream_Stat(pStream, NULL, 0);
361 ok(hr == E_INVALIDARG, "Stat returned %#lx, expected %#lx\n", hr, E_INVALIDARG);
363 hr = IWICStream_Stat(pStream, &Stats, 0);
364 ok(hr == S_OK, "Stat returned %#lx, expected %#lx\n", hr, S_OK);
365 ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
366 ok(Stats.type == STGTY_STREAM, "Stat returned type %ld, expected %d\n", Stats.type, STGTY_STREAM);
367 ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%lu;%lu)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart);
368 ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%lu;%lu), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0);
369 ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%lu;%lu), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0);
370 ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%lu;%lu), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0);
371 ok(Stats.grfMode == 0, "Stat returned access mode %ld, expected %d\n", Stats.grfMode, 0);
372 ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#lx, expected %#x\n", Stats.grfLocksSupported, 0);
373 ok(Stats.grfStateBits == 0, "Stat returned state bits %#lx, expected %#x\n", Stats.grfStateBits, 0);
376 /* Clone */
377 hr = IWICStream_Clone(pStream, (IStream**)&pBufStream);
378 ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
381 IWICStream_Release(pStream);
382 IWICImagingFactory_Release(pFactory);
385 static void test_StreamOnStreamRange(void)
387 IWICImagingFactory *pFactory;
388 IWICStream *pStream, *pSubStream;
389 IStream *CopyStream;
390 const BYTE CmpMem[] = {
391 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
392 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
393 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
394 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
396 BYTE Memory[64], MemBuf[64];
397 LARGE_INTEGER LargeNull, LargeInt;
398 ULARGE_INTEGER uLargeNull, uNewPos, uSize;
399 ULONG uBytesRead, uBytesWritten;
400 HRESULT hr;
401 STATSTG Stats;
403 LargeNull.QuadPart = 0;
404 uLargeNull.QuadPart = 0;
406 memcpy(Memory, CmpMem, sizeof(CmpMem));
408 CoInitialize(NULL);
410 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
411 if(FAILED(hr)) {
412 skip("CoCreateInstance returned with %#lx, expected %#lx\n", hr, S_OK);
413 return;
416 hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
417 ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK);
418 if(FAILED(hr)) {
419 skip("Failed to create stream\n");
420 return;
423 hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
424 ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK);
426 hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
427 ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK);
429 uNewPos.QuadPart = 20;
430 uSize.QuadPart = 20;
431 hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
432 ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#lx, expected %#lx\n", hr, S_OK);
433 if(FAILED(hr)) {
434 skip("InitializeFromIStreamRegion unimplemented\n");
435 IWICStream_Release(pSubStream);
436 IWICStream_Release(pStream);
437 IWICImagingFactory_Release(pFactory);
438 CoUninitialize();
439 return;
442 /* Seek */
443 CHECK_CUR_POS(pStream, 0);
444 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
445 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 20, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 20);
446 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
447 CHECK_CUR_POS(pStream, 0);
449 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
450 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
451 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
452 CHECK_CUR_POS(pStream, 0);
454 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
455 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
457 LargeInt.u.HighPart = 1;
458 LargeInt.u.LowPart = 0;
459 uNewPos.u.HighPart = 0xdeadbeef;
460 uNewPos.u.LowPart = 0xdeadbeef;
461 hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
462 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
463 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
464 CHECK_CUR_POS(pStream, 0);
466 LargeInt.QuadPart = 30;
467 uNewPos.u.HighPart = 0xdeadbeef;
468 uNewPos.u.LowPart = 0xdeadbeef;
469 hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
470 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
471 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
472 CHECK_CUR_POS(pStream, 0);
474 LargeInt.QuadPart = 1;
475 uNewPos.u.HighPart = 0xdeadbeef;
476 uNewPos.u.LowPart = 0xdeadbeef;
477 hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
478 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#lx, expected %#lx\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
479 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
480 CHECK_CUR_POS(pStream, 0);
482 LargeInt.QuadPart = -1;
483 hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
484 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
485 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%lu;%lu)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
486 CHECK_CUR_POS(pStream, 0);
488 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
489 LargeInt.QuadPart = -25;
490 uNewPos.u.HighPart = 0xdeadbeef;
491 uNewPos.u.LowPart = 0xdeadbeef;
492 hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
493 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
494 "Seek returned with %#lx, expected %#lx\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
495 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
496 CHECK_CUR_POS(pStream, 0);
497 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
500 /* Read */
501 hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead);
502 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
503 if(SUCCEEDED(hr)) {
504 ok(uBytesRead == 12, "Read %lu bytes, expected %u\n", uBytesRead, 12);
505 ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n");
507 /* check whether the seek pointer has moved correctly */
508 CHECK_CUR_POS(pSubStream, uBytesRead);
509 CHECK_CUR_POS(pStream, 0);
512 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
514 hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead); /* source = dest */
515 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
516 if(SUCCEEDED(hr)) {
517 ok(uBytesRead == 10, "Read %lu bytes, expected %u\n", uBytesRead, 10);
518 ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
520 CHECK_CUR_POS(pStream, 0);
522 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
524 hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead); /* request too many bytes */
525 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
526 if(SUCCEEDED(hr)) {
527 ok(uBytesRead == 20, "Read %lu bytes\n", uBytesRead);
528 ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
530 CHECK_CUR_POS(pStream, 0);
532 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
533 uBytesRead = 0xdeadbeef;
534 hr = IWICStream_Read(pSubStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */
535 ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
536 ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %lu\n", uBytesRead);
538 hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */
539 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
541 uBytesRead = 0xdeadbeef;
542 hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead);
543 ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
544 ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %lu\n", uBytesRead);
546 hr = IWICStream_Read(pSubStream, NULL, 0, NULL);
547 ok(hr == E_INVALIDARG, "Read returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
549 hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL);
550 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
552 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
553 ZeroMemory(MemBuf, sizeof(MemBuf));
554 hr = IWICStream_Read(pSubStream, MemBuf, 30, &uBytesRead);
555 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
556 if(SUCCEEDED(hr)) {
557 ok(uBytesRead == 20, "Read %lu bytes\n", uBytesRead);
558 ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n");
560 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
563 /* Write */
564 MemBuf[0] = CmpMem[0] + 1;
565 MemBuf[1] = CmpMem[1] + 1;
566 MemBuf[2] = CmpMem[2] + 1;
567 hr = IWICStream_Write(pSubStream, MemBuf, 3, &uBytesWritten);
568 ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, S_OK);
569 if(SUCCEEDED(hr)) {
570 ok(uBytesWritten == 3, "Wrote %lu bytes, expected %u\n", uBytesWritten, 3);
571 ok(memcmp(MemBuf, Memory+20, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
573 /* check whether the seek pointer has moved correctly */
574 CHECK_CUR_POS(pSubStream, uBytesWritten);
575 CHECK_CUR_POS(pStream, 0);
577 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
579 hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten);
580 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
582 uBytesWritten = 0xdeadbeef;
583 hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten);
584 ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
585 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten);
586 CHECK_CUR_POS(pSubStream, 0);
587 CHECK_CUR_POS(pStream, 0);
589 uBytesWritten = 0xdeadbeef;
590 hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten);
591 ok(hr == E_INVALIDARG, "Write returned with %#lx, expected %#lx\n", hr, E_INVALIDARG);
592 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten);
593 CHECK_CUR_POS(pSubStream, 0);
594 CHECK_CUR_POS(pStream, 0);
596 hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten);
597 ok(hr == S_OK, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL);
598 ok(uBytesWritten == 20, "Wrote %lu bytes, expected %u\n", uBytesWritten, 0);
599 CHECK_CUR_POS(pSubStream, uBytesWritten);
600 CHECK_CUR_POS(pStream, 0);
601 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
604 /* SetSize */
605 uNewPos.u.HighPart = 0;
606 uNewPos.u.LowPart = sizeof(Memory) + 10;
607 hr = IWICStream_SetSize(pSubStream, uNewPos);
608 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
610 uNewPos.u.HighPart = 0;
611 uNewPos.u.LowPart = sizeof(Memory);
612 hr = IWICStream_SetSize(pSubStream, uNewPos);
613 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
615 uNewPos.u.HighPart = 0;
616 uNewPos.u.LowPart = sizeof(Memory) - 10;
617 hr = IWICStream_SetSize(pSubStream, uNewPos);
618 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
620 uNewPos.u.HighPart = 0;
621 uNewPos.u.LowPart = 0;
622 hr = IWICStream_SetSize(pSubStream, uNewPos);
623 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
625 uNewPos.QuadPart = -10;
626 hr = IWICStream_SetSize(pSubStream, uNewPos);
627 ok(hr == E_NOTIMPL, "SetSize returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
630 /* CopyTo */
631 uNewPos.u.HighPart = 0;
632 uNewPos.u.LowPart = 30;
633 hr = IWICStream_CopyTo(pSubStream, NULL, uNewPos, NULL, NULL);
634 ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
636 hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream);
637 ok(hr == S_OK, "CreateStream failed with %#lx\n", hr);
639 hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL);
640 ok(hr == E_NOTIMPL, "CopyTo returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
641 IStream_Release(CopyStream);
644 /* Commit */
645 hr = IWICStream_Commit(pSubStream, STGC_DEFAULT);
646 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
648 hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE);
649 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
651 hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT);
652 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
654 hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
655 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
657 hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE);
658 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
661 /* Revert */
662 IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL);
663 hr = IWICStream_Revert(pSubStream);
664 ok(hr == E_NOTIMPL, "Revert returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
665 memcpy(Memory, CmpMem, sizeof(Memory));
668 /* LockRegion/UnlockRegion */
669 hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0);
670 ok(hr == E_NOTIMPL, "LockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
672 hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0);
673 ok(hr == E_NOTIMPL, "UnlockRegion returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
676 /* Stat */
677 hr = IWICStream_Stat(pSubStream, NULL, 0);
678 ok(hr == E_INVALIDARG, "Stat returned %#lx, expected %#lx\n", hr, E_INVALIDARG);
680 hr = IWICStream_Stat(pSubStream, &Stats, 0);
681 ok(hr == S_OK, "Stat returned %#lx, expected %#lx\n", hr, S_OK);
682 ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
683 ok(Stats.type == STGTY_STREAM, "Stat returned type %ld, expected %d\n", Stats.type, STGTY_STREAM);
684 ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%lu;%lu)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart);
685 ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%lu;%lu), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0);
686 ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%lu;%lu), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0);
687 ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%lu;%lu), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0);
688 ok(Stats.grfMode == 0, "Stat returned access mode %ld, expected %d\n", Stats.grfMode, 0);
689 ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#lx, expected %#x\n", Stats.grfLocksSupported, 0);
690 ok(Stats.grfStateBits == 0, "Stat returned state bits %#lx, expected %#x\n", Stats.grfStateBits, 0);
693 /* Clone */
694 hr = IWICStream_Clone(pSubStream, &CopyStream);
695 ok(hr == E_NOTIMPL, "Clone returned %#lx, expected %#lx\n", hr, E_NOTIMPL);
698 IWICStream_Release(pSubStream);
701 /* Recreate, this time larger than the original. */
702 hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
703 ok(hr == S_OK, "CreateStream returned with %#lx, expected %#lx\n", hr, S_OK);
705 uNewPos.QuadPart = 48;
706 uSize.QuadPart = 32;
707 hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
708 ok(hr == S_OK, "InitializeFromMemory returned with %#lx, expected %#lx\n", hr, S_OK);
710 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
711 ok(hr == S_OK, "Seek returned with %#lx, expected %#lx\n", hr, S_OK);
712 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%lu;%lu), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 16);
714 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
715 hr = IWICStream_Read(pSubStream, Memory, 48, &uBytesRead);
716 ok(hr == S_OK, "Read returned with %#lx, expected %#lx\n", hr, S_OK);
717 if(SUCCEEDED(hr)) {
718 ok(uBytesRead == 16, "Read %lu bytes\n", uBytesRead);
719 ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n");
722 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
723 uBytesWritten = 0xdeadbeef;
724 hr = IWICStream_Write(pSubStream, CmpMem, 32, &uBytesWritten);
725 ok(hr == STG_E_MEDIUMFULL, "Write returned with %#lx, expected %#lx\n", hr, STG_E_MEDIUMFULL);
726 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %lu\n", uBytesWritten);
727 CHECK_CUR_POS(pSubStream, 0);
728 CHECK_CUR_POS(pStream, 0);
730 IWICStream_Release(pSubStream);
731 IWICStream_Release(pStream);
732 IWICImagingFactory_Release(pFactory);
733 CoUninitialize();
736 static void test_StreamOnIStream(void)
738 static const BYTE data[] =
740 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
741 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
742 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
743 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
745 static const LARGE_INTEGER zero_pos;
746 static const ULARGE_INTEGER uzero;
747 IWICStream *stream, *substream;
748 IWICImagingFactory *factory;
749 BYTE memory[64], buff[64];
750 ULONG read_len, written;
751 ULARGE_INTEGER newpos;
752 IStream *copy_stream;
753 LARGE_INTEGER pos;
754 unsigned int i;
755 STATSTG stats;
756 HRESULT hr;
758 memcpy(memory, data, sizeof(data));
760 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
761 &IID_IWICImagingFactory, (void **)&factory);
762 ok(hr == S_OK, "Failed to create a factory, hr %#lx.\n", hr);
764 hr = IWICImagingFactory_CreateStream(factory, &stream);
765 ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr);
767 hr = IWICStream_InitializeFromMemory(stream, memory, sizeof(memory));
768 ok(hr == S_OK, "Failed to initialize stream, hr %#lx.\n", hr);
770 hr = IWICImagingFactory_CreateStream(factory, &substream);
771 ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr);
773 pos.QuadPart = 1;
774 hr = IWICStream_Seek(stream, pos, STREAM_SEEK_SET, &newpos);
775 ok(hr == S_OK, "Failed to set position, hr %#lx.\n", hr);
776 CHECK_CUR_POS(stream, 1);
778 hr = IWICStream_InitializeFromIStream(substream, (IStream *)stream);
779 ok(hr == S_OK, "Failed to initialize stream, hr %#lx.\n", hr);
780 CHECK_CUR_POS(substream, 1);
782 /* Seek */
783 CHECK_CUR_POS(stream, 1);
784 hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_END, &newpos);
785 ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr);
786 ok(newpos.QuadPart == sizeof(memory), "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart));
787 CHECK_CUR_POS(substream, sizeof(memory));
788 CHECK_CUR_POS(stream, sizeof(memory));
790 hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, &newpos);
791 ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr);
792 ok(newpos.QuadPart == 0, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart));
793 CHECK_CUR_POS(stream, 0);
794 CHECK_CUR_POS(substream, 0);
796 hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
797 ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr);
799 pos.u.HighPart = 1;
800 pos.u.LowPart = 0;
801 newpos.u.HighPart = 0xdeadbeef;
802 newpos.u.LowPart = 0xdeadbeef;
803 hr = IWICStream_Seek(substream, pos, STREAM_SEEK_SET, &newpos);
804 ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Unexpected hr %#lx.\n", hr);
805 ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n",
806 wine_dbgstr_longlong(newpos.QuadPart));
807 CHECK_CUR_POS(stream, 0);
808 CHECK_CUR_POS(substream, 0);
810 pos.QuadPart = sizeof(memory) + 1;
811 newpos.u.HighPart = 0xdeadbeef;
812 newpos.u.LowPart = 0xdeadbeef;
813 hr = IWICStream_Seek(substream, pos, STREAM_SEEK_SET, &newpos);
814 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
815 ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n",
816 wine_dbgstr_longlong(newpos.QuadPart));
817 CHECK_CUR_POS(stream, 0);
818 CHECK_CUR_POS(substream, 0);
820 pos.QuadPart = 1;
821 newpos.u.HighPart = 0xdeadbeef;
822 newpos.u.LowPart = 0xdeadbeef;
823 hr = IWICStream_Seek(substream, pos, STREAM_SEEK_END, &newpos);
824 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
825 ok(newpos.u.HighPart == 0xdeadbeef && newpos.u.LowPart == 0xdeadbeef, "Unexpected position %s.\n",
826 wine_dbgstr_longlong(newpos.QuadPart));
827 CHECK_CUR_POS(stream, 0);
828 CHECK_CUR_POS(substream, 0);
830 pos.QuadPart = -1;
831 hr = IWICStream_Seek(substream, pos, STREAM_SEEK_END, &newpos);
832 ok(hr == S_OK, "Failed to seek a stream, hr %#lx.\n", hr);
833 ok(newpos.QuadPart == sizeof(memory) - 1, "Unexpected position %s.\n", wine_dbgstr_longlong(newpos.QuadPart));
834 CHECK_CUR_POS(stream, sizeof(memory) - 1);
835 CHECK_CUR_POS(substream, sizeof(memory) - 1);
837 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
839 /* Read */
840 hr = IWICStream_Read(substream, buff, 12, &read_len);
841 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
842 ok(read_len == 12, "Unexpected read length %lu.\n", read_len);
843 ok(!memcmp(buff, data, 12), "Unexpected data.\n");
844 CHECK_CUR_POS(substream, read_len);
845 CHECK_CUR_POS(stream, read_len);
847 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
848 CHECK_CUR_POS(stream, 0);
850 hr = IWICStream_Read(substream, memory, 10, &read_len); /* source = dest */
851 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
852 ok(read_len == 10, "Unexpected read length %lu.\n", read_len);
853 ok(!memcmp(memory, data, read_len), "Unexpected data.\n");
854 CHECK_CUR_POS(stream, 10);
856 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
857 hr = IWICStream_Read(substream, memory, 2 * sizeof(data), &read_len); /* request too many bytes */
858 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
859 ok(read_len == 64, "Unexpected read length %lu.\n", read_len);
860 ok(!memcmp(memory, data, read_len), "Unexpected data.\n");
861 CHECK_CUR_POS(stream, sizeof(data));
863 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
864 read_len = 0xdeadbeef;
865 hr = IWICStream_Read(substream, NULL, 1, &read_len); /* destination buffer = NULL */
866 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
867 ok(read_len == 0xdeadbeef, "Unexpected read length %lu.\n", read_len);
869 read_len = 1;
870 hr = IWICStream_Read(substream, buff, 0, &read_len); /* read 0 bytes */
871 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
872 ok(read_len == 0, "Unexpected read length %lu.\n", read_len);
874 read_len = 0xdeadbeef;
875 hr = IWICStream_Read(substream, NULL, 0, &read_len);
876 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
877 ok(read_len == 0xdeadbeef, "Unexpected read length %lu.\n", read_len);
879 hr = IWICStream_Read(substream, NULL, 0, NULL);
880 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
882 hr = IWICStream_Read(substream, buff, 1, NULL);
883 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
884 CHECK_CUR_POS(substream, 1);
885 CHECK_CUR_POS(stream, 1);
886 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
888 /* Write */
889 for (i = 0; i < 3; ++i)
890 buff[i] = data[i] + 1;
892 hr = IWICStream_Write(substream, buff, 3, &written);
893 ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr);
894 ok(written == 3, "Unexpected written length %lu.\n", written);
895 ok(!memcmp(buff, memory, 3), "Unexpected stream data.\n");
896 CHECK_CUR_POS(substream, written);
897 CHECK_CUR_POS(stream, written);
898 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
900 hr = IWICStream_Write(substream, buff, 0, &written);
901 ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr);
903 written = 0xdeadbeef;
904 hr = IWICStream_Write(substream, NULL, 3, &written);
905 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
906 ok(written == 0xdeadbeef, "Unexpected written length %lu.\n", written);
907 CHECK_CUR_POS(substream, 0);
908 CHECK_CUR_POS(stream, 0);
910 written = 0xdeadbeef;
911 hr = IWICStream_Write(substream, NULL, 0, &written);
912 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
913 ok(written == 0xdeadbeef, "Unexpected written length %lu.\n", written);
914 CHECK_CUR_POS(substream, 0);
915 CHECK_CUR_POS(stream, 0);
917 /* SetSize */
918 newpos.u.HighPart = 0;
919 newpos.u.LowPart = sizeof(memory) + 10;
920 hr = IWICStream_SetSize(substream, newpos);
921 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
923 newpos.u.HighPart = 0;
924 newpos.u.LowPart = sizeof(memory);
925 hr = IWICStream_SetSize(substream, newpos);
926 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
928 newpos.u.HighPart = 0;
929 newpos.u.LowPart = sizeof(memory) - 10;
930 hr = IWICStream_SetSize(substream, newpos);
931 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
933 newpos.QuadPart = 0;
934 hr = IWICStream_SetSize(substream, newpos);
935 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
937 newpos.QuadPart = -10;
938 hr = IWICStream_SetSize(substream, newpos);
939 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
941 /* CopyTo */
942 newpos.u.HighPart = 0;
943 newpos.u.LowPart = 30;
944 hr = IWICStream_CopyTo(substream, NULL, newpos, NULL, NULL);
945 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
947 hr = CreateStreamOnHGlobal(NULL, TRUE, &copy_stream);
948 ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr);
950 hr = IWICStream_CopyTo(substream, copy_stream, newpos, NULL, NULL);
951 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
952 IStream_Release(copy_stream);
954 /* Commit */
955 hr = IWICStream_Commit(substream, STGC_DEFAULT);
956 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
958 hr = IWICStream_Commit(substream, STGC_OVERWRITE);
959 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
961 hr = IWICStream_Commit(substream, STGC_ONLYIFCURRENT);
962 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
964 hr = IWICStream_Commit(substream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
965 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
967 hr = IWICStream_Commit(substream, STGC_CONSOLIDATE);
968 ok(broken(hr == E_NOTIMPL) || hr == S_OK, "Commit returned %#lx\n", hr);
970 /* Revert */
971 IWICStream_Write(substream, buff + 5, 6, NULL);
972 hr = IWICStream_Revert(substream);
973 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
974 memcpy(memory, data, sizeof(memory));
976 /* LockRegion/UnlockRegion */
977 hr = IWICStream_LockRegion(substream, uzero, uzero, 0);
978 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
980 hr = IWICStream_UnlockRegion(substream, uzero, uzero, 0);
981 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
983 /* Stat */
984 hr = IWICStream_Stat(substream, NULL, 0);
985 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
987 hr = IWICStream_Stat(substream, &stats, 0);
988 ok(hr == S_OK, "Failed to get stream stats, hr %#lx.\n", hr);
989 ok(stats.pwcsName == NULL, "Unexpected name %p.\n", stats.pwcsName);
990 ok(stats.type == STGTY_STREAM, "Unexpected type %ld.\n", stats.type);
991 ok(stats.cbSize.QuadPart == sizeof(data), "Unexpected size %s.\n", wine_dbgstr_longlong(stats.cbSize.QuadPart));
992 ok(stats.mtime.dwHighDateTime == 0 && stats.mtime.dwLowDateTime == 0, "Unexpected mtime (%lu;%lu).\n",
993 stats.mtime.dwHighDateTime, stats.mtime.dwLowDateTime);
994 ok(stats.ctime.dwHighDateTime == 0 && stats.ctime.dwLowDateTime == 0, "Unexpected ctime (%lu;%lu).\n",
995 stats.ctime.dwHighDateTime, stats.ctime.dwLowDateTime);
996 ok(stats.atime.dwHighDateTime == 0 && stats.atime.dwLowDateTime == 0, "Unexpected atime (%lu;%lu).\n",
997 stats.atime.dwHighDateTime, stats.atime.dwLowDateTime);
998 ok(stats.grfMode == 0, "Unexpected mode %ld.\n", stats.grfMode);
999 ok(stats.grfLocksSupported == 0, "Unexpected locks support %#lx.\n", stats.grfLocksSupported);
1000 ok(stats.grfStateBits == 0, "Unexpected state bits %#lx.\n", stats.grfStateBits);
1002 /* Clone */
1003 hr = IWICStream_Clone(substream, &copy_stream);
1004 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1006 IWICStream_Release(substream);
1007 IWICStream_Release(stream);
1008 IWICImagingFactory_Release(factory);
1011 START_TEST(stream)
1013 CoInitialize(NULL);
1015 test_StreamOnMemory();
1016 test_StreamOnStreamRange();
1017 test_StreamOnIStream();
1019 CoUninitialize();