#include <errno.h>
#include <unistd.h>
#include <winioctl.h>
+#include <asm/socket.h>
+#include <cygwin/hdreg.h>
+#include <cygwin/fs.h>
#include "security.h"
#include "fhandler.h"
#include "cygerrno.h"
int
fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf)
{
- return fhandler_dev_raw::ioctl (cmd, buf);
+ DISK_GEOMETRY di;
+ PARTITION_INFORMATION pi;
+ DWORD bytes_read;
+ __off64_t drive_size = 0;
+ __off64_t start = 0;
+ switch (cmd)
+ {
+ case HDIO_GETGEO:
+ {
+ debug_printf ("HDIO_GETGEO");
+ if (!DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL, 0,
+ &di, sizeof (di),
+ &bytes_read, NULL))
+ {
+ __seterrno ();
+ return -1;
+ }
+ debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
+ di.Cylinders.LowPart,
+ di.TracksPerCylinder,
+ di.SectorsPerTrack,
+ di.BytesPerSector);
+ if (DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_PARTITION_INFO,
+ NULL, 0,
+ &pi, sizeof (pi),
+ &bytes_read, NULL))
+ {
+ debug_printf ("partition info: %ld (%ld)",
+ pi.StartingOffset.LowPart,
+ pi.PartitionLength.LowPart);
+ start = pi.StartingOffset.QuadPart >> 9ULL;
+ }
+ struct hd_geometry *geo = (struct hd_geometry *) buf;
+ geo->heads = di.TracksPerCylinder;
+ geo->sectors = di.SectorsPerTrack;
+ geo->cylinders = di.Cylinders.LowPart;
+ geo->start = start;
+ return 0;
+ }
+ case BLKGETSIZE:
+ case BLKGETSIZE64:
+ {
+ debug_printf ("BLKGETSIZE");
+ if (!DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL, 0,
+ &di, sizeof (di),
+ &bytes_read, NULL))
+ {
+ __seterrno ();
+ return -1;
+ }
+ debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
+ di.Cylinders.LowPart,
+ di.TracksPerCylinder,
+ di.SectorsPerTrack,
+ di.BytesPerSector);
+ if (DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_PARTITION_INFO,
+ NULL, 0,
+ &pi, sizeof (pi),
+ &bytes_read, NULL))
+ {
+ debug_printf ("partition info: %ld (%ld)",
+ pi.StartingOffset.LowPart,
+ pi.PartitionLength.LowPart);
+ drive_size = pi.PartitionLength.QuadPart;
+ }
+ else
+ {
+ drive_size = di.Cylinders.QuadPart * di.TracksPerCylinder *
+ di.SectorsPerTrack * di.BytesPerSector;
+ }
+ if (cmd == BLKGETSIZE)
+ *(long *)buf = drive_size >> 9UL;
+ else
+ *(__off64_t *)buf = drive_size;
+ return 0;
+ }
+ case BLKRRPART:
+ {
+ debug_printf ("BLKRRPART");
+ if (!DeviceIoControl (get_handle (),
+ IOCTL_DISK_UPDATE_DRIVE_SIZE,
+ NULL, 0,
+ &di, sizeof (di),
+ &bytes_read, NULL))
+ {
+ __seterrno ();
+ return -1;
+ }
+ return 0;
+ }
+ case BLKSSZGET:
+ {
+ debug_printf ("BLKSSZGET");
+ if (!DeviceIoControl (get_handle (),
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL, 0,
+ &di, sizeof (di),
+ &bytes_read, NULL))
+ {
+ __seterrno ();
+ return -1;
+ }
+ debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
+ di.Cylinders.LowPart,
+ di.TracksPerCylinder,
+ di.SectorsPerTrack,
+ di.BytesPerSector);
+ *(int *)buf = di.BytesPerSector;
+ return 0;
+ }
+ default:
+ return fhandler_dev_raw::ioctl (cmd, buf);
+ }
}
--- /dev/null
+/* cygwin/fs.h
+
+ Copyright 2002 Red Hat Inc.
+ Written by Chris January <chris@atomice.net>
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef _CYGWIN_FS_H_
+#define _CYGWIN_FS_H_
+
+#include <cygwin/types.h>
+
+#define BLKRRPART 0x0000125f
+#define BLKGETSIZE 0x00001260
+#define BLKSSZGET 0x00001268
+#define BLKGETSIZE64 0x00041268
+
+#endif