push 5b1efc32b5a8acb1d5b5e60584746392dd0c436e
[wine/hacks.git] / dlls / ole32 / tests / storage32.c
blobf89a787c0340ccd8baf736f3df997b4a06def9b3
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 char file1_nameA[] = {'c','o','p','y','t','e','s','t','A',0};
40 static const WCHAR file1_name[] = {'c','o','p','y','t','e','s','t','A',0};
41 static const char file2_nameA[] = {'c','o','p','y','t','e','s','t','B',0};
42 static const WCHAR file2_name[] = {'c','o','p','y','t','e','s','t','B',0};
43 static const WCHAR stgA_name[] = {'S','t','o','r','a','g','e','A',0};
44 static const WCHAR stgB_name[] = {'S','t','o','r','a','g','e','B',0};
45 static const WCHAR strmA_name[] = {'S','t','r','e','a','m','A',0};
46 static const WCHAR strmB_name[] = {'S','t','r','e','a','m','B',0};
47 static const WCHAR strmC_name[] = {'S','t','r','e','a','m','C',0};
49 /* Win9x and WinMe don't have lstrcmpW */
50 static int strcmp_ww(LPCWSTR strw1, LPCWSTR strw2)
52 CHAR stra1[512], stra2[512];
53 WideCharToMultiByte(CP_ACP, 0, strw1, -1, stra1, sizeof(stra1), NULL, NULL);
54 WideCharToMultiByte(CP_ACP, 0, strw2, -1, stra2, sizeof(stra2), NULL, NULL);
55 return lstrcmpA(stra1, stra2);
58 static void test_hglobal_storage_stat(void)
60 ILockBytes *ilb = NULL;
61 IStorage *stg = NULL;
62 HRESULT r;
63 STATSTG stat;
64 DWORD mode, refcount;
66 r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
67 ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
69 mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
70 r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
71 ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
73 r = WriteClassStg( stg, &test_stg_cls );
74 ok( r == S_OK, "WriteClassStg failed\n");
76 memset( &stat, 0, sizeof stat );
77 r = IStorage_Stat( stg, &stat, 0 );
79 ok( stat.pwcsName == NULL, "storage name not null\n");
80 ok( stat.type == 1, "type is wrong\n");
81 ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
82 ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
84 refcount = IStorage_Release( stg );
85 ok( refcount == 0, "IStorage refcount is wrong\n");
86 refcount = ILockBytes_Release( ilb );
87 ok( refcount == 0, "ILockBytes refcount is wrong\n");
90 static void test_create_storage_modes(void)
92 IStorage *stg = NULL;
93 HRESULT r;
95 DeleteFileA(filenameA);
97 /* test with some invalid parameters */
98 r = StgCreateDocfile( NULL, 0, 0, &stg);
99 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
100 r = StgCreateDocfile( filename, 0, 0, &stg);
101 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
102 r = StgCreateDocfile( filename, STGM_CREATE, 0, &stg);
103 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
104 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE, 0, &stg);
105 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
106 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
107 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
108 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
109 ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
110 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
111 ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
112 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
113 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
114 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
115 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
116 r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
117 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
119 /* StgCreateDocfile seems to be very particular about the flags it accepts */
120 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
121 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
122 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
123 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
124 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
125 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
126 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
127 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
128 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
129 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
130 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
131 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
132 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
133 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
134 ok(stg == NULL, "stg was set\n");
136 /* check what happens if the file already exists (which is how it's meant to be used) */
137 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
138 ok(r==S_OK, "StgCreateDocfile failed\n");
139 r = IStorage_Release(stg);
140 ok(r == 0, "storage not released\n");
141 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
142 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
143 r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
144 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
145 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE, 0, &stg);
146 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
147 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE, 0, &stg);
148 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
149 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE, 0, &stg);
150 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
151 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
152 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
153 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, &stg);
154 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
155 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_WRITE, 0, &stg);
156 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
157 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_WRITE, 0, &stg);
158 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
159 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
160 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
161 r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
162 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
163 ok(DeleteFileA(filenameA), "failed to delete file\n");
165 r = StgCreateDocfile( filename, 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 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
170 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
171 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
172 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
174 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
175 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
176 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
177 ok(r==S_OK, "StgCreateDocfile failed\n");
178 r = IStorage_Release(stg);
179 ok(r == 0, "storage not released\n");
180 ok(DeleteFileA(filenameA), "failed to delete file\n");
182 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
183 ok(r==S_OK, "StgCreateDocfile failed\n");
184 r = IStorage_Release(stg);
185 ok(r == 0, "storage not released\n");
186 ok(DeleteFileA(filenameA), "failed to delete file\n");
188 /* test the way excel uses StgCreateDocFile */
189 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
190 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
191 if(r == S_OK)
193 r = IStorage_Release(stg);
194 ok(r == 0, "storage not released\n");
195 ok(DeleteFileA(filenameA), "failed to delete file\n");
198 /* and the way windows media uses it ... */
199 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_NONE | STGM_READWRITE | STGM_TRANSACTED, 0, &stg);
200 ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
201 if (r == S_OK)
203 r = IStorage_Release(stg);
204 ok(r == 0, "storage not released\n");
205 ok(DeleteFileA(filenameA), "failed to delete file\n");
208 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
209 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
210 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
211 if(r == S_OK)
213 r = IStorage_Release(stg);
214 ok(r == 0, "storage not released\n");
215 ok(DeleteFileA(filenameA), "failed to delete file\n");
218 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg);
219 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
220 if(r == S_OK)
222 r = IStorage_Release(stg);
223 ok(r == 0, "storage not released\n");
224 ok(DeleteFileA(filenameA), "failed to delete file\n");
227 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
228 ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
229 if(r == S_OK)
231 r = IStorage_Release(stg);
232 ok(r == 0, "storage not released\n");
233 ok(DeleteFileA(filenameA), "failed to delete file\n");
236 /* test the way msi uses StgCreateDocfile */
237 r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
238 ok(r==S_OK, "StgCreateDocFile failed\n");
239 r = IStorage_Release(stg);
240 ok(r == 0, "storage not released\n");
241 ok(DeleteFileA(filenameA), "failed to delete file\n");
244 static void test_storage_stream(void)
246 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
247 static const WCHAR longname[] = {
248 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
249 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
251 IStorage *stg = NULL;
252 HRESULT r;
253 IStream *stm = NULL;
254 IStream *stm2 = NULL;
255 ULONG count = 0;
256 LARGE_INTEGER pos;
257 ULARGE_INTEGER p;
258 unsigned char buffer[0x100];
260 DeleteFileA(filenameA);
262 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
263 ok(r==S_OK, "StgCreateDocfile failed\n");
265 /* try create some invalid streams */
266 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, 0, &stm );
267 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
268 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 1, &stm );
269 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
270 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, NULL );
271 ok(r==STG_E_INVALIDPOINTER, "IStorage->CreateStream wrong error\n");
272 r = IStorage_CreateStream(stg, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
273 ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error\n");
274 r = IStorage_CreateStream(stg, longname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
275 ok(r==STG_E_INVALIDNAME || broken(r==S_OK) /* nt4 */,
276 "IStorage->CreateStream wrong error, got %d GetLastError()=%d\n", r, GetLastError());
277 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE, 0, 0, &stm );
278 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
279 r = IStorage_CreateStream(stg, stmname, STGM_READ, 0, 0, &stm );
280 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
281 r = IStorage_CreateStream(stg, stmname, STGM_WRITE, 0, 0, &stm );
282 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
283 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, 0, &stm );
284 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
285 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READ, 0, 0, &stm );
286 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
288 /* now really create a stream and delete it */
289 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
290 ok(r==S_OK, "IStorage->CreateStream failed\n");
291 r = IStream_Release(stm);
292 ok(r == 0, "wrong ref count\n");
293 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
294 ok(r==STG_E_FILEALREADYEXISTS, "IStorage->CreateStream failed\n");
295 r = IStorage_DestroyElement(stg,stmname);
296 ok(r==S_OK, "IStorage->DestroyElement failed\n");
298 /* create a stream and write to it */
299 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
300 ok(r==S_OK, "IStorage->CreateStream failed\n");
302 r = IStream_Clone(stm, &stm2);
303 ok(r==S_OK, "failed to clone stream\n");
305 r = IStream_Write(stm, NULL, 0, NULL );
306 ok(r==STG_E_INVALIDPOINTER, "IStream->Write wrong error\n");
307 r = IStream_Write(stm, "Hello\n", 0, NULL );
308 ok(r==S_OK, "failed to write stream\n");
309 r = IStream_Write(stm, "Hello\n", 0, &count );
310 ok(r==S_OK, "failed to write stream\n");
311 r = IStream_Write(stm, "Hello\n", 6, &count );
312 ok(r==S_OK, "failed to write stream\n");
313 r = IStream_Commit(stm, STGC_DEFAULT );
314 ok(r==S_OK, "failed to commit stream\n");
315 r = IStream_Commit(stm, STGC_DEFAULT );
316 ok(r==S_OK, "failed to commit stream\n");
318 /* seek round a bit, reset the stream size */
319 pos.QuadPart = 0;
320 r = IStream_Seek(stm, pos, 3, &p );
321 ok(r==STG_E_INVALIDFUNCTION, "IStream->Seek returned wrong error\n");
322 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
323 ok(r==S_OK, "failed to seek stream\n");
324 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
325 ok(r==S_OK, "failed to seek stream\n");
326 r = IStream_SetSize(stm,p);
327 ok(r==S_OK, "failed to set pos\n");
328 pos.QuadPart = 10;
329 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
330 ok(r==S_OK, "failed to seek stream\n");
331 ok(p.QuadPart == 10, "at wrong place\n");
332 pos.QuadPart = 0;
333 r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
334 ok(r==S_OK, "failed to seek stream\n");
335 ok(p.QuadPart == 0, "at wrong place\n");
336 r = IStream_Read(stm, buffer, sizeof buffer, &count );
337 ok(r==S_OK, "failed to set pos\n");
338 ok(count == 0, "read bytes from empty stream\n");
340 /* wrap up */
341 r = IStream_Release(stm2);
342 ok(r == 0, "wrong ref count\n");
344 /* create a stream and write to it */
345 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
346 ok(r==S_OK, "IStorage->CreateStream failed\n");
348 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p);
349 ok(r==STG_E_REVERTED, "overwritten stream should return STG_E_REVERTED instead of 0x%08x\n", r);
351 r = IStream_Release(stm2);
352 ok(r == 0, "wrong ref count\n");
353 r = IStream_Release(stm);
354 ok(r == 0, "wrong ref count\n");
356 r = IStorage_Release(stg);
357 ok(r == 0, "wrong ref count\n");
358 r = DeleteFileA(filenameA);
359 ok(r, "file should exist\n");
362 static BOOL touch_file(LPCSTR filename)
364 HANDLE file;
366 file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
367 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
368 if (file==INVALID_HANDLE_VALUE)
369 return FALSE;
370 CloseHandle(file);
371 return TRUE;
374 static BOOL is_zero_length(LPCSTR filename)
376 HANDLE file;
377 DWORD len;
379 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
380 OPEN_EXISTING, 0, NULL);
381 if (file==INVALID_HANDLE_VALUE)
382 return FALSE;
383 len = GetFileSize(file, NULL);
384 CloseHandle(file);
385 return len == 0;
388 static BOOL is_existing_file(LPCSTR filename)
390 HANDLE file;
392 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
393 OPEN_EXISTING, 0, NULL);
394 if (file==INVALID_HANDLE_VALUE)
395 return FALSE;
396 CloseHandle(file);
397 return TRUE;
400 static void test_open_storage(void)
402 static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
403 IStorage *stg = NULL, *stg2 = NULL;
404 HRESULT r;
405 DWORD stgm;
407 /* try opening a zero length file - it should stay zero length */
408 DeleteFileA(filenameA);
409 touch_file(filenameA);
410 stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
411 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
412 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
414 stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
415 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
416 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
417 ok(is_zero_length(filenameA), "file length changed\n");
419 DeleteFileA(filenameA);
421 /* try opening a nonexistent file - it should not create it */
422 stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
423 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
424 ok(r!=S_OK, "StgOpenStorage failed: 0x%08x\n", r);
425 if (r==S_OK) IStorage_Release(stg);
426 ok(!is_existing_file(filenameA), "StgOpenStorage should not create a file\n");
427 DeleteFileA(filenameA);
429 /* create the file */
430 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
431 ok(r==S_OK, "StgCreateDocfile failed\n");
432 IStorage_Release(stg);
434 r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
435 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
436 r = StgOpenStorage( NULL, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
437 ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
438 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, NULL);
439 ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
440 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 1, &stg);
441 ok(r==STG_E_INVALIDPARAMETER, "StgOpenStorage wrong error\n");
442 r = StgOpenStorage( szNonExist, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
443 ok(r==STG_E_FILENOTFOUND, "StgOpenStorage failed\n");
444 r = StgOpenStorage( filename, NULL, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
445 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
446 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
447 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
448 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
449 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
450 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
451 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
453 /* open it for real */
454 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg); /* XLViewer 97/2000 */
455 ok(r==S_OK, "StgOpenStorage failed\n");
456 if(stg)
458 r = IStorage_Release(stg);
459 ok(r == 0, "wrong ref count\n");
462 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
463 ok(r==S_OK, "StgOpenStorage failed\n");
464 if(stg)
466 r = IStorage_Release(stg);
467 ok(r == 0, "wrong ref count\n");
470 /* test the way word opens its custom dictionary */
471 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
472 STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
473 ok(r==S_OK, "StgOpenStorage failed\n");
474 if(stg)
476 r = IStorage_Release(stg);
477 ok(r == 0, "wrong ref count\n");
480 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
481 ok(r==S_OK, "StgOpenStorage failed\n");
482 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
483 ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
484 if(stg)
486 r = IStorage_Release(stg);
487 ok(r == 0, "wrong ref count\n");
490 /* now try write to a storage file we opened read-only */
491 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
492 ok(r==S_OK, "StgOpenStorage failed\n");
493 if(stg)
495 static const WCHAR stmname[] = { 'w','i','n','e','t','e','s','t',0};
496 IStream *stm = NULL;
497 IStorage *stg2 = NULL;
499 r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
500 0, 0, &stm );
501 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
502 r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
503 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
505 r = IStorage_Release(stg);
506 ok(r == 0, "wrong ref count\n");
509 /* open like visio 2003 */
510 stg = NULL;
511 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
512 ok(r == S_OK, "should succeed\n");
513 if (stg)
514 IStorage_Release(stg);
516 /* test other sharing modes with STGM_PRIORITY */
517 stg = NULL;
518 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
519 ok(r == S_OK, "should succeed\n");
520 if (stg)
521 IStorage_Release(stg);
523 stg = NULL;
524 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
525 ok(r == S_OK, "should succeed\n");
526 if (stg)
527 IStorage_Release(stg);
529 stg = NULL;
530 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_READ, NULL, 0, &stg);
531 ok(r == S_OK, "should succeed\n");
532 if (stg)
533 IStorage_Release(stg);
535 /* open like Project 2003 */
536 stg = NULL;
537 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
538 ok(r == S_OK, "should succeed\n");
539 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg2);
540 ok(r == S_OK, "should succeed\n");
541 if (stg2)
542 IStorage_Release(stg2);
543 if (stg)
544 IStorage_Release(stg);
546 stg = NULL;
547 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
548 ok(r == STG_E_INVALIDFLAG, "should fail\n");
550 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
551 ok(r == STG_E_INVALIDFLAG, "should fail\n");
553 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
554 ok(r == STG_E_INVALIDFLAG, "should fail\n");
556 r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
557 ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
559 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
560 ok(r == STG_E_INVALIDFLAG, "should fail\n");
562 r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
563 ok(r == STG_E_INVALIDFLAG, "should fail\n");
565 r = DeleteFileA(filenameA);
566 ok(r, "file didn't exist\n");
569 static void test_storage_suminfo(void)
571 IStorage *stg = NULL;
572 IPropertySetStorage *propset = NULL;
573 IPropertyStorage *ps = NULL;
574 HRESULT r;
576 DeleteFileA(filenameA);
578 /* create the file */
579 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
580 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
581 ok(r==S_OK, "StgCreateDocfile failed\n");
583 r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
584 ok(r == S_OK, "query interface failed\n");
586 /* delete it */
587 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
588 ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
590 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
591 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
592 ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
594 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
595 STGM_READ | 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_READ, &ps );
600 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
602 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
603 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
605 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
606 STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
607 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
609 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
610 STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
611 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
613 /* now try really creating a property set */
614 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
615 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
616 ok(r == S_OK, "failed to create property set storage\n");
618 if( ps )
619 IPropertyStorage_Release(ps);
621 /* now try creating the same thing again */
622 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
623 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
624 ok(r == S_OK, "failed to create property set storage\n");
625 if( ps )
626 IPropertyStorage_Release(ps);
628 /* should be able to open it */
629 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
630 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
631 ok(r == S_OK, "open failed\n");
632 if(r == S_OK)
633 IPropertyStorage_Release(ps);
635 /* delete it */
636 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
637 ok(r == S_OK, "failed to delete property set storage\n");
639 /* try opening with an invalid FMTID */
640 r = IPropertySetStorage_Open( propset, NULL,
641 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
642 ok(r == E_INVALIDARG, "open succeeded\n");
643 if(r == S_OK)
644 IPropertyStorage_Release(ps);
646 /* try a bad guid */
647 r = IPropertySetStorage_Open( propset, &IID_IStorage,
648 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
649 ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
650 if(r == S_OK)
651 IPropertyStorage_Release(ps);
654 /* try some invalid flags */
655 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
656 STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
657 ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
658 if(r == S_OK)
659 IPropertyStorage_Release(ps);
661 /* after deleting it, it should be gone */
662 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
663 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
664 ok(r == STG_E_FILENOTFOUND, "open failed\n");
665 if(r == S_OK)
666 IPropertyStorage_Release(ps);
668 r = IPropertySetStorage_Release( propset );
669 ok(r == 1, "ref count wrong\n");
671 r = IStorage_Release(stg);
672 ok(r == 0, "ref count wrong\n");
674 DeleteFileA(filenameA);
677 static void test_storage_refcount(void)
679 IStorage *stg = NULL;
680 IStorage *stgprio = NULL;
681 HRESULT r;
682 IStream *stm = NULL;
683 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
684 LARGE_INTEGER pos;
685 ULARGE_INTEGER upos;
686 STATSTG stat;
687 char buffer[10];
689 DeleteFileA(filenameA);
691 /* create the file */
692 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
693 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
694 ok(r==S_OK, "StgCreateDocfile failed\n");
696 r = WriteClassStg( stg, &test_stg_cls );
697 ok( r == S_OK, "WriteClassStg failed\n");
699 r = IStorage_Commit( stg, STGC_DEFAULT );
700 ok( r == S_OK, "IStorage_Commit failed\n");
702 /* now create a stream */
703 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
704 ok(r==S_OK, "IStorage->CreateStream failed\n");
706 r = IStorage_Release( stg );
707 ok (r == 0, "storage not released\n");
709 pos.QuadPart = 0;
710 r = IStream_Seek( stm, pos, 0, &upos );
711 ok (r == STG_E_REVERTED, "seek should fail\n");
713 r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
714 ok (r == STG_E_REVERTED, "stat should fail\n");
716 r = IStream_Write( stm, "Test string", strlen("Test string"), NULL);
717 ok (r == STG_E_REVERTED, "IStream_Write should return STG_E_REVERTED instead of 0x%08x\n", r);
719 r = IStream_Read( stm, buffer, sizeof(buffer), NULL);
720 ok (r == STG_E_REVERTED, "IStream_Read should return STG_E_REVERTED instead of 0x%08x\n", r);
722 r = IStream_Release(stm);
723 ok (r == 0, "stream not released\n");
725 /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
726 * StgOpenStorage calls in transacted mode */
727 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio);
728 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
730 todo_wine {
731 /* non-transacted mode read/write fails */
732 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
733 ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r);
736 /* non-transacted mode read-only succeeds */
737 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg);
738 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
739 IStorage_Release(stg);
741 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
742 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
743 if(stg)
745 static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
746 static const WCHAR stgname2[] = { 'C','V','_','i','e','w',0 };
747 static const WCHAR stmname2[] = { 'V','a','r','2','D','a','t','a',0 };
748 IStorage *stg2;
749 IStorage *stg3;
750 STATSTG statstg;
752 r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
753 ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
754 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
755 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
756 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
757 ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
758 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg.grfMode);
759 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
760 ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
761 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
762 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
764 r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
765 ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
767 r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
768 ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
769 ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)),
770 "Statstg pwcsName should have been the name the storage was created with\n");
771 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
772 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
773 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
774 ok(statstg.grfMode == STGM_SHARE_EXCLUSIVE,
775 "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%x\n", statstg.grfMode);
776 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
777 ok(IsEqualCLSID(&statstg.clsid, &CLSID_NULL), "Statstg clsid is not CLSID_NULL\n");
778 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
779 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
780 CoTaskMemFree(statstg.pwcsName);
782 r = IStorage_CreateStorage( stg2, stgname2, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stg3 );
783 ok(r == STG_E_ACCESSDENIED, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
785 r = IStorage_CreateStream( stg2, stmname2, STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
786 ok(r == STG_E_ACCESSDENIED, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
788 IStorage_Release(stg2);
790 r = IStorage_Release(stg);
791 ok(r == 0, "wrong ref count\n");
793 IStorage_Release(stgprio);
795 DeleteFileA(filenameA);
798 static void test_writeclassstg(void)
800 IStorage *stg = NULL;
801 HRESULT r;
802 CLSID temp_cls;
804 DeleteFileA(filenameA);
806 /* create the file */
807 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
808 STGM_READWRITE, 0, &stg);
809 ok(r==S_OK, "StgCreateDocfile failed\n");
811 r = ReadClassStg( NULL, NULL );
812 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
814 r = ReadClassStg( stg, NULL );
815 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
817 temp_cls.Data1 = 0xdeadbeef;
818 r = ReadClassStg( stg, &temp_cls );
819 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
821 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
823 r = WriteClassStg( NULL, NULL );
824 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
826 r = WriteClassStg( stg, NULL );
827 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
829 r = WriteClassStg( stg, &test_stg_cls );
830 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
832 r = ReadClassStg( stg, &temp_cls );
833 ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
834 ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
836 r = IStorage_Release( stg );
837 ok (r == 0, "storage not released\n");
839 DeleteFileA(filenameA);
842 static void test_streamenum(void)
844 IStorage *stg = NULL;
845 HRESULT r;
846 IStream *stm = NULL;
847 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
848 STATSTG stat;
849 IEnumSTATSTG *ee = NULL;
850 ULONG count;
852 DeleteFileA(filenameA);
854 /* create the file */
855 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
856 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
857 ok(r==S_OK, "StgCreateDocfile failed\n");
859 r = WriteClassStg( stg, &test_stg_cls );
860 ok( r == S_OK, "WriteClassStg failed\n");
862 r = IStorage_Commit( stg, STGC_DEFAULT );
863 ok( r == S_OK, "IStorage_Commit failed\n");
865 /* now create a stream */
866 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
867 ok(r==S_OK, "IStorage->CreateStream failed\n");
869 r = IStream_Release(stm);
871 /* first enum ... should be 1 stream */
872 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
873 ok(r==S_OK, "IStorage->EnumElements failed\n");
875 count = 0xf00;
876 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
877 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
878 ok(count == 1, "count wrong\n");
880 r = IEnumSTATSTG_Release(ee);
882 /* second enum... destroy the stream before reading */
883 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
884 ok(r==S_OK, "IStorage->EnumElements failed\n");
886 r = IStorage_DestroyElement(stg, stmname);
887 ok(r==S_OK, "IStorage->EnumElements failed\n");
889 todo_wine {
890 count = 0xf00;
891 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
892 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
893 ok(count == 0, "count wrong\n");
896 /* reset and try again */
897 r = IEnumSTATSTG_Reset(ee);
898 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
900 count = 0xf00;
901 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
902 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
903 ok(count == 0, "count wrong\n");
905 r = IEnumSTATSTG_Release(ee);
906 ok (r == 0, "enum not released\n");
908 r = IStorage_Release( stg );
909 ok (r == 0, "storage not released\n");
911 DeleteFileA(filenameA);
914 static void test_transact(void)
916 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
917 HRESULT r;
918 IStream *stm = NULL;
919 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
920 static const WCHAR stmname2[] = { 'F','O','O',0 };
921 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
922 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
924 DeleteFileA(filenameA);
926 /* create the file */
927 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
928 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
929 ok(r==S_OK, "StgCreateDocfile failed\n");
931 /* commit a new stream and storage */
932 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
933 ok(r==S_OK, "IStorage->CreateStream failed\n");
935 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
936 ok(r==S_OK, "IStream->Write failed\n");
938 IStream_Release(stm);
940 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
941 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
943 if (r == S_OK)
945 /* Create two substorages but only commit one */
946 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
947 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
949 if (r == S_OK)
950 IStorage_Release(stg3);
952 r = IStorage_Commit(stg, 0);
953 ok(r==S_OK, "IStorage->Commit failed\n");
955 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
956 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
958 if (r == S_OK)
959 IStorage_Release(stg3);
961 IStorage_Release(stg2);
964 /* now create a stream and storage, but don't commit them */
965 stm = NULL;
966 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
967 ok(r==S_OK, "IStorage->CreateStream failed\n");
969 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
970 ok(r==S_OK, "IStream->Write failed\n");
972 /* IStream::Commit does nothing for OLE storage streams */
973 r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
974 ok(r==S_OK, "IStream->Commit failed\n");
976 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
977 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
979 if (r == S_OK)
980 IStorage_Release(stg2);
982 IStream_Release(stm);
984 IStorage_Release(stg);
986 stm = NULL;
987 stg = NULL;
988 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
989 ok(r==S_OK, "StgOpenStorage failed\n");
991 if (!stg)
992 return;
994 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
995 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
997 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
998 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1000 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1001 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1003 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1004 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1006 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1007 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1008 if (r == S_OK)
1009 IStream_Release(stm);
1011 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1012 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1013 if (r == S_OK)
1014 IStorage_Release(stg2);
1016 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1017 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1019 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1020 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1021 if (r == S_OK)
1022 IStream_Release(stm);
1024 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1025 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1026 if (r == S_OK)
1028 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1029 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1030 if (r == S_OK)
1031 IStorage_Release(stg3);
1033 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1034 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1035 if (r == S_OK)
1036 IStorage_Release(stg3);
1038 IStorage_Release(stg2);
1041 IStorage_Release(stg);
1043 r = DeleteFileA(filenameA);
1044 ok( r == TRUE, "deleted file\n");
1047 static void test_substorage_share(void)
1049 IStorage *stg, *stg2, *stg3;
1050 IStream *stm, *stm2;
1051 HRESULT r;
1052 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1053 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1054 static const WCHAR othername[] = { 'N','E','W','N','A','M','E',0 };
1056 DeleteFileA(filenameA);
1058 /* create the file */
1059 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1060 STGM_READWRITE, 0, &stg);
1061 ok(r==S_OK, "StgCreateDocfile failed\n");
1063 /* create a read/write storage and try to open it again */
1064 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1065 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1067 if (r == S_OK)
1069 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1070 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1072 if (r == S_OK)
1073 IStorage_Release(stg3);
1075 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1076 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1078 if (r == S_OK)
1079 IStorage_Release(stg3);
1081 /* cannot rename the storage while it's open */
1082 r = IStorage_RenameElement(stg, stgname, othername);
1083 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1084 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stgname);
1086 /* destroying an object while it's open invalidates it */
1087 r = IStorage_DestroyElement(stg, stgname);
1088 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1090 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1091 ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r);
1093 if (r == S_OK)
1094 IStorage_Release(stm);
1096 IStorage_Release(stg2);
1099 /* create a read/write stream and try to open it again */
1100 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1101 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
1103 if (r == S_OK)
1105 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1106 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1108 if (r == S_OK)
1109 IStorage_Release(stm2);
1111 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1112 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1114 if (r == S_OK)
1115 IStorage_Release(stm2);
1117 /* cannot rename the stream while it's open */
1118 r = IStorage_RenameElement(stg, stmname, othername);
1119 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1120 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stmname);
1122 /* destroying an object while it's open invalidates it */
1123 r = IStorage_DestroyElement(stg, stmname);
1124 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1126 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1127 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1129 IStorage_Release(stm);
1132 IStorage_Release(stg);
1134 r = DeleteFileA(filenameA);
1135 ok( r == TRUE, "deleted file\n");
1138 static void test_revert(void)
1140 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1141 HRESULT r;
1142 IStream *stm = NULL, *stm2 = NULL;
1143 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1144 static const WCHAR stmname2[] = { 'F','O','O',0 };
1145 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1146 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1147 STATSTG statstg;
1149 DeleteFileA(filenameA);
1151 /* create the file */
1152 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1153 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1154 ok(r==S_OK, "StgCreateDocfile failed\n");
1156 /* commit a new stream and storage */
1157 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1158 ok(r==S_OK, "IStorage->CreateStream failed\n");
1160 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1161 ok(r==S_OK, "IStream->Write failed\n");
1163 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1164 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1166 if (r == S_OK)
1168 /* Create two substorages but only commit one */
1169 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1170 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1172 if (r == S_OK)
1173 IStorage_Release(stg3);
1175 r = IStorage_Commit(stg, 0);
1176 ok(r==S_OK, "IStorage->Commit failed\n");
1178 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1179 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1181 if (r == S_OK)
1182 IStorage_Release(stg3);
1185 /* now create a stream and storage, then revert */
1186 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
1187 ok(r==S_OK, "IStorage->CreateStream failed\n");
1189 r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1190 ok(r==S_OK, "IStream->Write failed\n");
1192 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1193 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1195 r = IStorage_Revert(stg);
1197 /* all open objects become invalid */
1198 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1199 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1201 r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL);
1202 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1204 r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1205 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1207 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1208 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1210 IStream_Release(stm);
1211 IStream_Release(stm2);
1212 IStorage_Release(stg2);
1213 IStorage_Release(stg3);
1215 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1216 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1218 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1219 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1221 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1222 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1224 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1225 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1227 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1228 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1229 if (r == S_OK)
1230 IStream_Release(stm);
1232 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1233 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1234 if (r == S_OK)
1235 IStorage_Release(stg2);
1237 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1238 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1240 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1241 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1242 if (r == S_OK)
1243 IStream_Release(stm);
1245 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1246 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1247 if (r == S_OK)
1249 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1250 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1251 if (r == S_OK)
1252 IStorage_Release(stg3);
1254 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1255 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1256 if (r == S_OK)
1257 IStorage_Release(stg3);
1259 IStorage_Release(stg2);
1262 IStorage_Release(stg);
1264 r = DeleteFileA(filenameA);
1265 ok( r == TRUE, "deleted file\n");
1267 /* Revert only invalidates objects in transacted mode */
1268 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1269 STGM_READWRITE, 0, &stg);
1270 ok(r==S_OK, "StgCreateDocfile failed\n");
1272 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1273 ok(r==S_OK, "IStorage->CreateStream failed\n");
1275 r = IStorage_Revert(stg);
1276 todo_wine ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1278 r = IStream_Write(stm, "this works\n", 11, NULL);
1279 ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1281 IStream_Release(stm);
1282 IStream_Release(stg);
1284 r = DeleteFileA(filenameA);
1285 ok( r == TRUE, "deleted file\n");
1288 static void test_parent_free(void)
1290 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1291 HRESULT r;
1292 IStream *stm = NULL;
1293 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1294 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1295 ULONG ref;
1296 STATSTG statstg;
1298 DeleteFileA(filenameA);
1300 /* create the file */
1301 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1302 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1303 ok(r==S_OK, "StgCreateDocfile failed\n");
1305 /* create a new storage */
1306 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1307 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1309 if (r == S_OK)
1311 /* now create a stream inside the new storage */
1312 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1313 ok(r==S_OK, "IStorage->CreateStream failed\n");
1315 if (r == S_OK)
1317 /* create a storage inside the new storage */
1318 r = IStorage_CreateStorage(stg2, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg3 );
1319 ok(r==S_OK, "IStorage->CreateStorage failed\n");
1322 /* free the parent */
1323 ref = IStorage_Release(stg2);
1324 ok(ref == 0, "IStorage still has %u references\n", ref);
1326 /* child objects are invalid */
1327 if (r == S_OK)
1329 r = IStream_Write(stm, "this should fail\n", 17, NULL);
1330 ok(r==STG_E_REVERTED, "IStream->Write sould fail, hr=%x\n", r);
1332 IStream_Release(stm);
1334 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1335 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1337 r = IStorage_SetStateBits(stg3, 1, 1);
1338 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1340 IStorage_Release(stg3);
1344 IStorage_Release(stg);
1346 r = DeleteFileA(filenameA);
1347 ok( r == TRUE, "deleted file\n");
1350 static void test_nonroot_transacted(void)
1352 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1353 HRESULT r;
1354 IStream *stm = NULL;
1355 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1356 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1357 static const WCHAR stmname2[] = { 'F','O','O',0 };
1359 DeleteFileA(filenameA);
1361 /* create a transacted file */
1362 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1363 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1364 ok(r==S_OK, "StgCreateDocfile failed\n");
1366 /* create a transacted substorage */
1367 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1368 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1370 if (r == S_OK)
1372 /* create and commit stmname */
1373 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1374 ok(r==S_OK, "IStorage->CreateStream failed\n");
1375 if (r == S_OK)
1376 IStream_Release(stm);
1378 IStorage_Commit(stg2, 0);
1380 /* create and revert stmname2 */
1381 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1382 ok(r==S_OK, "IStorage->CreateStream failed\n");
1383 if (r == S_OK)
1384 IStream_Release(stm);
1386 IStorage_Revert(stg2);
1388 /* check that Commit and Revert really worked */
1389 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1390 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1391 if (r == S_OK)
1392 IStream_Release(stm);
1394 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1395 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1396 if (r == S_OK)
1397 IStream_Release(stm);
1399 IStorage_Release(stg2);
1402 /* create a read-only transacted substorage */
1403 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2);
1404 ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r);
1406 if (r == S_OK)
1408 /* The storage can be modified. */
1409 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1410 todo_wine ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1411 if (r == S_OK)
1412 IStream_Release(stg3);
1414 /* But changes cannot be committed. */
1415 r = IStorage_Commit(stg2, 0);
1416 ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r);
1418 IStorage_Release(stg2);
1421 IStorage_Release(stg);
1423 /* create a non-transacted file */
1424 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1425 STGM_READWRITE, 0, &stg);
1426 ok(r==S_OK, "StgCreateDocfile failed\n");
1428 /* create a transacted substorage */
1429 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1430 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1432 if (r == S_OK)
1434 /* create and commit stmname */
1435 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1436 ok(r==S_OK, "IStorage->CreateStream failed\n");
1437 if (r == S_OK)
1438 IStream_Release(stm);
1440 IStorage_Commit(stg2, 0);
1442 /* create and revert stmname2 */
1443 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1444 ok(r==S_OK, "IStorage->CreateStream failed\n");
1445 if (r == S_OK)
1446 IStream_Release(stm);
1448 IStorage_Revert(stg2);
1450 /* check that Commit and Revert really worked */
1451 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1452 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1453 if (r == S_OK)
1454 IStream_Release(stm);
1456 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1457 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1458 if (r == S_OK)
1459 IStream_Release(stm);
1461 IStorage_Release(stg2);
1464 IStream_Release(stg);
1466 r = DeleteFileA(filenameA);
1467 ok( r == TRUE, "deleted file\n");
1470 static void test_ReadClassStm(void)
1472 CLSID clsid;
1473 HRESULT hr;
1474 IStream *pStream;
1475 static const LARGE_INTEGER llZero;
1477 hr = ReadClassStm(NULL, &clsid);
1478 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1480 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1481 ok_ole_success(hr, "CreateStreamOnHGlobal");
1482 hr = WriteClassStm(pStream, &test_stg_cls);
1483 ok_ole_success(hr, "WriteClassStm");
1485 hr = ReadClassStm(pStream, NULL);
1486 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1488 /* test not rewound stream */
1489 hr = ReadClassStm(pStream, &clsid);
1490 ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1491 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1493 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1494 ok_ole_success(hr, "IStream_Seek");
1495 hr = ReadClassStm(pStream, &clsid);
1496 ok_ole_success(hr, "ReadClassStm");
1497 ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
1500 struct access_res
1502 BOOL gothandle;
1503 DWORD lasterr;
1504 BOOL ignore;
1507 static const struct access_res create[16] =
1509 { TRUE, ERROR_SUCCESS, TRUE },
1510 { TRUE, ERROR_SUCCESS, TRUE },
1511 { TRUE, ERROR_SUCCESS, FALSE },
1512 { TRUE, ERROR_SUCCESS, FALSE },
1513 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1514 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1515 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1516 { TRUE, ERROR_SUCCESS, FALSE },
1517 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1518 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1519 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1520 { TRUE, ERROR_SUCCESS, TRUE },
1521 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1522 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1523 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1524 { TRUE, ERROR_SUCCESS, TRUE }
1527 static const struct access_res create_commit[16] =
1529 { TRUE, ERROR_SUCCESS, TRUE },
1530 { TRUE, ERROR_SUCCESS, TRUE },
1531 { TRUE, ERROR_SUCCESS, FALSE },
1532 { TRUE, ERROR_SUCCESS, FALSE },
1533 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1534 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1535 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1536 { TRUE, ERROR_SUCCESS, FALSE },
1537 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1538 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1539 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1540 { TRUE, ERROR_SUCCESS, TRUE },
1541 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1542 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1543 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1544 { TRUE, ERROR_SUCCESS, TRUE }
1547 static const struct access_res create_close[16] =
1549 { TRUE, ERROR_SUCCESS, FALSE },
1550 { TRUE, ERROR_SUCCESS, FALSE },
1551 { TRUE, ERROR_SUCCESS, FALSE },
1552 { TRUE, ERROR_SUCCESS, FALSE },
1553 { TRUE, ERROR_SUCCESS, FALSE },
1554 { TRUE, ERROR_SUCCESS, FALSE },
1555 { TRUE, ERROR_SUCCESS, FALSE },
1556 { TRUE, ERROR_SUCCESS, FALSE },
1557 { TRUE, ERROR_SUCCESS, FALSE },
1558 { TRUE, ERROR_SUCCESS, FALSE },
1559 { TRUE, ERROR_SUCCESS, FALSE },
1560 { TRUE, ERROR_SUCCESS, FALSE },
1561 { TRUE, ERROR_SUCCESS, FALSE },
1562 { TRUE, ERROR_SUCCESS, FALSE },
1563 { TRUE, ERROR_SUCCESS, FALSE },
1564 { TRUE, ERROR_SUCCESS }
1567 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1569 DWORD access = 0, share = 0;
1570 DWORD lasterr;
1571 HANDLE hfile;
1572 int i, j, idx = 0;
1574 for (i = 0; i < 4; i++)
1576 if (i == 0) access = 0;
1577 if (i == 1) access = GENERIC_READ;
1578 if (i == 2) access = GENERIC_WRITE;
1579 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
1581 for (j = 0; j < 4; j++)
1583 if (ares[idx].ignore)
1584 continue;
1586 if (j == 0) share = 0;
1587 if (j == 1) share = FILE_SHARE_READ;
1588 if (j == 2) share = FILE_SHARE_WRITE;
1589 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
1591 SetLastError(0xdeadbeef);
1592 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
1593 FILE_ATTRIBUTE_NORMAL, 0);
1594 lasterr = GetLastError();
1596 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
1597 "(%d, handle, %d): Expected %d, got %d\n",
1598 line, idx, ares[idx].gothandle,
1599 (hfile != INVALID_HANDLE_VALUE));
1601 ok(lasterr == ares[idx].lasterr ||
1602 broken(lasterr == 0xdeadbeef) /* win9x */,
1603 "(%d, lasterr, %d): Expected %d, got %d\n",
1604 line, idx, ares[idx].lasterr, lasterr);
1606 CloseHandle(hfile);
1607 idx++;
1612 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1614 static void test_access(void)
1616 IStorage *stg;
1617 HRESULT hr;
1619 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1621 /* STGM_TRANSACTED */
1623 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1624 STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, &stg);
1625 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1627 test_file_access("winetest", create);
1629 hr = IStorage_Commit(stg, STGC_DEFAULT);
1630 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1632 test_file_access("winetest", create_commit);
1634 IStorage_Release(stg);
1636 test_file_access("winetest", create_close);
1638 DeleteFileA("winetest");
1640 /* STGM_DIRECT */
1642 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1643 STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &stg);
1644 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1646 test_file_access("winetest", create);
1648 hr = IStorage_Commit(stg, STGC_DEFAULT);
1649 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1651 test_file_access("winetest", create_commit);
1653 IStorage_Release(stg);
1655 test_file_access("winetest", create_close);
1657 DeleteFileA("winetest");
1659 /* STGM_SHARE_DENY_NONE */
1661 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1662 STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
1663 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1665 test_file_access("winetest", create);
1667 hr = IStorage_Commit(stg, STGC_DEFAULT);
1668 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1670 test_file_access("winetest", create_commit);
1672 IStorage_Release(stg);
1674 test_file_access("winetest", create_close);
1676 DeleteFileA("winetest");
1678 /* STGM_SHARE_DENY_READ */
1680 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1681 STGM_SHARE_DENY_READ | STGM_TRANSACTED, 0, &stg);
1682 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1684 test_file_access("winetest", create);
1686 hr = IStorage_Commit(stg, STGC_DEFAULT);
1687 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1689 test_file_access("winetest", create_commit);
1691 IStorage_Release(stg);
1693 test_file_access("winetest", create_close);
1695 DeleteFileA("winetest");
1697 /* STGM_SHARE_DENY_WRITE */
1699 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1700 STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
1701 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1703 test_file_access("winetest", create);
1705 hr = IStorage_Commit(stg, STGC_DEFAULT);
1706 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1708 test_file_access("winetest", create_commit);
1710 IStorage_Release(stg);
1712 test_file_access("winetest", create_close);
1714 DeleteFileA("winetest");
1717 static void test_readonly(void)
1719 IStorage *stg, *stg2, *stg3;
1720 IStream *stream;
1721 HRESULT hr;
1722 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1723 static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
1724 static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
1726 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1727 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1728 if (SUCCEEDED(hr))
1730 hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
1731 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1732 if (SUCCEEDED(hr))
1734 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
1735 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1736 if (SUCCEEDED(hr))
1737 IStream_Release(stream);
1738 IStorage_Release(stg2);
1740 IStorage_Release(stg);
1743 /* re-open read only */
1744 hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
1745 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1746 if (SUCCEEDED(hr))
1748 hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
1749 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1750 if (SUCCEEDED(hr))
1752 /* CreateStream on read-only storage, name exists */
1753 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1754 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1755 if (SUCCEEDED(hr))
1756 IStream_Release(stream);
1758 /* CreateStream on read-only storage, name does not exist */
1759 hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1760 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1761 if (SUCCEEDED(hr))
1762 IStream_Release(stream);
1764 /* CreateStorage on read-only storage, name exists */
1765 hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1766 ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
1767 if (SUCCEEDED(hr))
1768 IStream_Release(stg3);
1770 /* CreateStorage on read-only storage, name does not exist */
1771 hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1772 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1773 if (SUCCEEDED(hr))
1774 IStream_Release(stg3);
1776 /* DestroyElement on read-only storage, name exists */
1777 hr = IStorage_DestroyElement( stg2, streamW );
1778 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1780 /* DestroyElement on read-only storage, name does not exist */
1781 hr = IStorage_DestroyElement( stg2, storageW );
1782 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1784 IStorage_Release(stg2);
1787 IStorage_Release(stg);
1790 DeleteFileA("winetest");
1793 static void test_simple(void)
1795 /* Tests for STGM_SIMPLE mode */
1797 IStorage *stg, *stg2;
1798 HRESULT r;
1799 IStream *stm;
1800 static const WCHAR stgname[] = { 'S','t','g',0 };
1801 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1802 static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
1803 LARGE_INTEGER pos;
1804 ULARGE_INTEGER upos;
1805 DWORD count;
1806 STATSTG stat;
1808 DeleteFileA(filenameA);
1810 r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1811 ok(r == S_OK, "got %08x\n", r);
1813 r = IStorage_CreateStorage(stg, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2);
1814 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
1815 if (SUCCEEDED(r)) IStorage_Release(stg2);
1817 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1818 ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
1819 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1820 ok(r == S_OK, "got %08x\n", r);
1822 upos.QuadPart = 6000;
1823 r = IStream_SetSize(stm, upos);
1824 ok(r == S_OK, "got %08x\n", r);
1826 r = IStream_Write(stm, "foo", 3, &count);
1827 ok(r == S_OK, "got %08x\n", r);
1828 ok(count == 3, "got %d\n", count);
1830 pos.QuadPart = 0;
1831 r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
1832 ok(r == S_OK, "got %08x\n", r);
1833 ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
1835 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1836 ok(r == S_OK ||
1837 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
1838 "got %08x\n", r);
1839 if (r == S_OK)
1840 ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
1842 pos.QuadPart = 1;
1843 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
1844 ok(r == S_OK, "got %08x\n", r);
1845 ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
1847 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1848 ok(r == S_OK ||
1849 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
1850 "got %08x\n", r);
1851 if (r == S_OK)
1852 ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
1854 IStream_Release(stm);
1856 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1857 ok(r == S_OK, "got %08x\n", r);
1859 upos.QuadPart = 100;
1860 r = IStream_SetSize(stm, upos);
1861 ok(r == S_OK, "got %08x\n", r);
1863 r = IStream_Write(stm, "foo", 3, &count);
1864 ok(r == S_OK, "got %08x\n", r);
1865 ok(count == 3, "got %d\n", count);
1867 IStream_Release(stm);
1869 IStorage_Commit(stg, STGC_DEFAULT);
1870 IStorage_Release(stg);
1872 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
1873 if (r == STG_E_INVALIDFLAG)
1875 win_skip("Flag combination is not supported on NT4 and below\n");
1876 DeleteFileA(filenameA);
1877 return;
1879 ok(r == S_OK, "got %08x\n", r);
1881 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg2);
1882 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
1883 if (SUCCEEDED(r)) IStorage_Release(stg2);
1885 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1886 ok(r == S_OK, "got %08x\n", r);
1888 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1889 ok(r == S_OK, "got %08x\n", r);
1890 ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
1892 IStream_Release(stm);
1894 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1895 ok(r == S_OK, "got %08x\n", r);
1897 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1898 ok(r == S_OK, "got %08x\n", r);
1899 ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
1901 IStream_Release(stm);
1904 IStorage_Release(stg);
1906 DeleteFileA(filenameA);
1909 static void test_fmtusertypestg(void)
1911 IStorage *stg;
1912 IEnumSTATSTG *stat;
1913 HRESULT hr;
1914 static const char fileA[] = {'f','m','t','t','e','s','t',0};
1915 static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0};
1916 static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0};
1917 static WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0};
1919 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1920 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1922 if (SUCCEEDED(hr))
1924 /* try to write the stream */
1925 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
1926 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1928 /* check that the stream was created */
1929 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
1930 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1931 if (SUCCEEDED(hr))
1933 BOOL found = FALSE;
1934 STATSTG statstg;
1935 DWORD got;
1936 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
1938 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
1939 found = TRUE;
1940 else
1941 ok(0, "found unexpected stream or storage\n");
1943 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
1944 IEnumSTATSTG_Release(stat);
1947 /* re-write the stream */
1948 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
1949 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1951 /* check that the stream is still there */
1952 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
1953 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1954 if (SUCCEEDED(hr))
1956 BOOL found = FALSE;
1957 STATSTG statstg;
1958 DWORD got;
1959 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
1961 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
1962 found = TRUE;
1963 else
1964 ok(0, "found unexpected stream or storage\n");
1966 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
1967 IEnumSTATSTG_Release(stat);
1970 IStorage_Release(stg);
1971 DeleteFileA( fileA );
1975 static void test_references(void)
1977 IStorage *stg,*stg2;
1978 HRESULT hr;
1979 unsigned c1,c2;
1980 static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
1982 DeleteFileA(filenameA);
1984 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1985 ok(hr==S_OK, "StgCreateDocfile failed\n");
1987 if (SUCCEEDED(hr))
1989 IStorage_Release(stg);
1991 hr = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
1992 ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr);
1994 if (SUCCEEDED(hr))
1996 hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2);
1997 ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr);
1999 if (SUCCEEDED(hr))
2001 c1 = IStorage_AddRef(stg);
2002 ok(c1 == 2, "creating internal storage added references to ancestor\n");
2003 c1 = IStorage_AddRef(stg);
2004 IStorage_Release(stg2);
2005 c2 = IStorage_AddRef(stg) - 1;
2006 ok(c1 == c2, "releasing internal storage removed references to ancestor\n");
2008 c1 = IStorage_Release(stg);
2009 while ( c1 ) c1 = IStorage_Release(stg);
2013 DeleteFileA(filenameA);
2016 /* dest
2017 * |-StorageA
2018 * | `StreamA: "StreamA"
2019 * |-StorageB
2020 * | `StreamB: "StreamB"
2021 * `StreamC: "StreamC"
2023 static HRESULT create_test_file(IStorage *dest)
2025 IStorage *stgA = NULL, *stgB = NULL;
2026 IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
2027 const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
2028 const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
2029 const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
2030 ULONG bytes;
2031 HRESULT hr;
2033 hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
2034 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2035 if(FAILED(hr))
2036 goto cleanup;
2038 hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
2039 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2040 if(FAILED(hr))
2041 goto cleanup;
2043 hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
2044 ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
2046 hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
2047 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2048 if(FAILED(hr))
2049 goto cleanup;
2051 hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
2052 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2053 if(FAILED(hr))
2054 goto cleanup;
2056 hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
2057 ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
2059 hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
2060 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2061 if(FAILED(hr))
2062 goto cleanup;
2064 hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
2065 ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
2067 cleanup:
2068 if(strmC)
2069 IStream_Release(strmC);
2070 if(strmB)
2071 IStream_Release(strmB);
2072 if(stgB)
2073 IStorage_Release(stgB);
2074 if(strmA)
2075 IStream_Release(strmA);
2076 if(stgA)
2077 IStorage_Release(stgA);
2079 return hr;
2082 static void test_copyto(void)
2084 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2085 IStream *strm_tmp;
2086 WCHAR buf[64];
2087 HRESULT hr;
2089 /* create & populate file1 */
2090 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2091 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2092 if(FAILED(hr))
2093 goto cleanup;
2095 hr = create_test_file(file1);
2096 if(FAILED(hr))
2097 goto cleanup;
2099 /* create file2 */
2100 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2101 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2102 if(FAILED(hr))
2103 goto cleanup;
2105 /* copy file1 into file2 */
2106 hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2107 ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2109 hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2110 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2111 if(FAILED(hr))
2112 goto cleanup;
2114 /* verify that all of file1 was copied */
2115 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2116 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2117 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2119 if(SUCCEEDED(hr)){
2120 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2121 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2122 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2124 if(SUCCEEDED(hr)){
2125 memset(buf, 0, sizeof(buf));
2126 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2127 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2128 if(SUCCEEDED(hr))
2129 ok(strcmp_ww(buf, strmA_name) == 0,
2130 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2132 IStream_Release(strm_tmp);
2135 IStorage_Release(stg_tmp);
2138 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2139 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2140 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2142 if(SUCCEEDED(hr)){
2143 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2144 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2145 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2147 if(SUCCEEDED(hr)){
2148 memset(buf, 0, sizeof(buf));
2149 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2150 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2151 if(SUCCEEDED(hr))
2152 ok(strcmp_ww(buf, strmB_name) == 0,
2153 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2155 IStream_Release(strm_tmp);
2158 IStorage_Release(stg_tmp);
2161 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2162 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2163 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2165 if(SUCCEEDED(hr)){
2166 memset(buf, 0, sizeof(buf));
2167 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2168 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2169 if(SUCCEEDED(hr))
2170 ok(strcmp_ww(buf, strmC_name) == 0,
2171 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2173 IStream_Release(strm_tmp);
2176 cleanup:
2177 if(file1)
2178 IStorage_Release(file1);
2179 if(file2)
2180 IStorage_Release(file2);
2182 DeleteFileA(file1_nameA);
2183 DeleteFileA(file2_nameA);
2186 static void test_copyto_snbexclusions(void)
2188 static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2190 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2191 IStream *strm_tmp;
2192 WCHAR buf[64];
2193 HRESULT hr;
2195 /* create & populate file1 */
2196 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2197 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2198 if(FAILED(hr))
2199 goto cleanup;
2201 hr = create_test_file(file1);
2202 if(FAILED(hr))
2203 goto cleanup;
2205 /* create file2 */
2206 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2207 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2208 if(FAILED(hr))
2209 goto cleanup;
2211 /* copy file1 to file2 with name exclusions */
2212 hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2213 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2214 if(FAILED(hr))
2215 goto cleanup;
2217 /* verify that file1 copied over, respecting exclusions */
2218 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2219 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2220 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2221 if(SUCCEEDED(hr))
2222 IStorage_Release(stg_tmp);
2224 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2225 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2226 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2227 if(SUCCEEDED(hr))
2228 IStream_Release(strm_tmp);
2230 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2231 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2232 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2234 if(SUCCEEDED(hr)){
2235 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2236 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2237 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2239 if(SUCCEEDED(hr)){
2240 memset(buf, 0, sizeof(buf));
2241 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2242 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2243 if(SUCCEEDED(hr))
2244 ok(strcmp_ww(buf, strmB_name) == 0,
2245 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2247 IStream_Release(strm_tmp);
2250 IStorage_Release(stg_tmp);
2253 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2254 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2255 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2256 if(SUCCEEDED(hr))
2257 IStream_Release(strm_tmp);
2259 cleanup:
2260 if(file1)
2261 IStorage_Release(file1);
2262 if(file2)
2263 IStorage_Release(file2);
2265 DeleteFileA(file1_nameA);
2266 DeleteFileA(file2_nameA);
2269 static void test_copyto_iidexclusions_storage(void)
2271 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2272 IStream *strm_tmp;
2273 WCHAR buf[64];
2274 HRESULT hr;
2276 /* create & populate file1 */
2277 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2278 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2279 if(FAILED(hr))
2280 goto cleanup;
2282 hr = create_test_file(file1);
2283 if(FAILED(hr))
2284 goto cleanup;
2286 /* create file2 */
2287 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2288 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2289 if(FAILED(hr))
2290 goto cleanup;
2292 /* copy file1 to file2 with iid exclusions */
2293 hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2294 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2295 if(FAILED(hr))
2296 goto cleanup;
2298 /* verify that file1 copied over, respecting exclusions */
2299 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2300 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2301 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2302 if(SUCCEEDED(hr))
2303 IStorage_Release(stg_tmp);
2305 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2306 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2307 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2308 if(SUCCEEDED(hr))
2309 IStream_Release(strm_tmp);
2311 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2312 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2313 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2314 if(SUCCEEDED(hr))
2315 IStorage_Release(stg_tmp);
2317 hr = IStorage_OpenStream(file2, strmB_name, NULL,
2318 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2319 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2320 if(SUCCEEDED(hr))
2321 IStream_Release(strm_tmp);
2323 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2324 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2325 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2327 if(SUCCEEDED(hr)){
2328 memset(buf, 0, sizeof(buf));
2329 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2330 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2331 if(SUCCEEDED(hr))
2332 ok(strcmp_ww(buf, strmC_name) == 0,
2333 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2335 IStream_Release(strm_tmp);
2338 cleanup:
2339 if(file1)
2340 IStorage_Release(file1);
2341 if(file2)
2342 IStorage_Release(file2);
2344 DeleteFileA(file1_nameA);
2345 DeleteFileA(file2_nameA);
2348 static void test_copyto_iidexclusions_stream(void)
2350 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2351 IStream *strm_tmp;
2352 HRESULT hr;
2354 /* create & populate file1 */
2355 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2356 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2357 if(FAILED(hr))
2358 goto cleanup;
2360 hr = create_test_file(file1);
2361 if(FAILED(hr))
2362 goto cleanup;
2364 /* create file2 */
2365 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2366 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2367 if(FAILED(hr))
2368 goto cleanup;
2370 /* copy file1 to file2 with iid exclusions */
2371 hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2372 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2373 if(FAILED(hr))
2374 goto cleanup;
2376 /* verify that file1 copied over, respecting exclusions */
2377 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2378 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2379 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2381 if(SUCCEEDED(hr)){
2382 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2383 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2384 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2385 if(SUCCEEDED(hr))
2386 IStream_Release(strm_tmp);
2388 IStorage_Release(stg_tmp);
2391 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2392 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2393 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2395 if(SUCCEEDED(hr)){
2396 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2397 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2398 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2399 if(SUCCEEDED(hr))
2400 IStream_Release(strm_tmp);
2402 IStorage_Release(stg_tmp);
2405 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2406 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2407 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2408 if(SUCCEEDED(hr))
2409 IStream_Release(strm_tmp);
2411 cleanup:
2412 if(file1)
2413 IStorage_Release(file1);
2414 if(file2)
2415 IStorage_Release(file2);
2417 DeleteFileA(file1_nameA);
2418 DeleteFileA(file2_nameA);
2421 static void test_rename(void)
2423 IStorage *stg, *stg2;
2424 IStream *stm;
2425 HRESULT r;
2426 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2427 static const WCHAR stgname2[] = { 'S','T','G',0 };
2428 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2429 static const WCHAR stmname2[] = { 'E','N','T','S',0 };
2431 DeleteFileA(filenameA);
2433 /* create the file */
2434 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2435 STGM_READWRITE, 0, &stg);
2436 ok(r==S_OK, "StgCreateDocfile failed\n");
2438 /* create a substorage */
2439 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2440 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2442 /* create a stream in the substorage */
2443 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2444 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2445 IStream_Release(stm);
2447 /* rename the stream */
2448 r = IStorage_RenameElement(stg2, stmname, stmname2);
2449 ok(r==S_OK, "IStorage->RenameElement failed, hr=%08x\n", r);
2451 /* cannot open stream with old name */
2452 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2453 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2454 if (SUCCEEDED(r)) IStream_Release(stm);
2456 /* can open stream with new name */
2457 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2458 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2459 if (SUCCEEDED(r)) IStream_Release(stm);
2461 IStorage_Release(stg2);
2463 /* rename the storage */
2464 IStorage_RenameElement(stg, stgname, stgname2);
2466 /* cannot open storage with old name */
2467 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2468 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2469 if (SUCCEEDED(r)) IStorage_Release(stg2);
2471 /* can open storage with new name */
2472 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2473 ok(r==S_OK, "IStorage_OpenStream should fail, hr=%08x\n", r);
2474 if (SUCCEEDED(r))
2476 /* opened storage still has the stream */
2477 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2478 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2479 if (SUCCEEDED(r)) IStream_Release(stm);
2481 IStorage_Release(stg2);
2484 IStorage_Release(stg);
2486 r = DeleteFileA(filenameA);
2487 ok( r == TRUE, "deleted file\n");
2490 static void test_toplevel_stat(void)
2492 IStorage *stg = NULL;
2493 HRESULT r;
2494 STATSTG stat;
2495 char prev_dir[MAX_PATH];
2496 char temp[MAX_PATH];
2497 char full_path[MAX_PATH];
2498 LPSTR rel_pathA;
2499 WCHAR rel_path[MAX_PATH];
2501 DeleteFileA(filenameA);
2503 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2504 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2505 ok(r==S_OK, "StgCreateDocfile failed\n");
2507 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2508 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2509 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2510 CoTaskMemFree(stat.pwcsName);
2512 IStorage_Release( stg );
2514 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2515 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2517 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2518 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2519 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2520 CoTaskMemFree(stat.pwcsName);
2522 IStorage_Release( stg );
2524 DeleteFileA(filenameA);
2526 /* Stat always returns the full path, even for files opened with a relative path. */
2527 GetCurrentDirectoryA(MAX_PATH, prev_dir);
2529 GetTempPathA(MAX_PATH, temp);
2531 SetCurrentDirectoryA(temp);
2533 GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA);
2534 MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH);
2536 r = StgCreateDocfile( rel_path, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2537 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2538 ok(r==S_OK, "StgCreateDocfile failed\n");
2540 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2541 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2542 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2543 CoTaskMemFree(stat.pwcsName);
2545 IStorage_Release( stg );
2547 r = StgOpenStorage( rel_path, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2548 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2550 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2551 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2552 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2553 CoTaskMemFree(stat.pwcsName);
2555 IStorage_Release( stg );
2557 SetCurrentDirectoryA(prev_dir);
2559 DeleteFileA(filenameA);
2562 START_TEST(storage32)
2564 CHAR temp[MAX_PATH];
2566 GetTempPathA(MAX_PATH, temp);
2567 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
2569 win_skip("Could not create temp file, %u\n", GetLastError());
2570 return;
2572 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
2573 DeleteFileA(filenameA);
2575 test_hglobal_storage_stat();
2576 test_create_storage_modes();
2577 test_storage_stream();
2578 test_open_storage();
2579 test_storage_suminfo();
2580 test_storage_refcount();
2581 test_streamenum();
2582 test_transact();
2583 test_substorage_share();
2584 test_revert();
2585 test_parent_free();
2586 test_nonroot_transacted();
2587 test_ReadClassStm();
2588 test_access();
2589 test_writeclassstg();
2590 test_readonly();
2591 test_simple();
2592 test_fmtusertypestg();
2593 test_references();
2594 test_copyto();
2595 test_copyto_snbexclusions();
2596 test_copyto_iidexclusions_storage();
2597 test_copyto_iidexclusions_stream();
2598 test_rename();
2599 test_toplevel_stat();