summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_floppy.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-09-27 15:33:02 +0000
committerCorinna Vinschen <corinna@vinschen.de>2005-09-27 15:33:02 +0000
commit357d430185b174a373d7e651f52f39ebf276dd2c (patch)
tree81c9ef7ff8ec6bb0d774ef9f5408860756c1e60a /winsup/cygwin/fhandler_floppy.cc
parentdbdc82aa7146042b14dbae369a074e5bf41b4aa8 (diff)
downloadcygnal-357d430185b174a373d7e651f52f39ebf276dd2c.tar.gz
cygnal-357d430185b174a373d7e651f52f39ebf276dd2c.tar.bz2
cygnal-357d430185b174a373d7e651f52f39ebf276dd2c.zip
* fhandler_floppy.cc (fhandler_dev_floppy::get_drive_info): Always
try IOCTL_DISK_GET_DRIVE_GEOMETRY_EX and IOCTL_DISK_GET_PARTITION_INFO_EX ioctls first, to allow access to GPT partitioned disks. Fall back to old non-EX ioctls otherwise. Add comment to explain NT4 weirdness.
Diffstat (limited to 'winsup/cygwin/fhandler_floppy.cc')
-rw-r--r--winsup/cygwin/fhandler_floppy.cc88
1 files changed, 61 insertions, 27 deletions
diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc
index cafac8c43..6f729caa8 100644
--- a/winsup/cygwin/fhandler_floppy.cc
+++ b/winsup/cygwin/fhandler_floppy.cc
@@ -52,48 +52,82 @@ fhandler_dev_floppy::fhandler_dev_floppy ()
int
fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo)
{
- DISK_GEOMETRY di;
- PARTITION_INFORMATION pi;
+ char dbuf[256];
+ char pbuf[256];
+
+ DISK_GEOMETRY *di;
+ PARTITION_INFORMATION_EX *pix = NULL;
+ PARTITION_INFORMATION *pi = NULL;
DWORD bytes_read = 0;
+ /* Always try using the new EX ioctls first (>= XP). If not available,
+ fall back to trying the old non-EX ioctls. */
if (!DeviceIoControl (get_handle (),
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL, 0,
- &di, sizeof (di),
- &bytes_read, NULL))
+ IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
+ dbuf, 256, &bytes_read, NULL))
{
- __seterrno ();
- return -1;
+ if (!DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
+ dbuf, 256, &bytes_read, NULL))
+ {
+ __seterrno ();
+ return -1;
+ }
+ di = (DISK_GEOMETRY *) dbuf;
}
- debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
- di.Cylinders.LowPart,
- di.TracksPerCylinder,
- di.SectorsPerTrack,
- di.BytesPerSector);
- bytes_per_sector = di.BytesPerSector;
+ else
+ di = &((DISK_GEOMETRY_EX *) dbuf)->Geometry;
+
if (DeviceIoControl (get_handle (),
- IOCTL_DISK_GET_PARTITION_INFO,
- NULL, 0,
- &pi, sizeof (pi),
- &bytes_read, NULL))
+ IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
+ pbuf, 256, &bytes_read, NULL))
+ pix = (PARTITION_INFORMATION_EX *) pbuf;
+ else if (DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
+ pbuf, 256, &bytes_read, NULL))
+ pi = (PARTITION_INFORMATION *) pbuf;
+
+ debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
+ di->Cylinders.LowPart,
+ di->TracksPerCylinder,
+ di->SectorsPerTrack,
+ di->BytesPerSector);
+ bytes_per_sector = di->BytesPerSector;
+ if (pix)
+ {
+ debug_printf ("partition info: offset %D length %D",
+ pix->StartingOffset.QuadPart,
+ pix->PartitionLength.QuadPart);
+ drive_size = pix->PartitionLength.QuadPart;
+ }
+ else if (pi)
{
debug_printf ("partition info: offset %D length %D",
- pi.StartingOffset.QuadPart,
- pi.PartitionLength.QuadPart);
- drive_size = pi.PartitionLength.QuadPart;
+ pi->StartingOffset.QuadPart,
+ pi->PartitionLength.QuadPart);
+ drive_size = pi->PartitionLength.QuadPart;
}
else
{
- drive_size = di.Cylinders.QuadPart * di.TracksPerCylinder *
- di.SectorsPerTrack * di.BytesPerSector;
+ /* Getting the partition size by using the drive geometry information
+ looks wrong, but this is a historical necessity. NT4 didn't maintain
+ partition information for the whole drive (aka "partition 0"), but
+ returned ERROR_INVALID_HANDLE instead. That got fixed in W2K. */
+ drive_size = di->Cylinders.QuadPart * di->TracksPerCylinder *
+ di->SectorsPerTrack * di->BytesPerSector;
}
debug_printf ("drive size: %D", drive_size);
if (geo)
{
- geo->heads = di.TracksPerCylinder;
- geo->sectors = di.SectorsPerTrack;
- geo->cylinders = di.Cylinders.LowPart;
- geo->start = pi.StartingOffset.QuadPart >> 9ULL;
+ geo->heads = di->TracksPerCylinder;
+ geo->sectors = di->SectorsPerTrack;
+ geo->cylinders = di->Cylinders.LowPart;
+ if (pix)
+ geo->start = pix->StartingOffset.QuadPart >> 9ULL;
+ else if (pi)
+ geo->start = pi->StartingOffset.QuadPart >> 9ULL;
+ else
+ geo->start = 0;
}
return 0;
}