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
26 #include "wine/test.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;
66 r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
67 ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
69 mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
70 r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
71 ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
73 r = WriteClassStg( stg, &test_stg_cls );
74 ok( r == S_OK, "WriteClassStg failed\n");
76 memset( &stat, 0, sizeof stat );
77 r = IStorage_Stat( stg, &stat, 0 );
79 ok( stat.pwcsName == NULL, "storage name not null\n");
80 ok( stat.type == 1, "type is wrong\n");
81 ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
82 ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
84 refcount = IStorage_Release( stg );
85 ok( refcount == 0, "IStorage refcount is wrong\n");
86 refcount = ILockBytes_Release( ilb );
87 ok( refcount == 0, "ILockBytes refcount is wrong\n");
90 static void test_create_storage_modes(void)
95 DeleteFileA(filenameA);
97 /* test with some invalid parameters */
98 r = StgCreateDocfile( NULL, 0, 0, &stg);
99 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
100 r = StgCreateDocfile( filename, 0, 0, &stg);
101 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
102 r = StgCreateDocfile( filename, STGM_CREATE, 0, &stg);
103 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
104 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE, 0, &stg);
105 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
106 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
107 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
108 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
109 ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
110 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
111 ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
112 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
113 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
114 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
115 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
116 r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
117 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
119 /* StgCreateDocfile seems to be very particular about the flags it accepts */
120 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
121 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
122 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
123 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
124 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
125 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
126 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
127 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
128 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
129 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
130 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
131 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
132 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
133 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
134 ok(stg == NULL, "stg was set\n");
136 /* check what happens if the file already exists (which is how it's meant to be used) */
137 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
138 ok(r==S_OK, "StgCreateDocfile failed\n");
139 r = IStorage_Release(stg);
140 ok(r == 0, "storage not released\n");
141 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
142 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
143 r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
144 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
145 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE, 0, &stg);
146 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
147 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE, 0, &stg);
148 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
149 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE, 0, &stg);
150 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
151 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
152 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
153 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, &stg);
154 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
155 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_WRITE, 0, &stg);
156 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
157 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_WRITE, 0, &stg);
158 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
159 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
160 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
161 r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
162 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
163 ok(DeleteFileA(filenameA), "failed to delete file\n");
165 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
166 ok(r==S_OK, "StgCreateDocfile failed\n");
167 r = IStorage_Release(stg);
168 ok(r == 0, "storage not released\n");
169 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
170 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
171 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
172 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
174 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
175 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
176 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
177 ok(r==S_OK, "StgCreateDocfile failed\n");
178 r = IStorage_Release(stg);
179 ok(r == 0, "storage not released\n");
180 ok(DeleteFileA(filenameA), "failed to delete file\n");
182 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
183 ok(r==S_OK, "StgCreateDocfile failed\n");
184 r = IStorage_Release(stg);
185 ok(r == 0, "storage not released\n");
186 ok(DeleteFileA(filenameA), "failed to delete file\n");
188 /* test the way excel uses StgCreateDocFile */
189 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
190 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
193 r = IStorage_Release(stg);
194 ok(r == 0, "storage not released\n");
195 ok(DeleteFileA(filenameA), "failed to delete file\n");
198 /* and the way windows media uses it ... */
199 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_NONE | STGM_READWRITE | STGM_TRANSACTED, 0, &stg);
200 ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
203 r = IStorage_Release(stg);
204 ok(r == 0, "storage not released\n");
205 ok(DeleteFileA(filenameA), "failed to delete file\n");
208 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
209 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
210 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
213 r = IStorage_Release(stg);
214 ok(r == 0, "storage not released\n");
215 ok(DeleteFileA(filenameA), "failed to delete file\n");
218 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg);
219 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
222 r = IStorage_Release(stg);
223 ok(r == 0, "storage not released\n");
224 ok(DeleteFileA(filenameA), "failed to delete file\n");
227 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
228 ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
231 r = IStorage_Release(stg);
232 ok(r == 0, "storage not released\n");
233 ok(DeleteFileA(filenameA), "failed to delete file\n");
236 /* test the way msi uses StgCreateDocfile */
237 r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
238 ok(r==S_OK, "StgCreateDocFile failed\n");
239 r = IStorage_Release(stg);
240 ok(r == 0, "storage not released\n");
241 ok(DeleteFileA(filenameA), "failed to delete file\n");
244 static void test_storage_stream(void)
246 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
247 static const WCHAR longname[] = {
248 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
249 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
251 IStorage *stg = NULL;
254 IStream *stm2 = NULL;
258 unsigned char buffer[0x100];
260 DeleteFileA(filenameA);
262 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
263 ok(r==S_OK, "StgCreateDocfile failed\n");
265 /* try create some invalid streams */
266 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, 0, &stm );
267 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
268 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 1, &stm );
269 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
270 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, NULL );
271 ok(r==STG_E_INVALIDPOINTER, "IStorage->CreateStream wrong error\n");
272 r = IStorage_CreateStream(stg, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
273 ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error\n");
274 r = IStorage_CreateStream(stg, longname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
275 ok(r==STG_E_INVALIDNAME || broken(r==S_OK) /* nt4 */,
276 "IStorage->CreateStream wrong error, got %d GetLastError()=%d\n", r, GetLastError());
277 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE, 0, 0, &stm );
278 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
279 r = IStorage_CreateStream(stg, stmname, STGM_READ, 0, 0, &stm );
280 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
281 r = IStorage_CreateStream(stg, stmname, STGM_WRITE, 0, 0, &stm );
282 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
283 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, 0, &stm );
284 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
285 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READ, 0, 0, &stm );
286 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
288 /* now really create a stream and delete it */
289 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
290 ok(r==S_OK, "IStorage->CreateStream failed\n");
291 r = IStream_Release(stm);
292 ok(r == 0, "wrong ref count\n");
293 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
294 ok(r==STG_E_FILEALREADYEXISTS, "IStorage->CreateStream failed\n");
295 r = IStorage_DestroyElement(stg,stmname);
296 ok(r==S_OK, "IStorage->DestroyElement failed\n");
298 /* create a stream and write to it */
299 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
300 ok(r==S_OK, "IStorage->CreateStream failed\n");
302 r = IStream_Clone(stm, &stm2);
303 ok(r==S_OK, "failed to clone stream\n");
305 r = IStream_Write(stm, NULL, 0, NULL );
306 ok(r==STG_E_INVALIDPOINTER, "IStream->Write wrong error\n");
307 r = IStream_Write(stm, "Hello\n", 0, NULL );
308 ok(r==S_OK, "failed to write stream\n");
309 r = IStream_Write(stm, "Hello\n", 0, &count );
310 ok(r==S_OK, "failed to write stream\n");
311 r = IStream_Write(stm, "Hello\n", 6, &count );
312 ok(r==S_OK, "failed to write stream\n");
313 r = IStream_Commit(stm, STGC_DEFAULT );
314 ok(r==S_OK, "failed to commit stream\n");
315 r = IStream_Commit(stm, STGC_DEFAULT );
316 ok(r==S_OK, "failed to commit stream\n");
318 /* Read past the end of the stream. */
320 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
321 ok(r==S_OK, "failed to seek stream\n");
322 ok(p.QuadPart == 3, "at wrong place\n");
323 r = IStream_Read(stm, buffer, sizeof buffer, &count );
324 ok(r==S_OK, "failed to read\n");
325 ok(count == 3, "read bytes past end of stream\n");
327 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
328 ok(r==S_OK, "failed to seek stream\n");
329 ok(p.QuadPart == 10, "at wrong place\n");
330 r = IStream_Read(stm, buffer, sizeof buffer, &count );
331 ok(r==S_OK, "failed to read\n");
332 ok(count == 0, "read bytes past end of stream\n");
333 pos.QuadPart = 10000;
334 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
335 ok(r==S_OK, "failed to seek stream\n");
336 ok(p.QuadPart == 10000, "at wrong place\n");
337 r = IStream_Read(stm, buffer, sizeof buffer, &count );
338 ok(r==S_OK, "failed to read\n");
339 ok(count == 0, "read bytes past end of stream\n");
341 /* Convert to a big block stream, and read past the end. */
343 r = IStream_SetSize(stm,p);
344 ok(r==S_OK, "failed to set pos\n");
346 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
347 ok(r==S_OK, "failed to seek stream\n");
348 ok(p.QuadPart == 4997, "at wrong place\n");
349 r = IStream_Read(stm, buffer, sizeof buffer, &count );
350 ok(r==S_OK, "failed to read\n");
351 ok(count == 3, "read bytes past end of stream\n");
353 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
354 ok(r==S_OK, "failed to seek stream\n");
355 ok(p.QuadPart == 5001, "at wrong place\n");
356 r = IStream_Read(stm, buffer, sizeof buffer, &count );
357 ok(r==S_OK, "failed to read\n");
358 ok(count == 0, "read bytes past end of stream\n");
359 pos.QuadPart = 10000;
360 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
361 ok(r==S_OK, "failed to seek stream\n");
362 ok(p.QuadPart == 10000, "at wrong place\n");
363 r = IStream_Read(stm, buffer, sizeof buffer, &count );
364 ok(r==S_OK, "failed to read\n");
365 ok(count == 0, "read bytes past end of stream\n");
367 /* seek round a bit, reset the stream size */
369 r = IStream_Seek(stm, pos, 3, &p );
370 ok(r==STG_E_INVALIDFUNCTION, "IStream->Seek returned wrong error\n");
371 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
372 ok(r==S_OK, "failed to seek stream\n");
373 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
374 ok(r==S_OK, "failed to seek stream\n");
375 r = IStream_SetSize(stm,p);
376 ok(r==S_OK, "failed to set pos\n");
378 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
379 ok(r==S_OK, "failed to seek stream\n");
380 ok(p.QuadPart == 10, "at wrong place\n");
381 r = IStream_Read(stm, buffer, sizeof buffer, &count );
382 ok(r==S_OK, "failed to set pos\n");
383 ok(count == 0, "read bytes from empty stream\n");
384 pos.QuadPart = 10000;
385 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
386 ok(r==S_OK, "failed to seek stream\n");
387 ok(p.QuadPart == 10000, "at wrong place\n");
388 r = IStream_Read(stm, buffer, sizeof buffer, &count );
389 ok(r==S_OK, "failed to set pos\n");
390 ok(count == 0, "read bytes from empty stream\n");
392 r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
393 ok(r==S_OK, "failed to seek stream\n");
394 ok(p.QuadPart == 0, "at wrong place\n");
395 r = IStream_Read(stm, buffer, sizeof buffer, &count );
396 ok(r==S_OK, "failed to set pos\n");
397 ok(count == 0, "read bytes from empty stream\n");
400 r = IStream_Release(stm2);
401 ok(r == 0, "wrong ref count\n");
403 /* create a stream and write to it */
404 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
405 ok(r==S_OK, "IStorage->CreateStream failed\n");
407 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p);
408 ok(r==STG_E_REVERTED, "overwritten stream should return STG_E_REVERTED instead of 0x%08x\n", r);
410 r = IStream_Release(stm2);
411 ok(r == 0, "wrong ref count\n");
412 r = IStream_Release(stm);
413 ok(r == 0, "wrong ref count\n");
415 r = IStorage_Release(stg);
416 ok(r == 0, "wrong ref count\n");
418 /* try create some invalid streams */
421 r = StgOpenStorage(filename, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
422 ok(r == S_OK, "should succeed\n");
425 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
426 ok(r == STG_E_INVALIDFLAG, "IStorage->OpenStream should return STG_E_INVALIDFLAG instead of 0x%08x\n", r);
427 IStorage_Release(stg);
430 r = DeleteFileA(filenameA);
431 ok(r, "file should exist\n");
434 static BOOL touch_file(LPCSTR filename)
438 file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
439 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
440 if (file==INVALID_HANDLE_VALUE)
446 static BOOL is_zero_length(LPCSTR filename)
451 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
452 OPEN_EXISTING, 0, NULL);
453 if (file==INVALID_HANDLE_VALUE)
455 len = GetFileSize(file, NULL);
460 static BOOL is_existing_file(LPCSTR filename)
464 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
465 OPEN_EXISTING, 0, NULL);
466 if (file==INVALID_HANDLE_VALUE)
472 static void test_open_storage(void)
474 static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
475 IStorage *stg = NULL, *stg2 = NULL;
479 /* try opening a zero length file - it should stay zero length */
480 DeleteFileA(filenameA);
481 touch_file(filenameA);
482 stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
483 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
484 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
486 stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
487 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
488 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
489 ok(is_zero_length(filenameA), "file length changed\n");
491 DeleteFileA(filenameA);
493 /* try opening a nonexistent file - it should not create it */
494 stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
495 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
496 ok(r!=S_OK, "StgOpenStorage failed: 0x%08x\n", r);
497 if (r==S_OK) IStorage_Release(stg);
498 ok(!is_existing_file(filenameA), "StgOpenStorage should not create a file\n");
499 DeleteFileA(filenameA);
501 /* create the file */
502 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
503 ok(r==S_OK, "StgCreateDocfile failed\n");
504 IStorage_Release(stg);
506 r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
507 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
508 r = StgOpenStorage( NULL, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
509 ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
510 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, NULL);
511 ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
512 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 1, &stg);
513 ok(r==STG_E_INVALIDPARAMETER, "StgOpenStorage wrong error\n");
514 r = StgOpenStorage( szNonExist, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
515 ok(r==STG_E_FILENOTFOUND, "StgOpenStorage failed\n");
516 r = StgOpenStorage( filename, NULL, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
517 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
518 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
519 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
520 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
521 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
522 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
523 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
525 /* open it for real */
526 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg); /* XLViewer 97/2000 */
527 ok(r==S_OK, "StgOpenStorage failed\n");
530 r = IStorage_Release(stg);
531 ok(r == 0, "wrong ref count\n");
534 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
535 ok(r==S_OK, "StgOpenStorage failed\n");
538 r = IStorage_Release(stg);
539 ok(r == 0, "wrong ref count\n");
542 /* test the way word opens its custom dictionary */
543 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
544 STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
545 ok(r==S_OK, "StgOpenStorage failed\n");
548 r = IStorage_Release(stg);
549 ok(r == 0, "wrong ref count\n");
552 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
553 ok(r==S_OK, "StgOpenStorage failed\n");
554 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
555 ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
558 r = IStorage_Release(stg);
559 ok(r == 0, "wrong ref count\n");
562 /* now try write to a storage file we opened read-only */
563 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
564 ok(r==S_OK, "StgOpenStorage failed\n");
567 static const WCHAR stmname[] = { 'w','i','n','e','t','e','s','t',0};
569 IStorage *stg2 = NULL;
571 r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
573 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
574 r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
575 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
577 r = IStorage_Release(stg);
578 ok(r == 0, "wrong ref count\n");
581 /* open like visio 2003 */
583 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
584 ok(r == S_OK, "should succeed\n");
586 IStorage_Release(stg);
588 /* test other sharing modes with STGM_PRIORITY */
590 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
591 ok(r == S_OK, "should succeed\n");
593 IStorage_Release(stg);
596 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
597 ok(r == S_OK, "should succeed\n");
599 IStorage_Release(stg);
602 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_READ, NULL, 0, &stg);
603 ok(r == S_OK, "should succeed\n");
605 IStorage_Release(stg);
607 /* open like Project 2003 */
609 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
610 ok(r == S_OK, "should succeed\n");
611 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg2);
612 ok(r == S_OK, "should succeed\n");
614 IStorage_Release(stg2);
616 IStorage_Release(stg);
619 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
620 ok(r == STG_E_INVALIDFLAG, "should fail\n");
622 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
623 ok(r == STG_E_INVALIDFLAG, "should fail\n");
625 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
626 ok(r == STG_E_INVALIDFLAG, "should fail\n");
628 r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
629 ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
631 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
632 ok(r == STG_E_INVALIDFLAG, "should fail\n");
634 r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
635 ok(r == STG_E_INVALIDFLAG, "should fail\n");
637 r = DeleteFileA(filenameA);
638 ok(r, "file didn't exist\n");
641 static void test_storage_suminfo(void)
643 IStorage *stg = NULL;
644 IPropertySetStorage *propset = NULL;
645 IPropertyStorage *ps = NULL;
648 DeleteFileA(filenameA);
650 /* create the file */
651 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
652 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
653 ok(r==S_OK, "StgCreateDocfile failed\n");
655 r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
656 ok(r == S_OK, "query interface failed\n");
659 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
660 ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
662 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
663 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
664 ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
666 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
667 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
668 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
670 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
672 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
674 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
675 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
677 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
678 STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
679 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
681 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
682 STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
683 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
685 /* now try really creating a property set */
686 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
687 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
688 ok(r == S_OK, "failed to create property set storage\n");
691 IPropertyStorage_Release(ps);
693 /* now try creating the same thing again */
694 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
695 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
696 ok(r == S_OK, "failed to create property set storage\n");
698 IPropertyStorage_Release(ps);
700 /* should be able to open it */
701 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
702 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
703 ok(r == S_OK, "open failed\n");
705 IPropertyStorage_Release(ps);
708 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
709 ok(r == S_OK, "failed to delete property set storage\n");
711 /* try opening with an invalid FMTID */
712 r = IPropertySetStorage_Open( propset, NULL,
713 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
714 ok(r == E_INVALIDARG, "open succeeded\n");
716 IPropertyStorage_Release(ps);
719 r = IPropertySetStorage_Open( propset, &IID_IStorage,
720 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
721 ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
723 IPropertyStorage_Release(ps);
726 /* try some invalid flags */
727 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
728 STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
729 ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
731 IPropertyStorage_Release(ps);
733 /* after deleting it, it should be gone */
734 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
735 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
736 ok(r == STG_E_FILENOTFOUND, "open failed\n");
738 IPropertyStorage_Release(ps);
740 r = IPropertySetStorage_Release( propset );
741 ok(r == 1, "ref count wrong\n");
743 r = IStorage_Release(stg);
744 ok(r == 0, "ref count wrong\n");
746 DeleteFileA(filenameA);
749 static void test_storage_refcount(void)
751 IStorage *stg = NULL;
752 IStorage *stgprio = NULL;
755 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
761 DeleteFileA(filenameA);
763 /* create the file */
764 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
765 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
766 ok(r==S_OK, "StgCreateDocfile failed\n");
768 r = WriteClassStg( stg, &test_stg_cls );
769 ok( r == S_OK, "WriteClassStg failed\n");
771 r = IStorage_Commit( stg, STGC_DEFAULT );
772 ok( r == S_OK, "IStorage_Commit failed\n");
774 /* now create a stream */
775 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
776 ok(r==S_OK, "IStorage->CreateStream failed\n");
778 r = IStorage_Release( stg );
779 ok (r == 0, "storage not released\n");
782 r = IStream_Seek( stm, pos, 0, &upos );
783 ok (r == STG_E_REVERTED, "seek should fail\n");
785 r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
786 ok (r == STG_E_REVERTED, "stat should fail\n");
788 r = IStream_Write( stm, "Test string", strlen("Test string"), NULL);
789 ok (r == STG_E_REVERTED, "IStream_Write should return STG_E_REVERTED instead of 0x%08x\n", r);
791 r = IStream_Read( stm, buffer, sizeof(buffer), NULL);
792 ok (r == STG_E_REVERTED, "IStream_Read should return STG_E_REVERTED instead of 0x%08x\n", r);
794 r = IStream_Release(stm);
795 ok (r == 0, "stream not released\n");
797 /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
798 * StgOpenStorage calls in transacted mode */
799 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio);
800 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
803 /* non-transacted mode read/write fails */
804 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
805 ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r);
808 /* non-transacted mode read-only succeeds */
809 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg);
810 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
811 IStorage_Release(stg);
813 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
814 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
817 static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
818 static const WCHAR stgname2[] = { 'C','V','_','i','e','w',0 };
819 static const WCHAR stmname2[] = { 'V','a','r','2','D','a','t','a',0 };
824 r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
825 ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
826 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
827 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
828 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
829 ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
830 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg.grfMode);
831 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
832 ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
833 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
834 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
836 r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
837 ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
839 r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
840 ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
841 ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)),
842 "Statstg pwcsName should have been the name the storage was created with\n");
843 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
844 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
845 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
846 ok(statstg.grfMode == STGM_SHARE_EXCLUSIVE,
847 "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%x\n", statstg.grfMode);
848 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
849 ok(IsEqualCLSID(&statstg.clsid, &CLSID_NULL), "Statstg clsid is not CLSID_NULL\n");
850 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
851 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
852 CoTaskMemFree(statstg.pwcsName);
854 r = IStorage_CreateStorage( stg2, stgname2, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stg3 );
855 ok(r == STG_E_ACCESSDENIED, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
857 r = IStorage_CreateStream( stg2, stmname2, STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
858 ok(r == STG_E_ACCESSDENIED, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
860 IStorage_Release(stg2);
862 r = IStorage_Release(stg);
863 ok(r == 0, "wrong ref count\n");
865 IStorage_Release(stgprio);
867 DeleteFileA(filenameA);
870 static void test_writeclassstg(void)
872 IStorage *stg = NULL;
876 DeleteFileA(filenameA);
878 /* create the file */
879 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
880 STGM_READWRITE, 0, &stg);
881 ok(r==S_OK, "StgCreateDocfile failed\n");
883 r = ReadClassStg( NULL, NULL );
884 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
886 r = ReadClassStg( stg, NULL );
887 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
889 temp_cls.Data1 = 0xdeadbeef;
890 r = ReadClassStg( stg, &temp_cls );
891 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
893 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
895 r = WriteClassStg( NULL, NULL );
896 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
898 r = WriteClassStg( stg, NULL );
899 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
901 r = WriteClassStg( stg, &test_stg_cls );
902 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
904 r = ReadClassStg( stg, &temp_cls );
905 ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
906 ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
908 r = IStorage_Release( stg );
909 ok (r == 0, "storage not released\n");
911 DeleteFileA(filenameA);
914 static void test_streamenum(void)
916 IStorage *stg = NULL;
919 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
920 static const WCHAR stmname2[] = { 'A','B','C','D','E','F','G','H','I',0 };
921 static const WCHAR stmname3[] = { 'A','B','C','D','E','F','G','H','I','J',0 };
923 IEnumSTATSTG *ee = NULL;
926 DeleteFileA(filenameA);
928 /* create the file */
929 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
930 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
931 ok(r==S_OK, "StgCreateDocfile failed\n");
933 r = WriteClassStg( stg, &test_stg_cls );
934 ok( r == S_OK, "WriteClassStg failed\n");
936 r = IStorage_Commit( stg, STGC_DEFAULT );
937 ok( r == S_OK, "IStorage_Commit failed\n");
939 /* now create a stream */
940 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
941 ok(r==S_OK, "IStorage->CreateStream failed\n");
943 r = IStream_Release(stm);
945 /* first enum ... should be 1 stream */
946 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
947 ok(r==S_OK, "IStorage->EnumElements failed\n");
950 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
951 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
952 ok(count == 1, "count wrong\n");
955 CoTaskMemFree(stat.pwcsName);
957 r = IEnumSTATSTG_Release(ee);
959 /* second enum... destroy the stream before reading */
960 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
961 ok(r==S_OK, "IStorage->EnumElements failed\n");
963 r = IStorage_DestroyElement(stg, stmname);
964 ok(r==S_OK, "IStorage->DestroyElement failed\n");
967 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
968 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
969 ok(count == 0, "count wrong\n");
971 /* reset and try again */
972 r = IEnumSTATSTG_Reset(ee);
973 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
976 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
977 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
978 ok(count == 0, "count wrong\n");
980 /* add a stream before reading */
981 r = IEnumSTATSTG_Reset(ee);
982 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
984 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
985 ok(r==S_OK, "IStorage->CreateStream failed\n");
987 r = IStream_Release(stm);
990 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
991 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
992 ok(count == 1, "count wrong\n");
996 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
997 CoTaskMemFree(stat.pwcsName);
1000 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1001 ok(r==S_OK, "IStorage->CreateStream failed\n");
1003 r = IStream_Release(stm);
1006 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1007 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1008 ok(count == 1, "count wrong\n");
1012 ok(lstrcmpiW(stat.pwcsName, stmname2) == 0, "expected ABCDEFGHI, got %s\n", wine_dbgstr_w(stat.pwcsName));
1013 CoTaskMemFree(stat.pwcsName);
1016 /* delete previous and next stream after reading */
1017 r = IStorage_CreateStream(stg, stmname3, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1018 ok(r==S_OK, "IStorage->CreateStream failed\n");
1020 r = IStream_Release(stm);
1022 r = IEnumSTATSTG_Reset(ee);
1023 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1026 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1027 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1028 ok(count == 1, "count wrong\n");
1032 ok(lstrcmpiW(stat.pwcsName, stmname) == 0, "expected CONTENTS, got %s\n", wine_dbgstr_w(stat.pwcsName));
1033 CoTaskMemFree(stat.pwcsName);
1036 r = IStorage_DestroyElement(stg, stmname);
1037 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1039 r = IStorage_DestroyElement(stg, stmname2);
1040 ok(r==S_OK, "IStorage->DestroyElement failed\n");
1043 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1044 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1045 ok(count == 1, "count wrong\n");
1049 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1050 CoTaskMemFree(stat.pwcsName);
1053 r = IStorage_Release( stg );
1054 todo_wine ok (r == 0, "storage not released\n");
1056 /* enumerator is still valid and working after the storage is released */
1057 r = IEnumSTATSTG_Reset(ee);
1058 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
1061 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
1062 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
1063 ok(count == 1, "count wrong\n");
1067 ok(lstrcmpiW(stat.pwcsName, stmname3) == 0, "expected ABCDEFGHIJ, got %s\n", wine_dbgstr_w(stat.pwcsName));
1068 CoTaskMemFree(stat.pwcsName);
1071 /* the storage is left open until the enumerator is freed */
1072 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE |
1073 STGM_READWRITE |STGM_TRANSACTED, NULL, 0, &stg);
1074 ok(r==STG_E_SHAREVIOLATION ||
1075 r==STG_E_LOCKVIOLATION, /* XP-SP2/W2K3-SP1 and below */
1076 "StgCreateDocfile failed, res=%x\n", r);
1078 r = IEnumSTATSTG_Release(ee);
1079 ok (r == 0, "enum not released\n");
1081 DeleteFileA(filenameA);
1084 static void test_transact(void)
1086 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1088 IStream *stm = NULL;
1089 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1090 static const WCHAR stmname2[] = { 'F','O','O',0 };
1091 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1092 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1094 DeleteFileA(filenameA);
1096 /* create the file */
1097 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1098 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1099 ok(r==S_OK, "StgCreateDocfile failed\n");
1101 /* commit a new stream and storage */
1102 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1103 ok(r==S_OK, "IStorage->CreateStream failed\n");
1105 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1106 ok(r==S_OK, "IStream->Write failed\n");
1108 IStream_Release(stm);
1110 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1111 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1115 /* Create two substorages but only commit one */
1116 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1117 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1120 IStorage_Release(stg3);
1122 r = IStorage_Commit(stg, 0);
1123 ok(r==S_OK, "IStorage->Commit failed\n");
1125 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1126 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1129 IStorage_Release(stg3);
1131 IStorage_Release(stg2);
1134 /* now create a stream and storage, but don't commit them */
1136 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1137 ok(r==S_OK, "IStorage->CreateStream failed\n");
1139 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
1140 ok(r==S_OK, "IStream->Write failed\n");
1142 /* IStream::Commit does nothing for OLE storage streams */
1143 r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
1144 ok(r==S_OK, "IStream->Commit failed\n");
1146 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1147 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1150 IStorage_Release(stg2);
1152 IStream_Release(stm);
1154 IStorage_Release(stg);
1158 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
1159 ok(r==S_OK, "StgOpenStorage failed\n");
1164 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1165 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1167 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1168 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1170 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1171 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1173 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1174 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1176 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1177 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1179 IStream_Release(stm);
1181 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1182 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1184 IStorage_Release(stg2);
1186 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1187 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1189 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1190 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1192 IStream_Release(stm);
1194 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1195 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1198 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1199 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1201 IStorage_Release(stg3);
1203 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1204 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1206 IStorage_Release(stg3);
1208 IStorage_Release(stg2);
1211 IStorage_Release(stg);
1213 r = DeleteFileA(filenameA);
1214 ok( r == TRUE, "deleted file\n");
1217 static void test_substorage_share(void)
1219 IStorage *stg, *stg2, *stg3;
1220 IStream *stm, *stm2;
1222 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1223 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1224 static const WCHAR othername[] = { 'N','E','W','N','A','M','E',0 };
1226 DeleteFileA(filenameA);
1228 /* create the file */
1229 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1230 STGM_READWRITE, 0, &stg);
1231 ok(r==S_OK, "StgCreateDocfile failed\n");
1233 /* create a read/write storage and try to open it again */
1234 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1235 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1239 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1240 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1243 IStorage_Release(stg3);
1245 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1246 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage should fail %08x\n", r);
1249 IStorage_Release(stg3);
1251 /* cannot rename the storage while it's open */
1252 r = IStorage_RenameElement(stg, stgname, othername);
1253 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1254 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stgname);
1256 /* destroying an object while it's open invalidates it */
1257 r = IStorage_DestroyElement(stg, stgname);
1258 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1260 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1261 ok(r==STG_E_REVERTED, "IStorage->CreateStream failed, hr=%08x\n", r);
1264 IStorage_Release(stm);
1266 IStorage_Release(stg2);
1269 /* create a read/write stream and try to open it again */
1270 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
1271 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
1275 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1276 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1279 IStorage_Release(stm2);
1281 r = IStorage_OpenStream(stg, stmname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm2);
1282 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStream should fail %08x\n", r);
1285 IStorage_Release(stm2);
1287 /* cannot rename the stream while it's open */
1288 r = IStorage_RenameElement(stg, stmname, othername);
1289 ok(r==STG_E_ACCESSDENIED, "IStorage->RenameElement should fail %08x\n", r);
1290 if (SUCCEEDED(r)) IStorage_RenameElement(stg, othername, stmname);
1292 /* destroying an object while it's open invalidates it */
1293 r = IStorage_DestroyElement(stg, stmname);
1294 ok(r==S_OK, "IStorage->DestroyElement failed, hr=%08x\n", r);
1296 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1297 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1299 IStorage_Release(stm);
1302 IStorage_Release(stg);
1304 r = DeleteFileA(filenameA);
1305 ok( r == TRUE, "deleted file\n");
1308 static void test_revert(void)
1310 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1312 IStream *stm = NULL, *stm2 = NULL;
1313 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1314 static const WCHAR stmname2[] = { 'F','O','O',0 };
1315 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1316 static const WCHAR stgname2[] = { 'T','E','M','P','S','T','G',0 };
1319 DeleteFileA(filenameA);
1321 /* create the file */
1322 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1323 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1324 ok(r==S_OK, "StgCreateDocfile failed\n");
1326 /* commit a new stream and storage */
1327 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1328 ok(r==S_OK, "IStorage->CreateStream failed\n");
1330 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
1331 ok(r==S_OK, "IStream->Write failed\n");
1333 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1334 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1338 /* Create two substorages but only commit one */
1339 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1340 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1343 IStorage_Release(stg3);
1345 r = IStorage_Commit(stg, 0);
1346 ok(r==S_OK, "IStorage->Commit failed\n");
1348 r = IStorage_CreateStorage(stg2, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1349 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1352 IStorage_Release(stg3);
1355 /* now create a stream and storage, then revert */
1356 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
1357 ok(r==S_OK, "IStorage->CreateStream failed\n");
1359 r = IStream_Write(stm2, "this is stream 2\n", 16, NULL);
1360 ok(r==S_OK, "IStream->Write failed\n");
1362 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1363 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1365 r = IStorage_Revert(stg);
1367 /* all open objects become invalid */
1368 r = IStream_Write(stm, "this shouldn't work\n", 20, NULL);
1369 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1371 r = IStream_Write(stm2, "this shouldn't work\n", 20, NULL);
1372 ok(r==STG_E_REVERTED, "IStream_Write should fail %08x\n", r);
1374 r = IStorage_Stat(stg2, &statstg, STATFLAG_NONAME);
1375 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1377 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1378 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1380 IStream_Release(stm);
1381 IStream_Release(stm2);
1382 IStorage_Release(stg2);
1383 IStorage_Release(stg3);
1385 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
1386 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
1388 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1389 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1391 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1392 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
1394 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1395 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1397 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1398 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1400 IStream_Release(stm);
1402 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1403 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1405 IStorage_Release(stg2);
1407 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1408 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
1410 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1411 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1413 IStream_Release(stm);
1415 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
1416 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1419 r = IStorage_OpenStorage(stg2, stgname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1420 ok(r==S_OK, "IStorage->OpenStorage should succeed %08x\n", r);
1422 IStorage_Release(stg3);
1424 r = IStorage_OpenStorage(stg2, stgname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg3 );
1425 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStorage should fail %08x\n", r);
1427 IStorage_Release(stg3);
1429 IStorage_Release(stg2);
1432 IStorage_Release(stg);
1434 r = DeleteFileA(filenameA);
1435 ok( r == TRUE, "deleted file\n");
1437 /* Revert only invalidates objects in transacted mode */
1438 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1439 STGM_READWRITE, 0, &stg);
1440 ok(r==S_OK, "StgCreateDocfile failed\n");
1442 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1443 ok(r==S_OK, "IStorage->CreateStream failed\n");
1445 r = IStorage_Revert(stg);
1446 ok(r==S_OK, "IStorage->Revert failed %08x\n", r);
1448 r = IStream_Write(stm, "this works\n", 11, NULL);
1449 ok(r==S_OK, "IStream_Write should succeed %08x\n", r);
1451 IStream_Release(stm);
1452 IStream_Release(stg);
1454 r = DeleteFileA(filenameA);
1455 ok( r == TRUE, "deleted file\n");
1458 static void test_parent_free(void)
1460 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1462 IStream *stm = NULL;
1463 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1464 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1468 DeleteFileA(filenameA);
1470 /* create the file */
1471 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1472 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1473 ok(r==S_OK, "StgCreateDocfile failed\n");
1475 /* create a new storage */
1476 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
1477 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1481 /* now create a stream inside the new storage */
1482 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1483 ok(r==S_OK, "IStorage->CreateStream failed\n");
1487 /* create a storage inside the new storage */
1488 r = IStorage_CreateStorage(stg2, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg3 );
1489 ok(r==S_OK, "IStorage->CreateStorage failed\n");
1492 /* free the parent */
1493 ref = IStorage_Release(stg2);
1494 ok(ref == 0, "IStorage still has %u references\n", ref);
1496 /* child objects are invalid */
1499 r = IStream_Write(stm, "this should fail\n", 17, NULL);
1500 ok(r==STG_E_REVERTED, "IStream->Write sould fail, hr=%x\n", r);
1502 IStream_Release(stm);
1504 r = IStorage_Stat(stg3, &statstg, STATFLAG_NONAME);
1505 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1507 r = IStorage_SetStateBits(stg3, 1, 1);
1508 ok(r==STG_E_REVERTED, "IStorage_Stat should fail %08x\n", r);
1510 IStorage_Release(stg3);
1514 IStorage_Release(stg);
1516 r = DeleteFileA(filenameA);
1517 ok( r == TRUE, "deleted file\n");
1520 static void test_nonroot_transacted(void)
1522 IStorage *stg = NULL, *stg2 = NULL, *stg3 = NULL;
1524 IStream *stm = NULL;
1525 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
1526 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1527 static const WCHAR stmname2[] = { 'F','O','O',0 };
1529 DeleteFileA(filenameA);
1531 /* create a transacted file */
1532 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1533 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
1534 ok(r==S_OK, "StgCreateDocfile failed\n");
1536 /* create a transacted substorage */
1537 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1538 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1542 /* create and commit stmname */
1543 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1544 ok(r==S_OK, "IStorage->CreateStream failed\n");
1546 IStream_Release(stm);
1548 IStorage_Commit(stg2, 0);
1550 /* create and revert stmname2 */
1551 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1552 ok(r==S_OK, "IStorage->CreateStream failed\n");
1554 IStream_Release(stm);
1556 IStorage_Revert(stg2);
1558 /* check that Commit and Revert really worked */
1559 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1560 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1562 IStream_Release(stm);
1564 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1565 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1567 IStream_Release(stm);
1569 IStorage_Release(stg2);
1572 /* create a read-only transacted substorage */
1573 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, NULL, 0, &stg2);
1574 ok(r==S_OK, "IStorage->OpenStorage failed, hr=%08x\n", r);
1578 /* The storage can be modified. */
1579 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
1580 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1582 IStream_Release(stg3);
1584 /* But changes cannot be committed. */
1585 r = IStorage_Commit(stg2, 0);
1586 ok(r==STG_E_ACCESSDENIED, "IStorage->Commit should fail, hr=%08x\n", r);
1588 IStorage_Release(stg2);
1591 IStorage_Release(stg);
1593 /* create a non-transacted file */
1594 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
1595 STGM_READWRITE, 0, &stg);
1596 ok(r==S_OK, "StgCreateDocfile failed\n");
1598 /* create a transacted substorage */
1599 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg2);
1600 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
1604 /* create and commit stmname */
1605 r = IStorage_CreateStream(stg2, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1606 ok(r==S_OK, "IStorage->CreateStream failed\n");
1608 IStream_Release(stm);
1610 IStorage_Commit(stg2, 0);
1612 /* create and revert stmname2 */
1613 r = IStorage_CreateStream(stg2, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
1614 ok(r==S_OK, "IStorage->CreateStream failed\n");
1616 IStream_Release(stm);
1618 IStorage_Revert(stg2);
1620 /* check that Commit and Revert really worked */
1621 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1622 ok(r==S_OK, "IStorage->OpenStream should succeed %08x\n", r);
1624 IStream_Release(stm);
1626 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
1627 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
1629 IStream_Release(stm);
1631 IStorage_Release(stg2);
1634 IStream_Release(stg);
1636 r = DeleteFileA(filenameA);
1637 ok( r == TRUE, "deleted file\n");
1640 static void test_ReadClassStm(void)
1645 static const LARGE_INTEGER llZero;
1647 hr = ReadClassStm(NULL, &clsid);
1648 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1650 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1651 ok_ole_success(hr, "CreateStreamOnHGlobal");
1652 hr = WriteClassStm(pStream, &test_stg_cls);
1653 ok_ole_success(hr, "WriteClassStm");
1655 hr = ReadClassStm(pStream, NULL);
1656 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1658 /* test not rewound stream */
1659 hr = ReadClassStm(pStream, &clsid);
1660 ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1661 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1663 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1664 ok_ole_success(hr, "IStream_Seek");
1665 hr = ReadClassStm(pStream, &clsid);
1666 ok_ole_success(hr, "ReadClassStm");
1667 ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
1669 IStream_Release(pStream);
1679 static const struct access_res create[16] =
1681 { TRUE, ERROR_SUCCESS, TRUE },
1682 { TRUE, ERROR_SUCCESS, TRUE },
1683 { TRUE, ERROR_SUCCESS, FALSE },
1684 { TRUE, ERROR_SUCCESS, FALSE },
1685 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1686 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1687 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1688 { TRUE, ERROR_SUCCESS, FALSE },
1689 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1690 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1691 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1692 { TRUE, ERROR_SUCCESS, TRUE },
1693 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1694 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1695 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1696 { TRUE, ERROR_SUCCESS, TRUE }
1699 static const struct access_res create_commit[16] =
1701 { TRUE, ERROR_SUCCESS, TRUE },
1702 { TRUE, ERROR_SUCCESS, TRUE },
1703 { TRUE, ERROR_SUCCESS, FALSE },
1704 { TRUE, ERROR_SUCCESS, FALSE },
1705 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1706 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1707 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1708 { TRUE, ERROR_SUCCESS, FALSE },
1709 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1710 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1711 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1712 { TRUE, ERROR_SUCCESS, TRUE },
1713 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1714 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1715 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1716 { TRUE, ERROR_SUCCESS, TRUE }
1719 static const struct access_res create_close[16] =
1721 { TRUE, ERROR_SUCCESS, FALSE },
1722 { TRUE, ERROR_SUCCESS, FALSE },
1723 { TRUE, ERROR_SUCCESS, FALSE },
1724 { TRUE, ERROR_SUCCESS, FALSE },
1725 { TRUE, ERROR_SUCCESS, FALSE },
1726 { TRUE, ERROR_SUCCESS, FALSE },
1727 { TRUE, ERROR_SUCCESS, FALSE },
1728 { TRUE, ERROR_SUCCESS, FALSE },
1729 { TRUE, ERROR_SUCCESS, FALSE },
1730 { TRUE, ERROR_SUCCESS, FALSE },
1731 { TRUE, ERROR_SUCCESS, FALSE },
1732 { TRUE, ERROR_SUCCESS, FALSE },
1733 { TRUE, ERROR_SUCCESS, FALSE },
1734 { TRUE, ERROR_SUCCESS, FALSE },
1735 { TRUE, ERROR_SUCCESS, FALSE },
1736 { TRUE, ERROR_SUCCESS }
1739 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1741 DWORD access = 0, share = 0;
1746 for (i = 0; i < 4; i++)
1748 if (i == 0) access = 0;
1749 if (i == 1) access = GENERIC_READ;
1750 if (i == 2) access = GENERIC_WRITE;
1751 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
1753 for (j = 0; j < 4; j++)
1755 if (ares[idx].ignore)
1758 if (j == 0) share = 0;
1759 if (j == 1) share = FILE_SHARE_READ;
1760 if (j == 2) share = FILE_SHARE_WRITE;
1761 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
1763 SetLastError(0xdeadbeef);
1764 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
1765 FILE_ATTRIBUTE_NORMAL, 0);
1766 lasterr = GetLastError();
1768 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
1769 "(%d, handle, %d): Expected %d, got %d\n",
1770 line, idx, ares[idx].gothandle,
1771 (hfile != INVALID_HANDLE_VALUE));
1773 ok(lasterr == ares[idx].lasterr ||
1774 broken(lasterr == 0xdeadbeef) /* win9x */,
1775 "(%d, lasterr, %d): Expected %d, got %d\n",
1776 line, idx, ares[idx].lasterr, lasterr);
1784 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1786 static void test_access(void)
1791 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1793 /* STGM_TRANSACTED */
1795 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1796 STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, &stg);
1797 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1799 test_file_access("winetest", create);
1801 hr = IStorage_Commit(stg, STGC_DEFAULT);
1802 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1804 test_file_access("winetest", create_commit);
1806 IStorage_Release(stg);
1808 test_file_access("winetest", create_close);
1810 DeleteFileA("winetest");
1814 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1815 STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &stg);
1816 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1818 test_file_access("winetest", create);
1820 hr = IStorage_Commit(stg, STGC_DEFAULT);
1821 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1823 test_file_access("winetest", create_commit);
1825 IStorage_Release(stg);
1827 test_file_access("winetest", create_close);
1829 DeleteFileA("winetest");
1831 /* STGM_SHARE_DENY_NONE */
1833 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1834 STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
1835 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1837 test_file_access("winetest", create);
1839 hr = IStorage_Commit(stg, STGC_DEFAULT);
1840 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1842 test_file_access("winetest", create_commit);
1844 IStorage_Release(stg);
1846 test_file_access("winetest", create_close);
1848 DeleteFileA("winetest");
1850 /* STGM_SHARE_DENY_READ */
1852 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1853 STGM_SHARE_DENY_READ | STGM_TRANSACTED, 0, &stg);
1854 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1856 test_file_access("winetest", create);
1858 hr = IStorage_Commit(stg, STGC_DEFAULT);
1859 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1861 test_file_access("winetest", create_commit);
1863 IStorage_Release(stg);
1865 test_file_access("winetest", create_close);
1867 DeleteFileA("winetest");
1869 /* STGM_SHARE_DENY_WRITE */
1871 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1872 STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
1873 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1875 test_file_access("winetest", create);
1877 hr = IStorage_Commit(stg, STGC_DEFAULT);
1878 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1880 test_file_access("winetest", create_commit);
1882 IStorage_Release(stg);
1884 test_file_access("winetest", create_close);
1886 DeleteFileA("winetest");
1889 static void test_readonly(void)
1891 IStorage *stg, *stg2, *stg3;
1894 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1895 static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
1896 static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
1898 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1899 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1902 hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
1903 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1906 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
1907 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1909 IStream_Release(stream);
1910 IStorage_Release(stg2);
1912 IStorage_Release(stg);
1915 /* re-open read only */
1916 hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
1917 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1920 hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
1921 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1924 /* CreateStream on read-only storage, name exists */
1925 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1926 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1928 IStream_Release(stream);
1930 /* CreateStream on read-only storage, name does not exist */
1931 hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1932 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1934 IStream_Release(stream);
1936 /* CreateStorage on read-only storage, name exists */
1937 hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1938 ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
1940 IStream_Release(stg3);
1942 /* CreateStorage on read-only storage, name does not exist */
1943 hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1944 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1946 IStream_Release(stg3);
1948 /* DestroyElement on read-only storage, name exists */
1949 hr = IStorage_DestroyElement( stg2, streamW );
1950 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1952 /* DestroyElement on read-only storage, name does not exist */
1953 hr = IStorage_DestroyElement( stg2, storageW );
1954 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1956 IStorage_Release(stg2);
1959 IStorage_Release(stg);
1962 DeleteFileA("winetest");
1965 static void test_simple(void)
1967 /* Tests for STGM_SIMPLE mode */
1969 IStorage *stg, *stg2;
1972 static const WCHAR stgname[] = { 'S','t','g',0 };
1973 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1974 static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
1976 ULARGE_INTEGER upos;
1980 DeleteFileA(filenameA);
1982 r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1983 ok(r == S_OK, "got %08x\n", r);
1985 r = IStorage_CreateStorage(stg, stgname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2);
1986 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
1987 if (SUCCEEDED(r)) IStorage_Release(stg2);
1989 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1990 ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
1991 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1992 ok(r == S_OK, "got %08x\n", r);
1994 upos.QuadPart = 6000;
1995 r = IStream_SetSize(stm, upos);
1996 ok(r == S_OK, "got %08x\n", r);
1998 r = IStream_Write(stm, "foo", 3, &count);
1999 ok(r == S_OK, "got %08x\n", r);
2000 ok(count == 3, "got %d\n", count);
2003 r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
2004 ok(r == S_OK, "got %08x\n", r);
2005 ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
2007 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2009 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2012 ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
2015 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
2016 ok(r == S_OK, "got %08x\n", r);
2017 ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
2019 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2021 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
2024 ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
2026 IStream_Release(stm);
2028 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
2029 ok(r == S_OK, "got %08x\n", r);
2031 upos.QuadPart = 100;
2032 r = IStream_SetSize(stm, upos);
2033 ok(r == S_OK, "got %08x\n", r);
2035 r = IStream_Write(stm, "foo", 3, &count);
2036 ok(r == S_OK, "got %08x\n", r);
2037 ok(count == 3, "got %d\n", count);
2039 IStream_Release(stm);
2041 IStorage_Commit(stg, STGC_DEFAULT);
2042 IStorage_Release(stg);
2044 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
2045 if (r == STG_E_INVALIDFLAG)
2047 win_skip("Flag combination is not supported on NT4 and below\n");
2048 DeleteFileA(filenameA);
2051 ok(r == S_OK, "got %08x\n", r);
2053 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg2);
2054 ok(r == STG_E_INVALIDFUNCTION, "got %08x\n", r);
2055 if (SUCCEEDED(r)) IStorage_Release(stg2);
2057 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2058 ok(r == S_OK, "got %08x\n", r);
2060 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2061 ok(r == S_OK, "got %08x\n", r);
2062 ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
2064 IStream_Release(stm);
2066 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
2067 ok(r == S_OK, "got %08x\n", r);
2069 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
2070 ok(r == S_OK, "got %08x\n", r);
2071 ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
2073 IStream_Release(stm);
2076 IStorage_Release(stg);
2078 DeleteFileA(filenameA);
2081 static void test_fmtusertypestg(void)
2086 static const char fileA[] = {'f','m','t','t','e','s','t',0};
2087 static const WCHAR fileW[] = {'f','m','t','t','e','s','t',0};
2088 static WCHAR userTypeW[] = {'S','t','g','U','s','r','T','y','p','e',0};
2089 static WCHAR strmNameW[] = {1,'C','o','m','p','O','b','j',0};
2091 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
2092 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2096 /* try to write the stream */
2097 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2098 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2100 /* check that the stream was created */
2101 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2102 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2108 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2110 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2113 ok(0, "found unexpected stream or storage\n");
2114 CoTaskMemFree(statstg.pwcsName);
2116 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2117 IEnumSTATSTG_Release(stat);
2120 /* re-write the stream */
2121 hr = WriteFmtUserTypeStg(stg, 0, userTypeW);
2122 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2124 /* check that the stream is still there */
2125 hr = IStorage_EnumElements(stg, 0, NULL, 0, &stat);
2126 ok(hr == S_OK, "should succeed, res=%x\n", hr);
2132 while ((hr = IEnumSTATSTG_Next(stat, 1, &statstg, &got)) == S_OK && got == 1)
2134 if (strcmp_ww(statstg.pwcsName, strmNameW) == 0)
2137 ok(0, "found unexpected stream or storage\n");
2138 CoTaskMemFree(statstg.pwcsName);
2140 ok(found == TRUE, "expected storage to contain stream \\0001CompObj\n");
2141 IEnumSTATSTG_Release(stat);
2144 IStorage_Release(stg);
2145 DeleteFileA( fileA );
2149 static void test_references(void)
2151 IStorage *stg,*stg2;
2154 static const WCHAR StorName[] = { 'D','a','t','a','S','p','a','c','e','I','n','f','o',0 };
2156 DeleteFileA(filenameA);
2158 hr = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2159 ok(hr==S_OK, "StgCreateDocfile failed\n");
2163 IStorage_Release(stg);
2165 hr = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
2166 ok(hr==S_OK, "StgOpenStorage failed (result=%x)\n",hr);
2170 hr = IStorage_CreateStorage(stg,StorName,STGM_READWRITE | STGM_SHARE_EXCLUSIVE,0,0,&stg2);
2171 ok(hr == S_OK, "IStorage_CreateStorage failed (result=%x)\n",hr);
2175 c1 = IStorage_AddRef(stg);
2176 ok(c1 == 2, "creating internal storage added references to ancestor\n");
2177 c1 = IStorage_AddRef(stg);
2178 IStorage_Release(stg2);
2179 c2 = IStorage_AddRef(stg) - 1;
2180 ok(c1 == c2, "releasing internal storage removed references to ancestor\n");
2182 c1 = IStorage_Release(stg);
2183 while ( c1 ) c1 = IStorage_Release(stg);
2187 DeleteFileA(filenameA);
2192 * | `StreamA: "StreamA"
2194 * | `StreamB: "StreamB"
2195 * `StreamC: "StreamC"
2197 static HRESULT create_test_file(IStorage *dest)
2199 IStorage *stgA = NULL, *stgB = NULL;
2200 IStream *strmA = NULL, *strmB = NULL, *strmC = NULL;
2201 const ULONG strmA_name_size = lstrlenW(strmA_name) * sizeof(WCHAR);
2202 const ULONG strmB_name_size = lstrlenW(strmB_name) * sizeof(WCHAR);
2203 const ULONG strmC_name_size = lstrlenW(strmC_name) * sizeof(WCHAR);
2207 hr = IStorage_CreateStorage(dest, stgA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgA);
2208 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2212 hr = IStorage_CreateStream(stgA, strmA_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmA);
2213 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2217 hr = IStream_Write(strmA, strmA_name, strmA_name_size, &bytes);
2218 ok(hr == S_OK && bytes == strmA_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmA_name_size);
2220 hr = IStorage_CreateStorage(dest, stgB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stgB);
2221 ok(hr == S_OK, "IStorage_CreateStorage failed: 0x%08x\n", hr);
2225 hr = IStorage_CreateStream(stgB, strmB_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmB);
2226 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2230 hr = IStream_Write(strmB, strmB_name, strmB_name_size, &bytes);
2231 ok(hr == S_OK && bytes == strmB_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmB_name_size);
2233 hr = IStorage_CreateStream(dest, strmC_name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &strmC);
2234 ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr);
2238 hr = IStream_Write(strmC, strmC_name, strmC_name_size, &bytes);
2239 ok(hr == S_OK && bytes == strmC_name_size, "IStream_Write failed: 0x%08x, %d of %d bytes written\n", hr, bytes, strmC_name_size);
2243 IStream_Release(strmC);
2245 IStream_Release(strmB);
2247 IStorage_Release(stgB);
2249 IStream_Release(strmA);
2251 IStorage_Release(stgA);
2256 static void test_copyto(void)
2258 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2263 /* create & populate file1 */
2264 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2265 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2269 hr = create_test_file(file1);
2274 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2275 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2279 /* copy file1 into file2 */
2280 hr = IStorage_CopyTo(file1, 0, NULL, NULL, NULL);
2281 ok(hr == STG_E_INVALIDPOINTER, "CopyTo should give STG_E_INVALIDPONITER, gave: 0x%08x\n", hr);
2283 hr = IStorage_CopyTo(file1, 0, NULL, NULL, file2);
2284 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2288 /* verify that all of file1 was copied */
2289 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2290 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2291 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2294 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2295 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2296 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2299 memset(buf, 0, sizeof(buf));
2300 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2301 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2303 ok(strcmp_ww(buf, strmA_name) == 0,
2304 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmA_name), wine_dbgstr_w(buf));
2306 IStream_Release(strm_tmp);
2309 IStorage_Release(stg_tmp);
2312 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2313 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2314 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2317 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2318 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2319 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2322 memset(buf, 0, sizeof(buf));
2323 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2324 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2326 ok(strcmp_ww(buf, strmB_name) == 0,
2327 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2329 IStream_Release(strm_tmp);
2332 IStorage_Release(stg_tmp);
2335 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2336 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2337 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2340 memset(buf, 0, sizeof(buf));
2341 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2342 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2344 ok(strcmp_ww(buf, strmC_name) == 0,
2345 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2347 IStream_Release(strm_tmp);
2352 IStorage_Release(file1);
2354 IStorage_Release(file2);
2356 DeleteFileA(file1_nameA);
2357 DeleteFileA(file2_nameA);
2360 static void test_copyto_snbexclusions(void)
2362 static const WCHAR *snb_exclude[] = {stgA_name, strmB_name, strmC_name, 0};
2364 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2369 /* create & populate file1 */
2370 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2371 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2375 hr = create_test_file(file1);
2380 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2381 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2385 /* copy file1 to file2 with name exclusions */
2386 hr = IStorage_CopyTo(file1, 0, NULL, (SNB)snb_exclude, file2);
2387 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2391 /* verify that file1 copied over, respecting exclusions */
2392 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2393 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2394 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2396 IStorage_Release(stg_tmp);
2398 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2399 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2400 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2402 IStream_Release(strm_tmp);
2404 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2405 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2406 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2409 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2410 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2411 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2414 memset(buf, 0, sizeof(buf));
2415 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2416 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2418 ok(strcmp_ww(buf, strmB_name) == 0,
2419 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmB_name), wine_dbgstr_w(buf));
2421 IStream_Release(strm_tmp);
2424 IStorage_Release(stg_tmp);
2427 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2428 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2429 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2431 IStream_Release(strm_tmp);
2435 IStorage_Release(file1);
2437 IStorage_Release(file2);
2439 DeleteFileA(file1_nameA);
2440 DeleteFileA(file2_nameA);
2443 static void test_copyto_iidexclusions_storage(void)
2445 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2450 /* create & populate file1 */
2451 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2452 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2456 hr = create_test_file(file1);
2461 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2462 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2466 /* copy file1 to file2 with iid exclusions */
2467 hr = IStorage_CopyTo(file1, 1, &IID_IStorage, NULL, file2);
2468 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2472 /* verify that file1 copied over, respecting exclusions */
2473 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2474 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2475 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2477 IStorage_Release(stg_tmp);
2479 hr = IStorage_OpenStream(file2, strmA_name, NULL,
2480 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2481 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2483 IStream_Release(strm_tmp);
2485 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2486 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2487 ok(hr == STG_E_FILENOTFOUND, "OpenStorage should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2489 IStorage_Release(stg_tmp);
2491 hr = IStorage_OpenStream(file2, strmB_name, NULL,
2492 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2493 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2495 IStream_Release(strm_tmp);
2497 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2498 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2499 ok(hr == S_OK, "OpenStream failed: 0x%08x\n", hr);
2502 memset(buf, 0, sizeof(buf));
2503 hr = IStream_Read(strm_tmp, buf, sizeof(buf), NULL);
2504 ok(hr == S_OK, "Read failed: 0x%08x\n", hr);
2506 ok(strcmp_ww(buf, strmC_name) == 0,
2507 "Expected %s to be read, got %s\n", wine_dbgstr_w(strmC_name), wine_dbgstr_w(buf));
2509 IStream_Release(strm_tmp);
2514 IStorage_Release(file1);
2516 IStorage_Release(file2);
2518 DeleteFileA(file1_nameA);
2519 DeleteFileA(file2_nameA);
2522 static void test_copyto_iidexclusions_stream(void)
2524 IStorage *file1 = NULL, *file2 = NULL, *stg_tmp;
2528 /* create & populate file1 */
2529 hr = StgCreateDocfile(file1_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file1);
2530 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2534 hr = create_test_file(file1);
2539 hr = StgCreateDocfile(file2_name, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &file2);
2540 ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
2544 /* copy file1 to file2 with iid exclusions */
2545 hr = IStorage_CopyTo(file1, 1, &IID_IStream, NULL, file2);
2546 ok(hr == S_OK, "CopyTo failed: 0x%08x\n", hr);
2550 /* verify that file1 copied over, respecting exclusions */
2551 hr = IStorage_OpenStorage(file2, stgA_name, NULL,
2552 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2553 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2556 hr = IStorage_OpenStream(stg_tmp, strmA_name, NULL,
2557 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2558 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2560 IStream_Release(strm_tmp);
2562 IStorage_Release(stg_tmp);
2565 hr = IStorage_OpenStorage(file2, stgB_name, NULL,
2566 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg_tmp);
2567 ok(hr == S_OK, "OpenStorage failed: 0x%08x\n", hr);
2570 hr = IStorage_OpenStream(stg_tmp, strmB_name, NULL,
2571 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2572 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2574 IStream_Release(strm_tmp);
2576 IStorage_Release(stg_tmp);
2579 hr = IStorage_OpenStream(file2, strmC_name, NULL,
2580 STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &strm_tmp);
2581 ok(hr == STG_E_FILENOTFOUND, "OpenStream should give STG_E_FILENOTFOUND, gave: 0x%08x\n", hr);
2583 IStream_Release(strm_tmp);
2587 IStorage_Release(file1);
2589 IStorage_Release(file2);
2591 DeleteFileA(file1_nameA);
2592 DeleteFileA(file2_nameA);
2595 static void test_rename(void)
2597 IStorage *stg, *stg2;
2600 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2601 static const WCHAR stgname2[] = { 'S','T','G',0 };
2602 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2603 static const WCHAR stmname2[] = { 'E','N','T','S',0 };
2605 DeleteFileA(filenameA);
2607 /* create the file */
2608 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2609 STGM_READWRITE, 0, &stg);
2610 ok(r==S_OK, "StgCreateDocfile failed\n");
2612 /* create a substorage */
2613 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2614 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2616 /* create a stream in the substorage */
2617 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2618 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2619 IStream_Release(stm);
2621 /* rename the stream */
2622 r = IStorage_RenameElement(stg2, stmname, stmname2);
2623 ok(r==S_OK, "IStorage->RenameElement failed, hr=%08x\n", r);
2625 /* cannot open stream with old name */
2626 r = IStorage_OpenStream(stg2, stmname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2627 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2628 if (SUCCEEDED(r)) IStream_Release(stm);
2630 /* can open stream with new name */
2631 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2632 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2633 if (SUCCEEDED(r)) IStream_Release(stm);
2635 IStorage_Release(stg2);
2637 /* rename the storage */
2638 IStorage_RenameElement(stg, stgname, stgname2);
2640 /* cannot open storage with old name */
2641 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2642 ok(r==STG_E_FILENOTFOUND, "IStorage_OpenStream should fail, hr=%08x\n", r);
2643 if (SUCCEEDED(r)) IStorage_Release(stg2);
2645 /* can open storage with new name */
2646 r = IStorage_OpenStorage(stg, stgname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg2);
2647 ok(r==S_OK, "IStorage_OpenStream should fail, hr=%08x\n", r);
2650 /* opened storage still has the stream */
2651 r = IStorage_OpenStream(stg2, stmname2, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
2652 ok(r==S_OK, "IStorage_OpenStream failed, hr=%08x\n", r);
2653 if (SUCCEEDED(r)) IStream_Release(stm);
2655 IStorage_Release(stg2);
2658 IStorage_Release(stg);
2660 r = DeleteFileA(filenameA);
2661 ok( r == TRUE, "deleted file\n");
2664 static void test_toplevel_stat(void)
2666 IStorage *stg = NULL;
2669 char prev_dir[MAX_PATH];
2670 char temp[MAX_PATH];
2671 char full_path[MAX_PATH];
2673 WCHAR rel_path[MAX_PATH];
2675 DeleteFileA(filenameA);
2677 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2678 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2679 ok(r==S_OK, "StgCreateDocfile failed\n");
2681 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2682 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2683 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2684 CoTaskMemFree(stat.pwcsName);
2686 IStorage_Release( stg );
2688 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2689 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2691 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2692 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2693 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2694 CoTaskMemFree(stat.pwcsName);
2696 IStorage_Release( stg );
2698 DeleteFileA(filenameA);
2700 /* Stat always returns the full path, even for files opened with a relative path. */
2701 GetCurrentDirectoryA(MAX_PATH, prev_dir);
2703 GetTempPathA(MAX_PATH, temp);
2705 SetCurrentDirectoryA(temp);
2707 GetFullPathNameA(filenameA, MAX_PATH, full_path, &rel_pathA);
2708 MultiByteToWideChar(CP_ACP, 0, rel_pathA, -1, rel_path, MAX_PATH);
2710 r = StgCreateDocfile( rel_path, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2711 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
2712 ok(r==S_OK, "StgCreateDocfile failed\n");
2714 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2715 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2716 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2717 CoTaskMemFree(stat.pwcsName);
2719 IStorage_Release( stg );
2721 r = StgOpenStorage( rel_path, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
2722 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
2724 r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT );
2725 ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n",
2726 wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName));
2727 CoTaskMemFree(stat.pwcsName);
2729 IStorage_Release( stg );
2731 SetCurrentDirectoryA(prev_dir);
2733 DeleteFileA(filenameA);
2736 static void test_substorage_enum(void)
2738 IStorage *stg, *stg2;
2742 static const WCHAR stgname[] = { 'P','E','R','M','S','T','G',0 };
2744 DeleteFileA(filenameA);
2746 /* create the file */
2747 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2748 STGM_READWRITE, 0, &stg);
2749 ok(r==S_OK, "StgCreateDocfile failed\n");
2751 /* create a substorage */
2752 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2753 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2755 /* create an enumelements */
2756 r = IStorage_EnumElements(stg2, 0, NULL, 0, &ee);
2757 ok(r==S_OK, "IStorage->EnumElements failed, hr=%08x\n", r);
2759 /* release the substorage */
2760 ref = IStorage_Release(stg2);
2761 todo_wine ok(ref==0, "storage not released\n");
2763 /* reopening fails, because the substorage is really still open */
2764 r = IStorage_OpenStorage(stg, stgname, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2765 ok(r==STG_E_ACCESSDENIED, "IStorage->OpenStorage failed, hr=%08x\n", r);
2767 /* destroying the storage invalidates the enumerator */
2768 r = IStorage_DestroyElement(stg, stgname);
2769 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2771 r = IEnumSTATSTG_Reset(ee);
2772 ok(r==STG_E_REVERTED, "IEnumSTATSTG->Reset failed, hr=%08x\n", r);
2774 IEnumSTATSTG_Release(ee);
2776 IStorage_Release(stg);
2778 r = DeleteFileA(filenameA);
2779 ok( r == TRUE, "deleted file\n");
2782 static void test_copyto_locking(void)
2784 IStorage *stg, *stg2, *stg3, *stg4;
2787 static const WCHAR stgname[] = { 'S','T','G','1',0 };
2788 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
2789 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
2791 DeleteFileA(filenameA);
2793 /* create the file */
2794 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2795 STGM_READWRITE, 0, &stg);
2796 ok(r==S_OK, "StgCreateDocfile failed\n");
2798 /* create a substorage */
2799 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2800 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2802 /* create another substorage */
2803 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg3);
2804 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2806 /* add a stream, and leave it open */
2807 r = IStorage_CreateStream(stg2, stmname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
2808 ok(r==S_OK, "IStorage->CreateStream failed, hr=%08x\n", r);
2810 /* Try to copy the storage while the stream is open */
2811 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
2812 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2814 IStream_Release(stm);
2816 /* create a substorage */
2817 r = IStorage_CreateStorage(stg2, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg4);
2818 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2820 /* Try to copy the storage while the substorage is open */
2821 r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
2822 todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2824 IStorage_Release(stg4);
2825 IStorage_Release(stg3);
2826 IStorage_Release(stg2);
2827 IStorage_Release(stg);
2829 r = DeleteFileA(filenameA);
2830 ok( r == TRUE, "deleted file\n");
2833 static void test_copyto_recursive(void)
2835 IStorage *stg, *stg2, *stg3, *stg4;
2837 static const WCHAR stgname[] = { 'S','T','G','1',0 };
2838 static const WCHAR stgname2[] = { 'S','T','G','2',0 };
2840 DeleteFileA(filenameA);
2842 /* create the file */
2843 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
2844 STGM_READWRITE, 0, &stg);
2845 ok(r==S_OK, "StgCreateDocfile failed\n");
2847 /* create a substorage */
2848 r = IStorage_CreateStorage(stg, stgname, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
2849 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2851 /* copy the parent to the child */
2852 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
2853 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2855 /* create a transacted substorage */
2856 r = IStorage_CreateStorage(stg, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg3);
2857 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2859 /* copy the parent to the transacted child */
2860 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg2);
2861 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2863 /* create a transacted subsubstorage */
2864 r = IStorage_CreateStorage(stg3, stgname2, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, 0, &stg4);
2865 ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r);
2867 /* copy the parent to the transacted child of the transacted child */
2868 r = IStorage_CopyTo(stg, 0, NULL, NULL, stg4);
2869 ok(r==STG_E_ACCESSDENIED, "IStorage->CopyTo failed, hr=%08x\n", r);
2871 /* copy the parent but exclude storage objects */
2872 r = IStorage_CopyTo(stg, 1, &IID_IStorage, NULL, stg4);
2873 ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
2875 IStorage_Release(stg4);
2876 IStorage_Release(stg3);
2877 IStorage_Release(stg2);
2878 IStorage_Release(stg);
2880 r = DeleteFileA(filenameA);
2881 ok( r == TRUE, "deleted file\n");
2884 START_TEST(storage32)
2886 CHAR temp[MAX_PATH];
2888 GetTempPathA(MAX_PATH, temp);
2889 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
2891 win_skip("Could not create temp file, %u\n", GetLastError());
2894 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
2895 DeleteFileA(filenameA);
2897 test_hglobal_storage_stat();
2898 test_create_storage_modes();
2899 test_storage_stream();
2900 test_open_storage();
2901 test_storage_suminfo();
2902 test_storage_refcount();
2905 test_substorage_share();
2908 test_nonroot_transacted();
2909 test_ReadClassStm();
2911 test_writeclassstg();
2914 test_fmtusertypestg();
2917 test_copyto_snbexclusions();
2918 test_copyto_iidexclusions_storage();
2919 test_copyto_iidexclusions_stream();
2921 test_toplevel_stat();
2922 test_substorage_enum();
2923 test_copyto_locking();
2924 test_copyto_recursive();