mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-21 16:26:12 +08:00
* ntdll.h (STATUS_NO_SUCH_FILE): Define.
* path.cc (get_nt_native_path): Reset upath.Length to 0 on each invocation. (symlink_info::check): Use NT native functions.
This commit is contained in:
parent
e1e4b104b6
commit
a888c0799c
@ -1,3 +1,10 @@
|
|||||||
|
2007-08-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* ntdll.h (STATUS_NO_SUCH_FILE): Define.
|
||||||
|
* path.cc (get_nt_native_path): Reset upath.Length to 0 on each
|
||||||
|
invocation.
|
||||||
|
(symlink_info::check): Use NT native functions.
|
||||||
|
|
||||||
2007-08-21 Corinna Vinschen <corinna@vinschen.de>
|
2007-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* uinfo.cc (pwdgrp::load): Use NT native functions.
|
* uinfo.cc (pwdgrp::load): Use NT native functions.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
|
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
|
||||||
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d)
|
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d)
|
||||||
|
#define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xc000000f)
|
||||||
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xc0000010)
|
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xc0000010)
|
||||||
#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013)
|
#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013)
|
||||||
#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022)
|
#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022)
|
||||||
|
@ -545,6 +545,7 @@ path_conv::set_normalized_path (const char *path_copy, bool strip_tail)
|
|||||||
PUNICODE_STRING
|
PUNICODE_STRING
|
||||||
get_nt_native_path (const char *path, UNICODE_STRING &upath)
|
get_nt_native_path (const char *path, UNICODE_STRING &upath)
|
||||||
{
|
{
|
||||||
|
upath.Length = 0;
|
||||||
if (path[0] == '/') /* special path w/o NT path representation. */
|
if (path[0] == '/') /* special path w/o NT path representation. */
|
||||||
str2uni_cat (upath, path);
|
str2uni_cat (upath, path);
|
||||||
else if (path[0] != '\\') /* X:\... or NUL, etc. */
|
else if (path[0] != '\\') /* X:\... or NUL, etc. */
|
||||||
@ -3511,47 +3512,91 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
|
|||||||
pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP);
|
pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP);
|
||||||
case_clash = false;
|
case_clash = false;
|
||||||
|
|
||||||
|
/* TODO: Temporarily do all char->UNICODE conversion here. This should
|
||||||
|
already be slightly faster than using Ascii functions. */
|
||||||
|
UNICODE_STRING upath;
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
size_t len = (strlen (path) + 8 + 8 + 1) * sizeof (WCHAR);
|
||||||
|
RtlInitEmptyUnicodeString (&upath, (PCWSTR) alloca (len), len);
|
||||||
|
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
|
||||||
while (suffix.next ())
|
while (suffix.next ())
|
||||||
{
|
{
|
||||||
error = 0;
|
FILE_BASIC_INFORMATION fbi;
|
||||||
fileattr = GetFileAttributes (suffix.path);
|
NTSTATUS status;
|
||||||
if (fileattr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
{
|
|
||||||
/* The GetFileAttributes call can fail for reasons that don't
|
|
||||||
matter, so we just return 0. For example, getting the
|
|
||||||
attributes of \\HOST will typically fail. */
|
|
||||||
debug_printf ("GetFileAttributes (%s) failed", suffix.path);
|
|
||||||
|
|
||||||
/* The above comment is not *quite* right. When calling
|
error = 0;
|
||||||
GetFileAttributes for a non-existant file an a Win9x share,
|
get_nt_native_path (suffix.path, upath);
|
||||||
GetLastError returns ERROR_INVALID_FUNCTION. Go figure!
|
status = NtQueryAttributesFile (&attr, &fbi);
|
||||||
Also, GetFileAttributes fails with ERROR_SHARING_VIOLATION
|
if (NT_SUCCESS (status))
|
||||||
if the file is locked exclusively by another process, or with
|
fileattr = fbi.FileAttributes;
|
||||||
ERROR_ACCESS_DENIED if the file exists but the user has no right
|
else
|
||||||
to open the file with FILE_READ_ATTRIBUTES.
|
{
|
||||||
If we don't special handle this here, the file is accidentally
|
debug_printf ("%p = NtQueryAttributesFile (%S)", status, &upath);
|
||||||
treated as non-existant. */
|
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||||
DWORD win_error = GetLastError ();
|
|
||||||
if (win_error == ERROR_INVALID_FUNCTION)
|
/* One of the inner path components is invalid. Bail out. */
|
||||||
win_error = ERROR_FILE_NOT_FOUND;
|
if (status == STATUS_OBJECT_PATH_NOT_FOUND)
|
||||||
else if (win_error == ERROR_SHARING_VIOLATION
|
|
||||||
|| win_error == ERROR_ACCESS_DENIED)
|
|
||||||
{
|
{
|
||||||
/* This is easily converted to NT functions at one point,
|
set_error (ENOENT);
|
||||||
see fhandler_base::fstat_by_name. */
|
break;
|
||||||
WIN32_FIND_DATA data;
|
}
|
||||||
HANDLE f = FindFirstFile (suffix.path, &data);
|
if (status != STATUS_OBJECT_NAME_NOT_FOUND
|
||||||
if (f != INVALID_HANDLE_VALUE)
|
&& status != STATUS_NO_SUCH_FILE) /* File not found on 9x share */
|
||||||
{
|
{
|
||||||
FindClose (f);
|
/* The file exists, but the user can't access it for one reason
|
||||||
fileattr = data.dwFileAttributes;
|
or the other. To get the file attributes we try to access the
|
||||||
|
information by opening the parent directory and getting the
|
||||||
|
file attributes using a matching NtQueryDirectoryFile call. */
|
||||||
|
UNICODE_STRING dirname, basename;
|
||||||
|
OBJECT_ATTRIBUTES dattr;
|
||||||
|
HANDLE dir;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
FILE_DIRECTORY_INFORMATION fdi;
|
||||||
|
|
||||||
|
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
||||||
|
InitializeObjectAttributes (&dattr, &dirname,
|
||||||
|
OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
|
&dattr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT
|
||||||
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
||||||
|
| FILE_DIRECTORY_FILE);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
debug_printf ("%p = NtOpenFile(%S)", status, &dirname);
|
||||||
|
fileattr = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fileattr = 0;
|
{
|
||||||
|
status = NtQueryDirectoryFile (dir, NULL, NULL, 0, &io,
|
||||||
|
&fdi, sizeof fdi,
|
||||||
|
FileDirectoryInformation,
|
||||||
|
TRUE, &basename, TRUE);
|
||||||
|
NtClose (dir);
|
||||||
|
/* Per MSDN, ZwQueryDirectoryFile allows to specify a buffer
|
||||||
|
which only fits the static parts of the structure (without
|
||||||
|
filename that is) in the first call. The buffer actually
|
||||||
|
contains valid data, even though ZwQueryDirectoryFile
|
||||||
|
returned STATUS_BUFFER_OVERFLOW.
|
||||||
|
|
||||||
|
Please note that this doesn't work for the info class
|
||||||
|
FileIdBothDirectoryInformation, unfortunately, so we don't
|
||||||
|
use this technique in fhandler_base::fstat_by_name, */
|
||||||
|
if (!NT_SUCCESS (status) && status != STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
debug_printf ("%p = NtQueryDirectoryFile(%S)",
|
||||||
|
status, &dirname);
|
||||||
|
fileattr = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fileattr = fdi.FileAttributes;
|
||||||
|
}
|
||||||
ext_tacked_on = !!*ext_here;
|
ext_tacked_on = !!*ext_here;
|
||||||
goto file_not_symlink;
|
goto file_not_symlink;
|
||||||
}
|
}
|
||||||
if (set_error (geterrno_from_win_error (win_error, EACCES)))
|
if (set_error (geterrno_from_win_error
|
||||||
|
(RtlNtStatusToDosError (status), EACCES)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user