Ask a questionAsk a question
 

QuestionAvoid or remove lock from StgOpenStorage()

  • Tuesday, November 03, 2009 8:35 AMinno1 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Greets,

    I try to open an outlook .msg file with StgOpenStorage().

    My problem is, that StgOpenStorage always locks my file. So, how can I avoid/remove the lock StgOpenStorage() adds to my file?
    (see last method of code OpenStorage())

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    
    namespace IStorageLock
    {
    	[ComImport]
    	[Guid("0000000d-0000-0000-C000-000000000046")]
    	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    	public interface IEnumSTATSTG
    	{
    		// The user needs to allocate an STATSTG array whose size is celt.
    		[PreserveSig]
    		uint Next(uint celt,
    		          [MarshalAs(UnmanagedType.LPArray), Out]
    		          System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt,
    		          out uint pceltFetched);
    
    		void Skip(uint celt);
    
    		void Reset();
    
    		[return: MarshalAs(UnmanagedType.Interface)]
    		IEnumSTATSTG Clone();
    	}
    
    	[ComImport]
    	[Guid("0000000b-0000-0000-C000-000000000046")]
    	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    	interface IStorage
    	{
    		void CreateStream(string pwcsName, uint grfMode, uint reserved1,
    		                  uint reserved2, out IStream ppstm);
    
    		void OpenStream(string pwcsName, IntPtr reserved1, uint grfMode,
    		                uint reserved2, out IStream ppstm);
    
    		void CreateStorage(string pwcsName, uint grfMode, uint reserved1,
    		                   uint reserved2, out IStorage ppstg);
    
    		void OpenStorage(string pwcsName, IStorage pstgPriority, uint grfMode,
    		                 IntPtr snbExclude, uint reserved, out IStorage ppstg);		
    
    		void CopyTo(uint ciidExclude, Guid rgiidExclude, IntPtr snbExclude,
    		            IStorage pstgDest);
    
    		void MoveElementTo(string pwcsName, IStorage pstgDest,
    		                   string pwcsNewName, uint grfFlags);
    
    		void Commit(uint grfCommitFlags);
    
    		void Revert();
    
    		void EnumElements(uint reserved1, IntPtr reserved2, uint reserved3,
    		                  out IEnumSTATSTG ppenum);
    
    		void DestroyElement(string pwcsName);
    
    		void RenameElement(string pwcsOldName, string pwcsNewName);
    
    		void SetElementTimes(string pwcsName,
    		                     System.Runtime.InteropServices.ComTypes.FILETIME pctime,
    		                     System.Runtime.InteropServices.ComTypes.FILETIME patime,
    		                     System.Runtime.InteropServices.ComTypes.FILETIME pmtime);		
    
    		void SetClass(Guid clsid);
    
    		void SetStateBits(uint grfStateBits, uint grfMask);
    
    		void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
    		          uint grfStatFlag);
    	}
    
    	class Lock
    	{
    		[Flags]
    		public enum STGM : int {
    			DIRECT           = 0x00000000,
    			TRANSACTED       = 0x00010000,
    			SIMPLE           = 0x08000000,
    			READ             = 0x00000000,
    			WRITE            = 0x00000001,
    			READWRITE        = 0x00000002,
    			SHARE_DENY_NONE  = 0x00000040,
    			SHARE_DENY_READ  = 0x00000030,
    			SHARE_DENY_WRITE = 0x00000020,
    			SHARE_EXCLUSIVE  = 0x00000010,
    			PRIORITY         = 0x00040000,
    			DELETEONRELEASE  = 0x04000000,
    			NOSCRATCH        = 0x00100000,
    			CREATE           = 0x00001000,
    			CONVERT          = 0x00020000,
    			FAILIFTHERE      = 0x00000000,
    			NOSNAPSHOT       = 0x00200000,
    			DIRECT_SWMR      = 0x00400000,
    		}
    
    		[DllImport("ole32.dll")]
    		private static extern int StgIsStorageFile([MarshalAs(UnmanagedType.LPWStr)]
    		                                           string pwcsName);
    
    		[DllImport("ole32.dll")]
    		static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)]
    		                                 string       pwcsName,
    		                                 IStorage     pstgPriority,
    		                                 STGM         grfMode,
    		                                 IntPtr       snbExclude,
    		                                 uint         reserved,
    		                                 out IStorage ppstgOpen);
    
    		public IStorage OpenStorage(string fileName)
    		{
    			if (StgIsStorageFile(fileName) != 0) {
    				return null;
    			}
    
    			IStorage storage = null;
    
    			//
    			// StgOpenStorage() locks file 'fileName'
    			//
    			// Set flags like:
    			// [http://stackoverflow.com/questions/1086814/opening-ole-compound-documents-read-only-with-stgopenstorage]
    			//
    			int stgOpenStorage = StgOpenStorage(fileName, null,
    			                                    STGM.READ            |
    			                                    STGM.SHARE_DENY_NONE |
    			                                    STGM.TRANSACTED,
    			                                    IntPtr.Zero, 0,
    			                                    out storage);
    			//
    			// Try to rename file (for testing purposes only)
    			//
    			try {
    				File.Move(fileName, fileName + @".renamed");
    			} catch (Exception ex) {		// exception: file alreay in use by another process
    				throw;
    			}
    
    			if (stgOpenStorage != 0) {
    				return null;
    			} else {
    				return storage;
    			}
    		}
    	}
    }


    Regards,

    inno
    • Edited byinno1 Tuesday, November 03, 2009 8:41 AMcode formatting
    •