janitorial: Remove remaining NULL checks before free() (found by Smatch).
[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 static void test_hglobal_storage_stat(void)
35 {
36     ILockBytes *ilb = NULL;
37     IStorage *stg = NULL;
38     HRESULT r;
39     STATSTG stat;
40     DWORD mode, refcount;
41
42     r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
43     ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
44
45     mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
46     r = StgCreateDocfileOnILockBytes( ilb, mode, 0,  &stg );
47     ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
48
49     r = WriteClassStg( stg, &test_stg_cls );
50     ok( r == S_OK, "WriteClassStg failed\n");
51
52     memset( &stat, 0, sizeof stat );
53     r = IStorage_Stat( stg, &stat, 0 );
54
55     ok( stat.pwcsName == NULL, "storage name not null\n");
56     ok( stat.type == 1, "type is wrong\n");
57     ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
58     ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
59
60     refcount = IStorage_Release( stg );
61     ok( refcount == 0, "IStorage refcount is wrong\n");
62     refcount = ILockBytes_Release( ilb );
63     ok( refcount == 0, "ILockBytes refcount is wrong\n");
64 }
65
66 static void test_create_storage_modes(void)
67 {
68    static const WCHAR szPrefix[] = { 's','t','g',0 };
69    static const WCHAR szDot[] = { '.',0 };
70    WCHAR filename[MAX_PATH];
71    IStorage *stg = NULL;
72    HRESULT r;
73
74    if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
75       return;
76
77    DeleteFileW(filename);
78
79    /* test with some invalid parameters */
80    r = StgCreateDocfile( NULL, 0, 0, &stg);
81    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
82    r = StgCreateDocfile( filename, 0, 0, &stg);
83    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
84    r = StgCreateDocfile( filename, STGM_CREATE, 0, &stg);
85    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
86    r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE, 0, &stg);
87    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
88    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
89    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
90    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
91    ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
92    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
93    ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
94    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
95    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
96    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
97    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
98    r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
99    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
100
101    /* StgCreateDocfile seems to be very particular about the flags it accepts */
102    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
103    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
104    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
105    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
106    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
107    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
108    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
109    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
110    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
111    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
112    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
113    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
114    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
115    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
116    ok(stg == NULL, "stg was set\n");
117
118    /* check what happens if the file already exists (which is how it's meant to be used) */
119    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
120    ok(r==S_OK, "StgCreateDocfile failed\n");
121    r = IStorage_Release(stg);
122    ok(r == 0, "storage not released\n");
123    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
124    ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
125    r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
126    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
127    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE, 0, &stg);
128    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
129    r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE, 0, &stg);
130    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
131    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE, 0, &stg);
132    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
133    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
134    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
135    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, &stg);
136    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
137    r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_WRITE, 0, &stg);
138    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
139    r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_WRITE, 0, &stg);
140    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
141    r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
142    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
143    r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
144    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
145    ok(DeleteFileW(filename), "failed to delete file\n");
146
147    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
148    ok(r==S_OK, "StgCreateDocfile failed\n");
149    r = IStorage_Release(stg);
150    ok(r == 0, "storage not released\n");
151    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
152    ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
153    r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
154    ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
155
156    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
157    ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
158    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
159    ok(r==S_OK, "StgCreateDocfile failed\n");
160    r = IStorage_Release(stg);
161    ok(r == 0, "storage not released\n");
162    ok(DeleteFileW(filename), "failed to delete file\n");
163
164    /* test the way excel uses StgCreateDocFile */
165    r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
166    ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
167    if(r == S_OK)
168    {
169       r = IStorage_Release(stg);
170       ok(r == 0, "storage not released\n");
171       ok(DeleteFileW(filename), "failed to delete file\n");
172    }
173
174    /* and the way windows media uses it ... */
175    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_NONE | STGM_READWRITE | STGM_TRANSACTED, 0, &stg);
176    ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
177    if (r == S_OK)
178    {
179       r = IStorage_Release(stg);
180       ok(r == 0, "storage not released\n");
181       ok(DeleteFileW(filename), "failed to delete file\n");
182    }
183
184    /* looks like we need STGM_TRANSACTED or STGM_CREATE */
185    r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
186    ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
187    if(r == S_OK)
188    {
189       r = IStorage_Release(stg);
190       ok(r == 0, "storage not released\n");
191       ok(DeleteFileW(filename), "failed to delete file\n");
192    }
193
194    r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg);
195    ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
196    if(r == S_OK)
197    {
198       r = IStorage_Release(stg);
199       ok(r == 0, "storage not released\n");
200       ok(DeleteFileW(filename), "failed to delete file\n");
201    }
202
203    r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
204    ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
205    if(r == S_OK)
206    {
207       r = IStorage_Release(stg);
208       ok(r == 0, "storage not released\n");
209       ok(DeleteFileW(filename), "failed to delete file\n");
210    }
211
212    /* test the way msi uses StgCreateDocfile */
213    r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
214    ok(r==S_OK, "StgCreateDocFile failed\n");
215    r = IStorage_Release(stg);
216    ok(r == 0, "storage not released\n");
217    ok(DeleteFileW(filename), "failed to delete file\n");
218 }
219
220 static void test_storage_stream(void)
221 {
222     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
223     static const WCHAR szPrefix[] = { 's','t','g',0 };
224     static const WCHAR szDot[] = { '.',0 };
225     static const WCHAR longname[] = {
226         'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
227         'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
228     };
229     WCHAR filename[MAX_PATH];
230     IStorage *stg = NULL;
231     HRESULT r;
232     IStream *stm = NULL;
233     ULONG count = 0;
234     LARGE_INTEGER pos;
235     ULARGE_INTEGER p;
236     unsigned char buffer[0x100];
237
238     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
239         return;
240
241     DeleteFileW(filename);
242
243     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
244     ok(r==S_OK, "StgCreateDocfile failed\n");
245
246     /* try create some invalid streams */
247     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, 0, &stm );
248     ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
249     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 1, &stm );
250     ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
251     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, NULL );
252     ok(r==STG_E_INVALIDPOINTER, "IStorage->CreateStream wrong error\n");
253     r = IStorage_CreateStream(stg, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
254     ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error\n");
255     r = IStorage_CreateStream(stg, longname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
256     ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error, got %ld GetLastError()=%ld\n", r, GetLastError());
257     r = IStorage_CreateStream(stg, stmname, STGM_READWRITE, 0, 0, &stm );
258     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
259     r = IStorage_CreateStream(stg, stmname, STGM_READ, 0, 0, &stm );
260     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
261     r = IStorage_CreateStream(stg, stmname, STGM_WRITE, 0, 0, &stm );
262     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
263     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, 0, &stm );
264     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
265     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READ, 0, 0, &stm );
266     ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
267
268     /* now really create a stream and delete it */
269     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
270     ok(r==S_OK, "IStorage->CreateStream failed\n");
271     r = IStream_Release(stm);
272     ok(r == 0, "wrong ref count\n");
273     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
274     ok(r==STG_E_FILEALREADYEXISTS, "IStorage->CreateStream failed\n");
275     r = IStorage_DestroyElement(stg,stmname);
276     ok(r==S_OK, "IStorage->DestroyElement failed\n");
277
278     /* create a stream and write to it */
279     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
280     ok(r==S_OK, "IStorage->CreateStream failed\n");
281
282     r = IStream_Write(stm, NULL, 0, NULL );
283     ok(r==STG_E_INVALIDPOINTER, "IStream->Write wrong error\n");
284     r = IStream_Write(stm, "Hello\n", 0, NULL );
285     ok(r==S_OK, "failed to write stream\n");
286     r = IStream_Write(stm, "Hello\n", 0, &count );
287     ok(r==S_OK, "failed to write stream\n");
288     r = IStream_Write(stm, "Hello\n", 6, &count );
289     ok(r==S_OK, "failed to write stream\n");
290     r = IStream_Commit(stm, STGC_DEFAULT );
291     ok(r==S_OK, "failed to commit stream\n");
292     r = IStream_Commit(stm, STGC_DEFAULT );
293     ok(r==S_OK, "failed to commit stream\n");
294
295     /* seek round a bit, reset the stream size */
296     pos.QuadPart = 0;
297     r = IStream_Seek(stm, pos, 3, &p );
298     ok(r==STG_E_INVALIDFUNCTION, "IStream->Seek returned wrong error\n");
299     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
300     ok(r==S_OK, "failed to seek stream\n");
301     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
302     ok(r==S_OK, "failed to seek stream\n");
303     r = IStream_SetSize(stm,p);
304     ok(r==S_OK, "failed to set pos\n");
305     pos.QuadPart = 10;
306     r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
307     ok(r==S_OK, "failed to seek stream\n");
308     ok(p.QuadPart == 10, "at wrong place\n");
309     pos.QuadPart = 0;
310     r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
311     ok(r==S_OK, "failed to seek stream\n");
312     ok(p.QuadPart == 0, "at wrong place\n");
313     r = IStream_Read(stm, buffer, sizeof buffer, &count );
314     ok(r==S_OK, "failed to set pos\n");
315     ok(count == 0, "read bytes from empty stream\n");
316
317     /* wrap up */
318     r = IStream_Release(stm);
319     ok(r == 0, "wrong ref count\n");
320     r = IStorage_Release(stg);
321     ok(r == 0, "wrong ref count\n");
322     r = DeleteFileW(filename);
323     ok(r, "file should exist\n");
324 }
325
326 static BOOL touch_file(LPCWSTR filename)
327 {
328     HANDLE file;
329
330     file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
331                 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
332     if (file==INVALID_HANDLE_VALUE)
333         return FALSE;
334     CloseHandle(file);
335     return TRUE;
336 }
337
338 static BOOL is_zero_length(LPCWSTR filename)
339 {
340     HANDLE file;
341     DWORD len;
342
343     file = CreateFileW(filename, GENERIC_READ, 0, NULL, 
344                 OPEN_EXISTING, 0, NULL);
345     if (file==INVALID_HANDLE_VALUE)
346         return FALSE;
347     len = GetFileSize(file, NULL);
348     CloseHandle(file);
349     return len == 0;
350 }
351
352 static BOOL is_existing_file(LPCWSTR filename)
353 {
354     HANDLE file;
355
356     file = CreateFileW(filename, GENERIC_READ, 0, NULL,
357                        OPEN_EXISTING, 0, NULL);
358     if (file==INVALID_HANDLE_VALUE)
359         return FALSE;
360     CloseHandle(file);
361     return TRUE;
362 }
363
364 static void test_open_storage(void)
365 {
366     static const WCHAR szPrefix[] = { 's','t','g',0 };
367     static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
368     static const WCHAR szDot[] = { '.',0 };
369     WCHAR filename[MAX_PATH];
370     IStorage *stg = NULL, *stg2 = NULL;
371     HRESULT r;
372     DWORD stgm;
373
374     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
375         return;
376
377     /* try opening a zero length file - it should stay zero length */
378     DeleteFileW(filename);
379     touch_file(filename);
380     stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
381     r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
382     ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
383
384     stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
385     r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
386     ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
387     ok(is_zero_length(filename), "file length changed\n");
388
389     DeleteFileW(filename);
390
391     /* try opening a nonexistent file - it should create it */
392     stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
393     r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
394     ok(r==S_OK, "StgOpenStorage failed: 0x%08lx\n", r);
395     if (r==S_OK) IStorage_Release(stg);
396     ok(is_existing_file(filename), "StgOpenStorage didn't create a file\n");
397     DeleteFileW(filename);
398
399     /* create the file */
400     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
401     ok(r==S_OK, "StgCreateDocfile failed\n");
402     IStorage_Release(stg);
403
404     r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
405     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
406     r = StgOpenStorage( NULL, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
407     ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
408     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, NULL);
409     ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
410     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 1, &stg);
411     ok(r==STG_E_INVALIDPARAMETER, "StgOpenStorage wrong error\n");
412     r = StgOpenStorage( szNonExist, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
413     ok(r==STG_E_FILENOTFOUND, "StgOpenStorage failed\n");
414     r = StgOpenStorage( filename, NULL, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
415     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
416     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
417     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
418     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
419     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
420     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
421     ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
422
423     /* open it for real */
424     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg); /* XLViewer 97/2000 */
425     ok(r==S_OK, "StgOpenStorage failed\n");
426     if(stg)
427     {
428         r = IStorage_Release(stg);
429         ok(r == 0, "wrong ref count\n");
430     }
431
432     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
433     ok(r==S_OK, "StgOpenStorage failed\n");
434     if(stg)
435     {
436         r = IStorage_Release(stg);
437         ok(r == 0, "wrong ref count\n");
438     }
439
440     /* test the way word opens its custom dictionary */
441     r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
442                         STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
443     ok(r==S_OK, "StgOpenStorage failed\n");
444     if(stg)
445     {
446         r = IStorage_Release(stg);
447         ok(r == 0, "wrong ref count\n");
448     }
449
450     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
451     ok(r==S_OK, "StgOpenStorage failed\n");
452     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
453     ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
454     if(stg)
455     {
456         r = IStorage_Release(stg);
457         ok(r == 0, "wrong ref count\n");
458     }
459
460     /* now try write to a storage file we opened read-only */ 
461     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
462     ok(r==S_OK, "StgOpenStorage failed\n");
463     if(stg)
464     { 
465         static const WCHAR stmname[] =  { 'w','i','n','e','t','e','s','t',0};
466         IStream *stm = NULL;
467         IStorage *stg2 = NULL;
468
469         r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
470                                    0, 0, &stm );
471         ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
472         r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
473         ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
474
475         r = IStorage_Release(stg);
476         ok(r == 0, "wrong ref count\n");
477     }
478
479     /* open like visio 2003 */
480     stg = NULL;
481     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
482     ok(r == S_OK, "should succeed\n");
483     if (stg)
484         IStorage_Release(stg);
485
486     /* test other sharing modes with STGM_PRIORITY */
487     stg = NULL;
488     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
489     ok(r == S_OK, "should succeed\n");
490     if (stg)
491         IStorage_Release(stg);
492
493     stg = NULL;
494     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
495     ok(r == S_OK, "should succeed\n");
496     if (stg)
497         IStorage_Release(stg);
498
499     stg = NULL;
500     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_READ, NULL, 0, &stg);
501     ok(r == S_OK, "should succeed\n");
502     if (stg)
503         IStorage_Release(stg);
504
505     /* open like Project 2003 */
506     stg = NULL;
507     r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
508     ok(r == S_OK, "should succeed\n");
509     r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg2);
510     ok(r == S_OK, "should succeed\n");
511     if (stg2)
512         IStorage_Release(stg2);
513     if (stg)
514         IStorage_Release(stg);
515
516     stg = NULL;
517     r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
518     ok(r == STG_E_INVALIDFLAG, "should fail\n");
519
520     r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
521     ok(r == STG_E_INVALIDFLAG, "should fail\n");
522
523     r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
524     ok(r == STG_E_INVALIDFLAG, "should fail\n");
525
526     r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
527     ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
528
529     r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
530     ok(r == STG_E_INVALIDFLAG, "should fail\n");
531
532     r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
533     ok(r == STG_E_INVALIDFLAG, "should fail\n");
534
535     r = DeleteFileW(filename);
536     ok(r, "file didn't exist\n");
537 }
538
539 static void test_storage_suminfo(void)
540 {
541     static const WCHAR szDot[] = { '.',0 };
542     static const WCHAR szPrefix[] = { 's','t','g',0 };
543     WCHAR filename[MAX_PATH];
544     IStorage *stg = NULL;
545     IPropertySetStorage *propset = NULL;
546     IPropertyStorage *ps = NULL;
547     HRESULT r;
548
549     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
550         return;
551
552     DeleteFileW(filename);
553
554     /* create the file */
555     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 
556                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
557     ok(r==S_OK, "StgCreateDocfile failed\n");
558
559     r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
560     ok(r == S_OK, "query interface failed\n");
561
562     /* delete it */
563     r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
564     ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
565
566     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
567                                 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
568     ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
569
570     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
571                                 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
572     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
573
574     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
575                                 STGM_READ, &ps );
576     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
577
578     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
579     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
580
581     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
582                                 STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
583     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
584
585     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
586                                 STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
587     ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
588
589     /* now try really creating a a property set */
590     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
591                                 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
592     ok(r == S_OK, "failed to create property set storage\n");
593
594     if( ps )
595         IPropertyStorage_Release(ps);
596
597     /* now try creating the same thing again */
598     r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
599                                 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
600     ok(r == S_OK, "failed to create property set storage\n");
601     if( ps )
602         IPropertyStorage_Release(ps);
603
604     /* should be able to open it */
605     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
606             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
607     ok(r == S_OK, "open failed\n");
608     if(r == S_OK)
609         IPropertyStorage_Release(ps);
610
611     /* delete it */
612     r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
613     ok(r == S_OK, "failed to delete property set storage\n");
614
615     /* try opening with an invalid FMTID */
616     r = IPropertySetStorage_Open( propset, NULL, 
617             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
618     ok(r == E_INVALIDARG, "open succeeded\n");
619     if(r == S_OK)
620         IPropertyStorage_Release(ps);
621
622     /* try a bad guid */
623     r = IPropertySetStorage_Open( propset, &IID_IStorage, 
624             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
625     ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
626     if(r == S_OK)
627         IPropertyStorage_Release(ps);
628     
629
630     /* try some invalid flags */
631     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
632             STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
633     ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
634     if(r == S_OK)
635         IPropertyStorage_Release(ps);
636
637     /* after deleting it, it should be gone */
638     r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation, 
639             STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
640     ok(r == STG_E_FILENOTFOUND, "open failed\n");
641     if(r == S_OK)
642         IPropertyStorage_Release(ps);
643
644     r = IPropertySetStorage_Release( propset );
645     ok(r == 1, "ref count wrong\n");
646
647     r = IStorage_Release(stg);
648     ok(r == 0, "ref count wrong\n");
649
650     DeleteFileW(filename);
651 }
652
653 static void test_storage_refcount(void)
654 {
655     static const WCHAR szPrefix[] = { 's','t','g',0 };
656     static const WCHAR szDot[] = { '.',0 };
657     WCHAR filename[MAX_PATH];
658     IStorage *stg = NULL;
659     IStorage *stgprio = NULL;
660     HRESULT r;
661     IStream *stm = NULL;
662     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
663     LARGE_INTEGER pos;
664     ULARGE_INTEGER upos;
665     STATSTG stat;
666     char buffer[10];
667
668     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
669         return;
670
671     DeleteFileW(filename);
672
673     /* create the file */
674     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 
675                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
676     ok(r==S_OK, "StgCreateDocfile failed\n");
677
678     r = WriteClassStg( stg, &test_stg_cls );
679     ok( r == S_OK, "WriteClassStg failed\n");
680
681     r = IStorage_Commit( stg, STGC_DEFAULT );
682     ok( r == S_OK, "IStorage_Commit failed\n");
683
684     /* now create a stream */
685     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
686     ok(r==S_OK, "IStorage->CreateStream failed\n");
687
688     r = IStorage_Release( stg );
689     ok (r == 0, "storage not released\n");
690
691     pos.QuadPart = 0;
692     r = IStream_Seek( stm, pos, 0, &upos );
693     ok (r == STG_E_REVERTED, "seek should fail\n");
694
695     r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
696     ok (r == STG_E_REVERTED, "stat should fail\n");
697
698     r = IStream_Write( stm, "Test string", strlen("Test string"), NULL);
699     ok (r == STG_E_REVERTED, "IStream_Write should return STG_E_REVERTED instead of 0x%08lx\n", r);
700
701     r = IStream_Read( stm, buffer, sizeof(buffer), NULL);
702     ok (r == STG_E_REVERTED, "IStream_Read should return STG_E_REVERTED instead of 0x%08lx\n", r);
703
704     r = IStream_Release(stm);
705     ok (r == 0, "stream not released\n");
706
707     /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
708      * StgOpenStorage calls in transacted mode */
709     r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio);
710     ok(r==S_OK, "StgOpenStorage failed with error 0x%08lx\n", r);
711
712     todo_wine {
713     /* non-transacted mode read/write fails */
714     r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
715     ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08lx\n", r);
716     }
717
718     /* non-transacted mode read-only succeeds */
719     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg);
720     ok(r==S_OK, "StgOpenStorage failed with error 0x%08lx\n", r);
721     IStorage_Release(stg);
722
723     r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
724     ok(r==S_OK, "StgOpenStorage failed with error 0x%08lx\n", r);
725     if(stg)
726     {
727         static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
728         static const WCHAR stgname2[] = { 'C','V','_','i','e','w',0 };
729         static const WCHAR stmname2[] = { 'V','a','r','2','D','a','t','a',0 };
730         IStorage *stg2;
731         IStorage *stg3;
732         STATSTG statstg;
733
734         r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
735         ok(r == S_OK, "Stat should have succeded instead of returning 0x%08lx\n", r);
736         ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %ld\n", statstg.type);
737         ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %ld\n", U(statstg.cbSize).LowPart);
738         ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %ld\n", U(statstg.cbSize).HighPart);
739         ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
740             "Statstg grfMode should have been 0x10022 instead of 0x%lx\n", statstg.grfMode);
741         ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %ld\n", statstg.grfLocksSupported);
742         ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
743         ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %ld\n", statstg.grfStateBits);
744         ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %ld\n", statstg.reserved);
745
746         r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
747         ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08lx\n", r);
748
749         r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
750         ok(r == S_OK, "Stat should have succeded instead of returning 0x%08lx\n", r);
751         ok(!lstrcmpW(statstg.pwcsName, stgname),
752             "Statstg pwcsName should have been the name the storage was created with\n");
753         ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %ld\n", statstg.type);
754         ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %ld\n", U(statstg.cbSize).LowPart);
755         ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %ld\n", U(statstg.cbSize).HighPart);
756         ok(statstg.grfMode == STGM_SHARE_EXCLUSIVE,
757             "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%lx\n", statstg.grfMode);
758         ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %ld\n", statstg.grfLocksSupported);
759         ok(IsEqualCLSID(&statstg.clsid, &CLSID_NULL), "Statstg clsid is not CLSID_NULL\n");
760         ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %ld\n", statstg.grfStateBits);
761         ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %ld\n", statstg.reserved);
762         CoTaskMemFree(statstg.pwcsName);
763
764         r = IStorage_CreateStorage( stg2, stgname2, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stg3 );
765         ok(r == STG_E_ACCESSDENIED, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08lx\n", r);
766
767         r = IStorage_CreateStream( stg2, stmname2, STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
768         ok(r == STG_E_ACCESSDENIED, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08lx\n", r);
769
770         IStorage_Release(stg2);
771
772         r = IStorage_Release(stg);
773         ok(r == 0, "wrong ref count\n");
774     }
775     IStorage_Release(stgprio);
776
777     DeleteFileW(filename);
778 }
779
780 static void test_streamenum(void)
781 {
782     static const WCHAR szPrefix[] = { 's','t','g',0 };
783     static const WCHAR szDot[] = { '.',0 };
784     WCHAR filename[MAX_PATH];
785     IStorage *stg = NULL;
786     HRESULT r;
787     IStream *stm = NULL;
788     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
789     STATSTG stat;
790     IEnumSTATSTG *ee = NULL;
791     ULONG count;
792
793     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
794         return;
795
796     DeleteFileW(filename);
797
798     /* create the file */
799     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
800                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
801     ok(r==S_OK, "StgCreateDocfile failed\n");
802
803     r = WriteClassStg( stg, &test_stg_cls );
804     ok( r == S_OK, "WriteClassStg failed\n");
805
806     r = IStorage_Commit( stg, STGC_DEFAULT );
807     ok( r == S_OK, "IStorage_Commit failed\n");
808
809     /* now create a stream */
810     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
811     ok(r==S_OK, "IStorage->CreateStream failed\n");
812
813     r = IStream_Release(stm);
814
815     /* first enum ... should be 1 stream */
816     r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
817     ok(r==S_OK, "IStorage->EnumElements failed\n");
818
819     count = 0xf00;
820     r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
821     ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
822     ok(count == 1, "count wrong\n");
823
824     r = IEnumSTATSTG_Release(ee);
825
826     /* second enum... destroy the stream before reading */
827     r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
828     ok(r==S_OK, "IStorage->EnumElements failed\n");
829
830     r = IStorage_DestroyElement(stg, stmname);
831     ok(r==S_OK, "IStorage->EnumElements failed\n");
832
833     todo_wine {
834     count = 0xf00;
835     r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
836     ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
837     ok(count == 0, "count wrong\n");
838     }
839
840     /* reset and try again */
841     r = IEnumSTATSTG_Reset(ee);
842     ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
843
844     count = 0xf00;
845     r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
846     ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
847     ok(count == 0, "count wrong\n");
848
849     r = IEnumSTATSTG_Release(ee);
850     ok (r == 0, "enum not released\n");
851
852     r = IStorage_Release( stg );
853     ok (r == 0, "storage not released\n");
854
855     DeleteFileW(filename);
856 }
857
858 static void test_transact(void)
859 {
860     static const WCHAR szPrefix[] = { 's','t','g',0 };
861     static const WCHAR szDot[] = { '.',0 };
862     WCHAR filename[MAX_PATH];
863     IStorage *stg = NULL;
864     HRESULT r;
865     IStream *stm = NULL;
866     static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
867
868     if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
869         return;
870
871     DeleteFileW(filename);
872
873     /* create the file */
874     r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 
875                             STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
876     ok(r==S_OK, "StgCreateDocfile failed\n");
877
878     /* now create a stream, but don't commit it */
879     r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
880     ok(r==S_OK, "IStorage->CreateStream failed\n");
881
882     r = IStream_Release(stm);
883
884     IStorage_Release(stg);
885
886     stm = NULL;
887     stg = NULL;
888     r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
889     ok(r==S_OK, "StgOpenStorage failed\n");
890
891     if (!stg)
892         return;
893
894     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
895     ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08lx\n", r);
896
897     r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
898     ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08lx\n", r);
899
900     r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
901     ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08lx\n", r);
902
903     todo_wine {
904     r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
905     ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08lx\n", r);
906     }
907
908     if (stm)
909         r = IStream_Release(stm);
910     IStorage_Release(stg);
911
912     r = DeleteFileW(filename);
913     ok( r == TRUE, "deleted file\n");
914 }
915
916 START_TEST(storage32)
917 {
918     test_hglobal_storage_stat();
919     test_create_storage_modes();
920     test_storage_stream();
921     test_open_storage();
922     test_storage_suminfo();
923     test_storage_refcount();
924     test_streamenum();
925     test_transact();
926 }