StgOpenStorage shouldn't open zero length storage files.

This commit is contained in:
Mike McCormack 2005-03-11 13:17:10 +00:00 committed by Alexandre Julliard
parent 3024167cc0
commit 77fc6a5d82
2 changed files with 82 additions and 6 deletions

View File

@ -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;
/*

View File

@ -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");