]> sourceware.org Git - newlib-cygwin.git/commitdiff
* fhandler.h (MAX_PARTITIONS): New definition.
authorCorinna Vinschen <corinna@vinschen.de>
Tue, 11 Jan 2011 14:50:45 +0000 (14:50 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 11 Jan 2011 14:50:45 +0000 (14:50 +0000)
(class fhandler_dev_floppy): Add partitions array member.  Add close
method.
* fhandler_floppy.cc (fhandler_dev_floppy::fhandler_dev_floppy): Zero
out partitions array.
(fhandler_dev_floppy::open): Fix "entire disk" condition for call to
DeviceIoControl (FSCTL_ALLOW_EXTENDED_DASD_IO).
When opening disks for writing, call DeviceIoControl (FSCTL_LOCK_VOLUME)
on all affected disk partitions starting with Vista.
(fhandler_dev_floppy::close): New method.
(fhandler_dev_floppy::dup): Duplicate handles in partitions, if any.
* wincap.h (wincaps::has_restricted_raw_disk_access): New element.
* wincap.cc: Implement above element throughout.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index fad41419f19436e2e996f57325c2a3c7ea12e87b..95fcb53012f3fa135fb7a65e4fb118b22e35c469 100644 (file)
@@ -1,3 +1,19 @@
+2011-01-11  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler.h (MAX_PARTITIONS): New definition.
+       (class fhandler_dev_floppy): Add partitions array member.  Add close
+       method.
+       * fhandler_floppy.cc (fhandler_dev_floppy::fhandler_dev_floppy): Zero
+       out partitions array.
+       (fhandler_dev_floppy::open): Fix "entire disk" condition for call to 
+       DeviceIoControl (FSCTL_ALLOW_EXTENDED_DASD_IO).
+       When opening disks for writing, call DeviceIoControl (FSCTL_LOCK_VOLUME)
+       on all affected disk partitions starting with Vista.
+       (fhandler_dev_floppy::close): New method.
+       (fhandler_dev_floppy::dup): Duplicate handles in partitions, if any.
+       * wincap.h (wincaps::has_restricted_raw_disk_access): New element.
+       * wincap.cc: Implement above element throughout.
+
 2011-01-11  Yaakov Selkowitz  <yselkowitz@users.sourceforge.net>
 
        * termios.cc (cfgetospeed, cfgetispeed): Constify argument per POSIX.
index 66ebc11989de5cf32c53ef8d5266d1e25f717e2c..056199038f8009d2e3696455906dd24cc1ed5988 100644 (file)
@@ -1,7 +1,7 @@
 /* fhandler.h
 
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
+   2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -687,11 +687,14 @@ class fhandler_dev_raw: public fhandler_base
   void fixup_after_exec ();
 };
 
+#define MAX_PARTITIONS 15
+
 class fhandler_dev_floppy: public fhandler_dev_raw
 {
  private:
   _off64_t drive_size;
   unsigned long bytes_per_sector;
+  HANDLE partitions[MAX_PARTITIONS];
   struct status_flags
   {
     unsigned eom_detected    : 1;
@@ -711,6 +714,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw
   fhandler_dev_floppy ();
 
   int open (int flags, mode_t mode = 0);
+  int close ();
   int dup (fhandler_base *child);
   void __stdcall raw_read (void *ptr, size_t& ulen);
   ssize_t __stdcall raw_write (const void *ptr, size_t ulen);
index 0d906b186d84068b92c7e792daea5932ecca9832..af8b7d2f1d841bdfafeca7ad8343c0cc080b3741 100644 (file)
@@ -2,7 +2,7 @@
    fhandler classes.
 
    Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009 Red Hat, Inc.
+   2009, 2011 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -32,6 +32,7 @@ details. */
 fhandler_dev_floppy::fhandler_dev_floppy ()
   : fhandler_dev_raw (), status ()
 {
+  memset (partitions, 0, sizeof partitions);
 }
 
 int
@@ -221,25 +222,98 @@ fhandler_dev_floppy::open (int flags, mode_t)
          make sure we're actually allowed to read *all* of the device.
         This is actually documented in the MSDN CreateFile man page. */
       if (get_major () != DEV_FLOPPY_MAJOR
-         && (get_major () == DEV_CDROM_MAJOR || get_minor () == 0)
+         && (get_major () == DEV_CDROM_MAJOR || get_minor () % 16 == 0)
          && !DeviceIoControl (get_handle (), FSCTL_ALLOW_EXTENDED_DASD_IO,
                               NULL, 0, NULL, 0, &bytes_read, NULL))
        debug_printf ("DeviceIoControl (FSCTL_ALLOW_EXTENDED_DASD_IO) "
                      "failed, %E");
+      /* If we're trying to write to a disk partition, lock the partition,
+        otherwise we will get "Access denied" starting with Vista. */
+      if (wincap.has_restricted_raw_disk_access ()
+         && get_major () != DEV_FLOPPY_MAJOR
+         && get_major () != DEV_CDROM_MAJOR
+         && (flags & O_ACCMODE) != O_RDONLY)
+       {
+         /* Special case: If we try to write to the entire disk, we have to
+            lock all partitions, otherwise writing fails as soon as we cross
+            a partition boundary. */
+         if (get_minor () % 16 == 0)
+           {
+             WCHAR part[MAX_PATH], *p;
+
+             sys_mbstowcs (part, MAX_PATH, get_win32_name ());
+             p = wcschr (part, L'\0') - 1;
+             for (int i = 0; i < MAX_PARTITIONS; ++i)
+               {
+                 NTSTATUS status;
+                 UNICODE_STRING upart;
+                 OBJECT_ATTRIBUTES attr;
+                 IO_STATUS_BLOCK io;
+
+                 __small_swprintf (p, L"%d", i + 1);
+                 RtlInitUnicodeString (&upart, part);
+                 InitializeObjectAttributes (&attr, &upart,
+                                             OBJ_INHERIT|OBJ_CASE_INSENSITIVE,
+                                             NULL, NULL);
+                 status = NtOpenFile (&partitions[i], GENERIC_WRITE, &attr,
+                                      &io, FILE_SHARE_VALID_FLAGS, 0);
+                 if (status == STATUS_OBJECT_NAME_NOT_FOUND ||
+                     status == STATUS_OBJECT_PATH_NOT_FOUND)
+                   break;
+                 else if (!NT_SUCCESS (status))
+                   debug_printf ("NtCreateFile(%W): status %p", part, status);
+                 else if (!DeviceIoControl (partitions[i], FSCTL_LOCK_VOLUME,
+                                            NULL, 0, NULL, 0,
+                                            &bytes_read, NULL))
+                   debug_printf ("DeviceIoControl (%W, FSCTL_LOCK_VOLUME) "
+                                 "failed, %E", part);
+               }
+           }
+         else if (!DeviceIoControl (get_handle (), FSCTL_LOCK_VOLUME,
+                                    NULL, 0, NULL, 0, &bytes_read, NULL))
+           debug_printf ("DeviceIoControl (FSCTL_LOCK_VOLUME) failed, %E");
+       }
     }
 
   return ret;
 }
 
+int
+fhandler_dev_floppy::close ()
+{
+  int ret = fhandler_dev_raw::close ();
+
+  /* See "Special case" comment in fhandler_dev_floppy::open. */
+  if (wincap.has_restricted_raw_disk_access ())
+    for (int i = 0; i < MAX_PARTITIONS && partitions[i]; ++i)
+      NtClose (partitions[i]);
+
+  return ret;
+}
+
 int
 fhandler_dev_floppy::dup (fhandler_base *child)
 {
+  fhandler_dev_floppy *fhc = (fhandler_dev_floppy *) child;
+
+  /* See "Special case" comment in fhandler_dev_floppy::open. */
+  memset (fhc->partitions, 0, sizeof fhc->partitions);
+  if (wincap.has_restricted_raw_disk_access ())
+    for (int i = 0; i < MAX_PARTITIONS && partitions[i]; ++i)
+      if (!DuplicateHandle (GetCurrentProcess (), partitions[i],
+                           GetCurrentProcess (), &fhc->partitions[i],
+                           0, TRUE, DUPLICATE_SAME_ACCESS))
+       {
+         __seterrno ();
+         while (--i >= 0)
+           NtClose (partitions[i]);
+         return -1;
+       }
+
   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 ());
index 7f1688516485887f5d740a456e3ef4c31f07709d..c6fe7cde3bb667158e37f3f6949f78b93309f99a 100644 (file)
@@ -2,7 +2,7 @@
                capability class to the appropriate values.
 
    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010 Red Hat, Inc.
+   2009, 2010, 2011 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -61,6 +61,7 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
   has_mwmo_inputavailable:false,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -101,6 +102,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -141,6 +143,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -181,6 +184,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -221,6 +225,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -261,6 +266,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -301,6 +307,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:false,
+  has_restricted_raw_disk_access:false,
 };
 
 wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -341,6 +348,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:true,
   has_fast_cwd:true,
+  has_restricted_raw_disk_access:true,
 };
 
 wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -381,6 +389,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_mwmo_inputavailable:true,
   has_buggy_thread_startup:false,
   has_fast_cwd:true,
+  has_restricted_raw_disk_access:true,
 };
 
 wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
index decfc1e5081bd82b4862541578113a8706c1c2a4..8a704b800952bf5944099c71074672f9657c9ab3 100644 (file)
@@ -1,7 +1,7 @@
 /* wincap.h: Header for OS capability class.
 
    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010 Red Hat, Inc.
+   2009, 2010, 2011 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -51,6 +51,7 @@ struct wincaps
   unsigned has_mwmo_inputavailable                     : 1;
   unsigned has_buggy_thread_startup                    : 1;
   unsigned has_fast_cwd                                        : 1;
+  unsigned has_restricted_raw_disk_access              : 1;
 };
 
 class wincapc
@@ -107,6 +108,7 @@ public:
   bool IMPLEMENT (has_mwmo_inputavailable)
   bool IMPLEMENT (has_buggy_thread_startup)
   bool IMPLEMENT (has_fast_cwd)
+  bool IMPLEMENT (has_restricted_raw_disk_access)
 
 #undef IMPLEMENT
 };
This page took 0.042771 seconds and 5 git commands to generate.