vbscript: Moved Error object implementation to global.c.
[wine/multimedia.git] / dlls / ole32 / tests / storage32.c
bloba14f19be6eedc0e13ae221d959cf28097b9ce352
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 r = StgIsStorageILockBytes( ilb );
70 ok( r == S_FALSE, "StgIsStorageILockBytes should have failed\n");
72 mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
73 r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
74 ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
76 r = WriteClassStg( stg, &test_stg_cls );
77 ok( r == S_OK, "WriteClassStg failed\n");
79 r = StgIsStorageILockBytes( ilb );
80 ok( r == S_OK, "StgIsStorageILockBytes failed\n");
82 memset( &stat, 0, sizeof stat );
83 r = IStorage_Stat( stg, &stat, 0 );
85 ok( stat.pwcsName == NULL, "storage name not null\n");
86 ok( stat.type == 1, "type is wrong\n");
87 ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
88 ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
90 refcount = IStorage_Release( stg );
91 ok( refcount == 0, "IStorage refcount is wrong\n");
92 refcount = ILockBytes_Release( ilb );
93 ok( refcount == 0, "ILockBytes refcount is wrong\n");
96 static void test_create_storage_modes(void)
98 IStorage *stg = NULL;
99 HRESULT r;
101 DeleteFileA(filenameA);
103 /* test with some invalid parameters */
104 r = StgCreateDocfile( NULL, 0, 0, &stg);
105 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
106 r = StgCreateDocfile( filename, 0, 0, &stg);
107 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
108 r = StgCreateDocfile( filename, STGM_CREATE, 0, &stg);
109 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
110 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE, 0, &stg);
111 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
112 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
113 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
114 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
115 ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
116 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
117 ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
118 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
119 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
120 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
121 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
122 r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
123 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
125 /* StgCreateDocfile seems to be very particular about the flags it accepts */
126 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
127 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
128 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
129 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
130 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
131 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
132 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
133 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
134 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
135 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
136 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
137 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
138 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
139 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
140 ok(stg == NULL, "stg was set\n");
142 /* check what happens if the file already exists (which is how it's meant to be used) */
143 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
144 ok(r==S_OK, "StgCreateDocfile failed\n");
145 r = IStorage_Release(stg);
146 ok(r == 0, "storage not released\n");
147 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
148 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
149 r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
150 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
151 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE, 0, &stg);
152 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
153 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE, 0, &stg);
154 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
155 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE, 0, &stg);
156 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
157 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
158 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
159 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, &stg);
160 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
161 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_WRITE, 0, &stg);
162 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
163 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_WRITE, 0, &stg);
164 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
165 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
166 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
167 r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
168 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
169 ok(DeleteFileA(filenameA), "failed to delete file\n");
171 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
172 ok(r==S_OK, "StgCreateDocfile failed\n");
173 r = IStorage_Release(stg);
174 ok(r == 0, "storage not released\n");
175 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
176 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
177 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
178 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
180 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
181 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
182 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | 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 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
189 ok(r==S_OK, "StgCreateDocfile failed\n");
190 r = IStorage_Release(stg);
191 ok(r == 0, "storage not released\n");
192 ok(DeleteFileA(filenameA), "failed to delete file\n");
194 /* test the way excel uses StgCreateDocFile */
195 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
196 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
197 if(r == S_OK)
199 r = IStorage_Release(stg);
200 ok(r == 0, "storage not released\n");
201 ok(DeleteFileA(filenameA), "failed to delete file\n");
204 /* and the way windows media uses it ... */
205 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_NONE | STGM_READWRITE | STGM_TRANSACTED, 0, &stg);
206 ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
207 if (r == S_OK)
209 r = IStorage_Release(stg);
210 ok(r == 0, "storage not released\n");
211 ok(DeleteFileA(filenameA), "failed to delete file\n");
214 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
215 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
216 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
217 if(r == S_OK)
219 r = IStorage_Release(stg);
220 ok(r == 0, "storage not released\n");
221 ok(DeleteFileA(filenameA), "failed to delete file\n");
224 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg);
225 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
226 if(r == S_OK)
228 r = IStorage_Release(stg);
229 ok(r == 0, "storage not released\n");
230 ok(DeleteFileA(filenameA), "failed to delete file\n");
233 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
234 ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
235 if(r == S_OK)
237 r = IStorage_Release(stg);
238 ok(r == 0, "storage not released\n");
239 ok(DeleteFileA(filenameA), "failed to delete file\n");
242 /* test the way msi uses StgCreateDocfile */
243 r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
244 ok(r==S_OK, "StgCreateDocFile failed\n");
245 r = IStorage_Release(stg);
246 ok(r == 0, "storage not released\n");
247 ok(DeleteFileA(filenameA), "failed to delete file\n");
250 static void test_stgcreatestorageex(void)
252 HRESULT (WINAPI *pStgCreateStorageEx)(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen);
253 HMODULE hOle32 = GetModuleHandleA("ole32");
254 IStorage *stg = NULL;
255 STGOPTIONS stgoptions = {1, 0, 4096};
256 HRESULT r;
258 pStgCreateStorageEx = (void *) GetProcAddress(hOle32, "StgCreateStorageEx");
259 if (!pStgCreateStorageEx)
261 win_skip("skipping test on NT4\n");
262 return;
265 DeleteFileA(filenameA);
267 /* Verify that StgCreateStorageEx can accept an options param */
268 r = pStgCreateStorageEx( filename,
269 STGM_SHARE_EXCLUSIVE | STGM_READWRITE,
270 STGFMT_DOCFILE,
272 &stgoptions,
273 NULL,
274 &IID_IStorage,
275 (void **) &stg);
276 ok(r==S_OK || r==STG_E_UNIMPLEMENTEDFUNCTION, "StgCreateStorageEx with options failed\n");
277 if (r==STG_E_UNIMPLEMENTEDFUNCTION)
279 /* We're on win98 which means all bets are off. Let's get out of here. */
280 win_skip("skipping test on win9x\n");
281 return;
284 r = IStorage_Release(stg);
285 ok(r == 0, "storage not released\n");
286 ok(DeleteFileA(filenameA), "failed to delete file\n");
288 /* Verify that StgCreateStorageEx can accept a NULL pStgOptions */
289 r = pStgCreateStorageEx( filename,
290 STGM_SHARE_EXCLUSIVE | STGM_READWRITE,
291 STGFMT_STORAGE,
293 NULL,
294 NULL,
295 &IID_IStorage,
296 (void **) &stg);
297 ok(r==S_OK, "StgCreateStorageEx with NULL options failed\n");
298 r = IStorage_Release(stg);
299 ok(r == 0, "storage not released\n");
300 ok(DeleteFileA(filenameA), "failed to delete file\n");
303 static void test_storage_stream(void)
305 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
306 static const WCHAR longname[] = {
307 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
308 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
310 IStorage *stg = NULL;
311 HRESULT r;
312 IStream *stm = NULL;
313 IStream *stm2 = NULL;
314 ULONG count = 0;
315 LARGE_INTEGER pos;
316 ULARGE_INTEGER p;
317 unsigned char buffer[0x100];
318 IUnknown *unk;
320 DeleteFileA(filenameA);
322 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
323 ok(r==S_OK, "StgCreateDocfile failed\n");
325 /* try create some invalid streams */
326 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, 0, &stm );
327 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
328 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 1, &stm );
329 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
330 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, NULL );
331 ok(r==STG_E_INVALIDPOINTER, "IStorage->CreateStream wrong error\n");
332 r = IStorage_CreateStream(stg, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
333 ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error\n");
334 r = IStorage_CreateStream(stg, longname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
335 ok(r==STG_E_INVALIDNAME || broken(r==S_OK) /* nt4 */,
336 "IStorage->CreateStream wrong error, got %d GetLastError()=%d\n", r, GetLastError());
337 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE, 0, 0, &stm );
338 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
339 r = IStorage_CreateStream(stg, stmname, STGM_READ, 0, 0, &stm );
340 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
341 r = IStorage_CreateStream(stg, stmname, STGM_WRITE, 0, 0, &stm );
342 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
343 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, 0, &stm );
344 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
345 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READ, 0, 0, &stm );
346 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
348 /* now really create a stream and delete it */
349 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
350 ok(r==S_OK, "IStorage->CreateStream failed\n");
352 /* test for support interfaces */
353 r = IStream_QueryInterface(stm, &IID_IPersist, (void**)&unk);
354 ok(r==E_NOINTERFACE, "got 0x%08x\n", r);
355 r = IStream_QueryInterface(stm, &IID_IPersistStream, (void**)&unk);
356 ok(r==E_NOINTERFACE, "got 0x%08x\n", r);
358 r = IStream_Release(stm);
359 ok(r == 0, "wrong ref count\n");
360 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
361 ok(r==STG_E_FILEALREADYEXISTS, "IStorage->CreateStream failed\n");
362 r = IStorage_DestroyElement(stg,stmname);
363 ok(r==S_OK, "IStorage->DestroyElement failed\n");
365 /* create a stream and write to it */
366 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
367 ok(r==S_OK, "IStorage->CreateStream failed\n");
369 r = IStream_Clone(stm, &stm2);
370 ok(r==S_OK, "failed to clone stream\n");
372 r = IStream_Write(stm, NULL, 0, NULL );
373 ok(r==STG_E_INVALIDPOINTER, "IStream->Write wrong error\n");
374 r = IStream_Write(stm, "Hello\n", 0, NULL );
375 ok(r==S_OK, "failed to write stream\n");
376 r = IStream_Write(stm, "Hello\n", 0, &count );
377 ok(r==S_OK, "failed to write stream\n");
378 r = IStream_Write(stm, "Hello\n", 6, &count );
379 ok(r==S_OK, "failed to write stream\n");
380 r = IStream_Commit(stm, STGC_DEFAULT );
381 ok(r==S_OK, "failed to commit stream\n");
382 r = IStream_Commit(stm, STGC_DEFAULT );
383 ok(r==S_OK, "failed to commit stream\n");
385 /* Read past the end of the stream. */
386 pos.QuadPart = 3;
387 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
388 ok(r==S_OK, "failed to seek stream\n");
389 ok(p.QuadPart == 3, "at wrong place\n");
390 r = IStream_Read(stm, buffer, sizeof buffer, &count );
391 ok(r==S_OK, "failed to read\n");
392 ok(count == 3, "read bytes past end of stream\n");
393 pos.QuadPart = 10;
394 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
395 ok(r==S_OK, "failed to seek stream\n");
396 ok(p.QuadPart == 10, "at wrong place\n");
397 r = IStream_Read(stm, buffer, sizeof buffer, &count );
398 ok(r==S_OK, "failed to read\n");
399 ok(count == 0, "read bytes past end of stream\n");
400 pos.QuadPart = 10000;
401 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
402 ok(r==S_OK, "failed to seek stream\n");
403 ok(p.QuadPart == 10000, "at wrong place\n");
404 r = IStream_Read(stm, buffer, sizeof buffer, &count );
405 ok(r==S_OK, "failed to read\n");
406 ok(count == 0, "read bytes past end of stream\n");
408 /* Convert to a big block stream, and read past the end. */
409 p.QuadPart = 5000;
410 r = IStream_SetSize(stm,p);
411 ok(r==S_OK, "failed to set pos\n");
412 pos.QuadPart = 4997;
413 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
414 ok(r==S_OK, "failed to seek stream\n");
415 ok(p.QuadPart == 4997, "at wrong place\n");
416 r = IStream_Read(stm, buffer, sizeof buffer, &count );
417 ok(r==S_OK, "failed to read\n");
418 ok(count == 3, "read bytes past end of stream\n");
419 pos.QuadPart = 5001;
420 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
421 ok(r==S_OK, "failed to seek stream\n");
422 ok(p.QuadPart == 5001, "at wrong place\n");
423 r = IStream_Read(stm, buffer, sizeof buffer, &count );
424 ok(r==S_OK, "failed to read\n");
425 ok(count == 0, "read bytes past end of stream\n");
426 pos.QuadPart = 10000;
427 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
428 ok(r==S_OK, "failed to seek stream\n");
429 ok(p.QuadPart == 10000, "at wrong place\n");
430 r = IStream_Read(stm, buffer, sizeof buffer, &count );
431 ok(r==S_OK, "failed to read\n");
432 ok(count == 0, "read bytes past end of stream\n");
434 /* seek round a bit, reset the stream size */
435 pos.QuadPart = 0;
436 r = IStream_Seek(stm, pos, 3, &p );
437 ok(r==STG_E_INVALIDFUNCTION, "IStream->Seek returned wrong error\n");
438 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
439 ok(r==S_OK, "failed to seek stream\n");
440 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
441 ok(r==S_OK, "failed to seek stream\n");
442 r = IStream_SetSize(stm,p);
443 ok(r==S_OK, "failed to set pos\n");
444 pos.QuadPart = 10;
445 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
446 ok(r==S_OK, "failed to seek stream\n");
447 ok(p.QuadPart == 10, "at wrong place\n");
448 r = IStream_Read(stm, buffer, sizeof buffer, &count );
449 ok(r==S_OK, "failed to set pos\n");
450 ok(count == 0, "read bytes from empty stream\n");
451 pos.QuadPart = 10000;
452 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
453 ok(r==S_OK, "failed to seek stream\n");
454 ok(p.QuadPart == 10000, "at wrong place\n");
455 r = IStream_Read(stm, buffer, sizeof buffer, &count );
456 ok(r==S_OK, "failed to set pos\n");
457 ok(count == 0, "read bytes from empty stream\n");
458 pos.QuadPart = 0;
459 r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
460 ok(r==S_OK, "failed to seek stream\n");
461 ok(p.QuadPart == 0, "at wrong place\n");
462 r = IStream_Read(stm, buffer, sizeof buffer, &count );
463 ok(r==S_OK, "failed to set pos\n");
464 ok(count == 0, "read bytes from empty stream\n");
466 /* wrap up */
467 r = IStream_Release(stm2);
468 ok(r == 0, "wrong ref count\n");
470 /* create a stream and write to it */
471 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
472 ok(r==S_OK, "IStorage->CreateStream failed\n");
474 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p);
475 ok(r==STG_E_REVERTED, "overwritten stream should return STG_E_REVERTED instead of 0x%08x\n", r);
477 r = IStream_Release(stm2);
478 ok(r == 0, "wrong ref count\n");
479 r = IStream_Release(stm);
480 ok(r == 0, "wrong ref count\n");
482 r = IStorage_Release(stg);
483 ok(r == 0, "wrong ref count\n");
485 /* try create some invalid streams */
486 stg = NULL;
487 stm = NULL;
488 r = StgOpenStorage(filename, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
489 ok(r == S_OK, "should succeed\n");
490 if (stg)
492 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
493 ok(r == STG_E_INVALIDFLAG, "IStorage->OpenStream should return STG_E_INVALIDFLAG instead of 0x%08x\n", r);
494 IStorage_Release(stg);
497 r = DeleteFileA(filenameA);
498 ok(r, "file should exist\n");
501 static BOOL touch_file(LPCSTR filename)
503 HANDLE file;
505 file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
506 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
507 if (file==INVALID_HANDLE_VALUE)
508 return FALSE;
509 CloseHandle(file);
510 return TRUE;
513 static BOOL is_zero_length(LPCSTR filename)
515 HANDLE file;
516 DWORD len;
518 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
519 OPEN_EXISTING, 0, NULL);
520 if (file==INVALID_HANDLE_VALUE)
521 return FALSE;
522 len = GetFileSize(file, NULL);
523 CloseHandle(file);
524 return len == 0;
527 static BOOL is_existing_file(LPCSTR filename)
529 HANDLE file;
531 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
532 OPEN_EXISTING, 0, NULL);
533 if (file==INVALID_HANDLE_VALUE)
534 return FALSE;
535 CloseHandle(file);
536 return TRUE;
539 static void test_open_storage(void)
541 static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
542 IStorage *stg = NULL, *stg2 = NULL;
543 HRESULT r;
544 DWORD stgm;
546 /* try opening a zero length file - it should stay zero length */
547 DeleteFileA(filenameA);
548 touch_file(filenameA);
549 stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
550 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
551 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
553 stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
554 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
555 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
556 ok(is_zero_length(filenameA), "file length changed\n");
558 DeleteFileA(filenameA);
560 /* try opening a nonexistent file - it should not create it */
561 stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
562 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
563 ok(r!=S_OK, "StgOpenStorage failed: 0x%08x\n", r);
564 if (r==S_OK) IStorage_Release(stg);
565 ok(!is_existing_file(filenameA), "StgOpenStorage should not create a file\n");
566 DeleteFileA(filenameA);
568 /* create the file */
569 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
570 ok(r==S_OK, "StgCreateDocfile failed\n");
571 IStorage_Release(stg);
573 r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
574 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
575 r = StgOpenStorage( NULL, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
576 ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
577 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, NULL);
578 ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
579 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 1, &stg);
580 ok(r==STG_E_INVALIDPARAMETER, "StgOpenStorage wrong error\n");
581 r = StgOpenStorage( szNonExist, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
582 ok(r==STG_E_FILENOTFOUND, "StgOpenStorage failed\n");
583 r = StgOpenStorage( filename, NULL, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
584 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
585 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
586 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
587 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
588 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
589 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
590 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
592 /* open it for real */
593 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg); /* XLViewer 97/2000 */
594 ok(r==S_OK, "StgOpenStorage failed\n");
595 if(stg)
597 r = IStorage_Release(stg);
598 ok(r == 0, "wrong ref count\n");
601 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
602 ok(r==S_OK, "StgOpenStorage failed\n");
603 if(stg)
605 r = IStorage_Release(stg);
606 ok(r == 0, "wrong ref count\n");
609 /* test the way word opens its custom dictionary */
610 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
611 STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
612 ok(r==S_OK, "StgOpenStorage failed\n");
613 if(stg)
615 r = IStorage_Release(stg);
616 ok(r == 0, "wrong ref count\n");
619 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
620 ok(r==S_OK, "StgOpenStorage failed\n");
621 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
622 ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
623 if(stg)
625 r = IStorage_Release(stg);
626 ok(r == 0, "wrong ref count\n");
629 /* now try write to a storage file we opened read-only */
630 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
631 ok(r==S_OK, "StgOpenStorage failed\n");
632 if(stg)
634 static const WCHAR stmname[] = { 'w','i','n','e','t','e','s','t',0};
635 IStream *stm = NULL;
636 IStorage *stg2 = NULL;
638 r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
639 0, 0, &stm );
640 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
641 r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
642 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
644 r = IStorage_Release(stg);
645 ok(r == 0, "wrong ref count\n");
648 /* open like visio 2003 */
649 stg = NULL;
650 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
651 ok(r == S_OK, "should succeed\n");
652 if (stg)
653 IStorage_Release(stg);
655 /* test other sharing modes with STGM_PRIORITY */
656 stg = NULL;
657 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
658 ok(r == S_OK, "should succeed\n");
659 if (stg)
660 IStorage_Release(stg);
662 stg = NULL;
663 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
664 ok(r == S_OK, "should succeed\n");
665 if (stg)
666 IStorage_Release(stg);
668 stg = NULL;
669 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_READ, NULL, 0, &stg);
670 ok(r == S_OK, "should succeed\n");
671 if (stg)
672 IStorage_Release(stg);
674 /* open like Project 2003 */
675 stg = NULL;
676 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
677 ok(r == S_OK, "should succeed\n");
678 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg2);
679 ok(r == S_OK, "should succeed\n");
680 if (stg2)
681 IStorage_Release(stg2);
682 if (stg)
683 IStorage_Release(stg);
685 stg = NULL;
686 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
687 ok(r == STG_E_INVALIDFLAG, "should fail\n");
689 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
690 ok(r == STG_E_INVALIDFLAG, "should fail\n");
692 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
693 ok(r == STG_E_INVALIDFLAG, "should fail\n");
695 r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
696 ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
698 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
699 ok(r == STG_E_INVALIDFLAG, "should fail\n");
701 r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
702 ok(r == STG_E_INVALIDFLAG, "should fail\n");
704 r = DeleteFileA(filenameA);
705 ok(r, "file didn't exist\n");
708 static void test_storage_suminfo(void)
710 IStorage *stg = NULL;
711 IPropertySetStorage *propset = NULL;
712 IPropertyStorage *ps = NULL;
713 HRESULT r;
715 DeleteFileA(filenameA);
717 /* create the file */
718 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
719 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
720 ok(r==S_OK, "StgCreateDocfile failed\n");
722 r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
723 ok(r == S_OK, "query interface failed\n");
725 /* delete it */
726 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
727 ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
729 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
730 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
731 ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
733 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
734 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
735 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
737 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
738 STGM_READ, &ps );
739 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
741 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
742 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
744 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
745 STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
746 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
748 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
749 STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
750 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
752 /* now try really creating a property set */
753 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
754 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
755 ok(r == S_OK, "failed to create property set storage\n");
757 if( ps )
758 IPropertyStorage_Release(ps);
760 /* now try creating the same thing again */
761 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
762 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
763 ok(r == S_OK, "failed to create property set storage\n");
764 if( ps )
765 IPropertyStorage_Release(ps);
767 /* should be able to open it */
768 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
769 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
770 ok(r == S_OK, "open failed\n");
771 if(r == S_OK)
772 IPropertyStorage_Release(ps);
774 /* delete it */
775 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
776 ok(r == S_OK, "failed to delete property set storage\n");
778 /* try opening with an invalid FMTID */
779 r = IPropertySetStorage_Open( propset, NULL,
780 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
781 ok(r == E_INVALIDARG, "open succeeded\n");
782 if(r == S_OK)
783 IPropertyStorage_Release(ps);
785 /* try a bad guid */
786 r = IPropertySetStorage_Open( propset, &IID_IStorage,
787 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
788 ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
789 if(r == S_OK)
790 IPropertyStorage_Release(ps);
793 /* try some invalid flags */
794 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
795 STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
796 ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
797 if(r == S_OK)
798 IPropertyStorage_Release(ps);
800 /* after deleting it, it should be gone */
801 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
802 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
803 ok(r == STG_E_FILENOTFOUND, "open failed\n");
804 if(r == S_OK)
805 IPropertyStorage_Release(ps);
807 r = IPropertySetStorage_Release( propset );
808 ok(r == 1, "ref count wrong\n");
810 r = IStorage_Release(stg);
811 ok(r == 0, "ref count wrong\n");
813 DeleteFileA(filenameA);
816 static void test_storage_refcount(void)
818 IStorage *stg = NULL;
819 IStorage *stgprio = NULL;
820 HRESULT r;
821 IStream *stm = NULL;
822 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
823 LARGE_INTEGER pos;
824 ULARGE_INTEGER upos;
825 STATSTG stat;
826 char buffer[10];
828 DeleteFileA(filenameA);
830 /* create the file */
831 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
832 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
833 ok(r==S_OK, "StgCreateDocfile failed\n");
835 r = WriteClassStg( stg, &test_stg_cls );
836 ok( r == S_OK, "WriteClassStg failed\n");
838 r = IStorage_Commit( stg, STGC_DEFAULT );
839 ok( r == S_OK, "IStorage_Commit failed\n");
841 /* now create a stream */
842 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
843 ok(r==S_OK, "IStorage->CreateStream failed\n");
845 r = IStorage_Release( stg );
846 ok (r == 0, "storage not released\n");
848 pos.QuadPart = 0;
849 r = IStream_Seek( stm, pos, 0, &upos );
850 ok (r == STG_E_REVERTED, "seek should fail\n");
852 r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
853 ok (r == STG_E_REVERTED, "stat should fail\n");
855 r = IStream_Write( stm, "Test string", strlen("Test string"), NULL);
856 ok (r == STG_E_REVERTED, "IStream_Write should return STG_E_REVERTED instead of 0x%08x\n", r);
858 r = IStream_Read( stm, buffer, sizeof(buffer), NULL);
859 ok (r == STG_E_REVERTED, "IStream_Read should return STG_E_REVERTED instead of 0x%08x\n", r);
861 r = IStream_Release(stm);
862 ok (r == 0, "stream not released\n");
864 /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
865 * StgOpenStorage calls in transacted mode */
866 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio);
867 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
869 todo_wine {
870 /* non-transacted mode read/write fails */
871 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
872 ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r);
875 /* non-transacted mode read-only succeeds */
876 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg);
877 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
878 IStorage_Release(stg);
880 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
881 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
882 if(stg)
884 static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
885 static const WCHAR stgname2[] = { 'C','V','_','i','e','w',0 };
886 static const WCHAR stmname2[] = { 'V','a','r','2','D','a','t','a',0 };
887 IStorage *stg2;
888 IStorage *stg3;
889 STATSTG statstg;
891 r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
892 ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r);
893 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
894 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
895 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
896 ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
897 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg.grfMode);
898 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
899 ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
900 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
901 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
903 r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
904 ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
906 r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
907 ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r);
908 ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)),
909 "Statstg pwcsName should have been the name the storage was created with\n");
910 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
911 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
912 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
913 ok(statstg.grfMode == STGM_SHARE_EXCLUSIVE,
914 "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%x\n", statstg.grfMode);
915 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
916 ok(IsEqualCLSID(&statstg.clsid, &CLSID_NULL), "Statstg clsid is not CLSID_NULL\n");
917 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
918 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
919 CoTaskMemFree(statstg.pwcsName);
921 r = IStorage_CreateStorage( stg2, stgname2, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stg3 );
922 ok(r == STG_E_ACCESSDENIED, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
924 r = IStorage_CreateStream( stg2, stmname2, STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
925 ok(r == STG_E_ACCESSDENIED, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
927 IStorage_Release(stg2);
929 r = IStorage_Release(stg);
930 ok(r == 0, "wrong ref count\n");
933 /* Multiple STGM_PRIORITY opens are possible. */
934 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
935 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
936 if(stg)
938 r = IStorage_Release(stg);
939 ok(r == 0, "wrong ref count\n");
942 r = StgOpenStorage( NULL, stgprio, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
943 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
944 if(stg)
946 static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
947 IStorage *stg2;
948 STATSTG statstg;
950 r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
951 ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r);
952 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
953 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
954 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
955 ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
956 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg.grfMode);
957 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
958 ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
959 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
960 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
962 r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
963 ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
965 IStorage_Release(stg2);
967 r = IStorage_Commit( stg, 0 );
968 ok(r == S_OK, "Commit should have succeeded instead of returning 0x%08x\n", r);
970 r = IStorage_Release(stg);
971 ok(r == 0, "wrong ref count\n");
973 /* IStorage_Release(stgprio) not necessary because StgOpenStorage released it. */
975 DeleteFileA(filenameA);
978 static void test_writeclassstg(void)
980 IStorage *stg = NULL;
981 HRESULT r;
982 CLSID temp_cls;
984 DeleteFileA(filenameA);
986 /* create the file */
987 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
988 STGM_READWRITE, 0, &stg);
989 ok(r==S_OK, "StgCreateDocfile failed\n");
991 r = ReadClassStg( NULL, NULL );
992 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
994 r = ReadClassStg( stg, NULL );
995 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
997 temp_cls.Data1 = 0xdeadbeef;
998 r = ReadClassStg( stg, &temp_cls );
999 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
1001 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
1003 r = WriteClassStg( NULL, NULL );
1004 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
1006 r = WriteClassStg( stg, NULL );
1007 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
1009 r = WriteClassStg( stg, &test_stg_cls );
1010 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
1012 r = ReadClassStg( stg, &temp_cls );
1013 ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
1014 ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
1016 r = IStorage_Release( stg );
1017 ok (r == 0, "storage not released\n");
1019 DeleteFileA(filenameA);
1022 static void test_streamenum(void)
1024 IStorage *stg = NULL;
1025 HRESULT r;
1026 IStream *stm = NULL;
1027 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1028 static const WCHAR stmname2[] = { 'A','B','C','D','E','F','G','H','I',0 };
1029 static const WCHAR stmname3[] = { 'A','B','C','D','E','F','G','H','I','J',0 };
1030 STATSTG stat;
1031 IEnumSTATSTG *ee = NULL;
1032 ULONG count;
1034 DeleteFileA(filenameA);
1036 /* create the file */
1037 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1038 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1039 ok(r==S_OK, "StgCreateDocfile failed\n");
1041 r = WriteClassStg( stg, &test_stg_cls );
1042 ok( r == S_OK, "WriteClassStg failed\n");
1044 r = IStorage_Commit( stg, STGC_DEFAULT );
1045 ok( r == S_OK, "IStorage_Commit failed\n");
1047 /* now create a stream */
1048 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1049 ok(r==S_OK, "IStorage->CreateStream failed\n");
1051 r = IStream_Release(stm);
1053 /* first enum ... should be 1 stream */
1054 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
1055 ok(r==S_OK, "IStorage->EnumElements failed\n");
1057 count = 0xf00;
1058 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1059 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1060 ok(count == 1, "count wrong\n");
1062 if (r == S_OK)
1063 CoTaskMemFree(stat.pwcsName);
1065 r = IEnumSTATSTG_Release(ee);
1066 ok(r==S_OK, "EnumSTATSTG_Release failed with error 0x%08x\n", r);
1068 /* second enum... destroy the stream before reading */
1069 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
1070 ok(r==S_OK, "IStorage->EnumElements failed\n");
1072 r = IStorage_DestroyElement(stg, stmname);
1073 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1075 count = 0xf00;
1076 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1077 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
1078 ok(count == 0, "count wrong\n");
1080 /* reset and try again */
1081 r = IEnumSTATSTG_Reset(ee);
1082 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1084 count = 0xf00;
1085 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1086 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
1087 ok(count == 0, "count wrong\n");
1089 /* add a stream before reading */
1090 r = IEnumSTATSTG_Reset(ee);
1091 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1093 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1094 ok(r==S_OK, "IStorage->CreateStream failed\n");
1096 r = IStream_Release(stm);
1097 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1099 count = 0xf00;
1100 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1101 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1102 ok(count == 1, "count wrong\n");
1104 if (r == S_OK)
1106 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1107 CoTaskMemFree(stat.pwcsName);
1110 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1111 ok(r==S_OK, "IStorage->CreateStream failed\n");
1113 r = IStream_Release(stm);
1114 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1116 count = 0xf00;
1117 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1118 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1119 ok(count == 1, "count wrong\n");
1121 if (r == S_OK)
1123 ok(lstrcmpiW(stat.pwcsName, stmname2) == 0, "expected ABCDEFGHI, got %s\n", wine_dbgstr_w(stat.pwcsName));
1124 CoTaskMemFree(stat.pwcsName);
1127 /* delete previous and next stream after reading */
1128 r = IStorage_CreateStream(stg, stmname3, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1129 ok(r==S_OK, "IStorage->CreateStream failed\n");
1131 r = IStream_Release(stm);
1132 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1134 r = IEnumSTATSTG_Reset(ee);
1135 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1137 count = 0xf00;
1138 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1139 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1140 ok(count == 1, "count wrong\n");
1142 if (r == S_OK)
1144 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1145 CoTaskMemFree(stat.pwcsName);
1148 r = IStorage_DestroyElement(stg, stmname);
1149 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1151 r = IStorage_DestroyElement(stg, stmname2);
1152 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1154 count = 0xf00;
1155 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1156 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1157 ok(count == 1, "count wrong\n");
1159 if (r == S_OK)
1161 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1162 CoTaskMemFree(stat.pwcsName);
1165 r = IStorage_Release( stg );
1166 todo_wine ok (r == 0, "storage not released\n");
1168 /* enumerator is still valid and working after the storage is released */
1169 r = IEnumSTATSTG_Reset(ee);
1170 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1172 count = 0xf00;
1173 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1174 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1175 ok(count == 1, "count wrong\n");
1177 if (r == S_OK)
1179 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1180 CoTaskMemFree(stat.pwcsName);
1183 /* the storage is left open until the enumerator is freed */
1184 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE |
1185 STGM_READWRITE |STGM_TRANSACTED, NULL, 0, &stg);
1186 ok(r==STG_E_SHAREVIOLATION ||
1187 r==STG_E_LOCKVIOLATION, /* XP-SP2/W2K3-SP1 and below */
1188 "StgCreateDocfile failed, res=%x\n", r);
1190 r = IEnumSTATSTG_Release(ee);
1191 ok (r == 0, "enum not released\n");
1193 DeleteFileA(filenameA);
1196 static void test_transact(void)
1198 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1199 HRESULT r;
1200 IStream *stm = NULL;
1201 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1202 static const WCHAR stmname2[] = { 'F','O','O',0 };
1203 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1204 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1206 DeleteFileA(filenameA);
1208 /* create the file */
1209 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1210 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1211 ok(r==S_OK, "StgCreateDocfile failed\n");
1213 /* commit a new stream and storage */
1214 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1215 ok(r==S_OK, "IStorage->CreateStream failed\n");
1217 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1218 ok(r==S_OK, "IStream->Write failed\n");
1220 IStream_Release(stm);
1222 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1223 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1225 if (r == S_OK)
1227 /* Create two substorages but only commit one */
1228 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1229 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1231 if (r == S_OK)
1232 IStorage_Release(stg3);
1234 r = IStorage_Commit(stg, 0);
1235 ok(r==S_OK, "IStorage->Commit failed\n");
1237 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1238 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1240 if (r == S_OK)
1241 IStorage_Release(stg3);
1243 IStorage_Release(stg2);
1246 /* now create a stream and storage, but don't commit them */
1247 stm = NULL;
1248 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1249 ok(r==S_OK, "IStorage->CreateStream failed\n");
1251 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
1252 ok(r==S_OK, "IStream->Write failed\n");
1254 /* IStream::Commit does nothing for OLE storage streams */
1255 r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
1256 ok(r==S_OK, "IStream->Commit failed\n");
1258 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1259 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1261 if (r == S_OK)
1262 IStorage_Release(stg2);
1264 IStream_Release(stm);
1266 IStorage_Release(stg);
1268 stm = NULL;
1269 stg = NULL;
1270 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
1271 ok(r==S_OK, "StgOpenStorage failed\n");
1273 if (!stg)
1274 return;
1276 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1277 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1279 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1280 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1282 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1283 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1285 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1286 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1288 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1289 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1290 if (r == S_OK)
1291 IStream_Release(stm);
1293 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1294 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1295 if (r == S_OK)
1296 IStorage_Release(stg2);
1298 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1299 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1301 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1302 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1303 if (r == S_OK)
1304 IStream_Release(stm);
1306 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1307 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1308 if (r == S_OK)
1310 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1311 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1312 if (r == S_OK)
1313 IStorage_Release(stg3);
1315 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1316 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1317 if (r == S_OK)
1318 IStorage_Release(stg3);
1320 IStorage_Release(stg2);
1323 IStorage_Release(stg);
1325 r = DeleteFileA(filenameA);
1326 ok( r == TRUE, "deleted file\n");
1329 static void test_substorage_share(void)
1331 IStorage *stg, *stg2, *stg3;
1332 IStream *stm, *stm2;
1333 HRESULT r;
1334 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1335 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1336 static const WCHAR othername[] = { 'N','E','W','N','A','M','E',0 };
1338 DeleteFileA(filenameA);
1340 /* create the file */
1341 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1342 STGM_READWRITE, 0, &stg);
1343 ok(r==S_OK, "StgCreateDocfile failed\n");
1345 /* create a read/write storage and try to open it again */
1346 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1347 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1349 if (r == S_OK)
1351 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1352 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1354 if (r == S_OK)
1355 IStorage_Release(stg3);
1357 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1358 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1360 if (r == S_OK)
1361 IStorage_Release(stg3);
1363 /* cannot rename the storage while it's open */
1364 r = IStorage_RenameElement(stg, stgname, othername);
1365 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1366 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stgname);
1368 /* destroying an object while it's open invalidates it */
1369 r = IStorage_DestroyElement(stg, stgname);
1370 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1372 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1373 ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r);
1375 if (r == S_OK)
1376 IStream_Release(stm);
1378 IStorage_Release(stg2);
1381 /* create a read/write stream and try to open it again */
1382 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1383 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
1385 if (r == S_OK)
1387 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1388 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1390 if (r == S_OK)
1391 IStream_Release(stm2);
1393 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1394 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1396 if (r == S_OK)
1397 IStream_Release(stm2);
1399 /* cannot rename the stream while it's open */
1400 r = IStorage_RenameElement(stg, stmname, othername);
1401 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1402 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stmname);
1404 /* destroying an object while it's open invalidates it */
1405 r = IStorage_DestroyElement(stg, stmname);
1406 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1408 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1409 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1411 IStream_Release(stm);
1414 IStorage_Release(stg);
1416 r = DeleteFileA(filenameA);
1417 ok( r == TRUE, "deleted file\n");
1420 static void test_revert(void)
1422 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1423 HRESULT r;
1424 IStream *stm = NULL, *stm2 = NULL;
1425 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1426 static const WCHAR stmname2[] = { 'F','O','O',0 };
1427 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1428 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1429 STATSTG statstg;
1431 DeleteFileA(filenameA);
1433 /* create the file */
1434 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1435 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1436 ok(r==S_OK, "StgCreateDocfile failed\n");
1438 /* commit a new stream and storage */
1439 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1440 ok(r==S_OK, "IStorage->CreateStream failed\n");
1442 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1443 ok(r==S_OK, "IStream->Write failed\n");
1445 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1446 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1448 if (r == S_OK)
1450 /* Create two substorages but only commit one */
1451 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1452 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1454 if (r == S_OK)
1455 IStorage_Release(stg3);
1457 r = IStorage_Commit(stg, 0);
1458 ok(r==S_OK, "IStorage->Commit failed\n");
1460 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1461 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1463 if (r == S_OK)
1464 IStorage_Release(stg3);
1467 /* now create a stream and storage, then revert */
1468 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
1469 ok(r==S_OK, "IStorage->CreateStream failed\n");
1471 r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1472 ok(r==S_OK, "IStream->Write failed\n");
1474 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1475 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1477 r = IStorage_Revert(stg);
1478 ok(r==S_OK, "Storage_Revert failed with error 0x%08x\n", r);
1480 /* all open objects become invalid */
1481 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1482 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1484 r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL);
1485 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1487 r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1488 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1490 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1491 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1493 IStream_Release(stm);
1494 IStream_Release(stm2);
1495 IStorage_Release(stg2);
1496 IStorage_Release(stg3);
1498 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1499 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1501 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1502 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1504 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1505 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1507 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1508 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1510 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1511 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1512 if (r == S_OK)
1513 IStream_Release(stm);
1515 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1516 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1517 if (r == S_OK)
1518 IStorage_Release(stg2);
1520 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1521 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1523 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1524 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1525 if (r == S_OK)
1526 IStream_Release(stm);
1528 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1529 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1530 if (r == S_OK)
1532 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1533 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1534 if (r == S_OK)
1535 IStorage_Release(stg3);
1537 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1538 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1539 if (r == S_OK)
1540 IStorage_Release(stg3);
1542 IStorage_Release(stg2);
1545 IStorage_Release(stg);
1547 r = DeleteFileA(filenameA);
1548 ok( r == TRUE, "deleted file\n");
1550 /* Revert only invalidates objects in transacted mode */
1551 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1552 STGM_READWRITE, 0, &stg);
1553 ok(r==S_OK, "StgCreateDocfile failed\n");
1555 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1556 ok(r==S_OK, "IStorage->CreateStream failed\n");
1558 r = IStorage_Revert(stg);
1559 ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1561 r = IStream_Write(stm, "this works\n", 11, NULL);
1562 ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1564 IStream_Release(stm);
1565 IStorage_Release(stg);
1567 r = DeleteFileA(filenameA);
1568 ok( r == TRUE, "deleted file\n");
1571 static void test_parent_free(void)
1573 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1574 HRESULT r;
1575 IStream *stm = NULL;
1576 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1577 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1578 ULONG ref;
1579 STATSTG statstg;
1581 DeleteFileA(filenameA);
1583 /* create the file */
1584 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1585 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1586 ok(r==S_OK, "StgCreateDocfile failed\n");
1588 /* create a new storage */
1589 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1590 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1592 if (r == S_OK)
1594 /* now create a stream inside the new storage */
1595 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1596 ok(r==S_OK, "IStorage->CreateStream failed\n");
1598 if (r == S_OK)
1600 /* create a storage inside the new storage */
1601 r = IStorage_CreateStorage(stg2, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg3 );
1602 ok(r==S_OK, "IStorage->CreateStorage failed\n");
1605 /* free the parent */
1606 ref = IStorage_Release(stg2);
1607 ok(ref == 0, "IStorage still has %u references\n", ref);
1609 /* child objects are invalid */
1610 if (r == S_OK)
1612 r = IStream_Write(stm, "this should fail\n", 17, NULL);
1613 ok(r==STG_E_REVERTED, "IStream->Write should fail, hr=%x\n", r);
1615 IStream_Release(stm);
1617 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1618 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1620 r = IStorage_SetStateBits(stg3, 1, 1);
1621 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1623 IStorage_Release(stg3);
1627 IStorage_Release(stg);
1629 r = DeleteFileA(filenameA);
1630 ok( r == TRUE, "deleted file\n");
1633 static void test_nonroot_transacted(void)
1635 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1636 HRESULT r;
1637 IStream *stm = NULL;
1638 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1639 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1640 static const WCHAR stmname2[] = { 'F','O','O',0 };
1642 DeleteFileA(filenameA);
1644 /* create a transacted file */
1645 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1646 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1647 ok(r==S_OK, "StgCreateDocfile failed\n");
1649 /* create a transacted substorage */
1650 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1651 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1653 if (r == S_OK)
1655 /* create and commit stmname */
1656 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1657 ok(r==S_OK, "IStorage->CreateStream failed\n");
1658 if (r == S_OK)
1659 IStream_Release(stm);
1661 IStorage_Commit(stg2, 0);
1663 /* create and revert stmname2 */
1664 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1665 ok(r==S_OK, "IStorage->CreateStream failed\n");
1666 if (r == S_OK)
1667 IStream_Release(stm);
1669 IStorage_Revert(stg2);
1671 /* check that Commit and Revert really worked */
1672 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1673 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1674 if (r == S_OK)
1675 IStream_Release(stm);
1677 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1678 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1679 if (r == S_OK)
1680 IStream_Release(stm);
1682 IStorage_Release(stg2);
1685 /* create a read-only transacted substorage */
1686 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2);
1687 ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r);
1689 if (r == S_OK)
1691 /* The storage can be modified. */
1692 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1693 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1694 if (r == S_OK)
1695 IStorage_Release(stg3);
1697 /* But changes cannot be committed. */
1698 r = IStorage_Commit(stg2, 0);
1699 ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r);
1701 IStorage_Release(stg2);
1704 IStorage_Release(stg);
1706 /* create a non-transacted file */
1707 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1708 STGM_READWRITE, 0, &stg);
1709 ok(r==S_OK, "StgCreateDocfile failed\n");
1711 /* create a transacted substorage */
1712 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1713 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1715 if (r == S_OK)
1717 /* create and commit stmname */
1718 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1719 ok(r==S_OK, "IStorage->CreateStream failed\n");
1720 if (r == S_OK)
1721 IStream_Release(stm);
1723 IStorage_Commit(stg2, 0);
1725 /* create and revert stmname2 */
1726 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1727 ok(r==S_OK, "IStorage->CreateStream failed\n");
1728 if (r == S_OK)
1729 IStream_Release(stm);
1731 IStorage_Revert(stg2);
1733 /* check that Commit and Revert really worked */
1734 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1735 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1736 if (r == S_OK)
1737 IStream_Release(stm);
1739 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1740 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1741 if (r == S_OK)
1742 IStream_Release(stm);
1744 IStorage_Release(stg2);
1747 IStorage_Release(stg);
1749 r = DeleteFileA(filenameA);
1750 ok( r == TRUE, "deleted file\n");
1753 static void test_ReadClassStm(void)
1755 CLSID clsid;
1756 HRESULT hr;
1757 IStream *pStream;
1758 static const LARGE_INTEGER llZero;
1760 hr = ReadClassStm(NULL, &clsid);
1761 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1763 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1764 ok_ole_success(hr, "CreateStreamOnHGlobal");
1765 hr = WriteClassStm(pStream, &test_stg_cls);
1766 ok_ole_success(hr, "WriteClassStm");
1768 hr = ReadClassStm(pStream, NULL);
1769 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1771 /* test not rewound stream */
1772 hr = ReadClassStm(pStream, &clsid);
1773 ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1774 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1776 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1777 ok_ole_success(hr, "IStream_Seek");
1778 hr = ReadClassStm(pStream, &clsid);
1779 ok_ole_success(hr, "ReadClassStm");
1780 ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
1782 IStream_Release(pStream);
1785 struct access_res
1787 BOOL gothandle;
1788 DWORD lasterr;
1789 BOOL ignore;
1792 static const struct access_res create[16] =
1794 { TRUE, ERROR_SUCCESS, TRUE },
1795 { TRUE, ERROR_SUCCESS, TRUE },
1796 { TRUE, ERROR_SUCCESS, FALSE },
1797 { TRUE, ERROR_SUCCESS, FALSE },
1798 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1799 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1800 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1801 { TRUE, ERROR_SUCCESS, FALSE },
1802 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1803 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1804 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1805 { TRUE, ERROR_SUCCESS, TRUE },
1806 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1807 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1808 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1809 { TRUE, ERROR_SUCCESS, TRUE }
1812 static const struct access_res create_commit[16] =
1814 { TRUE, ERROR_SUCCESS, TRUE },
1815 { TRUE, ERROR_SUCCESS, TRUE },
1816 { TRUE, ERROR_SUCCESS, FALSE },
1817 { TRUE, ERROR_SUCCESS, FALSE },
1818 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1819 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1820 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1821 { TRUE, ERROR_SUCCESS, FALSE },
1822 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1823 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1824 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1825 { TRUE, ERROR_SUCCESS, TRUE },
1826 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1827 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1828 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1829 { TRUE, ERROR_SUCCESS, TRUE }
1832 static const struct access_res create_close[16] =
1834 { TRUE, ERROR_SUCCESS, FALSE },
1835 { TRUE, ERROR_SUCCESS, FALSE },
1836 { TRUE, ERROR_SUCCESS, FALSE },
1837 { TRUE, ERROR_SUCCESS, FALSE },
1838 { TRUE, ERROR_SUCCESS, FALSE },
1839 { TRUE, ERROR_SUCCESS, FALSE },
1840 { TRUE, ERROR_SUCCESS, FALSE },
1841 { TRUE, ERROR_SUCCESS, FALSE },
1842 { TRUE, ERROR_SUCCESS, FALSE },
1843 { TRUE, ERROR_SUCCESS, FALSE },
1844 { TRUE, ERROR_SUCCESS, FALSE },
1845 { TRUE, ERROR_SUCCESS, FALSE },
1846 { TRUE, ERROR_SUCCESS, FALSE },
1847 { TRUE, ERROR_SUCCESS, FALSE },
1848 { TRUE, ERROR_SUCCESS, FALSE },
1849 { TRUE, ERROR_SUCCESS }
1852 static const DWORD access_modes[4] = {
1854 GENERIC_READ,
1855 GENERIC_WRITE,
1856 GENERIC_READ | GENERIC_WRITE
1859 static const DWORD share_modes[4] = {
1861 FILE_SHARE_READ,
1862 FILE_SHARE_WRITE,
1863 FILE_SHARE_READ | FILE_SHARE_WRITE
1866 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1868 int i, j, idx = 0;
1870 for (i = 0; i < sizeof(access_modes)/sizeof(access_modes[0]); i++)
1872 for (j = 0; j < sizeof(share_modes)/sizeof(share_modes[0]); j++)
1874 DWORD lasterr;
1875 HANDLE hfile;
1877 if (ares[idx].ignore)
1878 continue;
1880 SetLastError(0xdeadbeef);
1881 hfile = CreateFileA(file, access_modes[i], share_modes[j], NULL, OPEN_EXISTING,
1882 FILE_ATTRIBUTE_NORMAL, 0);
1883 lasterr = GetLastError();
1885 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
1886 "(%d, handle, %d): Expected %d, got %d\n",
1887 line, idx, ares[idx].gothandle,
1888 (hfile != INVALID_HANDLE_VALUE));
1890 ok(lasterr == ares[idx].lasterr ||
1891 broken(lasterr == 0xdeadbeef) /* win9x */,
1892 "(%d, lasterr, %d): Expected %d, got %d\n",
1893 line, idx, ares[idx].lasterr, lasterr);
1895 CloseHandle(hfile);
1896 idx++;
1901 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1903 static void test_access(void)
1905 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1906 static const char fileA[] = "winetest";
1907 IStorage *stg;
1908 HRESULT hr;
1910 /* STGM_TRANSACTED */
1911 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1912 STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, &stg);
1913 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1915 test_file_access(fileA, create);
1917 hr = IStorage_Commit(stg, STGC_DEFAULT);
1918 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1920 test_file_access(fileA, create_commit);
1922 IStorage_Release(stg);
1924 test_file_access(fileA, create_close);
1926 DeleteFileA(fileA);
1928 /* STGM_DIRECT */
1929 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1930 STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &stg);
1931 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1933 test_file_access(fileA, create);
1935 hr = IStorage_Commit(stg, STGC_DEFAULT);
1936 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1938 test_file_access(fileA, create_commit);
1940 IStorage_Release(stg);
1942 test_file_access(fileA, create_close);
1944 DeleteFileA(fileA);
1946 /* STGM_SHARE_DENY_NONE */
1947 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1948 STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
1949 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1951 test_file_access(fileA, create);
1953 hr = IStorage_Commit(stg, STGC_DEFAULT);
1954 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1956 test_file_access(fileA, create_commit);
1958 IStorage_Release(stg);
1960 test_file_access(fileA, create_close);
1962 DeleteFileA(fileA);
1964 /* STGM_SHARE_DENY_READ */
1965 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1966 STGM_SHARE_DENY_READ | STGM_TRANSACTED, 0, &stg);
1967 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1969 test_file_access(fileA, create);
1971 hr = IStorage_Commit(stg, STGC_DEFAULT);
1972 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1974 test_file_access(fileA, create_commit);
1976 IStorage_Release(stg);
1978 test_file_access(fileA, create_close);
1980 DeleteFileA(fileA);
1982 /* STGM_SHARE_DENY_WRITE */
1983 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1984 STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
1985 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1987 test_file_access(fileA, create);
1989 hr = IStorage_Commit(stg, STGC_DEFAULT);
1990 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1992 test_file_access(fileA, create_commit);
1994 IStorage_Release(stg);
1996 test_file_access(fileA, create_close);
1998 DeleteFileA(fileA);
2000 /* STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE - reader mode for direct SWMR mode */
2001 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
2002 ok(hr == S_OK, "got %08x\n", hr);
2003 IStorage_Release(stg);
2005 hr = StgOpenStorage(fileW, NULL, STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
2006 ok(hr == S_OK || broken(hr == STG_E_INVALIDFLAG), "got %08x\n", hr);
2007 if(hr != S_OK)
2008 return;
2010 test_file_access(fileA, create);
2012 IStorage_Release(stg);
2013 test_file_access(fileA, create_close);
2015 DeleteFileA(fileA);
2018 static void test_readonly(void)
2020 IStorage *stg, *stg2, *stg3;
2021 IStream *stream;
2022 HRESULT hr;
2023 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
2024 static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
2025 static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
2027 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
2028 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2029 if (SUCCEEDED(hr))
2031 hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
2032 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2033 if (SUCCEEDED(hr))
2035 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
2036 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2037 if (SUCCEEDED(hr))
2038 IStream_Release(stream);
2039 IStorage_Release(stg2);
2041 IStorage_Release(stg);
2044 /* re-open read only */
2045 hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
2046 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2047 if (SUCCEEDED(hr))
2049 hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
2050 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2051 if (SUCCEEDED(hr))
2053 /* CreateStream on read-only storage, name exists */
2054 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
2055 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2056 if (SUCCEEDED(hr))
2057 IStream_Release(stream);
2059 /* CreateStream on read-only storage, name does not exist */
2060 hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
2061 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2062 if (SUCCEEDED(hr))
2063 IStream_Release(stream);
2065 /* CreateStorage on read-only storage, name exists */
2066 hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
2067 ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
2068 if (SUCCEEDED(hr))
2069 IStorage_Release(stg3);
2071 /* CreateStorage on read-only storage, name does not exist */
2072 hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
2073 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2074 if (SUCCEEDED(hr))
2075 IStorage_Release(stg3);
2077 /* DestroyElement on read-only storage, name exists */
2078 hr = IStorage_DestroyElement( stg2, streamW );
2079 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2081 /* DestroyElement on read-only storage, name does not exist */
2082 hr = IStorage_DestroyElement( stg2, storageW );
2083 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2085 IStorage_Release(stg2);
2088 IStorage_Release(stg);
2091 DeleteFileA("winetest");
2094 static void test_simple(void)
2096 /* Tests for STGM_SIMPLE mode */
2098 IStorage *stg, *stg2;
2099 HRESULT r;
2100 IStream *stm;
2101 static const WCHAR stgname[] = { 'S','t','g',0 };
2102 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2103 static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
2104 LARGE_INTEGER pos;
2105 ULARGE_INTEGER upos;
2106 DWORD count;
2107 STATSTG stat;
2109 DeleteFileA(filenameA);
2111 r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
2112 ok(r == S_OK, "got %08x\n", r);
2114 r = IStorage_CreateStorage(stg, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2);
2115 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2116 if (SUCCEEDED(r)) IStorage_Release(stg2);
2118 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2119 ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
2120 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2121 ok(r == S_OK, "got %08x\n", r);
2123 upos.QuadPart = 6000;
2124 r = IStream_SetSize(stm, upos);
2125 ok(r == S_OK, "got %08x\n", r);
2127 r = IStream_Write(stm, "foo", 3, &count);
2128 ok(r == S_OK, "got %08x\n", r);
2129 ok(count == 3, "got %d\n", count);
2131 pos.QuadPart = 0;
2132 r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
2133 ok(r == S_OK, "got %08x\n", r);
2134 ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
2136 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2137 ok(r == S_OK ||
2138 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2139 "got %08x\n", r);
2140 if (r == S_OK)
2141 ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
2143 pos.QuadPart = 1;
2144 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
2145 ok(r == S_OK, "got %08x\n", r);
2146 ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
2148 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2149 ok(r == S_OK ||
2150 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2151 "got %08x\n", r);
2152 if (r == S_OK)
2153 ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
2155 IStream_Release(stm);
2157 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2158 ok(r == S_OK, "got %08x\n", r);
2160 upos.QuadPart = 100;
2161 r = IStream_SetSize(stm, upos);
2162 ok(r == S_OK, "got %08x\n", r);
2164 r = IStream_Write(stm, "foo", 3, &count);
2165 ok(r == S_OK, "got %08x\n", r);
2166 ok(count == 3, "got %d\n", count);
2168 IStream_Release(stm);
2170 IStorage_Commit(stg, STGC_DEFAULT);
2171 IStorage_Release(stg);
2173 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
2174 if (r == STG_E_INVALIDFLAG)
2176 win_skip("Flag combination is not supported on NT4 and below\n");
2177 DeleteFileA(filenameA);
2178 return;
2180 ok(r == S_OK, "got %08x\n", r);
2182 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg2);
2183 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2184 if (SUCCEEDED(r)) IStorage_Release(stg2);
2186 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2187 ok(r == S_OK, "got %08x\n", r);
2189 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2190 ok(r == S_OK, "got %08x\n", r);
2191 ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
2193 IStream_Release(stm);
2195 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2196 ok(r == S_OK, "got %08x\n", r);
2198 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2199 ok(r == S_OK, "got %08x\n", r);
2200 ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
2202 IStream_Release(stm);
2205 IStorage_Release(stg);
2207 DeleteFileA(filenameA);
2210 static void test_fmtusertypestg(void)
2212 IStorage *stg;
2213 IEnumSTATSTG *stat;
2214 HRESULT hr;
2215 static const char fileA[] = {'f','m','t','t','e','s','t',0};
2216 static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0};
2217 static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0};
2218 static const WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0};
2220 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
2221 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2223 if (SUCCEEDED(hr))
2225 /* try to write the stream */
2226 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2227 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2229 /* check that the stream was created */
2230 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2231 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2232 if (SUCCEEDED(hr))
2234 BOOL found = FALSE;
2235 STATSTG statstg;
2236 DWORD got;
2237 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2239 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2240 found = TRUE;
2241 else
2242 ok(0, "found unexpected stream or storage\n");
2243 CoTaskMemFree(statstg.pwcsName);
2245 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2246 IEnumSTATSTG_Release(stat);
2249 /* re-write the stream */
2250 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2251 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2253 /* check that the stream is still there */
2254 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2255 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2256 if (SUCCEEDED(hr))
2258 BOOL found = FALSE;
2259 STATSTG statstg;
2260 DWORD got;
2261 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2263 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2264 found = TRUE;
2265 else
2266 ok(0, "found unexpected stream or storage\n");
2267 CoTaskMemFree(statstg.pwcsName);
2269 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2270 IEnumSTATSTG_Release(stat);
2273 IStorage_Release(stg);
2274 DeleteFileA( fileA );
2278 static void test_references(void)
2280 IStorage *stg,*stg2;
2281 HRESULT hr;
2282 unsigned c1,c2;
2283 static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
2285 DeleteFileA(filenameA);
2287 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2288 ok(hr==S_OK, "StgCreateDocfile failed\n");
2290 if (SUCCEEDED(hr))
2292 IStorage_Release(stg);
2294 hr = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
2295 ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr);
2297 if (SUCCEEDED(hr))
2299 hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2);
2300 ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr);
2302 if (SUCCEEDED(hr))
2304 c1 = IStorage_AddRef(stg);
2305 ok(c1 == 2, "creating internal storage added references to ancestor\n");
2306 c1 = IStorage_AddRef(stg);
2307 IStorage_Release(stg2);
2308 c2 = IStorage_AddRef(stg) - 1;
2309 ok(c1 == c2, "releasing internal storage removed references to ancestor\n");
2311 c1 = IStorage_Release(stg);
2312 while ( c1 ) c1 = IStorage_Release(stg);
2316 DeleteFileA(filenameA);
2319 /* dest
2320 * |-StorageA
2321 * | `StreamA: "StreamA"
2322 * |-StorageB
2323 * | `StreamB: "StreamB"
2324 * `StreamC: "StreamC"
2326 static HRESULT create_test_file(IStorage *dest)
2328 IStorage *stgA = NULL, *stgB = NULL;
2329 IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
2330 const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
2331 const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
2332 const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
2333 ULONG bytes;
2334 HRESULT hr;
2336 hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
2337 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2338 if(FAILED(hr))
2339 goto cleanup;
2341 hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
2342 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2343 if(FAILED(hr))
2344 goto cleanup;
2346 hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
2347 ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
2349 hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
2350 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2351 if(FAILED(hr))
2352 goto cleanup;
2354 hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
2355 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2356 if(FAILED(hr))
2357 goto cleanup;
2359 hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
2360 ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
2362 hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
2363 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2364 if(FAILED(hr))
2365 goto cleanup;
2367 hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
2368 ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
2370 cleanup:
2371 if(strmC)
2372 IStream_Release(strmC);
2373 if(strmB)
2374 IStream_Release(strmB);
2375 if(stgB)
2376 IStorage_Release(stgB);
2377 if(strmA)
2378 IStream_Release(strmA);
2379 if(stgA)
2380 IStorage_Release(stgA);
2382 return hr;
2385 static void test_copyto(void)
2387 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2388 IStream *strm_tmp;
2389 WCHAR buf[64];
2390 HRESULT hr;
2392 /* create & populate file1 */
2393 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2394 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2395 if(FAILED(hr))
2396 goto cleanup;
2398 hr = create_test_file(file1);
2399 if(FAILED(hr))
2400 goto cleanup;
2402 /* create file2 */
2403 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2404 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2405 if(FAILED(hr))
2406 goto cleanup;
2408 /* copy file1 into file2 */
2409 hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2410 ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2412 hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2413 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2414 if(FAILED(hr))
2415 goto cleanup;
2417 /* verify that all of file1 was copied */
2418 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2419 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2420 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2422 if(SUCCEEDED(hr)){
2423 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2424 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2425 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2427 if(SUCCEEDED(hr)){
2428 memset(buf, 0, sizeof(buf));
2429 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2430 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2431 if(SUCCEEDED(hr))
2432 ok(strcmp_ww(buf, strmA_name) == 0,
2433 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2435 IStream_Release(strm_tmp);
2438 IStorage_Release(stg_tmp);
2441 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2442 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2443 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2445 if(SUCCEEDED(hr)){
2446 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2447 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2448 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2450 if(SUCCEEDED(hr)){
2451 memset(buf, 0, sizeof(buf));
2452 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2453 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2454 if(SUCCEEDED(hr))
2455 ok(strcmp_ww(buf, strmB_name) == 0,
2456 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2458 IStream_Release(strm_tmp);
2461 IStorage_Release(stg_tmp);
2464 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2465 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2466 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2468 if(SUCCEEDED(hr)){
2469 memset(buf, 0, sizeof(buf));
2470 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2471 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2472 if(SUCCEEDED(hr))
2473 ok(strcmp_ww(buf, strmC_name) == 0,
2474 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2476 IStream_Release(strm_tmp);
2479 cleanup:
2480 if(file1)
2481 IStorage_Release(file1);
2482 if(file2)
2483 IStorage_Release(file2);
2485 DeleteFileA(file1_nameA);
2486 DeleteFileA(file2_nameA);
2489 static void test_copyto_snbexclusions(void)
2491 static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2493 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2494 IStream *strm_tmp;
2495 WCHAR buf[64];
2496 HRESULT hr;
2498 /* create & populate file1 */
2499 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2500 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2501 if(FAILED(hr))
2502 goto cleanup;
2504 hr = create_test_file(file1);
2505 if(FAILED(hr))
2506 goto cleanup;
2508 /* create file2 */
2509 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2510 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2511 if(FAILED(hr))
2512 goto cleanup;
2514 /* copy file1 to file2 with name exclusions */
2515 hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2516 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2517 if(FAILED(hr))
2518 goto cleanup;
2520 /* verify that file1 copied over, respecting exclusions */
2521 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2522 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2523 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2524 if(SUCCEEDED(hr))
2525 IStorage_Release(stg_tmp);
2527 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2528 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2529 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2530 if(SUCCEEDED(hr))
2531 IStream_Release(strm_tmp);
2533 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2534 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2535 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2537 if(SUCCEEDED(hr)){
2538 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2539 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2540 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2542 if(SUCCEEDED(hr)){
2543 memset(buf, 0, sizeof(buf));
2544 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2545 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2546 if(SUCCEEDED(hr))
2547 ok(strcmp_ww(buf, strmB_name) == 0,
2548 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2550 IStream_Release(strm_tmp);
2553 IStorage_Release(stg_tmp);
2556 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2557 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2558 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2559 if(SUCCEEDED(hr))
2560 IStream_Release(strm_tmp);
2562 cleanup:
2563 if(file1)
2564 IStorage_Release(file1);
2565 if(file2)
2566 IStorage_Release(file2);
2568 DeleteFileA(file1_nameA);
2569 DeleteFileA(file2_nameA);
2572 static void test_copyto_iidexclusions_storage(void)
2574 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2575 IStream *strm_tmp;
2576 WCHAR buf[64];
2577 HRESULT hr;
2579 /* create & populate file1 */
2580 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2581 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2582 if(FAILED(hr))
2583 goto cleanup;
2585 hr = create_test_file(file1);
2586 if(FAILED(hr))
2587 goto cleanup;
2589 /* create file2 */
2590 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2591 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2592 if(FAILED(hr))
2593 goto cleanup;
2595 /* copy file1 to file2 with iid exclusions */
2596 hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2597 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2598 if(FAILED(hr))
2599 goto cleanup;
2601 /* verify that file1 copied over, respecting exclusions */
2602 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2603 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2604 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2605 if(SUCCEEDED(hr))
2606 IStorage_Release(stg_tmp);
2608 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2609 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2610 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2611 if(SUCCEEDED(hr))
2612 IStream_Release(strm_tmp);
2614 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2615 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2616 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2617 if(SUCCEEDED(hr))
2618 IStorage_Release(stg_tmp);
2620 hr = IStorage_OpenStream(file2, strmB_name, NULL,
2621 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2622 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2623 if(SUCCEEDED(hr))
2624 IStream_Release(strm_tmp);
2626 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2627 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2628 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2630 if(SUCCEEDED(hr)){
2631 memset(buf, 0, sizeof(buf));
2632 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2633 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2634 if(SUCCEEDED(hr))
2635 ok(strcmp_ww(buf, strmC_name) == 0,
2636 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2638 IStream_Release(strm_tmp);
2641 cleanup:
2642 if(file1)
2643 IStorage_Release(file1);
2644 if(file2)
2645 IStorage_Release(file2);
2647 DeleteFileA(file1_nameA);
2648 DeleteFileA(file2_nameA);
2651 static void test_copyto_iidexclusions_stream(void)
2653 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2654 IStream *strm_tmp;
2655 HRESULT hr;
2657 /* create & populate file1 */
2658 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2659 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2660 if(FAILED(hr))
2661 goto cleanup;
2663 hr = create_test_file(file1);
2664 if(FAILED(hr))
2665 goto cleanup;
2667 /* create file2 */
2668 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2669 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2670 if(FAILED(hr))
2671 goto cleanup;
2673 /* copy file1 to file2 with iid exclusions */
2674 hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2675 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2676 if(FAILED(hr))
2677 goto cleanup;
2679 /* verify that file1 copied over, respecting exclusions */
2680 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2681 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2682 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2684 if(SUCCEEDED(hr)){
2685 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2686 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2687 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2688 if(SUCCEEDED(hr))
2689 IStream_Release(strm_tmp);
2691 IStorage_Release(stg_tmp);
2694 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2695 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2696 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2698 if(SUCCEEDED(hr)){
2699 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2700 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2701 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2702 if(SUCCEEDED(hr))
2703 IStream_Release(strm_tmp);
2705 IStorage_Release(stg_tmp);
2708 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2709 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2710 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2711 if(SUCCEEDED(hr))
2712 IStream_Release(strm_tmp);
2714 cleanup:
2715 if(file1)
2716 IStorage_Release(file1);
2717 if(file2)
2718 IStorage_Release(file2);
2720 DeleteFileA(file1_nameA);
2721 DeleteFileA(file2_nameA);
2724 static void test_rename(void)
2726 IStorage *stg, *stg2;
2727 IStream *stm;
2728 HRESULT r;
2729 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2730 static const WCHAR stgname2[] = { 'S','T','G',0 };
2731 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2732 static const WCHAR stmname2[] = { 'E','N','T','S',0 };
2734 DeleteFileA(filenameA);
2736 /* create the file */
2737 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2738 STGM_READWRITE, 0, &stg);
2739 ok(r==S_OK, "StgCreateDocfile failed\n");
2741 /* create a substorage */
2742 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2743 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2745 /* create a stream in the substorage */
2746 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2747 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2748 IStream_Release(stm);
2750 /* rename the stream */
2751 r = IStorage_RenameElement(stg2, stmname, stmname2);
2752 ok(r==S_OK, "IStorage->RenameElement failed, hr=%08x\n", r);
2754 /* cannot open stream with old name */
2755 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2756 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2757 if (SUCCEEDED(r)) IStream_Release(stm);
2759 /* can open stream with new name */
2760 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2761 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2762 if (SUCCEEDED(r)) IStream_Release(stm);
2764 IStorage_Release(stg2);
2766 /* rename the storage */
2767 IStorage_RenameElement(stg, stgname, stgname2);
2769 /* cannot open storage with old name */
2770 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2771 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2772 if (SUCCEEDED(r)) IStorage_Release(stg2);
2774 /* can open storage with new name */
2775 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2776 ok(r==S_OK, "IStorage_OpenStream should fail, hr=%08x\n", r);
2777 if (SUCCEEDED(r))
2779 /* opened storage still has the stream */
2780 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2781 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2782 if (SUCCEEDED(r)) IStream_Release(stm);
2784 IStorage_Release(stg2);
2787 IStorage_Release(stg);
2789 r = DeleteFileA(filenameA);
2790 ok( r == TRUE, "deleted file\n");
2793 static void test_toplevel_stat(void)
2795 IStorage *stg = NULL;
2796 HRESULT r;
2797 STATSTG stat;
2798 char prev_dir[MAX_PATH];
2799 char temp[MAX_PATH];
2800 char full_path[MAX_PATH];
2801 LPSTR rel_pathA;
2802 WCHAR rel_path[MAX_PATH];
2804 DeleteFileA(filenameA);
2806 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2807 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2808 ok(r==S_OK, "StgCreateDocfile failed\n");
2810 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2811 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2812 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2813 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2814 CoTaskMemFree(stat.pwcsName);
2816 IStorage_Release( stg );
2818 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2819 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2821 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2822 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2823 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2824 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2825 CoTaskMemFree(stat.pwcsName);
2827 IStorage_Release( stg );
2829 DeleteFileA(filenameA);
2831 /* Stat always returns the full path, even for files opened with a relative path. */
2832 GetCurrentDirectoryA(MAX_PATH, prev_dir);
2834 GetTempPathA(MAX_PATH, temp);
2836 SetCurrentDirectoryA(temp);
2838 GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA);
2839 MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH);
2841 r = StgCreateDocfile( rel_path, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2842 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2843 ok(r==S_OK, "StgCreateDocfile failed\n");
2845 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2846 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2847 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2848 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2849 CoTaskMemFree(stat.pwcsName);
2851 IStorage_Release( stg );
2853 r = StgOpenStorage( rel_path, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2854 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2856 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2857 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2858 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2859 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2860 CoTaskMemFree(stat.pwcsName);
2862 IStorage_Release( stg );
2864 SetCurrentDirectoryA(prev_dir);
2866 DeleteFileA(filenameA);
2869 static void test_substorage_enum(void)
2871 IStorage *stg, *stg2;
2872 IEnumSTATSTG *ee;
2873 HRESULT r;
2874 ULONG ref;
2875 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2877 DeleteFileA(filenameA);
2879 /* create the file */
2880 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2881 STGM_READWRITE, 0, &stg);
2882 ok(r==S_OK, "StgCreateDocfile failed\n");
2884 /* create a substorage */
2885 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2886 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2888 /* create an enumelements */
2889 r = IStorage_EnumElements(stg2, 0, NULL, 0, &ee);
2890 ok(r==S_OK, "IStorage->EnumElements failed, hr=%08x\n", r);
2892 /* release the substorage */
2893 ref = IStorage_Release(stg2);
2894 todo_wine ok(ref==0, "storage not released\n");
2896 /* reopening fails, because the substorage is really still open */
2897 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2898 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage failed, hr=%08x\n", r);
2900 /* destroying the storage invalidates the enumerator */
2901 r = IStorage_DestroyElement(stg, stgname);
2902 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2904 r = IEnumSTATSTG_Reset(ee);
2905 ok(r==STG_E_REVERTED, "IEnumSTATSTG->Reset failed, hr=%08x\n", r);
2907 IEnumSTATSTG_Release(ee);
2909 IStorage_Release(stg);
2911 r = DeleteFileA(filenameA);
2912 ok( r == TRUE, "deleted file\n");
2915 static void test_copyto_locking(void)
2917 IStorage *stg, *stg2, *stg3, *stg4;
2918 IStream *stm;
2919 HRESULT r;
2920 static const WCHAR stgname[] = { 'S','T','G','1',0 };
2921 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
2922 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2924 DeleteFileA(filenameA);
2926 /* create the file */
2927 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2928 STGM_READWRITE, 0, &stg);
2929 ok(r==S_OK, "StgCreateDocfile failed\n");
2931 /* create a substorage */
2932 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2933 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2935 /* create another substorage */
2936 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
2937 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2939 /* add a stream, and leave it open */
2940 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2941 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2943 /* Try to copy the storage while the stream is open */
2944 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
2945 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2947 IStream_Release(stm);
2949 /* create a substorage */
2950 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg4);
2951 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2953 /* Try to copy the storage while the substorage is open */
2954 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
2955 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2957 IStorage_Release(stg4);
2958 IStorage_Release(stg3);
2959 IStorage_Release(stg2);
2960 IStorage_Release(stg);
2962 r = DeleteFileA(filenameA);
2963 ok( r == TRUE, "deleted file\n");
2966 static void test_copyto_recursive(void)
2968 IStorage *stg, *stg2, *stg3, *stg4;
2969 HRESULT r;
2970 static const WCHAR stgname[] = { 'S','T','G','1',0 };
2971 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
2973 DeleteFileA(filenameA);
2975 /* create the file */
2976 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2977 STGM_READWRITE, 0, &stg);
2978 ok(r==S_OK, "StgCreateDocfile failed\n");
2980 /* create a substorage */
2981 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2982 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2984 /* copy the parent to the child */
2985 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
2986 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2988 /* create a transacted substorage */
2989 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg3);
2990 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2992 /* copy the parent to the transacted child */
2993 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
2994 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2996 /* create a transacted subsubstorage */
2997 r = IStorage_CreateStorage(stg3, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg4);
2998 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
3000 /* copy the parent to the transacted child of the transacted child */
3001 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg4);
3002 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
3004 /* copy the parent but exclude storage objects */
3005 r = IStorage_CopyTo(stg, 1, &IID_IStorage, NULL, stg4);
3006 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
3008 IStorage_Release(stg4);
3009 IStorage_Release(stg3);
3010 IStorage_Release(stg2);
3011 IStorage_Release(stg);
3013 r = DeleteFileA(filenameA);
3014 ok( r == TRUE, "deleted file\n");
3017 static void test_hglobal_storage_creation(void)
3019 ILockBytes *ilb = NULL;
3020 IStorage *stg = NULL;
3021 HRESULT r;
3022 STATSTG stat;
3023 char junk[512];
3024 ULARGE_INTEGER offset;
3026 r = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
3027 ok(r == S_OK, "CreateILockBytesOnHGlobal failed, hr=%x\n", r);
3029 offset.QuadPart = 0;
3030 memset(junk, 0xaa, 512);
3031 r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
3032 ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
3034 offset.QuadPart = 2000;
3035 r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
3036 ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
3038 r = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stg);
3039 ok(r == S_OK, "StgCreateDocfileOnILockBytes failed, hr=%x\n", r);
3041 IStorage_Release(stg);
3043 r = StgOpenStorageOnILockBytes(ilb, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE,
3044 NULL, 0, &stg);
3045 ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
3047 if (SUCCEEDED(r))
3049 r = IStorage_Stat(stg, &stat, STATFLAG_NONAME);
3050 ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
3051 ok(IsEqualCLSID(&stat.clsid, &GUID_NULL), "unexpected CLSID value\n");
3053 IStorage_Release(stg);
3056 r = ILockBytes_Stat(ilb, &stat, STATFLAG_NONAME);
3057 ok(r == S_OK, "ILockBytes_Stat failed, hr=%x\n", r);
3058 ok(stat.cbSize.u.LowPart < 2512, "expected truncated size, got %d\n", stat.cbSize.u.LowPart);
3060 ILockBytes_Release(ilb);
3063 static void test_convert(void)
3065 static const WCHAR filename[] = {'s','t','o','r','a','g','e','.','s','t','g',0};
3066 IStorage *stg;
3067 HRESULT hr;
3069 hr = GetConvertStg(NULL);
3070 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3072 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
3073 ok(hr == S_OK, "StgCreateDocfile failed\n");
3074 hr = GetConvertStg(stg);
3075 ok(hr == STG_E_FILENOTFOUND, "got 0x%08x\n", hr);
3076 hr = SetConvertStg(stg, TRUE);
3077 ok(hr == S_OK, "got 0x%08x\n", hr);
3078 hr = SetConvertStg(stg, TRUE);
3079 ok(hr == S_OK, "got 0x%08x\n", hr);
3080 hr = GetConvertStg(stg);
3081 ok(hr == S_OK, "got 0x%08x\n", hr);
3082 hr = SetConvertStg(stg, FALSE);
3083 ok(hr == S_OK, "got 0x%08x\n", hr);
3084 hr = GetConvertStg(stg);
3085 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3087 IStorage_Release(stg);
3089 DeleteFileW(filename);
3092 static void test_direct_swmr(void)
3094 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
3095 IDirectWriterLock *dwlock;
3096 ULONG ref, ref2;
3097 IStorage *stg;
3098 HRESULT hr;
3100 /* it's possible to create in writer mode */
3101 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_DIRECT_SWMR, 0, &stg);
3102 todo_wine
3103 ok(hr == S_OK, "got %08x\n", hr);
3104 if (hr == S_OK) {
3105 IStorage_Release(stg);
3106 DeleteFileW(fileW);
3109 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
3110 ok(hr == S_OK, "got %08x\n", hr);
3111 IStorage_Release(stg);
3113 /* reader mode */
3114 hr = StgOpenStorage(fileW, NULL, STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
3115 ok(hr == S_OK || broken(hr == STG_E_INVALIDFLAG), "got %08x\n", hr);
3116 if(hr == S_OK)
3118 hr = IStorage_QueryInterface(stg, &IID_IDirectWriterLock, (void**)&dwlock);
3119 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
3120 IStorage_Release(stg);
3123 /* writer mode */
3124 hr = StgOpenStorage(fileW, NULL, STGM_DIRECT_SWMR | STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
3125 ok(hr == S_OK, "got %08x\n", hr);
3126 if(hr == S_OK)
3128 ref = IStorage_AddRef(stg);
3129 IStorage_Release(stg);
3131 hr = IStorage_QueryInterface(stg, &IID_IDirectWriterLock, (void**)&dwlock);
3132 ok(hr == S_OK, "got %08x\n", hr);
3134 ref2 = IStorage_AddRef(stg);
3135 IStorage_Release(stg);
3136 ok(ref2 == ref + 1, "got %u\n", ref2);
3138 IDirectWriterLock_Release(dwlock);
3139 IStorage_Release(stg);
3142 DeleteFileW(fileW);
3145 START_TEST(storage32)
3147 CHAR temp[MAX_PATH];
3149 GetTempPathA(MAX_PATH, temp);
3150 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
3152 win_skip("Could not create temp file, %u\n", GetLastError());
3153 return;
3155 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
3156 DeleteFileA(filenameA);
3158 test_hglobal_storage_stat();
3159 test_create_storage_modes();
3160 test_stgcreatestorageex();
3161 test_storage_stream();
3162 test_open_storage();
3163 test_storage_suminfo();
3164 test_storage_refcount();
3165 test_streamenum();
3166 test_transact();
3167 test_substorage_share();
3168 test_revert();
3169 test_parent_free();
3170 test_nonroot_transacted();
3171 test_ReadClassStm();
3172 test_access();
3173 test_writeclassstg();
3174 test_readonly();
3175 test_simple();
3176 test_fmtusertypestg();
3177 test_references();
3178 test_copyto();
3179 test_copyto_snbexclusions();
3180 test_copyto_iidexclusions_storage();
3181 test_copyto_iidexclusions_stream();
3182 test_rename();
3183 test_toplevel_stat();
3184 test_substorage_enum();
3185 test_copyto_locking();
3186 test_copyto_recursive();
3187 test_hglobal_storage_creation();
3188 test_convert();
3189 test_direct_swmr();