OLE32: StgOpenStorage shouldn't open zero length storage files
Mike McCormack
mike at codeweavers.com
Fri Mar 11 04:29:55 CST 2005
This fixes the Word 2000 "custom dictionary is not available" message
with builtin ole32.
Mike
ChangeLog:
* StgOpenStorage shouldn't open zero length storage files
-------------- next part --------------
Index: dlls/ole32/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/storage32.c,v
retrieving revision 1.75
diff -u -p -r1.75 storage32.c
--- dlls/ole32/storage32.c 9 Mar 2005 11:44:59 -0000 1.75
+++ dlls/ole32/storage32.c 11 Mar 2005 10:26:49 -0000
@@ -5677,6 +5677,15 @@ HRESULT WINAPI StgOpenStorage(
goto end;
}
+ /* shared reading requires transacted mode */
+ if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&
+ STGM_ACCESS_MODE(grfMode) == STGM_READWRITE &&
+ !(grfMode&STGM_TRANSACTED) )
+ {
+ hr = STG_E_INVALIDFLAG;
+ goto end;
+ }
+
/*
* Interpret the STGM value grfMode
*/
@@ -5728,7 +5737,17 @@ HRESULT WINAPI StgOpenStorage(
goto end;
}
+ /*
+ * Refuse to open the file if it's too small to be a structured storage file
+ * FIXME: verify the file when reading instead of here
+ */
length = GetFileSize(hFile, NULL);
+ if (length < 0x100)
+ {
+ CloseHandle(hFile);
+ hr = STG_E_FILEALREADYEXISTS;
+ goto end;
+ }
/*
* Allocate and initialize the new IStorage32object.
@@ -5749,7 +5768,7 @@ HRESULT WINAPI StgOpenStorage(
NULL,
grfMode,
TRUE,
- !length );
+ FALSE );
if (FAILED(hr))
{
@@ -6134,7 +6153,7 @@ static HRESULT validateSTGM(DWORD stgm)
/*
* STGM_NOSCRATCH requires STGM_TRANSACTED
*/
- if ( (stgm & STGM_NOSCRATCH) && (stgm & STGM_TRANSACTED) )
+ if ( (stgm & STGM_NOSCRATCH) && !(stgm & STGM_TRANSACTED) )
return E_FAIL;
/*
Index: dlls/ole32/tests/storage32.c
===================================================================
RCS file: /home/wine/wine/dlls/ole32/tests/storage32.c,v
retrieving revision 1.8
diff -u -p -r1.8 storage32.c
--- dlls/ole32/tests/storage32.c 9 Mar 2005 11:44:59 -0000 1.8
+++ dlls/ole32/tests/storage32.c 11 Mar 2005 10:26:49 -0000
@@ -315,6 +315,32 @@ void test_storage_stream(void)
ok(r == TRUE, "file should exist\n");
}
+static BOOL touch_file(LPCWSTR filename)
+{
+ HANDLE file;
+
+ file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file==INVALID_HANDLE_VALUE)
+ return FALSE;
+ CloseHandle(file);
+ return TRUE;
+}
+
+static BOOL is_zero_length(LPCWSTR filename)
+{
+ HANDLE file;
+ DWORD len;
+
+ file = CreateFileW(filename, GENERIC_READ, 0, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if (file==INVALID_HANDLE_VALUE)
+ return FALSE;
+ len = GetFileSize(file, NULL);
+ CloseHandle(file);
+ return len == 0;
+}
+
void test_open_storage(void)
{
static const WCHAR szPrefix[] = { 's','t','g',0 };
@@ -323,10 +349,23 @@ void test_open_storage(void)
WCHAR filename[MAX_PATH];
IStorage *stg = NULL, *stg2 = NULL;
HRESULT r;
+ DWORD stgm;
if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
return;
+ /* try opening a zero length file - it should stay zero length */
+ DeleteFileW(filename);
+ touch_file(filename);
+ stgm = STGM_NOSCRATCH | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE;
+ r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
+ ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
+
+ stgm = STGM_SHARE_EXCLUSIVE | STGM_READWRITE;
+ r = StgOpenStorage( filename, NULL, stgm, NULL, 0, &stg);
+ ok(r==STG_E_FILEALREADYEXISTS, "StgOpenStorage didn't fail\n");
+ ok(is_zero_length(filename), "file length changed\n");
+
DeleteFileW(filename);
/* create the file */
@@ -350,19 +389,37 @@ void test_open_storage(void)
ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_READ | STGM_READ, NULL, 0, &stg);
ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
+ r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
+ ok(r==STG_E_INVALIDFLAG, "StgOpenStorage failed\n");
/* open it for real */
r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE | STGM_READ, NULL, 0, &stg);
ok(r==S_OK, "StgOpenStorage failed\n");
- r = IStorage_Release(stg);
- ok(r == 0, "wrong ref count\n");
+ if(stg)
+ {
+ r = IStorage_Release(stg);
+ ok(r == 0, "wrong ref count\n");
+ }
+
+ /* test the way word opens its custom dictionary */
+ r = StgOpenStorage( filename, NULL, STGM_NOSCRATCH | STGM_TRANSACTED |
+ STGM_SHARE_DENY_WRITE | STGM_READWRITE, NULL, 0, &stg);
+ ok(r==S_OK, "StgOpenStorage failed\n");
+ if(stg)
+ {
+ r = IStorage_Release(stg);
+ ok(r == 0, "wrong ref count\n");
+ }
r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg);
ok(r==S_OK, "StgOpenStorage failed\n");
r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, NULL, 0, &stg2);
ok(r==STG_E_SHAREVIOLATION, "StgOpenStorage failed\n");
- r = IStorage_Release(stg);
- ok(r == 0, "wrong ref count\n");
+ if(stg)
+ {
+ r = IStorage_Release(stg);
+ ok(r == 0, "wrong ref count\n");
+ }
r = DeleteFileW(filename);
ok(r, "file didn't exist\n");
More information about the wine-patches
mailing list