1 /* fhandler_floppy.cc. See fhandler.h for a description of the
4 Copyright 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
13 #include <sys/termios.h>
16 #include <asm/socket.h>
17 #include <cygwin/hdreg.h>
18 #include <cygwin/fs.h>
24 /**********************************************************************/
25 /* fhandler_dev_floppy */
28 fhandler_dev_floppy::is_eom (int win_error)
30 int ret = (win_error == ERROR_INVALID_PARAMETER);
32 debug_printf ("end of medium");
37 fhandler_dev_floppy::is_eof (int)
41 debug_printf ("end of file");
45 fhandler_dev_floppy::fhandler_dev_floppy ()
51 fhandler_dev_floppy::open (int flags, mode_t)
53 /* The correct size of the buffer would be 512 bytes,
54 * which is the atomic size, supported by WinNT.
55 * Unfortunately, the performance is worse than
56 * access to file system on same device!
57 * Setting buffer size to a relatively big value
58 * increases performance by means.
59 * The new ioctl call with 'rdevio.h' header file
60 * supports changing this value.
62 * Let's be smart: Let's take a multiplier of typical tar
63 * and cpio buffer sizes by default!
65 devbufsiz = 61440L; /* 512L; */
66 return fhandler_dev_raw::open (flags);
70 fhandler_dev_floppy::lseek (_off64_t offset, int whence)
73 _off64_t drive_size = 0;
74 _off64_t lloffset = offset;
75 _off64_t current_position;
76 _off64_t sector_aligned_offset;
82 PARTITION_INFORMATION pi;
85 if (!DeviceIoControl (get_handle (),
86 IOCTL_DISK_GET_DRIVE_GEOMETRY,
94 debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
99 if (DeviceIoControl (get_handle (),
100 IOCTL_DISK_GET_PARTITION_INFO,
105 debug_printf ("partition info: %ld (%ld)",
106 pi.StartingOffset.LowPart,
107 pi.PartitionLength.LowPart);
108 drive_size = pi.PartitionLength.QuadPart;
112 drive_size = di.Cylinders.QuadPart * di.TracksPerCylinder *
113 di.SectorsPerTrack * di.BytesPerSector;
115 debug_printf ("drive size: %ld", drive_size);
117 if (whence == SEEK_END && drive_size > 0)
119 lloffset = offset + drive_size;
123 if (whence == SEEK_CUR)
125 low = SetFilePointer (get_handle (), 0, &high, FILE_CURRENT);
126 if (low == INVALID_SET_FILE_POINTER && GetLastError ())
131 current_position = low + ((_off64_t) high << 32);
132 /* devbufend and devbufstart are always 0 when writing. */
133 current_position -= devbufend - devbufstart;
135 lloffset += current_position;
140 drive_size > 0 && lloffset > drive_size)
146 /* FIXME: sector can possibly be not 512 bytes long */
147 sector_aligned_offset = (lloffset / 512) * 512;
148 bytes_left = lloffset - sector_aligned_offset;
150 if (whence == SEEK_SET)
152 /* Invalidate buffer. */
153 devbufstart = devbufend = 0;
155 low = sector_aligned_offset & UINT32_MAX;
156 high = sector_aligned_offset >> 32;
157 if (SetFilePointer (get_handle (), low, &high, FILE_BEGIN)
158 == INVALID_SET_FILE_POINTER && GetLastError ())
164 eom_detected (false);
165 size_t len = bytes_left;
167 return sector_aligned_offset + bytes_left;
175 fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf)
178 PARTITION_INFORMATION pi;
180 _off64_t drive_size = 0;
186 debug_printf ("HDIO_GETGEO");
187 if (!DeviceIoControl (get_handle (),
188 IOCTL_DISK_GET_DRIVE_GEOMETRY,
196 debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
197 di.Cylinders.LowPart,
198 di.TracksPerCylinder,
201 if (DeviceIoControl (get_handle (),
202 IOCTL_DISK_GET_PARTITION_INFO,
207 debug_printf ("partition info: %ld (%ld)",
208 pi.StartingOffset.LowPart,
209 pi.PartitionLength.LowPart);
210 start = pi.StartingOffset.QuadPart >> 9ULL;
212 struct hd_geometry *geo = (struct hd_geometry *) buf;
213 geo->heads = di.TracksPerCylinder;
214 geo->sectors = di.SectorsPerTrack;
215 geo->cylinders = di.Cylinders.LowPart;
222 debug_printf ("BLKGETSIZE");
223 if (!DeviceIoControl (get_handle (),
224 IOCTL_DISK_GET_DRIVE_GEOMETRY,
232 debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
233 di.Cylinders.LowPart,
234 di.TracksPerCylinder,
237 if (DeviceIoControl (get_handle (),
238 IOCTL_DISK_GET_PARTITION_INFO,
243 debug_printf ("partition info: %ld (%ld)",
244 pi.StartingOffset.LowPart,
245 pi.PartitionLength.LowPart);
246 drive_size = pi.PartitionLength.QuadPart;
250 drive_size = di.Cylinders.QuadPart * di.TracksPerCylinder *
251 di.SectorsPerTrack * di.BytesPerSector;
253 if (cmd == BLKGETSIZE)
254 *(long *)buf = drive_size >> 9UL;
256 *(_off64_t *)buf = drive_size;
261 debug_printf ("BLKRRPART");
262 if (!DeviceIoControl (get_handle (),
263 IOCTL_DISK_UPDATE_DRIVE_SIZE,
275 debug_printf ("BLKSSZGET");
276 if (!DeviceIoControl (get_handle (),
277 IOCTL_DISK_GET_DRIVE_GEOMETRY,
285 debug_printf ("disk geometry: (%ld cyl)*(%ld trk)*(%ld sec)*(%ld bps)",
286 di.Cylinders.LowPart,
287 di.TracksPerCylinder,
290 *(int *)buf = di.BytesPerSector;
294 return fhandler_dev_raw::ioctl (cmd, buf);