ole32: Remove unsupported interface REFIID from storage stream QueryInterface.
[wine/multimedia.git] / dlls / ole32 / tests / storage32.c
blobac3fc3f38ddb9f121be58f0fd0362f2699439b28
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 = GetModuleHandle("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");
932 IStorage_Release(stgprio);
934 DeleteFileA(filenameA);
937 static void test_writeclassstg(void)
939 IStorage *stg = NULL;
940 HRESULT r;
941 CLSID temp_cls;
943 DeleteFileA(filenameA);
945 /* create the file */
946 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
947 STGM_READWRITE, 0, &stg);
948 ok(r==S_OK, "StgCreateDocfile failed\n");
950 r = ReadClassStg( NULL, NULL );
951 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
953 r = ReadClassStg( stg, NULL );
954 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
956 temp_cls.Data1 = 0xdeadbeef;
957 r = ReadClassStg( stg, &temp_cls );
958 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
960 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
962 r = WriteClassStg( NULL, NULL );
963 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
965 r = WriteClassStg( stg, NULL );
966 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
968 r = WriteClassStg( stg, &test_stg_cls );
969 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
971 r = ReadClassStg( stg, &temp_cls );
972 ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
973 ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
975 r = IStorage_Release( stg );
976 ok (r == 0, "storage not released\n");
978 DeleteFileA(filenameA);
981 static void test_streamenum(void)
983 IStorage *stg = NULL;
984 HRESULT r;
985 IStream *stm = NULL;
986 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
987 static const WCHAR stmname2[] = { 'A','B','C','D','E','F','G','H','I',0 };
988 static const WCHAR stmname3[] = { 'A','B','C','D','E','F','G','H','I','J',0 };
989 STATSTG stat;
990 IEnumSTATSTG *ee = NULL;
991 ULONG count;
993 DeleteFileA(filenameA);
995 /* create the file */
996 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
997 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
998 ok(r==S_OK, "StgCreateDocfile failed\n");
1000 r = WriteClassStg( stg, &test_stg_cls );
1001 ok( r == S_OK, "WriteClassStg failed\n");
1003 r = IStorage_Commit( stg, STGC_DEFAULT );
1004 ok( r == S_OK, "IStorage_Commit failed\n");
1006 /* now create a stream */
1007 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1008 ok(r==S_OK, "IStorage->CreateStream failed\n");
1010 r = IStream_Release(stm);
1012 /* first enum ... should be 1 stream */
1013 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
1014 ok(r==S_OK, "IStorage->EnumElements failed\n");
1016 count = 0xf00;
1017 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1018 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1019 ok(count == 1, "count wrong\n");
1021 if (r == S_OK)
1022 CoTaskMemFree(stat.pwcsName);
1024 r = IEnumSTATSTG_Release(ee);
1025 ok(r==S_OK, "EnumSTATSTG_Release failed with error 0x%08x\n", r);
1027 /* second enum... destroy the stream before reading */
1028 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
1029 ok(r==S_OK, "IStorage->EnumElements failed\n");
1031 r = IStorage_DestroyElement(stg, stmname);
1032 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1034 count = 0xf00;
1035 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1036 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
1037 ok(count == 0, "count wrong\n");
1039 /* reset and try again */
1040 r = IEnumSTATSTG_Reset(ee);
1041 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1043 count = 0xf00;
1044 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1045 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
1046 ok(count == 0, "count wrong\n");
1048 /* add a stream before reading */
1049 r = IEnumSTATSTG_Reset(ee);
1050 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1052 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1053 ok(r==S_OK, "IStorage->CreateStream failed\n");
1055 r = IStream_Release(stm);
1056 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1058 count = 0xf00;
1059 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1060 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1061 ok(count == 1, "count wrong\n");
1063 if (r == S_OK)
1065 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1066 CoTaskMemFree(stat.pwcsName);
1069 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1070 ok(r==S_OK, "IStorage->CreateStream failed\n");
1072 r = IStream_Release(stm);
1073 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1075 count = 0xf00;
1076 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1077 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1078 ok(count == 1, "count wrong\n");
1080 if (r == S_OK)
1082 ok(lstrcmpiW(stat.pwcsName, stmname2) == 0, "expected ABCDEFGHI, got %s\n", wine_dbgstr_w(stat.pwcsName));
1083 CoTaskMemFree(stat.pwcsName);
1086 /* delete previous and next stream after reading */
1087 r = IStorage_CreateStream(stg, stmname3, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1088 ok(r==S_OK, "IStorage->CreateStream failed\n");
1090 r = IStream_Release(stm);
1091 ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r);
1093 r = IEnumSTATSTG_Reset(ee);
1094 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1096 count = 0xf00;
1097 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1098 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1099 ok(count == 1, "count wrong\n");
1101 if (r == S_OK)
1103 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1104 CoTaskMemFree(stat.pwcsName);
1107 r = IStorage_DestroyElement(stg, stmname);
1108 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1110 r = IStorage_DestroyElement(stg, stmname2);
1111 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1113 count = 0xf00;
1114 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1115 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1116 ok(count == 1, "count wrong\n");
1118 if (r == S_OK)
1120 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1121 CoTaskMemFree(stat.pwcsName);
1124 r = IStorage_Release( stg );
1125 todo_wine ok (r == 0, "storage not released\n");
1127 /* enumerator is still valid and working after the storage is released */
1128 r = IEnumSTATSTG_Reset(ee);
1129 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1131 count = 0xf00;
1132 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1133 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1134 ok(count == 1, "count wrong\n");
1136 if (r == S_OK)
1138 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1139 CoTaskMemFree(stat.pwcsName);
1142 /* the storage is left open until the enumerator is freed */
1143 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE |
1144 STGM_READWRITE |STGM_TRANSACTED, NULL, 0, &stg);
1145 ok(r==STG_E_SHAREVIOLATION ||
1146 r==STG_E_LOCKVIOLATION, /* XP-SP2/W2K3-SP1 and below */
1147 "StgCreateDocfile failed, res=%x\n", r);
1149 r = IEnumSTATSTG_Release(ee);
1150 ok (r == 0, "enum not released\n");
1152 DeleteFileA(filenameA);
1155 static void test_transact(void)
1157 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1158 HRESULT r;
1159 IStream *stm = NULL;
1160 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1161 static const WCHAR stmname2[] = { 'F','O','O',0 };
1162 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1163 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1165 DeleteFileA(filenameA);
1167 /* create the file */
1168 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1169 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1170 ok(r==S_OK, "StgCreateDocfile failed\n");
1172 /* commit a new stream and storage */
1173 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1174 ok(r==S_OK, "IStorage->CreateStream failed\n");
1176 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1177 ok(r==S_OK, "IStream->Write failed\n");
1179 IStream_Release(stm);
1181 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1182 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1184 if (r == S_OK)
1186 /* Create two substorages but only commit one */
1187 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1188 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1190 if (r == S_OK)
1191 IStorage_Release(stg3);
1193 r = IStorage_Commit(stg, 0);
1194 ok(r==S_OK, "IStorage->Commit failed\n");
1196 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1197 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1199 if (r == S_OK)
1200 IStorage_Release(stg3);
1202 IStorage_Release(stg2);
1205 /* now create a stream and storage, but don't commit them */
1206 stm = NULL;
1207 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1208 ok(r==S_OK, "IStorage->CreateStream failed\n");
1210 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
1211 ok(r==S_OK, "IStream->Write failed\n");
1213 /* IStream::Commit does nothing for OLE storage streams */
1214 r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
1215 ok(r==S_OK, "IStream->Commit failed\n");
1217 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1218 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1220 if (r == S_OK)
1221 IStorage_Release(stg2);
1223 IStream_Release(stm);
1225 IStorage_Release(stg);
1227 stm = NULL;
1228 stg = NULL;
1229 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
1230 ok(r==S_OK, "StgOpenStorage failed\n");
1232 if (!stg)
1233 return;
1235 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1236 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1238 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1239 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1241 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1242 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1244 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1245 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1247 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1248 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1249 if (r == S_OK)
1250 IStream_Release(stm);
1252 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1253 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1254 if (r == S_OK)
1255 IStorage_Release(stg2);
1257 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1258 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1260 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1261 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1262 if (r == S_OK)
1263 IStream_Release(stm);
1265 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1266 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1267 if (r == S_OK)
1269 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1270 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1271 if (r == S_OK)
1272 IStorage_Release(stg3);
1274 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1275 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1276 if (r == S_OK)
1277 IStorage_Release(stg3);
1279 IStorage_Release(stg2);
1282 IStorage_Release(stg);
1284 r = DeleteFileA(filenameA);
1285 ok( r == TRUE, "deleted file\n");
1288 static void test_substorage_share(void)
1290 IStorage *stg, *stg2, *stg3;
1291 IStream *stm, *stm2;
1292 HRESULT r;
1293 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1294 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1295 static const WCHAR othername[] = { 'N','E','W','N','A','M','E',0 };
1297 DeleteFileA(filenameA);
1299 /* create the file */
1300 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1301 STGM_READWRITE, 0, &stg);
1302 ok(r==S_OK, "StgCreateDocfile failed\n");
1304 /* create a read/write storage and try to open it again */
1305 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1306 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1308 if (r == S_OK)
1310 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1311 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1313 if (r == S_OK)
1314 IStorage_Release(stg3);
1316 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1317 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1319 if (r == S_OK)
1320 IStorage_Release(stg3);
1322 /* cannot rename the storage while it's open */
1323 r = IStorage_RenameElement(stg, stgname, othername);
1324 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1325 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stgname);
1327 /* destroying an object while it's open invalidates it */
1328 r = IStorage_DestroyElement(stg, stgname);
1329 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1331 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1332 ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r);
1334 if (r == S_OK)
1335 IStorage_Release(stm);
1337 IStorage_Release(stg2);
1340 /* create a read/write stream and try to open it again */
1341 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1342 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
1344 if (r == S_OK)
1346 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1347 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1349 if (r == S_OK)
1350 IStorage_Release(stm2);
1352 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1353 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1355 if (r == S_OK)
1356 IStorage_Release(stm2);
1358 /* cannot rename the stream while it's open */
1359 r = IStorage_RenameElement(stg, stmname, othername);
1360 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1361 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stmname);
1363 /* destroying an object while it's open invalidates it */
1364 r = IStorage_DestroyElement(stg, stmname);
1365 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1367 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1368 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1370 IStorage_Release(stm);
1373 IStorage_Release(stg);
1375 r = DeleteFileA(filenameA);
1376 ok( r == TRUE, "deleted file\n");
1379 static void test_revert(void)
1381 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1382 HRESULT r;
1383 IStream *stm = NULL, *stm2 = NULL;
1384 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1385 static const WCHAR stmname2[] = { 'F','O','O',0 };
1386 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1387 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1388 STATSTG statstg;
1390 DeleteFileA(filenameA);
1392 /* create the file */
1393 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1394 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1395 ok(r==S_OK, "StgCreateDocfile failed\n");
1397 /* commit a new stream and storage */
1398 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1399 ok(r==S_OK, "IStorage->CreateStream failed\n");
1401 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1402 ok(r==S_OK, "IStream->Write failed\n");
1404 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1405 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1407 if (r == S_OK)
1409 /* Create two substorages but only commit one */
1410 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1411 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1413 if (r == S_OK)
1414 IStorage_Release(stg3);
1416 r = IStorage_Commit(stg, 0);
1417 ok(r==S_OK, "IStorage->Commit failed\n");
1419 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1420 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1422 if (r == S_OK)
1423 IStorage_Release(stg3);
1426 /* now create a stream and storage, then revert */
1427 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
1428 ok(r==S_OK, "IStorage->CreateStream failed\n");
1430 r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1431 ok(r==S_OK, "IStream->Write failed\n");
1433 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1434 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1436 r = IStorage_Revert(stg);
1437 ok(r==S_OK, "Storage_Revert failed with error 0x%08x\n", r);
1439 /* all open objects become invalid */
1440 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1441 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1443 r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL);
1444 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1446 r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1447 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1449 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1450 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1452 IStream_Release(stm);
1453 IStream_Release(stm2);
1454 IStorage_Release(stg2);
1455 IStorage_Release(stg3);
1457 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1458 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1460 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1461 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1463 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1464 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1466 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1467 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1469 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1470 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1471 if (r == S_OK)
1472 IStream_Release(stm);
1474 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1475 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1476 if (r == S_OK)
1477 IStorage_Release(stg2);
1479 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1480 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1482 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1483 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1484 if (r == S_OK)
1485 IStream_Release(stm);
1487 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1488 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1489 if (r == S_OK)
1491 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1492 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1493 if (r == S_OK)
1494 IStorage_Release(stg3);
1496 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1497 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1498 if (r == S_OK)
1499 IStorage_Release(stg3);
1501 IStorage_Release(stg2);
1504 IStorage_Release(stg);
1506 r = DeleteFileA(filenameA);
1507 ok( r == TRUE, "deleted file\n");
1509 /* Revert only invalidates objects in transacted mode */
1510 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1511 STGM_READWRITE, 0, &stg);
1512 ok(r==S_OK, "StgCreateDocfile failed\n");
1514 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1515 ok(r==S_OK, "IStorage->CreateStream failed\n");
1517 r = IStorage_Revert(stg);
1518 ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1520 r = IStream_Write(stm, "this works\n", 11, NULL);
1521 ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1523 IStream_Release(stm);
1524 IStream_Release(stg);
1526 r = DeleteFileA(filenameA);
1527 ok( r == TRUE, "deleted file\n");
1530 static void test_parent_free(void)
1532 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1533 HRESULT r;
1534 IStream *stm = NULL;
1535 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1536 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1537 ULONG ref;
1538 STATSTG statstg;
1540 DeleteFileA(filenameA);
1542 /* create the file */
1543 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1544 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1545 ok(r==S_OK, "StgCreateDocfile failed\n");
1547 /* create a new storage */
1548 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1549 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1551 if (r == S_OK)
1553 /* now create a stream inside the new storage */
1554 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1555 ok(r==S_OK, "IStorage->CreateStream failed\n");
1557 if (r == S_OK)
1559 /* create a storage inside the new storage */
1560 r = IStorage_CreateStorage(stg2, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg3 );
1561 ok(r==S_OK, "IStorage->CreateStorage failed\n");
1564 /* free the parent */
1565 ref = IStorage_Release(stg2);
1566 ok(ref == 0, "IStorage still has %u references\n", ref);
1568 /* child objects are invalid */
1569 if (r == S_OK)
1571 r = IStream_Write(stm, "this should fail\n", 17, NULL);
1572 ok(r==STG_E_REVERTED, "IStream->Write should fail, hr=%x\n", r);
1574 IStream_Release(stm);
1576 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1577 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1579 r = IStorage_SetStateBits(stg3, 1, 1);
1580 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1582 IStorage_Release(stg3);
1586 IStorage_Release(stg);
1588 r = DeleteFileA(filenameA);
1589 ok( r == TRUE, "deleted file\n");
1592 static void test_nonroot_transacted(void)
1594 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1595 HRESULT r;
1596 IStream *stm = NULL;
1597 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1598 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1599 static const WCHAR stmname2[] = { 'F','O','O',0 };
1601 DeleteFileA(filenameA);
1603 /* create a transacted file */
1604 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1605 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1606 ok(r==S_OK, "StgCreateDocfile failed\n");
1608 /* create a transacted substorage */
1609 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1610 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1612 if (r == S_OK)
1614 /* create and commit stmname */
1615 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1616 ok(r==S_OK, "IStorage->CreateStream failed\n");
1617 if (r == S_OK)
1618 IStream_Release(stm);
1620 IStorage_Commit(stg2, 0);
1622 /* create and revert stmname2 */
1623 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1624 ok(r==S_OK, "IStorage->CreateStream failed\n");
1625 if (r == S_OK)
1626 IStream_Release(stm);
1628 IStorage_Revert(stg2);
1630 /* check that Commit and Revert really worked */
1631 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1632 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1633 if (r == S_OK)
1634 IStream_Release(stm);
1636 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1637 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1638 if (r == S_OK)
1639 IStream_Release(stm);
1641 IStorage_Release(stg2);
1644 /* create a read-only transacted substorage */
1645 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2);
1646 ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r);
1648 if (r == S_OK)
1650 /* The storage can be modified. */
1651 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1652 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1653 if (r == S_OK)
1654 IStream_Release(stg3);
1656 /* But changes cannot be committed. */
1657 r = IStorage_Commit(stg2, 0);
1658 ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r);
1660 IStorage_Release(stg2);
1663 IStorage_Release(stg);
1665 /* create a non-transacted file */
1666 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1667 STGM_READWRITE, 0, &stg);
1668 ok(r==S_OK, "StgCreateDocfile failed\n");
1670 /* create a transacted substorage */
1671 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1672 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1674 if (r == S_OK)
1676 /* create and commit stmname */
1677 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1678 ok(r==S_OK, "IStorage->CreateStream failed\n");
1679 if (r == S_OK)
1680 IStream_Release(stm);
1682 IStorage_Commit(stg2, 0);
1684 /* create and revert stmname2 */
1685 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1686 ok(r==S_OK, "IStorage->CreateStream failed\n");
1687 if (r == S_OK)
1688 IStream_Release(stm);
1690 IStorage_Revert(stg2);
1692 /* check that Commit and Revert really worked */
1693 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1694 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1695 if (r == S_OK)
1696 IStream_Release(stm);
1698 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1699 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1700 if (r == S_OK)
1701 IStream_Release(stm);
1703 IStorage_Release(stg2);
1706 IStream_Release(stg);
1708 r = DeleteFileA(filenameA);
1709 ok( r == TRUE, "deleted file\n");
1712 static void test_ReadClassStm(void)
1714 CLSID clsid;
1715 HRESULT hr;
1716 IStream *pStream;
1717 static const LARGE_INTEGER llZero;
1719 hr = ReadClassStm(NULL, &clsid);
1720 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1722 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1723 ok_ole_success(hr, "CreateStreamOnHGlobal");
1724 hr = WriteClassStm(pStream, &test_stg_cls);
1725 ok_ole_success(hr, "WriteClassStm");
1727 hr = ReadClassStm(pStream, NULL);
1728 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1730 /* test not rewound stream */
1731 hr = ReadClassStm(pStream, &clsid);
1732 ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1733 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1735 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1736 ok_ole_success(hr, "IStream_Seek");
1737 hr = ReadClassStm(pStream, &clsid);
1738 ok_ole_success(hr, "ReadClassStm");
1739 ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
1741 IStream_Release(pStream);
1744 struct access_res
1746 BOOL gothandle;
1747 DWORD lasterr;
1748 BOOL ignore;
1751 static const struct access_res create[16] =
1753 { TRUE, ERROR_SUCCESS, TRUE },
1754 { TRUE, ERROR_SUCCESS, TRUE },
1755 { TRUE, ERROR_SUCCESS, FALSE },
1756 { TRUE, ERROR_SUCCESS, FALSE },
1757 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1758 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1759 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1760 { TRUE, ERROR_SUCCESS, FALSE },
1761 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1762 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1763 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1764 { TRUE, ERROR_SUCCESS, TRUE },
1765 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1766 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1767 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1768 { TRUE, ERROR_SUCCESS, TRUE }
1771 static const struct access_res create_commit[16] =
1773 { TRUE, ERROR_SUCCESS, TRUE },
1774 { TRUE, ERROR_SUCCESS, TRUE },
1775 { TRUE, ERROR_SUCCESS, FALSE },
1776 { TRUE, ERROR_SUCCESS, FALSE },
1777 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1778 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1779 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1780 { TRUE, ERROR_SUCCESS, FALSE },
1781 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1782 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1783 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1784 { TRUE, ERROR_SUCCESS, TRUE },
1785 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1786 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1787 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1788 { TRUE, ERROR_SUCCESS, TRUE }
1791 static const struct access_res create_close[16] =
1793 { TRUE, ERROR_SUCCESS, FALSE },
1794 { TRUE, ERROR_SUCCESS, FALSE },
1795 { TRUE, ERROR_SUCCESS, FALSE },
1796 { TRUE, ERROR_SUCCESS, FALSE },
1797 { TRUE, ERROR_SUCCESS, FALSE },
1798 { TRUE, ERROR_SUCCESS, FALSE },
1799 { TRUE, ERROR_SUCCESS, FALSE },
1800 { TRUE, ERROR_SUCCESS, FALSE },
1801 { TRUE, ERROR_SUCCESS, FALSE },
1802 { TRUE, ERROR_SUCCESS, FALSE },
1803 { TRUE, ERROR_SUCCESS, FALSE },
1804 { TRUE, ERROR_SUCCESS, FALSE },
1805 { TRUE, ERROR_SUCCESS, FALSE },
1806 { TRUE, ERROR_SUCCESS, FALSE },
1807 { TRUE, ERROR_SUCCESS, FALSE },
1808 { TRUE, ERROR_SUCCESS }
1811 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1813 DWORD access = 0, share = 0;
1814 DWORD lasterr;
1815 HANDLE hfile;
1816 int i, j, idx = 0;
1818 for (i = 0; i < 4; i++)
1820 if (i == 0) access = 0;
1821 if (i == 1) access = GENERIC_READ;
1822 if (i == 2) access = GENERIC_WRITE;
1823 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
1825 for (j = 0; j < 4; j++)
1827 if (ares[idx].ignore)
1828 continue;
1830 if (j == 0) share = 0;
1831 if (j == 1) share = FILE_SHARE_READ;
1832 if (j == 2) share = FILE_SHARE_WRITE;
1833 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
1835 SetLastError(0xdeadbeef);
1836 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
1837 FILE_ATTRIBUTE_NORMAL, 0);
1838 lasterr = GetLastError();
1840 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
1841 "(%d, handle, %d): Expected %d, got %d\n",
1842 line, idx, ares[idx].gothandle,
1843 (hfile != INVALID_HANDLE_VALUE));
1845 ok(lasterr == ares[idx].lasterr ||
1846 broken(lasterr == 0xdeadbeef) /* win9x */,
1847 "(%d, lasterr, %d): Expected %d, got %d\n",
1848 line, idx, ares[idx].lasterr, lasterr);
1850 CloseHandle(hfile);
1851 idx++;
1856 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1858 static void test_access(void)
1860 IStorage *stg;
1861 HRESULT hr;
1863 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1865 /* STGM_TRANSACTED */
1867 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1868 STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, &stg);
1869 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1871 test_file_access("winetest", create);
1873 hr = IStorage_Commit(stg, STGC_DEFAULT);
1874 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1876 test_file_access("winetest", create_commit);
1878 IStorage_Release(stg);
1880 test_file_access("winetest", create_close);
1882 DeleteFileA("winetest");
1884 /* STGM_DIRECT */
1886 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1887 STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &stg);
1888 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1890 test_file_access("winetest", create);
1892 hr = IStorage_Commit(stg, STGC_DEFAULT);
1893 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1895 test_file_access("winetest", create_commit);
1897 IStorage_Release(stg);
1899 test_file_access("winetest", create_close);
1901 DeleteFileA("winetest");
1903 /* STGM_SHARE_DENY_NONE */
1905 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1906 STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
1907 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1909 test_file_access("winetest", create);
1911 hr = IStorage_Commit(stg, STGC_DEFAULT);
1912 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1914 test_file_access("winetest", create_commit);
1916 IStorage_Release(stg);
1918 test_file_access("winetest", create_close);
1920 DeleteFileA("winetest");
1922 /* STGM_SHARE_DENY_READ */
1924 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1925 STGM_SHARE_DENY_READ | STGM_TRANSACTED, 0, &stg);
1926 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1928 test_file_access("winetest", create);
1930 hr = IStorage_Commit(stg, STGC_DEFAULT);
1931 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1933 test_file_access("winetest", create_commit);
1935 IStorage_Release(stg);
1937 test_file_access("winetest", create_close);
1939 DeleteFileA("winetest");
1941 /* STGM_SHARE_DENY_WRITE */
1943 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1944 STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
1945 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1947 test_file_access("winetest", create);
1949 hr = IStorage_Commit(stg, STGC_DEFAULT);
1950 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1952 test_file_access("winetest", create_commit);
1954 IStorage_Release(stg);
1956 test_file_access("winetest", create_close);
1958 DeleteFileA("winetest");
1961 static void test_readonly(void)
1963 IStorage *stg, *stg2, *stg3;
1964 IStream *stream;
1965 HRESULT hr;
1966 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1967 static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
1968 static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
1970 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1971 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1972 if (SUCCEEDED(hr))
1974 hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
1975 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1976 if (SUCCEEDED(hr))
1978 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
1979 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1980 if (SUCCEEDED(hr))
1981 IStream_Release(stream);
1982 IStorage_Release(stg2);
1984 IStorage_Release(stg);
1987 /* re-open read only */
1988 hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
1989 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1990 if (SUCCEEDED(hr))
1992 hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
1993 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1994 if (SUCCEEDED(hr))
1996 /* CreateStream on read-only storage, name exists */
1997 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1998 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1999 if (SUCCEEDED(hr))
2000 IStream_Release(stream);
2002 /* CreateStream on read-only storage, name does not exist */
2003 hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
2004 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2005 if (SUCCEEDED(hr))
2006 IStream_Release(stream);
2008 /* CreateStorage on read-only storage, name exists */
2009 hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
2010 ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
2011 if (SUCCEEDED(hr))
2012 IStream_Release(stg3);
2014 /* CreateStorage on read-only storage, name does not exist */
2015 hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
2016 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2017 if (SUCCEEDED(hr))
2018 IStream_Release(stg3);
2020 /* DestroyElement on read-only storage, name exists */
2021 hr = IStorage_DestroyElement( stg2, streamW );
2022 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2024 /* DestroyElement on read-only storage, name does not exist */
2025 hr = IStorage_DestroyElement( stg2, storageW );
2026 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
2028 IStorage_Release(stg2);
2031 IStorage_Release(stg);
2034 DeleteFileA("winetest");
2037 static void test_simple(void)
2039 /* Tests for STGM_SIMPLE mode */
2041 IStorage *stg, *stg2;
2042 HRESULT r;
2043 IStream *stm;
2044 static const WCHAR stgname[] = { 'S','t','g',0 };
2045 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2046 static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
2047 LARGE_INTEGER pos;
2048 ULARGE_INTEGER upos;
2049 DWORD count;
2050 STATSTG stat;
2052 DeleteFileA(filenameA);
2054 r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
2055 ok(r == S_OK, "got %08x\n", r);
2057 r = IStorage_CreateStorage(stg, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2);
2058 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2059 if (SUCCEEDED(r)) IStorage_Release(stg2);
2061 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2062 ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
2063 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2064 ok(r == S_OK, "got %08x\n", r);
2066 upos.QuadPart = 6000;
2067 r = IStream_SetSize(stm, upos);
2068 ok(r == S_OK, "got %08x\n", r);
2070 r = IStream_Write(stm, "foo", 3, &count);
2071 ok(r == S_OK, "got %08x\n", r);
2072 ok(count == 3, "got %d\n", count);
2074 pos.QuadPart = 0;
2075 r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
2076 ok(r == S_OK, "got %08x\n", r);
2077 ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
2079 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2080 ok(r == S_OK ||
2081 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2082 "got %08x\n", r);
2083 if (r == S_OK)
2084 ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
2086 pos.QuadPart = 1;
2087 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
2088 ok(r == S_OK, "got %08x\n", r);
2089 ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
2091 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2092 ok(r == S_OK ||
2093 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2094 "got %08x\n", r);
2095 if (r == S_OK)
2096 ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
2098 IStream_Release(stm);
2100 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2101 ok(r == S_OK, "got %08x\n", r);
2103 upos.QuadPart = 100;
2104 r = IStream_SetSize(stm, upos);
2105 ok(r == S_OK, "got %08x\n", r);
2107 r = IStream_Write(stm, "foo", 3, &count);
2108 ok(r == S_OK, "got %08x\n", r);
2109 ok(count == 3, "got %d\n", count);
2111 IStream_Release(stm);
2113 IStorage_Commit(stg, STGC_DEFAULT);
2114 IStorage_Release(stg);
2116 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
2117 if (r == STG_E_INVALIDFLAG)
2119 win_skip("Flag combination is not supported on NT4 and below\n");
2120 DeleteFileA(filenameA);
2121 return;
2123 ok(r == S_OK, "got %08x\n", r);
2125 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg2);
2126 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2127 if (SUCCEEDED(r)) IStorage_Release(stg2);
2129 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2130 ok(r == S_OK, "got %08x\n", r);
2132 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2133 ok(r == S_OK, "got %08x\n", r);
2134 ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
2136 IStream_Release(stm);
2138 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2139 ok(r == S_OK, "got %08x\n", r);
2141 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2142 ok(r == S_OK, "got %08x\n", r);
2143 ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
2145 IStream_Release(stm);
2148 IStorage_Release(stg);
2150 DeleteFileA(filenameA);
2153 static void test_fmtusertypestg(void)
2155 IStorage *stg;
2156 IEnumSTATSTG *stat;
2157 HRESULT hr;
2158 static const char fileA[] = {'f','m','t','t','e','s','t',0};
2159 static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0};
2160 static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0};
2161 static WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0};
2163 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
2164 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2166 if (SUCCEEDED(hr))
2168 /* try to write the stream */
2169 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2170 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2172 /* check that the stream was created */
2173 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2174 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2175 if (SUCCEEDED(hr))
2177 BOOL found = FALSE;
2178 STATSTG statstg;
2179 DWORD got;
2180 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2182 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2183 found = TRUE;
2184 else
2185 ok(0, "found unexpected stream or storage\n");
2186 CoTaskMemFree(statstg.pwcsName);
2188 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2189 IEnumSTATSTG_Release(stat);
2192 /* re-write the stream */
2193 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2194 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2196 /* check that the stream is still there */
2197 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2198 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2199 if (SUCCEEDED(hr))
2201 BOOL found = FALSE;
2202 STATSTG statstg;
2203 DWORD got;
2204 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2206 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2207 found = TRUE;
2208 else
2209 ok(0, "found unexpected stream or storage\n");
2210 CoTaskMemFree(statstg.pwcsName);
2212 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2213 IEnumSTATSTG_Release(stat);
2216 IStorage_Release(stg);
2217 DeleteFileA( fileA );
2221 static void test_references(void)
2223 IStorage *stg,*stg2;
2224 HRESULT hr;
2225 unsigned c1,c2;
2226 static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
2228 DeleteFileA(filenameA);
2230 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2231 ok(hr==S_OK, "StgCreateDocfile failed\n");
2233 if (SUCCEEDED(hr))
2235 IStorage_Release(stg);
2237 hr = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
2238 ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr);
2240 if (SUCCEEDED(hr))
2242 hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2);
2243 ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr);
2245 if (SUCCEEDED(hr))
2247 c1 = IStorage_AddRef(stg);
2248 ok(c1 == 2, "creating internal storage added references to ancestor\n");
2249 c1 = IStorage_AddRef(stg);
2250 IStorage_Release(stg2);
2251 c2 = IStorage_AddRef(stg) - 1;
2252 ok(c1 == c2, "releasing internal storage removed references to ancestor\n");
2254 c1 = IStorage_Release(stg);
2255 while ( c1 ) c1 = IStorage_Release(stg);
2259 DeleteFileA(filenameA);
2262 /* dest
2263 * |-StorageA
2264 * | `StreamA: "StreamA"
2265 * |-StorageB
2266 * | `StreamB: "StreamB"
2267 * `StreamC: "StreamC"
2269 static HRESULT create_test_file(IStorage *dest)
2271 IStorage *stgA = NULL, *stgB = NULL;
2272 IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
2273 const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
2274 const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
2275 const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
2276 ULONG bytes;
2277 HRESULT hr;
2279 hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
2280 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2281 if(FAILED(hr))
2282 goto cleanup;
2284 hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
2285 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2286 if(FAILED(hr))
2287 goto cleanup;
2289 hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
2290 ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
2292 hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
2293 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2294 if(FAILED(hr))
2295 goto cleanup;
2297 hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
2298 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2299 if(FAILED(hr))
2300 goto cleanup;
2302 hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
2303 ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
2305 hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
2306 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2307 if(FAILED(hr))
2308 goto cleanup;
2310 hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
2311 ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
2313 cleanup:
2314 if(strmC)
2315 IStream_Release(strmC);
2316 if(strmB)
2317 IStream_Release(strmB);
2318 if(stgB)
2319 IStorage_Release(stgB);
2320 if(strmA)
2321 IStream_Release(strmA);
2322 if(stgA)
2323 IStorage_Release(stgA);
2325 return hr;
2328 static void test_copyto(void)
2330 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2331 IStream *strm_tmp;
2332 WCHAR buf[64];
2333 HRESULT hr;
2335 /* create & populate file1 */
2336 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2337 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2338 if(FAILED(hr))
2339 goto cleanup;
2341 hr = create_test_file(file1);
2342 if(FAILED(hr))
2343 goto cleanup;
2345 /* create file2 */
2346 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2347 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2348 if(FAILED(hr))
2349 goto cleanup;
2351 /* copy file1 into file2 */
2352 hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2353 ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2355 hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2356 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2357 if(FAILED(hr))
2358 goto cleanup;
2360 /* verify that all of file1 was copied */
2361 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2362 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2363 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2365 if(SUCCEEDED(hr)){
2366 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2367 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2368 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2370 if(SUCCEEDED(hr)){
2371 memset(buf, 0, sizeof(buf));
2372 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2373 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2374 if(SUCCEEDED(hr))
2375 ok(strcmp_ww(buf, strmA_name) == 0,
2376 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2378 IStream_Release(strm_tmp);
2381 IStorage_Release(stg_tmp);
2384 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2385 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2386 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2388 if(SUCCEEDED(hr)){
2389 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2390 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2391 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2393 if(SUCCEEDED(hr)){
2394 memset(buf, 0, sizeof(buf));
2395 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2396 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2397 if(SUCCEEDED(hr))
2398 ok(strcmp_ww(buf, strmB_name) == 0,
2399 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2401 IStream_Release(strm_tmp);
2404 IStorage_Release(stg_tmp);
2407 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2408 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2409 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2411 if(SUCCEEDED(hr)){
2412 memset(buf, 0, sizeof(buf));
2413 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2414 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2415 if(SUCCEEDED(hr))
2416 ok(strcmp_ww(buf, strmC_name) == 0,
2417 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2419 IStream_Release(strm_tmp);
2422 cleanup:
2423 if(file1)
2424 IStorage_Release(file1);
2425 if(file2)
2426 IStorage_Release(file2);
2428 DeleteFileA(file1_nameA);
2429 DeleteFileA(file2_nameA);
2432 static void test_copyto_snbexclusions(void)
2434 static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2436 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2437 IStream *strm_tmp;
2438 WCHAR buf[64];
2439 HRESULT hr;
2441 /* create & populate file1 */
2442 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2443 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2444 if(FAILED(hr))
2445 goto cleanup;
2447 hr = create_test_file(file1);
2448 if(FAILED(hr))
2449 goto cleanup;
2451 /* create file2 */
2452 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2453 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2454 if(FAILED(hr))
2455 goto cleanup;
2457 /* copy file1 to file2 with name exclusions */
2458 hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2459 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2460 if(FAILED(hr))
2461 goto cleanup;
2463 /* verify that file1 copied over, respecting exclusions */
2464 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2465 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2466 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2467 if(SUCCEEDED(hr))
2468 IStorage_Release(stg_tmp);
2470 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2471 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2472 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2473 if(SUCCEEDED(hr))
2474 IStream_Release(strm_tmp);
2476 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2477 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2478 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2480 if(SUCCEEDED(hr)){
2481 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2482 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2483 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2485 if(SUCCEEDED(hr)){
2486 memset(buf, 0, sizeof(buf));
2487 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2488 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2489 if(SUCCEEDED(hr))
2490 ok(strcmp_ww(buf, strmB_name) == 0,
2491 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2493 IStream_Release(strm_tmp);
2496 IStorage_Release(stg_tmp);
2499 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2500 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2501 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2502 if(SUCCEEDED(hr))
2503 IStream_Release(strm_tmp);
2505 cleanup:
2506 if(file1)
2507 IStorage_Release(file1);
2508 if(file2)
2509 IStorage_Release(file2);
2511 DeleteFileA(file1_nameA);
2512 DeleteFileA(file2_nameA);
2515 static void test_copyto_iidexclusions_storage(void)
2517 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2518 IStream *strm_tmp;
2519 WCHAR buf[64];
2520 HRESULT hr;
2522 /* create & populate file1 */
2523 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2524 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2525 if(FAILED(hr))
2526 goto cleanup;
2528 hr = create_test_file(file1);
2529 if(FAILED(hr))
2530 goto cleanup;
2532 /* create file2 */
2533 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2534 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2535 if(FAILED(hr))
2536 goto cleanup;
2538 /* copy file1 to file2 with iid exclusions */
2539 hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2540 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2541 if(FAILED(hr))
2542 goto cleanup;
2544 /* verify that file1 copied over, respecting exclusions */
2545 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2546 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2547 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2548 if(SUCCEEDED(hr))
2549 IStorage_Release(stg_tmp);
2551 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2552 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2553 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2554 if(SUCCEEDED(hr))
2555 IStream_Release(strm_tmp);
2557 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2558 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2559 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2560 if(SUCCEEDED(hr))
2561 IStorage_Release(stg_tmp);
2563 hr = IStorage_OpenStream(file2, strmB_name, NULL,
2564 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2565 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2566 if(SUCCEEDED(hr))
2567 IStream_Release(strm_tmp);
2569 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2570 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2571 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2573 if(SUCCEEDED(hr)){
2574 memset(buf, 0, sizeof(buf));
2575 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2576 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2577 if(SUCCEEDED(hr))
2578 ok(strcmp_ww(buf, strmC_name) == 0,
2579 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2581 IStream_Release(strm_tmp);
2584 cleanup:
2585 if(file1)
2586 IStorage_Release(file1);
2587 if(file2)
2588 IStorage_Release(file2);
2590 DeleteFileA(file1_nameA);
2591 DeleteFileA(file2_nameA);
2594 static void test_copyto_iidexclusions_stream(void)
2596 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2597 IStream *strm_tmp;
2598 HRESULT hr;
2600 /* create & populate file1 */
2601 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2602 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2603 if(FAILED(hr))
2604 goto cleanup;
2606 hr = create_test_file(file1);
2607 if(FAILED(hr))
2608 goto cleanup;
2610 /* create file2 */
2611 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2612 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2613 if(FAILED(hr))
2614 goto cleanup;
2616 /* copy file1 to file2 with iid exclusions */
2617 hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2618 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2619 if(FAILED(hr))
2620 goto cleanup;
2622 /* verify that file1 copied over, respecting exclusions */
2623 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2624 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2625 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2627 if(SUCCEEDED(hr)){
2628 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2629 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2630 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2631 if(SUCCEEDED(hr))
2632 IStream_Release(strm_tmp);
2634 IStorage_Release(stg_tmp);
2637 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2638 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2639 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2641 if(SUCCEEDED(hr)){
2642 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2643 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2644 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2645 if(SUCCEEDED(hr))
2646 IStream_Release(strm_tmp);
2648 IStorage_Release(stg_tmp);
2651 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2652 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2653 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2654 if(SUCCEEDED(hr))
2655 IStream_Release(strm_tmp);
2657 cleanup:
2658 if(file1)
2659 IStorage_Release(file1);
2660 if(file2)
2661 IStorage_Release(file2);
2663 DeleteFileA(file1_nameA);
2664 DeleteFileA(file2_nameA);
2667 static void test_rename(void)
2669 IStorage *stg, *stg2;
2670 IStream *stm;
2671 HRESULT r;
2672 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2673 static const WCHAR stgname2[] = { 'S','T','G',0 };
2674 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2675 static const WCHAR stmname2[] = { 'E','N','T','S',0 };
2677 DeleteFileA(filenameA);
2679 /* create the file */
2680 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2681 STGM_READWRITE, 0, &stg);
2682 ok(r==S_OK, "StgCreateDocfile failed\n");
2684 /* create a substorage */
2685 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2686 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2688 /* create a stream in the substorage */
2689 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2690 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2691 IStream_Release(stm);
2693 /* rename the stream */
2694 r = IStorage_RenameElement(stg2, stmname, stmname2);
2695 ok(r==S_OK, "IStorage->RenameElement failed, hr=%08x\n", r);
2697 /* cannot open stream with old name */
2698 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2699 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2700 if (SUCCEEDED(r)) IStream_Release(stm);
2702 /* can open stream with new name */
2703 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2704 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2705 if (SUCCEEDED(r)) IStream_Release(stm);
2707 IStorage_Release(stg2);
2709 /* rename the storage */
2710 IStorage_RenameElement(stg, stgname, stgname2);
2712 /* cannot open storage with old name */
2713 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2714 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2715 if (SUCCEEDED(r)) IStorage_Release(stg2);
2717 /* can open storage with new name */
2718 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2719 ok(r==S_OK, "IStorage_OpenStream should fail, hr=%08x\n", r);
2720 if (SUCCEEDED(r))
2722 /* opened storage still has the stream */
2723 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2724 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2725 if (SUCCEEDED(r)) IStream_Release(stm);
2727 IStorage_Release(stg2);
2730 IStorage_Release(stg);
2732 r = DeleteFileA(filenameA);
2733 ok( r == TRUE, "deleted file\n");
2736 static void test_toplevel_stat(void)
2738 IStorage *stg = NULL;
2739 HRESULT r;
2740 STATSTG stat;
2741 char prev_dir[MAX_PATH];
2742 char temp[MAX_PATH];
2743 char full_path[MAX_PATH];
2744 LPSTR rel_pathA;
2745 WCHAR rel_path[MAX_PATH];
2747 DeleteFileA(filenameA);
2749 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2750 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2751 ok(r==S_OK, "StgCreateDocfile failed\n");
2753 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2754 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2755 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2756 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2757 CoTaskMemFree(stat.pwcsName);
2759 IStorage_Release( stg );
2761 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2762 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2764 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2765 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2766 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2767 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2768 CoTaskMemFree(stat.pwcsName);
2770 IStorage_Release( stg );
2772 DeleteFileA(filenameA);
2774 /* Stat always returns the full path, even for files opened with a relative path. */
2775 GetCurrentDirectoryA(MAX_PATH, prev_dir);
2777 GetTempPathA(MAX_PATH, temp);
2779 SetCurrentDirectoryA(temp);
2781 GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA);
2782 MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH);
2784 r = StgCreateDocfile( rel_path, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2785 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2786 ok(r==S_OK, "StgCreateDocfile failed\n");
2788 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2789 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2790 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2791 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2792 CoTaskMemFree(stat.pwcsName);
2794 IStorage_Release( stg );
2796 r = StgOpenStorage( rel_path, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2797 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2799 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2800 ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r);
2801 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2802 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2803 CoTaskMemFree(stat.pwcsName);
2805 IStorage_Release( stg );
2807 SetCurrentDirectoryA(prev_dir);
2809 DeleteFileA(filenameA);
2812 static void test_substorage_enum(void)
2814 IStorage *stg, *stg2;
2815 IEnumSTATSTG *ee;
2816 HRESULT r;
2817 ULONG ref;
2818 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2820 DeleteFileA(filenameA);
2822 /* create the file */
2823 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2824 STGM_READWRITE, 0, &stg);
2825 ok(r==S_OK, "StgCreateDocfile failed\n");
2827 /* create a substorage */
2828 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2829 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2831 /* create an enumelements */
2832 r = IStorage_EnumElements(stg2, 0, NULL, 0, &ee);
2833 ok(r==S_OK, "IStorage->EnumElements failed, hr=%08x\n", r);
2835 /* release the substorage */
2836 ref = IStorage_Release(stg2);
2837 todo_wine ok(ref==0, "storage not released\n");
2839 /* reopening fails, because the substorage is really still open */
2840 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2841 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage failed, hr=%08x\n", r);
2843 /* destroying the storage invalidates the enumerator */
2844 r = IStorage_DestroyElement(stg, stgname);
2845 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2847 r = IEnumSTATSTG_Reset(ee);
2848 ok(r==STG_E_REVERTED, "IEnumSTATSTG->Reset failed, hr=%08x\n", r);
2850 IEnumSTATSTG_Release(ee);
2852 IStorage_Release(stg);
2854 r = DeleteFileA(filenameA);
2855 ok( r == TRUE, "deleted file\n");
2858 static void test_copyto_locking(void)
2860 IStorage *stg, *stg2, *stg3, *stg4;
2861 IStream *stm;
2862 HRESULT r;
2863 static const WCHAR stgname[] = { 'S','T','G','1',0 };
2864 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
2865 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2867 DeleteFileA(filenameA);
2869 /* create the file */
2870 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2871 STGM_READWRITE, 0, &stg);
2872 ok(r==S_OK, "StgCreateDocfile failed\n");
2874 /* create a substorage */
2875 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2876 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2878 /* create another substorage */
2879 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
2880 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2882 /* add a stream, and leave it open */
2883 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2884 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2886 /* Try to copy the storage while the stream is open */
2887 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
2888 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2890 IStream_Release(stm);
2892 /* create a substorage */
2893 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg4);
2894 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2896 /* Try to copy the storage while the substorage is open */
2897 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
2898 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2900 IStorage_Release(stg4);
2901 IStorage_Release(stg3);
2902 IStorage_Release(stg2);
2903 IStorage_Release(stg);
2905 r = DeleteFileA(filenameA);
2906 ok( r == TRUE, "deleted file\n");
2909 static void test_copyto_recursive(void)
2911 IStorage *stg, *stg2, *stg3, *stg4;
2912 HRESULT r;
2913 static const WCHAR stgname[] = { 'S','T','G','1',0 };
2914 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
2916 DeleteFileA(filenameA);
2918 /* create the file */
2919 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2920 STGM_READWRITE, 0, &stg);
2921 ok(r==S_OK, "StgCreateDocfile failed\n");
2923 /* create a substorage */
2924 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2925 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2927 /* copy the parent to the child */
2928 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
2929 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2931 /* create a transacted substorage */
2932 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg3);
2933 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2935 /* copy the parent to the transacted child */
2936 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
2937 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2939 /* create a transacted subsubstorage */
2940 r = IStorage_CreateStorage(stg3, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg4);
2941 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2943 /* copy the parent to the transacted child of the transacted child */
2944 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg4);
2945 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2947 /* copy the parent but exclude storage objects */
2948 r = IStorage_CopyTo(stg, 1, &IID_IStorage, NULL, stg4);
2949 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2951 IStorage_Release(stg4);
2952 IStorage_Release(stg3);
2953 IStorage_Release(stg2);
2954 IStorage_Release(stg);
2956 r = DeleteFileA(filenameA);
2957 ok( r == TRUE, "deleted file\n");
2960 static void test_hglobal_storage_creation(void)
2962 ILockBytes *ilb = NULL;
2963 IStorage *stg = NULL;
2964 HRESULT r;
2965 STATSTG stat;
2966 char junk[512];
2967 ULARGE_INTEGER offset;
2969 r = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb);
2970 ok(r == S_OK, "CreateILockBytesOnHGlobal failed, hr=%x\n", r);
2972 offset.QuadPart = 0;
2973 memset(junk, 0xaa, 512);
2974 r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
2975 ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
2977 offset.QuadPart = 2000;
2978 r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL);
2979 ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r);
2981 r = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stg);
2982 ok(r == S_OK, "StgCreateDocfileOnILockBytes failed, hr=%x\n", r);
2984 IStorage_Release(stg);
2986 r = StgOpenStorageOnILockBytes(ilb, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE,
2987 NULL, 0, &stg);
2988 ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
2990 if (SUCCEEDED(r))
2992 r = IStorage_Stat(stg, &stat, STATFLAG_NONAME);
2993 ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r);
2994 ok(IsEqualCLSID(&stat.clsid, &GUID_NULL), "unexpected CLSID value\n");
2996 IStorage_Release(stg);
2999 r = ILockBytes_Stat(ilb, &stat, STATFLAG_NONAME);
3000 ok(r == S_OK, "ILockBytes_Stat failed, hr=%x\n", r);
3001 ok(stat.cbSize.u.LowPart < 2512, "expected truncated size, got %d\n", stat.cbSize.u.LowPart);
3003 ILockBytes_Release(ilb);
3006 static void test_convert(void)
3008 static const WCHAR filename[] = {'s','t','o','r','a','g','e','.','s','t','g',0};
3009 IStorage *stg;
3010 HRESULT hr;
3012 hr = GetConvertStg(NULL);
3013 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3015 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
3016 ok(hr == S_OK, "StgCreateDocfile failed\n");
3017 hr = GetConvertStg(stg);
3018 ok(hr == STG_E_FILENOTFOUND, "got 0x%08x\n", hr);
3019 hr = SetConvertStg(stg, TRUE);
3020 ok(hr == S_OK, "got 0x%08x\n", hr);
3021 hr = SetConvertStg(stg, TRUE);
3022 ok(hr == S_OK, "got 0x%08x\n", hr);
3023 hr = GetConvertStg(stg);
3024 ok(hr == S_OK, "got 0x%08x\n", hr);
3025 hr = SetConvertStg(stg, FALSE);
3026 ok(hr == S_OK, "got 0x%08x\n", hr);
3027 hr = GetConvertStg(stg);
3028 ok(hr == S_FALSE, "got 0x%08x\n", hr);
3030 IStorage_Release(stg);
3032 DeleteFileW(filename);
3035 START_TEST(storage32)
3037 CHAR temp[MAX_PATH];
3039 GetTempPathA(MAX_PATH, temp);
3040 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
3042 win_skip("Could not create temp file, %u\n", GetLastError());
3043 return;
3045 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
3046 DeleteFileA(filenameA);
3048 test_hglobal_storage_stat();
3049 test_create_storage_modes();
3050 test_stgcreatestorageex();
3051 test_storage_stream();
3052 test_open_storage();
3053 test_storage_suminfo();
3054 test_storage_refcount();
3055 test_streamenum();
3056 test_transact();
3057 test_substorage_share();
3058 test_revert();
3059 test_parent_free();
3060 test_nonroot_transacted();
3061 test_ReadClassStm();
3062 test_access();
3063 test_writeclassstg();
3064 test_readonly();
3065 test_simple();
3066 test_fmtusertypestg();
3067 test_references();
3068 test_copyto();
3069 test_copyto_snbexclusions();
3070 test_copyto_iidexclusions_storage();
3071 test_copyto_iidexclusions_stream();
3072 test_rename();
3073 test_toplevel_stat();
3074 test_substorage_enum();
3075 test_copyto_locking();
3076 test_copyto_recursive();
3077 test_hglobal_storage_creation();
3078 test_convert();