From 26153d1c06d7688bf201cae51b147243f736a8c3 Mon Sep 17 00:00:00 2001 From: corinna Date: Wed, 28 Sep 2005 19:33:16 +0000 Subject: [PATCH] * fhandler.h (class fhandler_dev_raw): Delete current_position and eof_detected status flag. Delete is_eom and is_eof methods. Move drive_size, bytes_per_sector, eom_detected status flag, as well as the methods read_file, write_file, raw_read and raw_write to ... (class fhandler_dev_floppy): ... here. Remove is_eom and is_eof methods. Add dup method. * fhandler_floppy.cc (IS_EOM): New macro. (fhandler_dev_floppy::is_eom): Remove. (fhandler_dev_floppy::is_eof): Remove. (fhandler_dev_floppy::fhandler_dev_floppy): Initialize status flags. (fhandler_dev_floppy::get_drive_info): Only call EX functions on systems supporting them and stop suffering strange delays. (fhandler_dev_floppy::read_file): Move here, drop setting current_position. (fhandler_dev_floppy::write_file): Move here, drop setting current_position. (fhandler_dev_floppy::open): Rearrange comment. (fhandler_dev_floppy::dup): New method. (fhandler_dev_floppy::get_current_position): New inline method. Use instead of former current_position were appropriate. (fhandler_dev_floppy::raw_read): Move here. Drop EOF handling. (fhandler_dev_floppy::raw_write): Move here. Drop EOF handling. (fhandler_dev_floppy::lseek): Remove useless conditions. Convert sector_aligned_offset to LARGE_INTEGER to improve SetFilePointer call. (fhandler_dev_floppy::ioctl): Move blocksize check in RDSETBLK case to here. * fhandler_raw.cc (fhandler_dev_raw::is_eom): Remove. (fhandler_dev_raw::is_eof): Remove. (fhandler_dev_raw::write_file): Remove. (fhandler_dev_raw::read_file): Remove. (fhandler_dev_raw::raw_read): Remove. (fhandler_dev_raw::raw_write): Remove. (fhandler_dev_raw::dup): Drop copying removed members. (fhandler_dev_raw::ioctl): Drop blocksize testing. * wincap.h: Implement has_disk_ex_ioctls throughout. * wincap.cc: Ditto. (wincap_vista): Preliminary wincaps for Windows Vista/Longhorn. (wincapc::init): Add Vista/Longhorn handling. --- winsup/cygwin/ChangeLog | 41 +++++ winsup/cygwin/fhandler.h | 51 +++--- winsup/cygwin/fhandler_floppy.cc | 346 +++++++++++++++++++++++++++++++-------- winsup/cygwin/fhandler_raw.cc | 235 +------------------------- winsup/cygwin/wincap.cc | 93 +++++++++-- winsup/cygwin/wincap.h | 2 + 6 files changed, 425 insertions(+), 343 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 65d7a0fb93..8e742faa5f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,44 @@ +2005-09-28 Corinna Vinschen + + * fhandler.h (class fhandler_dev_raw): Delete current_position and + eof_detected status flag. Delete is_eom and is_eof methods. + Move drive_size, bytes_per_sector, eom_detected status flag, as well + as the methods read_file, write_file, raw_read and raw_write to ... + (class fhandler_dev_floppy): ... here. Remove is_eom and is_eof + methods. Add dup method. + * fhandler_floppy.cc (IS_EOM): New macro. + (fhandler_dev_floppy::is_eom): Remove. + (fhandler_dev_floppy::is_eof): Remove. + (fhandler_dev_floppy::fhandler_dev_floppy): Initialize status flags. + (fhandler_dev_floppy::get_drive_info): Only call EX functions on + systems supporting them and stop suffering strange delays. + (fhandler_dev_floppy::read_file): Move here, drop setting + current_position. + (fhandler_dev_floppy::write_file): Move here, drop setting + current_position. + (fhandler_dev_floppy::open): Rearrange comment. + (fhandler_dev_floppy::dup): New method. + (fhandler_dev_floppy::get_current_position): New inline method. Use + instead of former current_position were appropriate. + (fhandler_dev_floppy::raw_read): Move here. Drop EOF handling. + (fhandler_dev_floppy::raw_write): Move here. Drop EOF handling. + (fhandler_dev_floppy::lseek): Remove useless conditions. Convert + sector_aligned_offset to LARGE_INTEGER to improve SetFilePointer call. + (fhandler_dev_floppy::ioctl): Move blocksize check in RDSETBLK case + to here. + * fhandler_raw.cc (fhandler_dev_raw::is_eom): Remove. + (fhandler_dev_raw::is_eof): Remove. + (fhandler_dev_raw::write_file): Remove. + (fhandler_dev_raw::read_file): Remove. + (fhandler_dev_raw::raw_read): Remove. + (fhandler_dev_raw::raw_write): Remove. + (fhandler_dev_raw::dup): Drop copying removed members. + (fhandler_dev_raw::ioctl): Drop blocksize testing. + * wincap.h: Implement has_disk_ex_ioctls throughout. + * wincap.cc: Ditto. + (wincap_vista): Preliminary wincaps for Windows Vista/Longhorn. + (wincapc::init): Add Vista/Longhorn handling. + 2005-09-28 Christopher Faylor * dcrt0.cc (getstack): New function. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index ac1e4e9a9c..961aabc6c4 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -551,50 +551,29 @@ public: class fhandler_dev_raw: public fhandler_base { protected: - _off64_t drive_size; - _off64_t current_position; - unsigned long bytes_per_sector; char *devbuf; size_t devbufsiz; size_t devbufstart; size_t devbufend; struct status_flags { - unsigned eom_detected : 1; - unsigned eof_detected : 1; unsigned lastblk_to_read : 1; public: - status_flags () : - eom_detected (0), eof_detected (0), lastblk_to_read (0) - {} + status_flags () : lastblk_to_read (0) {} } status; - IMPLEMENT_STATUS_FLAG (bool, eom_detected) - IMPLEMENT_STATUS_FLAG (bool, eof_detected) IMPLEMENT_STATUS_FLAG (bool, lastblk_to_read) - virtual BOOL write_file (const void *buf, DWORD to_write, - DWORD *written, int *err); - virtual BOOL read_file (void *buf, DWORD to_read, DWORD *read, int *err); - - /* returns not null, if `win_error' determines an end of media condition */ - virtual int is_eom(int win_error); - /* returns not null, if `win_error' determines an end of file condition */ - virtual int is_eof(int win_error); - fhandler_dev_raw (); public: ~fhandler_dev_raw (); int open (int flags, mode_t mode = 0); - void raw_read (void *ptr, size_t& ulen); - int raw_write (const void *ptr, size_t ulen); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); int dup (fhandler_base *child); - int ioctl (unsigned int cmd, void *buf); void fixup_after_fork (HANDLE); @@ -604,20 +583,32 @@ class fhandler_dev_raw: public fhandler_base class fhandler_dev_floppy: public fhandler_dev_raw { private: + _off64_t drive_size; + unsigned long bytes_per_sector; + struct status_flags + { + unsigned eom_detected : 1; + public: + status_flags () : eom_detected (0) {} + } status; + + IMPLEMENT_STATUS_FLAG (bool, eom_detected) + + inline _off64_t get_current_position (); int fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo); - protected: - virtual int is_eom (int win_error); - virtual int is_eof (int win_error); + BOOL write_file (const void *buf, DWORD to_write, DWORD *written, int *err); + BOOL read_file (void *buf, DWORD to_read, DWORD *read, int *err); public: fhandler_dev_floppy (); - virtual int open (int flags, mode_t mode = 0); - - virtual _off64_t lseek (_off64_t offset, int whence); - - virtual int ioctl (unsigned int cmd, void *buf); + int open (int flags, mode_t mode = 0); + int dup (fhandler_base *child); + void raw_read (void *ptr, size_t& ulen); + int raw_write (const void *ptr, size_t ulen); + _off64_t lseek (_off64_t offset, int whence); + int ioctl (unsigned int cmd, void *buf); }; class fhandler_dev_tape: public fhandler_dev_raw diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index 6f729caa88..90209fc04b 100644 --- a/winsup/cygwin/fhandler_floppy.cc +++ b/winsup/cygwin/fhandler_floppy.cc @@ -14,6 +14,7 @@ details. */ #include #include #include +#include #include #include #include "cygerrno.h" @@ -21,31 +22,15 @@ details. */ #include "path.h" #include "fhandler.h" +#define IS_EOM(err) ((err) == ERROR_INVALID_PARAMETER \ + || (err) == ERROR_SEEK \ + || (err) == ERROR_SECTOR_NOT_FOUND) + /**********************************************************************/ /* fhandler_dev_floppy */ -int -fhandler_dev_floppy::is_eom (int win_error) -{ - int ret = (win_error == ERROR_INVALID_PARAMETER - || win_error == ERROR_SEEK - || win_error == ERROR_SECTOR_NOT_FOUND); - if (ret) - debug_printf ("end of medium"); - return ret; -} - -int -fhandler_dev_floppy::is_eof (int) -{ - int ret = 0; - if (ret) - debug_printf ("end of file"); - return ret; -} - fhandler_dev_floppy::fhandler_dev_floppy () - : fhandler_dev_raw () + : fhandler_dev_raw (), status () { } @@ -62,9 +47,22 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo) /* 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_EX, NULL, 0, - dbuf, 256, &bytes_read, NULL)) + if (wincap.has_disk_ex_ioctls ()) + { + if (!DeviceIoControl (get_handle (), + IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, + dbuf, 256, &bytes_read, NULL)) + { + __seterrno (); + return -1; + } + di = &((DISK_GEOMETRY_EX *) dbuf)->Geometry; + if (DeviceIoControl (get_handle (), + 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_DRIVE_GEOMETRY, NULL, 0, @@ -74,18 +72,11 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo) return -1; } di = (DISK_GEOMETRY *) dbuf; + if (DeviceIoControl (get_handle (), + IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, + pbuf, 256, &bytes_read, NULL)) + pi = (PARTITION_INFORMATION *) pbuf; } - else - di = &((DISK_GEOMETRY_EX *) dbuf)->Geometry; - - if (DeviceIoControl (get_handle (), - 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, @@ -132,22 +123,46 @@ fhandler_dev_floppy::get_drive_info (struct hd_geometry *geo) return 0; } +/* Wrapper functions for ReadFile and WriteFile to simplify error handling. */ +BOOL +fhandler_dev_floppy::read_file (void *buf, DWORD to_read, DWORD *read, int *err) +{ + BOOL ret; + + *err = 0; + if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0))) + *err = GetLastError (); + syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)", + ret, *err, get_handle (), buf, to_read, *read); + return ret; +} + +BOOL +fhandler_dev_floppy::write_file (const void *buf, DWORD to_write, + DWORD *written, int *err) +{ + BOOL ret; + + *err = 0; + if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0))) + *err = GetLastError (); + syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)", + ret, *err, get_handle (), buf, to_write, *written); + return ret; +} + int fhandler_dev_floppy::open (int flags, mode_t) { - /* The correct size of the buffer would be 512 bytes, - * which is the atomic size, supported by WinNT. - * Unfortunately, the performance is worse than - * access to file system on same device! - * Setting buffer size to a relatively big value - * increases performance by means. - * The new ioctl call with 'rdevio.h' header file - * supports changing this value. - * - * Let's be smart: Let's take a multiplier of typical tar - * and cpio buffer sizes by default! - */ - devbufsiz = 61440L; /* 512L; */ + /* The correct size of the buffer would be 512 bytes, which is the atomic + size, supported by WinNT. Unfortunately, the performance is worse than + access to file system on same device! Setting buffer size to a + relatively big value increases performance by means. The new ioctl call + with 'rdevio.h' header file supports changing this value. + + Let's try to be smart: Let's take a multiple of typical tar and cpio + buffer sizes by default. */ + devbufsiz = 61440L; int ret = fhandler_dev_raw::open (flags); if (ret && get_drive_info (NULL)) @@ -159,59 +174,244 @@ fhandler_dev_floppy::open (int flags, mode_t) return ret; } +int +fhandler_dev_floppy::dup (fhandler_base *child) +{ + int ret = fhandler_dev_raw::dup (child); + + if (!ret) + { + fhandler_dev_floppy *fhc = (fhandler_dev_floppy *) child; + + fhc->drive_size = drive_size; + fhc->bytes_per_sector = bytes_per_sector; + fhc->eom_detected (eom_detected ()); + } + return ret; +} + +inline _off64_t +fhandler_dev_floppy::get_current_position () +{ + LARGE_INTEGER off = { QuadPart: 0LL }; + off.LowPart = SetFilePointer (get_handle (), 0, &off.HighPart, FILE_CURRENT); + return off.QuadPart; +} + +void +fhandler_dev_floppy::raw_read (void *ptr, size_t& ulen) +{ + DWORD bytes_read = 0; + DWORD read2; + DWORD bytes_to_read; + int ret; + size_t len = ulen; + char *tgt; + char *p = (char *) ptr; + + /* Checking a previous end of media */ + if (eom_detected () && !lastblk_to_read ()) + { + set_errno (ENOSPC); + goto err; + } + + if (devbuf) + { + while (len > 0) + { + if (devbufstart < devbufend) + { + bytes_to_read = min (len, devbufend - devbufstart); + debug_printf ("read %d bytes from buffer (rest %d)", + bytes_to_read, + devbufend - devbufstart - bytes_to_read); + memcpy (p, devbuf + devbufstart, bytes_to_read); + len -= bytes_to_read; + p += bytes_to_read; + bytes_read += bytes_to_read; + devbufstart += bytes_to_read; + + if (lastblk_to_read ()) + { + lastblk_to_read (false); + break; + } + } + if (len > 0) + { + if (len >= devbufsiz) + { + bytes_to_read = (len / bytes_per_sector) * bytes_per_sector; + tgt = p; + } + else + { + tgt = devbuf; + bytes_to_read = devbufsiz; + } + _off64_t current_position = get_current_position (); + if (current_position + bytes_to_read >= drive_size) + bytes_to_read = drive_size - current_position; + if (!bytes_to_read) + { + eom_detected (true); + break; + } + + debug_printf ("read %d bytes %s", bytes_to_read, + len < devbufsiz ? "into buffer" : "directly"); + if (!read_file (tgt, bytes_to_read, &read2, &ret)) + { + if (!IS_EOM (ret)) + { + __seterrno (); + goto err; + } + + eom_detected (true); + + if (!read2) + { + if (!bytes_read) + { + debug_printf ("return -1, set errno to ENOSPC"); + set_errno (ENOSPC); + goto err; + } + break; + } + lastblk_to_read (true); + } + if (!read2) + break; + if (tgt == devbuf) + { + devbufstart = 0; + devbufend = read2; + } + else + { + len -= read2; + p += read2; + bytes_read += read2; + } + } + } + } + else if (!read_file (p, len, &bytes_read, &ret)) + { + if (!IS_EOM (ret)) + { + __seterrno (); + goto err; + } + if (bytes_read) + eom_detected (true); + else + { + debug_printf ("return -1, set errno to ENOSPC"); + set_errno (ENOSPC); + goto err; + } + } + + ulen = (size_t) bytes_read; + return; + +err: + ulen = (size_t) -1; +} + +int +fhandler_dev_floppy::raw_write (const void *ptr, size_t len) +{ + DWORD bytes_written = 0; + char *p = (char *) ptr; + int ret; + + /* Checking a previous end of media on tape */ + if (eom_detected ()) + { + set_errno (ENOSPC); + return -1; + } + + /* Invalidate buffer. */ + devbufstart = devbufend = 0; + + if (len > 0) + { + if (!write_file (p, len, &bytes_written, &ret)) + { + if (!IS_EOM (ret)) + { + __seterrno (); + return -1; + } + eom_detected (true); + if (!bytes_written) + { + set_errno (ENOSPC); + return -1; + } + } + } + return bytes_written; +} + _off64_t fhandler_dev_floppy::lseek (_off64_t offset, int whence) { char buf[512]; _off64_t lloffset = offset; - _off64_t sector_aligned_offset; + LARGE_INTEGER sector_aligned_offset; _off64_t bytes_left; - DWORD low; - LONG high = 0; - if (whence == SEEK_END && drive_size > 0) + if (whence == SEEK_END) { - lloffset = offset + drive_size; + lloffset += drive_size; whence = SEEK_SET; } - - if (whence == SEEK_CUR) + else if (whence == SEEK_CUR) { - lloffset += current_position - (devbufend - devbufstart); + lloffset += get_current_position () - (devbufend - devbufstart); whence = SEEK_SET; } - if (whence != SEEK_SET - || lloffset < 0 - || drive_size > 0 && lloffset >= drive_size) + if (whence != SEEK_SET || lloffset < 0 || lloffset >= drive_size) { set_errno (EINVAL); return -1; } - sector_aligned_offset = (lloffset / bytes_per_sector) * bytes_per_sector; - bytes_left = lloffset - sector_aligned_offset; + sector_aligned_offset.QuadPart = (lloffset / bytes_per_sector) + * bytes_per_sector; + bytes_left = lloffset - sector_aligned_offset.QuadPart; /* Invalidate buffer. */ devbufstart = devbufend = 0; - low = sector_aligned_offset & UINT32_MAX; - high = sector_aligned_offset >> 32; - if (SetFilePointer (get_handle (), low, &high, FILE_BEGIN) - == INVALID_SET_FILE_POINTER && GetLastError ()) + sector_aligned_offset.LowPart = + SetFilePointer (get_handle (), + sector_aligned_offset.LowPart, + §or_aligned_offset.HighPart, + FILE_BEGIN); + if (sector_aligned_offset.LowPart == INVALID_SET_FILE_POINTER + && GetLastError ()) { __seterrno (); return -1; } eom_detected (false); - current_position = sector_aligned_offset; + if (bytes_left) { size_t len = bytes_left; raw_read (buf, len); } - return current_position + bytes_left; + return sector_aligned_offset.QuadPart + bytes_left; } int @@ -257,6 +457,18 @@ fhandler_dev_floppy::ioctl (unsigned int cmd, void *buf) *(int *)buf = bytes_per_sector; return 0; } + case RDSETBLK: + /* Just check the restriction that blocksize must be a multiple + of the sector size of the underlying volume sector size, + then fall through to fhandler_dev_raw::ioctl. */ + struct rdop *op = (struct rdop *) buf; + if (op->rd_parm % bytes_per_sector) + { + SetLastError (ERROR_INVALID_PARAMETER); + __seterrno (); + return -1; + } + /*FALLTHRUGH*/ default: return fhandler_dev_raw::ioctl (cmd, buf); } diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index fe27bbd912..c5a8ab0748 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -27,52 +27,6 @@ /**********************************************************************/ /* fhandler_dev_raw */ -int -fhandler_dev_raw::is_eom (int win_error) -{ - return 0; -} - -int -fhandler_dev_raw::is_eof (int) -{ - return 0; -} - - -/* Wrapper functions to simplify error handling. */ - -BOOL -fhandler_dev_raw::write_file (const void *buf, DWORD to_write, - DWORD *written, int *err) -{ - BOOL ret; - - *err = 0; - if (!(ret = WriteFile (get_handle (), buf, to_write, written, 0))) - *err = GetLastError (); - else - current_position += *written; - syscall_printf ("%d (err %d) = WriteFile (%d, %d, write %d, written %d, 0)", - ret, *err, get_handle (), buf, to_write, *written); - return ret; -} - -BOOL -fhandler_dev_raw::read_file (void *buf, DWORD to_read, DWORD *read, int *err) -{ - BOOL ret; - - *err = 0; - if (!(ret = ReadFile (get_handle (), buf, to_read, read, 0))) - *err = GetLastError (); - else - current_position += *read; - syscall_printf ("%d (err %d) = ReadFile (%d, %d, to_read %d, read %d, 0)", - ret, *err, get_handle (), buf, to_read, *read); - return ret; -} - fhandler_dev_raw::fhandler_dev_raw () : fhandler_base (), status () { @@ -140,205 +94,20 @@ fhandler_dev_raw::open (int flags, mode_t) return res; } -void -fhandler_dev_raw::raw_read (void *ptr, size_t& ulen) -{ - DWORD bytes_read = 0; - DWORD read2; - DWORD bytes_to_read; - int ret; - size_t len = ulen; - char *tgt; - char *p = (char *) ptr; - - /* Checking a previous end of file */ - if (eof_detected () && !lastblk_to_read ()) - { - eof_detected (false); - ulen = 0; - return; - } - - /* Checking a previous end of media */ - if (eom_detected () && !lastblk_to_read ()) - { - set_errno (ENOSPC); - goto err; - } - - if (devbuf) - { - while (len > 0) - { - if (devbufstart < devbufend) - { - bytes_to_read = min (len, devbufend - devbufstart); - debug_printf ("read %d bytes from buffer (rest %d)", - bytes_to_read, - devbufend - devbufstart - bytes_to_read); - memcpy (p, devbuf + devbufstart, bytes_to_read); - len -= bytes_to_read; - p += bytes_to_read; - bytes_read += bytes_to_read; - devbufstart += bytes_to_read; - - if (lastblk_to_read ()) - { - lastblk_to_read (false); - break; - } - } - if (len > 0) - { - if (len >= devbufsiz) - { - bytes_to_read = (len / bytes_per_sector) * bytes_per_sector; - if (current_position + bytes_to_read >= drive_size) - bytes_to_read = drive_size - current_position; - tgt = p; - debug_printf ("read %d bytes direct from file",bytes_to_read); - } - else - { - tgt = devbuf; - bytes_to_read = devbufsiz; - if (current_position + bytes_to_read >= drive_size) - bytes_to_read = drive_size - current_position; - debug_printf ("read %d bytes from file into buffer", - bytes_to_read); - } - if (!bytes_to_read) - { - eom_detected (true); - break; - } - - if (!read_file (tgt, bytes_to_read, &read2, &ret)) - { - if (!is_eof (ret) && !is_eom (ret)) - { - __seterrno (); - goto err; - } - - if (is_eof (ret)) - eof_detected (true); - else - eom_detected (true); - - if (!read2) - { - if (!bytes_read && is_eom (ret)) - { - debug_printf ("return -1, set errno to ENOSPC"); - set_errno (ENOSPC); - goto err; - } - break; - } - lastblk_to_read (true); - } - if (!read2) - break; - if (tgt == devbuf) - { - devbufstart = 0; - devbufend = read2; - } - else - { - len -= read2; - p += read2; - bytes_read += read2; - } - } - } - } - else if (!read_file (p, len, &bytes_read, &ret)) - { - if (!is_eof (ret) && !is_eom (ret)) - { - __seterrno (); - goto err; - } - if (bytes_read) - { - if (is_eof (ret)) - eof_detected (true); - else - eom_detected (true); - } - else if (is_eom (ret)) - { - debug_printf ("return -1, set errno to ENOSPC"); - set_errno (ENOSPC); - goto err; - } - } - - ulen = (size_t) bytes_read; - return; - -err: - ulen = (size_t) -1; -} - -int -fhandler_dev_raw::raw_write (const void *ptr, size_t len) -{ - DWORD bytes_written = 0; - char *p = (char *) ptr; - int ret; - - /* Checking a previous end of media on tape */ - if (eom_detected ()) - { - set_errno (ENOSPC); - return -1; - } - - /* Invalidate buffer. */ - devbufstart = devbufend = 0; - - if (len > 0) - { - if (!write_file (p, len, &bytes_written, &ret)) - { - if (!is_eom (ret)) - { - __seterrno (); - return -1; - } - eom_detected (true); - if (!bytes_written) - { - set_errno (ENOSPC); - return -1; - } - } - } - return bytes_written; -} - int fhandler_dev_raw::dup (fhandler_base *child) { int ret = fhandler_base::dup (child); - if (! ret) + if (!ret) { fhandler_dev_raw *fhc = (fhandler_dev_raw *) child; - fhc->drive_size = drive_size; - fhc->current_position = current_position; - fhc->bytes_per_sector = bytes_per_sector; fhc->devbufsiz = devbufsiz; if (devbufsiz > 1L) fhc->devbuf = new char [devbufsiz]; fhc->devbufstart = 0; fhc->devbufend = 0; - fhc->eom_detected (eom_detected ()); - fhc->eof_detected (eof_detected ()); fhc->lastblk_to_read (false); } return ret; @@ -385,8 +154,6 @@ fhandler_dev_raw::ioctl (unsigned int cmd, void *buf) mop.mt_count = op->rd_parm; ret = ioctl (MTIOCTOP, &mop); } - else if (op->rd_parm % bytes_per_sector) - ret = ERROR_INVALID_PARAMETER; else if (devbuf && op->rd_parm < devbufend - devbufstart) ret = ERROR_INVALID_PARAMETER; else if (!devbuf || op->rd_parm != devbufsiz) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index a062c2ac26..2cfffc2d64 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -59,7 +59,8 @@ static NO_COPY wincaps wincap_unknown = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:true, - has_null_console_handler_routine:false + has_null_console_handler_routine:false, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_95 = { @@ -110,7 +111,8 @@ static NO_COPY wincaps wincap_95 = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:true, - has_null_console_handler_routine:false + has_null_console_handler_routine:false, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_95osr2 = { @@ -161,7 +163,8 @@ static NO_COPY wincaps wincap_95osr2 = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:true, - has_null_console_handler_routine:false + has_null_console_handler_routine:false, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_98 = { @@ -212,7 +215,8 @@ static NO_COPY wincaps wincap_98 = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:true, - has_null_console_handler_routine:false + has_null_console_handler_routine:false, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_98se = { @@ -263,7 +267,8 @@ static NO_COPY wincaps wincap_98se = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:true, - has_null_console_handler_routine:false + has_null_console_handler_routine:false, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_me = { @@ -314,7 +319,8 @@ static NO_COPY wincaps wincap_me = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:true, - has_null_console_handler_routine:false + has_null_console_handler_routine:false, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_nt3 = { @@ -365,7 +371,8 @@ static NO_COPY wincaps wincap_nt3 = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:false, - has_null_console_handler_routine:true + has_null_console_handler_routine:true, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_nt4 = { @@ -416,7 +423,8 @@ static NO_COPY wincaps wincap_nt4 = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:false, - has_null_console_handler_routine:true + has_null_console_handler_routine:true, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_nt4sp4 = { @@ -467,7 +475,8 @@ static NO_COPY wincaps wincap_nt4sp4 = { has_extended_priority_class:false, has_guid_volumes:false, detect_win16_exe:false, - has_null_console_handler_routine:true + has_null_console_handler_routine:true, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_2000 = { @@ -518,7 +527,8 @@ static NO_COPY wincaps wincap_2000 = { has_extended_priority_class:true, has_guid_volumes:true, detect_win16_exe:false, - has_null_console_handler_routine:true + has_null_console_handler_routine:true, + has_disk_ex_ioctls:false }; static NO_COPY wincaps wincap_xp = { @@ -569,7 +579,8 @@ static NO_COPY wincaps wincap_xp = { has_extended_priority_class:true, has_guid_volumes:true, detect_win16_exe:false, - has_null_console_handler_routine:true + has_null_console_handler_routine:true, + has_disk_ex_ioctls:true }; static NO_COPY wincaps wincap_2003 = { @@ -620,7 +631,60 @@ static NO_COPY wincaps wincap_2003 = { has_extended_priority_class:true, has_guid_volumes:true, detect_win16_exe:false, - has_null_console_handler_routine:true + has_null_console_handler_routine:true, + has_disk_ex_ioctls:true +}; + +static NO_COPY wincaps wincap_vista = { + lock_file_highword:UINT32_MAX, + chunksize:0, + shared:FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + is_winnt:true, + is_server:true, + access_denied_on_delete:false, + has_delete_on_close:true, + has_page_guard:true, + has_security:true, + has_security_descriptor_control:true, + has_get_process_times:true, + has_lseek_bug:false, + has_lock_file_ex:true, + has_signal_object_and_wait:true, + has_eventlog:true, + has_ip_helper_lib:true, + has_set_handle_information:true, + has_set_handle_information_on_console_handles:true, + supports_smp:true, + map_view_of_file_ex_sucks:false, + altgr_is_ctrl_alt:true, + has_physical_mem_access:true, + has_working_copy_on_write:true, + share_mmaps_only_by_name:false, + virtual_protect_works_on_shared_pages:true, + has_hard_links:true, + can_open_directories:true, + has_move_file_ex:true, + has_negative_pids:false, + has_unreliable_pipes:false, + has_named_pipes:true, + has_try_enter_critical_section:true, + has_raw_devices:true, + has_valid_processorlevel:true, + has_64bit_file_access:true, + has_process_io_counters:true, + supports_reading_modem_output_lines:true, + needs_memory_protection:true, + pty_needs_alloc_console:true, + has_terminal_services:true, + has_switch_to_thread:true, + cant_debug_dll_entry:false, + has_ioctl_storage_get_media_types_ex:true, + start_proc_suspended:false, + has_extended_priority_class:true, + has_guid_volumes:true, + detect_win16_exe:false, + has_null_console_handler_routine:true, + has_disk_ex_ioctls:true }; wincapc wincap; @@ -676,6 +740,11 @@ wincapc::init () caps = &wincap_2003; } break; + case 6: + os = "NT"; + has_osversioninfoex = true; + caps = &wincap_vista; + break; default: os = "??"; caps = &wincap_unknown; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 4f41065d0d..7bc3d5ca70 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -61,6 +61,7 @@ struct wincaps unsigned has_guid_volumes : 1; unsigned detect_win16_exe : 1; unsigned has_null_console_handler_routine : 1; + unsigned has_disk_ex_ioctls : 1; }; class wincapc @@ -126,6 +127,7 @@ public: bool IMPLEMENT (has_guid_volumes) bool IMPLEMENT (detect_win16_exe) bool IMPLEMENT (has_null_console_handler_routine) + bool IMPLEMENT (has_disk_ex_ioctls) #undef IMPLEMENT }; -- 2.11.0