diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 8f0398b4ad9..18a9b2de506 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -1299,6 +1299,13 @@ IopGetFileInformation( OUT PULONG ReturnedLength ); +BOOLEAN +NTAPI +IopVerifyDeviceObjectOnStack( + IN PDEVICE_OBJECT BaseDeviceObject, + IN PDEVICE_OBJECT TopDeviceObjectHint +); + // // I/O Timer Routines // diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c index a8da317317e..c14e61806ba 100644 --- a/ntoskrnl/io/iomgr/file.c +++ b/ntoskrnl/io/iomgr/file.c @@ -266,6 +266,54 @@ IopDoNameTransmogrify(IN PIRP Irp, ExFreePool(DataBuffer); } +NTSTATUS +IopCheckTopDeviceHint(IN OUT PDEVICE_OBJECT * DeviceObject, + IN POPEN_PACKET OpenPacket, + BOOLEAN DirectOpen) +{ + PDEVICE_OBJECT LocalDevice; + DEVICE_TYPE DeviceType; + + LocalDevice = *DeviceObject; + + /* Direct open is not allowed */ + if (DirectOpen) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validate we have a file system device */ + DeviceType = LocalDevice->DeviceType; + if (DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM && + DeviceType != FILE_DEVICE_CD_ROM_FILE_SYSTEM && + DeviceType != FILE_DEVICE_TAPE_FILE_SYSTEM && + DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM && + DeviceType != FILE_DEVICE_DFS_FILE_SYSTEM) + { + return STATUS_INVALID_PARAMETER; + } + + /* Verify the hint and if it's OK, return it */ + if (IopVerifyDeviceObjectOnStack(LocalDevice, OpenPacket->TopDeviceObjectHint)) + { + *DeviceObject = OpenPacket->TopDeviceObjectHint; + return STATUS_SUCCESS; + } + + /* Failure case here */ + /* If we thought was had come through a mount point, + * actually update we didn't and return the error + */ + if (OpenPacket->TraversedMountPoint) + { + OpenPacket->TraversedMountPoint = FALSE; + return STATUS_MOUNT_POINT_NOT_RESOLVED; + } + + /* Otherwise, just return the fact the hint is invalid */ + return STATUS_INVALID_DEVICE_OBJECT_PARAMETER; +} + NTSTATUS NTAPI IopParseDevice(IN PVOID ParseObject,