* 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.
This commit is contained in:
parent
5837aa428f
commit
95a5c969ab
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ());
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue