1 /* Unit test suite for SHLWAPI ShCreateStreamOnFile functions.
3 * Copyright 2008 Reece H. Dunn
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define WIN32_NO_STATUS
22 #define COM_NO_WINDOWS_H
29 #include <wine/test.h>
31 //#include "winbase.h"
37 static void test_IStream_invalid_operations(IStream
* stream
, DWORD mode
)
48 U(uzero
).HighPart
= 0;
57 /* IStream_Read from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Read helper function. */
59 ret
= stream
->lpVtbl
->Read(stream
, NULL
, 0, &count
);
60 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
62 ret
= stream
->lpVtbl
->Read(stream
, data
, 5, NULL
);
63 ok(ret
== S_FALSE
|| ret
== S_OK
, "expected S_FALSE or S_OK, got 0x%08x\n", ret
);
65 ret
= stream
->lpVtbl
->Read(stream
, data
, 0, NULL
);
66 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
68 ret
= stream
->lpVtbl
->Read(stream
, data
, 3, &count
);
69 ok(ret
== S_FALSE
|| ret
== S_OK
, "expected S_FALSE or S_OK, got 0x%08x\n", ret
);
73 /* IStream_Write from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Write helper function. */
75 ret
= stream
->lpVtbl
->Write(stream
, NULL
, 0, &count
);
76 if (mode
== STGM_READ
)
78 ok(ret
== STG_E_ACCESSDENIED
/* XP */ || broken(ret
== S_OK
) /* Win2000 + IE5 */,
79 "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
82 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
84 strcpy(data
, "Hello");
85 ret
= stream
->lpVtbl
->Write(stream
, data
, 5, NULL
);
86 if (mode
== STGM_READ
)
87 ok(ret
== STG_E_ACCESSDENIED
,
88 "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
90 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
92 strcpy(data
, "Hello");
93 ret
= stream
->lpVtbl
->Write(stream
, data
, 0, NULL
);
94 if (mode
== STGM_READ
)
95 ok(ret
== STG_E_ACCESSDENIED
,
96 "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
98 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
100 strcpy(data
, "Hello");
101 ret
= stream
->lpVtbl
->Write(stream
, data
, 0, &count
);
102 if (mode
== STGM_READ
)
103 ok(ret
== STG_E_ACCESSDENIED
,
104 "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
106 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
108 strcpy(data
, "Hello");
109 ret
= stream
->lpVtbl
->Write(stream
, data
, 3, &count
);
110 if (mode
== STGM_READ
)
111 ok(ret
== STG_E_ACCESSDENIED
,
112 "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
114 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
118 ret
= IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
119 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
121 ret
= IStream_Seek(stream
, zero
, 20, NULL
);
122 ok(ret
== E_INVALIDARG
,
123 "expected E_INVALIDARG, got 0x%08x\n", ret
);
125 /* IStream::CopyTo */
127 ret
= IStream_CopyTo(stream
, NULL
, uzero
, &uret
, &uret
);
128 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
131 ret
= IStream_CopyTo(stream
, clone
, uzero
, &uret
, &uret
);
132 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
134 ret
= IStream_CopyTo(stream
, stream
, uzero
, &uret
, &uret
);
135 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
137 ret
= IStream_CopyTo(stream
, stream
, uzero
, &uret
, NULL
);
138 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
140 ret
= IStream_CopyTo(stream
, stream
, uzero
, NULL
, &uret
);
141 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
143 /* IStream::Commit */
145 ret
= IStream_Commit(stream
, STGC_DEFAULT
);
146 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
148 /* IStream::Revert */
150 ret
= IStream_Revert(stream
);
151 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
153 /* IStream::LockRegion */
155 ret
= IStream_LockRegion(stream
, uzero
, uzero
, 0);
156 ok(ret
== E_NOTIMPL
/* XP */ || ret
== S_OK
/* Vista */,
157 "expected E_NOTIMPL or S_OK, got 0x%08x\n", ret
);
159 /* IStream::UnlockRegion */
161 if (ret
== E_NOTIMPL
) /* XP */ {
162 ret
= IStream_UnlockRegion(stream
, uzero
, uzero
, 0);
163 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
165 ret
= IStream_UnlockRegion(stream
, uzero
, uzero
, 0);
166 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
168 ret
= IStream_UnlockRegion(stream
, uzero
, uzero
, 0);
169 ok(ret
== STG_E_LOCKVIOLATION
, "expected STG_E_LOCKVIOLATION, got 0x%08x\n", ret
);
174 ret
= IStream_Stat(stream
, NULL
, 0);
175 ok(ret
== STG_E_INVALIDPOINTER
,
176 "expected STG_E_INVALIDPOINTER or E_NOTIMPL, got 0x%08x\n", ret
);
180 /* Passing a NULL pointer for the second IStream::Clone param crashes on Win7 */
183 ret
= IStream_Clone(stream
, &clone
);
184 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
185 ok(clone
== NULL
, "expected a NULL IStream object, got %p\n", stream
);
188 refcount
= IStream_Release(clone
);
189 ok(refcount
== 0, "expected 0, got %d\n", refcount
);
194 static void test_stream_read_write(IStream
*stream
, DWORD mode
)
196 static const LARGE_INTEGER start
;
198 unsigned char buf
[16];
199 DWORD written
, count
;
201 /* IStream_Read/Write from the COBJMACROS is undefined by shlwapi.h */
203 written
= 0xdeadbeaf;
204 ret
= stream
->lpVtbl
->Write(stream
, "\x5e\xa7", 2, &written
);
205 if (mode
== STGM_WRITE
|| mode
== STGM_READWRITE
)
207 ok(ret
== S_OK
, "IStream_Write error %#x (access %#x)\n", ret
, mode
);
208 ok(written
== 2, "expected 2, got %u\n", written
);
212 ok(ret
== STG_E_ACCESSDENIED
|| broken(ret
== S_OK
) /* win2000 */, "expected STG_E_ACCESSDENIED, got %#x (access %#x)\n", ret
, mode
);
213 ok(written
== 0xdeadbeaf || broken(written
== 2) /* win2000 */, "expected 0xdeadbeaf, got %#x\n", written
);
215 if (ret
== S_OK
) return; /* no point in further testing */
218 ret
= stream
->lpVtbl
->Seek(stream
, start
, STREAM_SEEK_SET
, NULL
);
219 ok(ret
== S_OK
, "Seek error %#x\n", ret
);
222 ret
= stream
->lpVtbl
->Read(stream
, buf
, 2, &count
);
225 ok(ret
== S_OK
|| broken(ret
== S_FALSE
) /* win2000 */, "IStream_Read error %#x (access %#x, written %u)\n", ret
, mode
, written
);
226 if (ret
== S_OK
&& (mode
== STGM_WRITE
|| mode
== STGM_READWRITE
))
228 ok(count
== 2, "expected 2, got %u\n", count
);
229 ok(buf
[0] == 0x5e && buf
[1] == 0xa7, "expected 5ea7, got %02x%02x\n", buf
[0], buf
[1]);
232 ok(count
== 0, "expected 0, got %u\n", count
);
236 ok(ret
== S_FALSE
, "expected S_FALSE, got %#x (access %#x, written %u)\n", ret
, mode
, written
);
237 ok(count
== 0, "expected 0, got %u\n", count
);
240 ret
= stream
->lpVtbl
->Seek(stream
, start
, STREAM_SEEK_SET
, NULL
);
241 ok(ret
== S_OK
, "Seek error %#x\n", ret
);
244 ret
= stream
->lpVtbl
->Read(stream
, buf
, 0, &count
);
245 ok(ret
== S_OK
, "IStream_Read error %#x (access %#x, written %u)\n", ret
, mode
, written
);
246 ok(count
== 0, "expected 0, got %u\n", count
);
249 ret
= stream
->lpVtbl
->Read(stream
, buf
, sizeof(buf
), &count
);
250 ok(ret
== S_FALSE
, "expected S_FALSE, got %#x (access %#x, written %u)\n", ret
, mode
, written
);
251 ok(count
== written
, "expected %u, got %u\n", written
, count
);
253 ok(buf
[0] == 0x5e && buf
[1] == 0xa7, "expected 5ea7, got %02x%02x\n", buf
[0], buf
[1]);
256 static void test_SHCreateStreamOnFileA(DWORD mode
, DWORD stgm
)
261 char test_file
[MAX_PATH
];
262 static const CHAR testA_txt
[] = "\\testA.txt";
264 trace("SHCreateStreamOnFileA: testing mode %d, STGM flags %08x\n", mode
, stgm
);
266 /* Don't used a fixed path for the testA.txt file */
267 GetTempPathA(MAX_PATH
, test_file
);
268 lstrcatA(test_file
, testA_txt
);
270 /* invalid arguments */
273 ret
= SHCreateStreamOnFileA(NULL
, mode
| stgm
, &stream
);
274 if (ret
== E_INVALIDARG
) /* Win98 SE */ {
275 win_skip("Not supported\n");
279 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) /* NT */ ||
280 ret
== HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME
) /* 9x */,
281 "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) "
282 "or HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), got 0x%08x\n", ret
);
283 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
285 if (0) /* This test crashes on WinXP SP2 */
287 ret
= SHCreateStreamOnFileA(test_file
, mode
| stgm
, NULL
);
288 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
292 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_CONVERT
| stgm
, &stream
);
293 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
294 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
297 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_DELETEONRELEASE
| stgm
, &stream
);
298 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
299 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
302 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_TRANSACTED
| stgm
, &stream
);
303 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
304 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
306 /* file does not exist */
309 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
310 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
311 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
314 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
315 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
316 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
319 test_IStream_invalid_operations(stream
, mode
);
321 refcount
= IStream_Release(stream
);
322 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
325 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
330 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
331 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
332 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
335 test_IStream_invalid_operations(stream
, mode
);
337 refcount
= IStream_Release(stream
);
338 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
342 ret
= SHCreateStreamOnFileA(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
343 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
344 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
349 test_stream_read_write(stream
, mode
);
350 test_IStream_invalid_operations(stream
, mode
);
352 refcount
= IStream_Release(stream
);
353 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
355 delret
= DeleteFileA(test_file
);
356 ok(delret
, "SHCreateStreamOnFileA: could not delete file '%s', got error %d\n",
357 test_file
, GetLastError());
362 static void test_SHCreateStreamOnFileW(DWORD mode
, DWORD stgm
)
367 WCHAR test_file
[MAX_PATH
];
368 CHAR test_fileA
[MAX_PATH
];
369 static const CHAR testW_txt
[] = "\\testW.txt";
371 trace("SHCreateStreamOnFileW: testing mode %d, STGM flags %08x\n", mode
, stgm
);
373 /* Don't used a fixed path for the testW.txt file */
374 GetTempPathA(MAX_PATH
, test_fileA
);
375 lstrcatA(test_fileA
, testW_txt
);
376 MultiByteToWideChar(CP_ACP
, 0, test_fileA
, -1, test_file
, MAX_PATH
);
378 /* invalid arguments */
384 ret
= SHCreateStreamOnFileW(NULL
, mode
| stgm
, &stream
);
385 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) || /* XP */
386 ret
== E_INVALIDARG
/* Vista */,
387 "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret
);
388 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
393 /* This test crashes on WinXP SP2 */
394 ret
= SHCreateStreamOnFileW(test_file
, mode
| stgm
, NULL
);
395 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
399 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_CONVERT
| stgm
, &stream
);
400 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
401 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
404 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_DELETEONRELEASE
| stgm
, &stream
);
405 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
406 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
409 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_TRANSACTED
| stgm
, &stream
);
410 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
411 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
413 /* file does not exist */
416 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
417 if (ret
== E_INVALIDARG
) /* Win98 SE */ {
418 win_skip("Not supported\n");
422 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
423 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
426 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
427 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
428 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
431 test_IStream_invalid_operations(stream
, mode
);
433 refcount
= IStream_Release(stream
);
434 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
437 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
442 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
443 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
444 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
447 test_IStream_invalid_operations(stream
, mode
);
449 refcount
= IStream_Release(stream
);
450 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
454 ret
= SHCreateStreamOnFileW(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
455 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
456 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
461 test_stream_read_write(stream
, mode
);
462 test_IStream_invalid_operations(stream
, mode
);
464 refcount
= IStream_Release(stream
);
465 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
467 delret
= DeleteFileA(test_fileA
);
468 ok(delret
, "SHCreateStreamOnFileW: could not delete the test file, got error %d\n",
474 static void test_SHCreateStreamOnFileEx(DWORD mode
, DWORD stgm
)
477 IStream
* template = NULL
;
480 WCHAR test_file
[MAX_PATH
];
481 CHAR test_fileA
[MAX_PATH
];
482 static const CHAR testEx_txt
[] = "\\testEx.txt";
485 if (winetest_debug
> 1)
486 trace("SHCreateStreamOnFileEx: testing mode %d, STGM flags %08x\n", mode
, stgm
);
488 /* Don't used a fixed path for the testEx.txt file */
489 GetTempPathA(MAX_PATH
, test_fileA
);
490 lstrcatA(test_fileA
, testEx_txt
);
491 MultiByteToWideChar(CP_ACP
, 0, test_fileA
, -1, test_file
, MAX_PATH
);
493 /* invalid arguments */
499 ret
= SHCreateStreamOnFileEx(NULL
, mode
, 0, FALSE
, NULL
, &stream
);
500 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) || /* XP */
501 ret
== E_INVALIDARG
/* Vista */,
502 "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret
);
503 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
507 ret
= SHCreateStreamOnFileEx(test_file
, mode
, 0, FALSE
, template, &stream
);
508 if (ret
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
)) {
509 win_skip("File probably locked by Anti-Virus/Spam software, trying again\n");
511 ret
= SHCreateStreamOnFileEx(test_file
, mode
, 0, FALSE
, template, &stream
);
513 ok( ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
) ||
514 ret
== HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
),
515 "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) or "
516 "HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got 0x%08x\n", ret
);
518 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
522 /* This test crashes on WinXP SP2 */
523 ret
= SHCreateStreamOnFileEx(test_file
, mode
, 0, FALSE
, NULL
, NULL
);
524 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileEx: expected E_INVALIDARG, got 0x%08x\n", ret
);
527 /* file does not exist */
530 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, FALSE
, NULL
, &stream
);
531 if ((stgm
& STGM_TRANSACTED
) == STGM_TRANSACTED
&& mode
== STGM_READ
) {
532 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
) /* XP */ || ret
== E_INVALIDARG
/* Vista */,
533 "SHCreateStreamOnFileEx: expected E_INVALIDARG or HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
535 if (ret
== E_INVALIDARG
) {
536 skip("SHCreateStreamOnFileEx: STGM_TRANSACTED not supported in this configuration.\n");
540 ok( ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
) ||
541 ret
== HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
),
542 "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) or "
543 "HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got 0x%08x\n", ret
);
545 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
548 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, TRUE
, NULL
, &stream
);
549 /* not supported on win9x */
550 if (broken(ret
== HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
) && stream
== NULL
)) {
551 skip("Not supported\n");
552 DeleteFileA(test_fileA
);
556 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
557 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
560 test_IStream_invalid_operations(stream
, mode
);
562 refcount
= IStream_Release(stream
);
563 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
565 delret
= DeleteFileA(test_fileA
);
566 ok(delret
, "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n",
571 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
572 if (ret
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
)) {
573 win_skip("File probably locked by Anti-Virus/Spam software, trying again\n");
575 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
577 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
578 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
581 test_IStream_invalid_operations(stream
, mode
);
583 refcount
= IStream_Release(stream
);
584 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
586 delret
= DeleteFileA(test_fileA
);
587 ok(delret
, "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n",
592 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
593 if (ret
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
)) {
594 win_skip("File probably locked by Anti-Virus/Spam software, trying again\n");
596 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
598 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
599 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
602 test_IStream_invalid_operations(stream
, mode
);
604 refcount
= IStream_Release(stream
);
605 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
608 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
613 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, FALSE
, NULL
, &stream
);
614 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
615 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
618 test_IStream_invalid_operations(stream
, mode
);
620 refcount
= IStream_Release(stream
);
621 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
625 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, TRUE
, NULL
, &stream
);
626 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_EXISTS
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), got 0x%08x\n", ret
);
627 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
630 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
631 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
632 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
635 test_IStream_invalid_operations(stream
, mode
);
637 refcount
= IStream_Release(stream
);
638 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
642 ret
= SHCreateStreamOnFileEx(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
643 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
644 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
647 test_IStream_invalid_operations(stream
, mode
);
649 refcount
= IStream_Release(stream
);
650 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
653 delret
= DeleteFileA(test_fileA
);
654 ok(delret
, "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n",
659 static void test_SHCreateStreamOnFileEx_CopyTo(void)
663 WCHAR tmpPath
[MAX_PATH
];
664 WCHAR srcFileName
[MAX_PATH
];
665 WCHAR dstFileName
[MAX_PATH
];
666 ULARGE_INTEGER count
, read
, written
;
667 LARGE_INTEGER distance
;
668 static const char srcContents
[1];
669 static const WCHAR prefix
[] = { 'T', 'S', 'T', 0 };
671 GetTempPathW(MAX_PATH
, tmpPath
);
672 GetTempFileNameW(tmpPath
, prefix
, 0, srcFileName
);
673 GetTempFileNameW(tmpPath
, prefix
, 0, dstFileName
);
675 ret
= SHCreateStreamOnFileEx(srcFileName
, STGM_CREATE
| STGM_READWRITE
| STGM_DELETEONRELEASE
, FILE_ATTRIBUTE_TEMPORARY
, FALSE
, NULL
, &src
);
676 ok(SUCCEEDED(ret
), "SHCreateStreamOnFileEx failed with ret=0x%08x\n", ret
);
678 written
.QuadPart
= 0;
679 ret
= IStream_Write(src
, srcContents
, sizeof(srcContents
), &U(written
).LowPart
);
680 ok(SUCCEEDED(ret
), "ISequentialStream_Write failed with ret=0x%08x\n", ret
);
682 distance
.QuadPart
= 0;
683 ret
= IStream_Seek(src
, distance
, STREAM_SEEK_SET
, &written
);
684 ok(SUCCEEDED(ret
), "ISequentialStream_Seek failed with ret=0x%08x\n", ret
);
686 ret
= SHCreateStreamOnFileEx(dstFileName
, STGM_CREATE
| STGM_READWRITE
| STGM_DELETEONRELEASE
, FILE_ATTRIBUTE_TEMPORARY
, FALSE
, NULL
, &dst
);
687 ok(SUCCEEDED(ret
), "SHCreateStreamOnFileEx failed with ret=0x%08x\n", ret
);
689 /* Test using a count larger than the source file, so that the Read operation will fall short */
692 ret
= IStream_CopyTo(src
, dst
, count
, &read
, &written
);
693 ok(SUCCEEDED(ret
), "CopyTo failed with ret=0x%08x\n", ret
);
695 ok(read
.QuadPart
== 1, "read does not match size: %d != 1\n", U(read
).LowPart
);
696 ok(written
.QuadPart
== 1, "written does not match size: %d != 1\n", U(written
).LowPart
);
698 IStream_Release(dst
);
699 IStream_Release(src
);
700 DeleteFileW( srcFileName
);
701 DeleteFileW( dstFileName
);
707 static const DWORD stgm_access
[] = {
713 static const DWORD stgm_sharing
[] = {
715 STGM_SHARE_DENY_NONE
,
716 STGM_SHARE_DENY_READ
,
717 STGM_SHARE_DENY_WRITE
,
721 static const DWORD stgm_flags
[] = {
724 STGM_DELETEONRELEASE
,
725 STGM_CONVERT
| STGM_DELETEONRELEASE
,
726 STGM_TRANSACTED
| STGM_CONVERT
,
727 STGM_TRANSACTED
| STGM_DELETEONRELEASE
,
728 STGM_TRANSACTED
| STGM_CONVERT
| STGM_DELETEONRELEASE
733 for (i
= 0; i
!= sizeof(stgm_access
)/sizeof(stgm_access
[0]); i
++) {
734 for (j
= 0; j
!= sizeof(stgm_sharing
)/sizeof(stgm_sharing
[0]); j
++) {
735 test_SHCreateStreamOnFileA(stgm_access
[i
], stgm_sharing
[j
]);
736 test_SHCreateStreamOnFileW(stgm_access
[i
], stgm_sharing
[j
]);
738 for (k
= 0; k
!= sizeof(stgm_flags
)/sizeof(stgm_flags
[0]); k
++)
739 test_SHCreateStreamOnFileEx(stgm_access
[i
], stgm_sharing
[j
] | stgm_flags
[k
]);
743 test_SHCreateStreamOnFileEx_CopyTo();