/// <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);
     }
 }