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
, DWORD stgm
)
193 static const char * test_file
= "c:\\test.txt";
195 trace("SHCreateStreamOnFileA: testing mode %d, STGM flags %08x\n", mode
, stgm
);
197 /* invalid arguments */
200 ret
= (*pSHCreateStreamOnFileA
)(NULL
, mode
| stgm
, &stream
);
201 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), got 0x%08x\n", ret
);
202 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
204 #if 0 /* This test crashes on WinXP SP2 */
205 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| stgm
, NULL
);
206 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
210 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_CONVERT
| stgm
, &stream
);
211 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
212 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
215 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_DELETEONRELEASE
| stgm
, &stream
);
216 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
217 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
220 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_TRANSACTED
| stgm
, &stream
);
221 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret
);
222 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
224 /* file does not exist */
227 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
228 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
229 ok(stream
== NULL
, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream
);
232 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
233 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
234 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
237 test_IStream_invalid_operations(stream
, mode
);
239 refcount
= IStream_Release(stream
);
240 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
243 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
248 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
249 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
250 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
253 test_IStream_invalid_operations(stream
, mode
);
255 refcount
= IStream_Release(stream
);
256 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
260 ret
= (*pSHCreateStreamOnFileA
)(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
261 ok(ret
== S_OK
, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret
);
262 ok(stream
!= NULL
, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
265 test_IStream_invalid_operations(stream
, mode
);
267 refcount
= IStream_Release(stream
);
268 ok(refcount
== 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount
);
270 ok(DeleteFileA(test_file
), "SHCreateStreamOnFileA: could not delete file '%s', got error %d\n", test_file
, GetLastError());
275 static void test_SHCreateStreamOnFileW(DWORD mode
, DWORD stgm
)
280 static const WCHAR test_file
[] = { 'c', ':', '\\', 't', 'e', 's', 't', '.', 't', 'x', 't', '\0' };
282 trace("SHCreateStreamOnFileW: testing mode %d, STGM flags %08x\n", mode
, stgm
);
284 /* invalid arguments */
287 ret
= (*pSHCreateStreamOnFileW
)(NULL
, mode
| stgm
, &stream
);
288 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) || /* XP */
289 ret
== E_INVALIDARG
/* Vista */,
290 "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret
);
291 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
293 #if 0 /* This test crashes on WinXP SP2 */
294 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| stgm
, NULL
);
295 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
299 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_CONVERT
| stgm
, &stream
);
300 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
301 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
304 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_DELETEONRELEASE
| stgm
, &stream
);
305 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
306 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
309 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_TRANSACTED
| stgm
, &stream
);
310 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret
);
311 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
313 /* file does not exist */
316 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
317 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
318 ok(stream
== NULL
, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream
);
321 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
322 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
323 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
326 test_IStream_invalid_operations(stream
, mode
);
328 refcount
= IStream_Release(stream
);
329 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
332 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
337 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, &stream
);
338 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
339 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
342 test_IStream_invalid_operations(stream
, mode
);
344 refcount
= IStream_Release(stream
);
345 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
349 ret
= (*pSHCreateStreamOnFileW
)(test_file
, mode
| STGM_CREATE
| stgm
, &stream
);
350 ok(ret
== S_OK
, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret
);
351 ok(stream
!= NULL
, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
354 test_IStream_invalid_operations(stream
, mode
);
356 refcount
= IStream_Release(stream
);
357 ok(refcount
== 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount
);
359 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileW: could not delete the test file, got error %d\n", GetLastError());
364 static void test_SHCreateStreamOnFileEx(DWORD mode
, DWORD stgm
)
367 IStream
* template = NULL
;
370 static const WCHAR test_file
[] = { 'c', ':', '\\', 't', 'e', 's', 't', '.', 't', 'x', 't', '\0' };
372 trace("SHCreateStreamOnFileEx: testing mode %d, STGM flags %08x\n", mode
, stgm
);
374 /* invalid arguments */
377 ret
= (*pSHCreateStreamOnFileEx
)(NULL
, mode
, 0, FALSE
, NULL
, &stream
);
378 ok(ret
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) || /* XP */
379 ret
== E_INVALIDARG
/* Vista */,
380 "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret
);
381 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
384 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
, 0, FALSE
, template, &stream
);
385 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
386 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
388 #if 0 /* This test crashes on WinXP SP2 */
389 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
, 0, FALSE
, NULL
, NULL
);
390 ok(ret
== E_INVALIDARG
, "SHCreateStreamOnFileEx: expected E_INVALIDARG, got 0x%08x\n", ret
);
393 /* file does not exist */
396 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, FALSE
, NULL
, &stream
);
397 if ((stgm
& STGM_TRANSACTED
) == STGM_TRANSACTED
&& mode
== STGM_READ
) {
398 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
) /* XP */ || ret
== E_INVALIDARG
/* Vista */,
399 "SHCreateStreamOnFileEx: expected E_INVALIDARG or HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
401 if (ret
== E_INVALIDARG
) {
402 skip("SHCreateStreamOnFileEx: STGM_TRANSACTED not supported in this configuration.\n");
406 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret
);
408 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
411 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, TRUE
, NULL
, &stream
);
412 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
413 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
416 test_IStream_invalid_operations(stream
, mode
);
418 refcount
= IStream_Release(stream
);
419 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
421 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
425 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
426 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
427 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
430 test_IStream_invalid_operations(stream
, mode
);
432 refcount
= IStream_Release(stream
);
433 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
435 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
439 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
440 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
441 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
444 test_IStream_invalid_operations(stream
, mode
);
446 refcount
= IStream_Release(stream
);
447 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
450 /* NOTE: don't delete the file, as it will be used for the file exists tests. */
455 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, FALSE
, NULL
, &stream
);
456 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
457 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
460 test_IStream_invalid_operations(stream
, mode
);
462 refcount
= IStream_Release(stream
);
463 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
467 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_FAILIFTHERE
| stgm
, 0, TRUE
, NULL
, &stream
);
468 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_EXISTS
), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), got 0x%08x\n", ret
);
469 ok(stream
== NULL
, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream
);
472 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, FALSE
, NULL
, &stream
);
473 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
474 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
477 test_IStream_invalid_operations(stream
, mode
);
479 refcount
= IStream_Release(stream
);
480 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
484 ret
= (*pSHCreateStreamOnFileEx
)(test_file
, mode
| STGM_CREATE
| stgm
, 0, TRUE
, NULL
, &stream
);
485 ok(ret
== S_OK
, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret
);
486 ok(stream
!= NULL
, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
489 test_IStream_invalid_operations(stream
, mode
);
491 refcount
= IStream_Release(stream
);
492 ok(refcount
== 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount
);
495 ok(DeleteFileW(test_file
), "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", GetLastError());
501 static const DWORD stgm_access
[] = {
507 static const DWORD stgm_sharing
[] = {
509 STGM_SHARE_DENY_NONE
,
510 STGM_SHARE_DENY_READ
,
511 STGM_SHARE_DENY_WRITE
,
515 static const DWORD stgm_flags
[] = {
518 STGM_DELETEONRELEASE
,
519 STGM_CONVERT
| STGM_DELETEONRELEASE
,
520 STGM_TRANSACTED
| STGM_CONVERT
,
521 STGM_TRANSACTED
| STGM_DELETEONRELEASE
,
522 STGM_TRANSACTED
| STGM_CONVERT
| STGM_DELETEONRELEASE
527 hShlwapi
= GetModuleHandleA("shlwapi.dll");
529 pSHCreateStreamOnFileA
= (void*)GetProcAddress(hShlwapi
, "SHCreateStreamOnFileA");
530 pSHCreateStreamOnFileW
= (void*)GetProcAddress(hShlwapi
, "SHCreateStreamOnFileW");
531 pSHCreateStreamOnFileEx
= (void*)GetProcAddress(hShlwapi
, "SHCreateStreamOnFileEx");
533 if (!pSHCreateStreamOnFileA
)
534 skip("SHCreateStreamOnFileA not found.\n");
536 if (!pSHCreateStreamOnFileW
)
537 skip("SHCreateStreamOnFileW not found.\n");
539 if (!pSHCreateStreamOnFileEx
)
540 skip("SHCreateStreamOnFileEx not found.\n");
542 for (i
= 0; i
!= sizeof(stgm_access
)/sizeof(stgm_access
[0]); i
++) {
543 for (j
= 0; j
!= sizeof(stgm_sharing
)/sizeof(stgm_sharing
[0]); j
++) {
544 if (pSHCreateStreamOnFileA
)
545 test_SHCreateStreamOnFileA(stgm_access
[i
], stgm_sharing
[j
]);
547 if (pSHCreateStreamOnFileW
)
548 test_SHCreateStreamOnFileW(stgm_access
[i
], stgm_sharing
[j
]);
550 if (pSHCreateStreamOnFileEx
) {
551 for (k
= 0; k
!= sizeof(stgm_flags
)/sizeof(stgm_flags
[0]); k
++)
552 test_SHCreateStreamOnFileEx(stgm_access
[i
], stgm_sharing
[j
] | stgm_flags
[k
]);