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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/test.h"
33 DEFINE_GUID( test_stg_cls
, 0x88888888, 0x0425, 0x0000, 0,0,0,0,0,0,0,0);
35 static void test_hglobal_storage_stat(void)
37 ILockBytes
*ilb
= NULL
;
43 r
= CreateILockBytesOnHGlobal( NULL
, TRUE
, &ilb
);
44 ok( r
== S_OK
, "CreateILockBytesOnHGlobal failed\n");
46 mode
= STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
;/*0x1012*/
47 r
= StgCreateDocfileOnILockBytes( ilb
, mode
, 0, &stg
);
48 ok( r
== S_OK
, "CreateILockBytesOnHGlobal failed\n");
50 r
= WriteClassStg( stg
, &test_stg_cls
);
51 ok( r
== S_OK
, "WriteClassStg failed\n");
53 memset( &stat
, 0, sizeof stat
);
54 r
= IStorage_Stat( stg
, &stat
, 0 );
56 ok( stat
.pwcsName
== NULL
, "storage name not null\n");
57 ok( stat
.type
== 1, "type is wrong\n");
58 ok( stat
.grfMode
== 0x12, "grf mode is incorrect\n");
59 ok( !memcmp(&stat
.clsid
, &test_stg_cls
, sizeof test_stg_cls
), "CLSID is wrong\n");
61 refcount
= IStorage_Release( stg
);
62 ok( refcount
== 0, "IStorage refcount is wrong\n");
63 refcount
= ILockBytes_Release( ilb
);
64 ok( refcount
== 0, "ILockBytes refcount is wrong\n");
67 static void test_create_storage_modes(void)
69 static const WCHAR szPrefix
[] = { 's','t','g',0 };
70 static const WCHAR szDot
[] = { '.',0 };
71 WCHAR filename
[MAX_PATH
];
75 if(!GetTempFileNameW(szDot
, szPrefix
, 0, filename
))
78 DeleteFileW(filename
);
80 /* test with some invalid parameters */
81 r
= StgCreateDocfile( NULL
, 0, 0, &stg
);
82 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
83 r
= StgCreateDocfile( filename
, 0, 0, &stg
);
84 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
85 r
= StgCreateDocfile( filename
, STGM_CREATE
, 0, &stg
);
86 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
87 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_READWRITE
, 0, &stg
);
88 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
89 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
, 0, &stg
);
90 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
91 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, NULL
);
92 ok(r
==STG_E_INVALIDPOINTER
, "StgCreateDocfile succeeded\n");
93 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 1, &stg
);
94 ok(r
==STG_E_INVALIDPARAMETER
, "StgCreateDocfile succeeded\n");
95 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, 0, &stg
);
96 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
97 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, &stg
);
98 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
99 r
= StgCreateDocfile( filename
, STGM_PRIORITY
, 0, &stg
);
100 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
102 /* StgCreateDocfile seems to be very particular about the flags it accepts */
103 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| STGM_WRITE
, 0, &stg
);
104 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
105 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 8, 0, &stg
);
106 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
107 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x80, 0, &stg
);
108 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
109 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x800, 0, &stg
);
110 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
111 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x8000, 0, &stg
);
112 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
113 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x80000, 0, &stg
);
114 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
115 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
| 0x800000, 0, &stg
);
116 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
117 ok(stg
== NULL
, "stg was set\n");
119 /* check what happens if the file already exists */
120 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
121 ok(r
==S_OK
, "StgCreateDocfile failed\n");
122 r
= IStorage_Release(stg
);
123 ok(r
== 0, "storage not released\n");
124 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
125 ok(r
==STG_E_FILEALREADYEXISTS
, "StgCreateDocfile wrong error\n");
126 r
= StgCreateDocfile( filename
, STGM_READ
, 0, &stg
);
127 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
128 r
= StgCreateDocfile( filename
, STGM_SHARE_EXCLUSIVE
, 0, &stg
);
129 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
130 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_WRITE
, 0, &stg
);
131 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile succeeded\n");
132 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
, 0, &stg
);
133 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
134 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
| STGM_TRANSACTED
, 0, &stg
);
135 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
136 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
| STGM_READWRITE
, 0, &stg
);
137 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
138 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_NONE
| STGM_WRITE
, 0, &stg
);
139 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
140 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_WRITE
| STGM_WRITE
, 0, &stg
);
141 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile failed\n");
142 r
= StgCreateDocfile( filename
, STGM_SHARE_DENY_WRITE
| STGM_READ
, 0, &stg
);
143 ok(r
==STG_E_INVALIDFLAG
, "StgCreateDocfile wrong error\n");
144 ok(DeleteFileW(filename
), "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");
162 ok(DeleteFileW(filename
), "failed to delete file\n");
164 /* test the way excel uses StgCreateDocFile */
165 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
|STGM_CREATE
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, 0, &stg
);
166 ok(r
==S_OK
, "StgCreateDocfile the excel way failed\n");
169 r
= IStorage_Release(stg
);
170 ok(r
== 0, "storage not released\n");
171 ok(DeleteFileW(filename
), "failed to delete file\n");
174 /* looks like we need STGM_TRANSACTED or STGM_CREATE */
175 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, 0, &stg
);
176 ok(r
==S_OK
, "StgCreateDocfile the excel way failed\n");
179 r
= IStorage_Release(stg
);
180 ok(r
== 0, "storage not released\n");
181 ok(DeleteFileW(filename
), "failed to delete file\n");
184 r
= StgCreateDocfile( filename
, STGM_TRANSACTED
|STGM_CREATE
|STGM_SHARE_DENY_WRITE
|STGM_WRITE
, 0, &stg
);
185 ok(r
==S_OK
, "StgCreateDocfile the excel way failed\n");
188 r
= IStorage_Release(stg
);
189 ok(r
== 0, "storage not released\n");
190 ok(DeleteFileW(filename
), "failed to delete file\n");
193 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, &stg
);
194 ok(r
==S_OK
, "StgCreateDocfile the powerpoint way failed\n");
197 r
= IStorage_Release(stg
);
198 ok(r
== 0, "storage not released\n");
199 ok(DeleteFileW(filename
), "failed to delete file\n");
202 /* test the way msi uses StgCreateDocfile */
203 r
= StgCreateDocfile( filename
, STGM_DIRECT
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &stg
);
204 ok(r
==S_OK
, "StgCreateDocFile failed\n");
205 r
= IStorage_Release(stg
);
206 ok(r
== 0, "storage not released\n");
207 ok(DeleteFileW(filename
), "failed to delete file\n");
210 static void test_storage_stream(void)
212 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
213 static const WCHAR szPrefix
[] = { 's','t','g',0 };
214 static const WCHAR szDot
[] = { '.',0 };
215 static const WCHAR longname
[] = {
216 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',
217 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0
219 WCHAR filename
[MAX_PATH
];
220 IStorage
*stg
= NULL
;
226 unsigned char buffer
[0x100];
228 if(!GetTempFileNameW(szDot
, szPrefix
, 0, filename
))
231 DeleteFileW(filename
);
233 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
234 ok(r
==S_OK
, "StgCreateDocfile failed\n");
236 /* try create some invalid streams */
237 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 1, 0, &stm
);
238 ok(r
==STG_E_INVALIDPARAMETER
, "IStorage->CreateStream wrong error\n");
239 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 1, &stm
);
240 ok(r
==STG_E_INVALIDPARAMETER
, "IStorage->CreateStream wrong error\n");
241 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, NULL
);
242 ok(r
==STG_E_INVALIDPOINTER
, "IStorage->CreateStream wrong error\n");
243 r
= IStorage_CreateStream(stg
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
244 ok(r
==STG_E_INVALIDNAME
, "IStorage->CreateStream wrong error\n");
245 r
= IStorage_CreateStream(stg
, longname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
246 ok(r
==STG_E_INVALIDNAME
, "IStorage->CreateStream wrong error, got %ld GetLastError()=%ld\n", r
, GetLastError());
247 r
= IStorage_CreateStream(stg
, stmname
, STGM_READWRITE
, 0, 0, &stm
);
248 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
249 r
= IStorage_CreateStream(stg
, stmname
, STGM_READ
, 0, 0, &stm
);
250 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
251 r
= IStorage_CreateStream(stg
, stmname
, STGM_WRITE
, 0, 0, &stm
);
252 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
253 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_DENY_NONE
| STGM_READWRITE
, 0, 0, &stm
);
254 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
255 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_DENY_NONE
| STGM_READ
, 0, 0, &stm
);
256 ok(r
==STG_E_INVALIDFLAG
, "IStorage->CreateStream wrong error\n");
258 /* now really create a stream and delete it */
259 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
260 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
261 r
= IStream_Release(stm
);
262 ok(r
== 0, "wrong ref count\n");
263 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
264 ok(r
==STG_E_FILEALREADYEXISTS
, "IStorage->CreateStream failed\n");
265 r
= IStorage_DestroyElement(stg
,stmname
);
266 ok(r
==S_OK
, "IStorage->DestroyElement failed\n");
268 /* create a stream and write to it */
269 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
270 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
272 r
= IStream_Write(stm
, NULL
, 0, NULL
);
273 ok(r
==STG_E_INVALIDPOINTER
, "IStream->Write wrong error\n");
274 r
= IStream_Write(stm
, "Hello\n", 0, NULL
);
275 ok(r
==S_OK
, "failed to write stream\n");
276 r
= IStream_Write(stm
, "Hello\n", 0, &count
);
277 ok(r
==S_OK
, "failed to write stream\n");
278 r
= IStream_Write(stm
, "Hello\n", 6, &count
);
279 ok(r
==S_OK
, "failed to write stream\n");
280 r
= IStream_Commit(stm
, STGC_DEFAULT
);
281 ok(r
==S_OK
, "failed to commit stream\n");
282 r
= IStream_Commit(stm
, STGC_DEFAULT
);
283 ok(r
==S_OK
, "failed to commit stream\n");
285 /* seek round a bit, reset the stream size */
287 r
= IStream_Seek(stm
, pos
, 3, &p
);
288 ok(r
==STG_E_INVALIDFUNCTION
, "IStream->Seek returned wrong error\n");
289 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, NULL
);
290 ok(r
==S_OK
, "failed to seek stream\n");
291 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
292 ok(r
==S_OK
, "failed to seek stream\n");
293 r
= IStream_SetSize(stm
,p
);
294 ok(r
==S_OK
, "failed to set pos\n");
296 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_SET
, &p
);
297 ok(r
==S_OK
, "failed to seek stream\n");
298 ok(p
.QuadPart
== 10, "at wrong place\n");
300 r
= IStream_Seek(stm
, pos
, STREAM_SEEK_END
, &p
);
301 ok(r
==S_OK
, "failed to seek stream\n");
302 ok(p
.QuadPart
== 0, "at wrong place\n");
303 r
= IStream_Read(stm
, buffer
, sizeof buffer
, &count
);
304 ok(r
==S_OK
, "failed to set pos\n");
305 ok(count
== 0, "read bytes from empty stream\n");
308 r
= IStream_Release(stm
);
309 ok(r
== 0, "wrong ref count\n");
310 r
= IStorage_Release(stg
);
311 ok(r
== 0, "wrong ref count\n");
312 r
= DeleteFileW(filename
);
313 ok(r
, "file should exist\n");
316 static BOOL
touch_file(LPCWSTR filename
)
320 file
= CreateFileW(filename
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
321 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
322 if (file
==INVALID_HANDLE_VALUE
)
328 static BOOL
is_zero_length(LPCWSTR filename
)
333 file
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
,
334 OPEN_EXISTING
, 0, NULL
);
335 if (file
==INVALID_HANDLE_VALUE
)
337 len
= GetFileSize(file
, NULL
);
342 static void test_open_storage(void)
344 static const WCHAR szPrefix
[] = { 's','t','g',0 };
345 static const WCHAR szNonExist
[] = { 'n','o','n','e','x','i','s','t',0 };
346 static const WCHAR szDot
[] = { '.',0 };
347 WCHAR filename
[MAX_PATH
];
348 IStorage
*stg
= NULL
, *stg2
= NULL
;
352 if(!GetTempFileNameW(szDot
, szPrefix
, 0, filename
))
355 /* try opening a zero length file - it should stay zero length */
356 DeleteFileW(filename
);
357 touch_file(filename
);
358 stgm
= STGM_NOSCRATCH
| STGM_TRANSACTED
| STGM_SHARE_DENY_WRITE
| STGM_READWRITE
;
359 r
= StgOpenStorage( filename
, NULL
, stgm
, NULL
, 0, &stg
);
360 ok(r
==STG_E_FILEALREADYEXISTS
, "StgOpenStorage didn't fail\n");
362 stgm
= STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
;
363 r
= StgOpenStorage( filename
, NULL
, stgm
, NULL
, 0, &stg
);
364 ok(r
==STG_E_FILEALREADYEXISTS
, "StgOpenStorage didn't fail\n");
365 ok(is_zero_length(filename
), "file length changed\n");
367 DeleteFileW(filename
);
369 /* create the file */
370 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
371 ok(r
==S_OK
, "StgCreateDocfile failed\n");
372 IStorage_Release(stg
);
374 r
= StgOpenStorage( filename
, NULL
, 0, NULL
, 0, &stg
);
375 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage wrong error\n");
376 r
= StgOpenStorage( NULL
, NULL
, STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
377 ok(r
==STG_E_INVALIDNAME
, "StgOpenStorage wrong error\n");
378 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, NULL
);
379 ok(r
==STG_E_INVALIDPOINTER
, "StgOpenStorage wrong error\n");
380 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 1, &stg
);
381 ok(r
==STG_E_INVALIDPARAMETER
, "StgOpenStorage wrong error\n");
382 r
= StgOpenStorage( szNonExist
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
383 ok(r
==STG_E_FILENOTFOUND
, "StgOpenStorage failed\n");
384 r
= StgOpenStorage( filename
, NULL
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
385 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
386 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_NONE
| STGM_READ
, NULL
, 0, &stg
);
387 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
388 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_READ
| STGM_READ
, NULL
, 0, &stg
);
389 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
390 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, NULL
, 0, &stg
);
391 ok(r
==STG_E_INVALIDFLAG
, "StgOpenStorage failed\n");
393 /* open it for real */
394 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_NONE
| STGM_READ
| STGM_TRANSACTED
, NULL
, 0, &stg
); /* XLViewer 97/2000 */
395 ok(r
==S_OK
, "StgOpenStorage failed\n");
398 r
= IStorage_Release(stg
);
399 ok(r
== 0, "wrong ref count\n");
402 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_WRITE
| STGM_READ
, NULL
, 0, &stg
);
403 ok(r
==S_OK
, "StgOpenStorage failed\n");
406 r
= IStorage_Release(stg
);
407 ok(r
== 0, "wrong ref count\n");
410 /* test the way word opens its custom dictionary */
411 r
= StgOpenStorage( filename
, NULL
, STGM_NOSCRATCH
| STGM_TRANSACTED
|
412 STGM_SHARE_DENY_WRITE
| STGM_READWRITE
, NULL
, 0, &stg
);
413 ok(r
==S_OK
, "StgOpenStorage failed\n");
416 r
= IStorage_Release(stg
);
417 ok(r
== 0, "wrong ref count\n");
420 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
421 ok(r
==S_OK
, "StgOpenStorage failed\n");
422 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg2
);
423 ok(r
==STG_E_SHAREVIOLATION
, "StgOpenStorage failed\n");
426 r
= IStorage_Release(stg
);
427 ok(r
== 0, "wrong ref count\n");
430 /* now try write to a storage file we opened read-only */
431 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, NULL
, 0, &stg
);
432 ok(r
==S_OK
, "StgOpenStorage failed\n");
435 static const WCHAR stmname
[] = { 'w','i','n','e','t','e','s','t',0};
437 IStorage
*stg2
= NULL
;
439 r
= IStorage_CreateStream( stg
, stmname
, STGM_WRITE
| STGM_SHARE_EXCLUSIVE
,
441 ok(r
== STG_E_ACCESSDENIED
, "CreateStream should fail\n");
442 r
= IStorage_CreateStorage( stg
, stmname
, STGM_WRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
443 ok(r
== STG_E_ACCESSDENIED
, "CreateStream should fail\n");
445 r
= IStorage_Release(stg
);
446 ok(r
== 0, "wrong ref count\n");
449 /* open like visio 2003 */
451 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_DENY_NONE
, NULL
, 0, &stg
);
452 ok(r
== S_OK
, "should succeed\n");
454 IStorage_Release(stg
);
456 /* test other sharing modes with STGM_PRIORITY */
458 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
459 ok(r
== S_OK
, "should succeed\n");
461 IStorage_Release(stg
);
464 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
465 ok(r
== S_OK
, "should succeed\n");
467 IStorage_Release(stg
);
470 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_SHARE_DENY_READ
, NULL
, 0, &stg
);
471 ok(r
== S_OK
, "should succeed\n");
473 IStorage_Release(stg
);
475 /* open like Project 2003 */
477 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stg
);
478 ok(r
== S_OK
, "should succeed\n");
479 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stg2
);
480 ok(r
== S_OK
, "should succeed\n");
482 IStorage_Release(stg2
);
484 IStorage_Release(stg
);
487 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
| STGM_READWRITE
, NULL
, 0, &stg
);
488 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
490 r
= StgOpenStorage( filename
, NULL
, STGM_TRANSACTED
| STGM_PRIORITY
, NULL
, 0, &stg
);
491 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
493 r
= StgOpenStorage( filename
, NULL
, STGM_SIMPLE
| STGM_PRIORITY
, NULL
, 0, &stg
);
494 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
496 r
= StgOpenStorage( filename
, NULL
, STGM_DELETEONRELEASE
| STGM_PRIORITY
, NULL
, 0, &stg
);
497 ok(r
== STG_E_INVALIDFUNCTION
, "should fail\n");
499 r
= StgOpenStorage( filename
, NULL
, STGM_NOSCRATCH
| STGM_PRIORITY
, NULL
, 0, &stg
);
500 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
502 r
= StgOpenStorage( filename
, NULL
, STGM_NOSNAPSHOT
| STGM_PRIORITY
, NULL
, 0, &stg
);
503 ok(r
== STG_E_INVALIDFLAG
, "should fail\n");
505 r
= DeleteFileW(filename
);
506 ok(r
, "file didn't exist\n");
509 static void test_storage_suminfo(void)
511 static const WCHAR szDot
[] = { '.',0 };
512 static const WCHAR szPrefix
[] = { 's','t','g',0 };
513 WCHAR filename
[MAX_PATH
];
514 IStorage
*stg
= NULL
;
515 IPropertySetStorage
*propset
= NULL
;
516 IPropertyStorage
*ps
= NULL
;
519 if(!GetTempFileNameW(szDot
, szPrefix
, 0, filename
))
522 DeleteFileW(filename
);
524 /* create the file */
525 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
526 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
527 ok(r
==S_OK
, "StgCreateDocfile failed\n");
529 r
= IStorage_QueryInterface( stg
, &IID_IPropertySetStorage
, (LPVOID
) &propset
);
530 ok(r
== S_OK
, "query interface failed\n");
533 r
= IPropertySetStorage_Delete( propset
, &FMTID_SummaryInformation
);
534 ok(r
== STG_E_FILENOTFOUND
, "deleted property set storage\n");
536 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
537 STGM_READ
| STGM_SHARE_EXCLUSIVE
, &ps
);
538 ok(r
== STG_E_FILENOTFOUND
, "opened property set storage\n");
540 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
541 STGM_READ
| STGM_SHARE_EXCLUSIVE
, &ps
);
542 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
544 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
546 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
548 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0, 0, &ps
);
549 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
551 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
552 STGM_WRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
553 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
555 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
556 STGM_CREATE
|STGM_WRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
557 ok(r
== STG_E_INVALIDFLAG
, "created property set storage\n");
559 /* now try really creating a a property set */
560 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
561 STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
562 ok(r
== S_OK
, "failed to create property set storage\n");
565 IPropertyStorage_Release(ps
);
567 /* now try creating the same thing again */
568 r
= IPropertySetStorage_Create( propset
, &FMTID_SummaryInformation
, NULL
, 0,
569 STGM_CREATE
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
570 ok(r
== S_OK
, "failed to create property set storage\n");
572 IPropertyStorage_Release(ps
);
574 /* should be able to open it */
575 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
576 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
577 ok(r
== S_OK
, "open failed\n");
579 IPropertyStorage_Release(ps
);
582 r
= IPropertySetStorage_Delete( propset
, &FMTID_SummaryInformation
);
583 ok(r
== S_OK
, "failed to delete property set storage\n");
585 /* try opening with an invalid FMTID */
586 r
= IPropertySetStorage_Open( propset
, NULL
,
587 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
588 ok(r
== E_INVALIDARG
, "open succeeded\n");
590 IPropertyStorage_Release(ps
);
593 r
= IPropertySetStorage_Open( propset
, &IID_IStorage
,
594 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
595 ok(r
== STG_E_FILENOTFOUND
, "open succeeded\n");
597 IPropertyStorage_Release(ps
);
600 /* try some invalid flags */
601 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
602 STGM_CREATE
| STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
603 ok(r
== STG_E_INVALIDFLAG
, "open succeeded\n");
605 IPropertyStorage_Release(ps
);
607 /* after deleting it, it should be gone */
608 r
= IPropertySetStorage_Open( propset
, &FMTID_SummaryInformation
,
609 STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, &ps
);
610 ok(r
== STG_E_FILENOTFOUND
, "open failed\n");
612 IPropertyStorage_Release(ps
);
614 r
= IPropertySetStorage_Release( propset
);
615 ok(r
== 1, "ref count wrong\n");
617 r
= IStorage_Release(stg
);
618 ok(r
== 0, "ref count wrong\n");
620 DeleteFileW(filename
);
623 static void test_storage_refcount(void)
625 static const WCHAR szPrefix
[] = { 's','t','g',0 };
626 static const WCHAR szDot
[] = { '.',0 };
627 WCHAR filename
[MAX_PATH
];
628 IStorage
*stg
= NULL
;
629 IStorage
*stgprio
= NULL
;
632 static const WCHAR stmname
[] = { 'C','O','N','T','E','N','T','S',0 };
638 if(!GetTempFileNameW(szDot
, szPrefix
, 0, filename
))
641 DeleteFileW(filename
);
643 /* create the file */
644 r
= StgCreateDocfile( filename
, STGM_CREATE
| STGM_SHARE_EXCLUSIVE
|
645 STGM_READWRITE
|STGM_TRANSACTED
, 0, &stg
);
646 ok(r
==S_OK
, "StgCreateDocfile failed\n");
648 r
= WriteClassStg( stg
, &test_stg_cls
);
649 ok( r
== S_OK
, "WriteClassStg failed\n");
651 r
= IStorage_Commit( stg
, STGC_DEFAULT
);
652 ok( r
== S_OK
, "IStorage_Commit failed\n");
654 /* now create a stream */
655 r
= IStorage_CreateStream(stg
, stmname
, STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, 0, &stm
);
656 ok(r
==S_OK
, "IStorage->CreateStream failed\n");
658 r
= IStorage_Release( stg
);
659 ok (r
== 0, "storage not released\n");
662 r
= IStream_Seek( stm
, pos
, 0, &upos
);
663 ok (r
== STG_E_REVERTED
, "seek should fail\n");
665 r
= IStream_Stat( stm
, &stat
, STATFLAG_DEFAULT
);
666 ok (r
== STG_E_REVERTED
, "stat should fail\n");
668 r
= IStream_Write( stm
, "Test string", strlen("Test string"), NULL
);
669 ok (r
== STG_E_REVERTED
, "IStream_Write should return STG_E_REVERTED instead of 0x%08lx\n", r
);
671 r
= IStream_Read( stm
, buffer
, sizeof(buffer
), NULL
);
672 ok (r
== STG_E_REVERTED
, "IStream_Read should return STG_E_REVERTED instead of 0x%08lx\n", r
);
674 r
= IStream_Release(stm
);
675 ok (r
== 0, "stream not released\n");
677 /* tests that STGM_PRIORITY doesn't prevent readwrite access from other
678 * StgOpenStorage calls in transacted mode */
679 r
= StgOpenStorage( filename
, NULL
, STGM_PRIORITY
, NULL
, 0, &stgprio
);
680 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08lx\n", r
);
683 /* non-transacted mode read/write fails */
684 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, NULL
, 0, &stg
);
685 ok(r
==STG_E_LOCKVIOLATION
, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08lx\n", r
);
688 /* non-transacted mode read-only succeeds */
689 r
= StgOpenStorage( filename
, NULL
, STGM_SHARE_DENY_WRITE
|STGM_READ
, NULL
, 0, &stg
);
690 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08lx\n", r
);
691 IStorage_Release(stg
);
693 r
= StgOpenStorage( filename
, NULL
, STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
, NULL
, 0, &stg
);
694 ok(r
==S_OK
, "StgOpenStorage failed with error 0x%08lx\n", r
);
697 static const WCHAR stgname
[] = { ' ',' ',' ','2','9',0 };
698 static const WCHAR stgname2
[] = { 'C','V','_','i','e','w',0 };
699 static const WCHAR stmname2
[] = { 'V','a','r','2','D','a','t','a',0 };
704 r
= IStorage_Stat( stg
, &statstg
, STATFLAG_NONAME
);
705 ok(r
== S_OK
, "Stat should have succeded instead of returning 0x%08lx\n", r
);
706 ok(statstg
.type
== STGTY_STORAGE
, "Statstg type should have been STGTY_STORAGE instead of %ld\n", statstg
.type
);
707 ok(statstg
.cbSize
.LowPart
== 0, "Statstg cbSize.LowPart should have been 0 instead of %ld\n", statstg
.cbSize
.LowPart
);
708 ok(statstg
.cbSize
.HighPart
== 0, "Statstg cbSize.HighPart should have been 0 instead of %ld\n", statstg
.cbSize
.HighPart
);
709 ok(statstg
.grfMode
== (STGM_TRANSACTED
|STGM_SHARE_DENY_WRITE
|STGM_READWRITE
),
710 "Statstg grfMode should have been 0x10022 instead of 0x%lx\n", statstg
.grfMode
);
711 ok(statstg
.grfLocksSupported
== 0, "Statstg grfLocksSupported should have been 0 instead of %ld\n", statstg
.grfLocksSupported
);
712 ok(IsEqualCLSID(&statstg
.clsid
, &test_stg_cls
), "Statstg clsid is not test_stg_cls\n");
713 ok(statstg
.grfStateBits
== 0, "Statstg grfStateBits should have been 0 instead of %ld\n", statstg
.grfStateBits
);
714 ok(statstg
.reserved
== 0, "Statstg reserved should have been 0 instead of %ld\n", statstg
.reserved
);
716 r
= IStorage_CreateStorage( stg
, stgname
, STGM_SHARE_EXCLUSIVE
, 0, 0, &stg2
);
717 ok(r
== S_OK
, "CreateStorage should have succeeded instead of returning 0x%08lx\n", r
);
719 r
= IStorage_Stat( stg2
, &statstg
, STATFLAG_DEFAULT
);
720 ok(r
== S_OK
, "Stat should have succeded instead of returning 0x%08lx\n", r
);
721 ok(!lstrcmpW(statstg
.pwcsName
, stgname
),
722 "Statstg pwcsName should have been the name the storage was created with\n");
723 ok(statstg
.type
== STGTY_STORAGE
, "Statstg type should have been STGTY_STORAGE instead of %ld\n", statstg
.type
);
724 ok(statstg
.cbSize
.LowPart
== 0, "Statstg cbSize.LowPart should have been 0 instead of %ld\n", statstg
.cbSize
.LowPart
);
725 ok(statstg
.cbSize
.HighPart
== 0, "Statstg cbSize.HighPart should have been 0 instead of %ld\n", statstg
.cbSize
.HighPart
);
726 ok(statstg
.grfMode
== STGM_SHARE_EXCLUSIVE
,
727 "Statstg grfMode should have been STGM_SHARE_EXCLUSIVE instead of 0x%lx\n", statstg
.grfMode
);
728 ok(statstg
.grfLocksSupported
== 0, "Statstg grfLocksSupported should have been 0 instead of %ld\n", statstg
.grfLocksSupported
);
729 ok(IsEqualCLSID(&statstg
.clsid
, &CLSID_NULL
), "Statstg clsid is not CLSID_NULL\n");
730 ok(statstg
.grfStateBits
== 0, "Statstg grfStateBits should have been 0 instead of %ld\n", statstg
.grfStateBits
);
731 ok(statstg
.reserved
== 0, "Statstg reserved should have been 0 instead of %ld\n", statstg
.reserved
);
732 CoTaskMemFree(statstg
.pwcsName
);
734 r
= IStorage_CreateStorage( stg2
, stgname2
, STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
, 0, 0, &stg3
);
735 ok(r
== STG_E_ACCESSDENIED
, "CreateStorage should have returned STG_E_ACCESSDENIED instead of 0x%08lx\n", r
);
737 r
= IStorage_CreateStream( stg2
, stmname2
, STGM_CREATE
|STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
738 ok(r
== STG_E_ACCESSDENIED
, "CreateStream should have returned STG_E_ACCESSDENIED instead of 0x%08lx\n", r
);
740 IStorage_Release(stg2
);
742 r
= IStorage_Release(stg
);
743 ok(r
== 0, "wrong ref count\n");
745 IStorage_Release(stgprio
);
747 DeleteFileW(filename
);
750 START_TEST(storage32
)
752 test_hglobal_storage_stat();
753 test_create_storage_modes();
754 test_storage_stream();
756 test_storage_suminfo();
757 test_storage_refcount();