* autoload.cc: Add load statement for `NtOpenFile'.

* fhandler.h (fhandler_dev_raw::get_unit): New method.
	(fhandler_dev_tape::norewind): Eliminate.
	(fhandler_dev_tape::is_rewind_device): New method.
	* fhandler_raw.cc (fhandler_dev_raw::open): Open new
	fixed device name devices using NT internal method.
	Keep calling fhandler_base::open() for old mount table
	device mapping compatibility devices.
	(fhandler_dev_raw::fstat): Eliminate.  Settings are done
	by fhandler_base::fstat() already.
	* fhandler_tape.cc: Remove `norewind' usage throughout.
	* ntdll.h: Define FILE_SYNCHRONOUS_IO_NONALERT.
	Define struct _IO_STATUS_BLOCK.
	Declare NtOpenFile().
	* path.cc (get_raw_device_number): Add new approach for
	using fixed device names.
	(win32_device_name): Ditto.
	(get_device_number): Ditto.  Require POSIX path to begin
	with "/dev/".
	(mount_info::conv_to_win32_path): Call win32_device_name()
	instead of get_device_number() after evaluating mount points
	to allow changing the win32 destination path again.
	* security.cc (str2buf2uni): Remove `static' to be able to
	call function from fhandler_dev_raw::open().
	* wincap.cc: Set flag has_raw_devices appropriately.
	* wincap.h: Add flag has_raw_devices.
This commit is contained in:
Corinna Vinschen 2001-10-16 14:53:26 +00:00
parent 2ac3bab68d
commit 990690655c
10 changed files with 253 additions and 60 deletions

View File

@ -1,3 +1,32 @@
2001-10-16 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc: Add load statement for `NtOpenFile'.
* fhandler.h (fhandler_dev_raw::get_unit): New method.
(fhandler_dev_tape::norewind): Eliminate.
(fhandler_dev_tape::is_rewind_device): New method.
* fhandler_raw.cc (fhandler_dev_raw::open): Open new
fixed device name devices using NT internal method.
Keep calling fhandler_base::open() for old mount table
device mapping compatibility devices.
(fhandler_dev_raw::fstat): Eliminate. Settings are done
by fhandler_base::fstat() already.
* fhandler_tape.cc: Remove `norewind' usage throughout.
* ntdll.h: Define FILE_SYNCHRONOUS_IO_NONALERT.
Define struct _IO_STATUS_BLOCK.
Declare NtOpenFile().
* path.cc (get_raw_device_number): Add new approach for
using fixed device names.
(win32_device_name): Ditto.
(get_device_number): Ditto. Require POSIX path to begin
with "/dev/".
(mount_info::conv_to_win32_path): Call win32_device_name()
instead of get_device_number() after evaluating mount points
to allow changing the win32 destination path again.
* security.cc (str2buf2uni): Remove `static' to be able to
call function from fhandler_dev_raw::open().
* wincap.cc: Set flag has_raw_devices appropriately.
* wincap.h: Add flag has_raw_devices.
2001-10-16 Christopher Faylor <cgf@redhat.com>
* cygheap.h (cygheap_fdget::cygheap_fdget): Remove debugging operation

View File

@ -373,6 +373,7 @@ LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)

View File

@ -476,14 +476,14 @@ protected:
public:
~fhandler_dev_raw (void);
int get_unit () { return unit; }
int open (path_conv *, int flags, mode_t mode = 0);
int close (void);
int raw_read (void *ptr, size_t ulen);
int raw_write (const void *ptr, size_t ulen);
int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (2)));
int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *buf);
@ -511,9 +511,10 @@ public:
class fhandler_dev_tape: public fhandler_dev_raw
{
int norewind;
int lasterr;
bool is_rewind_device () { return get_unit () < 128; }
protected:
virtual void clear (void);

View File

@ -16,6 +16,7 @@
#include <cygwin/rdevio.h>
#include <sys/mtio.h>
#include <ntdef.h>
#include "cygerrno.h"
#include "perprocess.h"
#include "security.h"
@ -23,6 +24,7 @@
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
/* static wrapper functions to hide the effect of media changes and
bus resets which occurs after a new media is inserted. This is
@ -132,22 +134,69 @@ fhandler_dev_raw::~fhandler_dev_raw (void)
}
int
fhandler_dev_raw::open (path_conv *, int flags, mode_t)
fhandler_dev_raw::open (path_conv *real_path, int flags, mode_t)
{
int ret;
if (!wincap.has_raw_devices ())
{
set_errno (ENOENT);
debug_printf("%s is accessible under NT/W2K only",real_path->get_win32());
return 0;
}
/* Check for illegal flags. */
if (flags & (O_APPEND | O_EXCL))
{
set_errno (EINVAL);
return 0;
}
/* Always open a raw device existing and binary. */
flags &= ~(O_CREAT | O_TRUNC);
flags |= O_BINARY;
ret = fhandler_base::open (NULL, flags);
if (ret)
if (get_device () == FH_FLOPPY && get_unit () >= 224)
{
if (devbufsiz > 1L)
devbuf = new char [devbufsiz];
/* Compatibility mode for old mount table device mapping. */
if (!fhandler_base::open (real_path, flags))
return 0;
}
else
devbufsiz = 0;
return ret;
{
DWORD access = GENERIC_READ | SYNCHRONIZE;
if (get_device () == FH_TAPE
|| (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY
|| (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDWR)
access |= GENERIC_WRITE;
extern void str2buf2uni (UNICODE_STRING &, WCHAR *, const char *);
UNICODE_STRING dev;
WCHAR devname[MAX_PATH + 1];
str2buf2uni (dev, devname, real_path->get_win32 ());
OBJECT_ATTRIBUTES attr;
InitializeObjectAttributes(&attr, &dev, OBJ_CASE_INSENSITIVE, NULL, NULL);
HANDLE h;
IO_STATUS_BLOCK io;
NTSTATUS status = NtOpenFile (&h, access, &attr, &io, wincap.shared (),
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (status))
{
set_errno (RtlNtStatusToDosError (status));
debug_printf ("NtOpenFile: NTSTATUS: %d, Win32: %E", status);
return 0;
}
set_io_handle (h);
set_flags (flags);
}
set_r_binary (O_BINARY);
set_w_binary (O_BINARY);
if (devbufsiz > 1L)
devbuf = new char [devbufsiz];
return 1;
}
int
@ -156,15 +205,6 @@ fhandler_dev_raw::close (void)
return fhandler_base::close ();
}
int
fhandler_dev_raw::fstat (struct stat *buf, path_conv *pc)
{
this->fhandler_base::fstat (buf, pc);
buf->st_blksize = devbuf ? devbufsiz : 1;
return 0;
}
int
fhandler_dev_raw::raw_read (void *ptr, size_t ulen)
{

View File

@ -29,7 +29,6 @@ details. */
void
fhandler_dev_tape::clear (void)
{
norewind = 0;
lasterr = 0;
fhandler_dev_raw::clear ();
}
@ -66,7 +65,6 @@ fhandler_dev_tape::open (path_conv *real_path, int flags, mode_t)
{
int ret;
norewind = (real_path->get_unitn () >= 128);
devbufsiz = 1L;
ret = fhandler_dev_raw::open (real_path, flags);
@ -132,7 +130,7 @@ fhandler_dev_tape::close (void)
// To protected reads on signaling (e.g. Ctrl-C)
eof_detected = 1;
if (! norewind)
if (is_rewind_device ())
{
debug_printf ("rewinding\n");
op.mt_op = MTREW;
@ -153,7 +151,7 @@ fhandler_dev_tape::fstat (struct stat *buf, path_conv *pc)
{
int ret;
if (!(ret = fhandler_dev_raw::fstat (buf, pc)))
if (!(ret = fhandler_base::fstat (buf, pc)))
{
struct mtget get;
@ -227,7 +225,6 @@ fhandler_dev_tape::dup (fhandler_base *child)
{
fhandler_dev_tape *fhc = (fhandler_dev_tape *) child;
fhc->norewind = norewind;
fhc->lasterr = lasterr;
return fhandler_dev_raw::dup (child);
}

View File

@ -9,6 +9,7 @@
details. */
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
#define FILE_SYNCHRONOUS_IO_NONALERT 32
typedef enum _SYSTEM_INFORMATION_CLASS
{
@ -132,6 +133,12 @@ typedef struct _SYSTEM_PROCESSES
SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
typedef struct _IO_STATUS_BLOCK
{
NTSTATUS Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
/* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */
extern "C"
@ -144,6 +151,8 @@ extern "C"
NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
PLARGE_INTEGER, PULONG, SECTION_INHERIT,
ULONG, ULONG);
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
PVOID, ULONG, PULONG);

View File

@ -854,31 +854,112 @@ get_devn (const char *name, int &unit)
return devn;
}
/*
major minor POSIX filename NT filename
----- ----- -------------- -------------------------
FH_TAPE 0 /dev/st0 \device\tape0
FH_TAPE 1 /dev/st1 \device\tape1
...
FH_TAPE 128 /dev/nst0 \device\tape0
FH_TAPE 129 /dev/nst1 \device\tape1
...
FH_FLOPPY 0 /dev/fd0 \device\floppy0
FH_FLOPPY 1 /dev/fd1 \device\floppy1
...
FH_FLOPPY 16 /dev/scd0 \device\cdrom0
FH_FLOPPY 17 /dev/scd0 \device\cdrom1
...
FH_FLOPPY 32 /dev/sda \device\harddisk0\partition0
FH_FLOPPY 33 /dev/sda1 \device\harddisk0\partition1
...
FH_FLOPPY 47 /dev/sda15 \device\harddisk0\partition15
FH_FLOPPY 48 /dev/sdb \device\harddisk1\partition0
FH_FLOPPY 33 /dev/sdb1 \device\harddisk1\partition1
...
FH_FLOPPY 208 /dev/sdl \device\harddisk11\partition0
...
FH_FLOPPY 223 /dev/sdl15 \device\harddisk11\partition15
The following are needed to maintain backward compatibility with
the old Win32 partitioning scheme on W2K/XP.
FH_FLOPPY 224 from mount tab \\.\A:
...
FH_FLOPPY 250 from mount tab \\.\Z:
*/
static int
get_raw_device_number (const char *unix_path, const char *w32_path, int &unit)
get_raw_device_number (const char *name, const char *w32_path, int &unit)
{
int devn;
w32_path += 4;
if (wdeveqn ("tape", 4))
DWORD devn = FH_BAD;
if (!w32_path) /* New approach using fixed device names. */
{
unit = digits (w32_path + 4);
// norewind tape devices have leading n in name
if (udeveqn ("/dev/n", 6))
unit += 128;
devn = FH_TAPE;
if (deveqn ("st", 2))
{
unit = digits (name + 2);
if (unit >= 0 && unit < 128)
devn = FH_TAPE;
}
else if (deveqn ("nst", 3))
{
unit = digits (name + 3) + 128;
if (unit >= 128 && unit < 256)
devn = FH_TAPE;
}
else if (deveqn ("fd", 2))
{
unit = digits (name + 2);
if (unit >= 0 && unit < 16)
devn = FH_FLOPPY;
}
else if (deveqn ("scd", 3))
{
unit = digits (name + 3) + 16;
if (unit >= 16 && unit < 32)
devn = FH_FLOPPY;
}
else if (deveqn ("sd", 2) && isalpha (name[2]))
{
unit = (cyg_tolower (name[2]) - 'a') * 16 + 32;
if (unit >= 32 && unit < 224)
if (!name[3])
devn = FH_FLOPPY;
else
{
int d = digits (name + 3);
if (d >= 1 && d < 16)
{
unit += d;
devn = FH_FLOPPY;
}
}
}
}
else if (isdrive (w32_path))
else /* Backward compatible checking of mount table device mapping. */
{
unit = cyg_tolower (w32_path[0]) - 'a';
devn = FH_FLOPPY;
if (wdeveqn ("tape", 4))
{
unit = digits (w32_path + 4);
/* Norewind tape devices have leading n in name. */
if (deveqn ("n", 1))
unit += 128;
devn = FH_TAPE;
}
else if (wdeveqn ("physicaldrive", 13))
{
unit = digits (w32_path + 13) * 16 + 32;
devn = FH_FLOPPY;
}
else if (isdrive (w32_path))
{
unit = cyg_tolower (w32_path[0]) - 'a' + 224;
devn = FH_FLOPPY;
}
}
else if (wdeveqn ("physicaldrive", 13))
{
unit = digits (w32_path + 13) + 128;
devn = FH_FLOPPY;
}
else
devn = FH_BAD;
return devn;
}
@ -892,15 +973,18 @@ get_device_number (const char *unix_path, const char *w32_path, int &unit)
unit = 0;
if (*unix_path == '/' && udeveqn ("/dev/", 5))
devn = get_devn (unix_path, unit);
if (devn == FH_BAD && *w32_path == '\\' && wdeveqn ("\\dev\\", 5))
devn = get_devn (w32_path, unit);
if (devn == FH_BAD && udeveqn ("com", 3)
&& (unit = digits (unix_path + 3)) >= 0)
devn = FH_SERIAL;
else if (strncmp (w32_path, "\\\\.\\", 4) == 0)
devn = get_raw_device_number (unix_path, w32_path, unit);
{
devn = get_devn (unix_path, unit);
if (devn == FH_BAD && *w32_path == '\\' && wdeveqn ("\\dev\\", 5))
devn = get_devn (w32_path, unit);
if (devn == FH_BAD && udeveqn ("com", 3)
&& (unit = digits (unix_path + 3)) >= 0)
devn = FH_SERIAL;
if (devn == FH_BAD && wdeveqn ("\\\\.\\", 4))
devn = get_raw_device_number (unix_path + 5, w32_path + 4, unit);
if (devn == FH_BAD)
devn = get_raw_device_number (unix_path + 5, NULL, unit);
}
return devn;
}
@ -913,17 +997,36 @@ win32_device_name (const char *src_path, char *win32_path,
{
const char *devfmt;
devn = get_device_number (src_path, "", unit);
devn = get_device_number (src_path, win32_path, unit);
if (devn == FH_BAD)
return FALSE;
if ((devfmt = windows_device_names[FHDEVN (devn)]) == NULL)
return FALSE;
if (devn == FH_RANDOM)
__small_sprintf (win32_path, devfmt, unit == 8 ? "" : "u");
else
__small_sprintf (win32_path, devfmt, unit);
switch (devn)
{
case FH_RANDOM:
__small_sprintf (win32_path, devfmt, unit == 8 ? "" : "u");
break;
case FH_TAPE:
__small_sprintf (win32_path, "\\device\\tape%d", unit % 128);
break;
case FH_FLOPPY:
if (unit < 16)
__small_sprintf (win32_path, "\\device\\floppy%d", unit);
else if (unit < 32)
__small_sprintf (win32_path, "\\device\\cdrom%d", unit - 16);
else if (unit < 224)
__small_sprintf (win32_path, "\\device\\harddisk%d\\partition%d",
(unit - 32) / 16, unit % 16);
else
__small_sprintf (win32_path, "\\\\.\\%c:", unit - 224 + 'A');
break;
default:
__small_sprintf (win32_path, devfmt, unit);
break;
}
return TRUE;
}
@ -1335,7 +1438,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
*flags = mi->flags;
}
devn = get_device_number (src_path, dst, unit);
win32_device_name (src_path, dst, devn, unit);
out:
MALLOC_CHECK;

View File

@ -157,7 +157,7 @@ str2buf2lsa (LSA_STRING &tgt, char *buf, const char *srcstr)
memcpy(buf, srcstr, tgt.MaximumLength);
}
static void
void
str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
{
tgt.Length = strlen (srcstr) * sizeof (WCHAR);

View File

@ -43,6 +43,7 @@ static NO_COPY wincaps wincap_unknown = {
has_negative_pids:false,
has_unreliable_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:false,
};
@ -78,6 +79,7 @@ static NO_COPY wincaps wincap_95 = {
has_negative_pids:true,
has_unreliable_pipes:true,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:false,
};
@ -113,6 +115,7 @@ static NO_COPY wincaps wincap_95osr2 = {
has_negative_pids:true,
has_unreliable_pipes:true,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:false,
};
@ -148,6 +151,7 @@ static NO_COPY wincaps wincap_98 = {
has_negative_pids:true,
has_unreliable_pipes:true,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:true,
};
@ -183,6 +187,7 @@ static NO_COPY wincaps wincap_98se = {
has_negative_pids:true,
has_unreliable_pipes:true,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:true,
};
@ -218,6 +223,7 @@ static NO_COPY wincaps wincap_me = {
has_negative_pids:true,
has_unreliable_pipes:true,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:true,
};
@ -253,6 +259,7 @@ static NO_COPY wincaps wincap_nt3 = {
has_negative_pids:false,
has_unreliable_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:true,
has_valid_processorlevel:true,
};
@ -288,6 +295,7 @@ static NO_COPY wincaps wincap_nt4 = {
has_negative_pids:false,
has_unreliable_pipes:false,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
};
@ -323,6 +331,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_negative_pids:false,
has_unreliable_pipes:false,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
};
@ -358,6 +367,7 @@ static NO_COPY wincaps wincap_2000 = {
has_negative_pids:false,
has_unreliable_pipes:false,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
};
@ -393,6 +403,7 @@ static NO_COPY wincaps wincap_xp = {
has_negative_pids:false,
has_unreliable_pipes:false,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
};

View File

@ -44,6 +44,7 @@ struct wincaps
unsigned has_negative_pids : 1;
unsigned has_unreliable_pipes : 1;
unsigned has_try_enter_critical_section : 1;
unsigned has_raw_devices : 1;
unsigned has_valid_processorlevel : 1;
};
@ -93,6 +94,7 @@ public:
bool IMPLEMENT (has_negative_pids)
bool IMPLEMENT (has_unreliable_pipes)
bool IMPLEMENT (has_try_enter_critical_section)
bool IMPLEMENT (has_raw_devices)
bool IMPLEMENT (has_valid_processorlevel)
#undef IMPLEMENT