From 77fc6a5d8203cb73b2038bbf36a3b7c397044269 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Mar 2005 13:17:10 +0000 Subject: [PATCH] StgOpenStorage shouldn't open zero length storage files. --- dlls/ole32/storage32.c | 23 +++++++++++-- dlls/ole32/tests/storage32.c | 65 +++++++++++++++++++++++++++++++++--- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index f0d6b3f4c51..a9a032c953b 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -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; /* diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 48dcfdefbd0..88b61ce67de 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -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");