We have found that if processes on multiple machines attempt to open a networked structured storage file forreading they will occasionally report ‘A lock violation has occurred’ (STG_E_LOCKVIOLATION).
FYI: We use the flags according tohttp://msdn.microsoft.com/en-us/library/aa380341(v=vs.85).aspx to ensure we only deny writers on reading the file.
I have created a very simple C# test app and can reliably reproduce the error.
The API under test is simply:
private static void PerformTheTest(string filename) { NativeMethods.IStorage stgOpen; // Use interop to open the structured storage file. // According to http://msdn.microsoft.com/en-us/library/aa380341(v=vs.85).aspx: // // To support the single-writer, multireader, direct mode, the first flag combination is the valid grfMode parameter for the writer. The second flag combination is valid for readers. // STGM_DIRECT_SWMR | STGM_READWRITE | STGM_SHARE_DENY_WRITE // STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE // // In direct mode, one of the following three combinations are valid. // STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE // STGM_DIRECT | STGM_READ | STGM_SHARE_DENY_WRITE // STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE var errorCode = NativeMethods.StgOpenStorage(filename, null, NativeMethods.STGM.DIRECT | NativeMethods.STGM.SHARE_DENY_WRITE | NativeMethods.STGM.READ, IntPtr.Zero, 0, out stgOpen); if (errorCode != 0) Marshal.ThrowExceptionForHR(errorCode); // Release the storage. // NOTE: If we don't do this we run out of memory // e.g. There is insufficient memory available to complete operation. (Exception from HRESULT: 0x80030008 (STG_E_INSUFFICIENTMEMORY)) Marshal.ReleaseComObject(stgOpen); }
This has been tested in a Windows Server 2008 R2 environment and can be reproduced within minutes – often within seconds – using just three machines.
Regards
Andy