2 * Unit tests for OLE storage
4 * Copyright (c) 2004 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
28 #define NONAMELESSUNION
29 #define NONAMELESSSTRUCT
31 //#include <windows.h>
32 #include <wine/test.h>
38 DEFINE_GUID( test_stg_cls
, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0);
40 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
42 static CHAR filenameA
[MAX_PATH
];
43 static WCHAR filename
[MAX_PATH
];
45 static const char file1_nameA
[] = {'c','o','p','y','t','e','s','t','A',0};
46 static const WCHAR file1_name
[] = {'c','o','p','y','t','e','s','t','A',0};
47 static const char file2_nameA
[] = {'c','o','p','y','t','e','s','t','B',0};
48 static const WCHAR file2_name
[] = {'c','o','p','y','t','e','s','t','B',0};
49 static const WCHAR stgA_name
[] = {'S','t','o','r','a','g','e','A',0};
50 static const WCHAR stgB_name
[] = {'S','t','o','r','a','g','e','B',0};
51 static const WCHAR strmA_name
[] = {'S','t','r','e','a','m','A',0};
52 static const WCHAR strmB_name
[] = {'S','t','r','e','a','m','B',0};
53 static const WCHAR strmC_name
[] = {'S','t','r','e','a','m','C',0};
55 /* Win9x and WinMe don't have lstrcmpW */
56 static int strcmp_ww(LPCWSTR strw1
, LPCWSTR strw2
)
58 CHAR stra1
[512], stra2
[512];
59 WideCharToMultiByte(CP_ACP
, 0, strw1
, -1, stra1
, sizeof(stra1
), NULL
, NULL
);
60 WideCharToMultiByte(CP_ACP
, 0, strw2
, -1, stra2
, sizeof(stra2
), NULL
, NULL
);
61 return lstrcmpA(stra1
, stra2
);
64 typedef struct TestLockBytes
{
65 ILockBytes ILockBytes_iface
;
71 ULONG locks_supported
;
75 static inline TestLockBytes
*impl_from_ILockBytes(ILockBytes
*iface
)
77 return CONTAINING_RECORD(iface
, TestLockBytes
, ILockBytes_iface
);
80 static HRESULT WINAPI
TestLockBytes_QueryInterface(ILockBytes
*iface
, REFIID iid
,
83 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
85 if (!ppv
) return E_INVALIDARG
;
87 if (IsEqualIID(&IID_IUnknown
, iid
) ||
88 IsEqualIID(&IID_ILockBytes
, iid
))
89 *ppv
= &This
->ILockBytes_iface
;
93 IUnknown_AddRef((IUnknown
*)*ppv
);
97 static ULONG WINAPI
TestLockBytes_AddRef(ILockBytes
*iface
)
99 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
100 ULONG ref
= InterlockedIncrement(&This
->ref
);
104 static ULONG WINAPI
TestLockBytes_Release(ILockBytes
*iface
)
106 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
107 ULONG ref
= InterlockedDecrement(&This
->ref
);
111 static HRESULT WINAPI
TestLockBytes_ReadAt(ILockBytes
*iface
,
112 ULARGE_INTEGER ulOffset
, void *pv
, ULONG cb
, ULONG
*pcbRead
)
114 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
117 if (!pv
) return E_INVALIDARG
;
119 if (!pcbRead
) pcbRead
= &dummy
;
121 if (ulOffset
.QuadPart
>= This
->size
)
127 cb
= min(cb
, This
->size
- ulOffset
.QuadPart
);
130 memcpy(pv
, &This
->contents
[ulOffset
.QuadPart
], cb
);
135 static HRESULT WINAPI
TestLockBytes_WriteAt(ILockBytes
*iface
,
136 ULARGE_INTEGER ulOffset
, const void *pv
, ULONG cb
, ULONG
*pcbWritten
)
138 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
142 if (!pv
) return E_INVALIDARG
;
144 if (!pcbWritten
) pcbWritten
= &dummy
;
146 if (ulOffset
.QuadPart
+ cb
> This
->size
)
148 ULARGE_INTEGER new_size
;
149 new_size
.QuadPart
= ulOffset
.QuadPart
+ cb
;
150 hr
= ILockBytes_SetSize(iface
, new_size
);
151 if (FAILED(hr
)) return hr
;
155 memcpy(&This
->contents
[ulOffset
.QuadPart
], pv
, cb
);
160 static HRESULT WINAPI
TestLockBytes_Flush(ILockBytes
*iface
)
165 static HRESULT WINAPI
TestLockBytes_SetSize(ILockBytes
*iface
,
168 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
170 if (This
->buffer_size
< cb
.QuadPart
)
172 ULONG new_buffer_size
= max(This
->buffer_size
* 2, cb
.QuadPart
);
173 BYTE
* new_buffer
= HeapAlloc(GetProcessHeap(), 0, new_buffer_size
);
174 if (!new_buffer
) return E_OUTOFMEMORY
;
175 memcpy(new_buffer
, This
->contents
, This
->size
);
176 HeapFree(GetProcessHeap(), 0, This
->contents
);
177 This
->contents
= new_buffer
;
180 if (cb
.QuadPart
> This
->size
)
181 memset(&This
->contents
[This
->size
], 0, cb
.QuadPart
- This
->size
);
183 This
->size
= cb
.QuadPart
;
188 static HRESULT WINAPI
TestLockBytes_LockRegion(ILockBytes
*iface
,
189 ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
)
191 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
193 return This
->lock_hr
;
196 static HRESULT WINAPI
TestLockBytes_UnlockRegion(ILockBytes
*iface
,
197 ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
)
199 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
200 return This
->lock_hr
;
203 static HRESULT WINAPI
TestLockBytes_Stat(ILockBytes
*iface
,
204 STATSTG
*pstatstg
, DWORD grfStatFlag
)
206 TestLockBytes
*This
= impl_from_ILockBytes(iface
);
207 static const WCHAR dummy_name
[] = {'d','u','m','m','y',0};
209 if (!pstatstg
) return E_INVALIDARG
;
211 memset(pstatstg
, 0, sizeof(STATSTG
));
213 if (!(grfStatFlag
& STATFLAG_NONAME
))
215 pstatstg
->pwcsName
= CoTaskMemAlloc(sizeof(dummy_name
));
216 if (!pstatstg
->pwcsName
) return E_OUTOFMEMORY
;
217 memcpy(pstatstg
->pwcsName
, dummy_name
, sizeof(dummy_name
));
220 pstatstg
->type
= STGTY_LOCKBYTES
;
221 pstatstg
->cbSize
.QuadPart
= This
->size
;
222 pstatstg
->grfLocksSupported
= This
->locks_supported
;
227 static /* const */ ILockBytesVtbl TestLockBytes_Vtbl
= {
228 TestLockBytes_QueryInterface
,
229 TestLockBytes_AddRef
,
230 TestLockBytes_Release
,
231 TestLockBytes_ReadAt
,
232 TestLockBytes_WriteAt
,
234 TestLockBytes_SetSize
,
235 TestLockBytes_LockRegion
,
236 TestLockBytes_UnlockRegion
,
240 static void CreateTestLockBytes(TestLockBytes
**This
)
242 *This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(**This
));
246 (*This
)->ILockBytes_iface
.lpVtbl
= &TestLockBytes_Vtbl
;
251 static void DeleteTestLockBytes(TestLockBytes
*This
)
253 ok(This
->ILockBytes_iface
.lpVtbl
== &TestLockBytes_Vtbl
, "test lock bytes %p deleted with incorrect vtable\n", This
);
254 ok(This
->ref
== 1, "test lock bytes %p deleted with %i references instead of 1\n", This
, This
->ref
);
255 HeapFree(GetProcessHeap(), 0, This
->contents
);
256 HeapFree(GetProcessHeap(), 0, This
);
259 static void test_hglobal_storage_stat(void)
261 ILockBytes
*ilb
= NULL
;
262 IStorage
*stg
= NULL
;
265 DWORD mode
, refcount
;
267 r
= CreateILockBytesOnHGlobal( NULL
, TRUE
, &ilb
);
268 ok( r
== S_OK
, "CreateILockBytesOnHGlobal failed\n");
270 r
= StgIsStorageILockBytes( ilb
);
271 ok( r
== S_FALSE
, "StgIsStorageILockBytes should have failed\n");
273 mode
= STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
;/*0x1012*/
274 r
= StgCreateDocfileOnILockBytes( ilb
, mode
, 0, &stg
);
275 ok( r
== S_OK
, "StgCreateDocfileOnILockBytes failed\n");
277 r
= WriteClassStg( stg
, &test_stg_cls
);
278 ok( r
== S_OK
, "WriteClassStg failed\n");
280 r
= StgIsStorageILockBytes( ilb
);
281 ok( r
== S_OK
, "StgIsStorageILockBytes failed\n");
283 memset( &stat
, 0, sizeof stat
);
284 r
= IStorage_Stat( stg
, &stat
, 0 );
286 ok( stat
.pwcsName
== NULL
, "storage name not null\n");
287 ok( stat
.type
== 1, "type is wrong\n");
288 ok( stat
.grfMode
== 0x12, "grf mode is incorrect\n");
289 ok( !memcmp(&stat
.clsid
, &test_stg_cls
, sizeof test_stg_cls
), "CLSID is wrong\n");
291 refcount
= IStorage_Release( stg
);
292 ok( refcount
== 0, "IStorage refcount is wrong\n");
293 refcount
= ILockBytes_Release( ilb
);
294 ok( refcount
== 0, "ILockBytes refcount is wrong\n");
297 static void test_create_storage_modes(void)
299 IStorage
*stg
= NULL
;
302 DeleteFileA(filenameA
);
304 /* test with some invalid parameters */
305 r
= StgCreateDocfile( NULL
, 0, 0, &stg
);
306 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
307 r
= StgCreateDocfile( filename
, 0, 0, &stg
);
308 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
309 r
= StgCreateDocfile( filename
, STGM_CREATE
, 0, &stg
);
310 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
311 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_READWRITE
, 0, &stg
);
312 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
313 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
, 0, &stg
);
314 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
315 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, NULL
);
316 ok(r
==STG_E_INVALIDPOINTER
, "StgCreateDocfile succeeded\n");
317 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 1, &stg
);
318 ok(r
==STG_E_INVALIDPARAMETER
, "StgCreateDocfile succeeded\n");
319 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, 0, &stg
);
320 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
321 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, &stg
);
322 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
323 r
= StgCreateDocfile( filename
, STGM_PRIORITY
, 0, &stg
);
324 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
326 /* StgCreateDocfile seems to be very particular about the flags it accepts */
327 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| STGM_WRITE
, 0, &stg
);
328 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
329 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 8, 0, &stg
);
330 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
331 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x80, 0, &stg
);
332 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
333 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x800, 0, &stg
);
334 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
335 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x8000, 0, &stg
);
336 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
337 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x80000, 0, &stg
);
338 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
339 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x800000, 0, &stg
);
340 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
341 ok(stg
== NULL
, "stg was set\n");
343 /* check what happens if the file already exists (which is how it's meant to be used) */
344 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
345 ok(r
==S_OK
, "StgCreateDocfile failed\n");
346 r
= IStorage_Release(stg
);
347 ok(r
== 0, "storage not released\n");
348 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
349 ok(r
==STG_E_FILEALREADYEXISTS
, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
350 r
= StgCreateDocfile( filename
, STGM_READ
, 0, &stg
);
351 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
352 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
, 0, &stg
);
353 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
354 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_WRITE
, 0, &stg
);
355 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
356 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
, 0, &stg
);
357 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
358 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
| STGM_TRANSACTED
, 0, &stg
);
359 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
360 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
| STGM_READWRITE
, 0, &stg
);
361 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
362 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
| STGM_WRITE
, 0, &stg
);
363 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
364 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_WRITE
| STGM_WRITE
, 0, &stg
);
365 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
366 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_WRITE
| STGM_READ
, 0, &stg
);
367 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile wrong error\n");
368 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
| STGM_SHARE_DENY_WRITE
| STGM_READ
, 0, &stg
);
369 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile wrong error\n");
370 ok(DeleteFileA(filenameA
), "failed to delete file\n");
372 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
373 ok(r
==S_OK
, "StgCreateDocfile failed\n");
374 r
= IStorage_Release(stg
);
375 ok(r
== 0, "storage not released\n");
376 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
|STGM_FAILIFTHERE
, 0, &stg
);
377 ok(r
==STG_E_FILEALREADYEXISTS
, "StgCreateDocfile wrong error\n");
378 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_WRITE
, 0, &stg
);
379 ok(r
==STG_E_FILEALREADYEXISTS
, "StgCreateDocfile wrong error\n");
381 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, 0, &stg
);
382 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
383 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
384 ok(r
==S_OK
, "StgCreateDocfile failed\n");
385 r
= IStorage_Release(stg
);
386 ok(r
== 0, "storage not released\n");
387 ok(DeleteFileA(filenameA
), "failed to delete file\n");
389 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
390 ok(r
==S_OK
, "StgCreateDocfile failed\n");
391 r
= IStorage_Release(stg
);
392 ok(r
== 0, "storage not released\n");
393 ok(DeleteFileA(filenameA
), "failed to delete file\n");
395 /* test the way excel uses StgCreateDocFile */
396 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
|STGM_CREATE
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, 0, &stg
);
397 ok(r
==S_OK
, "StgCreateDocfile the excel way failed\n");
400 r
= IStorage_Release(stg
);
401 ok(r
== 0, "storage not released\n");
402 ok(DeleteFileA(filenameA
), "failed to delete file\n");
405 /* and the way windows media uses it ... */
406 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_DENY_NONE
| STGM_READWRITE
| STGM_TRANSACTED
, 0, &stg
);
407 ok(r
==S_OK
, "StgCreateDocfile the windows media way failed\n");
410 r
= IStorage_Release(stg
);
411 ok(r
== 0, "storage not released\n");
412 ok(DeleteFileA(filenameA
), "failed to delete file\n");
415 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
416 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, 0, &stg
);
417 ok(r
==S_OK
, "StgCreateDocfile the excel way failed\n");
420 r
= IStorage_Release(stg
);
421 ok(r
== 0, "storage not released\n");
422 ok(DeleteFileA(filenameA
), "failed to delete file\n");
425 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
|STGM_CREATE
|STGM_SHARE_DENY_WRITE
|STGM_WRITE
, 0, &stg
);
426 ok(r
==S_OK
, "StgCreateDocfile the excel way failed\n");
429 r
= IStorage_Release(stg
);
430 ok(r
== 0, "storage not released\n");
431 ok(DeleteFileA(filenameA
), "failed to delete file\n");
434 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
435 ok(r
==S_OK
, "StgCreateDocfile the powerpoint way failed\n");
438 r
= IStorage_Release(stg
);
439 ok(r
== 0, "storage not released\n");
440 ok(DeleteFileA(filenameA
), "failed to delete file\n");
443 /* test the way msi uses StgCreateDocfile */
444 r
= StgCreateDocfile( filename
, STGM_DIRECT
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stg
);
445 ok(r
==S_OK
, "StgCreateDocFile failed\n");
446 r
= IStorage_Release(stg
);
447 ok(r
== 0, "storage not released\n");
448 ok(DeleteFileA(filenameA
), "failed to delete file\n");
451 static void test_stgcreatestorageex(void)
453 HRESULT (WINAPI
*pStgCreateStorageEx
)(const WCHAR
* pwcsName
, DWORD grfMode
, DWORD stgfmt
, DWORD grfAttrs
, STGOPTIONS
* pStgOptions
, void* reserved
, REFIID riid
, void** ppObjectOpen
);
454 HMODULE hOle32
= GetModuleHandleA("ole32");
455 IStorage
*stg
= NULL
;
456 STGOPTIONS stgoptions
= {1, 0, 4096};
459 pStgCreateStorageEx
= (void *) GetProcAddress(hOle32
, "StgCreateStorageEx");
460 if (!pStgCreateStorageEx
)
462 win_skip("skipping test on NT4\n");
466 DeleteFileA(filenameA
);
468 /* Verify that StgCreateStorageEx can accept an options param */
469 r
= pStgCreateStorageEx( filename
,
470 STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
,
477 ok(r
==S_OK
|| r
==STG_E_UNIMPLEMENTEDFUNCTION
, "StgCreateStorageEx with options failed\n");
478 if (r
==STG_E_UNIMPLEMENTEDFUNCTION
)
480 /* We're on win98 which means all bets are off. Let's get out of here. */
481 win_skip("skipping test on win9x\n");
485 r
= IStorage_Release(stg
);
486 ok(r
== 0, "storage not released\n");
487 ok(DeleteFileA(filenameA
), "failed to delete file\n");
489 /* Verify that StgCreateStorageEx can accept a NULL pStgOptions */
490 r
= pStgCreateStorageEx( filename
,
491 STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
,
498 ok(r
==S_OK
, "StgCreateStorageEx with NULL options failed\n");
499 r
= IStorage_Release(stg
);
500 ok(r
== 0, "storage not released\n");
501 ok(DeleteFileA(filenameA
), "failed to delete file\n");
504 static void test_storage_stream(void)
506 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
507 static const WCHAR longname
[] = {
508 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
509 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
511 IStorage
*stg
= NULL
;
514 IStream
*stm2
= NULL
;
518 unsigned char buffer
[0x100];
522 DeleteFileA(filenameA
);
524 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
525 ok(r
==S_OK
, "StgCreateDocfile failed\n");
527 /* try create some invalid streams */
528 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 1, 0, &stm
);
529 ok(r
==STG_E_INVALIDPARAMETER
, "IStorage->CreateStream wrong error\n");
530 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 1, &stm
);
531 ok(r
==STG_E_INVALIDPARAMETER
, "IStorage->CreateStream wrong error\n");
532 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, NULL
);
533 ok(r
==STG_E_INVALIDPOINTER
, "IStorage->CreateStream wrong error\n");
534 r
= IStorage_CreateStream(stg
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
535 ok(r
==STG_E_INVALIDNAME
, "IStorage->CreateStream wrong error\n");
536 r
= IStorage_CreateStream(stg
, longname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
537 ok(r
==STG_E_INVALIDNAME
|| broken(r
==S_OK
) /* nt4 */,
538 "IStorage->CreateStream wrong error, got %d GetLastError()=%d\n", r
, GetLastError());
539 r
= IStorage_CreateStream(stg
, stmname
, STGM_READWRITE
, 0, 0, &stm
);
540 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
541 r
= IStorage_CreateStream(stg
, stmname
, STGM_READ
, 0, 0, &stm
);
542 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
543 r
= IStorage_CreateStream(stg
, stmname
, STGM_WRITE
, 0, 0, &stm
);
544 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
545 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_DENY_NONE
| STGM_READWRITE
, 0, 0, &stm
);
546 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
547 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_DENY_NONE
| STGM_READ
, 0, 0, &stm
);
548 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
550 /* now really create a stream and delete it */
551 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
552 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
554 /* test for support interfaces */
555 r
= IStream_QueryInterface(stm
, &IID_IPersist
, (void**)&unk
);
556 ok(r
==E_NOINTERFACE
, "got 0x%08x\n", r
);
557 r
= IStream_QueryInterface(stm
, &IID_IPersistStream
, (void**)&unk
);
558 ok(r
==E_NOINTERFACE
, "got 0x%08x\n", r
);
560 r
= IStream_Release(stm
);
561 ok(r
== 0, "wrong ref count\n");
562 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
563 ok(r
==STG_E_FILEALREADYEXISTS
, "IStorage->CreateStream failed\n");
564 r
= IStorage_DestroyElement(stg
,stmname
);
565 ok(r
==S_OK
, "IStorage->DestroyElement failed\n");
567 /* create a stream and write to it */
568 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
569 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
571 r
= IStream_Clone(stm
, &stm2
);
572 ok(r
==S_OK
, "failed to clone stream\n");
574 r
= IStream_Write(stm
, NULL
, 0, NULL
);
575 ok(r
==STG_E_INVALIDPOINTER
, "IStream->Write wrong error\n");
576 r
= IStream_Write(stm
, "Hello\n", 0, NULL
);
577 ok(r
==S_OK
, "failed to write stream\n");
578 r
= IStream_Write(stm
, "Hello\n", 0, &count
);
579 ok(r
==S_OK
, "failed to write stream\n");
580 r
= IStream_Write(stm
, "Hello\n", 6, &count
);
581 ok(r
==S_OK
, "failed to write stream\n");
582 r
= IStream_Commit(stm
, STGC_DEFAULT
);
583 ok(r
==S_OK
, "failed to commit stream\n");
584 r
= IStream_Commit(stm
, STGC_DEFAULT
);
585 ok(r
==S_OK
, "failed to commit stream\n");
587 /* Read past the end of the stream. */
589 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
590 ok(r
==S_OK
, "failed to seek stream\n");
591 ok(p
.QuadPart
== 3, "at wrong place\n");
592 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
593 ok(r
==S_OK
, "failed to read\n");
594 ok(count
== 3, "read bytes past end of stream\n");
596 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
597 ok(r
==S_OK
, "failed to seek stream\n");
598 ok(p
.QuadPart
== 10, "at wrong place\n");
599 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
600 ok(r
==S_OK
, "failed to read\n");
601 ok(count
== 0, "read bytes past end of stream\n");
602 pos
.QuadPart
= 10000;
603 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
604 ok(r
==S_OK
, "failed to seek stream\n");
605 ok(p
.QuadPart
== 10000, "at wrong place\n");
606 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
607 ok(r
==S_OK
, "failed to read\n");
608 ok(count
== 0, "read bytes past end of stream\n");
610 /* Convert to a big block stream, and read past the end. */
612 r
= IStream_SetSize(stm
,p
);
613 ok(r
==S_OK
, "failed to set pos\n");
615 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
616 ok(r
==S_OK
, "failed to seek stream\n");
617 ok(p
.QuadPart
== 4997, "at wrong place\n");
618 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
619 ok(r
==S_OK
, "failed to read\n");
620 ok(count
== 3, "read bytes past end of stream\n");
622 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
623 ok(r
==S_OK
, "failed to seek stream\n");
624 ok(p
.QuadPart
== 5001, "at wrong place\n");
625 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
626 ok(r
==S_OK
, "failed to read\n");
627 ok(count
== 0, "read bytes past end of stream\n");
628 pos
.QuadPart
= 10000;
629 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
630 ok(r
==S_OK
, "failed to seek stream\n");
631 ok(p
.QuadPart
== 10000, "at wrong place\n");
632 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
633 ok(r
==S_OK
, "failed to read\n");
634 ok(count
== 0, "read bytes past end of stream\n");
636 /* seek round a bit, reset the stream size */
638 r
= IStream_Seek(stm
, pos
, 3, &p
);
639 ok(r
==STG_E_INVALIDFUNCTION
, "IStream->Seek returned wrong error\n");
640 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, NULL
);
641 ok(r
==S_OK
, "failed to seek stream\n");
642 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
643 ok(r
==S_OK
, "failed to seek stream\n");
644 r
= IStream_SetSize(stm
,p
);
645 ok(r
==S_OK
, "failed to set pos\n");
647 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
648 ok(r
==S_OK
, "failed to seek stream\n");
649 ok(p
.QuadPart
== 10, "at wrong place\n");
650 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
651 ok(r
==S_OK
, "failed to set pos\n");
652 ok(count
== 0, "read bytes from empty stream\n");
653 pos
.QuadPart
= 10000;
654 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
655 ok(r
==S_OK
, "failed to seek stream\n");
656 ok(p
.QuadPart
== 10000, "at wrong place\n");
657 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
658 ok(r
==S_OK
, "failed to set pos\n");
659 ok(count
== 0, "read bytes from empty stream\n");
661 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_END
, &p
);
662 ok(r
==S_OK
, "failed to seek stream\n");
663 ok(p
.QuadPart
== 0, "at wrong place\n");
664 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
665 ok(r
==S_OK
, "failed to set pos\n");
666 ok(count
== 0, "read bytes from empty stream\n");
669 r
= IStream_Release(stm2
);
670 ok(r
== 0, "wrong ref count\n");
672 /* create a stream and write to it */
673 r
= IStorage_CreateStream(stg
, stmname
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm2
);
674 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
676 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
677 ok(r
==STG_E_REVERTED
, "overwritten stream should return STG_E_REVERTED instead of 0x%08x\n", r
);
679 r
= IStream_Release(stm2
);
680 ok(r
== 0, "wrong ref count\n");
681 r
= IStream_Release(stm
);
682 ok(r
== 0, "wrong ref count\n");
684 r
= IStorage_Release(stg
);
685 ok(r
== 0, "wrong ref count\n");
687 /* try create some invalid streams */
690 r
= StgOpenStorage(filename
, NULL
, STGM_READ
| STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
691 ok(r
== S_OK
, "should succeed\n");
694 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stm
);
695 ok(r
== STG_E_INVALIDFLAG
, "IStorage->OpenStream should return STG_E_INVALIDFLAG instead of 0x%08x\n", r
);
696 IStorage_Release(stg
);
699 ret
= DeleteFileA(filenameA
);
700 ok(ret
, "file should exist\n");
703 static BOOL
touch_file(LPCSTR filename
)
707 file
= CreateFileA(filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
708 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
709 if (file
==INVALID_HANDLE_VALUE
)
715 static BOOL
is_zero_length(LPCSTR filename
)
720 file
= CreateFileA(filename
, GENERIC_READ
, 0, NULL
,
721 OPEN_EXISTING
, 0, NULL
);
722 if (file
==INVALID_HANDLE_VALUE
)
724 len
= GetFileSize(file
, NULL
);
729 static BOOL
is_existing_file(LPCSTR filename
)
733 file
= CreateFileA(filename
, GENERIC_READ
, 0, NULL
,
734 OPEN_EXISTING
, 0, NULL
);
735 if (file
==INVALID_HANDLE_VALUE
)
741 static void test_open_storage(void)
743 static const WCHAR szNonExist
[] = { 'n','o','n','e','x','i','s','t',0 };
744 IStorage
*stg
= NULL
, *stg2
= NULL
;
749 /* try opening a zero length file - it should stay zero length */
750 DeleteFileA(filenameA
);
751 touch_file(filenameA
);
752 stgm
= STGM_NOSCRATCH
| STGM_TRANSACTED
| STGM_SHARE_DENY_WRITE
| STGM_READWRITE
;
753 r
= StgOpenStorage( filename
, NULL
, stgm
, NULL
, 0, &stg
);
754 ok(r
==STG_E_FILEALREADYEXISTS
, "StgOpenStorage didn't fail\n");
756 stgm
= STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
;
757 r
= StgOpenStorage( filename
, NULL
, stgm
, NULL
, 0, &stg
);
758 ok(r
==STG_E_FILEALREADYEXISTS
, "StgOpenStorage didn't fail\n");
759 ok(is_zero_length(filenameA
), "file length changed\n");
761 DeleteFileA(filenameA
);
763 /* try opening a nonexistent file - it should not create it */
764 stgm
= STGM_DIRECT
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
;
765 r
= StgOpenStorage( filename
, NULL
, stgm
, NULL
, 0, &stg
);
766 ok(r
!=S_OK
, "StgOpenStorage failed: 0x%08x\n", r
);
767 if (r
==S_OK
) IStorage_Release(stg
);
768 ok(!is_existing_file(filenameA
), "StgOpenStorage should not create a file\n");
769 DeleteFileA(filenameA
);
771 /* create the file */
772 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
773 ok(r
==S_OK
, "StgCreateDocfile failed\n");
774 IStorage_Release(stg
);
776 r
= StgOpenStorage( filename
, NULL
, 0, NULL
, 0, &stg
);
777 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage wrong error\n");
778 r
= StgOpenStorage( NULL
, NULL
, STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
779 ok(r
==STG_E_INVALIDNAME
, "StgOpenStorage wrong error\n");
780 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, NULL
);
781 ok(r
==STG_E_INVALIDPOINTER
, "StgOpenStorage wrong error\n");
782 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 1, &stg
);
783 ok(r
==STG_E_INVALIDPARAMETER
, "StgOpenStorage wrong error\n");
784 r
= StgOpenStorage( szNonExist
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
785 ok(r
==STG_E_FILENOTFOUND
, "StgOpenStorage failed\n");
786 r
= StgOpenStorage( filename
, NULL
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
787 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
788 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_NONE
| STGM_READ
, NULL
, 0, &stg
);
789 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
790 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_READ
| STGM_READ
, NULL
, 0, &stg
);
791 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
792 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, NULL
, 0, &stg
);
793 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
795 /* open it for real */
796 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_NONE
| STGM_READ
| STGM_TRANSACTED
, NULL
, 0, &stg
); /* XLViewer 97/2000 */
797 ok(r
==S_OK
, "StgOpenStorage failed\n");
800 r
= IStorage_Release(stg
);
801 ok(r
== 0, "wrong ref count\n");
804 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_WRITE
| STGM_READ
, NULL
, 0, &stg
);
805 ok(r
==S_OK
, "StgOpenStorage failed\n");
808 r
= IStorage_Release(stg
);
809 ok(r
== 0, "wrong ref count\n");
812 /* test the way word opens its custom dictionary */
813 r
= StgOpenStorage( filename
, NULL
, STGM_NOSCRATCH
| STGM_TRANSACTED
|
814 STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, NULL
, 0, &stg
);
815 ok(r
==S_OK
, "StgOpenStorage failed\n");
818 r
= IStorage_Release(stg
);
819 ok(r
== 0, "wrong ref count\n");
822 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
823 ok(r
==S_OK
, "StgOpenStorage failed\n");
824 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg2
);
825 ok(r
==STG_E_SHAREVIOLATION
, "StgOpenStorage failed\n");
828 r
= IStorage_Release(stg
);
829 ok(r
== 0, "wrong ref count\n");
832 /* now try write to a storage file we opened read-only */
833 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
834 ok(r
==S_OK
, "StgOpenStorage failed\n");
837 static const WCHAR stmname
[] = { 'w','i','n','e','t','e','s','t',0};
839 IStorage
*stg2
= NULL
;
841 r
= IStorage_CreateStream( stg
, stmname
, STGM_WRITE
| STGM_SHARE_EXCLUSIVE
,
843 ok(r
== STG_E_ACCESSDENIED
, "CreateStream should fail\n");
844 r
= IStorage_CreateStorage( stg
, stmname
, STGM_WRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
845 ok(r
== STG_E_ACCESSDENIED
, "CreateStream should fail\n");
847 r
= IStorage_Release(stg
);
848 ok(r
== 0, "wrong ref count\n");
851 /* open like visio 2003 */
853 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_DENY_NONE
, NULL
, 0, &stg
);
854 ok(r
== S_OK
, "should succeed\n");
856 IStorage_Release(stg
);
858 /* test other sharing modes with STGM_PRIORITY */
860 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
861 ok(r
== S_OK
, "should succeed\n");
863 IStorage_Release(stg
);
866 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
867 ok(r
== S_OK
, "should succeed\n");
869 IStorage_Release(stg
);
872 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_DENY_READ
, NULL
, 0, &stg
);
873 ok(r
== S_OK
, "should succeed\n");
875 IStorage_Release(stg
);
877 /* open like Project 2003 */
879 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stg
);
880 ok(r
== S_OK
, "should succeed\n");
881 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stg2
);
882 ok(r
== S_OK
, "should succeed\n");
884 IStorage_Release(stg2
);
886 IStorage_Release(stg
);
889 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_READWRITE
, NULL
, 0, &stg
);
890 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
892 r
= StgOpenStorage( filename
, NULL
, STGM_TRANSACTED
| STGM_PRIORITY
, NULL
, 0, &stg
);
893 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
895 r
= StgOpenStorage( filename
, NULL
, STGM_SIMPLE
| STGM_PRIORITY
, NULL
, 0, &stg
);
896 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
898 r
= StgOpenStorage( filename
, NULL
, STGM_DELETEONRELEASE
| STGM_PRIORITY
, NULL
, 0, &stg
);
899 ok(r
== STG_E_INVALIDFUNCTION
, "should fail\n");
901 r
= StgOpenStorage( filename
, NULL
, STGM_NOSCRATCH
| STGM_PRIORITY
, NULL
, 0, &stg
);
902 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
904 r
= StgOpenStorage( filename
, NULL
, STGM_NOSNAPSHOT
| STGM_PRIORITY
, NULL
, 0, &stg
);
905 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
907 ret
= DeleteFileA(filenameA
);
908 ok(ret
, "file didn't exist\n");
911 static void test_storage_suminfo(void)
913 IStorage
*stg
= NULL
;
914 IPropertySetStorage
*propset
= NULL
;
915 IPropertyStorage
*ps
= NULL
;
918 DeleteFileA(filenameA
);
920 /* create the file */
921 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
922 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
923 ok(r
==S_OK
, "StgCreateDocfile failed\n");
925 r
= IStorage_QueryInterface( stg
, &IID_IPropertySetStorage
, (LPVOID
) &propset
);
926 ok(r
== S_OK
, "query interface failed\n");
929 r
= IPropertySetStorage_Delete( propset
, &FMTID_SummaryInformation
);
930 ok(r
== STG_E_FILENOTFOUND
, "deleted property set storage\n");
932 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
933 STGM_READ
| STGM_SHARE_EXCLUSIVE
, &ps
);
934 ok(r
== STG_E_FILENOTFOUND
, "opened property set storage\n");
936 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
937 STGM_READ
| STGM_SHARE_EXCLUSIVE
, &ps
);
938 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
940 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
942 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
944 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0, 0, &ps
);
945 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
947 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
948 STGM_WRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
949 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
951 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
952 STGM_CREATE
|STGM_WRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
953 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
955 /* now try really creating a property set */
956 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
957 STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
958 ok(r
== S_OK
, "failed to create property set storage\n");
961 IPropertyStorage_Release(ps
);
963 /* now try creating the same thing again */
964 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
965 STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
966 ok(r
== S_OK
, "failed to create property set storage\n");
968 IPropertyStorage_Release(ps
);
970 /* should be able to open it */
971 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
972 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
973 ok(r
== S_OK
, "open failed\n");
975 IPropertyStorage_Release(ps
);
978 r
= IPropertySetStorage_Delete( propset
, &FMTID_SummaryInformation
);
979 ok(r
== S_OK
, "failed to delete property set storage\n");
981 /* try opening with an invalid FMTID */
982 r
= IPropertySetStorage_Open( propset
, NULL
,
983 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
984 ok(r
== E_INVALIDARG
, "open succeeded\n");
986 IPropertyStorage_Release(ps
);
989 r
= IPropertySetStorage_Open( propset
, &IID_IStorage
,
990 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
991 ok(r
== STG_E_FILENOTFOUND
, "open succeeded\n");
993 IPropertyStorage_Release(ps
);
996 /* try some invalid flags */
997 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
998 STGM_CREATE
| STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
999 ok(r
== STG_E_INVALIDFLAG
, "open succeeded\n");
1001 IPropertyStorage_Release(ps
);
1003 /* after deleting it, it should be gone */
1004 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
1005 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
1006 ok(r
== STG_E_FILENOTFOUND
, "open failed\n");
1008 IPropertyStorage_Release(ps
);
1010 r
= IPropertySetStorage_Release( propset
);
1011 ok(r
== 1, "ref count wrong\n");
1013 r
= IStorage_Release(stg
);
1014 ok(r
== 0, "ref count wrong\n");
1016 DeleteFileA(filenameA
);
1019 static void test_storage_refcount(void)
1021 IStorage
*stg
= NULL
;
1022 IStorage
*stgprio
= NULL
;
1024 IStream
*stm
= NULL
;
1025 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1027 ULARGE_INTEGER upos
;
1031 DeleteFileA(filenameA
);
1033 /* create the file */
1034 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1035 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
1036 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1038 r
= WriteClassStg( stg
, &test_stg_cls
);
1039 ok( r
== S_OK
, "WriteClassStg failed\n");
1041 r
= IStorage_Commit( stg
, STGC_DEFAULT
);
1042 ok( r
== S_OK
, "IStorage_Commit failed\n");
1044 /* now create a stream */
1045 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1046 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1048 r
= IStorage_Release( stg
);
1049 ok (r
== 0, "storage not released\n");
1052 r
= IStream_Seek( stm
, pos
, 0, &upos
);
1053 ok (r
== STG_E_REVERTED
, "seek should fail\n");
1055 r
= IStream_Stat( stm
, &stat
, STATFLAG_DEFAULT
);
1056 ok (r
== STG_E_REVERTED
, "stat should fail\n");
1058 r
= IStream_Write( stm
, "Test string", strlen("Test string"), NULL
);
1059 ok (r
== STG_E_REVERTED
, "IStream_Write should return STG_E_REVERTED instead of 0x%08x\n", r
);
1061 r
= IStream_Read( stm
, buffer
, sizeof(buffer
), NULL
);
1062 ok (r
== STG_E_REVERTED
, "IStream_Read should return STG_E_REVERTED instead of 0x%08x\n", r
);
1064 r
= IStream_Release(stm
);
1065 ok (r
== 0, "stream not released\n");
1067 /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
1068 * StgOpenStorage calls in transacted mode */
1069 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stgprio
);
1070 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
1072 /* non-transacted mode read/write fails */
1073 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg
);
1074 ok(r
==STG_E_LOCKVIOLATION
, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r
);
1076 /* non-transacted mode read-only succeeds */
1077 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_WRITE
|STGM_READ
, NULL
, 0, &stg
);
1078 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
1079 IStorage_Release(stg
);
1081 r
= StgOpenStorage( filename
, NULL
, STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, NULL
, 0, &stg
);
1082 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
1085 static const WCHAR stgname
[] = { ' ',' ',' ','2','9',0 };
1086 static const WCHAR stgname2
[] = { 'C','V','_','i','e','w',0 };
1087 static const WCHAR stmname2
[] = { 'V','a','r','2','D','a','t','a',0 };
1092 r
= IStorage_Stat( stg
, &statstg
, STATFLAG_NONAME
);
1093 ok(r
== S_OK
, "Stat should have succeeded instead of returning 0x%08x\n", r
);
1094 ok(statstg
.type
== STGTY_STORAGE
, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg
.type
);
1095 ok(U(statstg
.cbSize
).LowPart
== 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg
.cbSize
).LowPart
);
1096 ok(U(statstg
.cbSize
).HighPart
== 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg
.cbSize
).HighPart
);
1097 ok(statstg
.grfMode
== (STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
),
1098 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg
.grfMode
);
1099 ok(statstg
.grfLocksSupported
== 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg
.grfLocksSupported
);
1100 ok(IsEqualCLSID(&statstg
.clsid
, &test_stg_cls
), "Statstg clsid is not test_stg_cls\n");
1101 ok(statstg
.grfStateBits
== 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg
.grfStateBits
);
1102 ok(statstg
.reserved
== 0, "Statstg reserved should have been 0 instead of %d\n", statstg
.reserved
);
1104 r
= IStorage_CreateStorage( stg
, stgname
, STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1105 ok(r
== S_OK
, "CreateStorage should have succeeded instead of returning 0x%08x\n", r
);
1107 r
= IStorage_Stat( stg2
, &statstg
, STATFLAG_DEFAULT
);
1108 ok(r
== S_OK
, "Stat should have succeeded instead of returning 0x%08x\n", r
);
1109 ok(!memcmp(statstg
.pwcsName
, stgname
, sizeof(stgname
)),
1110 "Statstg pwcsName should have been the name the storage was created with\n");
1111 ok(statstg
.type
== STGTY_STORAGE
, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg
.type
);
1112 ok(U(statstg
.cbSize
).LowPart
== 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg
.cbSize
).LowPart
);
1113 ok(U(statstg
.cbSize
).HighPart
== 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg
.cbSize
).HighPart
);
1114 ok(statstg
.grfMode
== STGM_SHARE_EXCLUSIVE
,
1115 "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%x\n", statstg
.grfMode
);
1116 ok(statstg
.grfLocksSupported
== 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg
.grfLocksSupported
);
1117 ok(IsEqualCLSID(&statstg
.clsid
, &CLSID_NULL
), "Statstg clsid is not CLSID_NULL\n");
1118 ok(statstg
.grfStateBits
== 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg
.grfStateBits
);
1119 ok(statstg
.reserved
== 0, "Statstg reserved should have been 0 instead of %d\n", statstg
.reserved
);
1120 CoTaskMemFree(statstg
.pwcsName
);
1122 r
= IStorage_CreateStorage( stg2
, stgname2
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, 0, &stg3
);
1123 ok(r
== STG_E_ACCESSDENIED
, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r
);
1125 r
= IStorage_CreateStream( stg2
, stmname2
, STGM_CREATE
|STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
1126 ok(r
== STG_E_ACCESSDENIED
, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r
);
1128 IStorage_Release(stg2
);
1130 r
= IStorage_Release(stg
);
1131 ok(r
== 0, "wrong ref count\n");
1134 /* Multiple STGM_PRIORITY opens are possible. */
1135 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stg
);
1136 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
1139 r
= IStorage_Release(stg
);
1140 ok(r
== 0, "wrong ref count\n");
1143 r
= StgOpenStorage( NULL
, stgprio
, STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, NULL
, 0, &stg
);
1144 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
1147 static const WCHAR stgname
[] = { ' ',' ',' ','2','9',0 };
1151 r
= IStorage_Stat( stg
, &statstg
, STATFLAG_NONAME
);
1152 ok(r
== S_OK
, "Stat should have succeeded instead of returning 0x%08x\n", r
);
1153 ok(statstg
.type
== STGTY_STORAGE
, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg
.type
);
1154 ok(U(statstg
.cbSize
).LowPart
== 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg
.cbSize
).LowPart
);
1155 ok(U(statstg
.cbSize
).HighPart
== 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg
.cbSize
).HighPart
);
1156 ok(statstg
.grfMode
== (STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
),
1157 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg
.grfMode
);
1158 ok(statstg
.grfLocksSupported
== 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg
.grfLocksSupported
);
1159 ok(IsEqualCLSID(&statstg
.clsid
, &test_stg_cls
), "Statstg clsid is not test_stg_cls\n");
1160 ok(statstg
.grfStateBits
== 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg
.grfStateBits
);
1161 ok(statstg
.reserved
== 0, "Statstg reserved should have been 0 instead of %d\n", statstg
.reserved
);
1163 r
= IStorage_CreateStorage( stg
, stgname
, STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1164 ok(r
== S_OK
, "CreateStorage should have succeeded instead of returning 0x%08x\n", r
);
1166 IStorage_Release(stg2
);
1168 r
= IStorage_Commit( stg
, 0 );
1169 ok(r
== S_OK
, "Commit should have succeeded instead of returning 0x%08x\n", r
);
1171 r
= IStorage_Release(stg
);
1172 ok(r
== 0, "wrong ref count\n");
1174 /* IStorage_Release(stgprio) not necessary because StgOpenStorage released it. */
1176 DeleteFileA(filenameA
);
1179 static void test_writeclassstg(void)
1181 IStorage
*stg
= NULL
;
1185 DeleteFileA(filenameA
);
1187 /* create the file */
1188 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1189 STGM_READWRITE
, 0, &stg
);
1190 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1192 r
= ReadClassStg( NULL
, NULL
);
1193 ok(r
== E_INVALIDARG
, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r
);
1195 r
= ReadClassStg( stg
, NULL
);
1196 ok(r
== E_INVALIDARG
, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r
);
1198 temp_cls
.Data1
= 0xdeadbeef;
1199 r
= ReadClassStg( stg
, &temp_cls
);
1200 ok(r
== S_OK
, "ReadClassStg failed with 0x%08X\n", r
);
1202 ok(IsEqualCLSID(&temp_cls
, &CLSID_NULL
), "ReadClassStg returned wrong clsid\n");
1204 r
= WriteClassStg( NULL
, NULL
);
1205 ok(r
== E_INVALIDARG
, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r
);
1207 r
= WriteClassStg( stg
, NULL
);
1208 ok(r
== STG_E_INVALIDPOINTER
, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r
);
1210 r
= WriteClassStg( stg
, &test_stg_cls
);
1211 ok( r
== S_OK
, "WriteClassStg failed with 0x%08X\n", r
);
1213 r
= ReadClassStg( stg
, &temp_cls
);
1214 ok( r
== S_OK
, "ReadClassStg failed with 0x%08X\n", r
);
1215 ok(IsEqualCLSID(&temp_cls
, &test_stg_cls
), "ReadClassStg returned wrong clsid\n");
1217 r
= IStorage_Release( stg
);
1218 ok (r
== 0, "storage not released\n");
1220 DeleteFileA(filenameA
);
1223 static void test_streamenum(void)
1225 IStorage
*stg
= NULL
;
1227 IStream
*stm
= NULL
;
1228 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1229 static const WCHAR stmname2
[] = { 'A','B','C','D','E','F','G','H','I',0 };
1230 static const WCHAR stmname3
[] = { 'A','B','C','D','E','F','G','H','I','J',0 };
1231 static const STATSTG stat_null
;
1233 IEnumSTATSTG
*ee
= NULL
;
1236 DeleteFileA(filenameA
);
1238 /* create the file */
1239 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1240 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
1241 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1243 r
= WriteClassStg( stg
, &test_stg_cls
);
1244 ok( r
== S_OK
, "WriteClassStg failed\n");
1246 r
= IStorage_Commit( stg
, STGC_DEFAULT
);
1247 ok( r
== S_OK
, "IStorage_Commit failed\n");
1249 /* now create a stream */
1250 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1251 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1253 IStream_Release(stm
);
1255 /* first enum ... should be 1 stream */
1256 r
= IStorage_EnumElements(stg
, 0, NULL
, 0, &ee
);
1257 ok(r
==S_OK
, "IStorage->EnumElements failed\n");
1260 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1261 ok(r
==S_OK
, "IEnumSTATSTG->Next failed\n");
1262 ok(count
== 1, "count wrong\n");
1265 CoTaskMemFree(stat
.pwcsName
);
1267 r
= IEnumSTATSTG_Release(ee
);
1268 ok(r
==S_OK
, "EnumSTATSTG_Release failed with error 0x%08x\n", r
);
1270 /* second enum... destroy the stream before reading */
1271 r
= IStorage_EnumElements(stg
, 0, NULL
, 0, &ee
);
1272 ok(r
==S_OK
, "IStorage->EnumElements failed\n");
1274 r
= IStorage_DestroyElement(stg
, stmname
);
1275 ok(r
==S_OK
, "IStorage->DestroyElement failed\n");
1277 memset(&stat
, 0xad, sizeof(stat
));
1279 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1280 ok(r
==S_FALSE
, "IEnumSTATSTG->Next failed\n");
1281 ok(count
== 0, "count wrong\n");
1282 ok(memcmp(&stat
, &stat_null
, sizeof(stat
)) == 0, "stat is not zeroed\n");
1284 /* reset and try again */
1285 r
= IEnumSTATSTG_Reset(ee
);
1286 ok(r
==S_OK
, "IEnumSTATSTG->Reset failed\n");
1289 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1290 ok(r
==S_FALSE
, "IEnumSTATSTG->Next failed\n");
1291 ok(count
== 0, "count wrong\n");
1293 /* add a stream before reading */
1294 r
= IEnumSTATSTG_Reset(ee
);
1295 ok(r
==S_OK
, "IEnumSTATSTG->Reset failed\n");
1297 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1298 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1300 r
= IStream_Release(stm
);
1301 ok(r
==S_OK
, "Stream_Release failed with error 0x%08x\n", r
);
1304 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1305 ok(r
==S_OK
, "IEnumSTATSTG->Next failed\n");
1306 ok(count
== 1, "count wrong\n");
1310 ok(lstrcmpiW(stat
.pwcsName
, stmname
) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat
.pwcsName
));
1311 CoTaskMemFree(stat
.pwcsName
);
1314 r
= IStorage_CreateStream(stg
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1315 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1317 r
= IStream_Release(stm
);
1318 ok(r
==S_OK
, "Stream_Release failed with error 0x%08x\n", r
);
1321 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1322 ok(r
==S_OK
, "IEnumSTATSTG->Next failed\n");
1323 ok(count
== 1, "count wrong\n");
1327 ok(lstrcmpiW(stat
.pwcsName
, stmname2
) == 0, "expected ABCDEFGHI, got %s\n", wine_dbgstr_w(stat
.pwcsName
));
1328 CoTaskMemFree(stat
.pwcsName
);
1331 /* delete previous and next stream after reading */
1332 r
= IStorage_CreateStream(stg
, stmname3
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1333 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1335 r
= IStream_Release(stm
);
1336 ok(r
==S_OK
, "Stream_Release failed with error 0x%08x\n", r
);
1338 r
= IEnumSTATSTG_Reset(ee
);
1339 ok(r
==S_OK
, "IEnumSTATSTG->Reset failed\n");
1342 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1343 ok(r
==S_OK
, "IEnumSTATSTG->Next failed\n");
1344 ok(count
== 1, "count wrong\n");
1348 ok(lstrcmpiW(stat
.pwcsName
, stmname
) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat
.pwcsName
));
1349 CoTaskMemFree(stat
.pwcsName
);
1352 r
= IStorage_DestroyElement(stg
, stmname
);
1353 ok(r
==S_OK
, "IStorage->DestroyElement failed\n");
1355 r
= IStorage_DestroyElement(stg
, stmname2
);
1356 ok(r
==S_OK
, "IStorage->DestroyElement failed\n");
1359 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1360 ok(r
==S_OK
, "IEnumSTATSTG->Next failed\n");
1361 ok(count
== 1, "count wrong\n");
1365 ok(lstrcmpiW(stat
.pwcsName
, stmname3
) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat
.pwcsName
));
1366 CoTaskMemFree(stat
.pwcsName
);
1369 r
= IStorage_Release( stg
);
1370 todo_wine
ok (r
== 0, "storage not released\n");
1372 /* enumerator is still valid and working after the storage is released */
1373 r
= IEnumSTATSTG_Reset(ee
);
1374 ok(r
==S_OK
, "IEnumSTATSTG->Reset failed\n");
1377 r
= IEnumSTATSTG_Next(ee
, 1, &stat
, &count
);
1378 ok(r
==S_OK
, "IEnumSTATSTG->Next failed\n");
1379 ok(count
== 1, "count wrong\n");
1383 ok(lstrcmpiW(stat
.pwcsName
, stmname3
) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat
.pwcsName
));
1384 CoTaskMemFree(stat
.pwcsName
);
1387 /* the storage is left open until the enumerator is freed */
1388 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
|
1389 STGM_READWRITE
|STGM_TRANSACTED
, NULL
, 0, &stg
);
1390 ok(r
==STG_E_SHAREVIOLATION
||
1391 r
==STG_E_LOCKVIOLATION
, /* XP-SP2/W2K3-SP1 and below */
1392 "StgCreateDocfile failed, res=%x\n", r
);
1394 r
= IEnumSTATSTG_Release(ee
);
1395 ok (r
== 0, "enum not released\n");
1397 DeleteFileA(filenameA
);
1400 static void test_transact(void)
1402 IStorage
*stg
= NULL
, *stg2
= NULL
, *stg3
= NULL
;
1404 IStream
*stm
= NULL
;
1405 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1406 static const WCHAR stmname2
[] = { 'F','O','O',0 };
1407 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
1408 static const WCHAR stgname2
[] = { 'T','E','M','P','S','T','G',0 };
1411 DeleteFileA(filenameA
);
1413 /* create the file */
1414 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1415 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
1416 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1418 /* commit a new stream and storage */
1419 r
= IStorage_CreateStream(stg
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1420 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1422 r
= IStream_Write(stm
, "this is stream 1\n", 16, NULL
);
1423 ok(r
==S_OK
, "IStream->Write failed\n");
1425 IStream_Release(stm
);
1427 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1428 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1432 /* Create two substorages but only commit one */
1433 r
= IStorage_CreateStorage(stg2
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1434 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1437 IStorage_Release(stg3
);
1439 r
= IStorage_Commit(stg
, 0);
1440 ok(r
==S_OK
, "IStorage->Commit failed\n");
1442 r
= IStorage_CreateStorage(stg2
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1443 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1446 IStorage_Release(stg3
);
1448 IStorage_Release(stg2
);
1451 /* now create a stream and storage, but don't commit them */
1453 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1454 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1456 r
= IStream_Write(stm
, "this is stream 2\n", 16, NULL
);
1457 ok(r
==S_OK
, "IStream->Write failed\n");
1459 /* IStream::Commit does nothing for OLE storage streams */
1460 r
= IStream_Commit(stm
, STGC_ONLYIFCURRENT
| STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE
);
1461 ok(r
==S_OK
, "IStream->Commit failed\n");
1463 r
= IStorage_CreateStorage(stg
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1464 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1467 IStorage_Release(stg2
);
1469 IStream_Release(stm
);
1471 IStorage_Release(stg
);
1475 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_NONE
| STGM_READ
| STGM_TRANSACTED
, NULL
, 0, &stg
);
1476 ok(r
==S_OK
, "StgOpenStorage failed\n");
1481 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_SHARE_DENY_NONE
|STGM_READ
, 0, &stm
);
1482 ok(r
==STG_E_INVALIDFLAG
, "IStorage->OpenStream failed %08x\n", r
);
1484 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_DELETEONRELEASE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1485 ok(r
==STG_E_INVALIDFUNCTION
, "IStorage->OpenStream failed %08x\n", r
);
1487 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_TRANSACTED
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1488 ok(r
==STG_E_INVALIDFUNCTION
, "IStorage->OpenStream failed %08x\n", r
);
1490 r
= IStorage_OpenStorage(stg
, stmname
, NULL
, STGM_TRANSACTED
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1491 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream failed %08x\n", r
);
1493 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1494 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream should fail %08x\n", r
);
1496 IStream_Release(stm
);
1498 r
= IStorage_OpenStorage(stg
, stgname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1499 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStorage should fail %08x\n", r
);
1501 IStorage_Release(stg2
);
1503 r
= IStorage_OpenStorage(stg
, stmname2
, NULL
, STGM_TRANSACTED
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1504 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream failed %08x\n", r
);
1506 r
= IStorage_OpenStream(stg
, stmname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1507 ok(r
==S_OK
, "IStorage->OpenStream should succeed %08x\n", r
);
1509 IStream_Release(stm
);
1511 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1512 ok(r
==S_OK
, "IStorage->OpenStorage should succeed %08x\n", r
);
1515 r
= IStorage_OpenStorage(stg2
, stgname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg3
);
1516 ok(r
==S_OK
, "IStorage->OpenStorage should succeed %08x\n", r
);
1518 IStorage_Release(stg3
);
1520 r
= IStorage_OpenStorage(stg2
, stgname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg3
);
1521 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStorage should fail %08x\n", r
);
1523 IStorage_Release(stg3
);
1525 IStorage_Release(stg2
);
1528 IStorage_Release(stg
);
1530 ret
= DeleteFileA(filenameA
);
1531 ok(ret
, "deleted file\n");
1534 static void test_substorage_share(void)
1536 IStorage
*stg
, *stg2
, *stg3
;
1537 IStream
*stm
, *stm2
;
1539 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
1540 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1541 static const WCHAR othername
[] = { 'N','E','W','N','A','M','E',0 };
1544 DeleteFileA(filenameA
);
1546 /* create the file */
1547 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1548 STGM_READWRITE
, 0, &stg
);
1549 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1551 /* create a read/write storage and try to open it again */
1552 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1553 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1557 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1558 ok(r
==STG_E_ACCESSDENIED
, "IStorage->OpenStorage should fail %08x\n", r
);
1561 IStorage_Release(stg3
);
1563 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1564 ok(r
==STG_E_ACCESSDENIED
, "IStorage->OpenStorage should fail %08x\n", r
);
1567 IStorage_Release(stg3
);
1569 /* cannot rename the storage while it's open */
1570 r
= IStorage_RenameElement(stg
, stgname
, othername
);
1571 ok(r
==STG_E_ACCESSDENIED
, "IStorage->RenameElement should fail %08x\n", r
);
1572 if (SUCCEEDED(r
)) IStorage_RenameElement(stg
, othername
, stgname
);
1574 /* destroying an object while it's open invalidates it */
1575 r
= IStorage_DestroyElement(stg
, stgname
);
1576 ok(r
==S_OK
, "IStorage->DestroyElement failed, hr=%08x\n", r
);
1578 r
= IStorage_CreateStream(stg2
, stmname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
1579 ok(r
==STG_E_REVERTED
, "IStorage->CreateStream failed, hr=%08x\n", r
);
1582 IStream_Release(stm
);
1584 IStorage_Release(stg2
);
1587 /* create a read/write stream and try to open it again */
1588 r
= IStorage_CreateStream(stg
, stmname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
1589 ok(r
==S_OK
, "IStorage->CreateStream failed, hr=%08x\n", r
);
1593 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stm2
);
1594 ok(r
==STG_E_ACCESSDENIED
, "IStorage->OpenStream should fail %08x\n", r
);
1597 IStream_Release(stm2
);
1599 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stm2
);
1600 ok(r
==STG_E_ACCESSDENIED
, "IStorage->OpenStream should fail %08x\n", r
);
1603 IStream_Release(stm2
);
1605 /* cannot rename the stream while it's open */
1606 r
= IStorage_RenameElement(stg
, stmname
, othername
);
1607 ok(r
==STG_E_ACCESSDENIED
, "IStorage->RenameElement should fail %08x\n", r
);
1608 if (SUCCEEDED(r
)) IStorage_RenameElement(stg
, othername
, stmname
);
1610 /* destroying an object while it's open invalidates it */
1611 r
= IStorage_DestroyElement(stg
, stmname
);
1612 ok(r
==S_OK
, "IStorage->DestroyElement failed, hr=%08x\n", r
);
1614 r
= IStream_Write(stm
, "this shouldn't work\n", 20, NULL
);
1615 ok(r
==STG_E_REVERTED
, "IStream_Write should fail %08x\n", r
);
1617 IStream_Release(stm
);
1620 IStorage_Release(stg
);
1622 ret
= DeleteFileA(filenameA
);
1623 ok(ret
, "deleted file\n");
1626 static void test_revert(void)
1628 IStorage
*stg
= NULL
, *stg2
= NULL
, *stg3
= NULL
;
1630 IStream
*stm
= NULL
, *stm2
= NULL
;
1631 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1632 static const WCHAR stmname2
[] = { 'F','O','O',0 };
1633 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
1634 static const WCHAR stgname2
[] = { 'T','E','M','P','S','T','G',0 };
1638 DeleteFileA(filenameA
);
1640 /* create the file */
1641 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1642 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
1643 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1645 /* commit a new stream and storage */
1646 r
= IStorage_CreateStream(stg
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1647 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1649 r
= IStream_Write(stm
, "this is stream 1\n", 16, NULL
);
1650 ok(r
==S_OK
, "IStream->Write failed\n");
1652 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1653 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1657 /* Create two substorages but only commit one */
1658 r
= IStorage_CreateStorage(stg2
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1659 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1662 IStorage_Release(stg3
);
1664 r
= IStorage_Commit(stg
, 0);
1665 ok(r
==S_OK
, "IStorage->Commit failed\n");
1667 r
= IStorage_CreateStorage(stg2
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1668 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1671 IStorage_Release(stg3
);
1674 /* now create a stream and storage, then revert */
1675 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm2
);
1676 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1678 r
= IStream_Write(stm2
, "this is stream 2\n", 16, NULL
);
1679 ok(r
==S_OK
, "IStream->Write failed\n");
1681 r
= IStorage_CreateStorage(stg
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1682 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1684 r
= IStorage_Revert(stg
);
1685 ok(r
==S_OK
, "Storage_Revert failed with error 0x%08x\n", r
);
1687 /* all open objects become invalid */
1688 r
= IStream_Write(stm
, "this shouldn't work\n", 20, NULL
);
1689 ok(r
==STG_E_REVERTED
, "IStream_Write should fail %08x\n", r
);
1691 r
= IStream_Write(stm2
, "this shouldn't work\n", 20, NULL
);
1692 ok(r
==STG_E_REVERTED
, "IStream_Write should fail %08x\n", r
);
1694 r
= IStorage_Stat(stg2
, &statstg
, STATFLAG_NONAME
);
1695 ok(r
==STG_E_REVERTED
, "IStorage_Stat should fail %08x\n", r
);
1697 r
= IStorage_Stat(stg3
, &statstg
, STATFLAG_NONAME
);
1698 ok(r
==STG_E_REVERTED
, "IStorage_Stat should fail %08x\n", r
);
1700 IStream_Release(stm
);
1701 IStream_Release(stm2
);
1702 IStorage_Release(stg2
);
1703 IStorage_Release(stg3
);
1705 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_SHARE_DENY_NONE
|STGM_READ
, 0, &stm
);
1706 ok(r
==STG_E_INVALIDFLAG
, "IStorage->OpenStream failed %08x\n", r
);
1708 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_DELETEONRELEASE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1709 ok(r
==STG_E_INVALIDFUNCTION
, "IStorage->OpenStream failed %08x\n", r
);
1711 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_TRANSACTED
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1712 ok(r
==STG_E_INVALIDFUNCTION
, "IStorage->OpenStream failed %08x\n", r
);
1714 r
= IStorage_OpenStorage(stg
, stmname
, NULL
, STGM_TRANSACTED
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1715 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream failed %08x\n", r
);
1717 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1718 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream should fail %08x\n", r
);
1720 IStream_Release(stm
);
1722 r
= IStorage_OpenStorage(stg
, stgname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1723 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStorage should fail %08x\n", r
);
1725 IStorage_Release(stg2
);
1727 r
= IStorage_OpenStorage(stg
, stmname2
, NULL
, STGM_TRANSACTED
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1728 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream failed %08x\n", r
);
1730 r
= IStorage_OpenStream(stg
, stmname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1731 ok(r
==S_OK
, "IStorage->OpenStream should succeed %08x\n", r
);
1733 IStream_Release(stm
);
1735 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg2
);
1736 ok(r
==S_OK
, "IStorage->OpenStorage should succeed %08x\n", r
);
1739 r
= IStorage_OpenStorage(stg2
, stgname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg3
);
1740 ok(r
==S_OK
, "IStorage->OpenStorage should succeed %08x\n", r
);
1742 IStorage_Release(stg3
);
1744 r
= IStorage_OpenStorage(stg2
, stgname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg3
);
1745 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStorage should fail %08x\n", r
);
1747 IStorage_Release(stg3
);
1749 IStorage_Release(stg2
);
1752 IStorage_Release(stg
);
1754 ret
= DeleteFileA(filenameA
);
1755 ok(ret
, "deleted file\n");
1757 /* Revert only invalidates objects in transacted mode */
1758 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1759 STGM_READWRITE
, 0, &stg
);
1760 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1762 r
= IStorage_CreateStream(stg
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1763 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1765 r
= IStorage_Revert(stg
);
1766 ok(r
==S_OK
, "IStorage->Revert failed %08x\n", r
);
1768 r
= IStream_Write(stm
, "this works\n", 11, NULL
);
1769 ok(r
==S_OK
, "IStream_Write should succeed %08x\n", r
);
1771 IStream_Release(stm
);
1772 IStorage_Release(stg
);
1774 ret
= DeleteFileA(filenameA
);
1775 ok(ret
, "deleted file\n");
1778 static void test_parent_free(void)
1780 IStorage
*stg
= NULL
, *stg2
= NULL
, *stg3
= NULL
;
1782 IStream
*stm
= NULL
;
1783 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1784 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
1789 DeleteFileA(filenameA
);
1791 /* create the file */
1792 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1793 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
1794 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1796 /* create a new storage */
1797 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
1798 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1802 /* now create a stream inside the new storage */
1803 r
= IStorage_CreateStream(stg2
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1804 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1808 /* create a storage inside the new storage */
1809 r
= IStorage_CreateStorage(stg2
, stgname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stg3
);
1810 ok(r
==S_OK
, "IStorage->CreateStorage failed\n");
1813 /* free the parent */
1814 ref
= IStorage_Release(stg2
);
1815 ok(ref
== 0, "IStorage still has %u references\n", ref
);
1817 /* child objects are invalid */
1820 r
= IStream_Write(stm
, "this should fail\n", 17, NULL
);
1821 ok(r
==STG_E_REVERTED
, "IStream->Write should fail, hr=%x\n", r
);
1823 IStream_Release(stm
);
1825 r
= IStorage_Stat(stg3
, &statstg
, STATFLAG_NONAME
);
1826 ok(r
==STG_E_REVERTED
, "IStorage_Stat should fail %08x\n", r
);
1828 r
= IStorage_SetStateBits(stg3
, 1, 1);
1829 ok(r
==STG_E_REVERTED
, "IStorage_Stat should fail %08x\n", r
);
1831 IStorage_Release(stg3
);
1835 IStorage_Release(stg
);
1837 ret
= DeleteFileA(filenameA
);
1838 ok(ret
, "deleted file\n");
1841 static void test_nonroot_transacted(void)
1843 IStorage
*stg
= NULL
, *stg2
= NULL
, *stg3
= NULL
;
1845 IStream
*stm
= NULL
;
1846 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
1847 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
1848 static const WCHAR stmname2
[] = { 'F','O','O',0 };
1851 DeleteFileA(filenameA
);
1853 /* create a transacted file */
1854 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1855 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
1856 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1858 /* create a transacted substorage */
1859 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, 0, 0, &stg2
);
1860 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1864 /* create and commit stmname */
1865 r
= IStorage_CreateStream(stg2
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1866 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1868 IStream_Release(stm
);
1870 IStorage_Commit(stg2
, 0);
1872 /* create and revert stmname2 */
1873 r
= IStorage_CreateStream(stg2
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1874 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1876 IStream_Release(stm
);
1878 IStorage_Revert(stg2
);
1880 /* check that Commit and Revert really worked */
1881 r
= IStorage_OpenStream(stg2
, stmname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1882 ok(r
==S_OK
, "IStorage->OpenStream should succeed %08x\n", r
);
1884 IStream_Release(stm
);
1886 r
= IStorage_OpenStream(stg2
, stmname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1887 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream should fail %08x\n", r
);
1889 IStream_Release(stm
);
1891 IStorage_Release(stg2
);
1894 /* create a read-only transacted substorage */
1895 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, NULL
, 0, &stg2
);
1896 ok(r
==S_OK
, "IStorage->OpenStorage failed, hr=%08x\n", r
);
1900 /* The storage can be modified. */
1901 r
= IStorage_CreateStorage(stg2
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
1902 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1904 IStorage_Release(stg3
);
1906 /* But changes cannot be committed. */
1907 r
= IStorage_Commit(stg2
, 0);
1908 ok(r
==STG_E_ACCESSDENIED
, "IStorage->Commit should fail, hr=%08x\n", r
);
1910 IStorage_Release(stg2
);
1913 IStorage_Release(stg
);
1915 /* create a non-transacted file */
1916 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
1917 STGM_READWRITE
, 0, &stg
);
1918 ok(r
==S_OK
, "StgCreateDocfile failed\n");
1920 /* create a transacted substorage */
1921 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, 0, 0, &stg2
);
1922 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
1926 /* create and commit stmname */
1927 r
= IStorage_CreateStream(stg2
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1928 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1930 IStream_Release(stm
);
1932 IStorage_Commit(stg2
, 0);
1934 /* create and revert stmname2 */
1935 r
= IStorage_CreateStream(stg2
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
1936 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
1938 IStream_Release(stm
);
1940 IStorage_Revert(stg2
);
1942 /* check that Commit and Revert really worked */
1943 r
= IStorage_OpenStream(stg2
, stmname
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1944 ok(r
==S_OK
, "IStorage->OpenStream should succeed %08x\n", r
);
1946 IStream_Release(stm
);
1948 r
= IStorage_OpenStream(stg2
, stmname2
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stm
);
1949 ok(r
==STG_E_FILENOTFOUND
, "IStorage->OpenStream should fail %08x\n", r
);
1951 IStream_Release(stm
);
1953 IStorage_Release(stg2
);
1956 IStorage_Release(stg
);
1958 ret
= DeleteFileA(filenameA
);
1959 ok(ret
, "deleted file\n");
1962 static void test_ReadClassStm(void)
1967 static const LARGE_INTEGER llZero
;
1969 hr
= ReadClassStm(NULL
, &clsid
);
1970 ok(hr
== E_INVALIDARG
, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1972 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
1973 ok_ole_success(hr
, "CreateStreamOnHGlobal");
1974 hr
= WriteClassStm(pStream
, &test_stg_cls
);
1975 ok_ole_success(hr
, "WriteClassStm");
1977 hr
= ReadClassStm(pStream
, NULL
);
1978 ok(hr
== E_INVALIDARG
, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1980 /* test not rewound stream */
1981 hr
= ReadClassStm(pStream
, &clsid
);
1982 ok(hr
== STG_E_READFAULT
, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr
);
1983 ok(IsEqualCLSID(&clsid
, &CLSID_NULL
), "clsid should have been zeroed\n");
1985 hr
= IStream_Seek(pStream
, llZero
, STREAM_SEEK_SET
, NULL
);
1986 ok_ole_success(hr
, "IStream_Seek");
1987 hr
= ReadClassStm(pStream
, &clsid
);
1988 ok_ole_success(hr
, "ReadClassStm");
1989 ok(IsEqualCLSID(&clsid
, &test_stg_cls
), "clsid should have been set to CLSID_WineTest\n");
1991 IStream_Release(pStream
);
2001 static const struct access_res create
[16] =
2003 { TRUE
, ERROR_SUCCESS
, TRUE
},
2004 { TRUE
, ERROR_SUCCESS
, TRUE
},
2005 { TRUE
, ERROR_SUCCESS
, FALSE
},
2006 { TRUE
, ERROR_SUCCESS
, FALSE
},
2007 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2008 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2009 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2010 { TRUE
, ERROR_SUCCESS
, FALSE
},
2011 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2012 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2013 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2014 { TRUE
, ERROR_SUCCESS
, TRUE
},
2015 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2016 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2017 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2018 { TRUE
, ERROR_SUCCESS
, TRUE
}
2021 static const struct access_res create_commit
[16] =
2023 { TRUE
, ERROR_SUCCESS
, TRUE
},
2024 { TRUE
, ERROR_SUCCESS
, TRUE
},
2025 { TRUE
, ERROR_SUCCESS
, FALSE
},
2026 { TRUE
, ERROR_SUCCESS
, FALSE
},
2027 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2028 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2029 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2030 { TRUE
, ERROR_SUCCESS
, FALSE
},
2031 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2032 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2033 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2034 { TRUE
, ERROR_SUCCESS
, TRUE
},
2035 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2036 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2037 { FALSE
, ERROR_SHARING_VIOLATION
, FALSE
},
2038 { TRUE
, ERROR_SUCCESS
, TRUE
}
2041 static const struct access_res create_close
[16] =
2043 { TRUE
, ERROR_SUCCESS
, FALSE
},
2044 { TRUE
, ERROR_SUCCESS
, FALSE
},
2045 { TRUE
, ERROR_SUCCESS
, FALSE
},
2046 { TRUE
, ERROR_SUCCESS
, FALSE
},
2047 { TRUE
, ERROR_SUCCESS
, FALSE
},
2048 { TRUE
, ERROR_SUCCESS
, FALSE
},
2049 { TRUE
, ERROR_SUCCESS
, FALSE
},
2050 { TRUE
, ERROR_SUCCESS
, FALSE
},
2051 { TRUE
, ERROR_SUCCESS
, FALSE
},
2052 { TRUE
, ERROR_SUCCESS
, FALSE
},
2053 { TRUE
, ERROR_SUCCESS
, FALSE
},
2054 { TRUE
, ERROR_SUCCESS
, FALSE
},
2055 { TRUE
, ERROR_SUCCESS
, FALSE
},
2056 { TRUE
, ERROR_SUCCESS
, FALSE
},
2057 { TRUE
, ERROR_SUCCESS
, FALSE
},
2058 { TRUE
, ERROR_SUCCESS
}
2061 static const DWORD access_modes
[4] = {
2065 GENERIC_READ
| GENERIC_WRITE
2068 static const DWORD share_modes
[4] = {
2072 FILE_SHARE_READ
| FILE_SHARE_WRITE
2075 static void _test_file_access(LPCSTR file
, const struct access_res
*ares
, DWORD line
)
2079 for (i
= 0; i
< sizeof(access_modes
)/sizeof(access_modes
[0]); i
++)
2081 for (j
= 0; j
< sizeof(share_modes
)/sizeof(share_modes
[0]); j
++)
2086 if (ares
[idx
].ignore
)
2089 SetLastError(0xdeadbeef);
2090 hfile
= CreateFileA(file
, access_modes
[i
], share_modes
[j
], NULL
, OPEN_EXISTING
,
2091 FILE_ATTRIBUTE_NORMAL
, 0);
2092 lasterr
= GetLastError();
2094 ok((hfile
!= INVALID_HANDLE_VALUE
) == ares
[idx
].gothandle
,
2095 "(%d, handle, %d): Expected %d, got %d\n",
2096 line
, idx
, ares
[idx
].gothandle
,
2097 (hfile
!= INVALID_HANDLE_VALUE
));
2099 ok(lasterr
== ares
[idx
].lasterr
||
2100 broken(lasterr
== 0xdeadbeef) /* win9x */,
2101 "(%d, lasterr, %d): Expected %d, got %d\n",
2102 line
, idx
, ares
[idx
].lasterr
, lasterr
);
2110 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
2112 static void test_access(void)
2114 static const WCHAR fileW
[] = {'w','i','n','e','t','e','s','t',0};
2115 static const char fileA
[] = "winetest";
2119 /* STGM_TRANSACTED */
2120 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
|
2121 STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, 0, &stg
);
2122 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2124 test_file_access(fileA
, create
);
2126 hr
= IStorage_Commit(stg
, STGC_DEFAULT
);
2127 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2129 test_file_access(fileA
, create_commit
);
2131 IStorage_Release(stg
);
2133 test_file_access(fileA
, create_close
);
2138 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
|
2139 STGM_SHARE_EXCLUSIVE
| STGM_DIRECT
, 0, &stg
);
2140 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2142 test_file_access(fileA
, create
);
2144 hr
= IStorage_Commit(stg
, STGC_DEFAULT
);
2145 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2147 test_file_access(fileA
, create_commit
);
2149 IStorage_Release(stg
);
2151 test_file_access(fileA
, create_close
);
2155 /* STGM_SHARE_DENY_NONE */
2156 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
|
2157 STGM_SHARE_DENY_NONE
| STGM_TRANSACTED
, 0, &stg
);
2158 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2160 test_file_access(fileA
, create
);
2162 hr
= IStorage_Commit(stg
, STGC_DEFAULT
);
2163 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2165 test_file_access(fileA
, create_commit
);
2167 IStorage_Release(stg
);
2169 test_file_access(fileA
, create_close
);
2173 /* STGM_SHARE_DENY_READ */
2174 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
|
2175 STGM_SHARE_DENY_READ
| STGM_TRANSACTED
, 0, &stg
);
2176 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2178 test_file_access(fileA
, create
);
2180 hr
= IStorage_Commit(stg
, STGC_DEFAULT
);
2181 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2183 test_file_access(fileA
, create_commit
);
2185 IStorage_Release(stg
);
2187 test_file_access(fileA
, create_close
);
2191 /* STGM_SHARE_DENY_WRITE */
2192 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
|
2193 STGM_SHARE_DENY_WRITE
| STGM_TRANSACTED
, 0, &stg
);
2194 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2196 test_file_access(fileA
, create
);
2198 hr
= IStorage_Commit(stg
, STGC_DEFAULT
);
2199 ok(hr
== S_OK
, "Expected S_OK, got %08x\n", hr
);
2201 test_file_access(fileA
, create_commit
);
2203 IStorage_Release(stg
);
2205 test_file_access(fileA
, create_close
);
2209 /* STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE - reader mode for direct SWMR mode */
2210 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_DENY_WRITE
| STGM_TRANSACTED
, 0, &stg
);
2211 ok(hr
== S_OK
, "got %08x\n", hr
);
2212 IStorage_Release(stg
);
2214 hr
= StgOpenStorage(fileW
, NULL
, STGM_DIRECT_SWMR
| STGM_READ
| STGM_SHARE_DENY_NONE
, NULL
, 0, &stg
);
2215 ok(hr
== S_OK
|| broken(hr
== STG_E_INVALIDFLAG
), "got %08x\n", hr
);
2219 test_file_access(fileA
, create
);
2221 IStorage_Release(stg
);
2222 test_file_access(fileA
, create_close
);
2227 static void test_readonly(void)
2229 IStorage
*stg
, *stg2
, *stg3
;
2232 static const WCHAR fileW
[] = {'w','i','n','e','t','e','s','t',0};
2233 static const WCHAR storageW
[] = {'s','t','o','r','a','g','e',0};
2234 static const WCHAR streamW
[] = {'s','t','r','e','a','m',0};
2236 hr
= StgCreateDocfile( fileW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
2237 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2240 hr
= IStorage_CreateStorage( stg
, storageW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stg2
);
2241 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2244 hr
= IStorage_CreateStream( stg2
, streamW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stream
);
2245 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2247 IStream_Release(stream
);
2248 IStorage_Release(stg2
);
2250 IStorage_Release(stg
);
2253 /* re-open read only */
2254 hr
= StgOpenStorage( fileW
, NULL
, STGM_TRANSACTED
| STGM_SHARE_DENY_NONE
| STGM_READ
, NULL
, 0, &stg
);
2255 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2258 hr
= IStorage_OpenStorage( stg
, storageW
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg2
);
2259 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2262 /* CreateStream on read-only storage, name exists */
2263 hr
= IStorage_CreateStream( stg2
, streamW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, 0, &stream
);
2264 ok(hr
== STG_E_ACCESSDENIED
, "should fail, res=%x\n", hr
);
2266 IStream_Release(stream
);
2268 /* CreateStream on read-only storage, name does not exist */
2269 hr
= IStorage_CreateStream( stg2
, storageW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, 0, &stream
);
2270 ok(hr
== STG_E_ACCESSDENIED
, "should fail, res=%x\n", hr
);
2272 IStream_Release(stream
);
2274 /* CreateStorage on read-only storage, name exists */
2275 hr
= IStorage_CreateStorage( stg2
, streamW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, 0, &stg3
);
2276 ok(hr
== STG_E_FILEALREADYEXISTS
, "should fail, res=%x\n", hr
);
2278 IStorage_Release(stg3
);
2280 /* CreateStorage on read-only storage, name does not exist */
2281 hr
= IStorage_CreateStorage( stg2
, storageW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, 0, &stg3
);
2282 ok(hr
== STG_E_ACCESSDENIED
, "should fail, res=%x\n", hr
);
2284 IStorage_Release(stg3
);
2286 /* DestroyElement on read-only storage, name exists */
2287 hr
= IStorage_DestroyElement( stg2
, streamW
);
2288 ok(hr
== STG_E_ACCESSDENIED
, "should fail, res=%x\n", hr
);
2290 /* DestroyElement on read-only storage, name does not exist */
2291 hr
= IStorage_DestroyElement( stg2
, storageW
);
2292 ok(hr
== STG_E_ACCESSDENIED
, "should fail, res=%x\n", hr
);
2294 IStorage_Release(stg2
);
2297 IStorage_Release(stg
);
2300 DeleteFileA("winetest");
2303 static void test_simple(void)
2305 /* Tests for STGM_SIMPLE mode */
2307 IStorage
*stg
, *stg2
;
2310 static const WCHAR stgname
[] = { 'S','t','g',0 };
2311 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
2312 static const WCHAR stmname2
[] = { 'S','m','a','l','l',0 };
2314 ULARGE_INTEGER upos
;
2318 DeleteFileA(filenameA
);
2320 r
= StgCreateDocfile( filename
, STGM_SIMPLE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
2321 ok(r
== S_OK
, "got %08x\n", r
);
2323 r
= IStorage_CreateStorage(stg
, stgname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stg2
);
2324 ok(r
== STG_E_INVALIDFUNCTION
, "got %08x\n", r
);
2325 if (SUCCEEDED(r
)) IStorage_Release(stg2
);
2327 r
= IStorage_CreateStream(stg
, stmname
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
2328 ok(r
== STG_E_INVALIDFLAG
, "got %08x\n", r
);
2329 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
2330 ok(r
== S_OK
, "got %08x\n", r
);
2332 upos
.QuadPart
= 6000;
2333 r
= IStream_SetSize(stm
, upos
);
2334 ok(r
== S_OK
, "got %08x\n", r
);
2336 r
= IStream_Write(stm
, "foo", 3, &count
);
2337 ok(r
== S_OK
, "got %08x\n", r
);
2338 ok(count
== 3, "got %d\n", count
);
2341 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_CUR
, &upos
);
2342 ok(r
== S_OK
, "got %08x\n", r
);
2343 ok(upos
.QuadPart
== 3, "got %d\n", upos
.u
.LowPart
);
2345 r
= IStream_Stat(stm
, &stat
, STATFLAG_NONAME
);
2347 broken(r
== STG_E_INVALIDFUNCTION
), /* NT4 and below */
2350 ok(stat
.cbSize
.QuadPart
== 3, "got %d\n", stat
.cbSize
.u
.LowPart
);
2353 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &upos
);
2354 ok(r
== S_OK
, "got %08x\n", r
);
2355 ok(upos
.QuadPart
== 1, "got %d\n", upos
.u
.LowPart
);
2357 r
= IStream_Stat(stm
, &stat
, STATFLAG_NONAME
);
2359 broken(r
== STG_E_INVALIDFUNCTION
), /* NT4 and below */
2362 ok(stat
.cbSize
.QuadPart
== 1, "got %d\n", stat
.cbSize
.u
.LowPart
);
2364 IStream_Release(stm
);
2366 r
= IStorage_CreateStream(stg
, stmname2
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
2367 ok(r
== S_OK
, "got %08x\n", r
);
2369 upos
.QuadPart
= 100;
2370 r
= IStream_SetSize(stm
, upos
);
2371 ok(r
== S_OK
, "got %08x\n", r
);
2373 r
= IStream_Write(stm
, "foo", 3, &count
);
2374 ok(r
== S_OK
, "got %08x\n", r
);
2375 ok(count
== 3, "got %d\n", count
);
2377 IStream_Release(stm
);
2379 IStorage_Commit(stg
, STGC_DEFAULT
);
2380 IStorage_Release(stg
);
2382 r
= StgOpenStorage( filename
, NULL
, STGM_SIMPLE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, NULL
, 0, &stg
);
2383 if (r
== STG_E_INVALIDFLAG
)
2385 win_skip("Flag combination is not supported on NT4 and below\n");
2386 DeleteFileA(filenameA
);
2389 ok(r
== S_OK
, "got %08x\n", r
);
2391 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, NULL
, 0, &stg2
);
2392 ok(r
== STG_E_INVALIDFUNCTION
, "got %08x\n", r
);
2393 if (SUCCEEDED(r
)) IStorage_Release(stg2
);
2395 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stm
);
2396 ok(r
== S_OK
, "got %08x\n", r
);
2398 r
= IStream_Stat(stm
, &stat
, STATFLAG_NONAME
);
2399 ok(r
== S_OK
, "got %08x\n", r
);
2400 ok(stat
.cbSize
.QuadPart
== 6000, "got %d\n", stat
.cbSize
.u
.LowPart
);
2402 IStream_Release(stm
);
2404 r
= IStorage_OpenStream(stg
, stmname2
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stm
);
2405 ok(r
== S_OK
, "got %08x\n", r
);
2407 r
= IStream_Stat(stm
, &stat
, STATFLAG_NONAME
);
2408 ok(r
== S_OK
, "got %08x\n", r
);
2409 ok(stat
.cbSize
.QuadPart
== 4096, "got %d\n", stat
.cbSize
.u
.LowPart
);
2411 IStream_Release(stm
);
2414 IStorage_Release(stg
);
2416 DeleteFileA(filenameA
);
2419 static void test_fmtusertypestg(void)
2424 static const char fileA
[] = {'f','m','t','t','e','s','t',0};
2425 static const WCHAR fileW
[] = {'f','m','t','t','e','s','t',0};
2426 static WCHAR userTypeW
[] = {'S','t','g','U','s','r','T','y','p','e',0};
2427 static const WCHAR strmNameW
[] = {1,'C','o','m','p','O','b','j',0};
2428 static const STATSTG statstg_null
;
2430 hr
= StgCreateDocfile( fileW
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
2431 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2435 /* try to write the stream */
2436 hr
= WriteFmtUserTypeStg(stg
, 0, userTypeW
);
2437 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2439 /* check that the stream was created */
2440 hr
= IStorage_EnumElements(stg
, 0, NULL
, 0, &stat
);
2441 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2447 memset(&statstg
, 0xad, sizeof(statstg
));
2448 while ((hr
= IEnumSTATSTG_Next(stat
, 1, &statstg
, &got
)) == S_OK
&& got
== 1)
2450 if (strcmp_ww(statstg
.pwcsName
, strmNameW
) == 0)
2453 ok(0, "found unexpected stream or storage\n");
2454 CoTaskMemFree(statstg
.pwcsName
);
2456 ok(memcmp(&statstg
, &statstg_null
, sizeof(statstg
)) == 0, "statstg is not zeroed\n");
2457 ok(found
== TRUE
, "expected storage to contain stream \\0001CompObj\n");
2458 IEnumSTATSTG_Release(stat
);
2461 /* re-write the stream */
2462 hr
= WriteFmtUserTypeStg(stg
, 0, userTypeW
);
2463 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2465 /* check that the stream is still there */
2466 hr
= IStorage_EnumElements(stg
, 0, NULL
, 0, &stat
);
2467 ok(hr
== S_OK
, "should succeed, res=%x\n", hr
);
2473 memset(&statstg
, 0xad, sizeof(statstg
));
2474 while ((hr
= IEnumSTATSTG_Next(stat
, 1, &statstg
, &got
)) == S_OK
&& got
== 1)
2476 if (strcmp_ww(statstg
.pwcsName
, strmNameW
) == 0)
2479 ok(0, "found unexpected stream or storage\n");
2480 CoTaskMemFree(statstg
.pwcsName
);
2482 ok(memcmp(&statstg
, &statstg_null
, sizeof(statstg
)) == 0, "statstg is not zeroed\n");
2483 ok(found
== TRUE
, "expected storage to contain stream \\0001CompObj\n");
2484 IEnumSTATSTG_Release(stat
);
2487 IStorage_Release(stg
);
2488 DeleteFileA( fileA
);
2492 static void test_references(void)
2494 IStorage
*stg
,*stg2
;
2497 static const WCHAR StorName
[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
2499 DeleteFileA(filenameA
);
2501 hr
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
2502 ok(hr
==S_OK
, "StgCreateDocfile failed\n");
2506 IStorage_Release(stg
);
2508 hr
= StgOpenStorage( filename
, NULL
, STGM_TRANSACTED
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, NULL
, 0, &stg
);
2509 ok(hr
==S_OK
, "StgOpenStorage failed (result=%x)\n",hr
);
2513 hr
= IStorage_CreateStorage(stg
,StorName
,STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
,0,0,&stg2
);
2514 ok(hr
== S_OK
, "IStorage_CreateStorage failed (result=%x)\n",hr
);
2518 c1
= IStorage_AddRef(stg
);
2519 ok(c1
== 2, "creating internal storage added references to ancestor\n");
2520 c1
= IStorage_AddRef(stg
);
2521 IStorage_Release(stg2
);
2522 c2
= IStorage_AddRef(stg
) - 1;
2523 ok(c1
== c2
, "releasing internal storage removed references to ancestor\n");
2525 c1
= IStorage_Release(stg
);
2526 while ( c1
) c1
= IStorage_Release(stg
);
2530 DeleteFileA(filenameA
);
2535 * | `StreamA: "StreamA"
2537 * | `StreamB: "StreamB"
2538 * `StreamC: "StreamC"
2540 static HRESULT
create_test_file(IStorage
*dest
)
2542 IStorage
*stgA
= NULL
, *stgB
= NULL
;
2543 IStream
*strmA
= NULL
, *strmB
= NULL
, *strmC
= NULL
;
2544 const ULONG strmA_name_size
= lstrlenW(strmA_name
) * sizeof(WCHAR
);
2545 const ULONG strmB_name_size
= lstrlenW(strmB_name
) * sizeof(WCHAR
);
2546 const ULONG strmC_name_size
= lstrlenW(strmC_name
) * sizeof(WCHAR
);
2550 hr
= IStorage_CreateStorage(dest
, stgA_name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stgA
);
2551 ok(hr
== S_OK
, "IStorage_CreateStorage failed: 0x%08x\n", hr
);
2555 hr
= IStorage_CreateStream(stgA
, strmA_name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &strmA
);
2556 ok(hr
== S_OK
, "IStorage_CreateStream failed: 0x%08x\n", hr
);
2560 hr
= IStream_Write(strmA
, strmA_name
, strmA_name_size
, &bytes
);
2561 ok(hr
== S_OK
&& bytes
== strmA_name_size
, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr
, bytes
, strmA_name_size
);
2563 hr
= IStorage_CreateStorage(dest
, stgB_name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stgB
);
2564 ok(hr
== S_OK
, "IStorage_CreateStorage failed: 0x%08x\n", hr
);
2568 hr
= IStorage_CreateStream(stgB
, strmB_name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &strmB
);
2569 ok(hr
== S_OK
, "IStorage_CreateStream failed: 0x%08x\n", hr
);
2573 hr
= IStream_Write(strmB
, strmB_name
, strmB_name_size
, &bytes
);
2574 ok(hr
== S_OK
&& bytes
== strmB_name_size
, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr
, bytes
, strmB_name_size
);
2576 hr
= IStorage_CreateStream(dest
, strmC_name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &strmC
);
2577 ok(hr
== S_OK
, "IStorage_CreateStream failed: 0x%08x\n", hr
);
2581 hr
= IStream_Write(strmC
, strmC_name
, strmC_name_size
, &bytes
);
2582 ok(hr
== S_OK
&& bytes
== strmC_name_size
, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr
, bytes
, strmC_name_size
);
2586 IStream_Release(strmC
);
2588 IStream_Release(strmB
);
2590 IStorage_Release(stgB
);
2592 IStream_Release(strmA
);
2594 IStorage_Release(stgA
);
2599 static void test_copyto(void)
2601 IStorage
*file1
= NULL
, *file2
= NULL
, *stg_tmp
;
2606 /* create & populate file1 */
2607 hr
= StgCreateDocfile(file1_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file1
);
2608 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2612 hr
= create_test_file(file1
);
2617 hr
= StgCreateDocfile(file2_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file2
);
2618 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2622 /* copy file1 into file2 */
2623 hr
= IStorage_CopyTo(file1
, 0, NULL
, NULL
, NULL
);
2624 ok(hr
== STG_E_INVALIDPOINTER
, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr
);
2626 hr
= IStorage_CopyTo(file1
, 0, NULL
, NULL
, file2
);
2627 ok(hr
== S_OK
, "CopyTo failed: 0x%08x\n", hr
);
2631 /* verify that all of file1 was copied */
2632 hr
= IStorage_OpenStorage(file2
, stgA_name
, NULL
,
2633 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2634 ok(hr
== S_OK
, "OpenStorage failed: 0x%08x\n", hr
);
2637 hr
= IStorage_OpenStream(stg_tmp
, strmA_name
, NULL
,
2638 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2639 ok(hr
== S_OK
, "OpenStream failed: 0x%08x\n", hr
);
2642 memset(buf
, 0, sizeof(buf
));
2643 hr
= IStream_Read(strm_tmp
, buf
, sizeof(buf
), NULL
);
2644 ok(hr
== S_OK
, "Read failed: 0x%08x\n", hr
);
2646 ok(strcmp_ww(buf
, strmA_name
) == 0,
2647 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name
), wine_dbgstr_w(buf
));
2649 IStream_Release(strm_tmp
);
2652 IStorage_Release(stg_tmp
);
2655 hr
= IStorage_OpenStorage(file2
, stgB_name
, NULL
,
2656 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2657 ok(hr
== S_OK
, "OpenStorage failed: 0x%08x\n", hr
);
2660 hr
= IStorage_OpenStream(stg_tmp
, strmB_name
, NULL
,
2661 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2662 ok(hr
== S_OK
, "OpenStream failed: 0x%08x\n", hr
);
2665 memset(buf
, 0, sizeof(buf
));
2666 hr
= IStream_Read(strm_tmp
, buf
, sizeof(buf
), NULL
);
2667 ok(hr
== S_OK
, "Read failed: 0x%08x\n", hr
);
2669 ok(strcmp_ww(buf
, strmB_name
) == 0,
2670 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name
), wine_dbgstr_w(buf
));
2672 IStream_Release(strm_tmp
);
2675 IStorage_Release(stg_tmp
);
2678 hr
= IStorage_OpenStream(file2
, strmC_name
, NULL
,
2679 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2680 ok(hr
== S_OK
, "OpenStream failed: 0x%08x\n", hr
);
2683 memset(buf
, 0, sizeof(buf
));
2684 hr
= IStream_Read(strm_tmp
, buf
, sizeof(buf
), NULL
);
2685 ok(hr
== S_OK
, "Read failed: 0x%08x\n", hr
);
2687 ok(strcmp_ww(buf
, strmC_name
) == 0,
2688 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name
), wine_dbgstr_w(buf
));
2690 IStream_Release(strm_tmp
);
2695 IStorage_Release(file1
);
2697 IStorage_Release(file2
);
2699 DeleteFileA(file1_nameA
);
2700 DeleteFileA(file2_nameA
);
2703 static void test_copyto_snbexclusions(void)
2705 static const WCHAR
*snb_exclude
[] = {stgA_name
, strmB_name
, strmC_name
, 0};
2707 IStorage
*file1
= NULL
, *file2
= NULL
, *stg_tmp
;
2712 /* create & populate file1 */
2713 hr
= StgCreateDocfile(file1_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file1
);
2714 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2718 hr
= create_test_file(file1
);
2723 hr
= StgCreateDocfile(file2_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file2
);
2724 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2728 /* copy file1 to file2 with name exclusions */
2729 hr
= IStorage_CopyTo(file1
, 0, NULL
, (SNB
)snb_exclude
, file2
);
2730 ok(hr
== S_OK
, "CopyTo failed: 0x%08x\n", hr
);
2734 /* verify that file1 copied over, respecting exclusions */
2735 hr
= IStorage_OpenStorage(file2
, stgA_name
, NULL
,
2736 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2737 ok(hr
== STG_E_FILENOTFOUND
, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2739 IStorage_Release(stg_tmp
);
2741 hr
= IStorage_OpenStream(file2
, strmA_name
, NULL
,
2742 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2743 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2745 IStream_Release(strm_tmp
);
2747 hr
= IStorage_OpenStorage(file2
, stgB_name
, NULL
,
2748 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2749 ok(hr
== S_OK
, "OpenStorage failed: 0x%08x\n", hr
);
2752 hr
= IStorage_OpenStream(stg_tmp
, strmB_name
, NULL
,
2753 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2754 ok(hr
== S_OK
, "OpenStream failed: 0x%08x\n", hr
);
2757 memset(buf
, 0, sizeof(buf
));
2758 hr
= IStream_Read(strm_tmp
, buf
, sizeof(buf
), NULL
);
2759 ok(hr
== S_OK
, "Read failed: 0x%08x\n", hr
);
2761 ok(strcmp_ww(buf
, strmB_name
) == 0,
2762 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name
), wine_dbgstr_w(buf
));
2764 IStream_Release(strm_tmp
);
2767 IStorage_Release(stg_tmp
);
2770 hr
= IStorage_OpenStream(file2
, strmC_name
, NULL
,
2771 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2772 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2774 IStream_Release(strm_tmp
);
2778 IStorage_Release(file1
);
2780 IStorage_Release(file2
);
2782 DeleteFileA(file1_nameA
);
2783 DeleteFileA(file2_nameA
);
2786 static void test_copyto_iidexclusions_storage(void)
2788 IStorage
*file1
= NULL
, *file2
= NULL
, *stg_tmp
;
2793 /* create & populate file1 */
2794 hr
= StgCreateDocfile(file1_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file1
);
2795 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2799 hr
= create_test_file(file1
);
2804 hr
= StgCreateDocfile(file2_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file2
);
2805 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2809 /* copy file1 to file2 with iid exclusions */
2810 hr
= IStorage_CopyTo(file1
, 1, &IID_IStorage
, NULL
, file2
);
2811 ok(hr
== S_OK
, "CopyTo failed: 0x%08x\n", hr
);
2815 /* verify that file1 copied over, respecting exclusions */
2816 hr
= IStorage_OpenStorage(file2
, stgA_name
, NULL
,
2817 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2818 ok(hr
== STG_E_FILENOTFOUND
, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2820 IStorage_Release(stg_tmp
);
2822 hr
= IStorage_OpenStream(file2
, strmA_name
, NULL
,
2823 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2824 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2826 IStream_Release(strm_tmp
);
2828 hr
= IStorage_OpenStorage(file2
, stgB_name
, NULL
,
2829 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2830 ok(hr
== STG_E_FILENOTFOUND
, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2832 IStorage_Release(stg_tmp
);
2834 hr
= IStorage_OpenStream(file2
, strmB_name
, NULL
,
2835 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2836 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2838 IStream_Release(strm_tmp
);
2840 hr
= IStorage_OpenStream(file2
, strmC_name
, NULL
,
2841 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2842 ok(hr
== S_OK
, "OpenStream failed: 0x%08x\n", hr
);
2845 memset(buf
, 0, sizeof(buf
));
2846 hr
= IStream_Read(strm_tmp
, buf
, sizeof(buf
), NULL
);
2847 ok(hr
== S_OK
, "Read failed: 0x%08x\n", hr
);
2849 ok(strcmp_ww(buf
, strmC_name
) == 0,
2850 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name
), wine_dbgstr_w(buf
));
2852 IStream_Release(strm_tmp
);
2857 IStorage_Release(file1
);
2859 IStorage_Release(file2
);
2861 DeleteFileA(file1_nameA
);
2862 DeleteFileA(file2_nameA
);
2865 static void test_copyto_iidexclusions_stream(void)
2867 IStorage
*file1
= NULL
, *file2
= NULL
, *stg_tmp
;
2871 /* create & populate file1 */
2872 hr
= StgCreateDocfile(file1_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file1
);
2873 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2877 hr
= create_test_file(file1
);
2882 hr
= StgCreateDocfile(file2_name
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &file2
);
2883 ok(hr
== S_OK
, "StgCreateDocfile failed: 0x%08x\n", hr
);
2887 /* copy file1 to file2 with iid exclusions */
2888 hr
= IStorage_CopyTo(file1
, 1, &IID_IStream
, NULL
, file2
);
2889 ok(hr
== S_OK
, "CopyTo failed: 0x%08x\n", hr
);
2893 /* verify that file1 copied over, respecting exclusions */
2894 hr
= IStorage_OpenStorage(file2
, stgA_name
, NULL
,
2895 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2896 ok(hr
== S_OK
, "OpenStorage failed: 0x%08x\n", hr
);
2899 hr
= IStorage_OpenStream(stg_tmp
, strmA_name
, NULL
,
2900 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2901 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2903 IStream_Release(strm_tmp
);
2905 IStorage_Release(stg_tmp
);
2908 hr
= IStorage_OpenStorage(file2
, stgB_name
, NULL
,
2909 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg_tmp
);
2910 ok(hr
== S_OK
, "OpenStorage failed: 0x%08x\n", hr
);
2913 hr
= IStorage_OpenStream(stg_tmp
, strmB_name
, NULL
,
2914 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2915 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2917 IStream_Release(strm_tmp
);
2919 IStorage_Release(stg_tmp
);
2922 hr
= IStorage_OpenStream(file2
, strmC_name
, NULL
,
2923 STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &strm_tmp
);
2924 ok(hr
== STG_E_FILENOTFOUND
, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr
);
2926 IStream_Release(strm_tmp
);
2930 IStorage_Release(file1
);
2932 IStorage_Release(file2
);
2934 DeleteFileA(file1_nameA
);
2935 DeleteFileA(file2_nameA
);
2938 static void test_rename(void)
2940 IStorage
*stg
, *stg2
;
2943 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
2944 static const WCHAR stgname2
[] = { 'S','T','G',0 };
2945 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
2946 static const WCHAR stmname2
[] = { 'E','N','T','S',0 };
2949 DeleteFileA(filenameA
);
2951 /* create the file */
2952 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
2953 STGM_READWRITE
, 0, &stg
);
2954 ok(r
==S_OK
, "StgCreateDocfile failed\n");
2956 /* create a substorage */
2957 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
2958 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
2960 /* create a stream in the substorage */
2961 r
= IStorage_CreateStream(stg2
, stmname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
2962 ok(r
==S_OK
, "IStorage->CreateStream failed, hr=%08x\n", r
);
2963 IStream_Release(stm
);
2965 /* rename the stream */
2966 r
= IStorage_RenameElement(stg2
, stmname
, stmname2
);
2967 ok(r
==S_OK
, "IStorage->RenameElement failed, hr=%08x\n", r
);
2969 /* cannot open stream with old name */
2970 r
= IStorage_OpenStream(stg2
, stmname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stm
);
2971 ok(r
==STG_E_FILENOTFOUND
, "IStorage_OpenStream should fail, hr=%08x\n", r
);
2972 if (SUCCEEDED(r
)) IStream_Release(stm
);
2974 /* can open stream with new name */
2975 r
= IStorage_OpenStream(stg2
, stmname2
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stm
);
2976 ok(r
==S_OK
, "IStorage_OpenStream failed, hr=%08x\n", r
);
2977 if (SUCCEEDED(r
)) IStream_Release(stm
);
2979 IStorage_Release(stg2
);
2981 /* rename the storage */
2982 IStorage_RenameElement(stg
, stgname
, stgname2
);
2984 /* cannot open storage with old name */
2985 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg2
);
2986 ok(r
==STG_E_FILENOTFOUND
, "IStorage_OpenStream should fail, hr=%08x\n", r
);
2987 if (SUCCEEDED(r
)) IStorage_Release(stg2
);
2989 /* can open storage with new name */
2990 r
= IStorage_OpenStorage(stg
, stgname2
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg2
);
2991 ok(r
==S_OK
, "IStorage_OpenStream should fail, hr=%08x\n", r
);
2994 /* opened storage still has the stream */
2995 r
= IStorage_OpenStream(stg2
, stmname2
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stm
);
2996 ok(r
==S_OK
, "IStorage_OpenStream failed, hr=%08x\n", r
);
2997 if (SUCCEEDED(r
)) IStream_Release(stm
);
2999 IStorage_Release(stg2
);
3002 IStorage_Release(stg
);
3004 ret
= DeleteFileA(filenameA
);
3005 ok(ret
, "deleted file\n");
3008 static void test_toplevel_stat(void)
3010 IStorage
*stg
= NULL
;
3013 char prev_dir
[MAX_PATH
];
3014 char temp
[MAX_PATH
];
3015 char full_path
[MAX_PATH
];
3017 WCHAR rel_path
[MAX_PATH
];
3019 DeleteFileA(filenameA
);
3021 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
3022 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
3023 ok(r
==S_OK
, "StgCreateDocfile failed\n");
3025 r
= IStorage_Stat( stg
, &stat
, STATFLAG_DEFAULT
);
3026 ok(r
==S_OK
, "Storage_Stat failed with error 0x%08x\n", r
);
3027 ok(!strcmp_ww(stat
.pwcsName
, filename
), "expected %s, got %s\n",
3028 wine_dbgstr_w(filename
), wine_dbgstr_w(stat
.pwcsName
));
3029 CoTaskMemFree(stat
.pwcsName
);
3031 IStorage_Release( stg
);
3033 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg
);
3034 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
3036 r
= IStorage_Stat( stg
, &stat
, STATFLAG_DEFAULT
);
3037 ok(r
==S_OK
, "Storage_Stat failed with error 0x%08x\n", r
);
3038 ok(!strcmp_ww(stat
.pwcsName
, filename
), "expected %s, got %s\n",
3039 wine_dbgstr_w(filename
), wine_dbgstr_w(stat
.pwcsName
));
3040 CoTaskMemFree(stat
.pwcsName
);
3042 IStorage_Release( stg
);
3044 DeleteFileA(filenameA
);
3046 /* Stat always returns the full path, even for files opened with a relative path. */
3047 GetCurrentDirectoryA(MAX_PATH
, prev_dir
);
3049 GetTempPathA(MAX_PATH
, temp
);
3051 SetCurrentDirectoryA(temp
);
3053 GetFullPathNameA(filenameA
, MAX_PATH
, full_path
, &rel_pathA
);
3054 MultiByteToWideChar(CP_ACP
, 0, rel_pathA
, -1, rel_path
, MAX_PATH
);
3056 r
= StgCreateDocfile( rel_path
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
3057 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
3058 ok(r
==S_OK
, "StgCreateDocfile failed\n");
3060 r
= IStorage_Stat( stg
, &stat
, STATFLAG_DEFAULT
);
3061 ok(r
==S_OK
, "Storage_Stat failed with error 0x%08x\n", r
);
3062 ok(!strcmp_ww(stat
.pwcsName
, filename
), "expected %s, got %s\n",
3063 wine_dbgstr_w(filename
), wine_dbgstr_w(stat
.pwcsName
));
3064 CoTaskMemFree(stat
.pwcsName
);
3066 IStorage_Release( stg
);
3068 r
= StgOpenStorage( rel_path
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg
);
3069 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08x\n", r
);
3071 r
= IStorage_Stat( stg
, &stat
, STATFLAG_DEFAULT
);
3072 ok(r
==S_OK
, "Storage_Stat failed with error 0x%08x\n", r
);
3073 ok(!strcmp_ww(stat
.pwcsName
, filename
), "expected %s, got %s\n",
3074 wine_dbgstr_w(filename
), wine_dbgstr_w(stat
.pwcsName
));
3075 CoTaskMemFree(stat
.pwcsName
);
3077 IStorage_Release( stg
);
3079 SetCurrentDirectoryA(prev_dir
);
3081 DeleteFileA(filenameA
);
3084 static void test_substorage_enum(void)
3086 IStorage
*stg
, *stg2
;
3090 static const WCHAR stgname
[] = { 'P','E','R','M','S','T','G',0 };
3093 DeleteFileA(filenameA
);
3095 /* create the file */
3096 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
3097 STGM_READWRITE
, 0, &stg
);
3098 ok(r
==S_OK
, "StgCreateDocfile failed\n");
3100 /* create a substorage */
3101 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
3102 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3104 /* create an enumelements */
3105 r
= IStorage_EnumElements(stg2
, 0, NULL
, 0, &ee
);
3106 ok(r
==S_OK
, "IStorage->EnumElements failed, hr=%08x\n", r
);
3108 /* release the substorage */
3109 ref
= IStorage_Release(stg2
);
3110 todo_wine
ok(ref
==0, "storage not released\n");
3112 /* reopening fails, because the substorage is really still open */
3113 r
= IStorage_OpenStorage(stg
, stgname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
3114 ok(r
==STG_E_ACCESSDENIED
, "IStorage->OpenStorage failed, hr=%08x\n", r
);
3116 /* destroying the storage invalidates the enumerator */
3117 r
= IStorage_DestroyElement(stg
, stgname
);
3118 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3120 r
= IEnumSTATSTG_Reset(ee
);
3121 ok(r
==STG_E_REVERTED
, "IEnumSTATSTG->Reset failed, hr=%08x\n", r
);
3123 IEnumSTATSTG_Release(ee
);
3125 IStorage_Release(stg
);
3127 ret
= DeleteFileA(filenameA
);
3128 ok(ret
, "deleted file\n");
3131 static void test_copyto_locking(void)
3133 IStorage
*stg
, *stg2
, *stg3
, *stg4
;
3136 static const WCHAR stgname
[] = { 'S','T','G','1',0 };
3137 static const WCHAR stgname2
[] = { 'S','T','G','2',0 };
3138 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
3141 DeleteFileA(filenameA
);
3143 /* create the file */
3144 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
3145 STGM_READWRITE
, 0, &stg
);
3146 ok(r
==S_OK
, "StgCreateDocfile failed\n");
3148 /* create a substorage */
3149 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
3150 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3152 /* create another substorage */
3153 r
= IStorage_CreateStorage(stg
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg3
);
3154 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3156 /* add a stream, and leave it open */
3157 r
= IStorage_CreateStream(stg2
, stmname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3158 ok(r
==S_OK
, "IStorage->CreateStream failed, hr=%08x\n", r
);
3160 /* Try to copy the storage while the stream is open */
3161 r
= IStorage_CopyTo(stg2
, 0, NULL
, NULL
, stg3
);
3162 ok(r
==S_OK
, "IStorage->CopyTo failed, hr=%08x\n", r
);
3164 IStream_Release(stm
);
3166 /* create a substorage */
3167 r
= IStorage_CreateStorage(stg2
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg4
);
3168 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3170 /* Try to copy the storage while the substorage is open */
3171 r
= IStorage_CopyTo(stg2
, 0, NULL
, NULL
, stg3
);
3172 ok(r
==S_OK
, "IStorage->CopyTo failed, hr=%08x\n", r
);
3174 IStorage_Release(stg4
);
3175 IStorage_Release(stg3
);
3176 IStorage_Release(stg2
);
3177 IStorage_Release(stg
);
3179 ret
= DeleteFileA(filenameA
);
3180 ok(ret
, "deleted file\n");
3183 static void test_copyto_recursive(void)
3185 IStorage
*stg
, *stg2
, *stg3
, *stg4
;
3187 static const WCHAR stgname
[] = { 'S','T','G','1',0 };
3188 static const WCHAR stgname2
[] = { 'S','T','G','2',0 };
3191 DeleteFileA(filenameA
);
3193 /* create the file */
3194 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
3195 STGM_READWRITE
, 0, &stg
);
3196 ok(r
==S_OK
, "StgCreateDocfile failed\n");
3198 /* create a substorage */
3199 r
= IStorage_CreateStorage(stg
, stgname
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
3200 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3202 /* copy the parent to the child */
3203 r
= IStorage_CopyTo(stg
, 0, NULL
, NULL
, stg2
);
3204 ok(r
==STG_E_ACCESSDENIED
, "IStorage->CopyTo failed, hr=%08x\n", r
);
3206 /* create a transacted substorage */
3207 r
= IStorage_CreateStorage(stg
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, 0, 0, &stg3
);
3208 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3210 /* copy the parent to the transacted child */
3211 r
= IStorage_CopyTo(stg
, 0, NULL
, NULL
, stg2
);
3212 ok(r
==STG_E_ACCESSDENIED
, "IStorage->CopyTo failed, hr=%08x\n", r
);
3214 /* create a transacted subsubstorage */
3215 r
= IStorage_CreateStorage(stg3
, stgname2
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_TRANSACTED
, 0, 0, &stg4
);
3216 ok(r
==S_OK
, "IStorage->CreateStorage failed, hr=%08x\n", r
);
3218 /* copy the parent to the transacted child of the transacted child */
3219 r
= IStorage_CopyTo(stg
, 0, NULL
, NULL
, stg4
);
3220 ok(r
==STG_E_ACCESSDENIED
, "IStorage->CopyTo failed, hr=%08x\n", r
);
3222 /* copy the parent but exclude storage objects */
3223 r
= IStorage_CopyTo(stg
, 1, &IID_IStorage
, NULL
, stg4
);
3224 ok(r
==S_OK
, "IStorage->CopyTo failed, hr=%08x\n", r
);
3226 IStorage_Release(stg4
);
3227 IStorage_Release(stg3
);
3228 IStorage_Release(stg2
);
3229 IStorage_Release(stg
);
3231 ret
= DeleteFileA(filenameA
);
3232 ok(ret
, "deleted file\n");
3235 static void test_hglobal_storage_creation(void)
3237 ILockBytes
*ilb
= NULL
;
3238 IStorage
*stg
= NULL
;
3242 ULARGE_INTEGER offset
;
3244 r
= CreateILockBytesOnHGlobal(NULL
, TRUE
, &ilb
);
3245 ok(r
== S_OK
, "CreateILockBytesOnHGlobal failed, hr=%x\n", r
);
3247 offset
.QuadPart
= 0;
3248 memset(junk
, 0xaa, 512);
3249 r
= ILockBytes_WriteAt(ilb
, offset
, junk
, 512, NULL
);
3250 ok(r
== S_OK
, "ILockBytes_WriteAt failed, hr=%x\n", r
);
3252 offset
.QuadPart
= 2000;
3253 r
= ILockBytes_WriteAt(ilb
, offset
, junk
, 512, NULL
);
3254 ok(r
== S_OK
, "ILockBytes_WriteAt failed, hr=%x\n", r
);
3256 r
= StgCreateDocfileOnILockBytes(ilb
, STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, &stg
);
3257 ok(r
== S_OK
, "StgCreateDocfileOnILockBytes failed, hr=%x\n", r
);
3259 IStorage_Release(stg
);
3261 r
= StgOpenStorageOnILockBytes(ilb
, NULL
, STGM_READ
|STGM_SHARE_EXCLUSIVE
,
3263 ok(r
== S_OK
, "StgOpenStorageOnILockBytes failed, hr=%x\n", r
);
3267 r
= IStorage_Stat(stg
, &stat
, STATFLAG_NONAME
);
3268 ok(r
== S_OK
, "StgOpenStorageOnILockBytes failed, hr=%x\n", r
);
3269 ok(IsEqualCLSID(&stat
.clsid
, &GUID_NULL
), "unexpected CLSID value\n");
3271 IStorage_Release(stg
);
3274 r
= ILockBytes_Stat(ilb
, &stat
, STATFLAG_NONAME
);
3275 ok(r
== S_OK
, "ILockBytes_Stat failed, hr=%x\n", r
);
3276 ok(stat
.cbSize
.u
.LowPart
< 2512, "expected truncated size, got %d\n", stat
.cbSize
.u
.LowPart
);
3278 ILockBytes_Release(ilb
);
3281 static void test_convert(void)
3283 static const WCHAR filename
[] = {'s','t','o','r','a','g','e','.','s','t','g',0};
3287 hr
= GetConvertStg(NULL
);
3288 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3290 hr
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
3291 ok(hr
== S_OK
, "StgCreateDocfile failed\n");
3292 hr
= GetConvertStg(stg
);
3293 ok(hr
== STG_E_FILENOTFOUND
, "got 0x%08x\n", hr
);
3294 hr
= SetConvertStg(stg
, TRUE
);
3295 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3296 hr
= SetConvertStg(stg
, TRUE
);
3297 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3298 hr
= GetConvertStg(stg
);
3299 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3300 hr
= SetConvertStg(stg
, FALSE
);
3301 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3302 hr
= GetConvertStg(stg
);
3303 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
3305 IStorage_Release(stg
);
3307 DeleteFileW(filename
);
3310 static void test_direct_swmr(void)
3312 static const WCHAR fileW
[] = {'w','i','n','e','t','e','s','t',0};
3313 IDirectWriterLock
*dwlock
;
3318 /* it's possible to create in writer mode */
3319 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_DENY_WRITE
| STGM_DIRECT_SWMR
, 0, &stg
);
3321 ok(hr
== S_OK
, "got %08x\n", hr
);
3323 IStorage_Release(stg
);
3327 hr
= StgCreateDocfile(fileW
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_DENY_WRITE
| STGM_TRANSACTED
, 0, &stg
);
3328 ok(hr
== S_OK
, "got %08x\n", hr
);
3329 IStorage_Release(stg
);
3332 hr
= StgOpenStorage(fileW
, NULL
, STGM_DIRECT_SWMR
| STGM_READ
| STGM_SHARE_DENY_NONE
, NULL
, 0, &stg
);
3333 ok(hr
== S_OK
|| broken(hr
== STG_E_INVALIDFLAG
), "got %08x\n", hr
);
3336 hr
= IStorage_QueryInterface(stg
, &IID_IDirectWriterLock
, (void**)&dwlock
);
3337 ok(hr
== E_NOINTERFACE
, "got %08x\n", hr
);
3338 IStorage_Release(stg
);
3342 hr
= StgOpenStorage(fileW
, NULL
, STGM_DIRECT_SWMR
| STGM_READWRITE
| STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
3343 ok(hr
== S_OK
, "got %08x\n", hr
);
3346 ref
= IStorage_AddRef(stg
);
3347 IStorage_Release(stg
);
3349 hr
= IStorage_QueryInterface(stg
, &IID_IDirectWriterLock
, (void**)&dwlock
);
3350 ok(hr
== S_OK
, "got %08x\n", hr
);
3352 ref2
= IStorage_AddRef(stg
);
3353 IStorage_Release(stg
);
3354 ok(ref2
== ref
+ 1, "got %u\n", ref2
);
3356 IDirectWriterLock_Release(dwlock
);
3357 IStorage_Release(stg
);
3369 const int *locked_bytes
;
3370 const int *fail_ranges
;
3374 static const int priority_locked_bytes
[] = { 0x158, 0x181, 0x193, -1 };
3375 static const int rwex_locked_bytes
[] = { 0x193, 0x1a7, 0x1bb, 0x1cf, -1 };
3376 static const int rw_locked_bytes
[] = { 0x193, 0x1a7, -1 };
3377 static const int nosn_locked_bytes
[] = { 0x16c, 0x193, 0x1a7, 0x1cf, -1 };
3378 static const int rwdw_locked_bytes
[] = { 0x193, 0x1a7, 0x1cf, -1 };
3379 static const int wodw_locked_bytes
[] = { 0x1a7, 0x1cf, -1 };
3380 static const int tr_locked_bytes
[] = { 0x193, -1 };
3381 static const int no_locked_bytes
[] = { -1 };
3382 static const int roex_locked_bytes
[] = { 0x193, 0x1bb, 0x1cf, -1 };
3384 static const int rwex_fail_ranges
[] = { 0x193,0x1e3, -1 };
3385 static const int rw_fail_ranges
[] = { 0x1bb,0x1e3, -1 };
3386 static const int rwdw_fail_ranges
[] = { 0x1a7,0x1e3, -1 };
3387 static const int dw_fail_ranges
[] = { 0x1a7,0x1cf, -1 };
3388 static const int tr_fail_ranges
[] = { 0x1bb,0x1cf, -1 };
3389 static const int pr_fail_ranges
[] = { 0x180,0x181, 0x1bb,0x1cf, -1 };
3390 static const int roex_fail_ranges
[] = { 0x0,-1 };
3392 static const struct lock_test lock_tests
[] = {
3393 { STGM_PRIORITY
, FALSE
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, priority_locked_bytes
, pr_fail_ranges
, FALSE
},
3394 { STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, TRUE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, rwex_locked_bytes
, 0, FALSE
},
3395 { STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
|STGM_TRANSACTED
, TRUE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, rwex_locked_bytes
, 0, FALSE
},
3396 { STGM_CREATE
|STGM_READWRITE
|STGM_TRANSACTED
, TRUE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, rw_locked_bytes
, 0, FALSE
},
3397 { STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_DENY_WRITE
|STGM_TRANSACTED
, TRUE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, rwdw_locked_bytes
, 0, FALSE
},
3398 { STGM_CREATE
|STGM_WRITE
|STGM_SHARE_DENY_WRITE
|STGM_TRANSACTED
, TRUE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, wodw_locked_bytes
, 0, FALSE
},
3399 { STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, FALSE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, rwex_locked_bytes
, rwex_fail_ranges
, FALSE
},
3400 { STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
|STGM_TRANSACTED
, FALSE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, rwex_locked_bytes
, rwex_fail_ranges
, FALSE
},
3401 { STGM_READWRITE
|STGM_TRANSACTED
, FALSE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, rw_locked_bytes
, rw_fail_ranges
, FALSE
},
3402 { STGM_READWRITE
|STGM_TRANSACTED
|STGM_NOSNAPSHOT
, FALSE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, nosn_locked_bytes
, rwdw_fail_ranges
, FALSE
},
3403 { STGM_READWRITE
|STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
, FALSE
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, rwdw_locked_bytes
, rwdw_fail_ranges
, FALSE
},
3404 { STGM_READ
|STGM_SHARE_DENY_WRITE
, FALSE
, GENERIC_READ
, FILE_SHARE_READ
, no_locked_bytes
, dw_fail_ranges
, TRUE
},
3405 { STGM_READ
|STGM_TRANSACTED
, FALSE
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, tr_locked_bytes
, tr_fail_ranges
, FALSE
},
3406 { STGM_READ
|STGM_SHARE_EXCLUSIVE
, FALSE
, GENERIC_READ
, FILE_SHARE_READ
, roex_locked_bytes
, roex_fail_ranges
, FALSE
},
3407 { STGM_READ
|STGM_SHARE_EXCLUSIVE
|STGM_TRANSACTED
, FALSE
, GENERIC_READ
, FILE_SHARE_READ
, roex_locked_bytes
, roex_fail_ranges
, FALSE
},
3410 static BOOL
can_open(LPCWSTR filename
, DWORD access
, DWORD sharing
)
3414 hfile
= CreateFileW(filename
, access
, sharing
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
3416 if (hfile
== INVALID_HANDLE_VALUE
)
3423 static void check_sharing(LPCWSTR filename
, const struct lock_test
*current
,
3424 DWORD access
, DWORD sharing
, const char *desc
, DWORD
*open_mode
, BOOL
*any_failure
)
3426 if (can_open(filename
, access
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
))
3428 *open_mode
= access
;
3429 if (!current
->todo
|| (current
->sharing
& sharing
))
3430 ok(current
->sharing
& sharing
||
3431 broken(!(current
->sharing
& sharing
) && access
== GENERIC_WRITE
&& (current
->stg_mode
& 0xf) != STGM_READ
) /* win2k */,
3432 "file with mode %x should not be openable with %s permission\n", current
->stg_mode
, desc
);
3435 todo_wine
ok(current
->sharing
& sharing
||
3436 broken(!(current
->sharing
& sharing
) && access
== GENERIC_WRITE
&& (current
->stg_mode
& 0xf) != STGM_READ
) /* win2k */,
3437 "file with mode %x should not be openable with %s permission\n", current
->stg_mode
, desc
);
3438 *any_failure
= TRUE
;
3443 if (!current
->todo
|| !(current
->sharing
& sharing
))
3444 ok(!(current
->sharing
& sharing
), "file with mode %x should be openable with %s permission\n", current
->stg_mode
, desc
);
3447 todo_wine
ok(!(current
->sharing
& sharing
), "file with mode %x should be openable with %s permission\n", current
->stg_mode
, desc
);
3448 *any_failure
= TRUE
;
3453 static void check_access(LPCWSTR filename
, const struct lock_test
*current
,
3454 DWORD access
, DWORD sharing
, const char *desc
, DWORD open_mode
, BOOL
*any_failure
)
3456 if (can_open(filename
, open_mode
, (FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
) & ~sharing
))
3458 if (!current
->todo
|| !(current
->access
& access
))
3459 ok(!(current
->access
& access
), "file with mode %x should not be openable without %s sharing\n", current
->stg_mode
, desc
);
3462 todo_wine
ok(!(current
->access
& access
), "file with mode %x should not be openable without %s sharing\n", current
->stg_mode
, desc
);
3463 *any_failure
= TRUE
;
3468 if (!current
->todo
|| (current
->access
& access
))
3469 ok(current
->access
& access
, "file with mode %x should be openable without %s sharing\n", current
->stg_mode
, desc
);
3472 todo_wine
ok(current
->access
& access
, "file with mode %x should be openable without %s sharing\n", current
->stg_mode
, desc
);
3473 *any_failure
= TRUE
;
3478 static void test_locking(void)
3480 static const WCHAR filename
[] = {'w','i','n','e','t','e','s','t',0};
3485 for (i
=0; i
<sizeof(lock_tests
)/sizeof(lock_tests
[0]); i
++)
3487 const struct lock_test
*current
= &lock_tests
[i
];
3488 BOOL any_failure
= FALSE
;
3489 DWORD open_mode
= 0;
3491 if (current
->create
)
3493 hr
= StgCreateDocfile(filename
, current
->stg_mode
, 0, &stg
);
3494 ok(SUCCEEDED(hr
), "StgCreateDocfile with mode %x failed with hr %x\n", current
->stg_mode
, hr
);
3495 if (FAILED(hr
)) continue;
3499 hr
= StgCreateDocfile(filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
3500 ok(SUCCEEDED(hr
), "StgCreateDocfile failed with hr %x\n", hr
);
3501 if (FAILED(hr
)) continue;
3502 IStorage_Release(stg
);
3504 hr
= StgOpenStorage(filename
, NULL
, current
->stg_mode
, NULL
, 0, &stg
);
3505 ok(SUCCEEDED(hr
), "StgOpenStorage with mode %x failed with hr %x\n", current
->stg_mode
, hr
);
3508 DeleteFileW(filename
);
3513 check_sharing(filename
, current
, GENERIC_READ
, FILE_SHARE_READ
, "READ", &open_mode
, &any_failure
);
3514 check_sharing(filename
, current
, GENERIC_WRITE
, FILE_SHARE_WRITE
, "WRITE", &open_mode
, &any_failure
);
3515 check_sharing(filename
, current
, DELETE
, FILE_SHARE_DELETE
, "DELETE", &open_mode
, &any_failure
);
3520 BOOL locked
, expect_locked
;
3522 const int* next_lock
= current
->locked_bytes
;
3524 check_access(filename
, current
, GENERIC_READ
, FILE_SHARE_READ
, "READ", open_mode
, &any_failure
);
3525 check_access(filename
, current
, GENERIC_WRITE
, FILE_SHARE_WRITE
, "WRITE", open_mode
, &any_failure
);
3526 check_access(filename
, current
, DELETE
, FILE_SHARE_DELETE
, "DELETE", open_mode
, &any_failure
);
3528 hfile
= CreateFileW(filename
, open_mode
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
3529 ok(hfile
!= INVALID_HANDLE_VALUE
, "couldn't open file with mode %x\n", current
->stg_mode
);
3531 ol
.u
.s
.OffsetHigh
= 0;
3534 for (ol
.u
.s
.Offset
= 0x7ffffe00; ol
.u
.s
.Offset
!= 0x80000000; ol
.u
.s
.Offset
++)
3536 if (LockFileEx(hfile
, LOCKFILE_EXCLUSIVE_LOCK
|LOCKFILE_FAIL_IMMEDIATELY
, 0, 1, 0, &ol
))
3540 ok(!LockFileEx(hfile
, LOCKFILE_FAIL_IMMEDIATELY
, 0, 1, 0, &ol
), "shared locks should not be used\n");
3544 UnlockFileEx(hfile
, 0, 1, 0, &ol
);
3546 if ((ol
.u
.s
.Offset
&0x1ff) == *next_lock
)
3548 expect_locked
= TRUE
;
3552 expect_locked
= FALSE
;
3554 if (!current
->todo
|| locked
== expect_locked
)
3555 ok(locked
== expect_locked
, "byte %x of file with mode %x is %slocked but should %sbe\n",
3556 ol
.u
.s
.Offset
, current
->stg_mode
, locked
?"":"not ", expect_locked
?"":"not ");
3560 todo_wine
ok(locked
== expect_locked
, "byte %x of file with mode %x is %slocked but should %sbe\n",
3561 ol
.u
.s
.Offset
, current
->stg_mode
, locked
?"":"not ", expect_locked
?"":"not ");
3568 IStorage_Release( stg
);
3570 if (!current
->create
)
3573 BOOL failed
, expect_failed
=FALSE
;
3575 const int* next_range
= current
->fail_ranges
;
3577 hfile
= CreateFileW(filename
, open_mode
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
3578 ok(hfile
!= INVALID_HANDLE_VALUE
, "couldn't open file with mode %x\n", current
->stg_mode
);
3580 ol
.u
.s
.OffsetHigh
= 0;
3583 for (ol
.u
.s
.Offset
= 0x7ffffe00; ol
.u
.s
.Offset
!= 0x80000000; ol
.u
.s
.Offset
++)
3585 if (ol
.u
.s
.Offset
== 0x7fffff92 ||
3586 (ol
.u
.s
.Offset
== 0x7fffff80 && current
->stg_mode
== (STGM_TRANSACTED
|STGM_READWRITE
)) ||
3587 (ol
.u
.s
.Offset
== 0x7fffff80 && current
->stg_mode
== (STGM_TRANSACTED
|STGM_READ
)))
3588 continue; /* This makes opens hang */
3590 if (ol
.u
.s
.Offset
< 0x7fffff00)
3591 LockFileEx(hfile
, 0, 0, 1, 0, &ol
);
3593 LockFileEx(hfile
, LOCKFILE_EXCLUSIVE_LOCK
, 0, 1, 0, &ol
);
3595 hr
= StgOpenStorage(filename
, NULL
, current
->stg_mode
, NULL
, 0, &stg
);
3596 ok(hr
== S_OK
|| hr
== STG_E_LOCKVIOLATION
|| hr
== STG_E_SHAREVIOLATION
, "failed with unexpected hr %x\n", hr
);
3597 if (SUCCEEDED(hr
)) IStorage_Release(stg
);
3599 UnlockFileEx(hfile
, 0, 1, 0, &ol
);
3601 failed
= FAILED(hr
);
3603 if (!expect_failed
&& (ol
.u
.s
.Offset
&0x1ff) == next_range
[0])
3605 expect_failed
= TRUE
;
3607 else if (expect_failed
&& (ol
.u
.s
.Offset
&0x1ff) == next_range
[1])
3609 expect_failed
= FALSE
;
3613 if (!current
->todo
|| failed
== expect_failed
)
3614 ok(failed
== expect_failed
, "open with byte %x locked, mode %x %s but should %s\n",
3615 ol
.u
.s
.Offset
, current
->stg_mode
, failed
?"failed":"succeeded", expect_failed
?"fail":"succeed");
3619 todo_wine
ok(failed
== expect_failed
, "open with byte %x locked, mode %x %s but should %s\n",
3620 ol
.u
.s
.Offset
, current
->stg_mode
, failed
?"failed":"succeeded", expect_failed
?"fail":"succeed");
3627 DeleteFileW(filename
);
3629 if (current
->todo
&& !any_failure
)
3630 todo_wine
ok(1, "tests succeeded for mode %x\n", current
->stg_mode
);
3634 static void test_transacted_shared(void)
3636 IStorage
*stg
= NULL
;
3637 IStorage
*stgrw
= NULL
;
3639 IStream
*stm
= NULL
;
3640 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
3642 ULARGE_INTEGER upos
;
3646 DeleteFileA(filenameA
);
3648 /* create a new transacted storage with a stream */
3649 r
= StgCreateDocfile(filename
, STGM_CREATE
|
3650 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
3651 ok(r
==S_OK
, "StgCreateDocfile failed %x\n", r
);
3653 r
= WriteClassStg(stg
, &test_stg_cls
);
3654 ok(r
== S_OK
, "WriteClassStg failed %x\n", r
);
3656 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
3657 ok(r
==S_OK
, "IStorage->CreateStream failed %x\n", r
);
3660 r
= IStream_Seek(stm
, pos
, 0, &upos
);
3661 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3663 r
= IStream_Write(stm
, "aaa", 3, NULL
);
3664 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3666 r
= IStorage_Commit(stg
, STGC_ONLYIFCURRENT
);
3667 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3669 /* open a second transacted read/write storage */
3670 r
= StgOpenStorage(filename
, NULL
, STGM_READWRITE
| STGM_TRANSACTED
| STGM_SHARE_DENY_NONE
, NULL
, 0, &stgrw
);
3671 ok(r
==S_OK
, "StgOpenStorage failed %x\n", r
);
3673 /* update stream on the first storage and commit */
3675 r
= IStream_Seek(stm
, pos
, 0, &upos
);
3676 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3678 r
= IStream_Write(stm
, "ccc", 3, NULL
);
3679 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3681 r
= IStorage_Commit(stg
, STGC_ONLYIFCURRENT
);
3682 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3684 /* update again without committing */
3686 r
= IStream_Seek(stm
, pos
, 0, &upos
);
3687 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3689 r
= IStream_Write(stm
, "ddd", 3, NULL
);
3690 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3692 IStream_Release(stm
);
3694 /* we can still read the old content from the second storage */
3695 r
= IStorage_OpenStream(stgrw
, stmname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stm
);
3696 ok(r
==S_OK
, "IStorage->OpenStream failed %x\n", r
);
3699 r
= IStream_Seek(stm
, pos
, 0, &upos
);
3700 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3702 r
= IStream_Read(stm
, buffer
, sizeof(buffer
), &bytesread
);
3703 ok(r
==S_OK
, "IStream->Read failed %x\n", r
);
3704 ok(bytesread
== 3, "read wrong number of bytes %i\n", bytesread
);
3705 ok(memcmp(buffer
, "aaa", 3) == 0, "wrong data\n");
3707 /* and overwrite the data */
3709 r
= IStream_Seek(stm
, pos
, 0, &upos
);
3710 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3712 r
= IStream_Write(stm
, "bbb", 3, NULL
);
3713 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3715 IStream_Release(stm
);
3717 /* commit fails because we're out of date */
3718 r
= IStorage_Commit(stgrw
, STGC_ONLYIFCURRENT
);
3719 ok(r
==STG_E_NOTCURRENT
, "IStorage->Commit failed %x\n", r
);
3721 /* unless we force it */
3722 r
= IStorage_Commit(stgrw
, STGC_DEFAULT
);
3723 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3725 /* reverting gets us back to the last commit from the same storage */
3726 r
= IStorage_Revert(stg
);
3727 ok(r
==S_OK
, "IStorage->Revert failed %x\n", r
);
3729 r
= IStorage_OpenStream(stg
, stmname
, NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stm
);
3730 ok(r
==S_OK
, "IStorage->CreateStream failed %x\n", r
);
3733 r
= IStream_Seek(stm
, pos
, 0, &upos
);
3734 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3736 r
= IStream_Read(stm
, buffer
, sizeof(buffer
), &bytesread
);
3737 ok(r
==S_OK
, "IStream->Read failed %x\n", r
);
3738 ok(bytesread
== 3, "read wrong number of bytes %i\n", bytesread
);
3739 ok(memcmp(buffer
, "ccc", 3) == 0, "wrong data\n");
3741 /* and committing fails forever */
3742 r
= IStorage_Commit(stg
, STGC_ONLYIFCURRENT
);
3743 ok(r
==STG_E_NOTCURRENT
, "IStorage->Commit failed %x\n", r
);
3745 IStream_Release(stm
);
3747 IStorage_Release(stg
);
3748 IStorage_Release(stgrw
);
3750 DeleteFileA(filenameA
);
3753 static void test_overwrite(void)
3755 IStorage
*stg
= NULL
;
3757 IStream
*stm
= NULL
;
3758 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
3759 static const WCHAR stmname2
[] = { 'C','O','N','T','E','N','T','2',0 };
3761 ULARGE_INTEGER upos
;
3763 DWORD orig_size
, new_size
;
3768 DeleteFileA(filenameA
);
3770 r
= StgCreateDocfile(filename
, STGM_CREATE
| STGM_READWRITE
| STGM_TRANSACTED
, 0, &stg
);
3771 ok(r
==S_OK
, "StgCreateDocfile failed %x\n", r
);
3773 r
= WriteClassStg(stg
, &test_stg_cls
);
3774 ok(r
== S_OK
, "WriteClassStg failed %x\n", r
);
3776 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
3777 ok(r
==S_OK
, "IStorage->CreateStream failed %x\n", r
);
3780 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &upos
);
3781 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3783 memset(buffer
, 'a', sizeof(buffer
));
3786 /* Write enough bytes to pass the minimum storage file size */
3787 r
= IStream_Write(stm
, buffer
, sizeof(buffer
), NULL
);
3788 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3791 r
= IStorage_Commit(stg
, STGC_DEFAULT
);
3792 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3794 hfile
= CreateFileA(filenameA
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3795 NULL
, OPEN_EXISTING
, 0, NULL
);
3796 ok(hfile
!= NULL
, "couldn't open file %d\n", GetLastError());
3798 orig_size
= GetFileSize(hfile
, NULL
);
3801 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &upos
);
3802 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3804 r
= IStream_Write(stm
, "b", 1, NULL
);
3805 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3807 r
= IStorage_Commit(stg
, STGC_OVERWRITE
);
3808 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3810 new_size
= GetFileSize(hfile
, NULL
);
3812 todo_wine
ok(new_size
== orig_size
, "file grew from %d bytes to %d\n", orig_size
, new_size
);
3814 IStream_Release(stm
);
3816 IStorage_RenameElement(stg
, stmname
, stmname2
);
3818 r
= IStorage_Commit(stg
, STGC_OVERWRITE
);
3819 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3821 new_size
= GetFileSize(hfile
, NULL
);
3823 todo_wine
ok(new_size
== orig_size
, "file grew from %d bytes to %d\n", orig_size
, new_size
);
3825 IStorage_Release(stg
);
3827 r
= StgOpenStorage(filename
, NULL
, STGM_READWRITE
| STGM_TRANSACTED
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
3828 ok(r
==S_OK
, "StgOpenStorage failed %x\n", r
);
3830 r
= IStorage_OpenStream(stg
, stmname2
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stm
);
3831 ok(r
==S_OK
, "IStorage->CreateStream failed %x\n", r
);
3833 r
= IStream_Read(stm
, buffer
, sizeof(buffer
), &bytesread
);
3834 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3835 ok(bytesread
== sizeof(buffer
), "only read %d bytes\n", bytesread
);
3836 ok(buffer
[0] == 'b', "unexpected data at byte 0\n");
3838 for (i
=1; i
<sizeof(buffer
); i
++)
3839 if (buffer
[i
] != 'a')
3841 ok(i
== sizeof(buffer
), "unexpected data at byte %i\n", i
);
3844 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &upos
);
3845 ok(r
==S_OK
, "IStream->Seek failed %x\n", r
);
3847 r
= IStream_Write(stm
, "c", 1, NULL
);
3848 ok(r
==S_OK
, "IStream->Write failed %x\n", r
);
3850 r
= IStorage_Commit(stg
, STGC_OVERWRITE
);
3851 ok(r
==S_OK
, "IStorage->Commit failed %x\n", r
);
3853 new_size
= GetFileSize(hfile
, NULL
);
3855 todo_wine
ok(new_size
== orig_size
, "file grew from %d bytes to %d\n", orig_size
, new_size
);
3857 IStream_Release(stm
);
3859 IStorage_Release(stg
);
3863 DeleteFileA(filenameA
);
3866 static void test_custom_lockbytes(void)
3868 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
3869 TestLockBytes
* lockbytes
;
3874 CreateTestLockBytes(&lockbytes
);
3876 hr
= StgCreateDocfileOnILockBytes(&lockbytes
->ILockBytes_iface
, STGM_CREATE
|STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
3877 ok(hr
==S_OK
, "StgCreateDocfileOnILockBytes failed %x\n", hr
);
3879 hr
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, 0, &stm
);
3880 ok(hr
==S_OK
, "IStorage_CreateStream failed %x\n", hr
);
3882 IStream_Release(stm
);
3884 hr
= IStorage_Commit(stg
, 0);
3886 IStorage_Release(stg
);
3888 ok(!lockbytes
->lock_called
, "unexpected call to LockRegion\n");
3890 lockbytes
->locks_supported
= LOCK_WRITE
|LOCK_EXCLUSIVE
|LOCK_ONLYONCE
;
3892 hr
= StgCreateDocfileOnILockBytes(&lockbytes
->ILockBytes_iface
, STGM_CREATE
|STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
3893 ok(hr
==S_OK
, "StgCreateDocfileOnILockBytes failed %x\n", hr
);
3895 hr
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, 0, &stm
);
3896 ok(hr
==S_OK
, "IStorage_CreateStream failed %x\n", hr
);
3898 IStream_Release(stm
);
3900 hr
= IStorage_Commit(stg
, 0);
3902 IStorage_Release(stg
);
3904 ok(lockbytes
->lock_called
, "expected LockRegion to be called\n");
3906 lockbytes
->lock_hr
= STG_E_INVALIDFUNCTION
;
3908 hr
= StgCreateDocfileOnILockBytes(&lockbytes
->ILockBytes_iface
, STGM_CREATE
|STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
3909 ok(hr
==STG_E_INVALIDFUNCTION
, "StgCreateDocfileOnILockBytes failed %x\n", hr
);
3911 DeleteTestLockBytes(lockbytes
);
3914 START_TEST(storage32
)
3916 CHAR temp
[MAX_PATH
];
3918 GetTempPathA(MAX_PATH
, temp
);
3919 if(!GetTempFileNameA(temp
, "stg", 0, filenameA
))
3921 win_skip("Could not create temp file, %u\n", GetLastError());
3924 MultiByteToWideChar(CP_ACP
, 0, filenameA
, -1, filename
, MAX_PATH
);
3925 DeleteFileA(filenameA
);
3927 test_hglobal_storage_stat();
3928 test_create_storage_modes();
3929 test_stgcreatestorageex();
3930 test_storage_stream();
3931 test_open_storage();
3932 test_storage_suminfo();
3933 test_storage_refcount();
3936 test_substorage_share();
3939 test_nonroot_transacted();
3940 test_ReadClassStm();
3942 test_writeclassstg();
3945 test_fmtusertypestg();
3948 test_copyto_snbexclusions();
3949 test_copyto_iidexclusions_storage();
3950 test_copyto_iidexclusions_stream();
3952 test_toplevel_stat();
3953 test_substorage_enum();
3954 test_copyto_locking();
3955 test_copyto_recursive();
3956 test_hglobal_storage_creation();
3960 test_transacted_shared();
3962 test_custom_lockbytes();