[MOUNTMGR] Misc. fixes to QueryDeviceInformation:

- Simplify failure path for DeviceName query failure
- Don't make stable query failure fail the whole function call

Based on a patch by Vadim Galiant

CORE-15550
This commit is contained in:
Pierre Schweitzer 2019-01-20 17:32:48 +01:00
parent 3ae86a245d
commit 20ddde0a97
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -213,12 +213,12 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
PIRP Irp; PIRP Irp;
USHORT Size; USHORT Size;
KEVENT Event; KEVENT Event;
NTSTATUS Status;
BOOLEAN IsRemovable; BOOLEAN IsRemovable;
PMOUNTDEV_NAME Name; PMOUNTDEV_NAME Name;
PMOUNTDEV_UNIQUE_ID Id; PMOUNTDEV_UNIQUE_ID Id;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
NTSTATUS Status, IntStatus;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PARTITION_INFORMATION_EX PartitionInfo; PARTITION_INFORMATION_EX PartitionInfo;
@ -282,7 +282,7 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatusBlock.Status; Status = IoStatusBlock.Status;
} }
/* In case of failure, don't fail, that's no vital */ /* In case of failure, don't fail, that's no vital */
@ -329,7 +329,7 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatusBlock.Status; Status = IoStatusBlock.Status;
} }
/* Once again here, failure isn't major */ /* Once again here, failure isn't major */
@ -368,7 +368,7 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatusBlock.Status; Status = IoStatusBlock.Status;
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -470,32 +470,33 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
} }
} }
/* Here we can't fail and assume default value */ if (NT_SUCCESS(Status))
if (!NT_SUCCESS(Status))
{ {
FreePool(Name); /* Copy back found name to the caller */
ObDereferenceObject(DeviceObject); DeviceName->Length = Name->NameLength;
ObDereferenceObject(FileObject); DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
return Status; DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
if (!DeviceName->Buffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
}
} }
/* Copy back found name to the caller */
DeviceName->Length = Name->NameLength;
DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
if (!DeviceName->Buffer)
{
FreePool(Name);
ObDereferenceObject(DeviceObject);
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
FreePool(Name); FreePool(Name);
} }
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(DeviceObject);
ObDereferenceObject(FileObject);
return Status;
}
/* If caller wants device unique ID */ /* If caller wants device unique ID */
if (UniqueId) if (UniqueId)
{ {
@ -628,14 +629,14 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
Stack = IoGetNextIrpStackLocation(Irp); Stack = IoGetNextIrpStackLocation(Irp);
Stack->FileObject = FileObject; Stack->FileObject = FileObject;
Status = IoCallDriver(DeviceObject, Irp); IntStatus = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) if (IntStatus == STATUS_PENDING)
{ {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatusBlock.Status; IntStatus = IoStatusBlock.Status;
} }
*HasGuid = NT_SUCCESS(Status); *HasGuid = NT_SUCCESS(IntStatus);
} }
ObDereferenceObject(DeviceObject); ObDereferenceObject(DeviceObject);