ReactOS 0.4.15-dev-7961-gdcf9eb0
storage32.c
Go to the documentation of this file.
1/*
2 * Unit tests for OLE storage
3 *
4 * Copyright (c) 2004 Mike McCormack
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <stdio.h>
22
23#define COBJMACROS
24#ifdef __REACTOS__
25#define CONST_VTABLE
26#else
27#define NONAMELESSUNION
28#define NONAMELESSSTRUCT
29#endif
30
31#include <windows.h>
32#include "wine/test.h"
33
34#include "ole2.h"
35#include "objidl.h"
36#include "initguid.h"
37
38DEFINE_GUID( test_stg_cls, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0);
39
40#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
41
44
45static const char file1_nameA[] = {'c','o','p','y','t','e','s','t','A',0};
46static const WCHAR file1_name[] = {'c','o','p','y','t','e','s','t','A',0};
47static const char file2_nameA[] = {'c','o','p','y','t','e','s','t','B',0};
48static const WCHAR file2_name[] = {'c','o','p','y','t','e','s','t','B',0};
49static const WCHAR stgA_name[] = {'S','t','o','r','a','g','e','A',0};
50static const WCHAR stgB_name[] = {'S','t','o','r','a','g','e','B',0};
51static const WCHAR strmA_name[] = {'S','t','r','e','a','m','A',0};
52static const WCHAR strmB_name[] = {'S','t','r','e','a','m','B',0};
53static const WCHAR strmC_name[] = {'S','t','r','e','a','m','C',0};
54
55/* Win9x and WinMe don't have lstrcmpW */
56static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2)
57{
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);
62}
63
64typedef struct TestLockBytes {
74
76{
77 return CONTAINING_RECORD(iface, TestLockBytes, ILockBytes_iface);
78}
79
81 void **ppv)
82{
84
85 if (!ppv) return E_INVALIDARG;
86
87 if (IsEqualIID(&IID_IUnknown, iid) ||
88 IsEqualIID(&IID_ILockBytes, iid))
89 *ppv = &This->ILockBytes_iface;
90 else
91 return E_NOINTERFACE;
92
93 IUnknown_AddRef((IUnknown*)*ppv);
94 return S_OK;
95}
96
98{
101 return ref;
102}
103
105{
108 return ref;
109}
110
112 ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead)
113{
115 ULONG dummy;
116
117 if (!pv) return E_INVALIDARG;
118
119 if (!pcbRead) pcbRead = &dummy;
120
121 if (ulOffset.QuadPart >= This->size)
122 {
123 *pcbRead = 0;
124 return S_OK;
125 }
126
127 cb = min(cb, This->size - ulOffset.QuadPart);
128
129 *pcbRead = cb;
130 memcpy(pv, &This->contents[ulOffset.QuadPart], cb);
131
132 return S_OK;
133}
134
136 ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten)
137{
139 HRESULT hr;
140 ULONG dummy;
141
142 if (!pv) return E_INVALIDARG;
143
144 if (!pcbWritten) pcbWritten = &dummy;
145
146 if (ulOffset.QuadPart + cb > This->size)
147 {
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;
152 }
153
154 *pcbWritten = cb;
155 memcpy(&This->contents[ulOffset.QuadPart], pv, cb);
156
157 return S_OK;
158}
159
161{
162 return S_OK;
163}
164
167{
169
170 if (This->buffer_size < cb.QuadPart)
171 {
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;
178 }
179
180 if (cb.QuadPart > This->size)
181 memset(&This->contents[This->size], 0, cb.QuadPart - This->size);
182
183 This->size = cb.QuadPart;
184
185 return S_OK;
186}
187
189 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
190{
192 This->lock_called++;
193 return This->lock_hr;
194}
195
197 ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
198{
200 return This->lock_hr;
201}
202
204 STATSTG *pstatstg, DWORD grfStatFlag)
205{
207 static const WCHAR dummy_name[] = {'d','u','m','m','y',0};
208
209 if (!pstatstg) return E_INVALIDARG;
210
211 memset(pstatstg, 0, sizeof(STATSTG));
212
213 if (!(grfStatFlag & STATFLAG_NONAME))
214 {
215 pstatstg->pwcsName = CoTaskMemAlloc(sizeof(dummy_name));
216 if (!pstatstg->pwcsName) return E_OUTOFMEMORY;
217 memcpy(pstatstg->pwcsName, dummy_name, sizeof(dummy_name));
218 }
219
220 pstatstg->type = STGTY_LOCKBYTES;
221 pstatstg->cbSize.QuadPart = This->size;
222 pstatstg->grfLocksSupported = This->locks_supported;
223
224 return S_OK;
225}
226
227static const ILockBytesVtbl TestLockBytes_Vtbl = {
238};
239
241{
243
244 if (*This)
245 {
246 (*This)->ILockBytes_iface.lpVtbl = &TestLockBytes_Vtbl;
247 (*This)->ref = 1;
248 }
249}
250
252{
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);
257}
258
260{
261 ILockBytes *ilb = NULL;
262 IStorage *stg = NULL;
263 HRESULT r;
264 STATSTG stat;
265 DWORD mode, refcount;
266
268 ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
269
270 r = StgIsStorageILockBytes( ilb );
271 ok( r == S_FALSE, "StgIsStorageILockBytes should have failed\n");
272
274 r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
275 ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
276
277 r = WriteClassStg( stg, &test_stg_cls );
278 ok( r == S_OK, "WriteClassStg failed\n");
279
280 r = StgIsStorageILockBytes( ilb );
281 ok( r == S_OK, "StgIsStorageILockBytes failed\n");
282
283 memset( &stat, 0, sizeof stat );
284 r = IStorage_Stat( stg, &stat, 0 );
285
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");
290
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");
295}
296
298{
299 IStorage *stg = NULL;
300 HRESULT r;
301
303
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");
310 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
312 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
314 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
316 ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
318 ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
320 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
322 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
324 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
325
326 /* StgCreateDocfile seems to be very particular about the flags it accepts */
328 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
330 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
332 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
334 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
336 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
338 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
340 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
341 ok(stg == NULL, "stg was set\n");
342
343 /* check what happens if the file already exists (which is how it's meant to be used) */
345 ok(r==S_OK, "StgCreateDocfile failed\n");
346 r = IStorage_Release(stg);
347 ok(r == 0, "storage not released\n");
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 */
353 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
355 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
357 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
359 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
361 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
363 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
365 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
367 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
369 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
370 ok(DeleteFileA(filenameA), "failed to delete file\n");
371
373 ok(r==S_OK, "StgCreateDocfile failed\n");
374 r = IStorage_Release(stg);
375 ok(r == 0, "storage not released\n");
377 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
379 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
380
382 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
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");
388
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");
394
395 /* test the way excel uses StgCreateDocFile */
397 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
398 if(r == S_OK)
399 {
400 r = IStorage_Release(stg);
401 ok(r == 0, "storage not released\n");
402 ok(DeleteFileA(filenameA), "failed to delete file\n");
403 }
404
405 /* and the way windows media uses it ... */
407 ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
408 if (r == S_OK)
409 {
410 r = IStorage_Release(stg);
411 ok(r == 0, "storage not released\n");
412 ok(DeleteFileA(filenameA), "failed to delete file\n");
413 }
414
415 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
417 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
418 if(r == S_OK)
419 {
420 r = IStorage_Release(stg);
421 ok(r == 0, "storage not released\n");
422 ok(DeleteFileA(filenameA), "failed to delete file\n");
423 }
424
426 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
427 if(r == S_OK)
428 {
429 r = IStorage_Release(stg);
430 ok(r == 0, "storage not released\n");
431 ok(DeleteFileA(filenameA), "failed to delete file\n");
432 }
433
435 ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
436 if(r == S_OK)
437 {
438 r = IStorage_Release(stg);
439 ok(r == 0, "storage not released\n");
440 ok(DeleteFileA(filenameA), "failed to delete file\n");
441 }
442
443 /* test the way msi uses StgCreateDocfile */
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");
449}
450
451static void test_stgcreatestorageex(void)
452{
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};
457 HRESULT r;
458
459 pStgCreateStorageEx = (void *) GetProcAddress(hOle32, "StgCreateStorageEx");
460 if (!pStgCreateStorageEx)
461 {
462 win_skip("skipping test on NT4\n");
463 return;
464 }
465
467
468 /* Verify that StgCreateStorageEx can accept an options param */
469 r = pStgCreateStorageEx( filename,
472 0,
473 &stgoptions,
474 NULL,
475 &IID_IStorage,
476 (void **) &stg);
477 ok(r==S_OK || r==STG_E_UNIMPLEMENTEDFUNCTION, "StgCreateStorageEx with options failed\n");
479 {
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");
482 return;
483 }
484
485 r = IStorage_Release(stg);
486 ok(r == 0, "storage not released\n");
487 ok(DeleteFileA(filenameA), "failed to delete file\n");
488
489 /* Verify that StgCreateStorageEx can accept a NULL pStgOptions */
490 r = pStgCreateStorageEx( filename,
493 0,
494 NULL,
495 NULL,
496 &IID_IStorage,
497 (void **) &stg);
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");
502}
503
504static void test_storage_stream(void)
505{
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
510 };
511 IStorage *stg = NULL;
512 HRESULT r;
513 IStream *stm = NULL;
514 IStream *stm2 = NULL;
515 ULONG count = 0;
518 unsigned char buffer[0x100];
519 IUnknown *unk;
520 BOOL ret;
521
523
525 ok(r==S_OK, "StgCreateDocfile failed\n");
526
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");
549
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");
553
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);
559
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");
566
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");
570
571 r = IStream_Clone(stm, &stm2);
572 ok(r==S_OK, "failed to clone stream\n");
573
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");
586
587 /* Read past the end of the stream. */
588 pos.QuadPart = 3;
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");
595 pos.QuadPart = 10;
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");
609
610 /* Convert to a big block stream, and read past the end. */
611 p.QuadPart = 5000;
612 r = IStream_SetSize(stm,p);
613 ok(r==S_OK, "failed to set pos\n");
614 pos.QuadPart = 4997;
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");
621 pos.QuadPart = 5001;
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");
635
636 /* seek round a bit, reset the stream size */
637 pos.QuadPart = 0;
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");
646 pos.QuadPart = 10;
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");
660 pos.QuadPart = 0;
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");
667
668 /* wrap up */
669 r = IStream_Release(stm2);
670 ok(r == 0, "wrong ref count\n");
671
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");
675
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);
678
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");
683
684 r = IStorage_Release(stg);
685 ok(r == 0, "wrong ref count\n");
686
687 /* try create some invalid streams */
688 stg = NULL;
689 stm = NULL;
691 ok(r == S_OK, "should succeed\n");
692 if (stg)
693 {
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);
697 }
698
700 ok(ret, "file should exist\n");
701}
702
704{
705 HANDLE file;
706
710 return FALSE;
712 return TRUE;
713}
714
716{
717 HANDLE file;
718 DWORD len;
719
721 OPEN_EXISTING, 0, NULL);
723 return FALSE;
726 return len == 0;
727}
728
730{
731 HANDLE file;
732
734 OPEN_EXISTING, 0, NULL);
736 return FALSE;
738 return TRUE;
739}
740
741static void test_open_storage(void)
742{
743 static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
744 IStorage *stg = NULL, *stg2 = NULL;
745 HRESULT r;
746 DWORD stgm;
747 BOOL ret;
748
749 /* try opening a zero length file - it should stay zero length */
753 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
754 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
755
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");
760
762
763 /* try opening a nonexistent file - it should not create it */
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");
770
771 /* create the file */
773 ok(r==S_OK, "StgCreateDocfile failed\n");
774 IStorage_Release(stg);
775
776 r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
777 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
779 ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
781 ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
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");
787 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
789 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
791 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
793 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
794
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");
798 if(stg)
799 {
800 r = IStorage_Release(stg);
801 ok(r == 0, "wrong ref count\n");
802 }
803
805 ok(r==S_OK, "StgOpenStorage failed\n");
806 if(stg)
807 {
808 r = IStorage_Release(stg);
809 ok(r == 0, "wrong ref count\n");
810 }
811
812 /* test the way word opens its custom dictionary */
815 ok(r==S_OK, "StgOpenStorage failed\n");
816 if(stg)
817 {
818 r = IStorage_Release(stg);
819 ok(r == 0, "wrong ref count\n");
820 }
821
823 ok(r==S_OK, "StgOpenStorage failed\n");
825 ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
826 if(stg)
827 {
828 r = IStorage_Release(stg);
829 ok(r == 0, "wrong ref count\n");
830 }
831
832 /* now try write to a storage file we opened read-only */
834 ok(r==S_OK, "StgOpenStorage failed\n");
835 if(stg)
836 {
837 static const WCHAR stmname[] = { 'w','i','n','e','t','e','s','t',0};
838 IStream *stm = NULL;
839 IStorage *stg2 = NULL;
840
841 r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
842 0, 0, &stm );
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");
846
847 r = IStorage_Release(stg);
848 ok(r == 0, "wrong ref count\n");
849 }
850
851 /* open like visio 2003 */
852 stg = NULL;
854 ok(r == S_OK, "should succeed\n");
855 if (stg)
856 IStorage_Release(stg);
857
858 /* test other sharing modes with STGM_PRIORITY */
859 stg = NULL;
861 ok(r == S_OK, "should succeed\n");
862 if (stg)
863 IStorage_Release(stg);
864
865 stg = NULL;
867 ok(r == S_OK, "should succeed\n");
868 if (stg)
869 IStorage_Release(stg);
870
871 stg = NULL;
873 ok(r == S_OK, "should succeed\n");
874 if (stg)
875 IStorage_Release(stg);
876
877 /* open like Project 2003 */
878 stg = NULL;
880 ok(r == S_OK, "should succeed\n");
882 ok(r == S_OK, "should succeed\n");
883 if (stg2)
884 IStorage_Release(stg2);
885 if (stg)
886 IStorage_Release(stg);
887
888 stg = NULL;
890 ok(r == STG_E_INVALIDFLAG, "should fail\n");
891
893 ok(r == STG_E_INVALIDFLAG, "should fail\n");
894
896 ok(r == STG_E_INVALIDFLAG, "should fail\n");
897
899 ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
900
902 ok(r == STG_E_INVALIDFLAG, "should fail\n");
903
905 ok(r == STG_E_INVALIDFLAG, "should fail\n");
906
908 ok(ret, "file didn't exist\n");
909}
910
911static void test_storage_suminfo(void)
912{
913 IStorage *stg = NULL;
914 IPropertySetStorage *propset = NULL;
916 HRESULT r;
917
919
920 /* create the file */
923 ok(r==S_OK, "StgCreateDocfile failed\n");
924
925 r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
926 ok(r == S_OK, "query interface failed\n");
927
928 /* delete it */
929 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
930 ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
931
932 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
934 ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
935
936 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
938 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
939
940 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
941 STGM_READ, &ps );
942 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
943
944 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
945 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
946
947 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
949 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
950
951 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
953 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
954
955 /* now try really creating a property set */
956 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
958 ok(r == S_OK, "failed to create property set storage\n");
959
960 if( ps )
961 IPropertyStorage_Release(ps);
962
963 /* now try creating the same thing again */
964 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
966 ok(r == S_OK, "failed to create property set storage\n");
967 if( ps )
968 IPropertyStorage_Release(ps);
969
970 /* should be able to open it */
971 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
973 ok(r == S_OK, "open failed\n");
974 if(r == S_OK)
975 IPropertyStorage_Release(ps);
976
977 /* delete it */
978 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
979 ok(r == S_OK, "failed to delete property set storage\n");
980
981 /* try opening with an invalid FMTID */
982 r = IPropertySetStorage_Open( propset, NULL,
984 ok(r == E_INVALIDARG, "open succeeded\n");
985 if(r == S_OK)
986 IPropertyStorage_Release(ps);
987
988 /* try a bad guid */
989 r = IPropertySetStorage_Open( propset, &IID_IStorage,
991 ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
992 if(r == S_OK)
993 IPropertyStorage_Release(ps);
994
995
996 /* try some invalid flags */
997 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
999 ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
1000 if(r == S_OK)
1001 IPropertyStorage_Release(ps);
1002
1003 /* after deleting it, it should be gone */
1004 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
1006 ok(r == STG_E_FILENOTFOUND, "open failed\n");
1007 if(r == S_OK)
1008 IPropertyStorage_Release(ps);
1009
1010 r = IPropertySetStorage_Release( propset );
1011 ok(r == 1, "ref count wrong\n");
1012
1013 r = IStorage_Release(stg);
1014 ok(r == 0, "ref count wrong\n");
1015
1017}
1018
1019static void test_storage_refcount(void)
1020{
1021 IStorage *stg = NULL;
1022 IStorage *stgprio = NULL;
1023 HRESULT r;
1024 IStream *stm = NULL;
1025 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1027 ULARGE_INTEGER upos;
1028 STATSTG stat;
1029 char buffer[10];
1030
1032
1033 /* create the file */
1036 ok(r==S_OK, "StgCreateDocfile failed\n");
1037
1038 r = WriteClassStg( stg, &test_stg_cls );
1039 ok( r == S_OK, "WriteClassStg failed\n");
1040
1041 r = IStorage_Commit( stg, STGC_DEFAULT );
1042 ok( r == S_OK, "IStorage_Commit failed\n");
1043
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");
1047
1048 r = IStorage_Release( stg );
1049 ok (r == 0, "storage not released\n");
1050
1051 pos.QuadPart = 0;
1052 r = IStream_Seek( stm, pos, 0, &upos );
1053 ok (r == STG_E_REVERTED, "seek should fail\n");
1054
1055 r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
1056 ok (r == STG_E_REVERTED, "stat should fail\n");
1057
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);
1060
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);
1063
1064 r = IStream_Release(stm);
1065 ok (r == 0, "stream not released\n");
1066
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);
1071
1072 /* non-transacted mode read/write fails */
1074 ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r);
1075
1076 /* non-transacted mode read-only succeeds */
1078 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
1079 IStorage_Release(stg);
1080
1082 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
1083 if(stg)
1084 {
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 };
1088 IStorage *stg2;
1089 IStorage *stg3;
1090 STATSTG statstg;
1091
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);
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);
1103
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);
1106
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);
1121
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);
1124
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);
1127
1128 IStorage_Release(stg2);
1129
1130 r = IStorage_Release(stg);
1131 ok(r == 0, "wrong ref count\n");
1132 }
1133
1134 /* Multiple STGM_PRIORITY opens are possible. */
1136 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
1137 if(stg)
1138 {
1139 r = IStorage_Release(stg);
1140 ok(r == 0, "wrong ref count\n");
1141 }
1142
1144 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
1145 if(stg)
1146 {
1147 static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
1148 IStorage *stg2;
1149 STATSTG statstg;
1150
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);
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);
1162
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);
1165
1166 IStorage_Release(stg2);
1167
1168 r = IStorage_Commit( stg, 0 );
1169 ok(r == S_OK, "Commit should have succeeded instead of returning 0x%08x\n", r);
1170
1171 r = IStorage_Release(stg);
1172 ok(r == 0, "wrong ref count\n");
1173 }
1174 /* IStorage_Release(stgprio) not necessary because StgOpenStorage released it. */
1175
1177}
1178
1179static void test_writeclassstg(void)
1180{
1181 IStorage *stg = NULL;
1182 HRESULT r;
1183 CLSID temp_cls, cls2;
1184
1186
1187 /* create the file */
1189 STGM_READWRITE, 0, &stg);
1190 ok(r==S_OK, "StgCreateDocfile failed\n");
1191
1192 r = ReadClassStg( NULL, NULL );
1193 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
1194
1195 memset(&temp_cls, 0xcc, sizeof(temp_cls));
1196 memset(&cls2, 0xcc, sizeof(cls2));
1197 r = ReadClassStg( NULL, &temp_cls );
1198 ok(r == E_INVALIDARG, "got 0x%08x\n", r);
1199 ok(IsEqualCLSID(&temp_cls, &cls2), "got wrong clsid\n");
1200
1201 r = ReadClassStg( stg, NULL );
1202 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
1203
1204 temp_cls.Data1 = 0xdeadbeef;
1205 r = ReadClassStg( stg, &temp_cls );
1206 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
1207
1208 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
1209
1210 r = WriteClassStg( NULL, NULL );
1211 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
1212
1213 r = WriteClassStg( stg, NULL );
1214 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
1215
1216 r = WriteClassStg( stg, &test_stg_cls );
1217 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
1218
1219 r = ReadClassStg( stg, &temp_cls );
1220 ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
1221 ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
1222
1223 r = IStorage_Release( stg );
1224 ok (r == 0, "storage not released\n");
1225
1227}
1228
1229static void test_streamenum(void)
1230{
1231 IStorage *stg = NULL;
1232 HRESULT r;
1233 IStream *stm = NULL;
1234 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1235 static const WCHAR stmname2[] = { 'A','B','C','D','E','F','G','H','I',0 };
1236 static const WCHAR stmname3[] = { 'A','B','C','D','E','F','G','H','I','J',0 };
1237 static const STATSTG stat_null;
1238 STATSTG stat;
1239 IEnumSTATSTG *ee = NULL;
1240 ULONG count;
1241
1243
1244 /* create the file */
1247 ok(r==S_OK, "StgCreateDocfile failed\n");
1248
1249 r = WriteClassStg( stg, &test_stg_cls );
1250 ok( r == S_OK, "WriteClassStg failed\n");
1251
1252 r = IStorage_Commit( stg, STGC_DEFAULT );
1253 ok( r == S_OK, "IStorage_Commit failed\n");
1254
1255 /* now create a stream */
1256 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1257 ok(r==S_OK, "IStorage->CreateStream failed\n");
1258
1259 IStream_Release(stm);
1260
1261 /* first enum ... should be 1 stream */
1262 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
1263 ok(r==S_OK, "IStorage->EnumElements failed\n");
1264
1265 count = 0xf00;
1266 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1267 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1268 ok(count == 1, "count wrong\n");
1269
1270 if (r == S_OK)
1271 CoTaskMemFree(stat.pwcsName);
1272
1273 r = IEnumSTATSTG_Release(ee);
1274 ok(r==S_OK, "EnumSTATSTG_Release failed with error 0x%08x\n", r);
1275
1276 /* second enum... destroy the stream before reading */
1277 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
1278 ok(r==S_OK, "IStorage->EnumElements failed\n");
1279
1280 r = IStorage_DestroyElement(stg, stmname);
1281 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1282
1283 memset(&stat, 0xad, sizeof(stat));
1284 count = 0xf00;
1285 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1286 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
1287 ok(count == 0, "count wrong\n");
1288 ok(memcmp(&stat, &stat_null, sizeof(stat)) == 0, "stat is not zeroed\n");
1289
1290 /* reset and try again */
1291 r = IEnumSTATSTG_Reset(ee);
1292 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1293
1294 count = 0xf00;
1295 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1296 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
1297 ok(count == 0, "count wrong\n");
1298
1299 /* add a stream before reading */
1300 r = IEnumSTATSTG_Reset(ee);
1301 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1302
1303 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1304 ok(r==S_OK, "IStorage->CreateStream failed\n");
1305
1306 r = IStream_Release(stm);
1307 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1308
1309 count = 0xf00;
1310 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1311 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1312 ok(count == 1, "count wrong\n");
1313
1314 if (r == S_OK)
1315 {
1316 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1317 CoTaskMemFree(stat.pwcsName);
1318 }
1319
1320 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1321 ok(r==S_OK, "IStorage->CreateStream failed\n");
1322
1323 r = IStream_Release(stm);
1324 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1325
1326 count = 0xf00;
1327 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1328 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1329 ok(count == 1, "count wrong\n");
1330
1331 if (r == S_OK)
1332 {
1333 ok(lstrcmpiW(stat.pwcsName, stmname2) == 0, "expected ABCDEFGHI, got %s\n", wine_dbgstr_w(stat.pwcsName));
1334 CoTaskMemFree(stat.pwcsName);
1335 }
1336
1337 /* delete previous and next stream after reading */
1338 r = IStorage_CreateStream(stg, stmname3, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1339 ok(r==S_OK, "IStorage->CreateStream failed\n");
1340
1341 r = IStream_Release(stm);
1342 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1343
1344 r = IEnumSTATSTG_Reset(ee);
1345 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1346
1347 count = 0xf00;
1348 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1349 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1350 ok(count == 1, "count wrong\n");
1351
1352 if (r == S_OK)
1353 {
1354 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1355 CoTaskMemFree(stat.pwcsName);
1356 }
1357
1358 r = IStorage_DestroyElement(stg, stmname);
1359 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1360
1361 r = IStorage_DestroyElement(stg, stmname2);
1362 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1363
1364 count = 0xf00;
1365 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1366 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1367 ok(count == 1, "count wrong\n");
1368
1369 if (r == S_OK)
1370 {
1371 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1372 CoTaskMemFree(stat.pwcsName);
1373 }
1374
1375 r = IStorage_Release( stg );
1376 todo_wine ok (r == 0, "storage not released\n");
1377
1378 /* enumerator is still valid and working after the storage is released */
1379 r = IEnumSTATSTG_Reset(ee);
1380 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1381
1382 count = 0xf00;
1383 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1384 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1385 ok(count == 1, "count wrong\n");
1386
1387 if (r == S_OK)
1388 {
1389 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1390 CoTaskMemFree(stat.pwcsName);
1391 }
1392
1393 /* the storage is left open until the enumerator is freed */
1397 r==STG_E_LOCKVIOLATION, /* XP-SP2/W2K3-SP1 and below */
1398 "StgCreateDocfile failed, res=%x\n", r);
1399
1400 r = IEnumSTATSTG_Release(ee);
1401 ok (r == 0, "enum not released\n");
1402
1404}
1405
1406static void test_transact(void)
1407{
1408 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1409 HRESULT r;
1410 IStream *stm = NULL;
1411 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1412 static const WCHAR stmname2[] = { 'F','O','O',0 };
1413 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1414 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1415 BOOL ret;
1416
1418
1419 /* create the file */
1422 ok(r==S_OK, "StgCreateDocfile failed\n");
1423
1424 /* commit a new stream and storage */
1425 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1426 ok(r==S_OK, "IStorage->CreateStream failed\n");
1427
1428 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1429 ok(r==S_OK, "IStream->Write failed\n");
1430
1431 IStream_Release(stm);
1432
1433 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1434 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1435
1436 if (r == S_OK)
1437 {
1438 /* Create two substorages but only commit one */
1439 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1440 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1441
1442 if (r == S_OK)
1443 IStorage_Release(stg3);
1444
1445 r = IStorage_Commit(stg, 0);
1446 ok(r==S_OK, "IStorage->Commit failed\n");
1447
1448 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1449 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1450
1451 if (r == S_OK)
1452 IStorage_Release(stg3);
1453
1454 IStorage_Release(stg2);
1455 }
1456
1457 /* now create a stream and storage, but don't commit them */
1458 stm = NULL;
1459 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1460 ok(r==S_OK, "IStorage->CreateStream failed\n");
1461
1462 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
1463 ok(r==S_OK, "IStream->Write failed\n");
1464
1465 /* IStream::Commit does nothing for OLE storage streams */
1466 r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
1467 ok(r==S_OK, "IStream->Commit failed\n");
1468
1469 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1470 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1471
1472 if (r == S_OK)
1473 IStorage_Release(stg2);
1474
1475 IStream_Release(stm);
1476
1477 IStorage_Release(stg);
1478
1479 stm = NULL;
1480 stg = NULL;
1482 ok(r==S_OK, "StgOpenStorage failed\n");
1483
1484 if (!stg)
1485 return;
1486
1487 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1488 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1489
1490 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1491 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1492
1493 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1494 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1495
1496 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1497 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1498
1499 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1500 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1501 if (r == S_OK)
1502 IStream_Release(stm);
1503
1504 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1505 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1506 if (r == S_OK)
1507 IStorage_Release(stg2);
1508
1509 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1510 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1511
1512 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1513 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1514 if (r == S_OK)
1515 IStream_Release(stm);
1516
1517 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1518 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1519 if (r == S_OK)
1520 {
1521 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1522 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1523 if (r == S_OK)
1524 IStorage_Release(stg3);
1525
1526 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1527 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1528 if (r == S_OK)
1529 IStorage_Release(stg3);
1530
1531 IStorage_Release(stg2);
1532 }
1533
1534 IStorage_Release(stg);
1535
1537 ok(ret, "deleted file\n");
1538}
1539
1540static void test_substorage_share(void)
1541{
1542 IStorage *stg, *stg2, *stg3;
1543 IStream *stm, *stm2;
1544 HRESULT r;
1545 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1546 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1547 static const WCHAR othername[] = { 'N','E','W','N','A','M','E',0 };
1548 BOOL ret;
1549
1551
1552 /* create the file */
1554 STGM_READWRITE, 0, &stg);
1555 ok(r==S_OK, "StgCreateDocfile failed\n");
1556
1557 /* create a read/write storage and try to open it again */
1558 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1559 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1560
1561 if (r == S_OK)
1562 {
1563 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1564 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1565
1566 if (r == S_OK)
1567 IStorage_Release(stg3);
1568
1569 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1570 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1571
1572 if (r == S_OK)
1573 IStorage_Release(stg3);
1574
1575 /* cannot rename the storage while it's open */
1576 r = IStorage_RenameElement(stg, stgname, othername);
1577 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1578 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stgname);
1579
1580 /* destroying an object while it's open invalidates it */
1581 r = IStorage_DestroyElement(stg, stgname);
1582 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1583
1584 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1585 ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r);
1586
1587 if (r == S_OK)
1588 IStream_Release(stm);
1589
1590 IStorage_Release(stg2);
1591 }
1592
1593 /* create a read/write stream and try to open it again */
1594 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1595 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
1596
1597 if (r == S_OK)
1598 {
1599 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1600 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1601
1602 if (r == S_OK)
1603 IStream_Release(stm2);
1604
1605 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1606 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1607
1608 if (r == S_OK)
1609 IStream_Release(stm2);
1610
1611 /* cannot rename the stream while it's open */
1612 r = IStorage_RenameElement(stg, stmname, othername);
1613 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1614 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stmname);
1615
1616 /* destroying an object while it's open invalidates it */
1617 r = IStorage_DestroyElement(stg, stmname);
1618 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1619
1620 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1621 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1622
1623 IStream_Release(stm);
1624 }
1625
1626 IStorage_Release(stg);
1627
1629 ok(ret, "deleted file\n");
1630}
1631
1632static void test_revert(void)
1633{
1634 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1635 HRESULT r;
1636 IStream *stm = NULL, *stm2 = NULL;
1637 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1638 static const WCHAR stmname2[] = { 'F','O','O',0 };
1639 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1640 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1641 STATSTG statstg;
1642 BOOL ret;
1643
1645
1646 /* create the file */
1649 ok(r==S_OK, "StgCreateDocfile failed\n");
1650
1651 /* commit a new stream and storage */
1652 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1653 ok(r==S_OK, "IStorage->CreateStream failed\n");
1654
1655 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1656 ok(r==S_OK, "IStream->Write failed\n");
1657
1658 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1659 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1660
1661 if (r == S_OK)
1662 {
1663 /* Create two substorages but only commit one */
1664 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1665 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1666
1667 if (r == S_OK)
1668 IStorage_Release(stg3);
1669
1670 r = IStorage_Commit(stg, 0);
1671 ok(r==S_OK, "IStorage->Commit failed\n");
1672
1673 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1674 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1675
1676 if (r == S_OK)
1677 IStorage_Release(stg3);
1678 }
1679
1680 /* now create a stream and storage, then revert */
1681 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
1682 ok(r==S_OK, "IStorage->CreateStream failed\n");
1683
1684 r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1685 ok(r==S_OK, "IStream->Write failed\n");
1686
1687 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1688 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1689
1690 r = IStorage_Revert(stg);
1691 ok(r==S_OK, "Storage_Revert failed with error 0x%08x\n", r);
1692
1693 /* all open objects become invalid */
1694 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1695 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1696
1697 r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL);
1698 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1699
1700 r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1701 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1702
1703 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1704 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1705
1706 IStream_Release(stm);
1707 IStream_Release(stm2);
1708 IStorage_Release(stg2);
1709 IStorage_Release(stg3);
1710
1711 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1712 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1713
1714 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1715 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1716
1717 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1718 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1719
1720 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1721 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1722
1723 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1724 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1725 if (r == S_OK)
1726 IStream_Release(stm);
1727
1728 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1729 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1730 if (r == S_OK)
1731 IStorage_Release(stg2);
1732
1733 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1734 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1735
1736 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1737 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1738 if (r == S_OK)
1739 IStream_Release(stm);
1740
1741 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1742 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1743 if (r == S_OK)
1744 {
1745 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1746 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1747 if (r == S_OK)
1748 IStorage_Release(stg3);
1749
1750 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1751 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1752 if (r == S_OK)
1753 IStorage_Release(stg3);
1754
1755 IStorage_Release(stg2);
1756 }
1757
1758 IStorage_Release(stg);
1759
1761 ok(ret, "deleted file\n");
1762
1763 /* Revert only invalidates objects in transacted mode */
1765 STGM_READWRITE, 0, &stg);
1766 ok(r==S_OK, "StgCreateDocfile failed\n");
1767
1768 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1769 ok(r==S_OK, "IStorage->CreateStream failed\n");
1770
1771 r = IStorage_Revert(stg);
1772 ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1773
1774 r = IStream_Write(stm, "this works\n", 11, NULL);
1775 ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1776
1777 IStream_Release(stm);
1778 IStorage_Release(stg);
1779
1781 ok(ret, "deleted file\n");
1782}
1783
1784static void test_parent_free(void)
1785{
1786 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1787 HRESULT r;
1788 IStream *stm = NULL;
1789 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1790 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1791 ULONG ref;
1792 STATSTG statstg;
1793 BOOL ret;
1794
1796
1797 /* create the file */
1800 ok(r==S_OK, "StgCreateDocfile failed\n");
1801
1802 /* create a new storage */
1803 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1804 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1805
1806 if (r == S_OK)
1807 {
1808 /* now create a stream inside the new storage */
1809 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1810 ok(r==S_OK, "IStorage->CreateStream failed\n");
1811
1812 if (r == S_OK)
1813 {
1814 /* create a storage inside the new storage */
1815 r = IStorage_CreateStorage(stg2, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg3 );
1816 ok(r==S_OK, "IStorage->CreateStorage failed\n");
1817 }
1818
1819 /* free the parent */
1820 ref = IStorage_Release(stg2);
1821 ok(ref == 0, "IStorage still has %u references\n", ref);
1822
1823 /* child objects are invalid */
1824 if (r == S_OK)
1825 {
1826 r = IStream_Write(stm, "this should fail\n", 17, NULL);
1827 ok(r==STG_E_REVERTED, "IStream->Write should fail, hr=%x\n", r);
1828
1829 IStream_Release(stm);
1830
1831 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1832 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1833
1834 r = IStorage_SetStateBits(stg3, 1, 1);
1835 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1836
1837 IStorage_Release(stg3);
1838 }
1839 }
1840
1841 IStorage_Release(stg);
1842
1844 ok(ret, "deleted file\n");
1845}
1846
1848{
1849 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1850 HRESULT r;
1851 IStream *stm = NULL;
1852 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1853 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1854 static const WCHAR stmname2[] = { 'F','O','O',0 };
1855 BOOL ret;
1856
1858
1859 /* create a transacted file */
1862 ok(r==S_OK, "StgCreateDocfile failed\n");
1863
1864 /* create a transacted substorage */
1865 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1866 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1867
1868 if (r == S_OK)
1869 {
1870 /* create and commit stmname */
1871 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1872 ok(r==S_OK, "IStorage->CreateStream failed\n");
1873 if (r == S_OK)
1874 IStream_Release(stm);
1875
1876 IStorage_Commit(stg2, 0);
1877
1878 /* create and revert stmname2 */
1879 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1880 ok(r==S_OK, "IStorage->CreateStream failed\n");
1881 if (r == S_OK)
1882 IStream_Release(stm);
1883
1884 IStorage_Revert(stg2);
1885
1886 /* check that Commit and Revert really worked */
1887 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1888 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1889 if (r == S_OK)
1890 IStream_Release(stm);
1891
1892 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1893 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1894 if (r == S_OK)
1895 IStream_Release(stm);
1896
1897 IStorage_Release(stg2);
1898 }
1899
1900 /* create a read-only transacted substorage */
1901 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2);
1902 ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r);
1903
1904 if (r == S_OK)
1905 {
1906 /* The storage can be modified. */
1907 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1908 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1909 if (r == S_OK)
1910 IStorage_Release(stg3);
1911
1912 /* But changes cannot be committed. */
1913 r = IStorage_Commit(stg2, 0);
1914 ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r);
1915
1916 IStorage_Release(stg2);
1917 }
1918
1919 IStorage_Release(stg);
1920
1921 /* create a non-transacted file */
1923 STGM_READWRITE, 0, &stg);
1924 ok(r==S_OK, "StgCreateDocfile failed\n");
1925
1926 /* create a transacted substorage */
1927 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1928 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1929
1930 if (r == S_OK)
1931 {
1932 /* create and commit stmname */
1933 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1934 ok(r==S_OK, "IStorage->CreateStream failed\n");
1935 if (r == S_OK)
1936 IStream_Release(stm);
1937
1938 IStorage_Commit(stg2, 0);
1939
1940 /* create and revert stmname2 */
1941 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1942 ok(r==S_OK, "IStorage->CreateStream failed\n");
1943 if (r == S_OK)
1944 IStream_Release(stm);
1945
1946 IStorage_Revert(stg2);
1947
1948 /* check that Commit and Revert really worked */
1949 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1950 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1951 if (r == S_OK)
1952 IStream_Release(stm);
1953
1954 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1955 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1956 if (r == S_OK)
1957 IStream_Release(stm);
1958
1959 IStorage_Release(stg2);
1960 }
1961
1962 IStorage_Release(stg);
1963
1965 ok(ret, "deleted file\n");
1966}
1967
1968static void test_ReadClassStm(void)
1969{
1970 CLSID clsid, clsid2;
1971 HRESULT hr;
1972 IStream *pStream;
1973 static const LARGE_INTEGER llZero;
1974
1976 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1977
1978 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1979 ok_ole_success(hr, "CreateStreamOnHGlobal");
1980 hr = WriteClassStm(pStream, &test_stg_cls);
1981 ok_ole_success(hr, "WriteClassStm");
1982
1983 hr = ReadClassStm(pStream, NULL);
1984 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1985
1986 memset(&clsid, 0xcc, sizeof(clsid));
1987 memset(&clsid2, 0xcc, sizeof(clsid2));
1989 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1990 ok(IsEqualCLSID(&clsid, &clsid2), "got wrong clsid\n");
1991
1992 /* test not rewound stream */
1993 hr = ReadClassStm(pStream, &clsid);
1994 ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1995 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1996
1997 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1998 ok_ole_success(hr, "IStream_Seek");
1999 hr = ReadClassStm(pStream, &clsid);
2000 ok_ole_success(hr, "ReadClassStm");
2001 ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
2002
2003 IStream_Release(pStream);
2004}
2005
2006struct access_res
2007{
2009 DWORD lasterr;
2010 BOOL ignore;
2011};
2012
2013static const struct access_res create[16] =
2014{
2015 { TRUE, ERROR_SUCCESS, TRUE },
2016 { TRUE, ERROR_SUCCESS, TRUE },
2017 { TRUE, ERROR_SUCCESS, FALSE },
2018 { TRUE, ERROR_SUCCESS, FALSE },
2022 { TRUE, ERROR_SUCCESS, FALSE },
2026 { TRUE, ERROR_SUCCESS, TRUE },
2030 { TRUE, ERROR_SUCCESS, TRUE }
2031};
2032
2033static const struct access_res create_commit[16] =
2034{
2035 { TRUE, ERROR_SUCCESS, TRUE },
2036 { TRUE, ERROR_SUCCESS, TRUE },
2037 { TRUE, ERROR_SUCCESS, FALSE },
2038 { TRUE, ERROR_SUCCESS, FALSE },
2042 { TRUE, ERROR_SUCCESS, FALSE },
2046 { TRUE, ERROR_SUCCESS, TRUE },
2050 { TRUE, ERROR_SUCCESS, TRUE }
2051};
2052
2053static const struct access_res create_close[16] =
2054{
2055 { TRUE, ERROR_SUCCESS, FALSE },
2056 { TRUE, ERROR_SUCCESS, FALSE },
2057 { TRUE, ERROR_SUCCESS, FALSE },
2058 { TRUE, ERROR_SUCCESS, FALSE },
2059 { TRUE, ERROR_SUCCESS, FALSE },
2060 { TRUE, ERROR_SUCCESS, FALSE },
2061 { TRUE, ERROR_SUCCESS, FALSE },
2062 { TRUE, ERROR_SUCCESS, FALSE },
2063 { TRUE, ERROR_SUCCESS, FALSE },
2064 { TRUE, ERROR_SUCCESS, FALSE },
2065 { TRUE, ERROR_SUCCESS, FALSE },
2066 { TRUE, ERROR_SUCCESS, FALSE },
2067 { TRUE, ERROR_SUCCESS, FALSE },
2068 { TRUE, ERROR_SUCCESS, FALSE },
2069 { TRUE, ERROR_SUCCESS, FALSE },
2070 { TRUE, ERROR_SUCCESS }
2071};
2072
2073static const DWORD access_modes[4] = {
2074 0,
2078};
2079
2080static const DWORD share_modes[4] = {
2081 0,
2085};
2086
2087static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
2088{
2089 int i, j, idx = 0;
2090
2091 for (i = 0; i < ARRAY_SIZE(access_modes); i++)
2092 {
2093 for (j = 0; j < ARRAY_SIZE(share_modes); j++)
2094 {
2095 DWORD lasterr;
2096 HANDLE hfile;
2097
2098 if (ares[idx].ignore)
2099 continue;
2100
2101 SetLastError(0xdeadbeef);
2105
2106 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
2107 "(%d, handle, %d): Expected %d, got %d\n",
2108 line, idx, ares[idx].gothandle,
2109 (hfile != INVALID_HANDLE_VALUE));
2110
2111 ok(lasterr == ares[idx].lasterr ||
2112 broken(lasterr == 0xdeadbeef) /* win9x */,
2113 "(%d, lasterr, %d): Expected %d, got %d\n",
2114 line, idx, ares[idx].lasterr, lasterr);
2115
2116 CloseHandle(hfile);
2117 idx++;
2118 }
2119 }
2120}
2121
2122#define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
2123
2124static void test_access(void)
2125{
2126 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
2127 static const char fileA[] = "winetest";
2128 IStorage *stg;
2129 HRESULT hr;
2130
2131 /* STGM_TRANSACTED */
2134 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2135
2136 test_file_access(fileA, create);
2137
2138 hr = IStorage_Commit(stg, STGC_DEFAULT);
2139 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2140
2142
2143 IStorage_Release(stg);
2144
2146
2147 DeleteFileA(fileA);
2148
2149 /* STGM_DIRECT */
2152 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2153
2154 test_file_access(fileA, create);
2155
2156 hr = IStorage_Commit(stg, STGC_DEFAULT);
2157 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2158
2160
2161 IStorage_Release(stg);
2162
2164
2165 DeleteFileA(fileA);
2166
2167 /* STGM_SHARE_DENY_NONE */
2170 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2171
2172 test_file_access(fileA, create);
2173
2174 hr = IStorage_Commit(stg, STGC_DEFAULT);
2175 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2176
2178
2179 IStorage_Release(stg);
2180
2182
2183 DeleteFileA(fileA);
2184
2185 /* STGM_SHARE_DENY_READ */
2188 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2189
2190 test_file_access(fileA, create);
2191
2192 hr = IStorage_Commit(stg, STGC_DEFAULT);
2193 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2194
2196
2197 IStorage_Release(stg);
2198
2200
2201 DeleteFileA(fileA);
2202
2203 /* STGM_SHARE_DENY_WRITE */
2206 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2207
2208 test_file_access(fileA, create);
2209
2210 hr = IStorage_Commit(stg, STGC_DEFAULT);
2211 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
2212
2214
2215 IStorage_Release(stg);
2216
2218
2219 DeleteFileA(fileA);
2220
2221 /* STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE - reader mode for direct SWMR mode */
2223 ok(hr == S_OK, "got %08x\n", hr);
2224 IStorage_Release(stg);
2225
2227 ok(hr == S_OK || broken(hr == STG_E_INVALIDFLAG), "got %08x\n", hr);
2228 if(hr != S_OK)
2229 return;
2230
2231 test_file_access(fileA, create);
2232
2233 IStorage_Release(stg);
2235
2236 DeleteFileA(fileA);
2237}
2238
2239static void test_readonly(void)
2240{
2241 IStorage *stg, *stg2, *stg3;
2242 IStream *stream;
2243 HRESULT hr;
2244 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
2245 static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
2246 static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
2247
2249 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2250 if (SUCCEEDED(hr))
2251 {
2252 hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
2253 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2254 if (SUCCEEDED(hr))
2255 {
2256 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
2257 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2258 if (SUCCEEDED(hr))
2259 IStream_Release(stream);
2260 IStorage_Release(stg2);
2261 }
2262 IStorage_Release(stg);
2263 }
2264
2265 /* re-open read only */
2267 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2268 if (SUCCEEDED(hr))
2269 {
2270 hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
2271 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2272 if (SUCCEEDED(hr))
2273 {
2274 /* CreateStream on read-only storage, name exists */
2275 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
2276 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2277 if (SUCCEEDED(hr))
2278 IStream_Release(stream);
2279
2280 /* CreateStream on read-only storage, name does not exist */
2281 hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
2282 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2283 if (SUCCEEDED(hr))
2284 IStream_Release(stream);
2285
2286 /* CreateStorage on read-only storage, name exists */
2287 hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
2288 ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
2289 if (SUCCEEDED(hr))
2290 IStorage_Release(stg3);
2291
2292 /* CreateStorage on read-only storage, name does not exist */
2293 hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
2294 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2295 if (SUCCEEDED(hr))
2296 IStorage_Release(stg3);
2297
2298 /* DestroyElement on read-only storage, name exists */
2299 hr = IStorage_DestroyElement( stg2, streamW );
2300 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2301
2302 /* DestroyElement on read-only storage, name does not exist */
2303 hr = IStorage_DestroyElement( stg2, storageW );
2304 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2305
2306 IStorage_Release(stg2);
2307 }
2308
2309 IStorage_Release(stg);
2310 }
2311
2312 DeleteFileA("winetest");
2313}
2314
2315static void test_simple(void)
2316{
2317 /* Tests for STGM_SIMPLE mode */
2318
2319 IStorage *stg, *stg2;
2320 HRESULT r;
2321 IStream *stm;
2322 static const WCHAR stgname[] = { 'S','t','g',0 };
2323 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2324 static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
2326 ULARGE_INTEGER upos;
2327 DWORD count;
2328 STATSTG stat;
2329
2331
2333 ok(r == S_OK, "got %08x\n", r);
2334
2335 r = IStorage_CreateStorage(stg, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2);
2336 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2337 if (SUCCEEDED(r)) IStorage_Release(stg2);
2338
2339 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2340 ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
2341 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2342 ok(r == S_OK, "got %08x\n", r);
2343
2344 upos.QuadPart = 6000;
2345 r = IStream_SetSize(stm, upos);
2346 ok(r == S_OK, "got %08x\n", r);
2347
2348 r = IStream_Write(stm, "foo", 3, &count);
2349 ok(r == S_OK, "got %08x\n", r);
2350 ok(count == 3, "got %d\n", count);
2351
2352 pos.QuadPart = 0;
2353 r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
2354 ok(r == S_OK, "got %08x\n", r);
2355 ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
2356
2357 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2358 ok(r == S_OK ||
2359 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2360 "got %08x\n", r);
2361 if (r == S_OK)
2362 ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
2363
2364 pos.QuadPart = 1;
2365 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
2366 ok(r == S_OK, "got %08x\n", r);
2367 ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
2368
2369 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2370 ok(r == S_OK ||
2371 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2372 "got %08x\n", r);
2373 if (r == S_OK)
2374 ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
2375
2376 IStream_Release(stm);
2377
2378 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2379 ok(r == S_OK, "got %08x\n", r);
2380
2381 upos.QuadPart = 100;
2382 r = IStream_SetSize(stm, upos);
2383 ok(r == S_OK, "got %08x\n", r);
2384
2385 r = IStream_Write(stm, "foo", 3, &count);
2386 ok(r == S_OK, "got %08x\n", r);
2387 ok(count == 3, "got %d\n", count);
2388
2389 IStream_Release(stm);
2390
2391 IStorage_Commit(stg, STGC_DEFAULT);
2392 IStorage_Release(stg);
2393
2395 if (r == STG_E_INVALIDFLAG)
2396 {
2397 win_skip("Flag combination is not supported on NT4 and below\n");
2399 return;
2400 }
2401 ok(r == S_OK, "got %08x\n", r);
2402
2403 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg2);
2404 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2405 if (SUCCEEDED(r)) IStorage_Release(stg2);
2406
2407 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2408 ok(r == S_OK, "got %08x\n", r);
2409
2410 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2411 ok(r == S_OK, "got %08x\n", r);
2412 ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
2413
2414 IStream_Release(stm);
2415
2416 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2417 ok(r == S_OK, "got %08x\n", r);
2418
2419 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2420 ok(r == S_OK, "got %08x\n", r);
2421 ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
2422
2423 IStream_Release(stm);
2424
2425
2426 IStorage_Release(stg);
2427
2429}
2430
2431static void test_fmtusertypestg(void)
2432{
2433 IStorage *stg;
2435 HRESULT hr;
2436 static const char fileA[] = {'f','m','t','t','e','s','t',0};
2437 static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0};
2438 static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0};
2439 static const WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0};
2440 static const STATSTG statstg_null;
2441
2443 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2444
2445 if (SUCCEEDED(hr))
2446 {
2447 /* try to write the stream */
2448 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2449 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2450
2451 /* check that the stream was created */
2452 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2453 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2454 if (SUCCEEDED(hr))
2455 {
2456 BOOL found = FALSE;
2457 STATSTG statstg;
2458 DWORD got;
2459 memset(&statstg, 0xad, sizeof(statstg));
2460 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2461 {
2462 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2463 found = TRUE;
2464 else
2465 ok(0, "found unexpected stream or storage\n");
2466 CoTaskMemFree(statstg.pwcsName);
2467 }
2468 ok(memcmp(&statstg, &statstg_null, sizeof(statstg)) == 0, "statstg is not zeroed\n");
2469 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2470 IEnumSTATSTG_Release(stat);
2471 }
2472
2473 /* re-write the stream */
2474 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2475 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2476
2477 /* check that the stream is still there */
2478 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2479 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2480 if (SUCCEEDED(hr))
2481 {
2482 BOOL found = FALSE;
2483 STATSTG statstg;
2484 DWORD got;
2485 memset(&statstg, 0xad, sizeof(statstg));
2486 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2487 {
2488 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2489 found = TRUE;
2490 else
2491 ok(0, "found unexpected stream or storage\n");
2492 CoTaskMemFree(statstg.pwcsName);
2493 }
2494 ok(memcmp(&statstg, &statstg_null, sizeof(statstg)) == 0, "statstg is not zeroed\n");
2495 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2496 IEnumSTATSTG_Release(stat);
2497 }
2498
2499 IStorage_Release(stg);
2500 DeleteFileA( fileA );
2501 }
2502}
2503
2504static void test_references(void)
2505{
2506 IStorage *stg,*stg2;
2507 HRESULT hr;
2508 unsigned c1,c2;
2509 static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
2510
2512
2514 ok(hr==S_OK, "StgCreateDocfile failed\n");
2515
2516 if (SUCCEEDED(hr))
2517 {
2518 IStorage_Release(stg);
2519
2521 ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr);
2522
2523 if (SUCCEEDED(hr))
2524 {
2525 hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2);
2526 ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr);
2527
2528 if (SUCCEEDED(hr))
2529 {
2530 c1 = IStorage_AddRef(stg);
2531 ok(c1 == 2, "creating internal storage added references to ancestor\n");
2532 c1 = IStorage_AddRef(stg);
2533 IStorage_Release(stg2);
2534 c2 = IStorage_AddRef(stg) - 1;
2535 ok(c1 == c2, "releasing internal storage removed references to ancestor\n");
2536 }
2537 c1 = IStorage_Release(stg);
2538 while ( c1 ) c1 = IStorage_Release(stg);
2539 }
2540 }
2541
2543}
2544
2545/* dest
2546 * |-StorageA
2547 * | `StreamA: "StreamA"
2548 * |-StorageB
2549 * | `StreamB: "StreamB"
2550 * `StreamC: "StreamC"
2551 */
2553{
2554 IStorage *stgA = NULL, *stgB = NULL;
2555 IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
2556 const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
2557 const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
2558 const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
2559 ULONG bytes;
2560 HRESULT hr;
2561
2562 hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
2563 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2564 if(FAILED(hr))
2565 goto cleanup;
2566
2567 hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
2568 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2569 if(FAILED(hr))
2570 goto cleanup;
2571
2572 hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
2573 ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
2574
2575 hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
2576 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2577 if(FAILED(hr))
2578 goto cleanup;
2579
2580 hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
2581 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2582 if(FAILED(hr))
2583 goto cleanup;
2584
2585 hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
2586 ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
2587
2588 hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
2589 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2590 if(FAILED(hr))
2591 goto cleanup;
2592
2593 hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
2594 ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
2595
2596cleanup:
2597 if(strmC)
2598 IStream_Release(strmC);
2599 if(strmB)
2600 IStream_Release(strmB);
2601 if(stgB)
2602 IStorage_Release(stgB);
2603 if(strmA)
2604 IStream_Release(strmA);
2605 if(stgA)
2606 IStorage_Release(stgA);
2607
2608 return hr;
2609}
2610
2611static void test_copyto(void)
2612{
2613 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2614 IStream *strm_tmp;
2615 WCHAR buf[64];
2616 HRESULT hr;
2617
2618 /* create & populate file1 */
2620 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2621 if(FAILED(hr))
2622 goto cleanup;
2623
2624 hr = create_test_file(file1);
2625 if(FAILED(hr))
2626 goto cleanup;
2627
2628 /* create file2 */
2630 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2631 if(FAILED(hr))
2632 goto cleanup;
2633
2634 /* copy file1 into file2 */
2635 hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2636 ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2637
2638 hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2639 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2640 if(FAILED(hr))
2641 goto cleanup;
2642
2643 /* verify that all of file1 was copied */
2644 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2645 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2646 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2647
2648 if(SUCCEEDED(hr)){
2649 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2650 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2651 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2652
2653 if(SUCCEEDED(hr)){
2654 memset(buf, 0, sizeof(buf));
2655 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2656 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2657 if(SUCCEEDED(hr))
2658 ok(strcmp_ww(buf, strmA_name) == 0,
2659 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2660
2661 IStream_Release(strm_tmp);
2662 }
2663
2664 IStorage_Release(stg_tmp);
2665 }
2666
2667 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2668 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2669 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2670
2671 if(SUCCEEDED(hr)){
2672 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2673 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2674 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2675
2676 if(SUCCEEDED(hr)){
2677 memset(buf, 0, sizeof(buf));
2678 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2679 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2680 if(SUCCEEDED(hr))
2681 ok(strcmp_ww(buf, strmB_name) == 0,
2682 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2683
2684 IStream_Release(strm_tmp);
2685 }
2686
2687 IStorage_Release(stg_tmp);
2688 }
2689
2690 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2691 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2692 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2693
2694 if(SUCCEEDED(hr)){
2695 memset(buf, 0, sizeof(buf));
2696 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2697 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2698 if(SUCCEEDED(hr))
2699 ok(strcmp_ww(buf, strmC_name) == 0,
2700 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2701
2702 IStream_Release(strm_tmp);
2703 }
2704
2705cleanup:
2706 if(file1)
2707 IStorage_Release(file1);
2708 if(file2)
2709 IStorage_Release(file2);
2710
2713}
2714
2716{
2717 static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2718
2719 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2720 IStream *strm_tmp;
2721 WCHAR buf[64];
2722 HRESULT hr;
2723
2724 /* create & populate file1 */
2726 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2727 if(FAILED(hr))
2728 goto cleanup;
2729
2730 hr = create_test_file(file1);
2731 if(FAILED(hr))
2732 goto cleanup;
2733
2734 /* create file2 */
2736 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2737 if(FAILED(hr))
2738 goto cleanup;
2739
2740 /* copy file1 to file2 with name exclusions */
2741 hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2742 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2743 if(FAILED(hr))
2744 goto cleanup;
2745
2746 /* verify that file1 copied over, respecting exclusions */
2747 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2748 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2749 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2750 if(SUCCEEDED(hr))
2751 IStorage_Release(stg_tmp);
2752
2753 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2754 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2755 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2756 if(SUCCEEDED(hr))
2757 IStream_Release(strm_tmp);
2758
2759 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2760 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2761 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2762
2763 if(SUCCEEDED(hr)){
2764 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2765 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2766 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2767
2768 if(SUCCEEDED(hr)){
2769 memset(buf, 0, sizeof(buf));
2770 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2771 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2772 if(SUCCEEDED(hr))
2773 ok(strcmp_ww(buf, strmB_name) == 0,
2774 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2775
2776 IStream_Release(strm_tmp);
2777 }
2778
2779 IStorage_Release(stg_tmp);
2780 }
2781
2782 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2783 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2784 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2785 if(SUCCEEDED(hr))
2786 IStream_Release(strm_tmp);
2787
2788cleanup:
2789 if(file1)
2790 IStorage_Release(file1);
2791 if(file2)
2792 IStorage_Release(file2);
2793
2796}
2797
2799{
2800 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2801 IStream *strm_tmp;
2802 WCHAR buf[64];
2803 HRESULT hr;
2804
2805 /* create & populate file1 */
2807 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2808 if(FAILED(hr))
2809 goto cleanup;
2810
2811 hr = create_test_file(file1);
2812 if(FAILED(hr))
2813 goto cleanup;
2814
2815 /* create file2 */
2817 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2818 if(FAILED(hr))
2819 goto cleanup;
2820
2821 /* copy file1 to file2 with iid exclusions */
2822 hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2823 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2824 if(FAILED(hr))
2825 goto cleanup;
2826
2827 /* verify that file1 copied over, respecting exclusions */
2828 hr = IStorage_OpenStorage(file2, stgA_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);
2831 if(SUCCEEDED(hr))
2832 IStorage_Release(stg_tmp);
2833
2834 hr = IStorage_OpenStream(file2, strmA_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);
2837 if(SUCCEEDED(hr))
2838 IStream_Release(strm_tmp);
2839
2840 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2841 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2842 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2843 if(SUCCEEDED(hr))
2844 IStorage_Release(stg_tmp);
2845
2846 hr = IStorage_OpenStream(file2, strmB_name, NULL,
2847 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2848 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2849 if(SUCCEEDED(hr))
2850 IStream_Release(strm_tmp);
2851
2852 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2853 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2854 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2855
2856 if(SUCCEEDED(hr)){
2857 memset(buf, 0, sizeof(buf));
2858 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2859 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2860 if(SUCCEEDED(hr))
2861 ok(strcmp_ww(buf, strmC_name) == 0,
2862 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2863
2864 IStream_Release(strm_tmp);
2865 }
2866
2867cleanup:
2868 if(file1)
2869 IStorage_Release(file1);
2870 if(file2)
2871 IStorage_Release(file2);
2872
2875}
2876
2878{
2879 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2880 IStream *strm_tmp;
2881 HRESULT hr;
2882
2883 /* create & populate file1 */
2885 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2886 if(FAILED(hr))
2887 goto cleanup;
2888
2889 hr = create_test_file(file1);
2890 if(FAILED(hr))
2891 goto cleanup;
2892
2893 /* create file2 */
2895 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2896 if(FAILED(hr))
2897 goto cleanup;
2898
2899 /* copy file1 to file2 with iid exclusions */
2900 hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2901 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2902 if(FAILED(hr))
2903 goto cleanup;
2904
2905 /* verify that file1 copied over, respecting exclusions */
2906 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2907 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2908 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2909
2910 if(SUCCEEDED(hr)){
2911 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2912 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2913 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2914 if(SUCCEEDED(hr))
2915 IStream_Release(strm_tmp);
2916
2917 IStorage_Release(stg_tmp);
2918 }
2919
2920 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2921 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2922 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2923
2924 if(SUCCEEDED(hr)){
2925 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2926 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2927 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2928 if(SUCCEEDED(hr))
2929 IStream_Release(strm_tmp);
2930
2931 IStorage_Release(stg_tmp);
2932 }
2933
2934 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2935 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2936 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2937 if(SUCCEEDED(hr))
2938 IStream_Release(strm_tmp);
2939
2940cleanup:
2941 if(file1)
2942 IStorage_Release(file1);
2943 if(file2)
2944 IStorage_Release(file2);
2945
2948}
2949
2950static void test_rename(void)
2951{
2952 IStorage *stg, *stg2;
2953 IStream *stm;
2954 HRESULT r;
2955 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2956 static const WCHAR stgname2[] = { 'S','T','G',0 };
2957 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2958 static const WCHAR stmname2[] = { 'E','N','T','S',0 };
2959 BOOL ret;
2960
2962
2963 /* create the file */
2965 STGM_READWRITE, 0, &stg);
2966 ok(r==S_OK, "StgCreateDocfile failed\n");
2967
2968 /* create a substorage */
2969 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2970 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2971
2972 /* create a stream in the substorage */
2973 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2974 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2975 IStream_Release(stm);
2976
2977 /* rename the stream */
2978 r = IStorage_RenameElement(stg2, stmname, stmname2);
2979 ok(r==S_OK, "IStorage->RenameElement failed, hr=%08x\n", r);
2980
2981 /* cannot open stream with old name */
2982 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2983 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2984 if (SUCCEEDED(r)) IStream_Release(stm);
2985
2986 /* can open stream with new name */
2987 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2988 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2989 if (SUCCEEDED(r)) IStream_Release(stm);
2990
2991 IStorage_Release(stg2);
2992
2993 /* rename the storage */
2994 IStorage_RenameElement(stg, stgname, stgname2);
2995
2996 /* cannot open storage with old name */
2997 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2998 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2999 if (SUCCEEDED(r)) IStorage_Release(stg2);
3000
3001 /* can open storage with new name */
3002 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
3003 ok(r==S_OK, "IStorage_OpenStream should fail, hr=%08x\n", r);
3004 if (SUCCEEDED(r))
3005 {
3006 /* opened storage still has the stream */
3007 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
3008 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
3009 if (SUCCEEDED(r)) IStream_Release(stm);
3010
3011 IStorage_Release(stg2);
3012 }
3013
3014 IStorage_Release(stg);
3015
3017 ok(ret, "deleted file\n");
3018}
3019
3020static void test_toplevel_stat(void)
3021{
3022 IStorage *stg = NULL;
3023 HRESULT r;
3024 STATSTG stat;
3025 char prev_dir[MAX_PATH];
3026 char temp[MAX_PATH];
3027 char full_path[MAX_PATH];
3028 LPSTR rel_pathA;
3029 WCHAR rel_path[MAX_PATH];
3030
3032
3035 ok(r==S_OK, "StgCreateDocfile failed\n");
3036
3037 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
3038 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
3039 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
3041 CoTaskMemFree(stat.pwcsName);
3042
3043 IStorage_Release( stg );
3044
3046 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
3047
3048 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
3049 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
3050 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
3052 CoTaskMemFree(stat.pwcsName);
3053
3054 IStorage_Release( stg );
3055
3057
3058 /* Stat always returns the full path, even for files opened with a relative path. */
3059 GetCurrentDirectoryA(MAX_PATH, prev_dir);
3060
3062
3064
3065 GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA);
3066 MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH);
3067
3070 ok(r==S_OK, "StgCreateDocfile failed\n");
3071
3072 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
3073 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
3074 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
3076 CoTaskMemFree(stat.pwcsName);
3077
3078 IStorage_Release( stg );
3079
3081 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
3082
3083 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
3084 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
3085 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
3087 CoTaskMemFree(stat.pwcsName);
3088
3089 IStorage_Release( stg );
3090
3091 SetCurrentDirectoryA(prev_dir);
3092
3094}
3095
3096static void test_substorage_enum(void)
3097{
3098 IStorage *stg, *stg2;
3099 IEnumSTATSTG *ee;
3100 HRESULT r;
3101 ULONG ref;
3102 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
3103 BOOL ret;
3104
3106
3107 /* create the file */
3109 STGM_READWRITE, 0, &stg);
3110 ok(r==S_OK, "StgCreateDocfile failed\n");
3111
3112 /* create a substorage */
3113 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
3114 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3115
3116 /* create an enumelements */
3117 r = IStorage_EnumElements(stg2, 0, NULL, 0, &ee);
3118 ok(r==S_OK, "IStorage->EnumElements failed, hr=%08x\n", r);
3119
3120 /* release the substorage */
3121 ref = IStorage_Release(stg2);
3122 todo_wine ok(ref==0, "storage not released\n");
3123
3124 /* reopening fails, because the substorage is really still open */
3125 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
3126 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage failed, hr=%08x\n", r);
3127
3128 /* destroying the storage invalidates the enumerator */
3129 r = IStorage_DestroyElement(stg, stgname);
3130 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3131
3132 r = IEnumSTATSTG_Reset(ee);
3133 ok(r==STG_E_REVERTED, "IEnumSTATSTG->Reset failed, hr=%08x\n", r);
3134
3135 IEnumSTATSTG_Release(ee);
3136
3137 IStorage_Release(stg);
3138
3140 ok(ret, "deleted file\n");
3141}
3142
3143static void test_copyto_locking(void)
3144{
3145 IStorage *stg, *stg2, *stg3, *stg4;
3146 IStream *stm;
3147 HRESULT r;
3148 static const WCHAR stgname[] = { 'S','T','G','1',0 };
3149 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
3150 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
3151 BOOL ret;
3152
3154
3155 /* create the file */
3157 STGM_READWRITE, 0, &stg);
3158 ok(r==S_OK, "StgCreateDocfile failed\n");
3159
3160 /* create a substorage */
3161 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
3162 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3163
3164 /* create another substorage */
3165 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
3166 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3167
3168 /* add a stream, and leave it open */
3169 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
3170 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
3171
3172 /* Try to copy the storage while the stream is open */
3173 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
3174 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
3175
3176 IStream_Release(stm);
3177
3178 /* create a substorage */
3179 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg4);
3180 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3181
3182 /* Try to copy the storage while the substorage is open */
3183 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
3184 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
3185
3186 IStorage_Release(stg4);
3187 IStorage_Release(stg3);
3188 IStorage_Release(stg2);
3189 IStorage_Release(stg);
3190
3192 ok(ret, "deleted file\n");
3193}
3194
3195static void test_copyto_recursive(void)
3196{
3197 IStorage *stg, *stg2, *stg3, *stg4;
3198 HRESULT r;
3199 static const WCHAR stgname[] = { 'S','T','G','1',0 };
3200 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
3201 BOOL ret;
3202
3204
3205 /* create the file */
3207 STGM_READWRITE, 0, &stg);
3208 ok(r==S_OK, "StgCreateDocfile failed\n");
3209
3210 /* create a substorage */
3211 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
3212 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3213
3214 /* copy the parent to the child */
3215 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
3216 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
3217
3218 /* create a transacted substorage */
3219 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg3);
3220 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3221
3222 /* copy the parent to the transacted child */
3223 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
3224 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
3225
3226 /* create a transacted subsubstorage */
3227 r = IStorage_CreateStorage(stg3, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg4);
3228 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3229
3230 /* copy the parent to the transacted child of the transacted child */
3231 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg4);
3232 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
3233
3234 /* copy the parent but exclude storage objects */
3235 r = IStorage_CopyTo(stg, 1, &IID_IStorage, NULL, stg4);
3236 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
3237
3238 IStorage_Release(stg4);
3239 IStorage_Release(stg3);
3240 IStorage_Release(stg2);
3241 IStorage_Release(stg);
3242
3244 ok(ret, "deleted file\n");
3245}
3246
3248{
3249 ILockBytes *ilb = NULL;
3250 IStorage *stg = NULL;
3251 HRESULT r;
3252 STATSTG stat;
3253 char junk[512];
3255
3257 ok(r == S_OK, "CreateILockBytesOnHGlobal failed, hr=%x\n", r);
3258
3259 offset.QuadPart = 0;
3260 memset(junk, 0xaa, 512);
3261 r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
3262 ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
3263
3264 offset.QuadPart = 2000;
3265 r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
3266 ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
3267
3269 ok(r == S_OK, "StgCreateDocfileOnILockBytes failed, hr=%x\n", r);
3270
3271 IStorage_Release(stg);
3272
3274 NULL, 0, &stg);
3275 ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
3276
3277 if (SUCCEEDED(r))
3278 {
3279 r = IStorage_Stat(stg, &stat, STATFLAG_NONAME);
3280 ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
3281 ok(IsEqualCLSID(&stat.clsid, &GUID_NULL), "unexpected CLSID value\n");
3282
3283 IStorage_Release(stg);
3284 }
3285
3286 r = ILockBytes_Stat(ilb, &stat, STATFLAG_NONAME);
3287 ok(r == S_OK, "ILockBytes_Stat failed, hr=%x\n", r);
3288 ok(stat.cbSize.u.LowPart < 2512, "expected truncated size, got %d\n", stat.cbSize.u.LowPart);
3289
3290 ILockBytes_Release(ilb);
3291}
3292
3293static void test_convert(void)
3294{
3295 static const WCHAR filename[] = {'s','t','o','r','a','g','e','.','s','t','g',0};
3296 IStorage *stg;
3297 HRESULT hr;
3298
3300 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3301
3303 ok(hr == S_OK, "StgCreateDocfile failed\n");
3304 hr = GetConvertStg(stg);
3305 ok(hr == STG_E_FILENOTFOUND, "got 0x%08x\n", hr);
3306 hr = SetConvertStg(stg, TRUE);
3307 ok(hr == S_OK, "got 0x%08x\n", hr);
3308 hr = SetConvertStg(stg, TRUE);
3309 ok(hr == S_OK, "got 0x%08x\n", hr);
3310 hr = GetConvertStg(stg);
3311 ok(hr == S_OK, "got 0x%08x\n", hr);
3312 hr = SetConvertStg(stg, FALSE);
3313 ok(hr == S_OK, "got 0x%08x\n", hr);
3314 hr = GetConvertStg(stg);
3315 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3316
3317 IStorage_Release(stg);
3318
3320}
3321
3322static void test_direct_swmr(void)
3323{
3324 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
3325 IDirectWriterLock *dwlock;
3326 ULONG ref, ref2;
3327 IStorage *stg;
3328 HRESULT hr;
3329
3330 /* it's possible to create in writer mode */
3333 ok(hr == S_OK, "got %08x\n", hr);
3334if (hr == S_OK) {
3335 IStorage_Release(stg);
3337}
3338
3340 ok(hr == S_OK, "got %08x\n", hr);
3341 IStorage_Release(stg);
3342
3343 /* reader mode */
3345 ok(hr == S_OK || broken(hr == STG_E_INVALIDFLAG), "got %08x\n", hr);
3346 if(hr == S_OK)
3347 {
3348 hr = IStorage_QueryInterface(stg, &IID_IDirectWriterLock, (void**)&dwlock);
3349 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
3350 IStorage_Release(stg);
3351 }
3352
3353 /* writer mode */
3355 ok(hr == S_OK, "got %08x\n", hr);
3356 if(hr == S_OK)
3357 {
3358 ref = IStorage_AddRef(stg);
3359 IStorage_Release(stg);
3360
3361 hr = IStorage_QueryInterface(stg, &IID_IDirectWriterLock, (void**)&dwlock);
3362 ok(hr == S_OK, "got %08x\n", hr);
3363
3364 ref2 = IStorage_AddRef(stg);
3365 IStorage_Release(stg);
3366 ok(ref2 == ref + 1, "got %u\n", ref2);
3367
3368 IDirectWriterLock_Release(dwlock);
3369 IStorage_Release(stg);
3370 }
3371
3373}
3374
3376{
3381 const int *locked_bytes;
3382 const int *fail_ranges;
3384};
3385
3386static const int priority_locked_bytes[] = { 0x158, 0x181, 0x193, -1 };
3387static const int rwex_locked_bytes[] = { 0x193, 0x1a7, 0x1bb, 0x1cf, -1 };
3388static const int rw_locked_bytes[] = { 0x193, 0x1a7, -1 };
3389static const int nosn_locked_bytes[] = { 0x16c, 0x193, 0x1a7, 0x1cf, -1 };
3390static const int rwdw_locked_bytes[] = { 0x193, 0x1a7, 0x1cf, -1 };
3391static const int wodw_locked_bytes[] = { 0x1a7, 0x1cf, -1 };
3392static const int tr_locked_bytes[] = { 0x193, -1 };
3393static const int no_locked_bytes[] = { -1 };
3394static const int roex_locked_bytes[] = { 0x193, 0x1bb, 0x1cf, -1 };
3395
3396static const int rwex_fail_ranges[] = { 0x193,0x1e3, -1 };
3397static const int rw_fail_ranges[] = { 0x1bb,0x1e3, -1 };
3398static const int rwdw_fail_ranges[] = { 0x1a7,0x1e3, -1 };
3399static const int dw_fail_ranges[] = { 0x1a7,0x1cf, -1 };
3400static const int tr_fail_ranges[] = { 0x1bb,0x1cf, -1 };
3401static const int pr_fail_ranges[] = { 0x180,0x181, 0x1bb,0x1cf, -1 };
3402static const int roex_fail_ranges[] = { 0x0,-1 };
3403
3404static const struct lock_test lock_tests[] = {
3420};
3421
3423{
3424 HANDLE hfile;
3425
3427
3428 if (hfile == INVALID_HANDLE_VALUE)
3429 return FALSE;
3430
3431 CloseHandle(hfile);
3432 return TRUE;
3433}
3434
3436 DWORD access, DWORD sharing, const char *desc, DWORD *open_mode, BOOL *any_failure)
3437{
3439 {
3440 *open_mode = access;
3441 if (!current->todo || (current->sharing & sharing))
3442 ok(current->sharing & sharing ||
3443 broken(!(current->sharing & sharing) && access == GENERIC_WRITE && (current->stg_mode & 0xf) != STGM_READ) /* win2k */,
3444 "file with mode %x should not be openable with %s permission\n", current->stg_mode, desc);
3445 else
3446 {
3447 todo_wine ok(current->sharing & sharing ||
3448 broken(!(current->sharing & sharing) && access == GENERIC_WRITE && (current->stg_mode & 0xf) != STGM_READ) /* win2k */,
3449 "file with mode %x should not be openable with %s permission\n", current->stg_mode, desc);
3450 *any_failure = TRUE;
3451 }
3452 }
3453 else
3454 {
3455 if (!current->todo || !(current->sharing & sharing))
3456 ok(!(current->sharing & sharing), "file with mode %x should be openable with %s permission\n", current->stg_mode, desc);
3457 else
3458 {
3459 todo_wine ok(!(current->sharing & sharing), "file with mode %x should be openable with %s permission\n", current->stg_mode, desc);
3460 *any_failure = TRUE;
3461 }
3462 }
3463}
3464
3465static void check_access(LPCWSTR filename, const struct lock_test *current,
3466 DWORD access, DWORD sharing, const char *desc, DWORD open_mode, BOOL *any_failure)
3467{
3469 {
3470 if (!current->todo || !(current->access & access))
3471 ok(!(current->access & access), "file with mode %x should not be openable without %s sharing\n", current->stg_mode, desc);
3472 else
3473 {
3474 todo_wine ok(!(current->access & access), "file with mode %x should not be openable without %s sharing\n", current->stg_mode, desc);
3475 *any_failure = TRUE;
3476 }
3477 }
3478 else
3479 {
3480 if (!current->todo || (current->access & access))
3481 ok(current->access & access, "file with mode %x should be openable without %s sharing\n", current->stg_mode, desc);
3482 else
3483 {
3484 todo_wine ok(current->access & access, "file with mode %x should be openable without %s sharing\n", current->stg_mode, desc);
3485 *any_failure = TRUE;
3486 }
3487 }
3488}
3489
3490static void test_locking(void)
3491{
3492 static const WCHAR filename[] = {'w','i','n','e','t','e','s','t',0};
3493 int i;
3494 IStorage *stg;
3495 HRESULT hr;
3496
3497 for (i = 0; i < ARRAY_SIZE(lock_tests); i++)
3498 {
3499 const struct lock_test *current = &lock_tests[i];
3500 BOOL any_failure = FALSE;
3501 DWORD open_mode = 0;
3502
3503 if (current->create)
3504 {
3505 hr = StgCreateDocfile(filename, current->stg_mode, 0, &stg);
3506 ok(SUCCEEDED(hr), "StgCreateDocfile with mode %x failed with hr %x\n", current->stg_mode, hr);
3507 if (FAILED(hr)) continue;
3508 }
3509 else
3510 {
3512 ok(SUCCEEDED(hr), "StgCreateDocfile failed with hr %x\n", hr);
3513 if (FAILED(hr)) continue;
3514 IStorage_Release(stg);
3515
3516 hr = StgOpenStorage(filename, NULL, current->stg_mode, NULL, 0, &stg);
3517 ok(SUCCEEDED(hr), "StgOpenStorage with mode %x failed with hr %x\n", current->stg_mode, hr);
3518 if (FAILED(hr))
3519 {
3521 continue;
3522 }
3523 }
3524
3525 check_sharing(filename, current, GENERIC_READ, FILE_SHARE_READ, "READ", &open_mode, &any_failure);
3526 check_sharing(filename, current, GENERIC_WRITE, FILE_SHARE_WRITE, "WRITE", &open_mode, &any_failure);
3527 check_sharing(filename, current, DELETE, FILE_SHARE_DELETE, "DELETE", &open_mode, &any_failure);
3528
3529 if (open_mode != 0)
3530 {
3531 HANDLE hfile;
3532 BOOL locked, expect_locked;
3533 OVERLAPPED ol;
3534 const int* next_lock = current->locked_bytes;
3535
3536 check_access(filename, current, GENERIC_READ, FILE_SHARE_READ, "READ", open_mode, &any_failure);
3537 check_access(filename, current, GENERIC_WRITE, FILE_SHARE_WRITE, "WRITE", open_mode, &any_failure);
3538 check_access(filename, current, DELETE, FILE_SHARE_DELETE, "DELETE", open_mode, &any_failure);
3539
3541 ok(hfile != INVALID_HANDLE_VALUE, "couldn't open file with mode %x\n", current->stg_mode);
3542
3543 ol.OffsetHigh = 0;
3544 ol.hEvent = NULL;
3545
3546 for (ol.Offset = 0x7ffffe00; ol.Offset != 0x80000000; ol.Offset++)
3547 {
3549 locked = FALSE;
3550 else
3551 {
3552 ok(!LockFileEx(hfile, LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &ol), "shared locks should not be used\n");
3553 locked = TRUE;
3554 }
3555
3556 UnlockFileEx(hfile, 0, 1, 0, &ol);
3557
3558 if ((ol.Offset&0x1ff) == *next_lock)
3559 {
3560 expect_locked = TRUE;
3561 next_lock++;
3562 }
3563 else
3564 expect_locked = FALSE;
3565
3566 if (!current->todo || locked == expect_locked)
3567 ok(locked == expect_locked, "byte %x of file with mode %x is %slocked but should %sbe\n",
3568 ol.Offset, current->stg_mode, locked?"":"not ", expect_locked?"":"not ");
3569 else
3570 {
3571 any_failure = TRUE;
3572 todo_wine ok(locked == expect_locked, "byte %x of file with mode %x is %slocked but should %sbe\n",
3573 ol.Offset, current->stg_mode, locked?"":"not ", expect_locked?"":"not ");
3574 }
3575 }
3576
3577 CloseHandle(hfile);
3578 }
3579
3580 IStorage_Release( stg );
3581
3582 if (!current->create)
3583 {
3584 HANDLE hfile;
3585 BOOL failed, expect_failed=FALSE;
3586 OVERLAPPED ol;
3587 const int* next_range = current->fail_ranges;
3588
3590 ok(hfile != INVALID_HANDLE_VALUE, "couldn't open file with mode %x\n", current->stg_mode);
3591
3592 ol.OffsetHigh = 0;
3593 ol.hEvent = NULL;
3594
3595 for (ol.Offset = 0x7ffffe00; ol.Offset != 0x80000000; ol.Offset++)
3596 {
3597 if (ol.Offset == 0x7fffff92 ||
3598 (ol.Offset == 0x7fffff80 && current->stg_mode == (STGM_TRANSACTED|STGM_READWRITE)) ||
3599 (ol.Offset == 0x7fffff80 && current->stg_mode == (STGM_TRANSACTED|STGM_READ)))
3600 continue; /* This makes opens hang */
3601
3602 if (ol.Offset < 0x7fffff00)
3603 LockFileEx(hfile, 0, 0, 1, 0, &ol);
3604 else
3605 LockFileEx(hfile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ol);
3606
3607 hr = StgOpenStorage(filename, NULL, current->stg_mode, NULL, 0, &stg);
3608 ok(hr == S_OK || hr == STG_E_LOCKVIOLATION || hr == STG_E_SHAREVIOLATION, "failed with unexpected hr %x\n", hr);
3609 if (SUCCEEDED(hr)) IStorage_Release(stg);
3610
3611 UnlockFileEx(hfile, 0, 1, 0, &ol);
3612
3613 failed = FAILED(hr);
3614
3615 if (!expect_failed && (ol.Offset&0x1ff) == next_range[0])
3616 {
3617 expect_failed = TRUE;
3618 }
3619 else if (expect_failed && (ol.Offset&0x1ff) == next_range[1])
3620 {
3621 expect_failed = FALSE;
3622 next_range += 2;
3623 }
3624
3625 if (!current->todo || failed == expect_failed)
3626 ok(failed == expect_failed, "open with byte %x locked, mode %x %s but should %s\n",
3627 ol.Offset, current->stg_mode, failed?"failed":"succeeded", expect_failed?"fail":"succeed");
3628 else
3629 {
3630 any_failure = TRUE;
3631 todo_wine ok(failed == expect_failed, "open with byte %x locked, mode %x %s but should %s\n",
3632 ol.Offset, current->stg_mode, failed?"failed":"succeeded", expect_failed?"fail":"succeed");
3633 }
3634 }
3635
3636 CloseHandle(hfile);
3637 }
3638
3640
3641 if (current->todo && !any_failure)
3642 todo_wine ok(1, "tests succeeded for mode %x\n", current->stg_mode);
3643 }
3644}
3645
3646static void test_transacted_shared(void)
3647{
3648 IStorage *stg = NULL;
3649 IStorage *stgrw = NULL;
3650 HRESULT r;
3651 IStream *stm = NULL;
3652 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
3654 ULARGE_INTEGER upos;
3655 char buffer[10];
3656 ULONG bytesread;
3657
3659
3660 /* create a new transacted storage with a stream */
3663 ok(r==S_OK, "StgCreateDocfile failed %x\n", r);
3664
3665 r = WriteClassStg(stg, &test_stg_cls);
3666 ok(r == S_OK, "WriteClassStg failed %x\n", r);
3667
3668 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
3669 ok(r==S_OK, "IStorage->CreateStream failed %x\n", r);
3670
3671 pos.QuadPart = 0;
3672 r = IStream_Seek(stm, pos, 0, &upos);
3673 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3674
3675 r = IStream_Write(stm, "aaa", 3, NULL);
3676 ok(r==S_OK, "IStream->Write failed %x\n", r);
3677
3678 r = IStorage_Commit(stg, STGC_ONLYIFCURRENT);
3679 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3680
3681 /* open a second transacted read/write storage */
3683 ok(r==S_OK, "StgOpenStorage failed %x\n", r);
3684
3685 /* update stream on the first storage and commit */
3686 pos.QuadPart = 0;
3687 r = IStream_Seek(stm, pos, 0, &upos);
3688 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3689
3690 r = IStream_Write(stm, "ccc", 3, NULL);
3691 ok(r==S_OK, "IStream->Write failed %x\n", r);
3692
3693 r = IStorage_Commit(stg, STGC_ONLYIFCURRENT);
3694 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3695
3696 /* update again without committing */
3697 pos.QuadPart = 0;
3698 r = IStream_Seek(stm, pos, 0, &upos);
3699 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3700
3701 r = IStream_Write(stm, "ddd", 3, NULL);
3702 ok(r==S_OK, "IStream->Write failed %x\n", r);
3703
3704 IStream_Release(stm);
3705
3706 /* we can still read the old content from the second storage */
3707 r = IStorage_OpenStream(stgrw, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
3708 ok(r==S_OK, "IStorage->OpenStream failed %x\n", r);
3709
3710 pos.QuadPart = 0;
3711 r = IStream_Seek(stm, pos, 0, &upos);
3712 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3713
3714 r = IStream_Read(stm, buffer, sizeof(buffer), &bytesread);
3715 ok(r==S_OK, "IStream->Read failed %x\n", r);
3716 ok(bytesread == 3, "read wrong number of bytes %i\n", bytesread);
3717 ok(memcmp(buffer, "aaa", 3) == 0, "wrong data\n");
3718
3719 /* and overwrite the data */
3720 pos.QuadPart = 0;
3721 r = IStream_Seek(stm, pos, 0, &upos);
3722 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3723
3724 r = IStream_Write(stm, "bbb", 3, NULL);
3725 ok(r==S_OK, "IStream->Write failed %x\n", r);
3726
3727 IStream_Release(stm);
3728
3729 /* commit fails because we're out of date */
3730 r = IStorage_Commit(stgrw, STGC_ONLYIFCURRENT);
3731 ok(r==STG_E_NOTCURRENT, "IStorage->Commit failed %x\n", r);
3732
3733 /* unless we force it */
3734 r = IStorage_Commit(stgrw, STGC_DEFAULT);
3735 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3736
3737 /* reverting gets us back to the last commit from the same storage */
3738 r = IStorage_Revert(stg);
3739 ok(r==S_OK, "IStorage->Revert failed %x\n", r);
3740
3741 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
3742 ok(r==S_OK, "IStorage->CreateStream failed %x\n", r);
3743
3744 pos.QuadPart = 0;
3745 r = IStream_Seek(stm, pos, 0, &upos);
3746 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3747
3748 r = IStream_Read(stm, buffer, sizeof(buffer), &bytesread);
3749 ok(r==S_OK, "IStream->Read failed %x\n", r);
3750 ok(bytesread == 3, "read wrong number of bytes %i\n", bytesread);
3751 ok(memcmp(buffer, "ccc", 3) == 0, "wrong data\n");
3752
3753 /* and committing fails forever */
3754 r = IStorage_Commit(stg, STGC_ONLYIFCURRENT);
3755 ok(r==STG_E_NOTCURRENT, "IStorage->Commit failed %x\n", r);
3756
3757 IStream_Release(stm);
3758
3759 IStorage_Release(stg);
3760 IStorage_Release(stgrw);
3761
3763}
3764
3765static void test_overwrite(void)
3766{
3767 IStorage *stg = NULL;
3768 HRESULT r;
3769 IStream *stm = NULL;
3770 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
3771 static const WCHAR stmname2[] = { 'C','O','N','T','E','N','T','2',0 };
3773 ULARGE_INTEGER upos;
3774 char buffer[4096];
3775 DWORD orig_size, new_size;
3776 ULONG bytesread;
3777 HANDLE hfile;
3778 int i;
3779
3781
3783 ok(r==S_OK, "StgCreateDocfile failed %x\n", r);
3784
3785 r = WriteClassStg(stg, &test_stg_cls);
3786 ok(r == S_OK, "WriteClassStg failed %x\n", r);
3787
3788 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
3789 ok(r==S_OK, "IStorage->CreateStream failed %x\n", r);
3790
3791 pos.QuadPart = 0;
3792 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
3793 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3794
3795 memset(buffer, 'a', sizeof(buffer));
3796 for (i=0; i<4; i++)
3797 {
3798 /* Write enough bytes to pass the minimum storage file size */
3799 r = IStream_Write(stm, buffer, sizeof(buffer), NULL);
3800 ok(r==S_OK, "IStream->Write failed %x\n", r);
3801 }
3802
3803 r = IStorage_Commit(stg, STGC_DEFAULT);
3804 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3805
3807 NULL, OPEN_EXISTING, 0, NULL);
3808 ok(hfile != NULL, "couldn't open file %d\n", GetLastError());
3809
3810 orig_size = GetFileSize(hfile, NULL);
3811
3812 pos.QuadPart = 0;
3813 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
3814 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3815
3816 r = IStream_Write(stm, "b", 1, NULL);
3817 ok(r==S_OK, "IStream->Write failed %x\n", r);
3818
3819 r = IStorage_Commit(stg, STGC_OVERWRITE);
3820 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3821
3822 new_size = GetFileSize(hfile, NULL);
3823
3824 todo_wine ok(new_size == orig_size, "file grew from %d bytes to %d\n", orig_size, new_size);
3825
3826 IStream_Release(stm);
3827
3828 IStorage_RenameElement(stg, stmname, stmname2);
3829
3830 r = IStorage_Commit(stg, STGC_OVERWRITE);
3831 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3832
3833 new_size = GetFileSize(hfile, NULL);
3834
3835 todo_wine ok(new_size == orig_size, "file grew from %d bytes to %d\n", orig_size, new_size);
3836
3837 IStorage_Release(stg);
3838
3840 ok(r==S_OK, "StgOpenStorage failed %x\n", r);
3841
3842 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
3843 ok(r==S_OK, "IStorage->CreateStream failed %x\n", r);
3844
3845 r = IStream_Read(stm, buffer, sizeof(buffer), &bytesread);
3846 ok(r==S_OK, "IStream->Write failed %x\n", r);
3847 ok(bytesread == sizeof(buffer), "only read %d bytes\n", bytesread);
3848 ok(buffer[0] == 'b', "unexpected data at byte 0\n");
3849
3850 for (i=1; i<sizeof(buffer); i++)
3851 if (buffer[i] != 'a')
3852 break;
3853 ok(i == sizeof(buffer), "unexpected data at byte %i\n", i);
3854
3855 pos.QuadPart = 0;
3856 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
3857 ok(r==S_OK, "IStream->Seek failed %x\n", r);
3858
3859 r = IStream_Write(stm, "c", 1, NULL);
3860 ok(r==S_OK, "IStream->Write failed %x\n", r);
3861
3862 r = IStorage_Commit(stg, STGC_OVERWRITE);
3863 ok(r==S_OK, "IStorage->Commit failed %x\n", r);
3864
3865 new_size = GetFileSize(hfile, NULL);
3866
3867 todo_wine ok(new_size == orig_size, "file grew from %d bytes to %d\n", orig_size, new_size);
3868
3869 IStream_Release(stm);
3870
3871 IStorage_Release(stg);
3872
3873 CloseHandle(hfile);
3874
3876}
3877
3878static void test_custom_lockbytes(void)
3879{
3880 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
3881 TestLockBytes* lockbytes;
3882 HRESULT hr;
3883 IStorage* stg;
3884 IStream* stm;
3885
3886 CreateTestLockBytes(&lockbytes);
3887
3889 ok(hr==S_OK, "StgCreateDocfileOnILockBytes failed %x\n", hr);
3890
3891 hr = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stm);
3892 ok(hr==S_OK, "IStorage_CreateStream failed %x\n", hr);
3893
3894 IStream_Release(stm);
3895
3896 hr = IStorage_Commit(stg, 0);
3897
3898 IStorage_Release(stg);
3899
3900 ok(!lockbytes->lock_called, "unexpected call to LockRegion\n");
3901
3902 lockbytes->locks_supported = LOCK_WRITE|LOCK_EXCLUSIVE|LOCK_ONLYONCE;
3903
3905 ok(hr==S_OK, "StgCreateDocfileOnILockBytes failed %x\n", hr);
3906
3907 hr = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stm);
3908 ok(hr==S_OK, "IStorage_CreateStream failed %x\n", hr);
3909
3910 IStream_Release(stm);
3911
3912 hr = IStorage_Commit(stg, 0);
3913
3914 IStorage_Release(stg);
3915
3916 ok(lockbytes->lock_called, "expected LockRegion to be called\n");
3917
3918 lockbytes->lock_hr = STG_E_INVALIDFUNCTION;
3919
3921 ok(hr==STG_E_INVALIDFUNCTION, "StgCreateDocfileOnILockBytes failed %x\n", hr);
3922
3923 DeleteTestLockBytes(lockbytes);
3924}
3925
3926START_TEST(storage32)
3927{
3929
3931 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
3932 {
3933 win_skip("Could not create temp file, %u\n", GetLastError());
3934 return;
3935 }
3938
3947 test_transact();
3949 test_revert();
3953 test_access();
3955 test_readonly();
3956 test_simple();
3959 test_copyto();
3963 test_rename();
3969 test_convert();
3971 test_locking();
3975}
#define broken(x)
Definition: _sntprintf.h:21
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define stat
Definition: acwin.h:99
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
#define U(x)
Definition: wordpad.c:45
const GUID IID_IUnknown
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI UnlockFileEx(IN HANDLE hFile, IN DWORD dwReserved, IN DWORD nNumberOfBytesToUnLockLow, IN DWORD nNumberOfBytesToUnLockHigh, IN LPOVERLAPPED lpOverlapped)
Definition: lock.c:183
BOOL WINAPI LockFileEx(IN HANDLE hFile, IN DWORD dwFlags, IN DWORD dwReserved, IN DWORD nNumberOfBytesToLockLow, IN DWORD nNumberOfBytesToLockHigh, IN LPOVERLAPPED lpOverlapped)
Definition: lock.c:82
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
DWORD WINAPI GetFullPathNameA(IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart)
Definition: path.c:993
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm)
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
HRESULT WINAPI ReadClassStg(IStorage *pstg, CLSID *pclsid)
Definition: storage32.c:9103
HRESULT WINAPI WriteClassStm(IStream *pStm, REFCLSID rclsid)
Definition: storage32.c:9525
HRESULT WINAPI StgCreateDocfileOnILockBytes(ILockBytes *plkbyt, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8946
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8636
HRESULT WINAPI ReadClassStm(IStream *pStm, CLSID *pclsid)
Definition: storage32.c:9548
HRESULT WINAPI GetConvertStg(IStorage *stg)
Definition: storage32.c:10617
HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt)
Definition: storage32.c:9056
HRESULT WINAPI WriteClassStg(IStorage *pStg, REFCLSID rclsid)
Definition: storage32.c:9078
HRESULT WINAPI WriteFmtUserTypeStg(LPSTORAGE pstg, CLIPFORMAT cf, LPOLESTR lpszUserType)
Definition: storage32.c:9356
HRESULT WINAPI SetConvertStg(IStorage *storage, BOOL convert)
Definition: storage32.c:10648
HRESULT WINAPI StgOpenStorageOnILockBytes(ILockBytes *plkbyt, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8984
static const WCHAR fileW[]
Definition: url.c:111
r reserved
Definition: btrfs.c:3006
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
uint8_t junk[422]
Definition: fsck.fat.h:34
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL global, BOOL delete_on_release, ILockBytes **ret)
Definition: memlockbytes.c:98
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
#define CREATE_ALWAYS
Definition: disk.h:72
static const WCHAR desc[]
Definition: protectdata.c:36
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define todo_wine
Definition: custom.c:79
static const struct access_res create[16]
Definition: package.c:7644
static ULONG POBJECT_ATTRIBUTES PIO_STATUS_BLOCK ULONG sharing
Definition: pipe.c:70
static char * dest
Definition: rtl.c:135
static const LARGE_INTEGER llZero
Definition: moniker.c:1113
static void test_direct_swmr(void)
Definition: storage32.c:3322
static const int rw_fail_ranges[]
Definition: storage32.c:3397
static BOOL can_open(LPCWSTR filename, DWORD access, DWORD sharing)
Definition: storage32.c:3422
static HRESULT create_test_file(IStorage *dest)
Definition: storage32.c:2552
static void test_create_storage_modes(void)
Definition: storage32.c:297
static const char file1_nameA[]
Definition: storage32.c:45
static void test_substorage_share(void)
Definition: storage32.c:1540
static const WCHAR stgA_name[]
Definition: storage32.c:49
static void test_access(void)
Definition: storage32.c:2124
static const int priority_locked_bytes[]
Definition: storage32.c:3386
static void DeleteTestLockBytes(TestLockBytes *This)
Definition: storage32.c:251
static const int tr_fail_ranges[]
Definition: storage32.c:3400
static const int wodw_locked_bytes[]
Definition: storage32.c:3391
static const WCHAR strmA_name[]
Definition: storage32.c:51
static void test_overwrite(void)
Definition: storage32.c:3765
static BOOL is_zero_length(LPCSTR filename)
Definition: storage32.c:715
static TestLockBytes * impl_from_ILockBytes(ILockBytes *iface)
Definition: storage32.c:75
static void test_copyto_recursive(void)
Definition: storage32.c:3195
static void test_streamenum(void)
Definition: storage32.c:1229
static void test_toplevel_stat(void)
Definition: storage32.c:3020
static const int rwex_locked_bytes[]
Definition: storage32.c:3387
static void test_copyto(void)
Definition: storage32.c:2611
static HRESULT WINAPI TestLockBytes_ReadAt(ILockBytes *iface, ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead)
Definition: storage32.c:111
static const int roex_locked_bytes[]
Definition: storage32.c:3394
static void test_simple(void)
Definition: storage32.c:2315
static void test_rename(void)
Definition: storage32.c:2950
static void test_custom_lockbytes(void)
Definition: storage32.c:3878
static void test_writeclassstg(void)
Definition: storage32.c:1179
static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2)
Definition: storage32.c:56
static void test_copyto_iidexclusions_stream(void)
Definition: storage32.c:2877
#define ok_ole_success(hr, func)
Definition: storage32.c:40
static const WCHAR file2_name[]
Definition: storage32.c:48
static void test_transact(void)
Definition: storage32.c:1406
static void check_sharing(LPCWSTR filename, const struct lock_test *current, DWORD access, DWORD sharing, const char *desc, DWORD *open_mode, BOOL *any_failure)
Definition: storage32.c:3435
static void test_references(void)
Definition: storage32.c:2504
static HRESULT WINAPI TestLockBytes_LockRegion(ILockBytes *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: storage32.c:188
static void test_readonly(void)
Definition: storage32.c:2239
static BOOL touch_file(LPCSTR filename)
Definition: storage32.c:703
static const int pr_fail_ranges[]
Definition: storage32.c:3401
static const ILockBytesVtbl TestLockBytes_Vtbl
Definition: storage32.c:227
static const int dw_fail_ranges[]
Definition: storage32.c:3399
static void test_substorage_enum(void)
Definition: storage32.c:3096
static const char file2_nameA[]
Definition: storage32.c:47
static const WCHAR strmB_name[]
Definition: storage32.c:52
static const int rwdw_fail_ranges[]
Definition: storage32.c:3398
static const DWORD share_modes[4]
Definition: storage32.c:2080
static void test_ReadClassStm(void)
Definition: storage32.c:1968
static HRESULT WINAPI TestLockBytes_Flush(ILockBytes *iface)
Definition: storage32.c:160
static void test_fmtusertypestg(void)
Definition: storage32.c:2431
static void test_revert(void)
Definition: storage32.c:1632
static void test_copyto_snbexclusions(void)
Definition: storage32.c:2715
static const int tr_locked_bytes[]
Definition: storage32.c:3392
static HRESULT WINAPI TestLockBytes_Stat(ILockBytes *iface, STATSTG *pstatstg, DWORD grfStatFlag)
Definition: storage32.c:203
static void test_convert(void)
Definition: storage32.c:3293
static const struct access_res create_close[16]
Definition: storage32.c:2053
static void test_copyto_iidexclusions_storage(void)
Definition: storage32.c:2798
static void test_parent_free(void)
Definition: storage32.c:1784
static const int rw_locked_bytes[]
Definition: storage32.c:3388
static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
Definition: storage32.c:2087
static void test_open_storage(void)
Definition: storage32.c:741
static BOOL is_existing_file(LPCSTR filename)
Definition: storage32.c:729
static void test_stgcreatestorageex(void)
Definition: storage32.c:451
static HRESULT WINAPI TestLockBytes_WriteAt(ILockBytes *iface, ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten)
Definition: storage32.c:135
static const DWORD access_modes[4]
Definition: storage32.c:2073
static void test_nonroot_transacted(void)
Definition: storage32.c:1847
static const WCHAR stgB_name[]
Definition: storage32.c:50
static void check_access(LPCWSTR filename, const struct lock_test *current, DWORD access, DWORD sharing, const char *desc, DWORD open_mode, BOOL *any_failure)
Definition: storage32.c:3465
static const int rwex_fail_ranges[]
Definition: storage32.c:3396
static const int rwdw_locked_bytes[]
Definition: storage32.c:3390
static const struct access_res create_commit[16]
Definition: storage32.c:2033
static CHAR filenameA[MAX_PATH]
Definition: storage32.c:42
static void test_hglobal_storage_stat(void)
Definition: storage32.c:259
static void test_transacted_shared(void)
Definition: storage32.c:3646
static void test_locking(void)
Definition: storage32.c:3490
static void test_storage_suminfo(void)
Definition: storage32.c:911
static ULONG WINAPI TestLockBytes_Release(ILockBytes *iface)
Definition: storage32.c:104
static const WCHAR file1_name[]
Definition: storage32.c:46
static const struct lock_test lock_tests[]
Definition: storage32.c:3404
#define test_file_access(file, ares)
Definition: storage32.c:2122
static void CreateTestLockBytes(TestLockBytes **This)
Definition: storage32.c:240
static HRESULT WINAPI TestLockBytes_UnlockRegion(ILockBytes *iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
Definition: storage32.c:196
static const int roex_fail_ranges[]
Definition: storage32.c:3402
static const int no_locked_bytes[]
Definition: storage32.c:3393
static const WCHAR strmC_name[]
Definition: storage32.c:53
static const int nosn_locked_bytes[]
Definition: storage32.c:3389
static void test_copyto_locking(void)
Definition: storage32.c:3143
static void test_storage_refcount(void)
Definition: storage32.c:1019
static ULONG WINAPI TestLockBytes_AddRef(ILockBytes *iface)
Definition: storage32.c:97
static void test_hglobal_storage_creation(void)
Definition: storage32.c:3247
static HRESULT WINAPI TestLockBytes_SetSize(ILockBytes *iface, ULARGE_INTEGER cb)
Definition: storage32.c:165
static void test_storage_stream(void)
Definition: storage32.c:504
static HRESULT WINAPI TestLockBytes_QueryInterface(ILockBytes *iface, REFIID iid, void **ppv)
Definition: storage32.c:80
#define min(a, b)
Definition: monoChain.cc:55
REFCLSID clsid
Definition: msctf.c:82
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define DELETE
Definition: nt_native.h:57
#define GENERIC_WRITE
Definition: nt_native.h:90
#define STGM_CREATE
Definition: objbase.h:926
#define STGFMT_DOCFILE
Definition: objbase.h:936
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_SHARE_DENY_NONE
Definition: objbase.h:920
#define STGM_DIRECT_SWMR
Definition: objbase.h:931
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_TRANSACTED
Definition: objbase.h:915
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_FAILIFTHERE
Definition: objbase.h:928
#define STGM_DELETEONRELEASE
Definition: objbase.h:925
#define STGM_NOSNAPSHOT
Definition: objbase.h:930
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
#define STGM_SIMPLE
Definition: objbase.h:916
#define STGM_PRIORITY
Definition: objbase.h:924
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
#define STGFMT_STORAGE
Definition: objbase.h:933
#define STGM_SHARE_DENY_READ
Definition: objbase.h:921
#define STGM_NOSCRATCH
Definition: objbase.h:929
const FMTID FMTID_SummaryInformation
long LONG
Definition: pedump.c:60
const GUID IID_IPersist
Definition: proxy.cpp:14
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define CLSID_NULL
Definition: guiddef.h:99
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define IsEqualCLSID(rclsid1, rclsid2)
Definition: guiddef.h:96
static calc_node_t temp
Definition: rpn_ieee.c:38
#define win_skip
Definition: test.h:160
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
ULONG buffer_size
Definition: storage32.c:69
ULONG size
Definition: storage32.c:68
ILockBytes ILockBytes_iface
Definition: storage32.c:65
ULONG lock_called
Definition: storage32.c:72
HRESULT lock_hr
Definition: storage32.c:70
BYTE * contents
Definition: storage32.c:67
ULONG locks_supported
Definition: storage32.c:71
DWORD OffsetHigh
Definition: winbase.h:816
DWORD Offset
Definition: winbase.h:815
HANDLE hEvent
Definition: winbase.h:820
struct _ULARGE_INTEGER::@4140 u
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
DWORD lasterr
Definition: package.c:7640
BOOL ignore
Definition: package.c:7641
BOOL gothandle
Definition: package.c:7639
Definition: fci.c:127
Definition: parser.c:49
const int * fail_ranges
Definition: storage32.c:3382
BOOL todo
Definition: storage32.c:3383
DWORD sharing
Definition: storage32.c:3380
const int * locked_bytes
Definition: storage32.c:3381
DWORD stg_mode
Definition: storage32.c:3377
DWORD access
Definition: storage32.c:3379
BOOL create
Definition: storage32.c:3378
Definition: send.c:48
Definition: stat.h:55
Definition: parse.h:23
#define max(a, b)
Definition: svc.c:63
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int ret
#define LOCKFILE_FAIL_IMMEDIATELY
Definition: winbase.h:385
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOCKFILE_EXCLUSIVE_LOCK
Definition: winbase.h:386
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define STG_E_SHAREVIOLATION
Definition: winerror.h:2577
#define STG_E_INVALIDPOINTER
Definition: winerror.h:2571
#define S_FALSE
Definition: winerror.h:2357
#define STG_E_REVERTED
Definition: winerror.h:2590
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define STG_E_NOTCURRENT
Definition: winerror.h:2589
#define STG_E_LOCKVIOLATION
Definition: winerror.h:2578
#define STG_E_INVALIDNAME
Definition: winerror.h:2584
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_READFAULT
Definition: winerror.h:2576
#define STG_E_FILEALREADYEXISTS
Definition: winerror.h:2579
#define STG_E_FILENOTFOUND
Definition: winerror.h:2565
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568
#define STG_E_INVALIDPARAMETER
Definition: winerror.h:2580
#define STG_E_INVALIDFLAG
Definition: winerror.h:2587
#define STG_E_UNIMPLEMENTEDFUNCTION
Definition: winerror.h:2586
#define STG_E_INVALIDFUNCTION
Definition: winerror.h:2564
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193