/// <summary> /// Supported on Windows XP and upward /// </summary> public static DISK_GEOMETRY_EX GetDiskGeometryEx(SafeFileHandle hDevice) { uint dummy; DISK_GEOMETRY_EX diskGeometryEx = new DISK_GEOMETRY_EX(); IntPtr lpOutBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(diskGeometryEx)); Marshal.StructureToPtr(diskGeometryEx, lpOutBuffer, false); bool success = DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IntPtr.Zero, 0, lpOutBuffer, (uint)Marshal.SizeOf(typeof(DISK_GEOMETRY_EX)), out dummy, IntPtr.Zero); diskGeometryEx = (DISK_GEOMETRY_EX)Marshal.PtrToStructure(lpOutBuffer, typeof(DISK_GEOMETRY_EX)); Marshal.FreeHGlobal(lpOutBuffer); if (!success) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == (int)Win32Error.ERROR_INVALID_FUNCTION) { // Windows 2000 will throw this exception because IOCTL_DISK_GET_DRIVE_GEOMETRY_EX is only supported from XP onward throw new InvalidOperationException("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX is not supported"); } else { string message = String.Format("Unable to retrieve disk geometry, Win32 Error: {0}", errorCode); throw new IOException(message); } } return(diskGeometryEx); }
public static DISK_GEOMETRY GetDiskGeometryAndSize(SafeFileHandle hDevice, out long diskSize) { if (Environment.OSVersion.Version >= new Version(5, 1, 0, 0)) { // XP and upward DISK_GEOMETRY_EX diskGeometryEx = GetDiskGeometryEx(hDevice); diskSize = diskGeometryEx.DiskSize; return(diskGeometryEx.Geometry); } else { // Windows 2000 DISK_GEOMETRY diskGeometry = GetDiskGeometry(hDevice); diskSize = GetPartitionSize(hDevice); return(diskGeometry); } }