* 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:
parent
a5f316d8cf
commit
5b312b4747
|
@ -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.
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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 *) {}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
|
Loading…
Reference in New Issue