mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:52:57 +00:00
- Move the code in IoCreateFile inside IopParseDevice where it belongs. Currently only a raw move and hacks to make it not regress anything, but in the future we can now finally start applying some important fixes for proper communication with FSDs and setting a myriad of flags and settings required. Will also allow for some nice optimizations in the future.
svn path=/trunk/; revision=22878
This commit is contained in:
parent
51cd8da6b7
commit
0f2c6e474b
1 changed files with 158 additions and 157 deletions
|
@ -34,6 +34,10 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PVPB Vpb;
|
PVPB Vpb;
|
||||||
|
PIRP Irp;
|
||||||
|
PEXTENDED_IO_STACK_LOCATION StackLoc;
|
||||||
|
IO_SECURITY_CONTEXT SecurityContext;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
DPRINT("IopParseDevice:\n"
|
DPRINT("IopParseDevice:\n"
|
||||||
"DeviceObject : %p\n"
|
"DeviceObject : %p\n"
|
||||||
"RelatedFileObject : %p\n"
|
"RelatedFileObject : %p\n"
|
||||||
|
@ -46,6 +50,13 @@ 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;
|
||||||
|
|
||||||
|
RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
|
||||||
|
&IoFileObjectType->TypeInfo.GenericMapping);
|
||||||
|
RtlMapGenericMask(&AccessState->OriginalDesiredAccess,
|
||||||
|
&IoFileObjectType->TypeInfo.GenericMapping);
|
||||||
|
SeSetAccessStateGenericMapping(AccessState,
|
||||||
|
&IoFileObjectType->TypeInfo.GenericMapping);
|
||||||
|
|
||||||
/* Create the actual file object */
|
/* Create the actual file object */
|
||||||
Status = ObCreateObject(AccessMode,
|
Status = ObCreateObject(AccessMode,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
|
@ -112,9 +123,145 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
Status = IopReferenceDeviceObject(DeviceObject);
|
Status = IopReferenceDeviceObject(DeviceObject);
|
||||||
FileObject->DeviceObject = DeviceObject;
|
FileObject->DeviceObject = DeviceObject;
|
||||||
|
|
||||||
/* Set the file object and return success */
|
FileObject->Type = IO_TYPE_FILE;
|
||||||
|
FileObject->Size = sizeof(FILE_OBJECT);
|
||||||
|
|
||||||
|
if (OpenPacket->CreateOptions &
|
||||||
|
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_SYNCHRONOUS_IO;
|
||||||
|
if (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_ALERTABLE_IO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OpenPacket->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
|
||||||
|
}
|
||||||
|
if (OpenPacket->CreateOptions & FILE_WRITE_THROUGH)
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_WRITE_THROUGH;
|
||||||
|
}
|
||||||
|
if (OpenPacket->CreateOptions & FILE_SEQUENTIAL_ONLY)
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_SEQUENTIAL_ONLY;
|
||||||
|
}
|
||||||
|
if (OpenPacket->CreateOptions & FILE_RANDOM_ACCESS)
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_RANDOM_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Attributes & OBJ_CASE_INSENSITIVE))
|
||||||
|
{
|
||||||
|
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityContext.SecurityQos = SecurityQos;
|
||||||
|
SecurityContext.AccessState = AccessState;
|
||||||
|
SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
|
||||||
|
SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
|
||||||
|
|
||||||
|
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
|
||||||
|
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/* Now set the IRP data */
|
||||||
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
|
Irp->RequestorMode = AccessMode;
|
||||||
|
Irp->Flags = IRP_CREATE_OPERATION |
|
||||||
|
IRP_SYNCHRONOUS_API;// |
|
||||||
|
//IRP_DEFER_IO_COMPLETION;
|
||||||
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
|
Irp->UserEvent = &FileObject->Event;
|
||||||
|
Irp->UserIosb = &IoStatusBlock;
|
||||||
|
Irp->MdlAddress = NULL;
|
||||||
|
Irp->PendingReturned = FALSE;
|
||||||
|
Irp->UserEvent = NULL;
|
||||||
|
Irp->Cancel = FALSE;
|
||||||
|
Irp->CancelRoutine = NULL;
|
||||||
|
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
|
||||||
|
|
||||||
|
StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp);
|
||||||
|
StackLoc->Control = 0;
|
||||||
|
StackLoc->FileObject = FileObject;
|
||||||
|
|
||||||
|
switch (OpenPacket->CreateFileType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case CreateFileTypeNone:
|
||||||
|
StackLoc->MajorFunction = IRP_MJ_CREATE;
|
||||||
|
StackLoc->Flags = OpenPacket->Options;
|
||||||
|
StackLoc->Parameters.Create.EaLength = OpenPacket->EaBuffer != NULL ? OpenPacket->EaLength : 0;
|
||||||
|
StackLoc->Flags |= !(Attributes & OBJ_CASE_INSENSITIVE) ? SL_CASE_SENSITIVE: 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CreateFileTypeNamedPipe:
|
||||||
|
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
|
||||||
|
StackLoc->Parameters.CreatePipe.Parameters = OpenPacket->MailslotOrPipeParameters;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CreateFileTypeMailslot:
|
||||||
|
StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
|
||||||
|
StackLoc->Parameters.CreateMailslot.Parameters = OpenPacket->MailslotOrPipeParameters;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the common data */
|
||||||
|
Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
|
||||||
|
Irp->AssociatedIrp.SystemBuffer =OpenPacket->EaBuffer;
|
||||||
|
StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) | (OpenPacket->CreateOptions & 0x00FFFFFF);
|
||||||
|
StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
|
||||||
|
StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
|
||||||
|
StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
|
||||||
|
|
||||||
|
/* Reference the file object and call the driver */
|
||||||
|
ObReferenceObject(FileObject);
|
||||||
|
Status = IoCallDriver(FileObject->DeviceObject, Irp );
|
||||||
|
|
||||||
|
/* Copy the status block */
|
||||||
|
OpenPacket->Information = IoStatusBlock.Information;
|
||||||
|
OpenPacket->FinalStatus = IoStatusBlock.Status;
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&FileObject->Event,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
Status = IoStatusBlock.Status;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PKNORMAL_ROUTINE NormalRoutine;
|
||||||
|
PVOID NormalContext;
|
||||||
|
|
||||||
|
/* We'll have to complete it ourselves */
|
||||||
|
ASSERT(!Irp->PendingReturned);
|
||||||
|
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
||||||
|
IopCompleteRequest(&Irp->Tail.Apc,
|
||||||
|
&NormalRoutine,
|
||||||
|
&NormalContext,
|
||||||
|
(PVOID*)&FileObject,
|
||||||
|
&NormalContext);
|
||||||
|
KeLowerIrql(OldIrql);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FileObject->DeviceObject = NULL;
|
||||||
|
FileObject->Vpb = NULL;
|
||||||
|
FileObject = NULL;
|
||||||
|
//ObDereferenceObject(FileObject);
|
||||||
|
}
|
||||||
|
|
||||||
*Object = FileObject;
|
*Object = FileObject;
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -804,20 +951,11 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
IN PVOID ExtraCreateParameters OPTIONAL,
|
IN PVOID ExtraCreateParameters OPTIONAL,
|
||||||
IN ULONG Options)
|
IN ULONG Options)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = NULL;
|
|
||||||
PIRP Irp;
|
|
||||||
PEXTENDED_IO_STACK_LOCATION StackLoc;
|
|
||||||
IO_SECURITY_CONTEXT SecurityContext;
|
|
||||||
KPROCESSOR_MODE AccessMode;
|
KPROCESSOR_MODE AccessMode;
|
||||||
HANDLE LocalHandle = 0;
|
HANDLE LocalHandle = 0;
|
||||||
LARGE_INTEGER SafeAllocationSize;
|
LARGE_INTEGER SafeAllocationSize;
|
||||||
PVOID SystemEaBuffer = NULL;
|
PVOID SystemEaBuffer = NULL;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
AUX_DATA AuxData;
|
|
||||||
ACCESS_STATE AccessState;
|
|
||||||
KIRQL OldIrql;
|
|
||||||
PKNORMAL_ROUTINE NormalRoutine;
|
|
||||||
PVOID NormalContext;
|
|
||||||
OPEN_PACKET OpenPacket;
|
OPEN_PACKET OpenPacket;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -928,156 +1066,19 @@ IoCreateFile(OUT PHANDLE FileHandle,
|
||||||
&OpenPacket,
|
&OpenPacket,
|
||||||
&LocalHandle);
|
&LocalHandle);
|
||||||
|
|
||||||
RtlMapGenericMask(&DesiredAccess, &IoFileObjectType->TypeInfo.GenericMapping);
|
DPRINT1("Status: %lx %lx\n", Status, LocalHandle);
|
||||||
ObReferenceObjectByHandle(LocalHandle,
|
|
||||||
DesiredAccess,
|
|
||||||
NULL,
|
|
||||||
KernelMode,
|
|
||||||
(PVOID*)&FileObject,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
|
||||||
|
|
||||||
FileObject->Type = IO_TYPE_FILE;
|
_SEH_TRY
|
||||||
FileObject->Size = sizeof(FILE_OBJECT);
|
|
||||||
|
|
||||||
if (CreateOptions &
|
|
||||||
(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
|
|
||||||
{
|
{
|
||||||
FileObject->Flags |= FO_SYNCHRONOUS_IO;
|
*FileHandle = LocalHandle;
|
||||||
if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
|
IoStatusBlock->Information = OpenPacket.Information;
|
||||||
{
|
IoStatusBlock->Status = OpenPacket.FinalStatus;
|
||||||
FileObject->Flags |= FO_ALERTABLE_IO;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
if (CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
|
|
||||||
{
|
{
|
||||||
FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
|
||||||
if (CreateOptions & FILE_WRITE_THROUGH)
|
|
||||||
{
|
|
||||||
FileObject->Flags |= FO_WRITE_THROUGH;
|
|
||||||
}
|
|
||||||
if (CreateOptions & FILE_SEQUENTIAL_ONLY)
|
|
||||||
{
|
|
||||||
FileObject->Flags |= FO_SEQUENTIAL_ONLY;
|
|
||||||
}
|
|
||||||
if (CreateOptions & FILE_RANDOM_ACCESS)
|
|
||||||
{
|
|
||||||
FileObject->Flags |= FO_RANDOM_ACCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ObjectAttributes->Attributes & OBJ_CASE_INSENSITIVE))
|
|
||||||
{
|
|
||||||
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SeCreateAccessState(&AccessState, &AuxData, FILE_ALL_ACCESS, NULL);
|
|
||||||
SecurityContext.SecurityQos = NULL; /* ?? */
|
|
||||||
SecurityContext.AccessState = &AccessState;
|
|
||||||
SecurityContext.DesiredAccess = DesiredAccess;
|
|
||||||
SecurityContext.FullCreateOptions = CreateOptions;
|
|
||||||
|
|
||||||
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
|
|
||||||
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
|
||||||
|
|
||||||
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
ZwClose(LocalHandle);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now set the IRP data */
|
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
|
||||||
Irp->RequestorMode = AccessMode;
|
|
||||||
Irp->Flags = IRP_CREATE_OPERATION |
|
|
||||||
IRP_SYNCHRONOUS_API |
|
|
||||||
IRP_DEFER_IO_COMPLETION;
|
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
|
||||||
Irp->UserEvent = &FileObject->Event;
|
|
||||||
Irp->UserIosb = IoStatusBlock;
|
|
||||||
Irp->MdlAddress = NULL;
|
|
||||||
Irp->PendingReturned = FALSE;
|
|
||||||
Irp->UserEvent = NULL;
|
|
||||||
Irp->Cancel = FALSE;
|
|
||||||
Irp->CancelRoutine = NULL;
|
|
||||||
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
|
|
||||||
|
|
||||||
StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp);
|
|
||||||
StackLoc->Control = 0;
|
|
||||||
StackLoc->FileObject = FileObject;
|
|
||||||
|
|
||||||
switch (CreateFileType)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case CreateFileTypeNone:
|
|
||||||
StackLoc->MajorFunction = IRP_MJ_CREATE;
|
|
||||||
StackLoc->Flags = Options;
|
|
||||||
StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0;
|
|
||||||
StackLoc->Flags |= !(ObjectAttributes->Attributes & OBJ_CASE_INSENSITIVE) ? SL_CASE_SENSITIVE: 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CreateFileTypeNamedPipe:
|
|
||||||
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
|
|
||||||
StackLoc->Parameters.CreatePipe.Parameters = ExtraCreateParameters;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CreateFileTypeMailslot:
|
|
||||||
StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
|
|
||||||
StackLoc->Parameters.CreateMailslot.Parameters = ExtraCreateParameters;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the common data */
|
|
||||||
Irp->Overlay.AllocationSize = SafeAllocationSize;
|
|
||||||
Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
|
|
||||||
StackLoc->Parameters.Create.Options = (CreateDisposition << 24) | (CreateOptions & 0x00FFFFFF);
|
|
||||||
StackLoc->Parameters.Create.FileAttributes = FileAttributes;
|
|
||||||
StackLoc->Parameters.Create.ShareAccess = ShareAccess;
|
|
||||||
StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
|
|
||||||
|
|
||||||
Status = IofCallDriver(FileObject->DeviceObject, Irp );
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&FileObject->Event,
|
|
||||||
Executive,
|
|
||||||
AccessMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
Status = IoStatusBlock->Status;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We'll have to complete it ourselves */
|
|
||||||
ASSERT(!Irp->PendingReturned);
|
|
||||||
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
|
||||||
IopCompleteRequest(&Irp->Tail.Apc,
|
|
||||||
&NormalRoutine,
|
|
||||||
&NormalContext,
|
|
||||||
(PVOID*)&FileObject,
|
|
||||||
&NormalContext);
|
|
||||||
KeLowerIrql(OldIrql);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
FileObject->DeviceObject = NULL;
|
|
||||||
FileObject->Vpb = NULL;
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
*FileHandle = LocalHandle;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
}
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
/* cleanup EABuffer if captured */
|
/* cleanup EABuffer if captured */
|
||||||
if (AccessMode != KernelMode && (SystemEaBuffer))
|
if (AccessMode != KernelMode && (SystemEaBuffer))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue