mshtml: Added IHTMLWindow2::focus implementation.
[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(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);
118
119     LargeInt.QuadPart = sizeof(Memory) + 10;
120     uNewPos.u.HighPart = 0xdeadbeef;
121     uNewPos.u.LowPart = 0xdeadbeef;
122     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
123     ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG);
124     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);
125     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
126     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);
127
128     LargeInt.QuadPart = 1;
129     uNewPos.u.HighPart = 0xdeadbeef;
130     uNewPos.u.LowPart = 0xdeadbeef;
131     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
132     ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG);
133     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);
134     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
135     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);
136
137     LargeInt.QuadPart = -1;
138     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
139     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
140     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);
141
142     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
143     LargeInt.QuadPart = -(LONGLONG)sizeof(Memory) - 5;
144     uNewPos.u.HighPart = 0xdeadbeef;
145     uNewPos.u.LowPart = 0xdeadbeef;
146     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
147     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW),
148        "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
149     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);
150     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
151     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 */
152     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
153
154
155     /* Read */
156     hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead);
157     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
158     if(SUCCEEDED(hr)) {
159         ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 3);
160         ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n");
161
162         /* check whether the seek pointer has moved correctly */
163         IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
164         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);
165     }
166
167     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
168
169     hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead);   /* source = dest */
170     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
171     if(SUCCEEDED(hr)) {
172         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
173         ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
174     }
175
176     IWICStream_Seek(pStream, SeekPos, STREAM_SEEK_SET, NULL);
177
178     hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead);   /* source and dest overlap */
179     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
180     if(SUCCEEDED(hr)) {
181         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
182         ok(memcmp(Memory, CmpMemOverlap, uBytesRead) == 0, "Read returned invalid data!\n");
183     }
184
185     memcpy(Memory, CmpMem, sizeof(CmpMem));
186
187     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
188
189     hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead);   /* request too many bytes */
190     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
191     if(SUCCEEDED(hr)) {
192         ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
193         ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
194     }
195
196     hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead);    /* destination buffer = NULL */
197     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
198
199     hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead);    /* read 0 bytes */
200     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
201
202     hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead);
203     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
204
205     hr = IWICStream_Read(pStream, NULL, 0, NULL);
206     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
207
208     hr = IWICStream_Read(pStream, MemBuf, 1, NULL);
209     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
210
211     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
212     ZeroMemory(MemBuf, sizeof(MemBuf));
213     hr = IWICStream_Read(pStream, MemBuf, sizeof(Memory) + 10, &uBytesRead);
214     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
215     if(SUCCEEDED(hr)) {
216         ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
217         ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n");
218     }
219     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
220
221
222     /* Write */
223     MemBuf[0] = CmpMem[0] + 1;
224     MemBuf[1] = CmpMem[1] + 1;
225     MemBuf[2] = CmpMem[2] + 1;
226     hr = IWICStream_Write(pStream, MemBuf, 3, &uBytesWritten);
227     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
228     if(SUCCEEDED(hr)) {
229         ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
230         ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
231
232         /* check whether the seek pointer has moved correctly */
233         IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
234         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);
235     }
236     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
237
238     hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten);
239     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
240
241     /* Restore the original contents of the memory stream. */
242     hr = IWICStream_Write(pStream, CmpMem, sizeof(CmpMem), &uBytesWritten);
243     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
244
245     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
246
247     /* Source and destination overlap. */
248     hr = IWICStream_Write(pStream, Memory + 5, 10, &uBytesWritten);
249     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
250     if(SUCCEEDED(hr)) {
251         ok(uBytesWritten == 10, "Wrote %u bytes, expected %u\n", uBytesWritten, 10);
252         ok(memcmp(CmpMemOverlap, Memory, sizeof(CmpMemOverlap)) == 0, "Wrote returned invalid data!\n");
253     }
254
255     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
256
257     uBytesWritten = 0xdeadbeef;
258     hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten);
259     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
260     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
261     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
262     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);
263
264     uBytesWritten = 0xdeadbeef;
265     hr = IWICStream_Write(pStream, NULL, 0, &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     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
269     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);
270
271     uBytesWritten = 0xdeadbeef;
272     hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten);
273     ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
274     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
275     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
276     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);
277     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
278
279
280     /* SetSize */
281     uNewPos.u.HighPart = 0;
282     uNewPos.u.LowPart = sizeof(Memory) + 10;
283     hr = IWICStream_SetSize(pStream, uNewPos);
284     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
285
286     uNewPos.u.HighPart = 0;
287     uNewPos.u.LowPart = sizeof(Memory);
288     hr = IWICStream_SetSize(pStream, uNewPos);
289     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
290
291     uNewPos.u.HighPart = 0;
292     uNewPos.u.LowPart = sizeof(Memory) - 10;
293     hr = IWICStream_SetSize(pStream, uNewPos);
294     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
295
296     uNewPos.u.HighPart = 0;
297     uNewPos.u.LowPart = 0;
298     hr = IWICStream_SetSize(pStream, uNewPos);
299     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
300
301     uNewPos.QuadPart = -10;
302     hr = IWICStream_SetSize(pStream, uNewPos);
303     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
304
305
306     /* CopyTo */
307     uNewPos.u.HighPart = 0;
308     uNewPos.u.LowPart = 5;
309     hr = IWICStream_CopyTo(pStream, NULL, uNewPos, NULL, NULL);
310     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
311
312     hr = IWICImagingFactory_CreateStream(pFactory, &pBufStream);
313     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
314
315     hr = IWICStream_InitializeFromMemory(pBufStream, Memory, sizeof(Memory));
316     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
317
318     hr = IWICStream_CopyTo(pStream, (IStream*)pBufStream, uNewPos, NULL, NULL);
319     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
320     IWICStream_Release(pBufStream);
321
322
323     /* Commit */
324     hr = IWICStream_Commit(pStream, STGC_DEFAULT);
325     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
326
327     hr = IWICStream_Commit(pStream, STGC_OVERWRITE);
328     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
329
330     hr = IWICStream_Commit(pStream, STGC_ONLYIFCURRENT);
331     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
332
333     hr = IWICStream_Commit(pStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
334     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
335
336     hr = IWICStream_Commit(pStream, STGC_CONSOLIDATE);
337     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
338
339
340     /* Revert */
341     IWICStream_Write(pStream, &MemBuf[5], 6, NULL);
342     hr = IWICStream_Revert(pStream);
343     ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
344     memcpy(Memory, CmpMem, sizeof(Memory));
345
346
347     /* LockRegion/UnlockRegion */
348     hr = IWICStream_LockRegion(pStream, uLargeNull, uLargeNull, 0);
349     ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
350
351     hr = IWICStream_UnlockRegion(pStream, uLargeNull, uLargeNull, 0);
352     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
353
354
355     /* Stat */
356     hr = IWICStream_Stat(pStream, NULL, 0);
357     ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
358
359     hr = IWICStream_Stat(pStream, &Stats, 0);
360     ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK);
361     ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
362     ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM);
363     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);
364     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);
365     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);
366     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);
367     ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
368     ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
369     ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
370
371
372     /* Clone */
373     hr = IWICStream_Clone(pStream, (IStream**)&pBufStream);
374     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
375
376
377     IWICStream_Release(pStream);
378     IWICStream_Release(pFactory);
379     CoUninitialize();
380 }
381
382 static void test_StreamOnStreamRange(void)
383 {
384     IWICImagingFactory *pFactory;
385     IWICStream *pStream, *pSubStream;
386     IStream *CopyStream;
387     const BYTE CmpMem[] = {
388         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
389         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
390         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
391         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
392     };
393     BYTE Memory[64], MemBuf[64];
394     LARGE_INTEGER LargeNull, LargeInt;
395     ULARGE_INTEGER uLargeNull, uNewPos, uSize;
396     ULONG uBytesRead, uBytesWritten;
397     HRESULT hr;
398     STATSTG Stats;
399
400     LargeNull.QuadPart = 0;
401     uLargeNull.QuadPart = 0;
402
403     memcpy(Memory, CmpMem, sizeof(CmpMem));
404
405     CoInitialize(NULL);
406
407     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
408     if(FAILED(hr)) {
409         skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
410         return;
411     }
412
413     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
414     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
415     if(FAILED(hr)) {
416         skip("Failed to create stream\n");
417         return;
418     }
419
420     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
421     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
422
423     hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
424     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
425
426     uNewPos.QuadPart = 20;
427     uSize.QuadPart = 20;
428     hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
429     ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#x, expected %#x\n", hr, S_OK);
430     if(FAILED(hr)) {
431         skip("InitializeFromIStreamRegion unimplemented\n");
432         IWICStream_Release(pSubStream);
433         IWICStream_Release(pStream);
434         IWICImagingFactory_Release(pFactory);
435         CoUninitialize();
436         return;
437     }
438
439     /* Seek */
440     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
441     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, uBytesWritten);
442     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
443
444     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
445     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
446     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);
447
448     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
449     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
450
451     LargeInt.u.HighPart = 1;
452     LargeInt.u.LowPart = 0;
453     uNewPos.u.HighPart = 0xdeadbeef;
454     uNewPos.u.LowPart = 0xdeadbeef;
455     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
456     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
457     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);
458     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
459     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);
460
461     LargeInt.QuadPart = 30;
462     uNewPos.u.HighPart = 0xdeadbeef;
463     uNewPos.u.LowPart = 0xdeadbeef;
464     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
465     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
466     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);
467     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
468     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);
469
470     LargeInt.QuadPart = 1;
471     uNewPos.u.HighPart = 0xdeadbeef;
472     uNewPos.u.LowPart = 0xdeadbeef;
473     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
474     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
475     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);
476     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
477     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);
478
479     LargeInt.QuadPart = -1;
480     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
481     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
482     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
483
484     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
485     LargeInt.QuadPart = -25;
486     uNewPos.u.HighPart = 0xdeadbeef;
487     uNewPos.u.LowPart = 0xdeadbeef;
488     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
489     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
490        "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
491     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);
492     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
493     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 */
494     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
495
496
497     /* Read */
498     hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead);
499     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
500     if(SUCCEEDED(hr)) {
501         ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 3);
502         ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n");
503
504         /* check whether the seek pointer has moved correctly */
505         IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
506         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);
507     }
508
509     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
510
511     hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead);   /* source = dest */
512     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
513     if(SUCCEEDED(hr)) {
514         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
515         ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
516     }
517
518     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
519
520     hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead);   /* request too many bytes */
521     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
522     if(SUCCEEDED(hr)) {
523         ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
524         ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
525     }
526
527     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
528     uBytesRead = 0xdeadbeef;
529     hr = IWICStream_Read(pSubStream, NULL, 1, &uBytesRead);    /* destination buffer = NULL */
530     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
531     ok(uBytesRead == 0xdeadbeef, "Expected uBytesRead to be unchanged, got %u\n", uBytesRead);
532
533     hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead);    /* read 0 bytes */
534     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
535
536     uBytesRead = 0xdeadbeef;
537     hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead);
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, NULL, 0, NULL);
542     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
543
544     hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL);
545     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
546
547     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
548     ZeroMemory(MemBuf, sizeof(MemBuf));
549     hr = IWICStream_Read(pSubStream, MemBuf, 30, &uBytesRead);
550     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
551     if(SUCCEEDED(hr)) {
552         ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
553         ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n");
554     }
555     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
556
557
558     /* Write */
559     MemBuf[0] = CmpMem[0] + 1;
560     MemBuf[1] = CmpMem[1] + 1;
561     MemBuf[2] = CmpMem[2] + 1;
562     hr = IWICStream_Write(pSubStream, MemBuf, 3, &uBytesWritten);
563     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
564     if(SUCCEEDED(hr)) {
565         ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
566         ok(memcmp(MemBuf, Memory+20, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
567
568         /* check whether the seek pointer has moved correctly */
569         IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
570         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);
571     }
572     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
573
574     hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten);
575     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
576
577     uBytesWritten = 0xdeadbeef;
578     hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten);
579     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
580     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
581     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
582     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);
583
584     uBytesWritten = 0xdeadbeef;
585     hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten);
586     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
587     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
588     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
589     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);
590
591     hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten);
592     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
593     ok(uBytesWritten == 20, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
594     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
595     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);
596     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
597
598
599     /* SetSize */
600     uNewPos.u.HighPart = 0;
601     uNewPos.u.LowPart = sizeof(Memory) + 10;
602     hr = IWICStream_SetSize(pSubStream, uNewPos);
603     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
604
605     uNewPos.u.HighPart = 0;
606     uNewPos.u.LowPart = sizeof(Memory);
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) - 10;
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 = 0;
617     hr = IWICStream_SetSize(pSubStream, uNewPos);
618     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
619
620     uNewPos.QuadPart = -10;
621     hr = IWICStream_SetSize(pSubStream, uNewPos);
622     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
623
624
625     /* CopyTo */
626     uNewPos.u.HighPart = 0;
627     uNewPos.u.LowPart = 30;
628     hr = IWICStream_CopyTo(pSubStream, NULL, uNewPos, NULL, NULL);
629     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
630
631     hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream);
632     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
633
634     hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL);
635     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
636     IWICStream_Release(CopyStream);
637
638
639     /* Commit */
640     hr = IWICStream_Commit(pSubStream, STGC_DEFAULT);
641     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
642
643     hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE);
644     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
645
646     hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT);
647     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
648
649     hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
650     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
651
652     hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE);
653     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
654
655
656     /* Revert */
657     IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL);
658     hr = IWICStream_Revert(pSubStream);
659     ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
660     memcpy(Memory, CmpMem, sizeof(Memory));
661
662
663     /* LockRegion/UnlockRegion */
664     hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0);
665     ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
666
667     hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0);
668     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
669
670
671     /* Stat */
672     hr = IWICStream_Stat(pSubStream, NULL, 0);
673     ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
674
675     hr = IWICStream_Stat(pSubStream, &Stats, 0);
676     ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK);
677     ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
678     ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM);
679     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);
680     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);
681     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);
682     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);
683     ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
684     ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
685     ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
686
687
688     /* Clone */
689     hr = IWICStream_Clone(pSubStream, &CopyStream);
690     ok(hr == E_NOTIMPL, "Clone returned %#x, expected %#x\n", hr, E_NOTIMPL);
691
692
693     IWICStream_Release(pSubStream);
694
695
696     /* Recreate, this time larger than the original. */
697     hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
698     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
699
700     uNewPos.QuadPart = 48;
701     uSize.QuadPart = 32;
702     hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
703     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
704
705     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
706     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
707     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, uBytesWritten);
708
709     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
710     hr = IWICStream_Read(pSubStream, Memory, 48, &uBytesRead);
711     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
712     if(SUCCEEDED(hr)) {
713         ok(uBytesRead == 16, "Read %u bytes\n", uBytesRead);
714         ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n");
715     }
716
717     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
718     uBytesWritten = 0xdeadbeef;
719     hr = IWICStream_Write(pSubStream, CmpMem, 32, &uBytesWritten);
720     ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
721     ok(uBytesWritten == 0xdeadbeef, "Expected uBytesWritten to be unchanged, got %u\n", uBytesWritten);
722     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
723     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);
724
725
726     IWICStream_Release(pSubStream);
727     IWICStream_Release(pStream);
728     IWICStream_Release(pFactory);
729     CoUninitialize();
730 }
731
732 START_TEST(stream)
733 {
734     test_StreamOnMemory();
735     test_StreamOnStreamRange();
736 }