1. How to create partition on hdd using IOCTL_DISK_SET_DRIVE_LAYOUT on C#
  2. public static bool partitionDisk(string path)
  3. {
  4. var signature = new byte[4];
  5. System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(signature);
  6. using (SafeFileHandle handle = NativeMethods2.CreateFile(path, (NativeMethods2.FILE_SHARE_READ|NativeMethods.GENERIC_READ ) | (NativeMethods.GENERIC_WRITE | NativeMethods2.FILE_SHARE_WRITE), 0, IntPtr.Zero, NativeMethods2.OPEN_EXISTING, 0, IntPtr.Zero))
  7. {
  8. if (handle.IsInvalid) { throw new Win32Exception(); }
  9.  
  10. var newdi = new NativeMethods2.DRIVE_LAYOUT_INFORMATION_EX();
  11.  
  12. newdi.PartitionStyle = NativeMethods2.PARTITION_STYLE.PARTITION_STYLE_MBR;
  13. newdi.PartitionCount = 4;
  14. newdi.DriveLayoutInformaiton.Mbr.Signature = BitConverter.ToInt32(signature, 0);
  15.  
  16. newdi.PartitionEntry = new NativeMethods2.PARTITION_INFORMATION_EX[0x16];
  17. newdi.PartitionEntry[0] = new NativeMethods2.PARTITION_INFORMATION_EX();
  18.  
  19. newdi.PartitionEntry[0].PartitionStyle = NativeMethods2.PARTITION_STYLE.PARTITION_STYLE_MBR;
  20. newdi.PartitionEntry[0].StartingOffset = 1048576; // check by diskpart
  21. newdi.PartitionEntry[0].PartitionLength = 0xFFFFFFFFFFfffff; //int64 max
  22. newdi.PartitionEntry[0].PartitionNumber = 1;
  23. newdi.PartitionEntry[0].RewritePartition = true;
  24. newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.BootIndicator = false;
  25. newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.HiddenSectors = 0; //sector size
  26. newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.PartitionType = 0x07;// PARTITION_IFS (NTFS partition or logical drive)
  27. newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.RecognizedPartition = true;
  28.  
  29. for (int k = 2; k < newdi.PartitionCount; k++)
  30. {
  31. newdi.PartitionEntry[k] = new NativeMethods2.PARTITION_INFORMATION_EX();
  32.  
  33. newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.BootIndicator = false;
  34. newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.HiddenSectors = 0;
  35. newdi.PartitionEntry[k].PartitionLength = 0;
  36. newdi.PartitionEntry[k].PartitionNumber = k;
  37. newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.PartitionType = 0;
  38. newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.RecognizedPartition = false;
  39. newdi.PartitionEntry[k].RewritePartition = true;
  40. newdi.PartitionEntry[k].StartingOffset = 0;
  41. }
  42.  
  43. Int32 bytesOut = 0;
  44. if (NativeMethods2.DeviceIoControl(handle, NativeMethods2.IOCTL_DISK_SET_DRIVE_LAYOUT, ref newdi, Marshal.SizeOf(newdi), IntPtr.Zero, 0, ref bytesOut, IntPtr.Zero) == false) { throw new Win32Exception(); }
  45. }
  46. }
  47.  
  48. private static class NativeMethods2
  49. {
  50. public const int GENERIC_READ = -2147483648;
  51. public const int GENERIC_WRITE = 1073741824;
  52. public const int OPEN_EXISTING = 3;
  53.  
  54. public const int FILE_SHARE_READ = 0x0000000001;
  55. public const int FILE_SHARE_WRITE = 0x0000000002;
  56.  
  57. public const int IOCTL_DISK_UPDATE_PROPERTIES = 0x70140;
  58. public const int IOCTL_DISK_SET_DRIVE_LAYOUT_EX = 0x7C054;
  59.  
  60. public enum PARTITION_STYLE
  61. {
  62. PARTITION_STYLE_MBR = 0,
  63. PARTITION_STYLE_GPT = 1,
  64. PARTITION_STYLE_RAW = 2,
  65. }
  66.  
  67. [StructLayout(LayoutKind.Sequential)]
  68. public struct DRIVE_LAYOUT_INFORMATION_EX
  69. {
  70. public PARTITION_STYLE PartitionStyle;
  71. public int PartitionCount;
  72. public DRIVE_LAYOUT_INFORMATION_UNION DriveLayoutInformaiton;
  73. [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 0x16)]
  74. public PARTITION_INFORMATION_EX[] PartitionEntry;
  75. }
  76.  
  77. [StructLayout(LayoutKind.Sequential)]
  78. public struct PARTITION_INFORMATION_EX
  79. {
  80. public PARTITION_STYLE PartitionStyle;
  81. public long StartingOffset;
  82. public long PartitionLength;
  83. public int PartitionNumber;
  84. public bool RewritePartition;
  85. public PARTITION_INFORMATION_UNION DriveLayoutInformaiton;
  86. }
  87.  
  88. [StructLayout(LayoutKind.Sequential)]
  89. public struct PARTITION_INFORMATION_MBR
  90. {
  91. public byte PartitionType;
  92. public bool BootIndicator;
  93. public bool RecognizedPartition;
  94. public Int32 HiddenSectors;
  95. }
  96.  
  97. [StructLayout(LayoutKind.Sequential)]
  98. public struct PARTITION_INFORMATION_GPT
  99. {
  100. public Guid PartitionType; //GUID
  101. public Guid PartitionId; //GUID
  102. public Int64 Attributes;
  103. public char[] Name;
  104. }
  105.  
  106. [StructLayout(LayoutKind.Sequential)]
  107. public struct PARTITION_INFORMATION
  108. {
  109. public long StartingOffset;
  110. public long PartitionLength;
  111. public int HiddenSectors;
  112. public int PartitionNumber;
  113. public byte PartitionType;
  114. [MarshalAs(UnmanagedType.I1)]
  115. public bool BootIndicator;
  116. [MarshalAs(UnmanagedType.I1)]
  117. public bool RecognizedPartition;
  118. [MarshalAs(UnmanagedType.I1)]
  119. public bool RewritePartition;
  120. }
  121.  
  122. [StructLayout(LayoutKind.Explicit)]
  123. public struct DRIVE_LAYOUT_INFORMATION_UNION
  124. {
  125. [FieldOffset(0)]
  126. public DRIVE_LAYOUT_INFORMATION_MBR Mbr;
  127.  
  128. [FieldOffset(0)]
  129. public DRIVE_LAYOUT_INFORMATION_GPT Gpt;
  130. }
  131.  
  132. [StructLayout(LayoutKind.Sequential)]
  133. public struct DRIVE_LAYOUT_INFORMATION_MBR
  134. {
  135. public Int32 Signature;
  136. }
  137.  
  138. [StructLayout(LayoutKind.Sequential)]
  139. public struct DRIVE_LAYOUT_INFORMATION_GPT
  140. {
  141. public Guid DiskId;
  142. public Int64 StartingUsableOffset;
  143. public Int64 UsableLength;
  144. public ulong MaxPartitionCount;
  145. }
  146.  
  147. [StructLayout(LayoutKind.Explicit)]
  148. public struct PARTITION_INFORMATION_UNION
  149. {
  150. [FieldOffset(0)]
  151. public PARTITION_INFORMATION_MBR Mbr;
  152. [FieldOffset(0)]
  153. public PARTITION_INFORMATION_GPT Gpt;
  154. }
  155.  
  156. [DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
  157. public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
  158.  
  159. [DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
  160. [return: MarshalAsAttribute(UnmanagedType.Bool)]
  161. public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref DRIVE_LAYOUT_INFORMATION_EX lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
  162. }
  163.  
  164. private static class NativeMethods
  165. {
  166. public const int GENERIC_READ = -2147483648;
  167. public const int GENERIC_WRITE = 1073741824;
  168. public const int OPEN_EXISTING = 3;
  169.  
  170. public const int IOCTL_DISK_CREATE_DISK = 0x7C058;
  171.  
  172. public enum PARTITION_STYLE
  173. {
  174. PARTITION_STYLE_MBR = 0,
  175. PARTITION_STYLE_GPT = 1,
  176. PARTITION_STYLE_RAW = 2,
  177. }
  178.  
  179. [StructLayoutAttribute(LayoutKind.Sequential)]
  180. public struct CREATE_DISK
  181. {
  182. public PARTITION_STYLE PartitionStyle;
  183. public CREATE_DISK_UNION_MBR_GPT MbrGpt;
  184. }
  185.  
  186. [StructLayoutAttribute(LayoutKind.Explicit)]
  187. public struct CREATE_DISK_UNION_MBR_GPT
  188. {
  189. [FieldOffset(0)]
  190. public CREATE_DISK_MBR Mbr;
  191. [FieldOffset(0)]
  192. public CREATE_DISK_GPT Gpt;
  193. }
  194.  
  195. [StructLayoutAttribute(LayoutKind.Sequential)]
  196. public struct CREATE_DISK_MBR
  197. {
  198. public Int32 Signature;
  199. }
  200.  
  201. [StructLayoutAttribute(LayoutKind.Sequential)]
  202. public struct CREATE_DISK_GPT
  203. {
  204. public Guid DiskId;
  205. public Int32 MaxPartitionCount;
  206. }
  207.  
  208. [DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
  209. public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
  210.  
  211. [DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
  212. [return: MarshalAsAttribute(UnmanagedType.Bool)]
  213. public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref CREATE_DISK lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
  214. }