From 6f2f76c41008ecff2cf5a1ae25be3f4cf9f4f5d0 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2005 11:44:59 +0000 Subject: [PATCH] Shared reading of storage files requires STGM_TRANSACTED. --- dlls/ole32/storage32.c | 50 ++++++++++++++++++------------------ dlls/ole32/tests/storage32.c | 23 ++++++++++++++--- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index c9b8596e0e3..f0d6b3f4c51 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -5426,7 +5426,7 @@ HRESULT WINAPI StgCreateDocfile( { StorageImpl* newStorage = 0; HANDLE hFile = INVALID_HANDLE_VALUE; - HRESULT hr = S_OK; + HRESULT hr = STG_E_INVALIDFLAG; DWORD shareMode; DWORD accessMode; DWORD creationMode; @@ -5449,7 +5449,7 @@ HRESULT WINAPI StgCreateDocfile( * Validate the STGM flags */ if ( FAILED( validateSTGM(grfMode) )) - return STG_E_INVALIDFLAG; + goto end; /* StgCreateDocFile always opens for write */ switch(STGM_ACCESS_MODE(grfMode)) @@ -5458,7 +5458,7 @@ HRESULT WINAPI StgCreateDocfile( case STGM_READWRITE: break; default: - return STG_E_INVALIDFLAG; + goto end; } /* can't share write */ @@ -5468,22 +5468,13 @@ HRESULT WINAPI StgCreateDocfile( case STGM_SHARE_DENY_WRITE: break; default: - return STG_E_INVALIDFLAG; + goto end; } - /* need to create in transacted mode */ - if( STGM_CREATE_MODE(grfMode) == STGM_CREATE && - !(grfMode&STGM_TRANSACTED) ) - return STG_E_INVALIDFLAG; - - /* - * Write only access only works in create mode. - * I guess we need read access to read in the old file if there is one. - */ - if( STGM_ACCESS_MODE(grfMode) == STGM_WRITE && - STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE && - STGM_CREATE_MODE(grfMode) != STGM_CREATE ) - return STG_E_INVALIDFLAG; + /* shared reading requires transacted mode */ + if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE && + !(grfMode&STGM_TRANSACTED) ) + goto end; /* * Generate a unique name. @@ -5494,7 +5485,7 @@ HRESULT WINAPI StgCreateDocfile( static const WCHAR prefix[] = { 'S', 'T', 'O', 0 }; if (STGM_SHARE_MODE(grfMode) == STGM_SHARE_EXCLUSIVE) - return STG_E_INVALIDFLAG; + goto end; memset(tempPath, 0, sizeof(tempPath)); memset(tempFileName, 0, sizeof(tempFileName)); @@ -5505,7 +5496,10 @@ HRESULT WINAPI StgCreateDocfile( if (GetTempFileNameW(tempPath, prefix, 0, tempFileName) != 0) pwcsName = tempFileName; else - return STG_E_INSUFFICIENTMEMORY; + { + hr = STG_E_INSUFFICIENTMEMORY; + goto end; + } creationMode = TRUNCATE_EXISTING; } @@ -5544,8 +5538,10 @@ HRESULT WINAPI StgCreateDocfile( if (hFile == INVALID_HANDLE_VALUE) { if(GetLastError() == ERROR_FILE_EXISTS) - return STG_E_FILEALREADYEXISTS; - return E_FAIL; + hr = STG_E_FILEALREADYEXISTS; + else + hr = E_FAIL; + goto end; } /* @@ -5554,7 +5550,10 @@ HRESULT WINAPI StgCreateDocfile( newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); if (newStorage == 0) - return STG_E_INSUFFICIENTMEMORY; + { + hr = STG_E_INSUFFICIENTMEMORY; + goto end; + } hr = StorageImpl_Construct( newStorage, @@ -5568,7 +5567,7 @@ HRESULT WINAPI StgCreateDocfile( if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, newStorage); - return hr; + goto end; } /* @@ -5578,6 +5577,8 @@ HRESULT WINAPI StgCreateDocfile( (IStorage*)newStorage, (REFIID)&IID_IStorage, (void**)ppstgOpen); +end: + TRACE("<-- %p r = %08lx\n", *ppstgOpen, hr); return hr; } @@ -6186,7 +6187,6 @@ static DWORD GetAccessModeFromSTGM(DWORD stgm) case STGM_READ: return GENERIC_READ; case STGM_WRITE: - return GENERIC_WRITE; case STGM_READWRITE: return GENERIC_READ | GENERIC_WRITE; } @@ -6884,7 +6884,7 @@ HRESULT WINAPI ReadFmtUserTypeStg (LPSTORAGE pstg, CLIPFORMAT* pcf, LPOLESTR* lp STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm ); if( FAILED ( r ) ) { - ERR("Failed to open stream\n"); + WARN("Failed to open stream r = %08lx\n", r); return r; } diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index e861e2eccc8..48dcfdefbd0 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -153,8 +153,9 @@ void test_create_storage_modes(void) ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); r = StgCreateDocfile( filename, STGM_SHARE_EXCLUSIVE | STGM_WRITE, 0, &stg); ok(r==STG_E_FILEALREADYEXISTS, "StgCreateDocfile wrong error\n"); - /*ok(DeleteFileW(filename), "failed to delete file\n"); */ + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_DENY_WRITE | STGM_READWRITE, 0, &stg); + ok(r==STG_E_INVALIDFLAG, "StgCreateDocfile succeeded\n"); r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE |STGM_TRANSACTED, 0, &stg); ok(r==S_OK, "StgCreateDocfile failed\n"); r = IStorage_Release(stg); @@ -162,7 +163,6 @@ void test_create_storage_modes(void) ok(DeleteFileW(filename), "failed to delete file\n"); - /* test the way excel uses StgCreateDocFile */ r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_READWRITE, 0, &stg); ok(r==S_OK, "StgCreateDocfile the excel way failed\n"); @@ -183,6 +183,24 @@ void test_create_storage_modes(void) ok(DeleteFileW(filename), "failed to delete file\n"); } + r = StgCreateDocfile( filename, STGM_TRANSACTED|STGM_CREATE|STGM_SHARE_DENY_WRITE|STGM_WRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile the excel way failed\n"); + if(r == S_OK) + { + r = IStorage_Release(stg); + ok(r == 0, "storage not released\n"); + ok(DeleteFileW(filename), "failed to delete file\n"); + } + + r = StgCreateDocfile( filename, STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &stg); + ok(r==S_OK, "StgCreateDocfile the powerpoint way failed\n"); + if(r == S_OK) + { + r = IStorage_Release(stg); + ok(r == 0, "storage not released\n"); + ok(DeleteFileW(filename), "failed to delete file\n"); + } + /* test the way msi uses StgCreateDocfile */ r = StgCreateDocfile( filename, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg); ok(r==S_OK, "StgCreateDocFile failed\n"); @@ -454,7 +472,6 @@ void test_storage_suminfo(void) ok(r == STG_E_FILENOTFOUND, "open failed\n"); if(r == S_OK) IPropertyStorage_Release(ps); - printf("r = %08lx\n",r); r = IPropertySetStorage_Release( propset ); ok(r == 1, "ref count wrong\n");