1 /*
2 * Copyright 2009 Tony Wasserka
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "wine/test.h"
20
21 #define COBJMACROS
22 #include "wincodec.h"
23
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__)
_check_cur_pos(IStream * stream,ULONGLONG expected_pos,BOOL todo,unsigned int line)26 static void _check_cur_pos(IStream *stream, ULONGLONG expected_pos, BOOL todo, unsigned int line)
27 {
28 LARGE_INTEGER offset;
29 ULARGE_INTEGER pos;
30 HRESULT hr;
31
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 %#x.\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));
38 }
39
test_StreamOnMemory(void)40 static void test_StreamOnMemory(void)
41 {
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,
49 };
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,
55 };
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;
63
64 LargeNull.QuadPart = 0;
65 uLargeNull.QuadPart = 0;
66 SeekPos.QuadPart = 5;
67
68 memcpy(Memory, CmpMem, sizeof(CmpMem));
69
70 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
71 if(FAILED(hr)) {
72 skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
73 return;
74 }
75
76 hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
77 ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
78 if(FAILED(hr)) {
79 skip("Failed to create stream\n");
80 return;
81 }
82
83 /* InitializeFromMemory */
84 hr = IWICStream_InitializeFromMemory(pStream, NULL, sizeof(Memory)); /* memory = NULL */
85 ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#x, expected %#x\n", hr, E_INVALIDARG);
86
87 hr = IWICStream_InitializeFromMemory(pStream, Memory, 0); /* size = 0 */
88 ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
89
90 hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory)); /* stream already initialized */
91 ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#x, expected %#x\n", hr, WINCODEC_ERR_WRONGSTATE);
92
93 /* recreate stream */
94 IWICStream_Release(pStream);
95 hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
96 ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
97
98 hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
99 ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
100
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 %#x, expected %#x\n", hr, S_OK);
105 if(SUCCEEDED(hr)) {
106 ok(uBytesRead == sizeof(ZeroMem), "Read %u bytes\n", uBytesRead);
107 ok(memcmp(MemBuf, ZeroMem, sizeof(ZeroMem)) == 0, "Read returned invalid data!\n");
108 }
109
110 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
111
112 hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten);
113 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
114
115 /* Seek */
116 hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
117 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
118 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
119
120 hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
121 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
122
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 %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
129 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
130 CHECK_CUR_POS(pStream, 0);
131
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 %#x, expected %#x\n", hr, E_INVALIDARG);
137 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
138 CHECK_CUR_POS(pStream, 0);
139
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 %#x, expected %#x\n", hr, E_INVALIDARG);
145 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
146 CHECK_CUR_POS(pStream, 0);
147
148 LargeInt.QuadPart = -1;
149 hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
150 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
151 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
152
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 %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
160 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), 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);
163
164 /* Read */
165 hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead);
166 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
167 if(SUCCEEDED(hr)) {
168 ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 12);
169 ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n");
170
171 /* check whether the seek pointer has moved correctly */
172 CHECK_CUR_POS(pStream, uBytesRead);
173 }
174
175 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
176
177 hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source = dest */
178 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
179 if(SUCCEEDED(hr)) {
180 ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
181 ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
182 }
183
184 IWICStream_Seek(pStream, SeekPos, STREAM_SEEK_SET, NULL);
185
186 hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead); /* source and dest overlap */
187 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
188 if(SUCCEEDED(hr)) {
189 ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
190 ok(memcmp(Memory, CmpMemOverlap, uBytesRead) == 0, "Read returned invalid data!\n");
191 }
192
193 memcpy(Memory, CmpMem, sizeof(CmpMem));
194
195 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
196
197 hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead); /* request too many bytes */
198 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
199 if(SUCCEEDED(hr)) {
200 ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
201 ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
202 }
203
204 hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead); /* destination buffer = NULL */
205 ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
206
207 hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */
208 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
209
210 hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead);
211 ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
212
213 hr = IWICStream_Read(pStream, NULL, 0, NULL);
214 ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
215
216 hr = IWICStream_Read(pStream, MemBuf, 1, NULL);
217 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
218
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 %#x, expected %#x\n", hr, S_OK);
223 if(SUCCEEDED(hr)) {
224 ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
225 ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n");
226 }
227 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
228
229
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 %#x, expected %#x\n", hr, S_OK);
236 if(SUCCEEDED(hr)) {
237 ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
238 ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
239
240 /* check whether the seek pointer has moved correctly */
241 CHECK_CUR_POS(pStream, uBytesWritten);
242 }
243 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
244
245 hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten);
246 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
247
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 %#x, expected %#x\n", hr, S_OK);
251
252 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
253
254 /* Source and destination overlap. */
255 hr = IWICStream_Write(pStream, Memory + 5, 10, &uBytesWritten);
256 ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
257 if(SUCCEEDED(hr)) {
258 ok(uBytesWritten == 10, "Wrote %u bytes, expected %u\n", uBytesWritten, 10);
259 ok(memcmp(CmpMemOverlap, Memory, sizeof(CmpMemOverlap)) == 0, "Wrote returned invalid data!\n");
260 }
261
262 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
263
264 uBytesWritten = 0xdeadbeef;
265 hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten);
266 ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
267 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
268 CHECK_CUR_POS(pStream, 0);
269
270 uBytesWritten = 0xdeadbeef;
271 hr = IWICStream_Write(pStream, NULL, 0, &uBytesWritten);
272 ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
273 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
274 CHECK_CUR_POS(pStream, 0);
275
276 uBytesWritten = 0xdeadbeef;
277 hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten);
278 ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
279 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
280 CHECK_CUR_POS(pStream, 0);
281 IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
282
283
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 %#x, expected %#x\n", hr, E_NOTIMPL);
289
290 uNewPos.u.HighPart = 0;
291 uNewPos.u.LowPart = sizeof(Memory);
292 hr = IWICStream_SetSize(pStream, uNewPos);
293 ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
294
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 %#x, expected %#x\n", hr, E_NOTIMPL);
299
300 uNewPos.u.HighPart = 0;
301 uNewPos.u.LowPart = 0;
302 hr = IWICStream_SetSize(pStream, uNewPos);
303 ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
304
305 uNewPos.QuadPart = -10;
306 hr = IWICStream_SetSize(pStream, uNewPos);
307 ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
308
309
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 %#x, expected %#x\n", hr, E_NOTIMPL);
315
316 hr = IWICImagingFactory_CreateStream(pFactory, &pBufStream);
317 ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
318
319 hr = IWICStream_InitializeFromMemory(pBufStream, Memory, sizeof(Memory));
320 ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
321
322 hr = IWICStream_CopyTo(pStream, (IStream*)pBufStream, uNewPos, NULL, NULL);
323 ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
324 IWICStream_Release(pBufStream);
325
326
327 /* Commit */
328 hr = IWICStream_Commit(pStream, STGC_DEFAULT);
329 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
330
331 hr = IWICStream_Commit(pStream, STGC_OVERWRITE);
332 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
333
334 hr = IWICStream_Commit(pStream, STGC_ONLYIFCURRENT);
335 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
336
337 hr = IWICStream_Commit(pStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
338 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
339
340 hr = IWICStream_Commit(pStream, STGC_CONSOLIDATE);
341 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
342
343
344 /* Revert */
345 IWICStream_Write(pStream, &MemBuf[5], 6, NULL);
346 hr = IWICStream_Revert(pStream);
347 ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
348 memcpy(Memory, CmpMem, sizeof(Memory));
349
350
351 /* LockRegion/UnlockRegion */
352 hr = IWICStream_LockRegion(pStream, uLargeNull, uLargeNull, 0);
353 ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
354
355 hr = IWICStream_UnlockRegion(pStream, uLargeNull, uLargeNull, 0);
356 ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
357
358
359 /* Stat */
360 hr = IWICStream_Stat(pStream, NULL, 0);
361 ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
362
363 hr = IWICStream_Stat(pStream, &Stats, 0);
364 ok(hr == S_OK, "Stat returned %#x, expected %#x\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 %d, expected %d\n", Stats.type, STGTY_STREAM);
367 ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart);
368 ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), 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 (%u;%u), 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 (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0);
371 ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
372 ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
373 ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
374
375
376 /* Clone */
377 hr = IWICStream_Clone(pStream, (IStream**)&pBufStream);
378 ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
379
380
381 IWICStream_Release(pStream);
382 IWICImagingFactory_Release(pFactory);
383 }
384
test_StreamOnStreamRange(void)385 static void test_StreamOnStreamRange(void)
386 {
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,
395 };
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;
402
403 LargeNull.QuadPart = 0;
404 uLargeNull.QuadPart = 0;
405
406 memcpy(Memory, CmpMem, sizeof(CmpMem));
407
408 CoInitialize(NULL);
409
410 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
411 if(FAILED(hr)) {
412 skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
413 return;
414 }
415
416 hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
417 ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
418 if(FAILED(hr)) {
419 skip("Failed to create stream\n");
420 return;
421 }
422
423 hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
424 ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
425
426 hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
427 ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
428
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 %#x, expected %#x\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;
440 }
441
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 (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 20);
446 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
447 CHECK_CUR_POS(pStream, 0);
448
449 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
450 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
451 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
452 CHECK_CUR_POS(pStream, 0);
453
454 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
455 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
456
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 %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
463 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
464 CHECK_CUR_POS(pStream, 0);
465
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 %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
471 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
472 CHECK_CUR_POS(pStream, 0);
473
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 %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
479 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0xdeadbeef, 0xdeadbeef);
480 CHECK_CUR_POS(pStream, 0);
481
482 LargeInt.QuadPart = -1;
483 hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
484 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
485 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
486 CHECK_CUR_POS(pStream, 0);
487
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 %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
495 ok(uNewPos.u.HighPart == 0xdeadbeef && uNewPos.u.LowPart == 0xdeadbeef, "Seek cursor initialized to position (%u;%u), 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);
498
499
500 /* Read */
501 hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead);
502 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
503 if(SUCCEEDED(hr)) {
504 ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 12);
505 ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n");
506
507 /* check whether the seek pointer has moved correctly */
508 CHECK_CUR_POS(pSubStream, uBytesRead);
509 CHECK_CUR_POS(pStream, 0);
510 }
511
512 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
513
514 hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead); /* source = dest */
515 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
516 if(SUCCEEDED(hr)) {
517 ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
518 ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
519 }
520 CHECK_CUR_POS(pStream, 0);
521
522 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
523
524 hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead); /* request too many bytes */
525 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
526 if(SUCCEEDED(hr)) {
527 ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
528 ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
529 }
530 CHECK_CUR_POS(pStream, 0);
531
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 %#x, expected %#x\n", hr, E_INVALIDARG);
536 ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead);
537
538 hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead); /* read 0 bytes */
539 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
540
541 uBytesRead = 0xdeadbeef;
542 hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead);
543 ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
544 ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead);
545
546 hr = IWICStream_Read(pSubStream, NULL, 0, NULL);
547 ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
548
549 hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL);
550 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
551
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 %#x, expected %#x\n", hr, S_OK);
556 if(SUCCEEDED(hr)) {
557 ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
558 ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n");
559 }
560 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
561
562
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 %#x, expected %#x\n", hr, S_OK);
569 if(SUCCEEDED(hr)) {
570 ok(uBytesWritten == 3, "Wrote %u 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 */
572
573 /* check whether the seek pointer has moved correctly */
574 CHECK_CUR_POS(pSubStream, uBytesWritten);
575 CHECK_CUR_POS(pStream, 0);
576 }
577 IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
578
579 hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten);
580 ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
581
582 uBytesWritten = 0xdeadbeef;
583 hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten);
584 ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
585 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
586 CHECK_CUR_POS(pSubStream, 0);
587 CHECK_CUR_POS(pStream, 0);
588
589 uBytesWritten = 0xdeadbeef;
590 hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten);
591 ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
592 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
593 CHECK_CUR_POS(pSubStream, 0);
594 CHECK_CUR_POS(pStream, 0);
595
596 hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten);
597 ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
598 ok(uBytesWritten == 20, "Wrote %u 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);
602
603
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 %#x, expected %#x\n", hr, E_NOTIMPL);
609
610 uNewPos.u.HighPart = 0;
611 uNewPos.u.LowPart = sizeof(Memory);
612 hr = IWICStream_SetSize(pSubStream, uNewPos);
613 ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
614
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 %#x, expected %#x\n", hr, E_NOTIMPL);
619
620 uNewPos.u.HighPart = 0;
621 uNewPos.u.LowPart = 0;
622 hr = IWICStream_SetSize(pSubStream, uNewPos);
623 ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
624
625 uNewPos.QuadPart = -10;
626 hr = IWICStream_SetSize(pSubStream, uNewPos);
627 ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
628
629
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 %#x, expected %#x\n", hr, E_NOTIMPL);
635
636 hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream);
637 ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
638
639 hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL);
640 ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
641 IStream_Release(CopyStream);
642
643
644 /* Commit */
645 hr = IWICStream_Commit(pSubStream, STGC_DEFAULT);
646 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
647
648 hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE);
649 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
650
651 hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT);
652 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
653
654 hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
655 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
656
657 hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE);
658 ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
659
660
661 /* Revert */
662 IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL);
663 hr = IWICStream_Revert(pSubStream);
664 ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
665 memcpy(Memory, CmpMem, sizeof(Memory));
666
667
668 /* LockRegion/UnlockRegion */
669 hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0);
670 ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
671
672 hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0);
673 ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
674
675
676 /* Stat */
677 hr = IWICStream_Stat(pSubStream, NULL, 0);
678 ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
679
680 hr = IWICStream_Stat(pSubStream, &Stats, 0);
681 ok(hr == S_OK, "Stat returned %#x, expected %#x\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 %d, expected %d\n", Stats.type, STGTY_STREAM);
684 ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart);
685 ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), 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 (%u;%u), 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 (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0);
688 ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
689 ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
690 ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
691
692
693 /* Clone */
694 hr = IWICStream_Clone(pSubStream, &CopyStream);
695 ok(hr == E_NOTIMPL, "Clone returned %#x, expected %#x\n", hr, E_NOTIMPL);
696
697
698 IWICStream_Release(pSubStream);
699
700
701 /* Recreate, this time larger than the original. */
702 hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
703 ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
704
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 %#x, expected %#x\n", hr, S_OK);
709
710 hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
711 ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
712 ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 16);
713
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 %#x, expected %#x\n", hr, S_OK);
717 if(SUCCEEDED(hr)) {
718 ok(uBytesRead == 16, "Read %u bytes\n", uBytesRead);
719 ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n");
720 }
721
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 %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
726 ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
727 CHECK_CUR_POS(pSubStream, 0);
728 CHECK_CUR_POS(pStream, 0);
729
730 IWICStream_Release(pSubStream);
731 IWICStream_Release(pStream);
732 IWICImagingFactory_Release(pFactory);
733 CoUninitialize();
734 }
735
test_StreamOnIStream(void)736 static void test_StreamOnIStream(void)
737 {
738 static const BYTE data[] =
739 {
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,
744 };
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;
757
758 memcpy(memory, data, sizeof(data));
759
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 %#x.\n", hr);
763
764 hr = IWICImagingFactory_CreateStream(factory, &stream);
765 ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr);
766
767 hr = IWICStream_InitializeFromMemory(stream, memory, sizeof(memory));
768 ok(hr == S_OK, "Failed to initialize stream, hr %#x.\n", hr);
769
770 hr = IWICImagingFactory_CreateStream(factory, &substream);
771 ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr);
772
773 pos.QuadPart = 1;
774 hr = IWICStream_Seek(stream, pos, STREAM_SEEK_SET, &newpos);
775 ok(hr == S_OK, "Failed to set position, hr %#x.\n", hr);
776 CHECK_CUR_POS(stream, 1);
777
778 hr = IWICStream_InitializeFromIStream(substream, (IStream *)stream);
779 ok(hr == S_OK, "Failed to initialize stream, hr %#x.\n", hr);
780 CHECK_CUR_POS(substream, 1);
781
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 %#x.\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));
789
790 hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, &newpos);
791 ok(hr == S_OK, "Failed to seek a stream, hr %#x.\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);
795
796 hr = IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
797 ok(hr == S_OK, "Failed to seek a stream, hr %#x.\n", hr);
798
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 %#x.\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);
809
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 %#x.\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);
819
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 %#x.\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);
829
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 %#x.\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);
836
837 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
838
839 /* Read */
840 hr = IWICStream_Read(substream, buff, 12, &read_len);
841 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
842 ok(read_len == 12, "Unexpected read length %u.\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);
846
847 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
848 CHECK_CUR_POS(stream, 0);
849
850 hr = IWICStream_Read(substream, memory, 10, &read_len); /* source = dest */
851 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
852 ok(read_len == 10, "Unexpected read length %u.\n", read_len);
853 ok(!memcmp(memory, data, read_len), "Unexpected data.\n");
854 CHECK_CUR_POS(stream, 10);
855
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 %#x.\n", hr);
859 ok(read_len == 64, "Unexpected read length %u.\n", read_len);
860 ok(!memcmp(memory, data, read_len), "Unexpected data.\n");
861 CHECK_CUR_POS(stream, sizeof(data));
862
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 %#x.\n", hr);
867 ok(read_len == 0xdeadbeef, "Unexpected read length %u.\n", read_len);
868
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 %#x.\n", hr);
872 ok(read_len == 0, "Unexpected read length %u.\n", read_len);
873
874 read_len = 0xdeadbeef;
875 hr = IWICStream_Read(substream, NULL, 0, &read_len);
876 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
877 ok(read_len == 0xdeadbeef, "Unexpected read length %u.\n", read_len);
878
879 hr = IWICStream_Read(substream, NULL, 0, NULL);
880 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
881
882 hr = IWICStream_Read(substream, buff, 1, NULL);
883 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
884 CHECK_CUR_POS(substream, 1);
885 CHECK_CUR_POS(stream, 1);
886 IWICStream_Seek(substream, zero_pos, STREAM_SEEK_SET, NULL);
887
888 /* Write */
889 for (i = 0; i < 3; ++i)
890 buff[i] = data[i] + 1;
891
892 hr = IWICStream_Write(substream, buff, 3, &written);
893 ok(hr == S_OK, "Failed to write to stream, hr %#x.\n", hr);
894 ok(written == 3, "Unexpected written length %u.\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);
899
900 hr = IWICStream_Write(substream, buff, 0, &written);
901 ok(hr == S_OK, "Failed to write to stream, hr %#x.\n", hr);
902
903 written = 0xdeadbeef;
904 hr = IWICStream_Write(substream, NULL, 3, &written);
905 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
906 ok(written == 0xdeadbeef, "Unexpected written length %u.\n", written);
907 CHECK_CUR_POS(substream, 0);
908 CHECK_CUR_POS(stream, 0);
909
910 written = 0xdeadbeef;
911 hr = IWICStream_Write(substream, NULL, 0, &written);
912 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
913 ok(written == 0xdeadbeef, "Unexpected written length %u.\n", written);
914 CHECK_CUR_POS(substream, 0);
915 CHECK_CUR_POS(stream, 0);
916
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 %#x.\n", hr);
922
923 newpos.u.HighPart = 0;
924 newpos.u.LowPart = sizeof(memory);
925 hr = IWICStream_SetSize(substream, newpos);
926 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
927
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 %#x.\n", hr);
932
933 newpos.QuadPart = 0;
934 hr = IWICStream_SetSize(substream, newpos);
935 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
936
937 newpos.QuadPart = -10;
938 hr = IWICStream_SetSize(substream, newpos);
939 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
940
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 %#x.\n", hr);
946
947 hr = CreateStreamOnHGlobal(NULL, TRUE, ©_stream);
948 ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr);
949
950 hr = IWICStream_CopyTo(substream, copy_stream, newpos, NULL, NULL);
951 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
952 IStream_Release(copy_stream);
953
954 /* Commit */
955 hr = IWICStream_Commit(substream, STGC_DEFAULT);
956 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
957
958 hr = IWICStream_Commit(substream, STGC_OVERWRITE);
959 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
960
961 hr = IWICStream_Commit(substream, STGC_ONLYIFCURRENT);
962 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
963
964 hr = IWICStream_Commit(substream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
965 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
966
967 hr = IWICStream_Commit(substream, STGC_CONSOLIDATE);
968 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
969
970 /* Revert */
971 IWICStream_Write(substream, buff + 5, 6, NULL);
972 hr = IWICStream_Revert(substream);
973 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
974 memcpy(memory, data, sizeof(memory));
975
976 /* LockRegion/UnlockRegion */
977 hr = IWICStream_LockRegion(substream, uzero, uzero, 0);
978 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
979
980 hr = IWICStream_UnlockRegion(substream, uzero, uzero, 0);
981 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
982
983 /* Stat */
984 hr = IWICStream_Stat(substream, NULL, 0);
985 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
986
987 hr = IWICStream_Stat(substream, &stats, 0);
988 ok(hr == S_OK, "Failed to get stream stats, hr %#x.\n", hr);
989 ok(stats.pwcsName == NULL, "Unexpected name %p.\n", stats.pwcsName);
990 ok(stats.type == STGTY_STREAM, "Unexpected type %d.\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 (%u;%u).\n",
993 stats.mtime.dwHighDateTime, stats.mtime.dwLowDateTime);
994 ok(stats.ctime.dwHighDateTime == 0 && stats.ctime.dwLowDateTime == 0, "Unexpected ctime (%u;%u).\n",
995 stats.ctime.dwHighDateTime, stats.ctime.dwLowDateTime);
996 ok(stats.atime.dwHighDateTime == 0 && stats.atime.dwLowDateTime == 0, "Unexpected atime (%u;%u).\n",
997 stats.atime.dwHighDateTime, stats.atime.dwLowDateTime);
998 ok(stats.grfMode == 0, "Unexpected mode %d.\n", stats.grfMode);
999 ok(stats.grfLocksSupported == 0, "Unexpected locks support %#x.\n", stats.grfLocksSupported);
1000 ok(stats.grfStateBits == 0, "Unexpected state bits %#x.\n", stats.grfStateBits);
1001
1002 /* Clone */
1003 hr = IWICStream_Clone(substream, ©_stream);
1004 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
1005
1006 IWICStream_Release(substream);
1007 IWICStream_Release(stream);
1008 IWICImagingFactory_Release(factory);
1009 }
1010
START_TEST(stream)1011 START_TEST(stream)
1012 {
1013 CoInitialize(NULL);
1014
1015 test_StreamOnMemory();
1016 test_StreamOnStreamRange();
1017 test_StreamOnIStream();
1018
1019 CoUninitialize();
1020 }
1021