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
25 #include "wine/test.h"
32 /* Function pointers for the SHCreateStreamOnFile functions */
33 static HMODULE hShlwapi
;
34 static HRESULT (WINAPI
*pSHCreateStreamOnFileA
)(LPCSTR file
, DWORD mode
, IStream
**stream
);
35 static HRESULT (WINAPI
*pSHCreateStreamOnFileW
)(LPCWSTR file
, DWORD mode
, IStream
**stream
);
36 static HRESULT (WINAPI
*pSHCreateStreamOnFileEx
)(LPCWSTR file
, DWORD mode
, DWORD attributes
, BOOL create
, IStream
*template, IStream
**stream
);
39 static void test_IStream_invalid_operations(IStream
* stream
, DWORD mode
)
50 U(uzero
).HighPart
= 0;
59 /* IStream_Read from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Read helper function. */
61 ret
= stream
->lpVtbl
->Read(stream
, NULL
, 0, &count
);
62 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
64 ret
= stream
->lpVtbl
->Read(stream
, data
, 5, NULL
);
65 ok(ret
== S_FALSE
|| ret
== S_OK
, "expected S_FALSE or S_OK, got 0x%08x\n", ret
);
67 ret
= stream
->lpVtbl
->Read(stream
, data
, 0, NULL
);
68 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
70 ret
= stream
->lpVtbl
->Read(stream
, data
, 3, &count
);
71 ok(ret
== S_FALSE
|| ret
== S_OK
, "expected S_FALSE or S_OK, got 0x%08x\n", ret
);
75 /* IStream_Write from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Write helper function. */
77 ret
= stream
->lpVtbl
->Write(stream
, NULL
, 0, &count
);
78 if (mode
== STGM_READ
)
79 ok(ret
== STG_E_ACCESSDENIED
, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
81 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
83 strcpy(data
, "Hello");
84 ret
= stream
->lpVtbl
->Write(stream
, data
, 5, NULL
);
85 if (mode
== STGM_READ
)
86 ok(ret
== STG_E_ACCESSDENIED
, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
88 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
90 strcpy(data
, "Hello");
91 ret
= stream
->lpVtbl
->Write(stream
, data
, 0, NULL
);
92 if (mode
== STGM_READ
)
93 ok(ret
== STG_E_ACCESSDENIED
, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
95 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
97 strcpy(data
, "Hello");
98 ret
= stream
->lpVtbl
->Write(stream
, data
, 0, &count
);
99 if (mode
== STGM_READ
)
100 ok(ret
== STG_E_ACCESSDENIED
, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
102 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
104 strcpy(data
, "Hello");
105 ret
= stream
->lpVtbl
->Write(stream
, data
, 3, &count
);
106 if (mode
== STGM_READ
)
107 ok(ret
== STG_E_ACCESSDENIED
, "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret
);
109 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
113 ret
= IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
114 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
116 ret
= IStream_Seek(stream
, zero
, 20, NULL
);
117 ok(ret
== E_INVALIDARG
, "expected E_INVALIDARG, got 0x%08x\n", ret
);
119 /* IStream::CopyTo */
121 ret
= IStream_CopyTo(stream
, NULL
, uzero
, &uret
, &uret
);
122 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
125 ret
= IStream_CopyTo(stream
, clone
, uzero
, &uret
, &uret
);
126 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
128 ret
= IStream_CopyTo(stream
, stream
, uzero
, &uret
, &uret
);
129 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
131 ret
= IStream_CopyTo(stream
, stream
, uzero
, &uret
, NULL
);
132 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
134 ret
= IStream_CopyTo(stream
, stream
, uzero
, NULL
, &uret
);
135 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
137 /* IStream::Commit */
139 ret
= IStream_Commit(stream
, STGC_DEFAULT
);
140 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
142 /* IStream::Revert */
144 ret
= IStream_Revert(stream
);
145 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
147 /* IStream::LockRegion */
149 ret
= IStream_LockRegion(stream
, uzero
, uzero
, 0);
150 ok(ret
== E_NOTIMPL
/* XP */ || ret
== S_OK
/* Vista */,
151 "expected E_NOTIMPL or S_OK, got 0x%08x\n", ret
);
153 /* IStream::UnlockRegion */
155 if (ret
== E_NOTIMPL
) /* XP */ {
156 ret
= IStream_UnlockRegion(stream
, uzero
, uzero
, 0);
157 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
159 ret
= IStream_UnlockRegion(stream
, uzero
, uzero
, 0);
160 ok(ret
== S_OK
, "expected S_OK, got 0x%08x\n", ret
);
162 ret
= IStream_UnlockRegion(stream
, uzero
, uzero
, 0);
163 ok(ret
== STG_E_LOCKVIOLATION
, "expected STG_E_LOCKVIOLATION, got 0x%08x\n", ret
);
168 ret
= IStream_Stat(stream
, NULL
, 0);
169 ok(ret
== STG_E_INVALIDPOINTER
, "expected STG_E_INVALIDPOINTER, got 0x%08x\n", ret
);
173 ret
= IStream_Clone(stream
, NULL
);
174 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
177 ret
= IStream_Clone(stream
, &clone
);
178 ok(ret
== E_NOTIMPL
, "expected E_NOTIMPL, got 0x%08x\n", ret
);
179 ok(clone
== NULL
, "expected a NULL IStream object, got %p\n", stream
);
182 refcount
= IStream_Release(clone
);
183 ok(refcount
== 0, "expected 0, got %d\n", refcount
);
188 static void test_SHCreateStreamOnFileA(DWORD mode
)
193 static const char * test_file
= "c:\\test.txt";
195 printf("SHCreateStreamOnFileA: testing mode %d\n", mode
);
197 /* invalid arguments */
200 ret
= (*pSHCreateStreamOnFileA
)(NULL
, mode
, &stream
);
202 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), got 0x%08x\n", ret
);
203 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
205 #if 0 /* This test crashes on WinXP SP2 */
206 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
, NULL
);
207 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
211 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_CONVERT
, &stream
);
212 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
213 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
216 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_DELETEONRELEASE
, &stream
);
217 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
218 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
221 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_TRANSACTED
, &stream
);
222 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
223 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
225 /* file does not exist */
228 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_FAILIFTHERE
, &stream
);
230 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
231 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
234 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_CREATE
, &stream
);
236 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
238 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
241 test_IStream_invalid_operations(stream
, mode
);
243 refcount
= IStream_Release(stream
);
244 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
247 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
252 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_FAILIFTHERE
, &stream
);
254 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
256 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
259 test_IStream_invalid_operations(stream
, mode
);
261 refcount
= IStream_Release(stream
);
262 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
266 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_CREATE
, &stream
);
268 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
270 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
273 test_IStream_invalid_operations(stream
, mode
);
275 refcount
= IStream_Release(stream
);
276 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
278 ok(DeleteFileA(test_file
), "SHCreateStreamOnFileA: could not delete file '%s', got error %d\n", test_file
, GetLastError());
283 static void test_SHCreateStreamOnFileW(DWORD mode
)
288 static const WCHAR test_file
[] = { 'c', ':', '\\', 't', 'e', 's', 't', '.', 't', 'x', 't' };
290 printf("SHCreateStreamOnFileW: testing mode %d\n", mode
);
292 /* invalid arguments */
295 ret
= (*pSHCreateStreamOnFileW
)(NULL
, mode
, &stream
);
296 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) || /* XP */
297 ret
== E_INVALIDARG
/* Vista */,
298 "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret
);
299 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
301 #if 0 /* This test crashes on WinXP SP2 */
302 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
, NULL
);
303 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
307 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_CONVERT
, &stream
);
308 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
309 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
312 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_DELETEONRELEASE
, &stream
);
313 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
314 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
317 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_TRANSACTED
, &stream
);
318 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
319 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
321 /* file does not exist */
324 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_FAILIFTHERE
, &stream
);
326 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
327 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
330 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_CREATE
, &stream
);
332 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
334 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
337 test_IStream_invalid_operations(stream
, mode
);
339 refcount
= IStream_Release(stream
);
340 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
343 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
348 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_FAILIFTHERE
, &stream
);
350 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
352 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
355 test_IStream_invalid_operations(stream
, mode
);
357 refcount
= IStream_Release(stream
);
358 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
362 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_CREATE
, &stream
);
364 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
366 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
369 test_IStream_invalid_operations(stream
, mode
);
371 refcount
= IStream_Release(stream
);
372 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
374 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileW: could not delete the test file, got error %d\n", GetLastError());
379 static void test_SHCreateStreamOnFileEx(DWORD mode
, DWORD stgm
)
382 IStream
* template = NULL
;
385 static const WCHAR test_file
[] = { 'c', ':', '\\', 't', 'e', 's', 't', '.', 't', 'x', 't' };
387 printf("SHCreateStreamOnFileEx: testing mode %d, STGM flags %08x\n", mode
, stgm
);
389 /* invalid arguments */
392 ret
= (*pSHCreateStreamOnFileEx
)(NULL
, mode
, 0, FALSE
, NULL
, &stream
);
393 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) || /* XP */
394 ret
== E_INVALIDARG
/* Vista */,
395 "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret
);
396 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
399 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
, 0, FALSE
, template, &stream
);
401 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
402 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
404 #if 0 /* This test crashes on WinXP SP2 */
405 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
, 0, FALSE
, NULL
, NULL
);
406 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileEx: expected E_INVALIDARG, got 0x%08x\n", ret
);
409 /* file does not exist */
412 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, FALSE
, NULL
, &stream
);
413 if ((stgm
& STGM_TRANSACTED
) == STGM_TRANSACTED
&& mode
== STGM_READ
) {
414 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
) /* XP */ || ret
== E_INVALIDARG
/* Vista */,
415 "SHCreateStreamOnFileEx: expected E_INVALIDARG or HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
417 if (ret
== E_INVALIDARG
) {
418 printf("SHCreateStreamOnFileEx: STGM_TRANSACTED not supported in this configuration... skipping.\n");
423 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
425 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
428 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, TRUE
, NULL
, &stream
);
430 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
432 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
435 test_IStream_invalid_operations(stream
, mode
);
437 refcount
= IStream_Release(stream
);
438 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
440 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
444 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
446 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
448 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
451 test_IStream_invalid_operations(stream
, mode
);
453 refcount
= IStream_Release(stream
);
454 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
456 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
460 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
462 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
464 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
467 test_IStream_invalid_operations(stream
, mode
);
469 refcount
= IStream_Release(stream
);
470 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
473 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
478 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, FALSE
, NULL
, &stream
);
480 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
482 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
485 test_IStream_invalid_operations(stream
, mode
);
487 refcount
= IStream_Release(stream
);
488 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
492 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, TRUE
, NULL
, &stream
);
494 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_EXISTS
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), got 0x%08x\n", ret
);
495 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
498 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
500 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
502 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
505 test_IStream_invalid_operations(stream
, mode
);
507 refcount
= IStream_Release(stream
);
508 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
512 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
514 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
516 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
519 test_IStream_invalid_operations(stream
, mode
);
521 refcount
= IStream_Release(stream
);
522 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
526 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
532 static const DWORD stgm_flags
[] = {
535 STGM_DELETEONRELEASE
,
536 STGM_CONVERT
| STGM_DELETEONRELEASE
,
537 STGM_TRANSACTED
| STGM_CONVERT
,
538 STGM_TRANSACTED
| STGM_DELETEONRELEASE
,
539 STGM_TRANSACTED
| STGM_CONVERT
| STGM_DELETEONRELEASE
542 hShlwapi
= GetModuleHandleA("shlwapi.dll");
544 pSHCreateStreamOnFileA
= (void*)GetProcAddress(hShlwapi
, "SHCreateStreamOnFileA");
545 pSHCreateStreamOnFileW
= (void*)GetProcAddress(hShlwapi
, "SHCreateStreamOnFileW");
546 pSHCreateStreamOnFileEx
= (void*)GetProcAddress(hShlwapi
, "SHCreateStreamOnFileEx");
548 if (!pSHCreateStreamOnFileA
)
549 printf("SHCreateStreamOnFileA not found... skipping tests.\n");
551 test_SHCreateStreamOnFileA(STGM_READ
);
552 test_SHCreateStreamOnFileA(STGM_WRITE
);
553 test_SHCreateStreamOnFileA(STGM_READWRITE
);
556 if (!pSHCreateStreamOnFileW
)
557 printf("SHCreateStreamOnFileW not found... skipping tests.\n");
559 test_SHCreateStreamOnFileW(STGM_READ
);
560 test_SHCreateStreamOnFileW(STGM_WRITE
);
561 test_SHCreateStreamOnFileW(STGM_READWRITE
);
564 if (!pSHCreateStreamOnFileEx
)
565 printf("SHCreateStreamOnFileEx not found... skipping tests.\n");
569 for (i
= 0; i
!= sizeof(stgm_flags
)/sizeof(stgm_flags
[0]); i
++) {
570 test_SHCreateStreamOnFileEx(STGM_READ
, stgm_flags
[i
]);
571 test_SHCreateStreamOnFileEx(STGM_WRITE
, stgm_flags
[i
]);
572 test_SHCreateStreamOnFileEx(STGM_READWRITE
, stgm_flags
[i
]);