mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:05:44 +00:00
- Use a simpler and more robust way to detect direct device opens and save it in a variable that's read when needed, instead of having multiple large code paths.
svn path=/trunk/; revision=22902
This commit is contained in:
parent
70cd383c59
commit
979b777dd5
1 changed files with 88 additions and 52 deletions
|
@ -30,7 +30,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
OUT PVOID *Object)
|
OUT PVOID *Object)
|
||||||
{
|
{
|
||||||
POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
|
POPEN_PACKET OpenPacket = (POPEN_PACKET)Context;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT OriginalDeviceObject = (PDEVICE_OBJECT)ParseObject, DeviceObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PVPB Vpb;
|
PVPB Vpb;
|
||||||
|
@ -38,6 +38,8 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
PEXTENDED_IO_STACK_LOCATION StackLoc;
|
PEXTENDED_IO_STACK_LOCATION StackLoc;
|
||||||
IO_SECURITY_CONTEXT SecurityContext;
|
IO_SECURITY_CONTEXT SecurityContext;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
BOOLEAN DirectOpen = FALSE;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
DPRINT("IopParseDevice:\n"
|
DPRINT("IopParseDevice:\n"
|
||||||
"DeviceObject : %p\n"
|
"DeviceObject : %p\n"
|
||||||
"RelatedFileObject : %p\n"
|
"RelatedFileObject : %p\n"
|
||||||
|
@ -53,6 +55,17 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
/* Validate the open packet */
|
/* Validate the open packet */
|
||||||
if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
|
if (!IopValidateOpenPacket(OpenPacket)) return STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
|
|
||||||
|
/* Check if we have a related file object */
|
||||||
|
if (OpenPacket->RelatedFileObject)
|
||||||
|
{
|
||||||
|
/* Use the related file object's device object */
|
||||||
|
OriginalDeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference the DO FIXME: Don't allow failure */
|
||||||
|
Status = IopReferenceDeviceObject(OriginalDeviceObject);
|
||||||
|
|
||||||
|
/* Map the generic mask and set the new mapping in the access state */
|
||||||
RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
|
RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
|
||||||
&IoFileObjectType->TypeInfo.GenericMapping);
|
&IoFileObjectType->TypeInfo.GenericMapping);
|
||||||
RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
|
RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
|
||||||
|
@ -60,10 +73,73 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
SeSetAccessStateGenericMapping(AccessState,
|
SeSetAccessStateGenericMapping(AccessState,
|
||||||
&IoFileObjectType->TypeInfo.GenericMapping);
|
&IoFileObjectType->TypeInfo.GenericMapping);
|
||||||
|
|
||||||
|
/* Check if this is a direct open */
|
||||||
|
if (!(RemainingName->Length) && !(OpenPacket->RelatedFileObject))
|
||||||
|
{
|
||||||
|
/* Remember this for later */
|
||||||
|
DirectOpen = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a related FO that wasn't a direct open */
|
||||||
|
if ((OpenPacket->RelatedFileObject) &&
|
||||||
|
!(OpenPacket->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))
|
||||||
|
{
|
||||||
|
/* The device object is the one we were given */
|
||||||
|
DeviceObject = OriginalDeviceObject;
|
||||||
|
|
||||||
|
/* Check if the related FO had a VPB */
|
||||||
|
if (OpenPacket->RelatedFileObject->Vpb)
|
||||||
|
{
|
||||||
|
/* Yes, remember it */
|
||||||
|
Vpb = OpenPacket->RelatedFileObject->Vpb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The device object is the one we were given */
|
||||||
|
DeviceObject = OriginalDeviceObject;
|
||||||
|
|
||||||
|
/* Check if it has a VPB */
|
||||||
|
if ((DeviceObject->Vpb) && !(DirectOpen))
|
||||||
|
{
|
||||||
|
/* Check if it's not already mounted */
|
||||||
|
if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
||||||
|
{
|
||||||
|
/* Mount the volume */
|
||||||
|
Status = IopMountVolume(DeviceObject,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
&Vpb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Couldn't mount, fail the lookup */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the VPB's device object */
|
||||||
|
DeviceObject = DeviceObject->Vpb->DeviceObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there's an attached device */
|
||||||
|
if (DeviceObject->AttachedDevice)
|
||||||
|
{
|
||||||
|
/* Get the attached device */
|
||||||
|
DeviceObject = IoGetAttachedDevice(DeviceObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the actual file object */
|
/* Create the actual file object */
|
||||||
Status = ObCreateObject(AccessMode,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
Attributes,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = ObCreateObject(KernelMode,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
NULL,
|
&ObjectAttributes,
|
||||||
AccessMode,
|
AccessMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(FILE_OBJECT),
|
sizeof(FILE_OBJECT),
|
||||||
|
@ -72,54 +148,8 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
(PVOID*)&FileObject);
|
(PVOID*)&FileObject);
|
||||||
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
|
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
|
||||||
|
|
||||||
/* Parent is a device object */
|
/* Create the name for the file object */
|
||||||
DeviceObject = IoGetAttachedDevice(ParseObject);
|
RtlCreateUnicodeString(&FileObject->FileName, RemainingName->Buffer);
|
||||||
|
|
||||||
/* Check if we don't have a remaining name */
|
|
||||||
if (!*RemainingName->Buffer)
|
|
||||||
{
|
|
||||||
/* Then this is a device */
|
|
||||||
FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Check if we don't have a related file object */
|
|
||||||
if (!OpenPacket->RelatedFileObject)
|
|
||||||
{
|
|
||||||
/* Check if it has a VPB */
|
|
||||||
if (DeviceObject->Vpb)
|
|
||||||
{
|
|
||||||
/* Check if it's not already mounted */
|
|
||||||
if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
|
|
||||||
{
|
|
||||||
/* Mount the volume */
|
|
||||||
Status = IopMountVolume(DeviceObject,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
&Vpb);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Couldn't mount, fail the lookup */
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the VPB's device object */
|
|
||||||
DeviceObject = DeviceObject->Vpb->DeviceObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise, this is an open */
|
|
||||||
FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
|
|
||||||
DeviceObject = OpenPacket->RelatedFileObject->DeviceObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the name for the file object */
|
|
||||||
RtlCreateUnicodeString(&FileObject->FileName, RemainingName->Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the device object and reference it */
|
/* Set the device object and reference it */
|
||||||
Status = IopReferenceDeviceObject(DeviceObject);
|
Status = IopReferenceDeviceObject(DeviceObject);
|
||||||
|
@ -127,6 +157,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
|
|
||||||
FileObject->Type = IO_TYPE_FILE;
|
FileObject->Type = IO_TYPE_FILE;
|
||||||
FileObject->Size = sizeof(FILE_OBJECT);
|
FileObject->Size = sizeof(FILE_OBJECT);
|
||||||
|
FileObject->RelatedFileObject = OpenPacket->RelatedFileObject;
|
||||||
|
|
||||||
if (OpenPacket->CreateOptions &
|
if (OpenPacket->CreateOptions &
|
||||||
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
|
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
|
||||||
|
@ -155,6 +186,11 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
FileObject->Flags |= FO_RANDOM_ACCESS;
|
FileObject->Flags |= FO_RANDOM_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DirectOpen)
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(Attributes & OBJ_CASE_INSENSITIVE))
|
if (!(Attributes & OBJ_CASE_INSENSITIVE))
|
||||||
{
|
{
|
||||||
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
||||||
|
@ -168,7 +204,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
|
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
|
||||||
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
if (!Irp) return STATUS_UNSUCCESSFUL;
|
if (!Irp) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/* Now set the IRP data */
|
/* Now set the IRP data */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue