* 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.
This commit is contained in:
parent
655639ba89
commit
ceaf31f416
@ -1,3 +1,12 @@
|
|||||||
|
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>
|
2007-07-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_disk_file.cc (is_volume_mountpoint): New static inline
|
* fhandler_disk_file.cc (is_volume_mountpoint): New static inline
|
||||||
|
@ -335,16 +335,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
|||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Split path in dirname and basename */
|
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &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);
|
|
||||||
InitializeObjectAttributes (&attr, &dirname, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &dirname, OBJ_CASE_INSENSITIVE,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (!NT_SUCCESS (status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
if (!NT_SUCCESS (status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
@ -627,46 +618,51 @@ fhandler_disk_file::fstat (struct __stat64 *buf)
|
|||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
||||||
{
|
{
|
||||||
int ret = -1, oret = 0;
|
int ret = -1, opened = 0;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
const size_t fvi_size = sizeof (FILE_FS_VOLUME_INFORMATION)
|
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)
|
PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION)
|
||||||
alloca (fvi_size);
|
alloca (fvi_size);
|
||||||
const size_t fai_size = sizeof (FILE_FS_ATTRIBUTE_INFORMATION)
|
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)
|
PFILE_FS_ATTRIBUTE_INFORMATION pfai = (PFILE_FS_ATTRIBUTE_INFORMATION)
|
||||||
alloca (fai_size);
|
alloca (fai_size);
|
||||||
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
|
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
|
||||||
FILE_FS_SIZE_INFORMATION fsi;
|
FILE_FS_SIZE_INFORMATION fsi;
|
||||||
|
HANDLE fh = get_handle ();
|
||||||
|
|
||||||
if (!get_io_handle ())
|
if (!fh)
|
||||||
{
|
{
|
||||||
query_open (query_read_control);
|
OBJECT_ATTRIBUTES attr;
|
||||||
oret = open_fs (O_RDONLY | O_BINARY, 0);
|
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL,
|
||||||
if (!oret)
|
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. */
|
/* Can't open file. Try again with parent dir. */
|
||||||
char root[CYG_MAX_PATH];
|
UNICODE_STRING dirname;
|
||||||
if (!rootdir (get_win32_name (), root))
|
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, NULL);
|
||||||
goto out;
|
attr.ObjectName = &dirname;
|
||||||
pc.check (root, PC_SYM_NOFOLLOW);
|
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, &attr, &io,
|
||||||
oret = open_fs (O_RDONLY | O_BINARY, 0);
|
FILE_SHARE_VALID_FLAGS,
|
||||||
if (!oret)
|
FILE_OPEN_FOR_BACKUP_INTENT));
|
||||||
|
if (!opened)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get basic volume information. */
|
/* Get basic volume information. */
|
||||||
status = NtQueryVolumeInformationFile (get_handle (), &io, pfvi, fvi_size,
|
status = NtQueryVolumeInformationFile (fh, &io, pfvi, fvi_size,
|
||||||
FileFsVolumeInformation);
|
FileFsVolumeInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
status = NtQueryVolumeInformationFile (get_handle (), &io, pfai, fai_size,
|
status = NtQueryVolumeInformationFile (fh, &io, pfai, fai_size,
|
||||||
FileFsAttributeInformation);
|
FileFsAttributeInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
@ -682,8 +678,7 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
/* Get allocation related information. Try to get "full" information
|
/* Get allocation related information. Try to get "full" information
|
||||||
first, which is only available since W2K. If that fails, try to
|
first, which is only available since W2K. If that fails, try to
|
||||||
retrieve normal allocation information. */
|
retrieve normal allocation information. */
|
||||||
status = NtQueryVolumeInformationFile (get_handle (), &io, &full_fsi,
|
status = NtQueryVolumeInformationFile (fh, &io, &full_fsi, sizeof full_fsi,
|
||||||
sizeof full_fsi,
|
|
||||||
FileFsFullSizeInformation);
|
FileFsFullSizeInformation);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
@ -696,11 +691,12 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
{
|
{
|
||||||
/* Quotas active. We can't trust TotalAllocationUnits. */
|
/* Quotas active. We can't trust TotalAllocationUnits. */
|
||||||
NTFS_VOLUME_DATA_BUFFER nvdb;
|
NTFS_VOLUME_DATA_BUFFER nvdb;
|
||||||
DWORD bytes;
|
|
||||||
|
|
||||||
if (!DeviceIoControl (get_handle (), FSCTL_GET_NTFS_VOLUME_DATA, NULL,
|
status = NtFsControlFile (fh, NULL, NULL, NULL, &io,
|
||||||
0, &nvdb, sizeof nvdb, &bytes, NULL))
|
FSCTL_GET_NTFS_VOLUME_DATA,
|
||||||
debug_printf ("DeviceIoControl (%s) failed, %E", get_name ());
|
NULL, 0, &nvdb, sizeof nvdb);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
debug_printf ("NtFsControlFile (%s) failed, status %lx", status);
|
||||||
else
|
else
|
||||||
sfs->f_blocks = nvdb.TotalClusters.QuadPart;
|
sfs->f_blocks = nvdb.TotalClusters.QuadPart;
|
||||||
}
|
}
|
||||||
@ -708,8 +704,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = NtQueryVolumeInformationFile (get_handle (), &io, &fsi,
|
status = NtQueryVolumeInformationFile (fh, &io, &fsi, sizeof fsi,
|
||||||
sizeof fsi, FileFsSizeInformation);
|
FileFsSizeInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
@ -723,8 +719,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (oret)
|
if (opened)
|
||||||
close_fs ();
|
NtClose (fh);
|
||||||
syscall_printf ("%d = fstatvfs (%s, %p)", ret, get_name (), sfs);
|
syscall_printf ("%d = fstatvfs (%s, %p)", ret, get_name (), sfs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -805,4 +805,18 @@ extern "C"
|
|||||||
dest->Length = dest->MaximumLength = len;
|
dest->Length = dest->MaximumLength = len;
|
||||||
dest->Buffer = (PWSTR) buf;
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user