Module: wine Branch: master Commit: b3e26be0cb80daf582e8c57fb58bf6851b089e07 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b3e26be0cb80daf582e8c57fb5...
Author: Vincent Povirk vincent@codeweavers.com Date: Fri May 9 14:51:07 2014 -0500
ole32: STGM_NOSNAPSHOT implies deny write.
---
dlls/ole32/storage32.c | 10 ++++++++++ dlls/ole32/storage32.h | 9 ++++++--- dlls/ole32/tests/storage32.c | 4 ++++ 3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 56d3229..786924b 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -2908,6 +2908,13 @@ static HRESULT StorageImpl_GrabLocks(StorageImpl *This, DWORD openFlags) ULARGE_INTEGER cb; DWORD share_mode = STGM_SHARE_MODE(openFlags);
+ if (openFlags & STGM_NOSNAPSHOT) + { + /* STGM_NOSNAPSHOT implies deny write */ + if (share_mode == STGM_SHARE_DENY_READ) share_mode = STGM_SHARE_EXCLUSIVE; + else if (share_mode != STGM_SHARE_EXCLUSIVE) share_mode = STGM_SHARE_DENY_WRITE; + } + /* Wrap all other locking inside a single lock so we can check ranges safely */ offset.QuadPart = RANGELOCK_CHECKLOCKS; cb.QuadPart = 1; @@ -2954,6 +2961,9 @@ static HRESULT StorageImpl_GrabLocks(StorageImpl *This, DWORD openFlags) if (SUCCEEDED(hr) && (share_mode == STGM_SHARE_DENY_WRITE || share_mode == STGM_SHARE_EXCLUSIVE)) hr = StorageImpl_LockOne(This, RANGELOCK_DENY_WRITE_FIRST, RANGELOCK_DENY_WRITE_LAST);
+ if (SUCCEEDED(hr) && (openFlags & STGM_NOSNAPSHOT) == STGM_NOSNAPSHOT) + hr = StorageImpl_LockOne(This, RANGELOCK_NOSNAPSHOT_FIRST, RANGELOCK_NOSNAPSHOT_LAST); + offset.QuadPart = RANGELOCK_CHECKLOCKS; cb.QuadPart = 1; ILockBytes_UnlockRegion(This->lockBytes, offset, cb, LOCK_ONLYONCE); diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 0b8bcc8..c6fe8b2 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -508,7 +508,8 @@ StgStreamImpl* StgStreamImpl_Construct( * In particular, ends of ranges may be wrong.
0x0 through 0x57: Unknown. Causes read-only exclusive opens to fail. - 0x58 through 0x7f: Priority mode. + 0x58 through 0x6b: Priority mode. + 0x6c through 0x7f: No snapshot mode. 0x80: Commit lock. 0x81 through 0x91: Priority mode, again. Not sure why it uses two regions. 0x92: Lock-checking lock. Held while opening so ranges can be tested without @@ -524,7 +525,9 @@ StgStreamImpl* StgStreamImpl_Construct( #define RANGELOCK_UNK1_FIRST 0x7fffff00 #define RANGELOCK_UNK1_LAST 0x7fffff57 #define RANGELOCK_PRIORITY1_FIRST 0x7fffff58 -#define RANGELOCK_PRIORITY1_LAST 0x7fffff7f +#define RANGELOCK_PRIORITY1_LAST 0x7fffff6b +#define RANGELOCK_NOSNAPSHOT_FIRST 0x7fffff6c +#define RANGELOCK_NOSNAPSHOT_LAST 0x7fffff7f #define RANGELOCK_COMMIT 0x7fffff80 #define RANGELOCK_PRIORITY2_FIRST 0x7fffff81 #define RANGELOCK_PRIORITY2_LAST 0x7fffff91 @@ -539,7 +542,7 @@ StgStreamImpl* StgStreamImpl_Construct( #define RANGELOCK_DENY_WRITE_LAST 0x7fffffe2 #define RANGELOCK_UNK2_FIRST 0x7fffffe3 #define RANGELOCK_UNK2_LAST 0x7fffffff -#define RANGELOCK_TRANSACTION_FIRST RANGELOCK_PRIORITY1_FIRST +#define RANGELOCK_TRANSACTION_FIRST RANGELOCK_COMMIT #define RANGELOCK_TRANSACTION_LAST RANGELOCK_CHECKLOCKS #define RANGELOCK_FIRST RANGELOCK_UNK1_FIRST #define RANGELOCK_LAST RANGELOCK_UNK2_LAST diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index 5db9120..74b6def 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -3156,6 +3156,7 @@ struct lock_test static const int priority_locked_bytes[] = { 0x58, 0x81, 0x93, -1 }; static const int rwex_locked_bytes[] = { 0x93, 0xa7, 0xbb, 0xcf, -1 }; static const int rw_locked_bytes[] = { 0x93, 0xa7, -1 }; +static const int nosn_locked_bytes[] = { 0x6c, 0x93, 0xa7, 0xcf, -1 }; static const int rwdw_locked_bytes[] = { 0x93, 0xa7, 0xcf, -1 }; static const int wodw_locked_bytes[] = { 0xa7, 0xcf, -1 }; static const int tr_locked_bytes[] = { 0x93, -1 }; @@ -3164,6 +3165,7 @@ static const int roex_locked_bytes[] = { 0x93, 0xbb, 0xcf, -1 };
static const int rwex_fail_ranges[] = { 0x93,0xe3, -1 }; static const int rw_fail_ranges[] = { 0xbb,0xe3, -1 }; +static const int rwdw_fail_ranges[] = { 0xa7,0xe3, -1 }; static const int dw_fail_ranges[] = { 0xa7,0xcf, -1 }; static const int tr_fail_ranges[] = { 0xbb,0xcf, -1 }; static const int pr_fail_ranges[] = { 0x80,0x81, 0xbb,0xcf, -1 }; @@ -3179,6 +3181,8 @@ static const struct lock_test lock_tests[] = { { STGM_SHARE_EXCLUSIVE|STGM_READWRITE, FALSE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, rwex_locked_bytes, rwex_fail_ranges, FALSE }, { STGM_SHARE_EXCLUSIVE|STGM_READWRITE|STGM_TRANSACTED, FALSE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, rwex_locked_bytes, rwex_fail_ranges, FALSE }, { STGM_READWRITE|STGM_TRANSACTED, FALSE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, rw_locked_bytes, rw_fail_ranges, FALSE }, + { STGM_READWRITE|STGM_TRANSACTED|STGM_NOSNAPSHOT, FALSE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, nosn_locked_bytes, rwdw_fail_ranges, FALSE }, + { STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_DENY_WRITE, FALSE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, rwdw_locked_bytes, rwdw_fail_ranges, FALSE }, { STGM_READ|STGM_SHARE_DENY_WRITE, FALSE, GENERIC_READ, FILE_SHARE_READ, no_locked_bytes, dw_fail_ranges, TRUE }, { STGM_READ|STGM_TRANSACTED, FALSE, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, tr_locked_bytes, tr_fail_ranges, FALSE }, { STGM_READ|STGM_SHARE_EXCLUSIVE, FALSE, GENERIC_READ, FILE_SHARE_READ, roex_locked_bytes, roex_fail_ranges, TRUE },