OSDN Git Service

* fhandler.h (class fhandler_dev_raw): Delete current_position and
authorcorinna <corinna>
Wed, 28 Sep 2005 19:33:16 +0000 (19:33 +0000)
committercorinna <corinna>
Wed, 28 Sep 2005 19:33:16 +0000 (19:33 +0000)
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
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index 65d7a0f..8e742fa 100644 (file)
@@ -1,3 +1,44 @@
+2005-09-28  Corinna Vinschen  <corinna@vinschen.de>
+
+       * 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  <cgf@timesys.com>
 
        * dcrt0.cc (getstack): New function.
index ac1e4e9..961aabc 100644 (file)
@@ -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
index 6f729ca..90209fc 100644 (file)
@@ -14,6 +14,7 @@ details. */
 #include <unistd.h>
 #include <winioctl.h>
 #include <asm/socket.h>
+#include <cygwin/rdevio.h>
 #include <cygwin/hdreg.h>
 #include <cygwin/fs.h>
 #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,
+                                       &sector_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);
     }
index fe27bbd..c5a8ab0 100644 (file)
 /**********************************************************************/
 /* 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)
index a062c2a..2cfffc2 100644 (file)
@@ -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;
index 4f41065..7bc3d5c 100644 (file)
@@ -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
 };