push 8b07bf1f08b23b9893a622b47d2be359556765b1
[wine/hacks.git] / dlls / ole32 / tests / storage32.c
blob5ec51cfb516a3c2d882925a25e5239784b5f879b
1 /*
2 * Unit tests for OLE storage
4 * Copyright (c) 2004 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdio.h>
23 #define COBJMACROS
25 #include <windows.h>
26 #include "wine/test.h"
28 #include "ole2.h"
29 #include "objidl.h"
30 #include "initguid.h"
32 DEFINE_GUID( test_stg_cls, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0);
34 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
36 static CHAR filenameA[MAX_PATH];
37 static WCHAR filename[MAX_PATH];
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};
47 static void test_hglobal_storage_stat(void)
49 ILockBytes *ilb = NULL;
50 IStorage *stg = NULL;
51 HRESULT r;
52 STATSTG stat;
53 DWORD mode, refcount;
55 r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
56 ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
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");
62 r = WriteClassStg( stg, &test_stg_cls );
63 ok( r == S_OK, "WriteClassStg failed\n");
65 memset( &stat, 0, sizeof stat );
66 r = IStorage_Stat( stg, &stat, 0 );
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");
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");
79 static void test_create_storage_modes(void)
81 IStorage *stg = NULL;
82 HRESULT r;
84 DeleteFileA(filenameA);
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");
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");
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");
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");
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");
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");
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)
182 r = IStorage_Release(stg);
183 ok(r == 0, "storage not released\n");
184 ok(DeleteFileA(filenameA), "failed to delete file\n");
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)
192 r = IStorage_Release(stg);
193 ok(r == 0, "storage not released\n");
194 ok(DeleteFileA(filenameA), "failed to delete file\n");
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)
202 r = IStorage_Release(stg);
203 ok(r == 0, "storage not released\n");
204 ok(DeleteFileA(filenameA), "failed to delete file\n");
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)
211 r = IStorage_Release(stg);
212 ok(r == 0, "storage not released\n");
213 ok(DeleteFileA(filenameA), "failed to delete file\n");
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)
220 r = IStorage_Release(stg);
221 ok(r == 0, "storage not released\n");
222 ok(DeleteFileA(filenameA), "failed to delete file\n");
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");
233 static void test_storage_stream(void)
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
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];
249 DeleteFileA(filenameA);
251 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
252 ok(r==S_OK, "StgCreateDocfile failed\n");
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");
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");
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");
291 r = IStream_Clone(stm, &stm2);
292 ok(r==S_OK, "failed to clone stream\n");
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");
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");
329 /* wrap up */
330 r = IStream_Release(stm2);
331 ok(r == 0, "wrong ref count\n");
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");
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);
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");
345 r = IStorage_Release(stg);
346 ok(r == 0, "wrong ref count\n");
347 r = DeleteFileA(filenameA);
348 ok(r, "file should exist\n");
351 static BOOL touch_file(LPCSTR filename)
353 HANDLE file;
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;
363 static BOOL is_zero_length(LPCSTR filename)
365 HANDLE file;
366 DWORD len;
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;
377 static BOOL is_existing_file(LPCSTR filename)
379 HANDLE file;
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;
389 static void test_open_storage(void)
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;
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");
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");
408 DeleteFileA(filenameA);
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);
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);
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");
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)
447 r = IStorage_Release(stg);
448 ok(r == 0, "wrong ref count\n");
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)
455 r = IStorage_Release(stg);
456 ok(r == 0, "wrong ref count\n");
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)
465 r = IStorage_Release(stg);
466 ok(r == 0, "wrong ref count\n");
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)
475 r = IStorage_Release(stg);
476 ok(r == 0, "wrong ref count\n");
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)
484 static const WCHAR stmname[] = { 'w','i','n','e','t','e','s','t',0};
485 IStream *stm = NULL;
486 IStorage *stg2 = NULL;
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");
494 r = IStorage_Release(stg);
495 ok(r == 0, "wrong ref count\n");
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);
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);
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);
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);
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);
535 stg = NULL;
536 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
537 ok(r == STG_E_INVALIDFLAG, "should fail\n");
539 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
540 ok(r == STG_E_INVALIDFLAG, "should fail\n");
542 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
543 ok(r == STG_E_INVALIDFLAG, "should fail\n");
545 r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
546 ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
548 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
549 ok(r == STG_E_INVALIDFLAG, "should fail\n");
551 r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
552 ok(r == STG_E_INVALIDFLAG, "should fail\n");
554 r = DeleteFileA(filenameA);
555 ok(r, "file didn't exist\n");
558 static void test_storage_suminfo(void)
560 IStorage *stg = NULL;
561 IPropertySetStorage *propset = NULL;
562 IPropertyStorage *ps = NULL;
563 HRESULT r;
565 DeleteFileA(filenameA);
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");
572 r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
573 ok(r == S_OK, "query interface failed\n");
575 /* delete it */
576 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
577 ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
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");
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");
587 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
588 STGM_READ, &ps );
589 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
591 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
592 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
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");
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");
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");
607 if( ps )
608 IPropertyStorage_Release(ps);
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);
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);
624 /* delete it */
625 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
626 ok(r == S_OK, "failed to delete property set storage\n");
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);
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);
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);
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);
657 r = IPropertySetStorage_Release( propset );
658 ok(r == 1, "ref count wrong\n");
660 r = IStorage_Release(stg);
661 ok(r == 0, "ref count wrong\n");
663 DeleteFileA(filenameA);
666 static void test_storage_refcount(void)
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];
678 DeleteFileA(filenameA);
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");
685 r = WriteClassStg( stg, &test_stg_cls );
686 ok( r == S_OK, "WriteClassStg failed\n");
688 r = IStorage_Commit( stg, STGC_DEFAULT );
689 ok( r == S_OK, "IStorage_Commit failed\n");
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");
695 r = IStorage_Release( stg );
696 ok (r == 0, "storage not released\n");
698 pos.QuadPart = 0;
699 r = IStream_Seek( stm, pos, 0, &upos );
700 ok (r == STG_E_REVERTED, "seek should fail\n");
702 r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
703 ok (r == STG_E_REVERTED, "stat should fail\n");
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);
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);
711 r = IStream_Release(stm);
712 ok (r == 0, "stream not released\n");
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);
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);
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);
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)
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;
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);
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);
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);
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);
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);
777 IStorage_Release(stg2);
779 r = IStorage_Release(stg);
780 ok(r == 0, "wrong ref count\n");
782 IStorage_Release(stgprio);
784 DeleteFileA(filenameA);
787 static void test_writeclassstg(void)
789 IStorage *stg = NULL;
790 HRESULT r;
791 CLSID temp_cls;
793 DeleteFileA(filenameA);
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");
800 r = ReadClassStg( NULL, NULL );
801 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
803 r = ReadClassStg( stg, NULL );
804 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
806 temp_cls.Data1 = 0xdeadbeef;
807 r = ReadClassStg( stg, &temp_cls );
808 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
810 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
812 r = WriteClassStg( NULL, NULL );
813 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
815 r = WriteClassStg( stg, NULL );
816 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
818 r = WriteClassStg( stg, &test_stg_cls );
819 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
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");
825 r = IStorage_Release( stg );
826 ok (r == 0, "storage not released\n");
828 DeleteFileA(filenameA);
831 static void test_streamenum(void)
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;
841 DeleteFileA(filenameA);
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");
848 r = WriteClassStg( stg, &test_stg_cls );
849 ok( r == S_OK, "WriteClassStg failed\n");
851 r = IStorage_Commit( stg, STGC_DEFAULT );
852 ok( r == S_OK, "IStorage_Commit failed\n");
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");
858 r = IStream_Release(stm);
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");
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");
869 r = IEnumSTATSTG_Release(ee);
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");
875 r = IStorage_DestroyElement(stg, stmname);
876 ok(r==S_OK, "IStorage->EnumElements failed\n");
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");
885 /* reset and try again */
886 r = IEnumSTATSTG_Reset(ee);
887 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
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");
894 r = IEnumSTATSTG_Release(ee);
895 ok (r == 0, "enum not released\n");
897 r = IStorage_Release( stg );
898 ok (r == 0, "storage not released\n");
900 DeleteFileA(filenameA);
903 static void test_transact(void)
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 };
913 DeleteFileA(filenameA);
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");
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");
924 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
925 ok(r==S_OK, "IStream->Write failed\n");
927 IStream_Release(stm);
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);
932 if (r == S_OK)
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);
938 if (r == S_OK)
939 IStorage_Release(stg3);
941 r = IStorage_Commit(stg, 0);
942 ok(r==S_OK, "IStorage->Commit failed\n");
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);
947 if (r == S_OK)
948 IStorage_Release(stg3);
950 IStorage_Release(stg2);
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");
958 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
959 ok(r==S_OK, "IStream->Write failed\n");
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");
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);
968 if (r == S_OK)
969 IStorage_Release(stg2);
971 IStream_Release(stm);
973 IStorage_Release(stg);
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");
980 if (!stg)
981 return;
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);
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);
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);
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);
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);
999 if (r == S_OK)
1000 IStream_Release(stm);
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);
1006 if (r == S_OK)
1007 IStorage_Release(stg2);
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);
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);
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)
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);
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);
1031 IStorage_Release(stg2);
1034 IStorage_Release(stg);
1036 r = DeleteFileA(filenameA);
1037 ok( r == TRUE, "deleted file\n");
1040 static void test_substorage_share(void)
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 };
1048 DeleteFileA(filenameA);
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");
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);
1059 if (r == S_OK)
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);
1064 if (r == S_OK)
1065 IStorage_Release(stg3);
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);
1070 if (r == S_OK)
1071 IStorage_Release(stg3);
1073 #if 0
1074 /* This crashes on Wine. */
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);
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);
1083 if (r == S_OK)
1084 IStorage_Release(stm);
1085 #endif
1087 IStorage_Release(stg2);
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);
1094 if (r == S_OK)
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);
1099 if (r == S_OK)
1100 IStorage_Release(stm2);
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);
1105 if (r == S_OK)
1106 IStorage_Release(stm2);
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);
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);
1115 IStorage_Release(stm);
1118 IStorage_Release(stg);
1120 r = DeleteFileA(filenameA);
1121 ok( r == TRUE, "deleted file\n");
1124 static void test_revert(void)
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;
1135 DeleteFileA(filenameA);
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");
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");
1146 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1147 ok(r==S_OK, "IStream->Write failed\n");
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);
1152 if (r == S_OK)
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);
1158 if (r == S_OK)
1159 IStorage_Release(stg3);
1161 r = IStorage_Commit(stg, 0);
1162 ok(r==S_OK, "IStorage->Commit failed\n");
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);
1167 if (r == S_OK)
1168 IStorage_Release(stg3);
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");
1175 r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1176 ok(r==S_OK, "IStream->Write failed\n");
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);
1181 r = IStorage_Revert(stg);
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);
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);
1191 r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1192 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1194 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1195 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1198 IStream_Release(stm);
1199 IStream_Release(stm2);
1200 IStorage_Release(stg2);
1201 IStorage_Release(stg3);
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);
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);
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);
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);
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);
1219 if (r == S_OK)
1220 IStream_Release(stm);
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);
1226 if (r == S_OK)
1227 IStorage_Release(stg2);
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);
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);
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)
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);
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);
1251 IStorage_Release(stg2);
1254 IStorage_Release(stg);
1256 r = DeleteFileA(filenameA);
1257 ok( r == TRUE, "deleted file\n");
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");
1264 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1265 ok(r==S_OK, "IStorage->CreateStream failed\n");
1267 r = IStorage_Revert(stg);
1268 todo_wine ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1270 r = IStream_Write(stm, "this works\n", 11, NULL);
1271 ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1273 IStream_Release(stm);
1274 IStream_Release(stg);
1276 r = DeleteFileA(filenameA);
1277 ok( r == TRUE, "deleted file\n");
1280 static void test_nonroot_transacted(void)
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 };
1289 DeleteFileA(filenameA);
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");
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);
1300 if (r == S_OK)
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);
1308 IStorage_Commit(stg2, 0);
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);
1316 IStorage_Revert(stg2);
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);
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);
1329 IStorage_Release(stg2);
1332 IStream_Release(stg);
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");
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);
1343 if (r == S_OK)
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);
1351 IStorage_Commit(stg2, 0);
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);
1359 IStorage_Revert(stg2);
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);
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);
1372 IStorage_Release(stg2);
1375 IStream_Release(stg);
1377 r = DeleteFileA(filenameA);
1378 ok( r == TRUE, "deleted file\n");
1381 static void test_ReadClassStm(void)
1383 CLSID clsid;
1384 HRESULT hr;
1385 IStream *pStream;
1386 static const LARGE_INTEGER llZero;
1388 hr = ReadClassStm(NULL, &clsid);
1389 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
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");
1396 hr = ReadClassStm(pStream, NULL);
1397 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
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");
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");
1411 struct access_res
1413 BOOL gothandle;
1414 DWORD lasterr;
1415 BOOL ignore;
1418 static const struct access_res create[16] =
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 }
1438 static const struct access_res create_commit[16] =
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 }
1458 static const struct access_res create_close[16] =
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 }
1478 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1480 DWORD access = 0, share = 0;
1481 DWORD lasterr;
1482 HANDLE hfile;
1483 int i, j, idx = 0;
1485 for (i = 0; i < 4; i++)
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;
1492 for (j = 0; j < 4; j++)
1494 if (ares[idx].ignore)
1495 continue;
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;
1502 SetLastError(0xdeadbeef);
1503 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
1504 FILE_ATTRIBUTE_NORMAL, 0);
1505 lasterr = GetLastError();
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));
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);
1517 CloseHandle(hfile);
1518 idx++;
1523 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1525 static void test_access(void)
1527 IStorage *stg;
1528 HRESULT hr;
1530 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1532 /* STGM_TRANSACTED */
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);
1538 test_file_access("winetest", create);
1540 hr = IStorage_Commit(stg, STGC_DEFAULT);
1541 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1543 test_file_access("winetest", create_commit);
1545 IStorage_Release(stg);
1547 test_file_access("winetest", create_close);
1549 DeleteFileA("winetest");
1551 /* STGM_DIRECT */
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);
1557 test_file_access("winetest", create);
1559 hr = IStorage_Commit(stg, STGC_DEFAULT);
1560 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1562 test_file_access("winetest", create_commit);
1564 IStorage_Release(stg);
1566 test_file_access("winetest", create_close);
1568 DeleteFileA("winetest");
1570 /* STGM_SHARE_DENY_NONE */
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);
1576 test_file_access("winetest", create);
1578 hr = IStorage_Commit(stg, STGC_DEFAULT);
1579 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1581 test_file_access("winetest", create_commit);
1583 IStorage_Release(stg);
1585 test_file_access("winetest", create_close);
1587 DeleteFileA("winetest");
1589 /* STGM_SHARE_DENY_READ */
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);
1595 test_file_access("winetest", create);
1597 hr = IStorage_Commit(stg, STGC_DEFAULT);
1598 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1600 test_file_access("winetest", create_commit);
1602 IStorage_Release(stg);
1604 test_file_access("winetest", create_close);
1606 DeleteFileA("winetest");
1608 /* STGM_SHARE_DENY_WRITE */
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);
1614 test_file_access("winetest", create);
1616 hr = IStorage_Commit(stg, STGC_DEFAULT);
1617 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1619 test_file_access("winetest", create_commit);
1621 IStorage_Release(stg);
1623 test_file_access("winetest", create_close);
1625 DeleteFileA("winetest");
1628 static void test_readonly(void)
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};
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))
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))
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);
1651 IStorage_Release(stg);
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))
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))
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);
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);
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);
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);
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);
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);
1695 IStorage_Release(stg2);
1698 IStorage_Release(stg);
1701 DeleteFileA("winetest");
1704 static void test_simple(void)
1706 /* Tests for STGM_SIMPLE mode */
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;
1718 DeleteFileA(filenameA);
1720 r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1721 ok(r == S_OK, "got %08x\n", r);
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);
1728 upos.QuadPart = 6000;
1729 r = IStream_SetSize(stm, upos);
1730 ok(r == S_OK, "got %08x\n", r);
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);
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);
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);
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);
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);
1760 IStream_Release(stm);
1762 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1763 ok(r == S_OK, "got %08x\n", r);
1765 upos.QuadPart = 100;
1766 r = IStream_SetSize(stm, upos);
1767 ok(r == S_OK, "got %08x\n", r);
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);
1773 IStream_Release(stm);
1775 IStorage_Commit(stg, STGC_DEFAULT);
1776 IStorage_Release(stg);
1778 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
1779 if (r == STG_E_INVALIDFLAG)
1781 win_skip("Flag combination is not supported on NT4 and below\n");
1782 DeleteFileA(filenameA);
1783 return;
1785 ok(r == S_OK, "got %08x\n", r);
1787 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1788 ok(r == S_OK, "got %08x\n", r);
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);
1794 IStream_Release(stm);
1796 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1797 ok(r == S_OK, "got %08x\n", r);
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);
1803 IStream_Release(stm);
1806 IStorage_Release(stg);
1808 DeleteFileA(filenameA);
1811 static void test_fmtusertypestg(void)
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};
1820 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1821 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1823 if (SUCCEEDED(hr))
1825 /* try to write the stream */
1826 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
1827 ok(hr == S_OK, "should succeed, res=%x\n", hr);
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))
1834 BOOL found = FALSE;
1835 STATSTG statstg;
1836 DWORD got;
1837 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
1839 if (lstrcmpW(statstg.pwcsName, strmNameW) == 0)
1840 found = TRUE;
1841 else
1842 ok(0, "found unexpected stream or storage\n");
1844 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
1845 IEnumSTATSTG_Release(stat);
1848 /* re-write the stream */
1849 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
1850 ok(hr == S_OK, "should succeed, res=%x\n", hr);
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))
1857 BOOL found = FALSE;
1858 STATSTG statstg;
1859 DWORD got;
1860 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
1862 if (lstrcmpW(statstg.pwcsName, strmNameW) == 0)
1863 found = TRUE;
1864 else
1865 ok(0, "found unexpected stream or storage\n");
1867 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
1868 IEnumSTATSTG_Release(stat);
1871 IStorage_Release(stg);
1872 DeleteFileW( fileW );
1876 static void test_references(void)
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 };
1883 DeleteFileA(filenameA);
1885 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1886 ok(hr==S_OK, "StgCreateDocfile failed\n");
1888 if (SUCCEEDED(hr))
1890 IStorage_Release(stg);
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);
1895 if (SUCCEEDED(hr))
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);
1900 if (SUCCEEDED(hr))
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");
1909 c1 = IStorage_Release(stg);
1910 while ( c1 ) c1 = IStorage_Release(stg);
1915 /* dest
1916 * |-StorageA
1917 * | `StreamA: "StreamA"
1918 * |-StorageB
1919 * | `StreamB: "StreamB"
1920 * `StreamC: "StreamC"
1922 static HRESULT create_test_file(IStorage *dest)
1924 IStorage *stgA = NULL, *stgB = NULL;
1925 IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
1926 const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
1927 const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
1928 const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
1929 ULONG bytes;
1930 HRESULT hr;
1932 hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
1933 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
1934 if(FAILED(hr))
1935 goto cleanup;
1937 hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
1938 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
1939 if(FAILED(hr))
1940 goto cleanup;
1942 hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
1943 ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
1945 hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
1946 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
1947 if(FAILED(hr))
1948 goto cleanup;
1950 hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
1951 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
1952 if(FAILED(hr))
1953 goto cleanup;
1955 hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
1956 ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
1958 hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
1959 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
1960 if(FAILED(hr))
1961 goto cleanup;
1963 hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
1964 ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
1966 cleanup:
1967 if(strmC)
1968 IStream_Release(strmC);
1969 if(strmB)
1970 IStream_Release(strmB);
1971 if(stgB)
1972 IStorage_Release(stgB);
1973 if(strmA)
1974 IStream_Release(strmA);
1975 if(stgA)
1976 IStorage_Release(stgA);
1978 return hr;
1981 static void test_copyto(void)
1983 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
1984 IStream *strm_tmp;
1985 WCHAR buf[64];
1986 HRESULT hr;
1988 /* create & populate file1 */
1989 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
1990 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
1991 if(FAILED(hr))
1992 goto cleanup;
1994 hr = create_test_file(file1);
1995 if(FAILED(hr))
1996 goto cleanup;
1998 /* create file2 */
1999 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2000 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2001 if(FAILED(hr))
2002 goto cleanup;
2004 /* copy file1 into file2 */
2005 hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2006 ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2008 hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2009 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2010 if(FAILED(hr))
2011 goto cleanup;
2013 /* verify that all of file1 was copied */
2014 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2015 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2016 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2018 if(SUCCEEDED(hr)){
2019 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2020 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2021 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2023 if(SUCCEEDED(hr)){
2024 memset(buf, 0, sizeof(buf));
2025 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2026 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2027 if(SUCCEEDED(hr))
2028 ok(lstrcmpW(buf, strmA_name) == 0,
2029 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2031 IStream_Release(strm_tmp);
2034 IStorage_Release(stg_tmp);
2037 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2038 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2039 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2041 if(SUCCEEDED(hr)){
2042 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2043 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2044 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2046 if(SUCCEEDED(hr)){
2047 memset(buf, 0, sizeof(buf));
2048 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2049 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2050 if(SUCCEEDED(hr))
2051 ok(lstrcmpW(buf, strmB_name) == 0,
2052 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2054 IStream_Release(strm_tmp);
2057 IStorage_Release(stg_tmp);
2060 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2061 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2062 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2064 if(SUCCEEDED(hr)){
2065 memset(buf, 0, sizeof(buf));
2066 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2067 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2068 if(SUCCEEDED(hr))
2069 ok(lstrcmpW(buf, strmC_name) == 0,
2070 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2072 IStream_Release(strm_tmp);
2075 cleanup:
2076 if(file1)
2077 IStorage_Release(file1);
2078 if(file2)
2079 IStorage_Release(file2);
2081 DeleteFileW(file1_name);
2082 DeleteFileW(file2_name);
2085 static void test_copyto_snbexclusions(void)
2087 static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2089 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2090 IStream *strm_tmp;
2091 WCHAR buf[64];
2092 HRESULT hr;
2094 /* create & populate file1 */
2095 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2096 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2097 if(FAILED(hr))
2098 goto cleanup;
2100 hr = create_test_file(file1);
2101 if(FAILED(hr))
2102 goto cleanup;
2104 /* create file2 */
2105 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2106 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2107 if(FAILED(hr))
2108 goto cleanup;
2110 /* copy file1 to file2 with name exclusions */
2111 hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2112 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2113 if(FAILED(hr))
2114 goto cleanup;
2116 /* verify that file1 copied over, respecting exclusions */
2117 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2118 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2119 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2120 if(SUCCEEDED(hr))
2121 IStorage_Release(stg_tmp);
2123 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2124 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2125 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2126 if(SUCCEEDED(hr))
2127 IStream_Release(strm_tmp);
2129 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2130 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2131 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2133 if(SUCCEEDED(hr)){
2134 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2135 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2136 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2138 if(SUCCEEDED(hr)){
2139 memset(buf, 0, sizeof(buf));
2140 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2141 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2142 if(SUCCEEDED(hr))
2143 ok(lstrcmpW(buf, strmB_name) == 0,
2144 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2146 IStream_Release(strm_tmp);
2149 IStorage_Release(stg_tmp);
2152 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2153 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2154 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2155 if(SUCCEEDED(hr))
2156 IStream_Release(strm_tmp);
2158 cleanup:
2159 if(file1)
2160 IStorage_Release(file1);
2161 if(file2)
2162 IStorage_Release(file2);
2164 DeleteFileW(file1_name);
2165 DeleteFileW(file2_name);
2168 static void test_copyto_iidexclusions_storage(void)
2170 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2171 IStream *strm_tmp;
2172 WCHAR buf[64];
2173 HRESULT hr;
2175 /* create & populate file1 */
2176 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2177 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2178 if(FAILED(hr))
2179 goto cleanup;
2181 hr = create_test_file(file1);
2182 if(FAILED(hr))
2183 goto cleanup;
2185 /* create file2 */
2186 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2187 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2188 if(FAILED(hr))
2189 goto cleanup;
2191 /* copy file1 to file2 with iid exclusions */
2192 hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2193 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2194 if(FAILED(hr))
2195 goto cleanup;
2197 /* verify that file1 copied over, respecting exclusions */
2198 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2199 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2200 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2201 if(SUCCEEDED(hr))
2202 IStorage_Release(stg_tmp);
2204 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2205 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2206 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2207 if(SUCCEEDED(hr))
2208 IStream_Release(strm_tmp);
2210 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2211 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2212 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2213 if(SUCCEEDED(hr))
2214 IStorage_Release(stg_tmp);
2216 hr = IStorage_OpenStream(file2, strmB_name, NULL,
2217 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2218 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2219 if(SUCCEEDED(hr))
2220 IStream_Release(strm_tmp);
2222 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2223 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2224 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2226 if(SUCCEEDED(hr)){
2227 memset(buf, 0, sizeof(buf));
2228 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2229 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2230 if(SUCCEEDED(hr))
2231 ok(lstrcmpW(buf, strmC_name) == 0,
2232 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2234 IStream_Release(strm_tmp);
2237 cleanup:
2238 if(file1)
2239 IStorage_Release(file1);
2240 if(file2)
2241 IStorage_Release(file2);
2243 DeleteFileW(file1_name);
2244 DeleteFileW(file2_name);
2247 static void test_copyto_iidexclusions_stream(void)
2249 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2250 IStream *strm_tmp;
2251 HRESULT hr;
2253 /* create & populate file1 */
2254 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2255 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2256 if(FAILED(hr))
2257 goto cleanup;
2259 hr = create_test_file(file1);
2260 if(FAILED(hr))
2261 goto cleanup;
2263 /* create file2 */
2264 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2265 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2266 if(FAILED(hr))
2267 goto cleanup;
2269 /* copy file1 to file2 with iid exclusions */
2270 hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2271 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2272 if(FAILED(hr))
2273 goto cleanup;
2275 /* verify that file1 copied over, respecting exclusions */
2276 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2277 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2278 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2280 if(SUCCEEDED(hr)){
2281 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2282 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2283 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2284 if(SUCCEEDED(hr))
2285 IStream_Release(strm_tmp);
2287 IStorage_Release(stg_tmp);
2290 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2291 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2292 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2294 if(SUCCEEDED(hr)){
2295 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2296 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2297 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2298 if(SUCCEEDED(hr))
2299 IStream_Release(strm_tmp);
2301 IStorage_Release(stg_tmp);
2304 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2305 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2306 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2307 if(SUCCEEDED(hr))
2308 IStream_Release(strm_tmp);
2310 cleanup:
2311 if(file1)
2312 IStorage_Release(file1);
2313 if(file2)
2314 IStorage_Release(file2);
2316 DeleteFileW(file1_name);
2317 DeleteFileW(file2_name);
2320 START_TEST(storage32)
2322 CHAR temp[MAX_PATH];
2324 GetTempPathA(MAX_PATH, temp);
2325 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
2327 win_skip("Could not create temp file, %u\n", GetLastError());
2328 return;
2330 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
2331 DeleteFileA(filenameA);
2333 test_hglobal_storage_stat();
2334 test_create_storage_modes();
2335 test_storage_stream();
2336 test_open_storage();
2337 test_storage_suminfo();
2338 test_storage_refcount();
2339 test_streamenum();
2340 test_transact();
2341 test_substorage_share();
2342 test_revert();
2343 test_nonroot_transacted();
2344 test_ReadClassStm();
2345 test_access();
2346 test_writeclassstg();
2347 test_readonly();
2348 test_simple();
2349 test_fmtusertypestg();
2350 test_references();
2351 test_copyto();
2352 test_copyto_snbexclusions();
2353 test_copyto_iidexclusions_storage();
2354 test_copyto_iidexclusions_stream();