private static (long, uint) GetDiskProperties(string deviceName) { var x = new DISK_GEOMETRY_EX(); Execute(ref x, DISK_GET_DRIVE_GEOMETRY_EX, deviceName); return(x.DiskSize, x.Geometry.BytesPerSector); }
public static long GetDiskSectorSize(string deviceName) { var x = new DISK_GEOMETRY_EX(); Execute(ref x, DISK_GET_DRIVE_GEOMETRY_EX, deviceName); return(x.Geometry.BytesPerSector); }
public static long GetDiskLength(string deviceName) { var x = new DISK_GEOMETRY_EX(); Execute(ref x, DISK_GET_DRIVE_GEOMETRY_EX, deviceName); return(x.DiskSize); }
DiskGeometry(String deviceName) { var x = new DISK_GEOMETRY_EX(); IoCtl.Execute(ref x, IoCtl.DISK_GET_DRIVE_GEOMETRY_EX, deviceName); m_DiskSize = x.DiskSize; m_Geometry = x.Geometry; long remainder; m_MaximumLinearAddress = Math.DivRem(DiskSize, BytesPerSector, out remainder) - 1; ThrowIfDiskSizeOutOfIntegrity(remainder); m_BytesPerCylinder = BytesPerSector * Sector * Head; m_MaximumCubicAddress = DiskGeometry.Transform(m_MaximumLinearAddress, this); }
/// <summary> /// Retrieves the disk geometry of the specified disk. /// </summary> /// <param name="hfile">Handle to a valid, open disk.</param> /// <param name="geo">Receives the disk geometry information.</param> /// <returns></returns> /// <remarks></remarks> public static bool DiskGeometry(IntPtr hfile, ref DISK_GEOMETRY_EX geo) { if (hfile == DevProp.INVALID_HANDLE_VALUE) { return(false); } MemPtr mm = new MemPtr(); uint l = 0U; uint cb = 0U; l = (uint)Marshal.SizeOf <DISK_GEOMETRY_EX>(); mm.Alloc(l); NativeDisk.DeviceIoControl(hfile, NativeDisk.IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IntPtr.Zero, 0, mm.Handle, l, ref cb, IntPtr.Zero); geo = mm.ToStruct <DISK_GEOMETRY_EX>(); mm.Free(); return(true); }
private static void ExampleDiskIO() { const string drive = @"\\.\PhysicalDrive0"; Console.WriteLine(@"## Exmaple on {0} ##", drive); SafeFileHandle hddHandle = CreateFile(drive, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); if (hddHandle.IsInvalid) { int lastError = Marshal.GetLastWin32Error(); Console.WriteLine(@"!! Invalid {0}; Error ({1}): {2}", drive, lastError, new Win32Exception(lastError).Message); Console.WriteLine(); return; } using (DiskDeviceWrapper diskIo = new DiskDeviceWrapper(hddHandle, true)) { DISK_GEOMETRY_EX info = diskIo.DiskGetDriveGeometryEx(); Console.WriteLine("Sector size: " + info.Geometry.BytesPerSector); switch (info.PartitionInformation.PartitionStyle) { case PartitionStyle.PARTITION_STYLE_MBR: Console.WriteLine("MBR Id: " + info.PartitionInformation.MbrSignature); break; case PartitionStyle.PARTITION_STYLE_GPT: Console.WriteLine("GPT GUID: " + info.PartitionInformation.GptGuidId); break; } PARTITION_INFORMATION_EX partitionInfo = diskIo.DiskGetPartitionInfoEx(); Console.WriteLine("Partition style: " + partitionInfo.PartitionStyle); } Console.WriteLine(); }
/// <summary> /// Retrieve the partition table of a GPT-layout disk, manually. /// Must be Administrator. /// </summary> /// <param name="inf">DiskDeviceInfo object to the physical disk to read.</param> /// <param name="gptInfo">Receives the drive layout information.</param> /// <returns>True if successful.</returns> /// <remarks></remarks> public static bool ReadRawGptDisk(string devicePath, ref RAW_GPT_DISK gptInfo) { // Demand Administrator for accessing a raw disk. AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); // Dim principalPerm As New PrincipalPermission(Nothing, "Administrators") // principalPerm.Demand() var hfile = IO.CreateFile(devicePath, IO.GENERIC_READ | IO.GENERIC_WRITE, IO.FILE_SHARE_READ | IO.FILE_SHARE_WRITE, IntPtr.Zero, IO.OPEN_EXISTING, IO.FILE_FLAG_NO_BUFFERING | IO.FILE_FLAG_RANDOM_ACCESS, IntPtr.Zero); if (hfile == DevProp.INVALID_HANDLE_VALUE) { return(false); } DISK_GEOMETRY_EX geo = default; // get the disk geometry to retrieve the sector (LBA) size. if (!DiskGeometry(hfile, ref geo)) { User32.CloseHandle(hfile); return(false); } // sector size (usually 512 bytes) uint bps = geo.Geometry.BytesPerSector; uint br = 0U; long lp = 0L; long lp2 = 0L; var mm = new MemPtr(bps * 2L); IO.SetFilePointerEx(hfile, 0L, ref lp, IO.FilePointerMoveMethod.Begin); IO.ReadFile(hfile, mm.Handle, bps * 2, ref br, IntPtr.Zero); var mbr = new RAW_MBR(); var gpt = new RAW_GPT_HEADER(); RAW_GPT_PARTITION[] gpp = null; // read the master boot record. mbr = mm.ToStructAt <RAW_MBR>(446L); // read the GPT structure header. gpt = mm.ToStructAt <RAW_GPT_HEADER>(bps); // check the partition header CRC. if (gpt.IsValid) { long lr = br; // seek to the LBA of the partition information. IO.SetFilePointerEx(hfile, (uint)(bps * gpt.PartitionEntryLBA), ref lr, IO.FilePointerMoveMethod.Begin); br = (uint)lr; // calculate the size of the partition table buffer. lp = gpt.NumberOfPartitions * gpt.PartitionEntryLength; // byte align to the sector size. if (lp % bps != 0L) { lp += bps - lp % bps; } // bump up the memory pointer. mm.ReAlloc(lp); mm.ZeroMemory(); // read the partition information into the pointer. IO.ReadFile(hfile, mm.Handle, (uint)lp, ref br, IntPtr.Zero); // check the partition table CRC. if (mm.CalculateCrc32() == gpt.PartitionArrayCRC32) { // disk is valid. lp = (uint)Marshal.SizeOf <RAW_GPT_PARTITION>(); br = 0U; int i; int c = (int)gpt.NumberOfPartitions; gpp = new RAW_GPT_PARTITION[c + 1]; // populate the drive information. for (i = 0; i < c; i++) { gpp[i] = mm.ToStructAt <RAW_GPT_PARTITION>(lp2); // break on empty GUID, we are past the last partition. if (gpp[i].PartitionTypeGuid == Guid.Empty) { break; } lp2 += lp; } // trim off excess records from the array. if (i < c) { if (i == 0) { gpp = Array.Empty <RAW_GPT_PARTITION>(); } else { Array.Resize(ref gpp, i); } } } } // free the resources. mm.Free(); User32.CloseHandle(hfile); // if gpp is nothing then some error occurred somewhere and we did not succeed. if (gpp is null) { return(false); } // create a new RAW_GPT_DISK structure. gptInfo = new RAW_GPT_DISK(); gptInfo.Header = gpt; gptInfo.Partitions = gpp; // we have succeeded. return(true); }
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()); }