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 void test_hglobal_storage_stat(void)
41 ILockBytes *ilb = NULL;
47 r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb );
48 ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n");
50 mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/
51 r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg );
52 ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n");
54 r = WriteClassStg( stg, &test_stg_cls );
55 ok( r == S_OK, "WriteClassStg failed\n");
57 memset( &stat, 0, sizeof stat );
58 r = IStorage_Stat( stg, &stat, 0 );
60 ok( stat.pwcsName == NULL, "storage name not null\n");
61 ok( stat.type == 1, "type is wrong\n");
62 ok( stat.grfMode == 0x12, "grf mode is incorrect\n");
63 ok( !memcmp(&stat.clsid, &test_stg_cls, sizeof test_stg_cls), "CLSID is wrong\n");
65 refcount = IStorage_Release( stg );
66 ok( refcount == 0, "IStorage refcount is wrong\n");
67 refcount = ILockBytes_Release( ilb );
68 ok( refcount == 0, "ILockBytes refcount is wrong\n");
71 static void test_create_storage_modes(void)
76 DeleteFileA(filenameA);
78 /* test with some invalid parameters */
79 r = StgCreateDocfile( NULL, 0, 0, &stg);
80 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
81 r = StgCreateDocfile( filename, 0, 0, &stg);
82 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
83 r = StgCreateDocfile( filename, STGM_CREATE, 0, &stg);
84 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
85 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE, 0, &stg);
86 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
87 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &stg);
88 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
89 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, NULL);
90 ok(r==STG_E_INVALIDPOINTER, "StgCreateDocfile succeeded\n");
91 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, &stg);
92 ok(r==STG_E_INVALIDPARAMETER, "StgCreateDocfile succeeded\n");
93 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
94 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
95 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &stg);
96 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
97 r = StgCreateDocfile( filename, STGM_PRIORITY, 0, &stg);
98 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
100 /* StgCreateDocfile seems to be very particular about the flags it accepts */
101 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | STGM_WRITE, 0, &stg);
102 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
103 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 8, 0, &stg);
104 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
105 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80, 0, &stg);
106 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
107 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800, 0, &stg);
108 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
109 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x8000, 0, &stg);
110 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
111 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x80000, 0, &stg);
112 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
113 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED | 0x800000, 0, &stg);
114 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
115 ok(stg == NULL, "stg was set\n");
117 /* check what happens if the file already exists (which is how it's meant to be used) */
118 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
119 ok(r==S_OK, "StgCreateDocfile failed\n");
120 r = IStorage_Release(stg);
121 ok(r == 0, "storage not released\n");
122 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
123 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); /* FAILIFTHERE is default */
124 r = StgCreateDocfile( filename, STGM_READ, 0, &stg);
125 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); /* need at least readmode and sharemode */
126 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE, 0, &stg);
127 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
128 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE, 0, &stg);
129 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
130 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE, 0, &stg);
131 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
132 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
133 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
134 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, &stg);
135 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
136 r = StgCreateDocfile( filename, STGM_SHARE_DENY_NONE | STGM_WRITE, 0, &stg);
137 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
138 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_WRITE, 0, &stg);
139 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile failed\n");
140 r = StgCreateDocfile( filename, STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
141 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
142 r = StgCreateDocfile( filename, STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READ, 0, &stg);
143 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile wrong error\n");
144 ok(DeleteFileA(filenameA), "failed to delete file\n");
146 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
147 ok(r==S_OK, "StgCreateDocfile failed\n");
148 r = IStorage_Release(stg);
149 ok(r == 0, "storage not released\n");
150 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED |STGM_FAILIFTHERE, 0, &stg);
151 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
152 r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg);
153 ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n");
155 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg);
156 ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n");
157 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
158 ok(r==S_OK, "StgCreateDocfile failed\n");
159 r = IStorage_Release(stg);
160 ok(r == 0, "storage not released\n");
161 ok(DeleteFileA(filenameA), "failed to delete file\n");
163 r = StgCreateDocfile( filename, STGM_CREATE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
164 ok(r==S_OK, "StgCreateDocfile failed\n");
165 r = IStorage_Release(stg);
166 ok(r == 0, "storage not released\n");
167 ok(DeleteFileA(filenameA), "failed to delete file\n");
169 /* test the way excel uses StgCreateDocFile */
170 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
171 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
174 r = IStorage_Release(stg);
175 ok(r == 0, "storage not released\n");
176 ok(DeleteFileA(filenameA), "failed to delete file\n");
179 /* and the way windows media uses it ... */
180 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_NONE | STGM_READWRITE | STGM_TRANSACTED, 0, &stg);
181 ok(r==S_OK, "StgCreateDocfile the windows media way failed\n");
184 r = IStorage_Release(stg);
185 ok(r == 0, "storage not released\n");
186 ok(DeleteFileA(filenameA), "failed to delete file\n");
189 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
190 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg);
191 ok(r==S_OK, "StgCreateDocfile the excel way failed\n");
194 r = IStorage_Release(stg);
195 ok(r == 0, "storage not released\n");
196 ok(DeleteFileA(filenameA), "failed to delete file\n");
199 r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg);
200 ok(r==S_OK, "StgCreateDocfile the excel 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 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
209 ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n");
212 r = IStorage_Release(stg);
213 ok(r == 0, "storage not released\n");
214 ok(DeleteFileA(filenameA), "failed to delete file\n");
217 /* test the way msi uses StgCreateDocfile */
218 r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
219 ok(r==S_OK, "StgCreateDocFile failed\n");
220 r = IStorage_Release(stg);
221 ok(r == 0, "storage not released\n");
222 ok(DeleteFileA(filenameA), "failed to delete file\n");
225 static void test_storage_stream(void)
227 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
228 static const WCHAR longname[] = {
229 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
230 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
232 IStorage *stg = NULL;
235 IStream *stm2 = NULL;
239 unsigned char buffer[0x100];
241 DeleteFileA(filenameA);
243 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
244 ok(r==S_OK, "StgCreateDocfile failed\n");
246 /* try create some invalid streams */
247 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 1, 0, &stm );
248 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
249 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 1, &stm );
250 ok(r==STG_E_INVALIDPARAMETER, "IStorage->CreateStream wrong error\n");
251 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, NULL );
252 ok(r==STG_E_INVALIDPOINTER, "IStorage->CreateStream wrong error\n");
253 r = IStorage_CreateStream(stg, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
254 ok(r==STG_E_INVALIDNAME, "IStorage->CreateStream wrong error\n");
255 r = IStorage_CreateStream(stg, longname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
256 ok(r==STG_E_INVALIDNAME || broken(r==S_OK) /* nt4 */,
257 "IStorage->CreateStream wrong error, got %d GetLastError()=%d\n", r, GetLastError());
258 r = IStorage_CreateStream(stg, stmname, STGM_READWRITE, 0, 0, &stm );
259 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
260 r = IStorage_CreateStream(stg, stmname, STGM_READ, 0, 0, &stm );
261 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
262 r = IStorage_CreateStream(stg, stmname, STGM_WRITE, 0, 0, &stm );
263 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
264 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READWRITE, 0, 0, &stm );
265 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
266 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_DENY_NONE | STGM_READ, 0, 0, &stm );
267 ok(r==STG_E_INVALIDFLAG, "IStorage->CreateStream wrong error\n");
269 /* now really create a stream and delete it */
270 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
271 ok(r==S_OK, "IStorage->CreateStream failed\n");
272 r = IStream_Release(stm);
273 ok(r == 0, "wrong ref count\n");
274 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
275 ok(r==STG_E_FILEALREADYEXISTS, "IStorage->CreateStream failed\n");
276 r = IStorage_DestroyElement(stg,stmname);
277 ok(r==S_OK, "IStorage->DestroyElement failed\n");
279 /* create a stream and write to it */
280 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
281 ok(r==S_OK, "IStorage->CreateStream failed\n");
283 r = IStream_Clone(stm, &stm2);
284 ok(r==S_OK, "failed to clone stream\n");
286 r = IStream_Write(stm, NULL, 0, NULL );
287 ok(r==STG_E_INVALIDPOINTER, "IStream->Write wrong error\n");
288 r = IStream_Write(stm, "Hello\n", 0, NULL );
289 ok(r==S_OK, "failed to write stream\n");
290 r = IStream_Write(stm, "Hello\n", 0, &count );
291 ok(r==S_OK, "failed to write stream\n");
292 r = IStream_Write(stm, "Hello\n", 6, &count );
293 ok(r==S_OK, "failed to write stream\n");
294 r = IStream_Commit(stm, STGC_DEFAULT );
295 ok(r==S_OK, "failed to commit stream\n");
296 r = IStream_Commit(stm, STGC_DEFAULT );
297 ok(r==S_OK, "failed to commit stream\n");
299 /* seek round a bit, reset the stream size */
301 r = IStream_Seek(stm, pos, 3, &p );
302 ok(r==STG_E_INVALIDFUNCTION, "IStream->Seek returned wrong error\n");
303 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, NULL);
304 ok(r==S_OK, "failed to seek stream\n");
305 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
306 ok(r==S_OK, "failed to seek stream\n");
307 r = IStream_SetSize(stm,p);
308 ok(r==S_OK, "failed to set pos\n");
310 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
311 ok(r==S_OK, "failed to seek stream\n");
312 ok(p.QuadPart == 10, "at wrong place\n");
314 r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
315 ok(r==S_OK, "failed to seek stream\n");
316 ok(p.QuadPart == 0, "at wrong place\n");
317 r = IStream_Read(stm, buffer, sizeof buffer, &count );
318 ok(r==S_OK, "failed to set pos\n");
319 ok(count == 0, "read bytes from empty stream\n");
322 r = IStream_Release(stm2);
323 ok(r == 0, "wrong ref count\n");
325 /* create a stream and write to it */
326 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm2 );
327 ok(r==S_OK, "IStorage->CreateStream failed\n");
329 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p);
330 ok(r==STG_E_REVERTED, "overwritten stream should return STG_E_REVERTED instead of 0x%08x\n", r);
332 r = IStream_Release(stm2);
333 ok(r == 0, "wrong ref count\n");
334 r = IStream_Release(stm);
335 ok(r == 0, "wrong ref count\n");
337 r = IStorage_Release(stg);
338 ok(r == 0, "wrong ref count\n");
339 r = DeleteFileA(filenameA);
340 ok(r, "file should exist\n");
343 static BOOL touch_file(LPCSTR filename)
347 file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
348 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
349 if (file==INVALID_HANDLE_VALUE)
355 static BOOL is_zero_length(LPCSTR filename)
360 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
361 OPEN_EXISTING, 0, NULL);
362 if (file==INVALID_HANDLE_VALUE)
364 len = GetFileSize(file, NULL);
369 static BOOL is_existing_file(LPCSTR filename)
373 file = CreateFileA(filename, GENERIC_READ, 0, NULL,
374 OPEN_EXISTING, 0, NULL);
375 if (file==INVALID_HANDLE_VALUE)
381 static void test_open_storage(void)
383 static const WCHAR szNonExist[] = { 'n','o','n','e','x','i','s','t',0 };
384 IStorage *stg = NULL, *stg2 = NULL;
388 /* try opening a zero length file - it should stay zero length */
389 DeleteFileA(filenameA);
390 touch_file(filenameA);
391 stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
392 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
393 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
395 stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
396 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
397 ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
398 ok(is_zero_length(filenameA), "file length changed\n");
400 DeleteFileA(filenameA);
402 /* try opening a nonexistent file - it should not create it */
403 stgm = STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
404 r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
405 ok(r!=S_OK, "StgOpenStorage failed: 0x%08x\n", r);
406 if (r==S_OK) IStorage_Release(stg);
407 ok(!is_existing_file(filenameA), "StgOpenStorage should not create a file\n");
408 DeleteFileA(filenameA);
410 /* create the file */
411 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
412 ok(r==S_OK, "StgCreateDocfile failed\n");
413 IStorage_Release(stg);
415 r = StgOpenStorage( filename, NULL, 0, NULL, 0, &stg);
416 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage wrong error\n");
417 r = StgOpenStorage( NULL, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
418 ok(r==STG_E_INVALIDNAME, "StgOpenStorage wrong error\n");
419 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, NULL);
420 ok(r==STG_E_INVALIDPOINTER, "StgOpenStorage wrong error\n");
421 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 1, &stg);
422 ok(r==STG_E_INVALIDPARAMETER, "StgOpenStorage wrong error\n");
423 r = StgOpenStorage( szNonExist, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
424 ok(r==STG_E_FILENOTFOUND, "StgOpenStorage failed\n");
425 r = StgOpenStorage( filename, NULL, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
426 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
427 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
428 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
429 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
430 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
431 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
432 ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
434 /* open it for real */
435 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg); /* XLViewer 97/2000 */
436 ok(r==S_OK, "StgOpenStorage failed\n");
439 r = IStorage_Release(stg);
440 ok(r == 0, "wrong ref count\n");
443 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
444 ok(r==S_OK, "StgOpenStorage failed\n");
447 r = IStorage_Release(stg);
448 ok(r == 0, "wrong ref count\n");
451 /* test the way word opens its custom dictionary */
452 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
453 STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
454 ok(r==S_OK, "StgOpenStorage failed\n");
457 r = IStorage_Release(stg);
458 ok(r == 0, "wrong ref count\n");
461 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
462 ok(r==S_OK, "StgOpenStorage failed\n");
463 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
464 ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
467 r = IStorage_Release(stg);
468 ok(r == 0, "wrong ref count\n");
471 /* now try write to a storage file we opened read-only */
472 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
473 ok(r==S_OK, "StgOpenStorage failed\n");
476 static const WCHAR stmname[] = { 'w','i','n','e','t','e','s','t',0};
478 IStorage *stg2 = NULL;
480 r = IStorage_CreateStream( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE,
482 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
483 r = IStorage_CreateStorage( stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stg2);
484 ok(r == STG_E_ACCESSDENIED, "CreateStream should fail\n");
486 r = IStorage_Release(stg);
487 ok(r == 0, "wrong ref count\n");
490 /* open like visio 2003 */
492 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_NONE, NULL, 0, &stg);
493 ok(r == S_OK, "should succeed\n");
495 IStorage_Release(stg);
497 /* test other sharing modes with STGM_PRIORITY */
499 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
500 ok(r == S_OK, "should succeed\n");
502 IStorage_Release(stg);
505 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
506 ok(r == S_OK, "should succeed\n");
508 IStorage_Release(stg);
511 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_SHARE_DENY_READ, NULL, 0, &stg);
512 ok(r == S_OK, "should succeed\n");
514 IStorage_Release(stg);
516 /* open like Project 2003 */
518 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg);
519 ok(r == S_OK, "should succeed\n");
520 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stg2);
521 ok(r == S_OK, "should succeed\n");
523 IStorage_Release(stg2);
525 IStorage_Release(stg);
528 r = StgOpenStorage( filename, NULL, STGM_PRIORITY | STGM_READWRITE, NULL, 0, &stg);
529 ok(r == STG_E_INVALIDFLAG, "should fail\n");
531 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED | STGM_PRIORITY, NULL, 0, &stg);
532 ok(r == STG_E_INVALIDFLAG, "should fail\n");
534 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_PRIORITY, NULL, 0, &stg);
535 ok(r == STG_E_INVALIDFLAG, "should fail\n");
537 r = StgOpenStorage( filename, NULL, STGM_DELETEONRELEASE | STGM_PRIORITY, NULL, 0, &stg);
538 ok(r == STG_E_INVALIDFUNCTION, "should fail\n");
540 r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_PRIORITY, NULL, 0, &stg);
541 ok(r == STG_E_INVALIDFLAG, "should fail\n");
543 r = StgOpenStorage( filename, NULL, STGM_NOSNAPSHOT | STGM_PRIORITY, NULL, 0, &stg);
544 ok(r == STG_E_INVALIDFLAG, "should fail\n");
546 r = DeleteFileA(filenameA);
547 ok(r, "file didn't exist\n");
550 static void test_storage_suminfo(void)
552 IStorage *stg = NULL;
553 IPropertySetStorage *propset = NULL;
554 IPropertyStorage *ps = NULL;
557 DeleteFileA(filenameA);
559 /* create the file */
560 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
561 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
562 ok(r==S_OK, "StgCreateDocfile failed\n");
564 r = IStorage_QueryInterface( stg, &IID_IPropertySetStorage, (LPVOID) &propset );
565 ok(r == S_OK, "query interface failed\n");
568 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
569 ok(r == STG_E_FILENOTFOUND, "deleted property set storage\n");
571 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
572 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
573 ok(r == STG_E_FILENOTFOUND, "opened property set storage\n");
575 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
576 STGM_READ | STGM_SHARE_EXCLUSIVE, &ps );
577 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
579 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
581 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
583 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0, 0, &ps );
584 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
586 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
587 STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
588 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
590 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
591 STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, &ps );
592 ok(r == STG_E_INVALIDFLAG, "created property set storage\n");
594 /* now try really creating a property set */
595 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
596 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
597 ok(r == S_OK, "failed to create property set storage\n");
600 IPropertyStorage_Release(ps);
602 /* now try creating the same thing again */
603 r = IPropertySetStorage_Create( propset, &FMTID_SummaryInformation, NULL, 0,
604 STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps );
605 ok(r == S_OK, "failed to create property set storage\n");
607 IPropertyStorage_Release(ps);
609 /* should be able to open it */
610 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
611 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
612 ok(r == S_OK, "open failed\n");
614 IPropertyStorage_Release(ps);
617 r = IPropertySetStorage_Delete( propset, &FMTID_SummaryInformation );
618 ok(r == S_OK, "failed to delete property set storage\n");
620 /* try opening with an invalid FMTID */
621 r = IPropertySetStorage_Open( propset, NULL,
622 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
623 ok(r == E_INVALIDARG, "open succeeded\n");
625 IPropertyStorage_Release(ps);
628 r = IPropertySetStorage_Open( propset, &IID_IStorage,
629 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
630 ok(r == STG_E_FILENOTFOUND, "open succeeded\n");
632 IPropertyStorage_Release(ps);
635 /* try some invalid flags */
636 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
637 STGM_CREATE | STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
638 ok(r == STG_E_INVALIDFLAG, "open succeeded\n");
640 IPropertyStorage_Release(ps);
642 /* after deleting it, it should be gone */
643 r = IPropertySetStorage_Open( propset, &FMTID_SummaryInformation,
644 STGM_READWRITE|STGM_SHARE_EXCLUSIVE, &ps);
645 ok(r == STG_E_FILENOTFOUND, "open failed\n");
647 IPropertyStorage_Release(ps);
649 r = IPropertySetStorage_Release( propset );
650 ok(r == 1, "ref count wrong\n");
652 r = IStorage_Release(stg);
653 ok(r == 0, "ref count wrong\n");
655 DeleteFileA(filenameA);
658 static void test_storage_refcount(void)
660 IStorage *stg = NULL;
661 IStorage *stgprio = NULL;
664 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
670 DeleteFileA(filenameA);
672 /* create the file */
673 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
674 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
675 ok(r==S_OK, "StgCreateDocfile failed\n");
677 r = WriteClassStg( stg, &test_stg_cls );
678 ok( r == S_OK, "WriteClassStg failed\n");
680 r = IStorage_Commit( stg, STGC_DEFAULT );
681 ok( r == S_OK, "IStorage_Commit failed\n");
683 /* now create a stream */
684 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
685 ok(r==S_OK, "IStorage->CreateStream failed\n");
687 r = IStorage_Release( stg );
688 ok (r == 0, "storage not released\n");
691 r = IStream_Seek( stm, pos, 0, &upos );
692 ok (r == STG_E_REVERTED, "seek should fail\n");
694 r = IStream_Stat( stm, &stat, STATFLAG_DEFAULT );
695 ok (r == STG_E_REVERTED, "stat should fail\n");
697 r = IStream_Write( stm, "Test string", strlen("Test string"), NULL);
698 ok (r == STG_E_REVERTED, "IStream_Write should return STG_E_REVERTED instead of 0x%08x\n", r);
700 r = IStream_Read( stm, buffer, sizeof(buffer), NULL);
701 ok (r == STG_E_REVERTED, "IStream_Read should return STG_E_REVERTED instead of 0x%08x\n", r);
703 r = IStream_Release(stm);
704 ok (r == 0, "stream not released\n");
706 /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
707 * StgOpenStorage calls in transacted mode */
708 r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio);
709 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
712 /* non-transacted mode read/write fails */
713 r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg);
714 ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08x\n", r);
717 /* non-transacted mode read-only succeeds */
718 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg);
719 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
720 IStorage_Release(stg);
722 r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg);
723 ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r);
726 static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 };
727 static const WCHAR stgname2[] = { 'C','V','_','i','e','w',0 };
728 static const WCHAR stmname2[] = { 'V','a','r','2','D','a','t','a',0 };
733 r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME );
734 ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
735 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
736 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
737 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
738 ok(statstg.grfMode == (STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE),
739 "Statstg grfMode should have been 0x10022 instead of 0x%x\n", statstg.grfMode);
740 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
741 ok(IsEqualCLSID(&statstg.clsid, &test_stg_cls), "Statstg clsid is not test_stg_cls\n");
742 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
743 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
745 r = IStorage_CreateStorage( stg, stgname, STGM_SHARE_EXCLUSIVE, 0, 0, &stg2 );
746 ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r);
748 r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT );
749 ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r);
750 ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)),
751 "Statstg pwcsName should have been the name the storage was created with\n");
752 ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type);
753 ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart);
754 ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart);
755 ok(statstg.grfMode == STGM_SHARE_EXCLUSIVE,
756 "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%x\n", statstg.grfMode);
757 ok(statstg.grfLocksSupported == 0, "Statstg grfLocksSupported should have been 0 instead of %d\n", statstg.grfLocksSupported);
758 ok(IsEqualCLSID(&statstg.clsid, &CLSID_NULL), "Statstg clsid is not CLSID_NULL\n");
759 ok(statstg.grfStateBits == 0, "Statstg grfStateBits should have been 0 instead of %d\n", statstg.grfStateBits);
760 ok(statstg.reserved == 0, "Statstg reserved should have been 0 instead of %d\n", statstg.reserved);
761 CoTaskMemFree(statstg.pwcsName);
763 r = IStorage_CreateStorage( stg2, stgname2, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, 0, &stg3 );
764 ok(r == STG_E_ACCESSDENIED, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
766 r = IStorage_CreateStream( stg2, stmname2, STGM_CREATE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
767 ok(r == STG_E_ACCESSDENIED, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08x\n", r);
769 IStorage_Release(stg2);
771 r = IStorage_Release(stg);
772 ok(r == 0, "wrong ref count\n");
774 IStorage_Release(stgprio);
776 DeleteFileA(filenameA);
779 static void test_writeclassstg(void)
781 IStorage *stg = NULL;
785 DeleteFileA(filenameA);
787 /* create the file */
788 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
789 STGM_READWRITE, 0, &stg);
790 ok(r==S_OK, "StgCreateDocfile failed\n");
792 r = ReadClassStg( NULL, NULL );
793 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
795 r = ReadClassStg( stg, NULL );
796 ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
798 temp_cls.Data1 = 0xdeadbeef;
799 r = ReadClassStg( stg, &temp_cls );
800 ok(r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
802 ok(IsEqualCLSID(&temp_cls, &CLSID_NULL), "ReadClassStg returned wrong clsid\n");
804 r = WriteClassStg( NULL, NULL );
805 ok(r == E_INVALIDARG, "WriteClassStg should return E_INVALIDARG instead of 0x%08X\n", r);
807 r = WriteClassStg( stg, NULL );
808 ok(r == STG_E_INVALIDPOINTER, "WriteClassStg should return STG_E_INVALIDPOINTER instead of 0x%08X\n", r);
810 r = WriteClassStg( stg, &test_stg_cls );
811 ok( r == S_OK, "WriteClassStg failed with 0x%08X\n", r);
813 r = ReadClassStg( stg, &temp_cls );
814 ok( r == S_OK, "ReadClassStg failed with 0x%08X\n", r);
815 ok(IsEqualCLSID(&temp_cls, &test_stg_cls), "ReadClassStg returned wrong clsid\n");
817 r = IStorage_Release( stg );
818 ok (r == 0, "storage not released\n");
820 DeleteFileA(filenameA);
823 static void test_streamenum(void)
825 IStorage *stg = NULL;
828 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
830 IEnumSTATSTG *ee = NULL;
833 DeleteFileA(filenameA);
835 /* create the file */
836 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
837 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
838 ok(r==S_OK, "StgCreateDocfile failed\n");
840 r = WriteClassStg( stg, &test_stg_cls );
841 ok( r == S_OK, "WriteClassStg failed\n");
843 r = IStorage_Commit( stg, STGC_DEFAULT );
844 ok( r == S_OK, "IStorage_Commit failed\n");
846 /* now create a stream */
847 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
848 ok(r==S_OK, "IStorage->CreateStream failed\n");
850 r = IStream_Release(stm);
852 /* first enum ... should be 1 stream */
853 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
854 ok(r==S_OK, "IStorage->EnumElements failed\n");
857 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
858 ok(r==S_OK, "IEnumSTATSTG->Next failed\n");
859 ok(count == 1, "count wrong\n");
861 r = IEnumSTATSTG_Release(ee);
863 /* second enum... destroy the stream before reading */
864 r = IStorage_EnumElements(stg, 0, NULL, 0, &ee);
865 ok(r==S_OK, "IStorage->EnumElements failed\n");
867 r = IStorage_DestroyElement(stg, stmname);
868 ok(r==S_OK, "IStorage->EnumElements failed\n");
872 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
873 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
874 ok(count == 0, "count wrong\n");
877 /* reset and try again */
878 r = IEnumSTATSTG_Reset(ee);
879 ok(r==S_OK, "IEnumSTATSTG->Reset failed\n");
882 r = IEnumSTATSTG_Next(ee, 1, &stat, &count);
883 ok(r==S_FALSE, "IEnumSTATSTG->Next failed\n");
884 ok(count == 0, "count wrong\n");
886 r = IEnumSTATSTG_Release(ee);
887 ok (r == 0, "enum not released\n");
889 r = IStorage_Release( stg );
890 ok (r == 0, "storage not released\n");
892 DeleteFileA(filenameA);
895 static void test_transact(void)
897 IStorage *stg = NULL, *stg2 = NULL;
900 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
901 static const WCHAR stmname2[] = { 'F','O','O',0 };
903 DeleteFileA(filenameA);
905 /* create the file */
906 r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE |
907 STGM_READWRITE |STGM_TRANSACTED, 0, &stg);
908 ok(r==S_OK, "StgCreateDocfile failed\n");
910 /* now create a stream, but don't commit it */
911 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
912 ok(r==S_OK, "IStorage->CreateStream failed\n");
914 r = IStream_Write(stm, "this is stream 1\n", 16, NULL);
915 ok(r==S_OK, "IStream->Write failed\n");
917 r = IStream_Release(stm);
919 r = IStorage_Commit(stg, 0);
920 ok(r==S_OK, "IStorage->Commit failed\n");
922 /* now create a stream, but don't commit it */
924 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm );
925 ok(r==S_OK, "IStorage->CreateStream failed\n");
927 r = IStream_Write(stm, "this is stream 2\n", 16, NULL);
928 ok(r==S_OK, "IStream->Write failed\n");
930 r = IStream_Commit(stm, STGC_ONLYIFCURRENT | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
931 ok(r==S_OK, "IStream->Commit failed\n");
933 r = IStream_Release(stm);
935 IStorage_Release(stg);
939 r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_NONE | STGM_READ | STGM_TRANSACTED, NULL, 0, &stg);
940 ok(r==S_OK, "StgOpenStorage failed\n");
945 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_DENY_NONE|STGM_READ, 0, &stm );
946 ok(r==STG_E_INVALIDFLAG, "IStorage->OpenStream failed %08x\n", r);
948 r = IStorage_OpenStream(stg, stmname, NULL, STGM_DELETEONRELEASE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
949 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
951 r = IStorage_OpenStream(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
952 ok(r==STG_E_INVALIDFUNCTION, "IStorage->OpenStream failed %08x\n", r);
954 r = IStorage_OpenStorage(stg, stmname, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
955 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
958 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
959 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream should fail %08x\n", r);
962 r = IStream_Release(stm);
964 r = IStorage_OpenStorage(stg, stmname2, NULL, STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg2 );
965 ok(r==STG_E_FILENOTFOUND, "IStorage->OpenStream failed %08x\n", r);
967 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stm );
968 ok(r==S_OK, "IStorage->OpenStream should fail %08x\n", r);
970 r = IStream_Release(stm);
972 IStorage_Release(stg);
974 r = DeleteFileA(filenameA);
975 ok( r == TRUE, "deleted file\n");
978 static void test_ReadClassStm(void)
983 static const LARGE_INTEGER llZero;
985 hr = ReadClassStm(NULL, &clsid);
986 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
988 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
989 ok_ole_success(hr, "CreateStreamOnHGlobal");
990 hr = WriteClassStm(pStream, &test_stg_cls);
991 ok_ole_success(hr, "WriteClassStm");
993 hr = ReadClassStm(pStream, NULL);
994 ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr);
996 /* test not rewound stream */
997 hr = ReadClassStm(pStream, &clsid);
998 ok(hr == STG_E_READFAULT, "ReadClassStm should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
999 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid should have been zeroed\n");
1001 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1002 ok_ole_success(hr, "IStream_Seek");
1003 hr = ReadClassStm(pStream, &clsid);
1004 ok_ole_success(hr, "ReadClassStm");
1005 ok(IsEqualCLSID(&clsid, &test_stg_cls), "clsid should have been set to CLSID_WineTest\n");
1015 static const struct access_res create[16] =
1017 { TRUE, ERROR_SUCCESS, TRUE },
1018 { TRUE, ERROR_SUCCESS, TRUE },
1019 { TRUE, ERROR_SUCCESS, FALSE },
1020 { TRUE, ERROR_SUCCESS, FALSE },
1021 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1022 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1023 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1024 { TRUE, ERROR_SUCCESS, FALSE },
1025 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1026 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1027 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1028 { TRUE, ERROR_SUCCESS, TRUE },
1029 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1030 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1031 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1032 { TRUE, ERROR_SUCCESS, TRUE }
1035 static const struct access_res create_commit[16] =
1037 { TRUE, ERROR_SUCCESS, TRUE },
1038 { TRUE, ERROR_SUCCESS, TRUE },
1039 { TRUE, ERROR_SUCCESS, FALSE },
1040 { TRUE, ERROR_SUCCESS, FALSE },
1041 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1042 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1043 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1044 { TRUE, ERROR_SUCCESS, FALSE },
1045 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1046 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1047 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1048 { TRUE, ERROR_SUCCESS, TRUE },
1049 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1050 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1051 { FALSE, ERROR_SHARING_VIOLATION, FALSE },
1052 { TRUE, ERROR_SUCCESS, TRUE }
1055 static const struct access_res create_close[16] =
1057 { TRUE, ERROR_SUCCESS, FALSE },
1058 { TRUE, ERROR_SUCCESS, FALSE },
1059 { TRUE, ERROR_SUCCESS, FALSE },
1060 { TRUE, ERROR_SUCCESS, FALSE },
1061 { TRUE, ERROR_SUCCESS, FALSE },
1062 { TRUE, ERROR_SUCCESS, FALSE },
1063 { TRUE, ERROR_SUCCESS, FALSE },
1064 { TRUE, ERROR_SUCCESS, FALSE },
1065 { TRUE, ERROR_SUCCESS, FALSE },
1066 { TRUE, ERROR_SUCCESS, FALSE },
1067 { TRUE, ERROR_SUCCESS, FALSE },
1068 { TRUE, ERROR_SUCCESS, FALSE },
1069 { TRUE, ERROR_SUCCESS, FALSE },
1070 { TRUE, ERROR_SUCCESS, FALSE },
1071 { TRUE, ERROR_SUCCESS, FALSE },
1072 { TRUE, ERROR_SUCCESS }
1075 static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD line)
1077 DWORD access = 0, share = 0;
1082 for (i = 0; i < 4; i++)
1084 if (i == 0) access = 0;
1085 if (i == 1) access = GENERIC_READ;
1086 if (i == 2) access = GENERIC_WRITE;
1087 if (i == 3) access = GENERIC_READ | GENERIC_WRITE;
1089 for (j = 0; j < 4; j++)
1091 if (ares[idx].ignore)
1094 if (j == 0) share = 0;
1095 if (j == 1) share = FILE_SHARE_READ;
1096 if (j == 2) share = FILE_SHARE_WRITE;
1097 if (j == 3) share = FILE_SHARE_READ | FILE_SHARE_WRITE;
1099 SetLastError(0xdeadbeef);
1100 hfile = CreateFileA(file, access, share, NULL, OPEN_EXISTING,
1101 FILE_ATTRIBUTE_NORMAL, 0);
1102 lasterr = GetLastError();
1104 ok((hfile != INVALID_HANDLE_VALUE) == ares[idx].gothandle,
1105 "(%d, handle, %d): Expected %d, got %d\n",
1106 line, idx, ares[idx].gothandle,
1107 (hfile != INVALID_HANDLE_VALUE));
1109 ok(lasterr == ares[idx].lasterr ||
1110 broken(lasterr == 0xdeadbeef) /* win9x */,
1111 "(%d, lasterr, %d): Expected %d, got %d\n",
1112 line, idx, ares[idx].lasterr, lasterr);
1120 #define test_file_access(file, ares) _test_file_access(file, ares, __LINE__)
1122 static void test_access(void)
1127 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1129 /* STGM_TRANSACTED */
1131 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1132 STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED, 0, &stg);
1133 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1135 test_file_access("winetest", create);
1137 hr = IStorage_Commit(stg, STGC_DEFAULT);
1138 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1140 test_file_access("winetest", create_commit);
1142 IStorage_Release(stg);
1144 test_file_access("winetest", create_close);
1146 DeleteFileA("winetest");
1150 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1151 STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &stg);
1152 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1154 test_file_access("winetest", create);
1156 hr = IStorage_Commit(stg, STGC_DEFAULT);
1157 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1159 test_file_access("winetest", create_commit);
1161 IStorage_Release(stg);
1163 test_file_access("winetest", create_close);
1165 DeleteFileA("winetest");
1167 /* STGM_SHARE_DENY_NONE */
1169 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1170 STGM_SHARE_DENY_NONE | STGM_TRANSACTED, 0, &stg);
1171 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1173 test_file_access("winetest", create);
1175 hr = IStorage_Commit(stg, STGC_DEFAULT);
1176 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1178 test_file_access("winetest", create_commit);
1180 IStorage_Release(stg);
1182 test_file_access("winetest", create_close);
1184 DeleteFileA("winetest");
1186 /* STGM_SHARE_DENY_READ */
1188 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1189 STGM_SHARE_DENY_READ | STGM_TRANSACTED, 0, &stg);
1190 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1192 test_file_access("winetest", create);
1194 hr = IStorage_Commit(stg, STGC_DEFAULT);
1195 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1197 test_file_access("winetest", create_commit);
1199 IStorage_Release(stg);
1201 test_file_access("winetest", create_close);
1203 DeleteFileA("winetest");
1205 /* STGM_SHARE_DENY_WRITE */
1207 hr = StgCreateDocfile(fileW, STGM_CREATE | STGM_READWRITE |
1208 STGM_SHARE_DENY_WRITE | STGM_TRANSACTED, 0, &stg);
1209 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1211 test_file_access("winetest", create);
1213 hr = IStorage_Commit(stg, STGC_DEFAULT);
1214 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1216 test_file_access("winetest", create_commit);
1218 IStorage_Release(stg);
1220 test_file_access("winetest", create_close);
1222 DeleteFileA("winetest");
1225 static void test_readonly(void)
1227 IStorage *stg, *stg2, *stg3;
1230 static const WCHAR fileW[] = {'w','i','n','e','t','e','s','t',0};
1231 static const WCHAR storageW[] = {'s','t','o','r','a','g','e',0};
1232 static const WCHAR streamW[] = {'s','t','r','e','a','m',0};
1234 hr = StgCreateDocfile( fileW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1235 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1238 hr = IStorage_CreateStorage( stg, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stg2 );
1239 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1242 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stream );
1243 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1245 IStream_Release(stream);
1246 IStorage_Release(stg2);
1248 IStorage_Release(stg);
1251 /* re-open read only */
1252 hr = StgOpenStorage( fileW, NULL, STGM_TRANSACTED | STGM_SHARE_DENY_NONE | STGM_READ, NULL, 0, &stg);
1253 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1256 hr = IStorage_OpenStorage( stg, storageW, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2 );
1257 ok(hr == S_OK, "should succeed, res=%x\n", hr);
1260 /* CreateStream on read-only storage, name exists */
1261 hr = IStorage_CreateStream( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1262 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1264 IStream_Release(stream);
1266 /* CreateStream on read-only storage, name does not exist */
1267 hr = IStorage_CreateStream( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stream );
1268 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1270 IStream_Release(stream);
1272 /* CreateStorage on read-only storage, name exists */
1273 hr = IStorage_CreateStorage( stg2, streamW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1274 ok(hr == STG_E_FILEALREADYEXISTS, "should fail, res=%x\n", hr);
1276 IStream_Release(stg3);
1278 /* CreateStorage on read-only storage, name does not exist */
1279 hr = IStorage_CreateStorage( stg2, storageW, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READ, 0, 0, &stg3 );
1280 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1282 IStream_Release(stg3);
1284 /* DestroyElement on read-only storage, name exists */
1285 hr = IStorage_DestroyElement( stg2, streamW );
1286 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1288 /* DestroyElement on read-only storage, name does not exist */
1289 hr = IStorage_DestroyElement( stg2, storageW );
1290 ok(hr == STG_E_ACCESSDENIED, "should fail, res=%x\n", hr);
1292 IStorage_Release(stg2);
1295 IStorage_Release(stg);
1298 DeleteFileA("winetest");
1301 static void test_simple(void)
1303 /* Tests for STGM_SIMPLE mode */
1308 static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 };
1309 static const WCHAR stmname2[] = { 'S','m','a','l','l',0 };
1311 ULARGE_INTEGER upos;
1315 DeleteFileA(filenameA);
1317 r = StgCreateDocfile( filename, STGM_SIMPLE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg);
1318 ok(r == S_OK, "got %08x\n", r);
1320 r = IStorage_CreateStream(stg, stmname, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1321 ok(r == STG_E_INVALIDFLAG, "got %08x\n", r);
1322 r = IStorage_CreateStream(stg, stmname, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1323 ok(r == S_OK, "got %08x\n", r);
1325 upos.QuadPart = 6000;
1326 r = IStream_SetSize(stm, upos);
1327 ok(r == S_OK, "got %08x\n", r);
1329 r = IStream_Write(stm, "foo", 3, &count);
1330 ok(r == S_OK, "got %08x\n", r);
1331 ok(count == 3, "got %d\n", count);
1334 r = IStream_Seek(stm, pos, STREAM_SEEK_CUR, &upos);
1335 ok(r == S_OK, "got %08x\n", r);
1336 ok(upos.QuadPart == 3, "got %d\n", upos.u.LowPart);
1338 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1340 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
1343 ok(stat.cbSize.QuadPart == 3, "got %d\n", stat.cbSize.u.LowPart);
1346 r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &upos);
1347 ok(r == S_OK, "got %08x\n", r);
1348 ok(upos.QuadPart == 1, "got %d\n", upos.u.LowPart);
1350 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1352 broken(r == STG_E_INVALIDFUNCTION), /* NT4 and below */
1355 ok(stat.cbSize.QuadPart == 1, "got %d\n", stat.cbSize.u.LowPart);
1357 IStream_Release(stm);
1359 r = IStorage_CreateStream(stg, stmname2, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, 0, &stm);
1360 ok(r == S_OK, "got %08x\n", r);
1362 upos.QuadPart = 100;
1363 r = IStream_SetSize(stm, upos);
1364 ok(r == S_OK, "got %08x\n", r);
1366 r = IStream_Write(stm, "foo", 3, &count);
1367 ok(r == S_OK, "got %08x\n", r);
1368 ok(count == 3, "got %d\n", count);
1370 IStream_Release(stm);
1372 IStorage_Commit(stg, STGC_DEFAULT);
1373 IStorage_Release(stg);
1375 r = StgOpenStorage( filename, NULL, STGM_SIMPLE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &stg);
1376 if (r == STG_E_INVALIDFLAG)
1378 win_skip("Flag combination is not supported on NT4 and below\n");
1379 DeleteFileA(filenameA);
1382 ok(r == S_OK, "got %08x\n", r);
1384 r = IStorage_OpenStream(stg, stmname, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1385 ok(r == S_OK, "got %08x\n", r);
1387 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1388 ok(r == S_OK, "got %08x\n", r);
1389 ok(stat.cbSize.QuadPart == 6000, "got %d\n", stat.cbSize.u.LowPart);
1391 IStream_Release(stm);
1393 r = IStorage_OpenStream(stg, stmname2, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stm);
1394 ok(r == S_OK, "got %08x\n", r);
1396 r = IStream_Stat(stm, &stat, STATFLAG_NONAME);
1397 ok(r == S_OK, "got %08x\n", r);
1398 ok(stat.cbSize.QuadPart == 4096, "got %d\n", stat.cbSize.u.LowPart);
1400 IStream_Release(stm);
1403 IStorage_Release(stg);
1405 DeleteFileA(filenameA);
1408 START_TEST(storage32)
1410 CHAR temp[MAX_PATH];
1412 GetTempPathA(MAX_PATH, temp);
1413 if(!GetTempFileNameA(temp, "stg", 0, filenameA))
1415 win_skip("Could not create temp file, %u\n", GetLastError());
1418 MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filename, MAX_PATH);
1419 DeleteFileA(filenameA);
1421 test_hglobal_storage_stat();
1422 test_create_storage_modes();
1423 test_storage_stream();
1424 test_open_storage();
1425 test_storage_suminfo();
1426 test_storage_refcount();
1429 test_ReadClassStm();
1431 test_writeclassstg();