* devices.in (dev_cygdrive_storage): Revert mapping to \Device\Null.

(dev_storage): Ditto for /dev.
	* devices.cc: Regenerate.
	* fhandler.cc (fhandler_base::open_null): New method to open a fake
	\Device\Null handler.
	(fhandler_base::open): Fix formatting.  Change O_ACCMODE test to a
	switch statement.  Simplify a test which still tested for a now unused
	create_disposition.
	* fhandler.h (fhandler_base::open_null): Declare.
	(fhandler_netdrive::close): Declare.
	* fhandler_dev.cc (fhandler_dev::open): Open fake \Device\Null handle
	by just calling new open_null method.
	* fhandler_disk_file.cc (fhandler_cygdrive::open): Ditto.
	* fhandler_netdrive.cc (fhandler_netdrive::open): Call open_null
	rather than setting nohandle.
	(fhandler_netdrive::close): New method.
	* fhandler_registry.cc (fetch_hkey): Fix token in RegOpenUserClassesRoot
	call.  Create valid key for HKEY_CURRENT_CONFIG by mapping to real key
	HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current.
	(fhandler_registry::open): Set nohandle only when using pseudo registry
	handle.
	* fhandler_virtual.cc (fhandler_virtual::opendir): Call open rather
	than just setting nohandle here.
	* fhandler_virtual::fstatvfs): Set ST_RDONLY fs flag.
	* globals.cc (ro_u_null): New readonly UNICODE_STRING for \Device\Null.
	* path.h (path_conv::set_path): Revert previous change caring for
	wide_path.
This commit is contained in:
Corinna Vinschen 2013-10-31 14:26:42 +00:00
parent a5f316d8cf
commit 5b312b4747
12 changed files with 138 additions and 79 deletions

View File

@ -1,3 +1,33 @@
2013-10-30 Corinna Vinschen <corinna@vinschen.de>
* devices.in (dev_cygdrive_storage): Revert mapping to \Device\Null.
(dev_storage): Ditto for /dev.
* devices.cc: Regenerate.
* fhandler.cc (fhandler_base::open_null): New method to open a fake
\Device\Null handler.
(fhandler_base::open): Fix formatting. Change O_ACCMODE test to a
switch statement. Simplify a test which still tested for a now unused
create_disposition.
* fhandler.h (fhandler_base::open_null): Declare.
(fhandler_netdrive::close): Declare.
* fhandler_dev.cc (fhandler_dev::open): Open fake \Device\Null handle
by just calling new open_null method.
* fhandler_disk_file.cc (fhandler_cygdrive::open): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::open): Call open_null
rather than setting nohandle.
(fhandler_netdrive::close): New method.
* fhandler_registry.cc (fetch_hkey): Fix token in RegOpenUserClassesRoot
call. Create valid key for HKEY_CURRENT_CONFIG by mapping to real key
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current.
(fhandler_registry::open): Set nohandle only when using pseudo registry
handle.
* fhandler_virtual.cc (fhandler_virtual::opendir): Call open rather
than just setting nohandle here.
* fhandler_virtual::fstatvfs): Set ST_RDONLY fs flag.
* globals.cc (ro_u_null): New readonly UNICODE_STRING for \Device\Null.
* path.h (path_conv::set_path): Revert previous change caring for
wide_path.
2013-10-30 Corinna Vinschen <corinna@vinschen.de>
* devices.in (dev_cygdrive_storage): Map to \Device\Null.

View File

@ -91,7 +91,7 @@ exists_pty (const device& dev)
}
const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
{"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
@ -141,7 +141,7 @@ const device dev_error_storage =
#define BRACK(x) {devn_int: x}
const _RDATA device dev_storage[] =
{
{"/dev", BRACK(FH_DEV), "\\Device\\Null", exists, S_IFDIR, false},
{"/dev", BRACK(FH_DEV), "", exists, S_IFDIR, false},
{"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/com1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1", exists_ntdev_silent, S_IFCHR, true},
{"/dev/com2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2", exists_ntdev_silent, S_IFCHR, true},

View File

@ -87,7 +87,7 @@ exists_pty (const device& dev)
}
const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
{"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
@ -140,7 +140,7 @@ const device dev_error_storage =
/* Internal devices below are prefixed with a ":". This moves them out of
the POSIX namespace. */
%%
"/dev", BRACK(FH_DEV), "\\Device\\Null", exists, S_IFDIR
"/dev", BRACK(FH_DEV), "", exists, S_IFDIR
"/dev/tty", BRACK(FH_TTY), "/dev/tty", exists, S_IFCHR
"/dev/pty%(0-63)d", BRACK(FHDEV(DEV_PTYS_MAJOR, {$1})), "/dev/pty{$1}", exists_pty, S_IFCHR, =ptys_dev
":ptym%(0-63)d", BRACK(FHDEV(DEV_PTYM_MAJOR, {$1})), "/dev/ptym{$1}", exists_internal, S_IFCHR, =ptym_dev

View File

@ -507,6 +507,38 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
return res;
}
/* Open a fake handle to \\Device\\Null. This is a helper function for
fhandlers which just need some handle to keep track of BSD flock locks. */
int
fhandler_base::open_null (int flags)
{
int res = 0;
HANDLE fh;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
NTSTATUS status;
InitializeObjectAttributes (&attr, &ro_u_null, OBJ_CASE_INSENSITIVE |
((flags & O_CLOEXEC) ? 0 : OBJ_INHERIT),
NULL, NULL);
status = NtCreateFile (&fh, GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto done;
}
set_io_handle (fh);
set_flags (flags, pc.binmode ());
res = 1;
set_open_status ();
done:
debug_printf ("%y = NtCreateFile (%p, ... %S ...)", status, fh, &ro_u_null);
syscall_printf ("%d = fhandler_base::open_null (%y)", res, flags);
return res;
}
/* Open system call handler function. */
int
fhandler_base::open (int flags, mode_t mode)
@ -529,38 +561,44 @@ fhandler_base::open (int flags, mode_t mode)
options = FILE_OPEN_FOR_BACKUP_INTENT;
switch (query_open ())
{
case query_read_control:
access = READ_CONTROL;
break;
case query_read_attributes:
access = READ_CONTROL | FILE_READ_ATTRIBUTES;
break;
case query_write_control:
access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
break;
case query_write_dac:
access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
break;
case query_write_attributes:
access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
break;
default:
if ((flags & O_ACCMODE) == O_RDONLY)
case query_read_control:
access = READ_CONTROL;
break;
case query_read_attributes:
access = READ_CONTROL | FILE_READ_ATTRIBUTES;
break;
case query_write_control:
access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
break;
case query_write_dac:
access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
break;
case query_write_attributes:
access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
break;
default:
switch (flags & O_ACCMODE)
{
case O_RDONLY:
access = GENERIC_READ;
else if ((flags & O_ACCMODE) == O_WRONLY)
break;
case O_WRONLY:
access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
else
break;
default:
access = GENERIC_READ | GENERIC_WRITE;
if (flags & O_SYNC)
options |= FILE_WRITE_THROUGH;
if (flags & O_DIRECT)
options |= FILE_NO_INTERMEDIATE_BUFFERING;
if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
{
options |= FILE_SYNCHRONOUS_IO_NONALERT;
access |= SYNCHRONIZE;
}
break;
break;
}
if (flags & O_SYNC)
options |= FILE_WRITE_THROUGH;
if (flags & O_DIRECT)
options |= FILE_NO_INTERMEDIATE_BUFFERING;
if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
{
options |= FILE_SYNCHRONOUS_IO_NONALERT;
access |= SYNCHRONIZE;
}
break;
}
/* Don't use the FILE_OVERWRITE{_IF} flags here. See below for an
@ -596,7 +634,7 @@ fhandler_base::open (int flags, mode_t mode)
and/or FILE_ATTRIBUTE_SYSTEM attribute set, NtCreateFile fails with
STATUS_ACCESS_DENIED. Per MSDN you have to create the file with the
same attributes as already specified for the file. */
if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
if (create_disposition == FILE_CREATE
&& has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
file_attributes |= pc.file_attributes ();

View File

@ -310,6 +310,7 @@ class fhandler_base
virtual bool need_fixup_before () const {return false;}
int open_with_arch (int, mode_t = 0);
int open_null (int flags);
virtual int open (int, mode_t);
virtual void open_setup (int flags);
void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); }
@ -1962,6 +1963,7 @@ class fhandler_netdrive: public fhandler_virtual
void rewinddir (DIR *);
int closedir (DIR *);
int open (int flags, mode_t mode = 0);
int close ();
int __reg2 fstat (struct stat *buf);
fhandler_netdrive (void *) {}

View File

@ -16,7 +16,6 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "devices.h"
#include "tls_pbuf.h"
#define _COMPILING_NEWLIB
#include <dirent.h>
@ -54,16 +53,9 @@ fhandler_dev::open (int flags, mode_t mode)
int ret = fhandler_disk_file::open (flags & ~O_CREAT, mode);
if (!ret)
{
/* Open a fake handle to \\Device\\Null */
ret = open_null (flags);
dir_exists = false;
/* Open a fake handle to \\Device\\Null, but revert to the old path
string afterwards, otherwise readdir will return with an EFAULT
when trying to fetch the inode number of ".." */
tmp_pathbuf tp;
char *orig_path = tp.c_get ();
stpcpy (orig_path, get_win32_name ());
pc.set_path (dev ().native);
ret = fhandler_base::open (flags, mode);
pc.set_path (orig_path);
}
return ret;
}

View File

@ -2384,16 +2384,8 @@ fhandler_cygdrive::open (int flags, mode_t mode)
set_errno (EISDIR);
return 0;
}
/* Open a fake handle to \\Device\\Null, but revert to the old path
string afterwards, otherwise readdir will return with an EFAULT
when trying to fetch the inode number of ".." */
tmp_pathbuf tp;
char *orig_path = tp.c_get ();
stpcpy (orig_path, get_win32_name ());
pc.set_path (dev ().native);
int ret = fhandler_base::open (flags, mode);
pc.set_path (orig_path);
return ret;
/* Open a fake handle to \\Device\\Null */
return open_null (flags);
}
void

View File

@ -295,30 +295,23 @@ fhandler_netdrive::closedir (DIR *dir)
int
fhandler_netdrive::open (int flags, mode_t mode)
{
int res = fhandler_virtual::open (flags, mode);
if (!res)
goto out;
nohandle (true);
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{
set_errno (EEXIST);
res = 0;
goto out;
return 0;
}
else if (flags & O_WRONLY)
if (flags & O_WRONLY)
{
set_errno (EISDIR);
res = 0;
goto out;
return 0;
}
res = 1;
set_flags ((flags & ~O_TEXT) | O_BINARY | O_DIROPEN);
set_open_status ();
out:
syscall_printf ("%d = fhandler_netdrive::open(%y, 0%o)", res, flags, mode);
return res;
/* Open a fake handle to \\Device\\Null */
return open_null (flags);
}
int
fhandler_netdrive::close ()
{
/* Skip fhandler_virtual::close, which is a no-op. */
return fhandler_base::close ();
}

View File

@ -87,7 +87,7 @@ fetch_hkey (int idx) /* idx *must* be valid */
if (registry_keys[idx] == HKEY_CLASSES_ROOT)
{
if (RegOpenUserClassesRoot (cygheap->user.issetuid ()
? cygheap->user.imp_token () : hProcImpToken,
? cygheap->user.imp_token () : hProcToken,
0, KEY_READ, &key) == ERROR_SUCCESS)
return key;
}
@ -96,6 +96,17 @@ fetch_hkey (int idx) /* idx *must* be valid */
if (RegOpenCurrentUser (KEY_READ, &key) == ERROR_SUCCESS)
return key;
}
else if (registry_keys[idx] == HKEY_CURRENT_CONFIG)
{
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Hardware Profiles\\Current",
0, KEY_READ, &key) == ERROR_SUCCESS)
return key;
}
/* Unfortunately there's no way to generate a valid OS registry key for
the other root keys. HKEY_USERS and HKEY_LOCAL_MACHINE are file
handles internally, HKEY_PERFORMANCE_DATA is just a bad hack and
no registry key at all. */
return registry_keys[idx];
}
@ -820,7 +831,8 @@ fhandler_registry::open (int flags, mode_t mode)
set_io_handle (fetch_hkey (i));
/* Marking as nohandle allows to call dup on pseudo registry
handles. */
nohandle (true);
if (get_handle () >= HKEY_CLASSES_ROOT)
nohandle (true);
flags |= O_DIROPEN;
goto success;
}

View File

@ -1,7 +1,7 @@
/* fhandler_virtual.cc: base fhandler class for virtual filesystems
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Red Hat, Inc.
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
2013 Red Hat, Inc.
This file is part of Cygwin.
@ -84,10 +84,9 @@ fhandler_virtual::opendir (int fd)
else
{
cygheap_fdnew cfd;
if (cfd >= 0)
if (cfd >= 0 && open (O_RDONLY, 0))
{
cfd = this;
cfd->nohandle (true);
dir->__d_fd = cfd;
dir->__fh = this;
res = dir;
@ -273,6 +272,7 @@ fhandler_virtual::fstatvfs (struct statvfs *sfs)
set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX;
return 0;
}

View File

@ -146,6 +146,7 @@ extern "C" {
extern UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
extern UNICODE_STRING _RDATA ro_u_null = _ROU (L"\\Device\\Null");
#undef _ROU
/* Cygwin properties are meant to be readonly data placed in the DLL, but

View File

@ -380,7 +380,6 @@ class path_conv
cfree (modifiable_path ());
char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7);
strcpy (new_path, p);
cfree_and_null (wide_path);
return path = new_path;
}
bool is_binary ();