public static extern Boolean DeviceIoControl( FileSafeHandle hDevice, IoControlCode dwIoControlCode, ref DRIVE_LAYOUT_INFORMATION_EX lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped );
public static void DiskSetDriveLayoutEx(SafeHandle handle, DRIVE_LAYOUT_INFORMATION_EX layout) { var bufSize = Marshal.SizeOf(layout); var buf = Marshal.AllocHGlobal(bufSize); uint bytesReturned = 0; Marshal.StructureToPtr(layout, buf, false); var b = DeviceIoControl(handle.DangerousGetHandle(), IOCTL_DISK_SET_DRIVE_LAYOUT_EX, buf, (uint)bufSize, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero); Marshal.FreeHGlobal(buf); if (!b) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } }
/// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365174(v=vs.85).aspx"/></summary> public DRIVE_LAYOUT_INFORMATION_EX DiskGetDriveLayoutEx() { DRIVE_LAYOUT_INFORMATION_EX_INTERNAL data = DeviceIoControlHelper.InvokeIoControl <DRIVE_LAYOUT_INFORMATION_EX_INTERNAL>(Handle, IOControlCode.DiskGetDriveLayoutEx); DRIVE_LAYOUT_INFORMATION_EX res = new DRIVE_LAYOUT_INFORMATION_EX(); res.PartitionStyle = data.PartitionStyle; res.PartitionCount = data.PartitionCount; res.DriveLayoutInformaiton = data.DriveLayoutInformaiton; res.PartitionEntry = new PARTITION_INFORMATION_EX[res.PartitionCount]; for (int i = 0; i < res.PartitionCount; i++) { res.PartitionEntry[i] = data.PartitionEntry[i]; } return(res); }
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);
public override string ToString() { StringBuilder details = new StringBuilder(); if (dge.HasValue) { DISK_GEOMETRY_EX dge1 = dge.Value; details.Append('\t').AppendLine("DISK_GEOMETRY:"); details.Append("\t\t").Append("Cylinders: ").AppendLine(dge1.Geometry.Cylinders.ToString()); //public MEDIA_TYPE MediaType; details.Append("\t\t").Append("TracksPerCylinder: ") .AppendLine(dge1.Geometry.TracksPerCylinder.ToString()); details.Append("\t\t").Append("SectorsPerTrack: ") .AppendLine(dge1.Geometry.SectorsPerTrack.ToString()); details.Append("\t\t").Append("BytesPerSector: ") .AppendLine(dge1.Geometry.BytesPerSector.ToString()); details.Append("\t\t").Append("DiskSize: ").AppendLine(dge1.Geometry.DiskSize.ToString()); details.Append('\t').AppendLine("DISK_PARTITION_INFO:"); //details.Append("\t\t").Append("SizeOfPartitionInfo: ").AppendLine(dge.PartitionInformation.SizeOfPartitionInfo.ToString()); details.Append("\t\t").Append("PartitionStyle: ") .AppendLine(dge1.PartitionInformation.PartitionStyle.ToString()); switch (dge1.PartitionInformation.PartitionStyle) { case PartitionStyle.PARTITION_STYLE_MBR: details.Append("\t\t").Append("MbrSignature: ") .AppendLine(dge1.PartitionInformation.MbrSignature.ToString()); break; case PartitionStyle.PARTITION_STYLE_GPT: details.Append("\t\t").Append("GptGuidId: ") .AppendLine(dge1.PartitionInformation.GptGuidId.ToString()); break; case PartitionStyle.PARTITION_STYLE_RAW: break; default: throw new ArgumentOutOfRangeException(); } details.Append('\t').AppendLine("DISK_EX_INT13_INFO:"); details.Append("\t\t").Append("ExBufferSize: ") .AppendLine(dge1.DiskInt13Info.ExBufferSize.ToString()); details.Append("\t\t").Append("ExFlags: ").AppendLine(dge1.DiskInt13Info.ExFlags.ToString()); details.Append("\t\t").Append("ExCylinders: ") .AppendLine(dge1.DiskInt13Info.ExCylinders.ToString()); //public uint ExHeads; //public uint ExSectorsPerTrack; //public ulong ExSectorsPerDrive; //public ushort ExSectorSize; //public ushort ExReserved; } if (pie.HasValue) { PARTITION_INFORMATION_EX pie1 = pie.Value; details.Append('\t').AppendLine("PARTITION_INFORMATION_EX:"); details.Append("\t\t").Append("PartitionStyle: ").AppendLine(pie1.PartitionStyle.ToString()); details.Append("\t\t").Append("StartingOffset: ").AppendLine(pie1.StartingOffset.ToString()); details.Append("\t\t").Append("PartitionLength: ").AppendLine(pie1.PartitionLength.ToString()); details.Append("\t\t").Append("PartitionNumber: ").AppendLine(pie1.PartitionNumber.ToString()); details.Append("\t\t").Append("RewritePartition: ").AppendLine(pie1.RewritePartition.ToString()); switch (pie1.PartitionStyle) { case PartitionStyle.PARTITION_STYLE_MBR: details.Append("\t\t").AppendLine("PARTITION_INFORMATION_MBR: "); details.Append("\t\t\t").Append("PartitionType: ") .AppendLine(pie1.DriveLayoutInformaiton.Mbr.PartitionType.ToString()); details.Append("\t\t\t").Append("BootIndicator: ") .AppendLine(pie1.DriveLayoutInformaiton.Mbr.BootIndicator.ToString()); details.Append("\t\t\t").Append("RecognizedPartition: ") .AppendLine(pie1.DriveLayoutInformaiton.Mbr.RecognizedPartition.ToString()); details.Append("\t\t\t").Append("HiddenSectors: ") .AppendLine(pie1.DriveLayoutInformaiton.Mbr.HiddenSectors.ToString()); break; case PartitionStyle.PARTITION_STYLE_GPT: details.Append("\t\t").AppendLine("PARTITION_INFORMATION_GPT: "); details.Append("\t\t\t").Append("PartitionType: ") .AppendLine(pie1.DriveLayoutInformaiton.Gpt.PartitionType.ToString()); details.Append("\t\t\t").Append("PartitionId: ") .AppendLine(pie1.DriveLayoutInformaiton.Gpt.PartitionId.ToString()); details.Append("\t\t\t").Append("EFIPartitionAttributes: ") .AppendLine(pie1.DriveLayoutInformaiton.Gpt.Attributes.ToString()); details.Append("\t\t\t").Append("Name: ") .AppendLine(pie1.DriveLayoutInformaiton.Gpt.Name.ToString()); break; case PartitionStyle.PARTITION_STYLE_RAW: break; default: throw new ArgumentOutOfRangeException(); } } if (dlie.HasValue) { DRIVE_LAYOUT_INFORMATION_EX dlie1 = dlie.Value; details.Append('\t').AppendLine("DRIVE_LAYOUT_INFORMATION_EX:"); details.Append("\t\t").Append("PartitionStyle: ").AppendLine(dlie1.PartitionStyle.ToString()); details.Append("\t\t").Append("PartitionCount: ").AppendLine((dlie1.PartitionCount - 1).ToString()); // Last one is nulls switch (dlie1.PartitionStyle) { case PartitionStyle.PARTITION_STYLE_MBR: details.Append("\t\t").AppendLine("DRIVE_LAYOUT_INFORMATION_MBR: "); details.Append("\t\t\t").Append("Signature: ") .AppendLine(dlie1.DriveLayoutInformaiton.Mbr.Signature.ToString()); break; case PartitionStyle.PARTITION_STYLE_GPT: details.Append("\t\t").AppendLine("DRIVE_LAYOUT_INFORMATION_GPT: "); details.Append("\t\t\t").Append("DiskId: ") .AppendLine(dlie1.DriveLayoutInformaiton.Gpt.DiskId.ToString()); details.Append("\t\t\t").Append("StartingUsableOffset: ") .AppendLine(dlie1.DriveLayoutInformaiton.Gpt.StartingUsableOffset.ToString()); details.Append("\t\t\t").Append("UsableLength: ") .AppendLine(dlie1.DriveLayoutInformaiton.Gpt.UsableLength.ToString()); details.Append("\t\t\t").Append("MaxPartitionCount: ") .AppendLine(dlie1.DriveLayoutInformaiton.Gpt.MaxPartitionCount.ToString()); break; case PartitionStyle.PARTITION_STYLE_RAW: break; default: throw new ArgumentOutOfRangeException(); } for (int entry = 0; entry < dlie1.PartitionCount - 1; entry++) // Last one is nulls { PARTITION_INFORMATION_EX pie = dlie1.PartitionEntry[entry]; details.Append("\t\t").AppendLine("PARTITION_INFORMATION_EX:"); details.Append("\t\t\t").Append("PartitionStyle: ") .AppendLine(pie.PartitionStyle.ToString()); details.Append("\t\t\t").Append("StartingOffset: ") .AppendLine(pie.StartingOffset.ToString()); details.Append("\t\t\t").Append("PartitionLength: ") .AppendLine(pie.PartitionLength.ToString()); details.Append("\t\t\t").Append("PartitionNumber: ") .AppendLine(pie.PartitionNumber.ToString()); details.Append("\t\t\t").Append("RewritePartition: ") .AppendLine(pie.RewritePartition.ToString()); switch (pie.PartitionStyle) { case PartitionStyle.PARTITION_STYLE_MBR: details.Append("\t\t\t").AppendLine("PARTITION_INFORMATION_MBR: "); details.Append("\t\t\t\t").Append("PartitionType: ") .AppendLine(pie.DriveLayoutInformaiton.Mbr.PartitionType.ToString()); details.Append("\t\t\t\t").Append("BootIndicator: ") .AppendLine(pie.DriveLayoutInformaiton.Mbr.BootIndicator.ToString()); details.Append("\t\t\t\t").Append("RecognizedPartition: ") .AppendLine(pie.DriveLayoutInformaiton.Mbr.RecognizedPartition.ToString()); details.Append("\t\t\t\t").Append("HiddenSectors: ") .AppendLine(pie.DriveLayoutInformaiton.Mbr.HiddenSectors.ToString()); break; case PartitionStyle.PARTITION_STYLE_GPT: details.Append("\t\t\t").AppendLine("PARTITION_INFORMATION_GPT: "); details.Append("\t\t\t\t").Append("PartitionType: ") .AppendLine(pie.DriveLayoutInformaiton.Gpt.PartitionType.ToString()); details.Append("\t\t\t\t").Append("PartitionId: ") .AppendLine(pie.DriveLayoutInformaiton.Gpt.PartitionId.ToString()); details.Append("\t\t\t\t").Append("EFIPartitionAttributes: ") .AppendLine(pie.DriveLayoutInformaiton.Gpt.Attributes.ToString()); details.Append("\t\t\t\t").Append("Name: ") .AppendLine(pie.DriveLayoutInformaiton.Gpt.Name.ToString()); break; case PartitionStyle.PARTITION_STYLE_RAW: break; default: throw new ArgumentOutOfRangeException(); } } } if (da.HasValue) { GET_DISK_ATTRIBUTES da1 = da.Value; details.Append('\t').AppendLine("DISK_ATTRIBUTES:"); details.Append("\t\t").Append("Version: ").AppendLine(da1.Version.ToString()); //public int Reserved1; details.Append("\t\t").Append("Attributes: ").AppendLine(da1.Attributes.ToString()); if ((da1.Attributes & 1) == 1) { details.Append("\t\t").Append("Attributes: ").AppendLine(@"DISK_ATTRIBUTE_OFFLINE"); } if ((da1.Attributes & 2) == 2) { details.Append("\t\t").Append("Attributes: ").AppendLine(@"DISK_ATTRIBUTE_READ_ONLY"); } } if (vip.HasValue) { GETVERSIONINPARAMS vip1 = vip.Value; details.Append('\t').AppendLine("GETVERSIONINPARAMS:"); details.Append("\t\t").Append("Version: ").AppendLine(vip1.bVersion.ToString()); details.Append("\t\t").Append("Revision: ").AppendLine(vip1.bRevision.ToString()); details.Append("\t\t").Append("Reserved: ").AppendLine(vip1.bReserved.ToString()); details.Append("\t\t").Append("IDEDeviceMap: ").AppendLine(vip1.bIDEDeviceMap.ToString()); details.Append("\t\t").Append("Capabilities: ").AppendLine(vip1.fCapabilities.ToString()); //details.Append("\t\t").Append("dwReserved: ").AppendLine(vip1.dwReserved.ToString()); } if (sddp.HasValue) { STORAGE_DEVICE_DESCRIPTOR_PARSED_EX sddp1 = sddp.Value; details.Append('\t').AppendLine("STORAGE_DEVICE_DESCRIPTOR_PARSED:"); //details.Append("\t\t").Append("Size: ").AppendLine(sddp1.Size.ToString()); details.Append("\t\t").Append("SCSI DeviceType: ").AppendLine(sddp1.DeviceType.ToString()); details.Append("\t\t").Append("SCSI DeviceTypeModifier: ") .AppendLine(sddp1.DeviceTypeModifier.ToString()); details.Append("\t\t").Append("RemovableMedia: ").AppendLine(sddp1.RemovableMedia.ToString()); details.Append("\t\t").Append("CommandQueueing: ").AppendLine(sddp1.CommandQueueing.ToString()); //details.Append("\t\t").Append("VendorIdOffset: ").AppendLine(sddp1.VendorIdOffset.ToString()); //details.Append("\t\t").Append("ProductIdOffset: ").AppendLine(sddp1.ProductIdOffset.ToString()); //details.Append("\t\t").Append("ProductRevisionOffset: ").AppendLine(sddp1.ProductRevisionOffset.ToString()); //details.Append("\t\t").Append("SerialNumberOffset: ").AppendLine(sddp1.SerialNumberOffset.ToString()); details.Append("\t\t").Append("BusType: ").AppendLine(sddp1.BusType.ToString()); details.Append("\t\t").Append("RawPropertiesLength: ").AppendLine(sddp1.RawPropertiesLength.ToString()); details.Append("\t\t").Append("RawDeviceProperties: ").AppendLine(sddp1.RawDeviceProperties.ToString()); //public byte[] RawDeviceProperties; details.Append("\t\t").Append("VendorId: ").AppendLine(sddp1.VendorId); details.Append("\t\t").Append("ProductId: ").AppendLine(sddp1.ProductId); details.Append("\t\t").Append("ProductRevision: ").AppendLine(sddp1.ProductRevision); details.Append("\t\t").Append("SerialNumber: ").AppendLine(sddp1.SerialNumber); } return(details.ToString()); }
public void ListPartition() { for (uint i = 0; i < MAX_NUMBER_OF_DRIVES; i++) { // try to open the current physical drive string volume = string.Format("\\\\.\\PhysicalDrive{0}", i); SafeFileHandle hndl = CreateFile(volume, Native.GENERIC_READ | Native.GENERIC_WRITE, Native.FILE_SHARE_READ | Native.FILE_SHARE_WRITE, IntPtr.Zero, Native.OPEN_EXISTING, Native.FILE_ATTRIBUTE_READONLY, IntPtr.Zero); IntPtr driveLayoutPtr = IntPtr.Zero; int DRIVE_LAYOUT_BUFFER_SIZE = 1024; int error; uint dummy = 0; do { error = 0; driveLayoutPtr = Marshal.AllocHGlobal(DRIVE_LAYOUT_BUFFER_SIZE); if (DeviceIoControl(hndl, Native.IOCTL_DISK_GET_DRIVE_LAYOUT_EX, IntPtr.Zero, 0, driveLayoutPtr, (uint)DRIVE_LAYOUT_BUFFER_SIZE, ref dummy, IntPtr.Zero)) { // I/O-control has been invoked successfully, convert to DRIVE_LAYOUT_INFORMATION_EX DRIVE_LAYOUT_INFORMATION_EX driveLayout = (DRIVE_LAYOUT_INFORMATION_EX)Marshal.PtrToStructure(driveLayoutPtr, typeof(DRIVE_LAYOUT_INFORMATION_EX)); //Enumerate partitions by using pointer arithmetic for (uint p = 0; p < driveLayout.PartitionCount; p++) { IntPtr ptr = new IntPtr(driveLayoutPtr.ToInt64() + Marshal.OffsetOf(typeof(DRIVE_LAYOUT_INFORMATION_EX), "PartitionEntry").ToInt64() + (p * Marshal.SizeOf(typeof(PARTITION_INFORMATION_EX)))); PARTITION_INFORMATION_EX partInfo = (PARTITION_INFORMATION_EX)Marshal.PtrToStructure(ptr, typeof(PARTITION_INFORMATION_EX)); //Check partition is recognized or not if (partInfo.PartitionStyle != PARTITION_STYLE.PARTITION_STYLE_GPT) { if ((partInfo.PartitionStyle != PARTITION_STYLE.PARTITION_STYLE_MBR) || (partInfo.Mbr.RecognizedPartition)) { if (partInfo.Mbr.BootIndicator == true) { Console.WriteLine("Drive No: " + i + " Partition Number :" + partInfo.PartitionNumber + " is boot partition"); } } } else if (partInfo.PartitionStyle == PARTITION_STYLE.PARTITION_STYLE_GPT) { //e3c9e316-0b5c-4db8-817d-f92df00215ae guid is defined from MS here: //https://msdn.microsoft.com/en-us/library/windows/desktop/aa365449(v=vs.85).aspx if (partInfo.Gpt.PartitionType == new Guid("e3c9e316-0b5c-4db8-817d-f92df00215ae")) { Console.WriteLine("Drive No: " + i + " Partition Number :" + partInfo.PartitionNumber + " is boot partition"); } } } } else { error = Marshal.GetLastWin32Error(); DRIVE_LAYOUT_BUFFER_SIZE *= 2; } Marshal.FreeHGlobal(driveLayoutPtr); driveLayoutPtr = IntPtr.Zero; } while (error == Native.ERROR_INSUFFICIENT_BUFFER); } }