gdi32: Add a flag to request a default color table from init_dib_info.
[wine] / dlls / windowscodecs / tests / stream.c
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 static void test_StreamOnMemory(void)
25 {
26     IWICImagingFactory *pFactory;
27     IWICStream *pStream, *pBufStream;
28     const BYTE CmpMem[] = {
29         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
30         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
31         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
32         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
33     };
34     const BYTE CmpMemOverlap[] = {
35         0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
36         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
37         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
38         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
39     };
40     const BYTE ZeroMem[10] = {0};
41     BYTE Memory[64], MemBuf[64];
42     LARGE_INTEGER LargeNull, LargeInt, SeekPos;
43     ULARGE_INTEGER uLargeNull, uNewPos;
44     ULONG uBytesRead, uBytesWritten;
45     HRESULT hr;
46     STATSTG Stats;
47
48     LargeNull.QuadPart = 0;
49     uLargeNull.QuadPart = 0;
50     SeekPos.QuadPart = 5;
51
52     memcpy(Memory, CmpMem, sizeof(CmpMem));
53
54     CoInitialize(NULL);
55
56     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
57     if(FAILED(hr)) {
58         skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
59         return;
60     }
61
62     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
63     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
64     if(FAILED(hr)) {
65         skip("Failed to create stream\n");
66         return;
67     }
68
69     /* InitializeFromMemory */
70     hr = IWICStream_InitializeFromMemory(pStream, NULL, sizeof(Memory));   /* memory = NULL */
71     ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#x, expected %#x\n", hr, E_INVALIDARG);
72
73     hr = IWICStream_InitializeFromMemory(pStream, Memory, 0);   /* size = 0 */
74     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
75
76     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));   /* stream already initialized */
77     ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#x, expected %#x\n", hr, WINCODEC_ERR_WRONGSTATE);
78
79     /* recreate stream */
80     IWICStream_Release(pStream);
81     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
82     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
83
84     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
85     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
86
87     /* IWICStream does not maintain an independent copy of the backing memory buffer. */
88     memcpy(Memory, ZeroMem, sizeof(ZeroMem));
89     hr = IWICStream_Read(pStream, MemBuf, sizeof(ZeroMem), &uBytesRead);
90     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
91     if(SUCCEEDED(hr)) {
92         ok(uBytesRead == sizeof(ZeroMem), "Read %u bytes\n", uBytesRead);
93         ok(memcmp(MemBuf, ZeroMem, sizeof(ZeroMem)) == 0, "Read returned invalid data!\n");
94     }
95
96     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
97
98     hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten);
99     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
100
101     /* Seek */
102     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
103     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
104     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);
105
106     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
107     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
108
109     LargeInt.u.HighPart = 1;
110     LargeInt.u.LowPart = 0;
111     uNewPos.u.HighPart = 0xdeadbeef;
112     uNewPos.u.LowPart = 0xdeadbeef;
113     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
114     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
115     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);
116     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &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     LargeInt.QuadPart = sizeof(Memory) + 10;
121     uNewPos.u.HighPart = 0xdeadbeef;
122     uNewPos.u.LowPart = 0xdeadbeef;
123     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
124     ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG);
125     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);
126     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
127     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
128     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);
129
130     LargeInt.QuadPart = 1;
131     uNewPos.u.HighPart = 0xdeadbeef;
132     uNewPos.u.LowPart = 0xdeadbeef;
133     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
134     ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG);
135     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);
136     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
137     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
138     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);
139
140     LargeInt.QuadPart = -1;
141     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
142     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
143     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);
144
145     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
146     LargeInt.QuadPart = -(LONGLONG)sizeof(Memory) - 5;
147     uNewPos.u.HighPart = 0xdeadbeef;
148     uNewPos.u.LowPart = 0xdeadbeef;
149     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
150     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW),
151        "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
152     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);
153     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
154     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
155     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); /* remains unchanged */
156     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
157
158
159     /* Read */
160     hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead);
161     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
162     if(SUCCEEDED(hr)) {
163         ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 3);
164         ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n");
165
166         /* check whether the seek pointer has moved correctly */
167         IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
168         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesRead, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesRead);
169     }
170
171     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
172
173     hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead);   /* source = dest */
174     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
175     if(SUCCEEDED(hr)) {
176         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
177         ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
178     }
179
180     IWICStream_Seek(pStream, SeekPos, STREAM_SEEK_SET, NULL);
181
182     hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead);   /* source and dest overlap */
183     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
184     if(SUCCEEDED(hr)) {
185         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
186         ok(memcmp(Memory, CmpMemOverlap, uBytesRead) == 0, "Read returned invalid data!\n");
187     }
188
189     memcpy(Memory, CmpMem, sizeof(CmpMem));
190
191     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
192
193     hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead);   /* request too many bytes */
194     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
195     if(SUCCEEDED(hr)) {
196         ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
197         ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
198     }
199
200     hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead);    /* destination buffer = NULL */
201     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
202
203     hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead);    /* read 0 bytes */
204     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
205
206     hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead);
207     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
208
209     hr = IWICStream_Read(pStream, NULL, 0, NULL);
210     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
211
212     hr = IWICStream_Read(pStream, MemBuf, 1, NULL);
213     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
214
215     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
216     ZeroMemory(MemBuf, sizeof(MemBuf));
217     hr = IWICStream_Read(pStream, MemBuf, sizeof(Memory) + 10, &uBytesRead);
218     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
219     if(SUCCEEDED(hr)) {
220         ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
221         ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n");
222     }
223     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
224
225
226     /* Write */
227     MemBuf[0] = CmpMem[0] + 1;
228     MemBuf[1] = CmpMem[1] + 1;
229     MemBuf[2] = CmpMem[2] + 1;
230     hr = IWICStream_Write(pStream, MemBuf, 3, &uBytesWritten);
231     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
232     if(SUCCEEDED(hr)) {
233         ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
234         ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
235
236         /* check whether the seek pointer has moved correctly */
237         IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
238         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
239     }
240     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
241
242     hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten);
243     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
244
245     /* Restore the original contents of the memory stream. */
246     hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten);
247     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
248
249     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
250
251     /* Source and destination overlap. */
252     hr = IWICStream_Write(pStream, Memory + 5, 10, &uBytesWritten);
253     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
254     if(SUCCEEDED(hr)) {
255         ok(uBytesWritten == 10, "Wrote %u bytes, expected %u\n", uBytesWritten, 10);
256         ok(memcmp(CmpMemOverlap, Memory, sizeof(CmpMemOverlap)) == 0, "Wrote returned invalid data!\n");
257     }
258
259     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
260
261     uBytesWritten = 0xdeadbeef;
262     hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten);
263     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
264     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
265     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
266     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);
267
268     uBytesWritten = 0xdeadbeef;
269     hr = IWICStream_Write(pStream, NULL, 0, &uBytesWritten);
270     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
271     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
272     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
273     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);
274
275     uBytesWritten = 0xdeadbeef;
276     hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten);
277     ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
278     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
279     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
280     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);
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     IWICStream_Release(pFactory);
383     CoUninitialize();
384 }
385
386 static void test_StreamOnStreamRange(void)
387 {
388     IWICImagingFactory *pFactory;
389     IWICStream *pStream, *pSubStream;
390     IStream *CopyStream;
391     const BYTE CmpMem[] = {
392         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
393         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
394         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
395         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
396     };
397     BYTE Memory[64], MemBuf[64];
398     LARGE_INTEGER LargeNull, LargeInt;
399     ULARGE_INTEGER uLargeNull, uNewPos, uSize;
400     ULONG uBytesRead, uBytesWritten;
401     HRESULT hr;
402     STATSTG Stats;
403
404     LargeNull.QuadPart = 0;
405     uLargeNull.QuadPart = 0;
406
407     memcpy(Memory, CmpMem, sizeof(CmpMem));
408
409     CoInitialize(NULL);
410
411     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
412     if(FAILED(hr)) {
413         skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
414         return;
415     }
416
417     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
418     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
419     if(FAILED(hr)) {
420         skip("Failed to create stream\n");
421         return;
422     }
423
424     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
425     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
426
427     hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
428     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
429
430     uNewPos.QuadPart = 20;
431     uSize.QuadPart = 20;
432     hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
433     ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#x, expected %#x\n", hr, S_OK);
434     if(FAILED(hr)) {
435         skip("InitializeFromIStreamRegion unimplemented\n");
436         IWICStream_Release(pSubStream);
437         IWICStream_Release(pStream);
438         IWICImagingFactory_Release(pFactory);
439         CoUninitialize();
440         return;
441     }
442
443     /* Seek */
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
448     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
449     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
450     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);
451
452     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
453     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
454
455     LargeInt.u.HighPart = 1;
456     LargeInt.u.LowPart = 0;
457     uNewPos.u.HighPart = 0xdeadbeef;
458     uNewPos.u.LowPart = 0xdeadbeef;
459     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
460     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
461     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);
462     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
463     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
464     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);
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     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
473     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
474     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);
475
476     LargeInt.QuadPart = 1;
477     uNewPos.u.HighPart = 0xdeadbeef;
478     uNewPos.u.LowPart = 0xdeadbeef;
479     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
480     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
481     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);
482     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
483     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
484     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);
485
486     LargeInt.QuadPart = -1;
487     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
488     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
489     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
490
491     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
492     LargeInt.QuadPart = -25;
493     uNewPos.u.HighPart = 0xdeadbeef;
494     uNewPos.u.LowPart = 0xdeadbeef;
495     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
496     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
497        "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
498     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);
499     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
500     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
501     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); /* remains unchanged */
502     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
503
504
505     /* Read */
506     hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead);
507     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
508     if(SUCCEEDED(hr)) {
509         ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 3);
510         ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n");
511
512         /* check whether the seek pointer has moved correctly */
513         IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
514         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesRead, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesRead);
515     }
516
517     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
518
519     hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead);   /* source = dest */
520     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
521     if(SUCCEEDED(hr)) {
522         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
523         ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
524     }
525
526     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
527
528     hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead);   /* request too many bytes */
529     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
530     if(SUCCEEDED(hr)) {
531         ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
532         ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
533     }
534
535     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
536     uBytesRead = 0xdeadbeef;
537     hr = IWICStream_Read(pSubStream, NULL, 1, &uBytesRead);    /* destination buffer = NULL */
538     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
539     ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead);
540
541     hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead);    /* read 0 bytes */
542     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
543
544     uBytesRead = 0xdeadbeef;
545     hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead);
546     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
547     ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead);
548
549     hr = IWICStream_Read(pSubStream, NULL, 0, NULL);
550     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
551
552     hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL);
553     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
554
555     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
556     ZeroMemory(MemBuf, sizeof(MemBuf));
557     hr = IWICStream_Read(pSubStream, MemBuf, 30, &uBytesRead);
558     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
559     if(SUCCEEDED(hr)) {
560         ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
561         ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n");
562     }
563     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
564
565
566     /* Write */
567     MemBuf[0] = CmpMem[0] + 1;
568     MemBuf[1] = CmpMem[1] + 1;
569     MemBuf[2] = CmpMem[2] + 1;
570     hr = IWICStream_Write(pSubStream, MemBuf, 3, &uBytesWritten);
571     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
572     if(SUCCEEDED(hr)) {
573         ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
574         ok(memcmp(MemBuf, Memory+20, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
575
576         /* check whether the seek pointer has moved correctly */
577         IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
578         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
579     }
580     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
581
582     hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten);
583     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
584
585     uBytesWritten = 0xdeadbeef;
586     hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten);
587     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
588     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
589     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
590     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);
591
592     uBytesWritten = 0xdeadbeef;
593     hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten);
594     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
595     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
596     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
597     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);
598
599     hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten);
600     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
601     ok(uBytesWritten == 20, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
602     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
603     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
604     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
605
606
607     /* SetSize */
608     uNewPos.u.HighPart = 0;
609     uNewPos.u.LowPart = sizeof(Memory) + 10;
610     hr = IWICStream_SetSize(pSubStream, uNewPos);
611     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
612
613     uNewPos.u.HighPart = 0;
614     uNewPos.u.LowPart = sizeof(Memory);
615     hr = IWICStream_SetSize(pSubStream, uNewPos);
616     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
617
618     uNewPos.u.HighPart = 0;
619     uNewPos.u.LowPart = sizeof(Memory) - 10;
620     hr = IWICStream_SetSize(pSubStream, uNewPos);
621     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
622
623     uNewPos.u.HighPart = 0;
624     uNewPos.u.LowPart = 0;
625     hr = IWICStream_SetSize(pSubStream, uNewPos);
626     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
627
628     uNewPos.QuadPart = -10;
629     hr = IWICStream_SetSize(pSubStream, uNewPos);
630     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
631
632
633     /* CopyTo */
634     uNewPos.u.HighPart = 0;
635     uNewPos.u.LowPart = 30;
636     hr = IWICStream_CopyTo(pSubStream, NULL, uNewPos, NULL, NULL);
637     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
638
639     hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream);
640     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
641
642     hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL);
643     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
644     IWICStream_Release(CopyStream);
645
646
647     /* Commit */
648     hr = IWICStream_Commit(pSubStream, STGC_DEFAULT);
649     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
650
651     hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE);
652     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
653
654     hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT);
655     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
656
657     hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
658     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
659
660     hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE);
661     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
662
663
664     /* Revert */
665     IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL);
666     hr = IWICStream_Revert(pSubStream);
667     ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
668     memcpy(Memory, CmpMem, sizeof(Memory));
669
670
671     /* LockRegion/UnlockRegion */
672     hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0);
673     ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
674
675     hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0);
676     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
677
678
679     /* Stat */
680     hr = IWICStream_Stat(pSubStream, NULL, 0);
681     ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
682
683     hr = IWICStream_Stat(pSubStream, &Stats, 0);
684     ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK);
685     ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
686     ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM);
687     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);
688     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);
689     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);
690     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);
691     ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
692     ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
693     ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
694
695
696     /* Clone */
697     hr = IWICStream_Clone(pSubStream, &CopyStream);
698     ok(hr == E_NOTIMPL, "Clone returned %#x, expected %#x\n", hr, E_NOTIMPL);
699
700
701     IWICStream_Release(pSubStream);
702
703
704     /* Recreate, this time larger than the original. */
705     hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
706     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
707
708     uNewPos.QuadPart = 48;
709     uSize.QuadPart = 32;
710     hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
711     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
712
713     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
714     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
715     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);
716
717     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
718     hr = IWICStream_Read(pSubStream, Memory, 48, &uBytesRead);
719     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
720     if(SUCCEEDED(hr)) {
721         ok(uBytesRead == 16, "Read %u bytes\n", uBytesRead);
722         ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n");
723     }
724
725     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
726     uBytesWritten = 0xdeadbeef;
727     hr = IWICStream_Write(pSubStream, CmpMem, 32, &uBytesWritten);
728     ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
729     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
730     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
731     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);
732
733
734     IWICStream_Release(pSubStream);
735     IWICStream_Release(pStream);
736     IWICStream_Release(pFactory);
737     CoUninitialize();
738 }
739
740 START_TEST(stream)
741 {
742     test_StreamOnMemory();
743     test_StreamOnStreamRange();
744 }