private SafeFileHandle GetOrAddHandle(int _segmentId) { return(logHandles.GetOrAdd(_segmentId, segmentId => { uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; if (unbuffered) { fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; } if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; } var logHandle = Native32.CreateFileW( GetSegmentName(segmentId), fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (enablePrivileges) { Native32.EnableVolumePrivileges(ref dirname, logHandle); } SetFileSize(logHandle, segmentSize); if (useIoCompletionPort) { ioCompletionPort = Native32.CreateIoCompletionPort( logHandle, IntPtr.Zero, (uint)logHandle.DangerousGetHandle().ToInt64(), 0); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { Console.WriteLine("Log handle! : {0}", logHandle.ToString()); Console.WriteLine(e.ToString()); Environment.Exit(0); } return logHandle; })); }
/// Sets file size to the specified value. /// Does not reset file seek pointer to original location. private bool SetFileSize(string filename, SafeFileHandle logHandle, long size) { if (segmentSize <= 0) { return(false); } if (Native32.EnableVolumePrivileges(filename, logHandle)) { return(Native32.SetFileSize(logHandle, size)); } int lodist = (int)size; int hidist = (int)(size >> 32); Native32.SetFilePointer(logHandle, lodist, ref hidist, Native32.EMoveMethod.Begin); if (!Native32.SetEndOfFile(logHandle)) { return(false); } return(true); }
public LocalStorageDevice(string filename, bool enablePrivileges = false, bool useIoCompletionPort = false, bool unbuffered = false, bool deleteOnClose = false) { this.filename = filename; this.enablePrivileges = enablePrivileges; this.useIoCompletionPort = useIoCompletionPort; if (enablePrivileges) { Native32.EnableProcessPrivileges(); } Native32.GetDiskFreeSpace(filename.Substring(0, 3), out lpSectorsPerCluster, out lpBytesPerSector, out lpNumberOfFreeClusters, out lpTotalNumberOfClusters); uint fileAccess = Native32.GENERIC_READ | Native32.GENERIC_WRITE; uint fileShare = unchecked (((uint)FileShare.ReadWrite & ~(uint)FileShare.Inheritable)); uint fileCreation = unchecked ((uint)FileMode.OpenOrCreate); uint fileFlags = Native32.FILE_FLAG_OVERLAPPED; if (unbuffered) { fileFlags = fileFlags | Native32.FILE_FLAG_NO_BUFFERING; } if (deleteOnClose) { fileFlags = fileFlags | Native32.FILE_FLAG_DELETE_ON_CLOSE; } logHandle = Native32.CreateFileW(filename, fileAccess, fileShare, IntPtr.Zero, fileCreation, fileFlags, IntPtr.Zero); if (enablePrivileges) { Native32.EnableVolumePrivileges(ref filename, logHandle); } if (useIoCompletionPort) { ioCompletionPort = Native32.CreateIoCompletionPort( logHandle, IntPtr.Zero, (uint)logHandle.DangerousGetHandle().ToInt64(), 0); } try { ThreadPool.BindHandle(logHandle); } catch (Exception e) { Console.WriteLine("Log handle! : {0}", logHandle.ToString()); Console.WriteLine(e.ToString()); Environment.Exit(0); } }