ole32: STGM_NOSNAPSHOT implies deny write.

Vincent Povirk madewokherd at gmail.com
Fri May 9 16:01:55 CDT 2014


-------------- next part --------------
From 67db0773ab2683913127ebd7517a2bcdcf20e308 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Fri, 9 May 2014 14:51:07 -0500
Subject: [PATCH 1/2] 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 },
-- 
1.8.3.2



More information about the wine-patches mailing list