ntdll: Use stack buffers to retrieve the drive info from mountmgr.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-09 10:17:50 +02:00
parent bc8d04d6a5
commit b14eee69c7
1 changed files with 18 additions and 56 deletions

View File

@ -1946,9 +1946,8 @@ static int find_dos_device( const char *path )
return -1; return -1;
} }
static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd ) static NTSTATUS get_mountmgr_fs_info( HANDLE handle, int fd, struct mountmgr_unix_drive *drive, ULONG size )
{ {
struct mountmgr_unix_drive *drive;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING string; UNICODE_STRING string;
char *unix_name; char *unix_name;
@ -1957,25 +1956,16 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
NTSTATUS status; NTSTATUS status;
int letter; int letter;
if (server_get_unix_name( handle, &unix_name )) if ((status = server_get_unix_name( handle, &unix_name ))) return status;
return NULL;
letter = find_dos_device( unix_name ); letter = find_dos_device( unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name ); RtlFreeHeap( GetProcessHeap(), 0, unix_name );
if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, 1024 )))
return NULL;
if (letter == -1) if (letter == -1)
{ {
struct stat st; struct stat st;
if (fstat( fd, &st ) == -1) fstat( fd, &st );
{
RtlFreeHeap( GetProcessHeap(), 0, drive );
return NULL;
}
drive->unix_dev = st.st_dev; drive->unix_dev = st.st_dev;
drive->letter = 0; drive->letter = 0;
} }
@ -1984,36 +1974,16 @@ static struct mountmgr_unix_drive *get_mountmgr_fs_info( HANDLE handle, int fd )
RtlInitUnicodeString( &string, MOUNTMGR_DEVICE_NAME ); RtlInitUnicodeString( &string, MOUNTMGR_DEVICE_NAME );
InitializeObjectAttributes( &attr, &string, 0, NULL, NULL ); InitializeObjectAttributes( &attr, &string, 0, NULL, NULL );
if (NtOpenFile( &mountmgr, GENERIC_READ | SYNCHRONIZE, &attr, &io, status = NtOpenFile( &mountmgr, GENERIC_READ | SYNCHRONIZE, &attr, &io,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT )) FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT );
{ if (status) return status;
RtlFreeHeap( GetProcessHeap(), 0, drive );
return NULL;
}
status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE,
drive, sizeof(*drive), drive, 1024 ); drive, sizeof(*drive), drive, size );
if (status == STATUS_BUFFER_OVERFLOW)
{
if (!(drive = RtlReAllocateHeap( GetProcessHeap(), 0, drive, drive->size )))
{
RtlFreeHeap( GetProcessHeap(), 0, drive );
NtClose( mountmgr );
return NULL;
}
status = NtDeviceIoControlFile( mountmgr, NULL, NULL, NULL, &io, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE,
drive, sizeof(*drive), drive, drive->size );
}
NtClose( mountmgr ); NtClose( mountmgr );
if (status == STATUS_BUFFER_OVERFLOW) status = STATUS_SUCCESS;
if (status) else if (status) WARN("failed to retrieve filesystem type from mountmgr, status %#x\n", status);
{ return status;
WARN("failed to retrieve filesystem type from mountmgr, status %#x\n", status);
RtlFreeHeap( GetProcessHeap(), 0, drive );
return NULL;
}
return drive;
} }
@ -4106,15 +4076,12 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = errno_to_status( errno ); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = errno_to_status( errno );
else else
{ {
struct mountmgr_unix_drive *drive; struct mountmgr_unix_drive drive;
FILE_ID_INFORMATION *info = ptr; FILE_ID_INFORMATION *info = ptr;
info->VolumeSerialNumber = 0; info->VolumeSerialNumber = 0;
if ((drive = get_mountmgr_fs_info( handle, fd ))) if (!(io->u.Status = get_mountmgr_fs_info( handle, fd, &drive, sizeof(drive) )))
{ info->VolumeSerialNumber = drive.serial;
info->VolumeSerialNumber = drive->serial;
RtlFreeHeap( GetProcessHeap(), 0, drive );
}
memset( &info->FileId, 0, sizeof(info->FileId) ); memset( &info->FileId, 0, sizeof(info->FileId) );
*(ULONGLONG *)&info->FileId = st.st_ino; *(ULONGLONG *)&info->FileId = st.st_ino;
} }
@ -6212,7 +6179,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
static const WCHAR udfW[] = {'U','D','F'}; static const WCHAR udfW[] = {'U','D','F'};
FILE_FS_ATTRIBUTE_INFORMATION *info = buffer; FILE_FS_ATTRIBUTE_INFORMATION *info = buffer;
struct mountmgr_unix_drive *drive; struct mountmgr_unix_drive drive;
enum mountmgr_fs_type fs_type = MOUNTMGR_FS_TYPE_NTFS; enum mountmgr_fs_type fs_type = MOUNTMGR_FS_TYPE_NTFS;
if (length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION)) if (length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
@ -6221,11 +6188,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
break; break;
} }
if ((drive = get_mountmgr_fs_info( handle, fd ))) if (!get_mountmgr_fs_info( handle, fd, &drive, sizeof(drive) )) fs_type = drive.fs_type;
{
fs_type = drive->fs_type;
RtlFreeHeap( GetProcessHeap(), 0, drive );
}
else else
{ {
struct statfs stfs; struct statfs stfs;
@ -6298,7 +6261,8 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
case FileFsVolumeInformation: case FileFsVolumeInformation:
{ {
FILE_FS_VOLUME_INFORMATION *info = buffer; FILE_FS_VOLUME_INFORMATION *info = buffer;
struct mountmgr_unix_drive *drive; ULONGLONG data[64];
struct mountmgr_unix_drive *drive = (struct mountmgr_unix_drive *)data;
const WCHAR *label; const WCHAR *label;
if (length < sizeof(FILE_FS_VOLUME_INFORMATION)) if (length < sizeof(FILE_FS_VOLUME_INFORMATION))
@ -6307,7 +6271,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
break; break;
} }
if (!(drive = get_mountmgr_fs_info( handle, fd ))) if (get_mountmgr_fs_info( handle, fd, drive, sizeof(data) ))
{ {
io->u.Status = STATUS_NOT_IMPLEMENTED; io->u.Status = STATUS_NOT_IMPLEMENTED;
break; break;
@ -6320,8 +6284,6 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, IO_STATUS_BLOCK *io
length - offsetof( FILE_FS_VOLUME_INFORMATION, VolumeLabel ) ); length - offsetof( FILE_FS_VOLUME_INFORMATION, VolumeLabel ) );
info->SupportsObjects = (drive->fs_type == MOUNTMGR_FS_TYPE_NTFS); info->SupportsObjects = (drive->fs_type == MOUNTMGR_FS_TYPE_NTFS);
memcpy( info->VolumeLabel, label, info->VolumeLabelLength ); memcpy( info->VolumeLabel, label, info->VolumeLabelLength );
RtlFreeHeap( GetProcessHeap(), 0, drive );
io->Information = offsetof( FILE_FS_VOLUME_INFORMATION, VolumeLabel ) + info->VolumeLabelLength; io->Information = offsetof( FILE_FS_VOLUME_INFORMATION, VolumeLabel ) + info->VolumeLabelLength;
io->u.Status = STATUS_SUCCESS; io->u.Status = STATUS_SUCCESS;
break; break;