diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-07-27 10:10:57 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-07-27 10:10:57 +0000 |
commit | ceaf31f416220413feedcad1cc3e9f30f57dc28f (patch) | |
tree | 6e99d0266682d6c637a9169194bba47bc8df0d06 /winsup/cygwin | |
parent | 655639ba89fd6f9ca760b052981394cca04e49c9 (diff) | |
download | newlib-ceaf31f416220413feedcad1cc3e9f30f57dc28f.zip newlib-ceaf31f416220413feedcad1cc3e9f30f57dc28f.tar.gz newlib-ceaf31f416220413feedcad1cc3e9f30f57dc28f.tar.bz2 |
* fhandler_disk_file.cc (fhandler_base::fstat_by_name): Use
RtlSplitUnicodePath.
(fhandler_disk_file::fstat): Rename oret to opened. Open file using NT
functions right here. Try to open parent dir instead of root directory
to avoid call to rootdir. Use NtFsControlFile.
* ntdll.h (RtlSplitUnicodePath): Define.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 9 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 68 | ||||
-rw-r--r-- | winsup/cygwin/ntdll.h | 14 |
3 files changed, 55 insertions, 36 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ca68bb8..e8574d5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,14 @@ 2007-07-27 Corinna Vinschen <corinna@vinschen.de> + * fhandler_disk_file.cc (fhandler_base::fstat_by_name): Use + RtlSplitUnicodePath. + (fhandler_disk_file::fstat): Rename oret to opened. Open file using NT + functions right here. Try to open parent dir instead of root directory + to avoid call to rootdir. Use NtFsControlFile. + * ntdll.h (RtlSplitUnicodePath): Define. + +2007-07-27 Corinna Vinschen <corinna@vinschen.de> + * fhandler_disk_file.cc (is_volume_mountpoint): New static inline function. (path_conv::ndisk_links): Call is_volume_mountpoint. diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index bebc225..9264285 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -335,16 +335,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf) set_errno (ENOENT); return -1; } - /* Split path in dirname and basename */ - dirname = *pc.get_nt_native_path (); - USHORT len = dirname.Length / sizeof (WCHAR); - while (len > 0 && dirname.Buffer[--len] != L'\\') - ; - ++len; - RtlInitCountedUnicodeString (&basename, - dirname.Length - len * sizeof (WCHAR), - &dirname.Buffer[len]); - dirname.Length = len * sizeof (WCHAR); + RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename); InitializeObjectAttributes (&attr, &dirname, OBJ_CASE_INSENSITIVE, NULL, NULL); if (!NT_SUCCESS (status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY, @@ -627,46 +618,51 @@ fhandler_disk_file::fstat (struct __stat64 *buf) int __stdcall fhandler_disk_file::fstatvfs (struct statvfs *sfs) { - int ret = -1, oret = 0; + int ret = -1, opened = 0; NTSTATUS status; IO_STATUS_BLOCK io; const size_t fvi_size = sizeof (FILE_FS_VOLUME_INFORMATION) - + 256 * sizeof (WCHAR); + + (NAME_MAX + 1) * sizeof (WCHAR); PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION) alloca (fvi_size); const size_t fai_size = sizeof (FILE_FS_ATTRIBUTE_INFORMATION) - + 256 * sizeof (WCHAR); + + (NAME_MAX + 1) * sizeof (WCHAR); PFILE_FS_ATTRIBUTE_INFORMATION pfai = (PFILE_FS_ATTRIBUTE_INFORMATION) alloca (fai_size); FILE_FS_FULL_SIZE_INFORMATION full_fsi; FILE_FS_SIZE_INFORMATION fsi; + HANDLE fh = get_handle (); - if (!get_io_handle ()) + if (!fh) { - query_open (query_read_control); - oret = open_fs (O_RDONLY | O_BINARY, 0); - if (!oret) + OBJECT_ATTRIBUTES attr; + opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, + pc.get_object_attr (attr, sec_none_nih), + &io, FILE_SHARE_VALID_FLAGS, + FILE_OPEN_FOR_BACKUP_INTENT)); + if (!opened) { - /* Can't open file. Try again with rootdir. */ - char root[CYG_MAX_PATH]; - if (!rootdir (get_win32_name (), root)) - goto out; - pc.check (root, PC_SYM_NOFOLLOW); - oret = open_fs (O_RDONLY | O_BINARY, 0); - if (!oret) + /* Can't open file. Try again with parent dir. */ + UNICODE_STRING dirname; + RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, NULL); + attr.ObjectName = &dirname; + opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, &attr, &io, + FILE_SHARE_VALID_FLAGS, + FILE_OPEN_FOR_BACKUP_INTENT)); + if (!opened) goto out; } } /* Get basic volume information. */ - status = NtQueryVolumeInformationFile (get_handle (), &io, pfvi, fvi_size, + status = NtQueryVolumeInformationFile (fh, &io, pfvi, fvi_size, FileFsVolumeInformation); if (!NT_SUCCESS (status)) { __seterrno_from_nt_status (status); goto out; } - status = NtQueryVolumeInformationFile (get_handle (), &io, pfai, fai_size, + status = NtQueryVolumeInformationFile (fh, &io, pfai, fai_size, FileFsAttributeInformation); if (!NT_SUCCESS (status)) { @@ -682,8 +678,7 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs) /* Get allocation related information. Try to get "full" information first, which is only available since W2K. If that fails, try to retrieve normal allocation information. */ - status = NtQueryVolumeInformationFile (get_handle (), &io, &full_fsi, - sizeof full_fsi, + status = NtQueryVolumeInformationFile (fh, &io, &full_fsi, sizeof full_fsi, FileFsFullSizeInformation); if (NT_SUCCESS (status)) { @@ -696,11 +691,12 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs) { /* Quotas active. We can't trust TotalAllocationUnits. */ NTFS_VOLUME_DATA_BUFFER nvdb; - DWORD bytes; - if (!DeviceIoControl (get_handle (), FSCTL_GET_NTFS_VOLUME_DATA, NULL, - 0, &nvdb, sizeof nvdb, &bytes, NULL)) - debug_printf ("DeviceIoControl (%s) failed, %E", get_name ()); + status = NtFsControlFile (fh, NULL, NULL, NULL, &io, + FSCTL_GET_NTFS_VOLUME_DATA, + NULL, 0, &nvdb, sizeof nvdb); + if (!NT_SUCCESS (status)) + debug_printf ("NtFsControlFile (%s) failed, status %lx", status); else sfs->f_blocks = nvdb.TotalClusters.QuadPart; } @@ -708,8 +704,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs) } else { - status = NtQueryVolumeInformationFile (get_handle (), &io, &fsi, - sizeof fsi, FileFsSizeInformation); + status = NtQueryVolumeInformationFile (fh, &io, &fsi, sizeof fsi, + FileFsSizeInformation); if (!NT_SUCCESS (status)) { __seterrno_from_nt_status (status); @@ -723,8 +719,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs) ret = 0; } out: - if (oret) - close_fs (); + if (opened) + NtClose (fh); syscall_printf ("%d = fstatvfs (%s, %p)", ret, get_name (), sfs); return ret; } diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index d3837bb..cb2cccf 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -805,4 +805,18 @@ extern "C" dest->Length = dest->MaximumLength = len; dest->Buffer = (PWSTR) buf; } + inline + VOID NTAPI RtlSplitUnicodePath (PUNICODE_STRING path, PUNICODE_STRING dir, + PUNICODE_STRING file) + { + USHORT len = path->Length / sizeof (WCHAR); + while (len > 0 && path->Buffer[--len] != L'\\') + ; + ++len; + if (dir) + RtlInitCountedUnicodeString (dir, len * sizeof (WCHAR), path->Buffer); + if (file) + RtlInitCountedUnicodeString (file, path->Length - len * sizeof (WCHAR), + &path->Buffer[len]); + } } |