diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 18f248cbfd8..ae1fd80bca3 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -5914,7 +5914,6 @@ HRESULT WINAPI StgOpenStorage( goto end; } - /* STGM_PRIORITY implies exclusive access */ if (grfMode & STGM_PRIORITY) { if (grfMode & (STGM_TRANSACTED|STGM_SIMPLE|STGM_NOSCRATCH|STGM_NOSNAPSHOT)) @@ -5924,13 +5923,20 @@ HRESULT WINAPI StgOpenStorage( if(STGM_ACCESS_MODE(grfMode) != STGM_READ) return STG_E_INVALIDFLAG; grfMode &= ~0xf0; /* remove the existing sharing mode */ - grfMode |= STGM_SHARE_DENY_WRITE; + grfMode |= STGM_SHARE_DENY_NONE; + + /* STGM_PRIORITY stops other IStorage objects on the same file from + * committing until the STGM_PRIORITY IStorage is closed. it also + * stops non-transacted mode StgOpenStorage calls with write access from + * succeeding. obviously, both of these cannot be achieved through just + * file share flags */ + FIXME("STGM_PRIORITY mode not implemented correctly\n"); } /* * Validate the sharing mode */ - if (!(grfMode & STGM_TRANSACTED)) + if (!(grfMode & (STGM_TRANSACTED|STGM_PRIORITY))) switch(STGM_SHARE_MODE(grfMode)) { case STGM_SHARE_EXCLUSIVE: diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 19361505a12..708508969a0 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -626,6 +626,7 @@ static void test_storage_refcount(void) static const WCHAR szDot[] = { '.',0 }; WCHAR filename[MAX_PATH]; IStorage *stg = NULL; + IStorage *stgprio = NULL; HRESULT r; IStream *stm = NULL; static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; @@ -673,10 +674,24 @@ static void test_storage_refcount(void) r = IStream_Release(stm); ok (r == 0, "stream not released\n"); - /* test for grfMode open issue */ + /* tests that STGM_PRIORITY doesn't prevent readwrite access from other + * StgOpenStorage calls in transacted mode */ + r = StgOpenStorage( filename, NULL, STGM_PRIORITY, NULL, 0, &stgprio); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08lx\n", r); + + todo_wine { + /* non-transacted mode read/write fails */ + r = StgOpenStorage( filename, NULL, STGM_SHARE_EXCLUSIVE|STGM_READWRITE, NULL, 0, &stg); + ok(r==STG_E_LOCKVIOLATION, "StgOpenStorage should return STG_E_LOCKVIOLATION instead of 0x%08lx\n", r); + } + + /* non-transacted mode read-only succeeds */ + r = StgOpenStorage( filename, NULL, STGM_SHARE_DENY_WRITE|STGM_READ, NULL, 0, &stg); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08lx\n", r); + IStorage_Release(stg); r = StgOpenStorage( filename, NULL, STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_READWRITE, NULL, 0, &stg); - ok(r==S_OK, "StgOpenStorage failed\n"); + ok(r==S_OK, "StgOpenStorage failed with error 0x%08lx\n", r); if(stg) { static const WCHAR stgname[] = { ' ',' ',' ','2','9',0 }; @@ -727,6 +742,7 @@ static void test_storage_refcount(void) r = IStorage_Release(stg); ok(r == 0, "wrong ref count\n"); } + IStorage_Release(stgprio); DeleteFileW(filename); }