oleaut32/tests: Remove a temp file.
[wine] / dlls / ole32 / tests / storage32.c
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
25 #include <windows.h>
26 #include "wine/test.h"
27
28 #include "ole2.h"
29 #include "objidl.h"
30 #include "initguid.h"
31
32 DEFINE_GUID( test_stg_cls, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0);
33
34 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
35
36 static CHAR filenameA[MAX_PATH];
37 static WCHAR filename[MAX_PATH];
38
39 static const WCHAR file1_name[] = {'c','o','p','y','t','e','s','t','A',0};
40 static const WCHAR file2_name[] = {'c','o','p','y','t','e','s','t','B',0};
41 static const WCHAR stgA_name[] = {'S','t','o','r','a','g','e','A',0};
42 static const WCHAR stgB_name[] = {'S','t','o','r','a','g','e','B',0};
43 static const WCHAR strmA_name[] = {'S','t','r','e','a','m','A',0};
44 static const WCHAR strmB_name[] = {'S','t','r','e','a','m','B',0};
45 static const WCHAR strmC_name[] = {'S','t','r','e','a','m','C',0};
46
47 static void test_hglobal_storage_stat(void)
48 {
49     ILockBytes *ilb = NULL;
50     IStorage *stg = NULL;
51     HRESULT r;
52     STATSTG stat;
53     DWORD mode, refcount;
54
55     r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
56     ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
57
58     mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
59     r = StgCreateDocfileOnILockBytes( ilb, mode, 0,  &stg );
60     ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
61
62     r = WriteClassStg( stg, &test_stg_cls );
63     ok( r == S_OK, "WriteClassStg failed\n");
64
65     memset( &stat, 0, sizeof stat );
66     r = IStorage_Stat( stg, &stat, 0 );
67
68     ok( stat.pwcsName == NULL, "storage name not null\n");
69     ok( stat.type == 1, "type is wrong\n");
70     ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
71     ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
72
73     refcount = IStorage_Release( stg );
74     ok( refcount == 0, "IStorage refcount is wrong\n");
75     refcount = ILockBytes_Release( ilb );
76     ok( refcount == 0, "ILockBytes refcount is wrong\n");
77 }
78
79 static void test_create_storage_modes(void)
80 {
81    IStorage *stg = NULL;
82    HRESULT r;
83
84    DeleteFileA(filenameA);
85
86    /* test with some invalid parameters */
87    r = StgCreateDocfile( NULL, 0, 0, &stg);
88    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
89    r = StgCreateDocfile( filename, 0, 0, &stg);
90    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
91    r = StgCreateDocfile( filename, STGM_CREATE, 0, &stg);
92    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
93    r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE, 0, &stg);
94    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
95    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
96    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
97    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
98    ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
99    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
100    ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
101    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
102    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
103    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
104    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
105    r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
106    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
107
108    /* StgCreateDocfile seems to be very particular about the flags it accepts */
109    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
110    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
111    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
112    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
113    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
114    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
115    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
116    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
117    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
118    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
119    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
120    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
121    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
122    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
123    ok(stg == NULL, "stg was set\n");
124
125    /* check what happens if the file already exists (which is how it's meant to be used) */
126    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
127    ok(r==S_OK, "StgCreateDocfile failed\n");
128    r = IStorage_Release(stg);
129    ok(r == 0, "storage not released\n");
130    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
131    ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
132    r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
133    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
134    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE, 0, &stg);
135    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
136    r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE, 0, &stg);
137    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
138    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE, 0, &stg);
139    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
140    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
141    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
142    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, &stg);
143    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
144    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_WRITE, 0, &stg);
145    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
146    r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_WRITE, 0, &stg);
147    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
148    r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
149    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
150    r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
151    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
152    ok(DeleteFileA(filenameA), "failed to delete file\n");
153
154    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
155    ok(r==S_OK, "StgCreateDocfile failed\n");
156    r = IStorage_Release(stg);
157    ok(r == 0, "storage not released\n");
158    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
159    ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
160    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
161    ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
162
163    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
164    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
165    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
166    ok(r==S_OK, "StgCreateDocfile failed\n");
167    r = IStorage_Release(stg);
168    ok(r == 0, "storage not released\n");
169    ok(DeleteFileA(filenameA), "failed to delete file\n");
170
171    r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
172    ok(r==S_OK, "StgCreateDocfile failed\n");
173    r = IStorage_Release(stg);
174    ok(r == 0, "storage not released\n");
175    ok(DeleteFileA(filenameA), "failed to delete file\n");
176
177    /* test the way excel uses StgCreateDocFile */
178    r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
179    ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
180    if(r == S_OK)
181    {
182       r = IStorage_Release(stg);
183       ok(r == 0, "storage not released\n");
184       ok(DeleteFileA(filenameA), "failed to delete file\n");
185    }
186
187    /* and the way windows media uses it ... */
188    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_NONE | STGM_READWRITE | STGM_TRANSACTED, 0, &stg);
189    ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
190    if (r == S_OK)
191    {
192       r = IStorage_Release(stg);
193       ok(r == 0, "storage not released\n");
194       ok(DeleteFileA(filenameA), "failed to delete file\n");
195    }
196
197    /* looks like we need STGM_TRANSACTED or STGM_CREATE */
198    r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
199    ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
200    if(r == S_OK)
201    {
202       r = IStorage_Release(stg);
203       ok(r == 0, "storage not released\n");
204       ok(DeleteFileA(filenameA), "failed to delete file\n");
205    }
206
207    r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg);
208    ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
209    if(r == S_OK)
210    {
211       r = IStorage_Release(stg);
212       ok(r == 0, "storage not released\n");
213       ok(DeleteFileA(filenameA), "failed to delete file\n");
214    }
215
216    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
217    ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
218    if(r == S_OK)
219    {
220       r = IStorage_Release(stg);
221       ok(r == 0, "storage not released\n");
222       ok(DeleteFileA(filenameA), "failed to delete file\n");
223    }
224
225    /* test the way msi uses StgCreateDocfile */
226    r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
227    ok(r==S_OK, "StgCreateDocFile failed\n");
228    r = IStorage_Release(stg);
229    ok(r == 0, "storage not released\n");
230    ok(DeleteFileA(filenameA), "failed to delete file\n");
231 }
232
233 static void test_storage_stream(void)
234 {
235     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
236     static const WCHAR longname[] = {
237         'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
238         'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
239     };
240     IStorage *stg = NULL;
241     HRESULT r;
242     IStream *stm = NULL;
243     IStream *stm2 = NULL;
244     ULONG count = 0;
245     LARGE_INTEGER pos;
246     ULARGE_INTEGER p;
247     unsigned char buffer[0x100];
248
249     DeleteFileA(filenameA);
250
251     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
252     ok(r==S_OK, "StgCreateDocfile failed\n");
253
254     /* try create some invalid streams */
255     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, 0, &stm );
256     ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
257     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 1, &stm );
258     ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
259     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, NULL );
260     ok(r==STG_E_INVALIDPOINTER, "IStorage->CreateStream wrong error\n");
261     r = IStorage_CreateStream(stg, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
262     ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error\n");
263     r = IStorage_CreateStream(stg, longname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
264     ok(r==STG_E_INVALIDNAME || broken(r==S_OK) /* nt4 */,
265        "IStorage->CreateStream wrong error, got %d GetLastError()=%d\n", r, GetLastError());
266     r = IStorage_CreateStream(stg, stmname, STGM_READWRITE, 0, 0, &stm );
267     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
268     r = IStorage_CreateStream(stg, stmname, STGM_READ, 0, 0, &stm );
269     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
270     r = IStorage_CreateStream(stg, stmname, STGM_WRITE, 0, 0, &stm );
271     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
272     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, 0, &stm );
273     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
274     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READ, 0, 0, &stm );
275     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
276
277     /* now really create a stream and delete it */
278     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
279     ok(r==S_OK, "IStorage->CreateStream failed\n");
280     r = IStream_Release(stm);
281     ok(r == 0, "wrong ref count\n");
282     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
283     ok(r==STG_E_FILEALREADYEXISTS, "IStorage->CreateStream failed\n");
284     r = IStorage_DestroyElement(stg,stmname);
285     ok(r==S_OK, "IStorage->DestroyElement failed\n");
286
287     /* create a stream and write to it */
288     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
289     ok(r==S_OK, "IStorage->CreateStream failed\n");
290
291     r = IStream_Clone(stm, &stm2);
292     ok(r==S_OK, "failed to clone stream\n");
293
294     r = IStream_Write(stm, NULL, 0, NULL );
295     ok(r==STG_E_INVALIDPOINTER, "IStream->Write wrong error\n");
296     r = IStream_Write(stm, "Hello\n", 0, NULL );
297     ok(r==S_OK, "failed to write stream\n");
298     r = IStream_Write(stm, "Hello\n", 0, &count );
299     ok(r==S_OK, "failed to write stream\n");
300     r = IStream_Write(stm, "Hello\n", 6, &count );
301     ok(r==S_OK, "failed to write stream\n");
302     r = IStream_Commit(stm, STGC_DEFAULT );
303     ok(r==S_OK, "failed to commit stream\n");
304     r = IStream_Commit(stm, STGC_DEFAULT );
305     ok(r==S_OK, "failed to commit stream\n");
306
307     /* seek round a bit, reset the stream size */
308     pos.QuadPart = 0;
309     r = IStream_Seek(stm, pos, 3, &p );
310     ok(r==STG_E_INVALIDFUNCTION, "IStream->Seek returned wrong error\n");
311     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
312     ok(r==S_OK, "failed to seek stream\n");
313     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
314     ok(r==S_OK, "failed to seek stream\n");
315     r = IStream_SetSize(stm,p);
316     ok(r==S_OK, "failed to set pos\n");
317     pos.QuadPart = 10;
318     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
319     ok(r==S_OK, "failed to seek stream\n");
320     ok(p.QuadPart == 10, "at wrong place\n");
321     pos.QuadPart = 0;
322     r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
323     ok(r==S_OK, "failed to seek stream\n");
324     ok(p.QuadPart == 0, "at wrong place\n");
325     r = IStream_Read(stm, buffer, sizeof buffer, &count );
326     ok(r==S_OK, "failed to set pos\n");
327     ok(count == 0, "read bytes from empty stream\n");
328
329     /* wrap up */
330     r = IStream_Release(stm2);
331     ok(r == 0, "wrong ref count\n");
332
333     /* create a stream and write to it */
334     r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
335     ok(r==S_OK, "IStorage->CreateStream failed\n");
336
337     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p);
338     ok(r==STG_E_REVERTED, "overwritten stream should return STG_E_REVERTED instead of 0x%08x\n", r);
339
340     r = IStream_Release(stm2);
341     ok(r == 0, "wrong ref count\n");
342     r = IStream_Release(stm);
343     ok(r == 0, "wrong ref count\n");
344
345     r = IStorage_Release(stg);
346     ok(r == 0, "wrong ref count\n");
347     r = DeleteFileA(filenameA);
348     ok(r, "file should exist\n");
349 }
350
351 static BOOL touch_file(LPCSTR filename)
352 {
353     HANDLE file;
354
355     file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
356                 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
357     if (file==INVALID_HANDLE_VALUE)
358         return FALSE;
359     CloseHandle(file);
360     return TRUE;
361 }
362
363 static BOOL is_zero_length(LPCSTR filename)
364 {
365     HANDLE file;
366     DWORD len;
367
368     file = CreateFileA(filename, GENERIC_READ, 0, NULL,
369                 OPEN_EXISTING, 0, NULL);
370     if (file==INVALID_HANDLE_VALUE)
371         return FALSE;
372     len = GetFileSize(file, NULL);
373     CloseHandle(file);
374     return len == 0;
375 }
376
377 static BOOL is_existing_file(LPCSTR filename)
378 {
379     HANDLE file;
380
381     file = CreateFileA(filename, GENERIC_READ, 0, NULL,
382                        OPEN_EXISTING, 0, NULL);
383     if (file==INVALID_HANDLE_VALUE)
384         return FALSE;
385     CloseHandle(file);
386     return TRUE;
387 }
388
389 static void test_open_storage(void)
390 {
391     static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
392     IStorage *stg = NULL, *stg2 = NULL;
393     HRESULT r;
394     DWORD stgm;
395
396     /* try opening a zero length file - it should stay zero length */
397     DeleteFileA(filenameA);
398     touch_file(filenameA);
399     stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
400     r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
401     ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
402
403     stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
404     r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
405     ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
406     ok(is_zero_length(filenameA), "file length changed\n");
407
408     DeleteFileA(filenameA);
409
410     /* try opening a nonexistent file - it should not create it */
411     stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
412     r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
413     ok(r!=S_OK, "StgOpenStorage failed: 0x%08x\n", r);
414     if (r==S_OK) IStorage_Release(stg);
415     ok(!is_existing_file(filenameA), "StgOpenStorage should not create a file\n");
416     DeleteFileA(filenameA);
417
418     /* create the file */
419     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
420     ok(r==S_OK, "StgCreateDocfile failed\n");
421     IStorage_Release(stg);
422
423     r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
424     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
425     r = StgOpenStorage( NULL, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
426     ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
427     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, NULL);
428     ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
429     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 1, &stg);
430     ok(r==STG_E_INVALIDPARAMETER, "StgOpenStorage wrong error\n");
431     r = StgOpenStorage( szNonExist, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
432     ok(r==STG_E_FILENOTFOUND, "StgOpenStorage failed\n");
433     r = StgOpenStorage( filename, NULL, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
434     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
435     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
436     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
437     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
438     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
439     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
440     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
441
442     /* open it for real */
443     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg); /* XLViewer 97/2000 */
444     ok(r==S_OK, "StgOpenStorage failed\n");
445     if(stg)
446     {
447         r = IStorage_Release(stg);
448         ok(r == 0, "wrong ref count\n");
449     }
450
451     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
452     ok(r==S_OK, "StgOpenStorage failed\n");
453     if(stg)
454     {
455         r = IStorage_Release(stg);
456         ok(r == 0, "wrong ref count\n");
457     }
458
459     /* test the way word opens its custom dictionary */
460     r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
461                         STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
462     ok(r==S_OK, "StgOpenStorage failed\n");
463     if(stg)
464     {
465         r = IStorage_Release(stg);
466         ok(r == 0, "wrong ref count\n");
467     }
468
469     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
470     ok(r==S_OK, "StgOpenStorage failed\n");
471     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
472     ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
473     if(stg)
474     {
475         r = IStorage_Release(stg);
476         ok(r == 0, "wrong ref count\n");
477     }
478
479     /* now try write to a storage file we opened read-only */ 
480     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
481     ok(r==S_OK, "StgOpenStorage failed\n");
482     if(stg)
483     { 
484         static const WCHAR stmname[] =  { 'w','i','n','e','t','e','s','t',0};
485         IStream *stm = NULL;
486         IStorage *stg2 = NULL;
487
488         r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
489                                    0, 0, &stm );
490         ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
491         r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
492         ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
493
494         r = IStorage_Release(stg);
495         ok(r == 0, "wrong ref count\n");
496     }
497
498     /* open like visio 2003 */
499     stg = NULL;
500     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
501     ok(r == S_OK, "should succeed\n");
502     if (stg)
503         IStorage_Release(stg);
504
505     /* test other sharing modes with STGM_PRIORITY */
506     stg = NULL;
507     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
508     ok(r == S_OK, "should succeed\n");
509     if (stg)
510         IStorage_Release(stg);
511
512     stg = NULL;
513     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
514     ok(r == S_OK, "should succeed\n");
515     if (stg)
516         IStorage_Release(stg);
517
518     stg = NULL;
519     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_READ, NULL, 0, &stg);
520     ok(r == S_OK, "should succeed\n");
521     if (stg)
522         IStorage_Release(stg);
523
524     /* open like Project 2003 */
525     stg = NULL;
526     r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
527     ok(r == S_OK, "should succeed\n");
528     r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg2);
529     ok(r == S_OK, "should succeed\n");
530     if (stg2)
531         IStorage_Release(stg2);
532     if (stg)
533         IStorage_Release(stg);
534
535     stg = NULL;
536     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
537     ok(r == STG_E_INVALIDFLAG, "should fail\n");
538
539     r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
540     ok(r == STG_E_INVALIDFLAG, "should fail\n");
541
542     r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
543     ok(r == STG_E_INVALIDFLAG, "should fail\n");
544
545     r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
546     ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
547
548     r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
549     ok(r == STG_E_INVALIDFLAG, "should fail\n");
550
551     r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
552     ok(r == STG_E_INVALIDFLAG, "should fail\n");
553
554     r = DeleteFileA(filenameA);
555     ok(r, "file didn't exist\n");
556 }
557
558 static void test_storage_suminfo(void)
559 {
560     IStorage *stg = NULL;
561     IPropertySetStorage *propset = NULL;
562     IPropertyStorage *ps = NULL;
563     HRESULT r;
564
565     DeleteFileA(filenameA);
566
567     /* create the file */
568     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 
569                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
570     ok(r==S_OK, "StgCreateDocfile failed\n");
571
572     r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
573     ok(r == S_OK, "query interface failed\n");
574
575     /* delete it */
576     r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
577     ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
578
579     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
580                                 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
581     ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
582
583     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
584                                 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
585     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
586
587     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
588                                 STGM_READ, &ps );
589     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
590
591     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
592     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
593
594     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
595                                 STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
596     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
597
598     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
599                                 STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
600     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
601
602     /* now try really creating a property set */
603     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
604                                 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
605     ok(r == S_OK, "failed to create property set storage\n");
606
607     if( ps )
608         IPropertyStorage_Release(ps);
609
610     /* now try creating the same thing again */
611     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
612                                 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
613     ok(r == S_OK, "failed to create property set storage\n");
614     if( ps )
615         IPropertyStorage_Release(ps);
616
617     /* should be able to open it */
618     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
619             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
620     ok(r == S_OK, "open failed\n");
621     if(r == S_OK)
622         IPropertyStorage_Release(ps);
623
624     /* delete it */
625     r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
626     ok(r == S_OK, "failed to delete property set storage\n");
627
628     /* try opening with an invalid FMTID */
629     r = IPropertySetStorage_Open( propset, NULL, 
630             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
631     ok(r == E_INVALIDARG, "open succeeded\n");
632     if(r == S_OK)
633         IPropertyStorage_Release(ps);
634
635     /* try a bad guid */
636     r = IPropertySetStorage_Open( propset, &IID_IStorage, 
637             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
638     ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
639     if(r == S_OK)
640         IPropertyStorage_Release(ps);
641     
642
643     /* try some invalid flags */
644     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
645             STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
646     ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
647     if(r == S_OK)
648         IPropertyStorage_Release(ps);
649
650     /* after deleting it, it should be gone */
651     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
652             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
653     ok(r == STG_E_FILENOTFOUND, "open failed\n");
654     if(r == S_OK)
655         IPropertyStorage_Release(ps);
656
657     r = IPropertySetStorage_Release( propset );
658     ok(r == 1, "ref count wrong\n");
659
660     r = IStorage_Release(stg);
661     ok(r == 0, "ref count wrong\n");
662
663     DeleteFileA(filenameA);
664 }
665
666 static void test_storage_refcount(void)
667 {
668     IStorage *stg = NULL;
669     IStorage *stgprio = NULL;
670     HRESULT r;
671     IStream *stm = NULL;
672     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
673     LARGE_INTEGER pos;
674     ULARGE_INTEGER upos;
675     STATSTG stat;
676     char buffer[10];
677
678     DeleteFileA(filenameA);
679
680     /* create the file */
681     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 
682                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
683     ok(r==S_OK, "StgCreateDocfile failed\n");
684
685     r = WriteClassStg( stg, &test_stg_cls );
686     ok( r == S_OK, "WriteClassStg failed\n");
687
688     r = IStorage_Commit( stg, STGC_DEFAULT );
689     ok( r == S_OK, "IStorage_Commit failed\n");
690
691     /* now create a stream */
692     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
693     ok(r==S_OK, "IStorage->CreateStream failed\n");
694
695     r = IStorage_Release( stg );
696     ok (r == 0, "storage not released\n");
697
698     pos.QuadPart = 0;
699     r = IStream_Seek( stm, pos, 0, &upos );
700     ok (r == STG_E_REVERTED, "seek should fail\n");
701
702     r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
703     ok (r == STG_E_REVERTED, "stat should fail\n");
704
705     r = IStream_Write( stm, "Test string", strlen("Test string"), NULL);
706     ok (r == STG_E_REVERTED, "IStream_Write should return STG_E_REVERTED instead of 0x%08x\n", r);
707
708     r = IStream_Read( stm, buffer, sizeof(buffer), NULL);
709     ok (r == STG_E_REVERTED, "IStream_Read should return STG_E_REVERTED instead of 0x%08x\n", r);
710
711     r = IStream_Release(stm);
712     ok (r == 0, "stream not released\n");
713
714     /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
715      * StgOpenStorage calls in transacted mode */
716     r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio);
717     ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
718
719     todo_wine {
720     /* non-transacted mode read/write fails */
721     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
722     ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r);
723     }
724
725     /* non-transacted mode read-only succeeds */
726     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg);
727     ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
728     IStorage_Release(stg);
729
730     r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
731     ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
732     if(stg)
733     {
734         static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
735         static const WCHAR stgname2[] = { 'C','V','_','i','e','w',0 };
736         static const WCHAR stmname2[] = { 'V','a','r','2','D','a','t','a',0 };
737         IStorage *stg2;
738         IStorage *stg3;
739         STATSTG statstg;
740
741         r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
742         ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
743         ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
744         ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
745         ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
746         ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
747             "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg.grfMode);
748         ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
749         ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
750         ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
751         ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
752
753         r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
754         ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
755
756         r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
757         ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
758         ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)),
759             "Statstg pwcsName should have been the name the storage was created with\n");
760         ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
761         ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
762         ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
763         ok(statstg.grfMode == STGM_SHARE_EXCLUSIVE,
764             "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%x\n", statstg.grfMode);
765         ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
766         ok(IsEqualCLSID(&statstg.clsid, &CLSID_NULL), "Statstg clsid is not CLSID_NULL\n");
767         ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
768         ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
769         CoTaskMemFree(statstg.pwcsName);
770
771         r = IStorage_CreateStorage( stg2, stgname2, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stg3 );
772         ok(r == STG_E_ACCESSDENIED, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
773
774         r = IStorage_CreateStream( stg2, stmname2, STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
775         ok(r == STG_E_ACCESSDENIED, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
776
777         IStorage_Release(stg2);
778
779         r = IStorage_Release(stg);
780         ok(r == 0, "wrong ref count\n");
781     }
782     IStorage_Release(stgprio);
783
784     DeleteFileA(filenameA);
785 }
786
787 static void test_writeclassstg(void)
788 {
789     IStorage *stg = NULL;
790     HRESULT r;
791     CLSID temp_cls;
792
793     DeleteFileA(filenameA);
794
795     /* create the file */
796     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
797                             STGM_READWRITE, 0, &stg);
798     ok(r==S_OK, "StgCreateDocfile failed\n");
799
800     r = ReadClassStg( NULL, NULL );
801     ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
802
803     r = ReadClassStg( stg, NULL );
804     ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
805
806     temp_cls.Data1 = 0xdeadbeef;
807     r = ReadClassStg( stg, &temp_cls );
808     ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
809
810     ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
811
812     r = WriteClassStg( NULL, NULL );
813     ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
814
815     r = WriteClassStg( stg, NULL );
816     ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
817
818     r = WriteClassStg( stg, &test_stg_cls );
819     ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
820
821     r = ReadClassStg( stg, &temp_cls );
822     ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
823     ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
824
825     r = IStorage_Release( stg );
826     ok (r == 0, "storage not released\n");
827
828     DeleteFileA(filenameA);
829 }
830
831 static void test_streamenum(void)
832 {
833     IStorage *stg = NULL;
834     HRESULT r;
835     IStream *stm = NULL;
836     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
837     STATSTG stat;
838     IEnumSTATSTG *ee = NULL;
839     ULONG count;
840
841     DeleteFileA(filenameA);
842
843     /* create the file */
844     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
845                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
846     ok(r==S_OK, "StgCreateDocfile failed\n");
847
848     r = WriteClassStg( stg, &test_stg_cls );
849     ok( r == S_OK, "WriteClassStg failed\n");
850
851     r = IStorage_Commit( stg, STGC_DEFAULT );
852     ok( r == S_OK, "IStorage_Commit failed\n");
853
854     /* now create a stream */
855     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
856     ok(r==S_OK, "IStorage->CreateStream failed\n");
857
858     r = IStream_Release(stm);
859
860     /* first enum ... should be 1 stream */
861     r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
862     ok(r==S_OK, "IStorage->EnumElements failed\n");
863
864     count = 0xf00;
865     r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
866     ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
867     ok(count == 1, "count wrong\n");
868
869     r = IEnumSTATSTG_Release(ee);
870
871     /* second enum... destroy the stream before reading */
872     r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
873     ok(r==S_OK, "IStorage->EnumElements failed\n");
874
875     r = IStorage_DestroyElement(stg, stmname);
876     ok(r==S_OK, "IStorage->EnumElements failed\n");
877
878     todo_wine {
879     count = 0xf00;
880     r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
881     ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
882     ok(count == 0, "count wrong\n");
883     }
884
885     /* reset and try again */
886     r = IEnumSTATSTG_Reset(ee);
887     ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
888
889     count = 0xf00;
890     r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
891     ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
892     ok(count == 0, "count wrong\n");
893
894     r = IEnumSTATSTG_Release(ee);
895     ok (r == 0, "enum not released\n");
896
897     r = IStorage_Release( stg );
898     ok (r == 0, "storage not released\n");
899
900     DeleteFileA(filenameA);
901 }
902
903 static void test_transact(void)
904 {
905     IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
906     HRESULT r;
907     IStream *stm = NULL;
908     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
909     static const WCHAR stmname2[] = { 'F','O','O',0 };
910     static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
911     static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
912
913     DeleteFileA(filenameA);
914
915     /* create the file */
916     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 
917                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
918     ok(r==S_OK, "StgCreateDocfile failed\n");
919
920     /* commit a new stream and storage */
921     r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
922     ok(r==S_OK, "IStorage->CreateStream failed\n");
923
924     r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
925     ok(r==S_OK, "IStream->Write failed\n");
926
927     IStream_Release(stm);
928
929     r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
930     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
931
932     if (r == S_OK)
933     {
934         /* Create two substorages but only commit one */
935         r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
936         ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
937
938         if (r == S_OK)
939             IStorage_Release(stg3);
940
941         r = IStorage_Commit(stg, 0);
942         ok(r==S_OK, "IStorage->Commit failed\n");
943
944         r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
945         ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
946
947         if (r == S_OK)
948             IStorage_Release(stg3);
949
950         IStorage_Release(stg2);
951     }
952
953     /* now create a stream and storage, but don't commit them */
954     stm = NULL;
955     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
956     ok(r==S_OK, "IStorage->CreateStream failed\n");
957
958     r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
959     ok(r==S_OK, "IStream->Write failed\n");
960
961     /* IStream::Commit does nothing for OLE storage streams */
962     r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
963     ok(r==S_OK, "IStream->Commit failed\n");
964
965     r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
966     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
967
968     if (r == S_OK)
969         IStorage_Release(stg2);
970
971     IStream_Release(stm);
972
973     IStorage_Release(stg);
974
975     stm = NULL;
976     stg = NULL;
977     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
978     ok(r==S_OK, "StgOpenStorage failed\n");
979
980     if (!stg)
981         return;
982
983     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
984     ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
985
986     r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
987     ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
988
989     r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
990     ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
991
992     r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
993     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
994
995     todo_wine {
996     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
997     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
998     }
999     if (r == S_OK)
1000         IStream_Release(stm);
1001
1002     todo_wine {
1003     r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1004     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1005     }
1006     if (r == S_OK)
1007         IStorage_Release(stg2);
1008
1009     r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1010     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1011
1012     r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1013     ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1014     if (r == S_OK)
1015         IStream_Release(stm);
1016
1017     r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1018     ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1019     if (r == S_OK)
1020     {
1021         r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1022         ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1023         if (r == S_OK)
1024             IStorage_Release(stg3);
1025
1026         r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1027         todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1028         if (r == S_OK)
1029             IStorage_Release(stg3);
1030
1031         IStorage_Release(stg2);
1032     }
1033
1034     IStorage_Release(stg);
1035
1036     r = DeleteFileA(filenameA);
1037     ok( r == TRUE, "deleted file\n");
1038 }
1039
1040 static void test_substorage_share(void)
1041 {
1042     IStorage *stg, *stg2, *stg3;
1043     IStream *stm, *stm2;
1044     HRESULT r;
1045     static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1046     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1047
1048     DeleteFileA(filenameA);
1049
1050     /* create the file */
1051     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1052                             STGM_READWRITE, 0, &stg);
1053     ok(r==S_OK, "StgCreateDocfile failed\n");
1054
1055     /* create a read/write storage and try to open it again */
1056     r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1057     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1058
1059     if (r == S_OK)
1060     {
1061         r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1062         todo_wine ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1063
1064         if (r == S_OK)
1065             IStorage_Release(stg3);
1066
1067         r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1068         todo_wine ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1069
1070         if (r == S_OK)
1071             IStorage_Release(stg3);
1072
1073 #if 0
1074         /* This crashes on Wine. */
1075
1076         /* destroying an object while it's open invalidates it */
1077         r = IStorage_DestroyElement(stg, stgname);
1078         ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1079
1080         r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1081         todo_wine ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r);
1082
1083         if (r == S_OK)
1084             IStorage_Release(stm);
1085 #endif
1086
1087         IStorage_Release(stg2);
1088     }
1089
1090     /* create a read/write stream and try to open it again */
1091     r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1092     ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
1093
1094     if (r == S_OK)
1095     {
1096         r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1097         todo_wine ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1098
1099         if (r == S_OK)
1100             IStorage_Release(stm2);
1101
1102         r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1103         todo_wine ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1104
1105         if (r == S_OK)
1106             IStorage_Release(stm2);
1107
1108         /* destroying an object while it's open invalidates it */
1109         r = IStorage_DestroyElement(stg, stmname);
1110         ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1111
1112         r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1113         todo_wine ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1114
1115         IStorage_Release(stm);
1116     }
1117
1118     IStorage_Release(stg);
1119
1120     r = DeleteFileA(filenameA);
1121     ok( r == TRUE, "deleted file\n");
1122 }
1123
1124 static void test_revert(void)
1125 {
1126     IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1127     HRESULT r;
1128     IStream *stm = NULL, *stm2 = NULL;
1129     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1130     static const WCHAR stmname2[] = { 'F','O','O',0 };
1131     static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1132     static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1133     STATSTG statstg;
1134
1135     DeleteFileA(filenameA);
1136
1137     /* create the file */
1138     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1139                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1140     ok(r==S_OK, "StgCreateDocfile failed\n");
1141
1142     /* commit a new stream and storage */
1143     r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1144     ok(r==S_OK, "IStorage->CreateStream failed\n");
1145
1146     r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1147     ok(r==S_OK, "IStream->Write failed\n");
1148
1149     r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1150     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1151
1152     if (r == S_OK)
1153     {
1154         /* Create two substorages but only commit one */
1155         r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1156         ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1157
1158         if (r == S_OK)
1159             IStorage_Release(stg3);
1160
1161         r = IStorage_Commit(stg, 0);
1162         ok(r==S_OK, "IStorage->Commit failed\n");
1163
1164         r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1165         ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1166
1167         if (r == S_OK)
1168             IStorage_Release(stg3);
1169     }
1170
1171     /* now create a stream and storage, then revert */
1172     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
1173     ok(r==S_OK, "IStorage->CreateStream failed\n");
1174
1175     r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1176     ok(r==S_OK, "IStream->Write failed\n");
1177
1178     r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1179     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1180
1181     r = IStorage_Revert(stg);
1182
1183     /* all open objects become invalid */
1184     todo_wine {
1185     r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1186     ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1187
1188     r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL);
1189     ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1190
1191     r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1192     ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1193
1194     r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1195     ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1196     }
1197
1198     IStream_Release(stm);
1199     IStream_Release(stm2);
1200     IStorage_Release(stg2);
1201     IStorage_Release(stg3);
1202
1203     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1204     ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1205
1206     r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1207     ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1208
1209     r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1210     ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1211
1212     r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1213     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1214
1215     todo_wine {
1216     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1217     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1218     }
1219     if (r == S_OK)
1220         IStream_Release(stm);
1221
1222     todo_wine {
1223     r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1224     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1225     }
1226     if (r == S_OK)
1227         IStorage_Release(stg2);
1228
1229     r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1230     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1231
1232     r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1233     ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1234     if (r == S_OK)
1235         IStream_Release(stm);
1236
1237     r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1238     ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1239     if (r == S_OK)
1240     {
1241         r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1242         ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1243         if (r == S_OK)
1244             IStorage_Release(stg3);
1245
1246         r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1247         todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1248         if (r == S_OK)
1249             IStorage_Release(stg3);
1250
1251         IStorage_Release(stg2);
1252     }
1253
1254     IStorage_Release(stg);
1255
1256     r = DeleteFileA(filenameA);
1257     ok( r == TRUE, "deleted file\n");
1258
1259     /* Revert only invalidates objects in transacted mode */
1260     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1261                             STGM_READWRITE, 0, &stg);
1262     ok(r==S_OK, "StgCreateDocfile failed\n");
1263
1264     r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1265     ok(r==S_OK, "IStorage->CreateStream failed\n");
1266
1267     r = IStorage_Revert(stg);
1268     todo_wine ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1269
1270     r = IStream_Write(stm, "this works\n", 11, NULL);
1271     ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1272
1273     IStream_Release(stm);
1274     IStream_Release(stg);
1275
1276     r = DeleteFileA(filenameA);
1277     ok( r == TRUE, "deleted file\n");
1278 }
1279
1280 static void test_nonroot_transacted(void)
1281 {
1282     IStorage *stg = NULL, *stg2 = NULL;
1283     HRESULT r;
1284     IStream *stm = NULL;
1285     static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1286     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1287     static const WCHAR stmname2[] = { 'F','O','O',0 };
1288
1289     DeleteFileA(filenameA);
1290
1291     /* create a transacted file */
1292     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1293                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1294     ok(r==S_OK, "StgCreateDocfile failed\n");
1295
1296     /* create a transacted substorage */
1297     r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1298     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1299
1300     if (r == S_OK)
1301     {
1302         /* create and commit stmname */
1303         r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1304         ok(r==S_OK, "IStorage->CreateStream failed\n");
1305         if (r == S_OK)
1306             IStream_Release(stm);
1307
1308         IStorage_Commit(stg2, 0);
1309
1310         /* create and revert stmname2 */
1311         r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1312         ok(r==S_OK, "IStorage->CreateStream failed\n");
1313         if (r == S_OK)
1314             IStream_Release(stm);
1315
1316         IStorage_Revert(stg2);
1317
1318         /* check that Commit and Revert really worked */
1319         r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1320         ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1321         if (r == S_OK)
1322             IStream_Release(stm);
1323
1324         r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1325         todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1326         if (r == S_OK)
1327             IStream_Release(stm);
1328
1329         IStorage_Release(stg2);
1330     }
1331
1332     IStream_Release(stg);
1333
1334     /* create a non-transacted file */
1335     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1336                             STGM_READWRITE, 0, &stg);
1337     ok(r==S_OK, "StgCreateDocfile failed\n");
1338
1339     /* create a transacted substorage */
1340     r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1341     ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1342
1343     if (r == S_OK)
1344     {
1345         /* create and commit stmname */
1346         r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1347         ok(r==S_OK, "IStorage->CreateStream failed\n");
1348         if (r == S_OK)
1349             IStream_Release(stm);
1350
1351         IStorage_Commit(stg2, 0);
1352
1353         /* create and revert stmname2 */
1354         r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1355         ok(r==S_OK, "IStorage->CreateStream failed\n");
1356         if (r == S_OK)
1357             IStream_Release(stm);
1358
1359         IStorage_Revert(stg2);
1360
1361         /* check that Commit and Revert really worked */
1362         r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1363         ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1364         if (r == S_OK)
1365             IStream_Release(stm);
1366
1367         r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1368         todo_wine ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1369         if (r == S_OK)
1370             IStream_Release(stm);
1371
1372         IStorage_Release(stg2);
1373     }
1374
1375     IStream_Release(stg);
1376
1377     r = DeleteFileA(filenameA);
1378     ok( r == TRUE, "deleted file\n");
1379 }
1380
1381 static void test_ReadClassStm(void)
1382 {
1383     CLSID clsid;
1384     HRESULT hr;
1385     IStream *pStream;
1386     static const LARGE_INTEGER llZero;
1387
1388     hr = ReadClassStm(NULL, &clsid);
1389     ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1390
1391     hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1392     ok_ole_success(hr, "CreateStreamOnHGlobal");
1393     hr = WriteClassStm(pStream, &test_stg_cls);
1394     ok_ole_success(hr, "WriteClassStm");
1395
1396     hr = ReadClassStm(pStream, NULL);
1397     ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1398
1399     /* test not rewound stream */
1400     hr = ReadClassStm(pStream, &clsid);
1401     ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1402     ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1403
1404     hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1405     ok_ole_success(hr, "IStream_Seek");
1406     hr = ReadClassStm(pStream, &clsid);
1407     ok_ole_success(hr, "ReadClassStm");
1408     ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
1409 }
1410
1411 struct access_res
1412 {
1413     BOOL gothandle;
1414     DWORD lasterr;
1415     BOOL ignore;
1416 };
1417
1418 static const struct access_res create[16] =
1419 {
1420     { TRUE, ERROR_SUCCESS, TRUE },
1421     { TRUE, ERROR_SUCCESS, TRUE },
1422     { TRUE, ERROR_SUCCESS, FALSE },
1423     { TRUE, ERROR_SUCCESS, FALSE },
1424     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1425     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1426     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1427     { TRUE, ERROR_SUCCESS, FALSE },
1428     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1429     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1430     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1431     { TRUE, ERROR_SUCCESS, TRUE },
1432     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1433     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1434     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1435     { TRUE, ERROR_SUCCESS, TRUE }
1436 };
1437
1438 static const struct access_res create_commit[16] =
1439 {
1440     { TRUE, ERROR_SUCCESS, TRUE },
1441     { TRUE, ERROR_SUCCESS, TRUE },
1442     { TRUE, ERROR_SUCCESS, FALSE },
1443     { TRUE, ERROR_SUCCESS, FALSE },
1444     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1445     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1446     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1447     { TRUE, ERROR_SUCCESS, FALSE },
1448     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1449     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1450     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1451     { TRUE, ERROR_SUCCESS, TRUE },
1452     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1453     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1454     { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1455     { TRUE, ERROR_SUCCESS, TRUE }
1456 };
1457
1458 static const struct access_res create_close[16] =
1459 {
1460     { TRUE, ERROR_SUCCESS, FALSE },
1461     { TRUE, ERROR_SUCCESS, FALSE },
1462     { TRUE, ERROR_SUCCESS, FALSE },
1463     { TRUE, ERROR_SUCCESS, FALSE },
1464     { TRUE, ERROR_SUCCESS, FALSE },
1465     { TRUE, ERROR_SUCCESS, FALSE },
1466     { TRUE, ERROR_SUCCESS, FALSE },
1467     { TRUE, ERROR_SUCCESS, FALSE },
1468     { TRUE, ERROR_SUCCESS, FALSE },
1469     { TRUE, ERROR_SUCCESS, FALSE },
1470     { TRUE, ERROR_SUCCESS, FALSE },
1471     { TRUE, ERROR_SUCCESS, FALSE },
1472     { TRUE, ERROR_SUCCESS, FALSE },
1473     { TRUE, ERROR_SUCCESS, FALSE },
1474     { TRUE, ERROR_SUCCESS, FALSE },
1475     { TRUE, ERROR_SUCCESS }
1476 };
1477
1478 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1479 {
1480     DWORD access = 0, share = 0;
1481     DWORD lasterr;
1482     HANDLE hfile;
1483     int i, j, idx = 0;
1484
1485     for (i = 0; i < 4; i++)
1486     {
1487         if (i == 0) access = 0;
1488         if (i == 1) access = GENERIC_READ;
1489         if (i == 2) access = GENERIC_WRITE;
1490         if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
1491
1492         for (j = 0; j < 4; j++)
1493         {
1494             if (ares[idx].ignore)
1495                 continue;
1496
1497             if (j == 0) share = 0;
1498             if (j == 1) share = FILE_SHARE_READ;
1499             if (j == 2) share = FILE_SHARE_WRITE;
1500             if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
1501
1502             SetLastError(0xdeadbeef);
1503             hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
1504                                 FILE_ATTRIBUTE_NORMAL, 0);
1505             lasterr = GetLastError();
1506
1507             ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
1508                "(%d, handle, %d): Expected %d, got %d\n",
1509                line, idx, ares[idx].gothandle,
1510                (hfile != INVALID_HANDLE_VALUE));
1511
1512             ok(lasterr == ares[idx].lasterr ||
1513                broken(lasterr == 0xdeadbeef) /* win9x */,
1514                "(%d, lasterr, %d): Expected %d, got %d\n",
1515                line, idx, ares[idx].lasterr, lasterr);
1516
1517             CloseHandle(hfile);
1518             idx++;
1519         }
1520     }
1521 }
1522
1523 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1524
1525 static void test_access(void)
1526 {
1527     IStorage *stg;
1528     HRESULT hr;
1529
1530     static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1531
1532     /* STGM_TRANSACTED */
1533
1534     hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1535                           STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, &stg);
1536     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1537
1538     test_file_access("winetest", create);
1539
1540     hr = IStorage_Commit(stg, STGC_DEFAULT);
1541     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1542
1543     test_file_access("winetest", create_commit);
1544
1545     IStorage_Release(stg);
1546
1547     test_file_access("winetest", create_close);
1548
1549     DeleteFileA("winetest");
1550
1551     /* STGM_DIRECT */
1552
1553     hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1554                           STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &stg);
1555     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1556
1557     test_file_access("winetest", create);
1558
1559     hr = IStorage_Commit(stg, STGC_DEFAULT);
1560     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1561
1562     test_file_access("winetest", create_commit);
1563
1564     IStorage_Release(stg);
1565
1566     test_file_access("winetest", create_close);
1567
1568     DeleteFileA("winetest");
1569
1570     /* STGM_SHARE_DENY_NONE */
1571
1572     hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1573                           STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
1574     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1575
1576     test_file_access("winetest", create);
1577
1578     hr = IStorage_Commit(stg, STGC_DEFAULT);
1579     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1580
1581     test_file_access("winetest", create_commit);
1582
1583     IStorage_Release(stg);
1584
1585     test_file_access("winetest", create_close);
1586
1587     DeleteFileA("winetest");
1588
1589     /* STGM_SHARE_DENY_READ */
1590
1591     hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1592                           STGM_SHARE_DENY_READ | STGM_TRANSACTED, 0, &stg);
1593     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1594
1595     test_file_access("winetest", create);
1596
1597     hr = IStorage_Commit(stg, STGC_DEFAULT);
1598     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1599
1600     test_file_access("winetest", create_commit);
1601
1602     IStorage_Release(stg);
1603
1604     test_file_access("winetest", create_close);
1605
1606     DeleteFileA("winetest");
1607
1608     /* STGM_SHARE_DENY_WRITE */
1609
1610     hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1611                           STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
1612     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1613
1614     test_file_access("winetest", create);
1615
1616     hr = IStorage_Commit(stg, STGC_DEFAULT);
1617     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1618
1619     test_file_access("winetest", create_commit);
1620
1621     IStorage_Release(stg);
1622
1623     test_file_access("winetest", create_close);
1624
1625     DeleteFileA("winetest");
1626 }
1627
1628 static void test_readonly(void)
1629 {
1630     IStorage *stg, *stg2, *stg3;
1631     IStream *stream;
1632     HRESULT hr;
1633     static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1634     static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
1635     static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
1636
1637     hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1638     ok(hr == S_OK, "should succeed, res=%x\n", hr);
1639     if (SUCCEEDED(hr))
1640     {
1641         hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
1642         ok(hr == S_OK, "should succeed, res=%x\n", hr);
1643         if (SUCCEEDED(hr))
1644         {
1645             hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
1646             ok(hr == S_OK, "should succeed, res=%x\n", hr);
1647             if (SUCCEEDED(hr))
1648                 IStream_Release(stream);
1649             IStorage_Release(stg2);
1650         }
1651         IStorage_Release(stg);
1652     }
1653
1654     /* re-open read only */
1655     hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
1656     ok(hr == S_OK, "should succeed, res=%x\n", hr);
1657     if (SUCCEEDED(hr))
1658     {
1659         hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
1660         ok(hr == S_OK, "should succeed, res=%x\n", hr);
1661         if (SUCCEEDED(hr))
1662         {
1663             /* CreateStream on read-only storage, name exists */
1664             hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1665             ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1666             if (SUCCEEDED(hr))
1667                 IStream_Release(stream);
1668
1669             /* CreateStream on read-only storage, name does not exist */
1670             hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1671             ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1672             if (SUCCEEDED(hr))
1673                 IStream_Release(stream);
1674
1675             /* CreateStorage on read-only storage, name exists */
1676             hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1677             ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
1678             if (SUCCEEDED(hr))
1679                 IStream_Release(stg3);
1680
1681             /* CreateStorage on read-only storage, name does not exist */
1682             hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1683             ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1684             if (SUCCEEDED(hr))
1685                 IStream_Release(stg3);
1686
1687             /* DestroyElement on read-only storage, name exists */
1688             hr = IStorage_DestroyElement( stg2, streamW );
1689             ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1690
1691             /* DestroyElement on read-only storage, name does not exist */
1692             hr = IStorage_DestroyElement( stg2, storageW );
1693             ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1694
1695             IStorage_Release(stg2);
1696         }
1697
1698         IStorage_Release(stg);
1699     }
1700
1701     DeleteFileA("winetest");
1702 }
1703
1704 static void test_simple(void)
1705 {
1706     /* Tests for STGM_SIMPLE mode */
1707
1708     IStorage *stg;
1709     HRESULT r;
1710     IStream *stm;
1711     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1712     static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
1713     LARGE_INTEGER pos;
1714     ULARGE_INTEGER upos;
1715     DWORD count;
1716     STATSTG stat;
1717
1718     DeleteFileA(filenameA);
1719
1720     r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1721     ok(r == S_OK, "got %08x\n", r);
1722
1723     r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1724     ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
1725     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1726     ok(r == S_OK, "got %08x\n", r);
1727
1728     upos.QuadPart = 6000;
1729     r = IStream_SetSize(stm, upos);
1730     ok(r == S_OK, "got %08x\n", r);
1731
1732     r = IStream_Write(stm, "foo", 3, &count);
1733     ok(r == S_OK, "got %08x\n", r);
1734     ok(count == 3, "got %d\n", count);
1735
1736     pos.QuadPart = 0;
1737     r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
1738     ok(r == S_OK, "got %08x\n", r);
1739     ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
1740
1741     r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1742     ok(r == S_OK ||
1743        broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
1744        "got %08x\n", r);
1745     if (r == S_OK)
1746         ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
1747
1748     pos.QuadPart = 1;
1749     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
1750     ok(r == S_OK, "got %08x\n", r);
1751     ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
1752
1753     r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1754     ok(r == S_OK ||
1755        broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
1756        "got %08x\n", r);
1757     if (r == S_OK)
1758         ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
1759
1760     IStream_Release(stm);
1761
1762     r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1763     ok(r == S_OK, "got %08x\n", r);
1764
1765     upos.QuadPart = 100;
1766     r = IStream_SetSize(stm, upos);
1767     ok(r == S_OK, "got %08x\n", r);
1768
1769     r = IStream_Write(stm, "foo", 3, &count);
1770     ok(r == S_OK, "got %08x\n", r);
1771     ok(count == 3, "got %d\n", count);
1772
1773     IStream_Release(stm);
1774
1775     IStorage_Commit(stg, STGC_DEFAULT);
1776     IStorage_Release(stg);
1777
1778     r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
1779     if (r == STG_E_INVALIDFLAG)
1780     {
1781         win_skip("Flag combination is not supported on NT4 and below\n");
1782         DeleteFileA(filenameA);
1783         return;
1784     }
1785     ok(r == S_OK, "got %08x\n", r);
1786
1787     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1788     ok(r == S_OK, "got %08x\n", r);
1789
1790     r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1791     ok(r == S_OK, "got %08x\n", r);
1792     ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
1793
1794     IStream_Release(stm);
1795
1796     r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1797     ok(r == S_OK, "got %08x\n", r);
1798
1799     r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1800     ok(r == S_OK, "got %08x\n", r);
1801     ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
1802
1803     IStream_Release(stm);
1804
1805
1806     IStorage_Release(stg);
1807
1808     DeleteFileA(filenameA);
1809 }
1810
1811 static void test_fmtusertypestg(void)
1812 {
1813     IStorage *stg;
1814     IEnumSTATSTG *stat;
1815     HRESULT hr;
1816     static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0};
1817     static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0};
1818     static WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0};
1819
1820     hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1821     ok(hr == S_OK, "should succeed, res=%x\n", hr);
1822
1823     if (SUCCEEDED(hr))
1824     {
1825         /* try to write the stream */
1826         hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
1827         ok(hr == S_OK, "should succeed, res=%x\n", hr);
1828
1829         /* check that the stream was created */
1830         hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
1831         ok(hr == S_OK, "should succeed, res=%x\n", hr);
1832         if (SUCCEEDED(hr))
1833         {
1834             BOOL found = FALSE;
1835             STATSTG statstg;
1836             DWORD got;
1837             while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
1838             {
1839                 if (lstrcmpW(statstg.pwcsName, strmNameW) == 0)
1840                     found = TRUE;
1841                 else
1842                     ok(0, "found unexpected stream or storage\n");
1843             }
1844             ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
1845             IEnumSTATSTG_Release(stat);
1846         }
1847
1848         /* re-write the stream */
1849         hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
1850         ok(hr == S_OK, "should succeed, res=%x\n", hr);
1851
1852         /* check that the stream is still there */
1853         hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
1854         ok(hr == S_OK, "should succeed, res=%x\n", hr);
1855         if (SUCCEEDED(hr))
1856         {
1857             BOOL found = FALSE;
1858             STATSTG statstg;
1859             DWORD got;
1860             while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
1861             {
1862                 if (lstrcmpW(statstg.pwcsName, strmNameW) == 0)
1863                     found = TRUE;
1864                 else
1865                     ok(0, "found unexpected stream or storage\n");
1866             }
1867             ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
1868             IEnumSTATSTG_Release(stat);
1869         }
1870
1871         IStorage_Release(stg);
1872         DeleteFileW( fileW );
1873     }
1874 }
1875
1876 static void test_references(void)
1877 {
1878     IStorage *stg,*stg2;
1879     HRESULT hr;
1880     unsigned c1,c2;
1881     static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
1882
1883     DeleteFileA(filenameA);
1884
1885     hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1886     ok(hr==S_OK, "StgCreateDocfile failed\n");
1887
1888     if (SUCCEEDED(hr))
1889     {
1890         IStorage_Release(stg);
1891
1892         hr = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
1893         ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr);
1894
1895         if (SUCCEEDED(hr))
1896         {
1897             hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2);
1898             ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr);
1899
1900             if (SUCCEEDED(hr))
1901             {
1902                 c1 = IStorage_AddRef(stg);
1903                 ok(c1 == 2, "creating internal storage added references to ancestor\n");
1904                 c1 = IStorage_AddRef(stg);
1905                 IStorage_Release(stg2);
1906                 c2 = IStorage_AddRef(stg) - 1;
1907                 ok(c1 == c2, "releasing internal storage removed references to ancestor\n");
1908             }
1909             c1 = IStorage_Release(stg);
1910             while ( c1 ) c1 = IStorage_Release(stg);
1911         }
1912     }
1913
1914     DeleteFileA(filenameA);
1915 }
1916
1917 /* dest
1918  *  |-StorageA
1919  *  |  `StreamA: "StreamA"
1920  *  |-StorageB
1921  *  |  `StreamB: "StreamB"
1922  *  `StreamC: "StreamC"
1923  */
1924 static HRESULT create_test_file(IStorage *dest)
1925 {
1926     IStorage *stgA = NULL, *stgB = NULL;
1927     IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
1928     const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
1929     const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
1930     const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
1931     ULONG bytes;
1932     HRESULT hr;
1933
1934     hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
1935     ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
1936     if(FAILED(hr))
1937         goto cleanup;
1938
1939     hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
1940     ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
1941     if(FAILED(hr))
1942         goto cleanup;
1943
1944     hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
1945     ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
1946
1947     hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
1948     ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
1949     if(FAILED(hr))
1950         goto cleanup;
1951
1952     hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
1953     ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
1954     if(FAILED(hr))
1955         goto cleanup;
1956
1957     hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
1958     ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
1959
1960     hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
1961     ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
1962     if(FAILED(hr))
1963         goto cleanup;
1964
1965     hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
1966     ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
1967
1968 cleanup:
1969     if(strmC)
1970         IStream_Release(strmC);
1971     if(strmB)
1972         IStream_Release(strmB);
1973     if(stgB)
1974         IStorage_Release(stgB);
1975     if(strmA)
1976         IStream_Release(strmA);
1977     if(stgA)
1978         IStorage_Release(stgA);
1979
1980     return hr;
1981 }
1982
1983 static void test_copyto(void)
1984 {
1985     IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
1986     IStream *strm_tmp;
1987     WCHAR buf[64];
1988     HRESULT hr;
1989
1990     /* create & populate file1 */
1991     hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
1992     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
1993     if(FAILED(hr))
1994         goto cleanup;
1995
1996     hr = create_test_file(file1);
1997     if(FAILED(hr))
1998         goto cleanup;
1999
2000     /* create file2 */
2001     hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2002     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2003     if(FAILED(hr))
2004         goto cleanup;
2005
2006     /* copy file1 into file2 */
2007     hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2008     ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2009
2010     hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2011     ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2012     if(FAILED(hr))
2013         goto cleanup;
2014
2015     /* verify that all of file1 was copied */
2016     hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2017             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2018     ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2019
2020     if(SUCCEEDED(hr)){
2021         hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2022                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2023         ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2024
2025         if(SUCCEEDED(hr)){
2026             memset(buf, 0, sizeof(buf));
2027             hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2028             ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2029             if(SUCCEEDED(hr))
2030                 ok(lstrcmpW(buf, strmA_name) == 0,
2031                         "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2032
2033             IStream_Release(strm_tmp);
2034         }
2035
2036         IStorage_Release(stg_tmp);
2037     }
2038
2039     hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2040             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2041     ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2042
2043     if(SUCCEEDED(hr)){
2044         hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2045                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2046         ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2047
2048         if(SUCCEEDED(hr)){
2049             memset(buf, 0, sizeof(buf));
2050             hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2051             ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2052             if(SUCCEEDED(hr))
2053                 ok(lstrcmpW(buf, strmB_name) == 0,
2054                         "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2055
2056             IStream_Release(strm_tmp);
2057         }
2058
2059         IStorage_Release(stg_tmp);
2060     }
2061
2062     hr = IStorage_OpenStream(file2, strmC_name, NULL,
2063             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2064     ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2065
2066     if(SUCCEEDED(hr)){
2067         memset(buf, 0, sizeof(buf));
2068         hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2069         ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2070         if(SUCCEEDED(hr))
2071             ok(lstrcmpW(buf, strmC_name) == 0,
2072                     "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2073
2074         IStream_Release(strm_tmp);
2075     }
2076
2077 cleanup:
2078     if(file1)
2079         IStorage_Release(file1);
2080     if(file2)
2081         IStorage_Release(file2);
2082
2083     DeleteFileW(file1_name);
2084     DeleteFileW(file2_name);
2085 }
2086
2087 static void test_copyto_snbexclusions(void)
2088 {
2089     static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2090
2091     IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2092     IStream *strm_tmp;
2093     WCHAR buf[64];
2094     HRESULT hr;
2095
2096     /* create & populate file1 */
2097     hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2098     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2099     if(FAILED(hr))
2100         goto cleanup;
2101
2102     hr = create_test_file(file1);
2103     if(FAILED(hr))
2104         goto cleanup;
2105
2106     /* create file2 */
2107     hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2108     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2109     if(FAILED(hr))
2110         goto cleanup;
2111
2112     /* copy file1 to file2 with name exclusions */
2113     hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2114     ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2115     if(FAILED(hr))
2116         goto cleanup;
2117
2118     /* verify that file1 copied over, respecting exclusions */
2119     hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2120             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2121     ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2122     if(SUCCEEDED(hr))
2123         IStorage_Release(stg_tmp);
2124
2125     hr = IStorage_OpenStream(file2, strmA_name, NULL,
2126             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2127     ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2128     if(SUCCEEDED(hr))
2129         IStream_Release(strm_tmp);
2130
2131     hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2132             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2133     ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2134
2135     if(SUCCEEDED(hr)){
2136         hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2137                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2138         ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2139
2140         if(SUCCEEDED(hr)){
2141             memset(buf, 0, sizeof(buf));
2142             hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2143             ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2144             if(SUCCEEDED(hr))
2145                 ok(lstrcmpW(buf, strmB_name) == 0,
2146                         "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2147
2148             IStream_Release(strm_tmp);
2149         }
2150
2151         IStorage_Release(stg_tmp);
2152     }
2153
2154     hr = IStorage_OpenStream(file2, strmC_name, NULL,
2155             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2156     ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2157     if(SUCCEEDED(hr))
2158         IStream_Release(strm_tmp);
2159
2160 cleanup:
2161     if(file1)
2162         IStorage_Release(file1);
2163     if(file2)
2164         IStorage_Release(file2);
2165
2166     DeleteFileW(file1_name);
2167     DeleteFileW(file2_name);
2168 }
2169
2170 static void test_copyto_iidexclusions_storage(void)
2171 {
2172     IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2173     IStream *strm_tmp;
2174     WCHAR buf[64];
2175     HRESULT hr;
2176
2177     /* create & populate file1 */
2178     hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2179     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2180     if(FAILED(hr))
2181         goto cleanup;
2182
2183     hr = create_test_file(file1);
2184     if(FAILED(hr))
2185         goto cleanup;
2186
2187     /* create file2 */
2188     hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2189     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2190     if(FAILED(hr))
2191         goto cleanup;
2192
2193     /* copy file1 to file2 with iid exclusions */
2194     hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2195     ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2196     if(FAILED(hr))
2197         goto cleanup;
2198
2199     /* verify that file1 copied over, respecting exclusions */
2200     hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2201             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2202     ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2203     if(SUCCEEDED(hr))
2204         IStorage_Release(stg_tmp);
2205
2206     hr = IStorage_OpenStream(file2, strmA_name, NULL,
2207             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2208     ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2209     if(SUCCEEDED(hr))
2210         IStream_Release(strm_tmp);
2211
2212     hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2213             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2214     ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2215     if(SUCCEEDED(hr))
2216         IStorage_Release(stg_tmp);
2217
2218     hr = IStorage_OpenStream(file2, strmB_name, NULL,
2219             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2220     ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2221     if(SUCCEEDED(hr))
2222         IStream_Release(strm_tmp);
2223
2224     hr = IStorage_OpenStream(file2, strmC_name, NULL,
2225             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2226     ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2227
2228     if(SUCCEEDED(hr)){
2229         memset(buf, 0, sizeof(buf));
2230         hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2231         ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2232         if(SUCCEEDED(hr))
2233             ok(lstrcmpW(buf, strmC_name) == 0,
2234                     "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2235
2236         IStream_Release(strm_tmp);
2237     }
2238
2239 cleanup:
2240     if(file1)
2241         IStorage_Release(file1);
2242     if(file2)
2243         IStorage_Release(file2);
2244
2245     DeleteFileW(file1_name);
2246     DeleteFileW(file2_name);
2247 }
2248
2249 static void test_copyto_iidexclusions_stream(void)
2250 {
2251     IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2252     IStream *strm_tmp;
2253     HRESULT hr;
2254
2255     /* create & populate file1 */
2256     hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2257     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2258     if(FAILED(hr))
2259         goto cleanup;
2260
2261     hr = create_test_file(file1);
2262     if(FAILED(hr))
2263         goto cleanup;
2264
2265     /* create file2 */
2266     hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2267     ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2268     if(FAILED(hr))
2269         goto cleanup;
2270
2271     /* copy file1 to file2 with iid exclusions */
2272     hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2273     ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2274     if(FAILED(hr))
2275         goto cleanup;
2276
2277     /* verify that file1 copied over, respecting exclusions */
2278     hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2279             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2280     ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2281
2282     if(SUCCEEDED(hr)){
2283         hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2284                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2285         ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2286         if(SUCCEEDED(hr))
2287             IStream_Release(strm_tmp);
2288
2289         IStorage_Release(stg_tmp);
2290     }
2291
2292     hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2293             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2294     ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2295
2296     if(SUCCEEDED(hr)){
2297         hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2298                 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2299         ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2300         if(SUCCEEDED(hr))
2301             IStream_Release(strm_tmp);
2302
2303         IStorage_Release(stg_tmp);
2304     }
2305
2306     hr = IStorage_OpenStream(file2, strmC_name, NULL,
2307             STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2308     ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2309     if(SUCCEEDED(hr))
2310         IStream_Release(strm_tmp);
2311
2312 cleanup:
2313     if(file1)
2314         IStorage_Release(file1);
2315     if(file2)
2316         IStorage_Release(file2);
2317
2318     DeleteFileW(file1_name);
2319     DeleteFileW(file2_name);
2320 }
2321
2322 START_TEST(storage32)
2323 {
2324     CHAR temp[MAX_PATH];
2325
2326     GetTempPathA(MAX_PATH, temp);
2327     if(!GetTempFileNameA(temp, "stg", 0, filenameA))
2328     {
2329         win_skip("Could not create temp file, %u\n", GetLastError());
2330         return;
2331     }
2332     MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
2333     DeleteFileA(filenameA);
2334
2335     test_hglobal_storage_stat();
2336     test_create_storage_modes();
2337     test_storage_stream();
2338     test_open_storage();
2339     test_storage_suminfo();
2340     test_storage_refcount();
2341     test_streamenum();
2342     test_transact();
2343     test_substorage_share();
2344     test_revert();
2345     test_nonroot_transacted();
2346     test_ReadClassStm();
2347     test_access();
2348     test_writeclassstg();
2349     test_readonly();
2350     test_simple();
2351     test_fmtusertypestg();
2352     test_references();
2353     test_copyto();
2354     test_copyto_snbexclusions();
2355     test_copyto_iidexclusions_storage();
2356     test_copyto_iidexclusions_stream();
2357 }