PageRenderTime 33ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/Raven.Voron/Voron/Platform/Win32/NativeMethods.cs

https://github.com/mdavis/ravendb
C# | 421 lines | 312 code | 57 blank | 52 comment | 10 complexity | 7df7d03b4c746d1f167dcbcb07fee42b MD5 | raw file
  1. // -----------------------------------------------------------------------
  2. // <copyright file="NativeFileMethods.cs" company="Hibernating Rhinos LTD">
  3. // Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. using System;
  7. using System.ComponentModel;
  8. using System.IO;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Threading;
  12. using Microsoft.Win32.SafeHandles;
  13. using Voron.Exceptions;
  14. namespace Voron.Platform.Win32
  15. {
  16. public static unsafe class Win32NativeFileMethods
  17. {
  18. [DllImport("kernel32.dll", SetLastError = true)]
  19. public static extern bool WriteFile(SafeFileHandle hFile, byte* lpBuffer, int nNumberOfBytesToWrite,
  20. out int lpNumberOfBytesWritten, NativeOverlapped* lpOverlapped);
  21. [DllImport(@"kernel32.dll", SetLastError = true)]
  22. public static extern bool ReadFile(
  23. SafeFileHandle hFile,
  24. byte* pBuffer,
  25. int numBytesToRead,
  26. out int pNumberOfBytesRead,
  27. NativeOverlapped* lpOverlapped
  28. );
  29. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  30. public static extern SafeFileHandle CreateFile(string lpFileName,
  31. Win32NativeFileAccess dwDesiredAccess, Win32NativeFileShare dwShareMode,
  32. IntPtr lpSecurityAttributes,
  33. Win32NativeFileCreationDisposition dwCreationDisposition,
  34. Win32NativeFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile);
  35. [DllImport("kernel32.dll", SetLastError = true)]
  36. public static extern bool CloseHandle(IntPtr hObject);
  37. [DllImport("kernel32.dll", SetLastError = true)]
  38. private static extern bool SetEndOfFile(SafeFileHandle hFile);
  39. [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  40. private static extern int SetFilePointer([In] SafeFileHandle hFile, [In] int lDistanceToMove,
  41. [Out] out int lpDistanceToMoveHigh, [In] Win32NativeFileMoveMethod dwMoveMethod);
  42. [DllImport("kernel32.dll")]
  43. public static extern bool FlushFileBuffers(SafeFileHandle hFile);
  44. [DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
  45. public static extern int GetFinalPathNameByHandle(SafeFileHandle handle, [In, Out] StringBuilder path, int bufLen, int flags);
  46. public static void SetFileLength(SafeFileHandle fileHandle, long length)
  47. {
  48. var lo = (int)(length & 0xffffffff);
  49. var hi = (int)(length >> 32);
  50. int lastError;
  51. if (SetFilePointer(fileHandle, lo, out hi, Win32NativeFileMoveMethod.Begin) == -1)
  52. {
  53. lastError = Marshal.GetLastWin32Error();
  54. if (lastError != 0)
  55. throw new Win32Exception(lastError);
  56. }
  57. if (SetEndOfFile(fileHandle) == false)
  58. {
  59. lastError = Marshal.GetLastWin32Error();
  60. if (lastError == (int) Win32NativeFileErrors.DiskFull)
  61. {
  62. var filePath = new StringBuilder(256);
  63. while (GetFinalPathNameByHandle(fileHandle, filePath, filePath.Capacity, 0) > filePath.Capacity &&
  64. filePath.Capacity < 32767) // max unicode path length
  65. {
  66. filePath.EnsureCapacity(filePath.Capacity*2);
  67. }
  68. filePath = filePath.Replace(@"\\?\", string.Empty); // remove extended-length path prefix
  69. var fullFilePath = filePath.ToString();
  70. var driveLetter = Path.GetPathRoot(fullFilePath);
  71. var driveInfo = new DriveInfo(driveLetter);
  72. throw new DiskFullException(driveInfo, fullFilePath, length);
  73. }
  74. throw new Win32Exception(lastError);
  75. }
  76. }
  77. }
  78. public enum Win32NativeFileErrors
  79. {
  80. DiskFull = 0x70
  81. }
  82. public enum Win32NativeFileMoveMethod : uint
  83. {
  84. Begin = 0,
  85. Current = 1,
  86. End = 2
  87. }
  88. [Flags]
  89. public enum Win32NativeFileAccess : uint
  90. {
  91. //
  92. // Standard Section
  93. //
  94. AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type
  95. MaximumAllowed = 0x2000000, // MaximumAllowed access type
  96. Delete = 0x10000,
  97. ReadControl = 0x20000,
  98. WriteDAC = 0x40000,
  99. WriteOwner = 0x80000,
  100. Synchronize = 0x100000,
  101. StandardRightsRequired = 0xF0000,
  102. StandardRightsRead = ReadControl,
  103. StandardRightsWrite = ReadControl,
  104. StandardRightsExecute = ReadControl,
  105. StandardRightsAll = 0x1F0000,
  106. SpecificRightsAll = 0xFFFF,
  107. FILE_READ_DATA = 0x0001, // file & pipe
  108. FILE_LIST_DIRECTORY = 0x0001, // directory
  109. FILE_WRITE_DATA = 0x0002, // file & pipe
  110. FILE_ADD_FILE = 0x0002, // directory
  111. FILE_APPEND_DATA = 0x0004, // file
  112. FILE_ADD_SUBDIRECTORY = 0x0004, // directory
  113. FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
  114. FILE_READ_EA = 0x0008, // file & directory
  115. FILE_WRITE_EA = 0x0010, // file & directory
  116. FILE_EXECUTE = 0x0020, // file
  117. FILE_TRAVERSE = 0x0020, // directory
  118. FILE_DELETE_CHILD = 0x0040, // directory
  119. FILE_READ_ATTRIBUTES = 0x0080, // all
  120. FILE_WRITE_ATTRIBUTES = 0x0100, // all
  121. //
  122. // Generic Section
  123. //
  124. GenericRead = 0x80000000,
  125. GenericWrite = 0x40000000,
  126. GenericExecute = 0x20000000,
  127. GenericAll = 0x10000000,
  128. SPECIFIC_RIGHTS_ALL = 0x00FFFF,
  129. FILE_ALL_ACCESS =
  130. StandardRightsRequired |
  131. Synchronize |
  132. 0x1FF,
  133. FILE_GENERIC_READ =
  134. StandardRightsRead |
  135. FILE_READ_DATA |
  136. FILE_READ_ATTRIBUTES |
  137. FILE_READ_EA |
  138. Synchronize,
  139. FILE_GENERIC_WRITE =
  140. StandardRightsWrite |
  141. FILE_WRITE_DATA |
  142. FILE_WRITE_ATTRIBUTES |
  143. FILE_WRITE_EA |
  144. FILE_APPEND_DATA |
  145. Synchronize,
  146. FILE_GENERIC_EXECUTE =
  147. StandardRightsExecute |
  148. FILE_READ_ATTRIBUTES |
  149. FILE_EXECUTE |
  150. Synchronize
  151. }
  152. [Flags]
  153. public enum Win32NativeFileShare : uint
  154. {
  155. /// <summary>
  156. ///
  157. /// </summary>
  158. None = 0x00000000,
  159. /// <summary>
  160. /// Enables subsequent open operations on an object to request read access.
  161. /// Otherwise, other processes cannot open the object if they request read access.
  162. /// If this flag is not specified, but the object has been opened for read access, the function fails.
  163. /// </summary>
  164. Read = 0x00000001,
  165. /// <summary>
  166. /// Enables subsequent open operations on an object to request write access.
  167. /// Otherwise, other processes cannot open the object if they request write access.
  168. /// If this flag is not specified, but the object has been opened for write access, the function fails.
  169. /// </summary>
  170. Write = 0x00000002,
  171. /// <summary>
  172. /// Enables subsequent open operations on an object to request delete access.
  173. /// Otherwise, other processes cannot open the object if they request delete access.
  174. /// If this flag is not specified, but the object has been opened for delete access, the function fails.
  175. /// </summary>
  176. Delete = 0x00000004
  177. }
  178. public enum Win32NativeFileCreationDisposition : uint
  179. {
  180. /// <summary>
  181. /// Creates a new file. The function fails if a specified file exists.
  182. /// </summary>
  183. New = 1,
  184. /// <summary>
  185. /// Creates a new file, always.
  186. /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
  187. /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
  188. /// </summary>
  189. CreateAlways = 2,
  190. /// <summary>
  191. /// Opens a file. The function fails if the file does not exist.
  192. /// </summary>
  193. OpenExisting = 3,
  194. /// <summary>
  195. /// Opens a file, always.
  196. /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
  197. /// </summary>
  198. OpenAlways = 4,
  199. /// <summary>
  200. /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
  201. /// The calling process must open the file with the GENERIC_WRITE access right.
  202. /// </summary>
  203. TruncateExisting = 5
  204. }
  205. [Flags]
  206. public enum Win32NativeFileAttributes : uint
  207. {
  208. Readonly = 0x00000001,
  209. Hidden = 0x00000002,
  210. System = 0x00000004,
  211. Directory = 0x00000010,
  212. Archive = 0x00000020,
  213. Device = 0x00000040,
  214. Normal = 0x00000080,
  215. Temporary = 0x00000100,
  216. SparseFile = 0x00000200,
  217. ReparsePoint = 0x00000400,
  218. Compressed = 0x00000800,
  219. Offline = 0x00001000,
  220. NotContentIndexed = 0x00002000,
  221. Encrypted = 0x00004000,
  222. Write_Through = 0x80000000,
  223. Overlapped = 0x40000000,
  224. NoBuffering = 0x20000000,
  225. RandomAccess = 0x10000000,
  226. SequentialScan = 0x08000000,
  227. DeleteOnClose = 0x04000000,
  228. BackupSemantics = 0x02000000,
  229. PosixSemantics = 0x01000000,
  230. OpenReparsePoint = 0x00200000,
  231. OpenNoRecall = 0x00100000,
  232. FirstPipeInstance = 0x00080000
  233. }
  234. public static unsafe class Win32MemoryMapNativeMethods
  235. {
  236. public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
  237. [Flags]
  238. public enum FileMapProtection : uint
  239. {
  240. PageReadonly = 0x02,
  241. PageReadWrite = 0x04,
  242. PageWriteCopy = 0x08,
  243. PageExecuteRead = 0x20,
  244. PageExecuteReadWrite = 0x40,
  245. SectionCommit = 0x8000000,
  246. SectionImage = 0x1000000,
  247. SectionNoCache = 0x10000000,
  248. SectionReserve = 0x4000000,
  249. }
  250. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  251. public static extern IntPtr CreateFileMapping(
  252. IntPtr hFile,
  253. IntPtr lpFileMappingAttributes,
  254. FileMapProtection flProtect,
  255. uint dwMaximumSizeHigh,
  256. uint dwMaximumSizeLow,
  257. [MarshalAs(UnmanagedType.LPStr)] string lpName);
  258. // ReSharper disable UnusedMember.Local
  259. [Flags]
  260. public enum NativeFileMapAccessType : uint
  261. {
  262. Copy = 0x01,
  263. Write = 0x02,
  264. Read = 0x04,
  265. AllAccess = 0x08,
  266. Execute = 0x20,
  267. }
  268. // ReSharper restore UnusedMember.Local
  269. [DllImport("kernel32.dll", SetLastError = true)]
  270. public static extern bool UnmapViewOfFile(byte* lpBaseAddress);
  271. [DllImport("kernel32.dll", SetLastError = true)]
  272. public static extern byte* MapViewOfFileEx(IntPtr hFileMappingObject,
  273. NativeFileMapAccessType dwDesiredAccess,
  274. uint dwFileOffsetHigh,
  275. uint dwFileOffsetLow,
  276. UIntPtr dwNumberOfBytesToMap,
  277. byte* lpBaseAddress);
  278. [DllImport("kernel32.dll", SetLastError = true)]
  279. [return: MarshalAs(UnmanagedType.Bool)]
  280. public static extern bool FlushFileBuffers(SafeFileHandle hFile);
  281. [DllImport("kernel32.dll")]
  282. public static extern bool FlushViewOfFile(byte* lpBaseAddress, IntPtr dwNumberOfBytesToFlush);
  283. }
  284. public static unsafe class Win32NativeMethods
  285. {
  286. [StructLayout(LayoutKind.Sequential)]
  287. public struct SYSTEM_INFO
  288. {
  289. public ushort processorArchitecture;
  290. // ReSharper disable once FieldCanBeMadeReadOnly.Local
  291. ushort reserved;
  292. public uint pageSize;
  293. public IntPtr minimumApplicationAddress;
  294. public IntPtr maximumApplicationAddress;
  295. public IntPtr activeProcessorMask;
  296. public uint numberOfProcessors;
  297. public uint processorType;
  298. public uint allocationGranularity;
  299. public ushort processorLevel;
  300. public ushort processorRevision;
  301. }
  302. [StructLayout(LayoutKind.Sequential)]
  303. public struct MEMORY_BASIC_INFORMATION
  304. {
  305. public UIntPtr BaseAddress;
  306. public UIntPtr AllocationBase;
  307. public uint AllocationProtect;
  308. public IntPtr RegionSize;
  309. public uint State;
  310. public uint Protect;
  311. public uint Type;
  312. }
  313. [DllImport("kernel32.dll", SetLastError = true)]
  314. public static extern byte* VirtualAlloc(byte* lpAddress, UIntPtr dwSize,
  315. AllocationType flAllocationType, MemoryProtection flProtect);
  316. [DllImport("kernel32.dll", SetLastError = true)]
  317. public static extern bool VirtualFree(byte* lpAddress, UIntPtr dwSize,
  318. FreeType dwFreeType);
  319. [DllImport("kernel32.dll")]
  320. public static extern int VirtualQuery(
  321. byte* lpAddress,
  322. MEMORY_BASIC_INFORMATION* lpBuffer,
  323. IntPtr dwLength
  324. );
  325. [Flags]
  326. public enum FreeType : uint
  327. {
  328. MEM_DECOMMIT = 0x4000,
  329. MEM_RELEASE = 0x8000
  330. }
  331. [Flags]
  332. public enum AllocationType : uint
  333. {
  334. COMMIT = 0x1000,
  335. RESERVE = 0x2000,
  336. RESET = 0x80000,
  337. LARGE_PAGES = 0x20000000,
  338. PHYSICAL = 0x400000,
  339. TOP_DOWN = 0x100000,
  340. WRITE_WATCH = 0x200000
  341. }
  342. [Flags]
  343. public enum MemoryProtection : uint
  344. {
  345. EXECUTE = 0x10,
  346. EXECUTE_READ = 0x20,
  347. EXECUTE_READWRITE = 0x40,
  348. EXECUTE_WRITECOPY = 0x80,
  349. NOACCESS = 0x01,
  350. READONLY = 0x02,
  351. READWRITE = 0x04,
  352. WRITECOPY = 0x08,
  353. GUARD_Modifierflag = 0x100,
  354. NOCACHE_Modifierflag = 0x200,
  355. WRITECOMBINE_Modifierflag = 0x400
  356. }
  357. // ReSharper restore InconsistentNaming
  358. [DllImport("kernel32.dll")]
  359. public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
  360. [DllImport("kernel32.dll", SetLastError = true)]
  361. [return: MarshalAs(UnmanagedType.Bool)]
  362. public static extern bool CloseHandle(IntPtr hObject);
  363. }
  364. }