Initialize IRP.RequestorMode in system functions that can be called from user mode.

Use safe copy routine to copy IoStatusBlock if a system funtion was called from user mode.
Do not use local IoStatusBlock copy in system functions.

svn path=/trunk/; revision=6995
This commit is contained in:
Eric Kohl 2003-12-13 14:36:42 +00:00
parent 90f099cffe
commit 619a2c32d9
10 changed files with 363 additions and 339 deletions

View file

@ -107,7 +107,7 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
FileObject = IoStack->FileObject;
if (DeviceObject->Flags & DO_BUFFERED_IO)
if (DeviceObject->Flags & DO_BUFFERED_IO)
{
if (IoStack->MajorFunction == IRP_MJ_READ)
{
@ -235,7 +235,17 @@ IoSecondStageCompletion(
if (Irp->UserIosb!=NULL)
{
*Irp->UserIosb=Irp->IoStatus;
if (Irp->RequestorMode == KernelMode)
{
*Irp->UserIosb = Irp->IoStatus;
}
else
{
DPRINT("Irp->RequestorMode == UserMode\n");
MmSafeCopyToUser(Irp->UserIosb,
&Irp->IoStatus,
sizeof(IO_STATUS_BLOCK));
}
}
if (Irp->UserEvent)
@ -248,19 +258,19 @@ IoSecondStageCompletion(
{
if (Irp->UserEvent == NULL)
{
KeSetEvent(&OriginalFileObject->Event,PriorityBoost,FALSE);
KeSetEvent(&OriginalFileObject->Event,PriorityBoost,FALSE);
}
else if (OriginalFileObject->Flags & FO_SYNCHRONOUS_IO && Irp->UserEvent != &OriginalFileObject->Event)
{
KeSetEvent(&OriginalFileObject->Event,PriorityBoost,FALSE);
KeSetEvent(&OriginalFileObject->Event,PriorityBoost,FALSE);
}
}
//Windows NT File System Internals, page 154
if (!(Irp->Flags & IRP_PAGING_IO) && OriginalFileObject)
{
// if the event is not the one in the file object, it needs dereferenced
if (Irp->UserEvent && Irp->UserEvent != &OriginalFileObject->Event)
// if the event is not the one in the file object, it needs dereferenced
if (Irp->UserEvent && Irp->UserEvent != &OriginalFileObject->Event)
{
ObDereferenceObject(Irp->UserEvent);
}
@ -302,5 +312,4 @@ IoSecondStageCompletion(
}
IoFreeIrp(Irp);
}

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.69 2003/11/06 18:05:54 ekohl Exp $
/* $Id: create.c,v 1.70 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -344,6 +344,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
PIRP Irp;
PIO_STACK_LOCATION StackLoc;
IO_SECURITY_CONTEXT SecurityContext;
KPROCESSOR_MODE PreviousMode;
DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
"ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@ -357,10 +358,12 @@ IoCreateFile(OUT PHANDLE FileHandle,
*FileHandle = 0;
Status = ObCreateObject(ExGetPreviousMode(),
PreviousMode = ExGetPreviousMode();
Status = ObCreateObject(PreviousMode,
IoFileObjectType,
ObjectAttributes,
ExGetPreviousMode(),
PreviousMode,
NULL,
sizeof(FILE_OBJECT),
0,
@ -421,7 +424,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
@ -476,7 +479,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
{
KeWaitForSingleObject(&FileObject->Event,
Executive,
KernelMode,
PreviousMode,
FALSE,
NULL);
Status = IoStatusBlock->Status;

View file

@ -1,4 +1,4 @@
/* $Id: dir.c,v 1.19 2003/08/07 11:47:33 silverblade Exp $
/* $Id: dir.c,v 1.20 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -92,14 +92,16 @@ NtQueryDirectoryFile(
PFILE_OBJECT FileObject;
NTSTATUS Status;
PEXTENDED_IO_STACK_LOCATION IoStack;
IO_STATUS_BLOCK IoSB;
KPROCESSOR_MODE PreviousMode;
DPRINT("NtQueryDirectoryFile()\n");
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY,
IoFileObjectType,
UserMode,
PreviousMode,
(PVOID *)&FileObject,
NULL);
@ -117,10 +119,10 @@ NtQueryDirectoryFile(
return STATUS_UNSUCCESSFUL;
}
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserIosb = &IoSB;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event;
KeResetEvent( &FileObject->Event );
Irp->UserBuffer=FileInformation;
@ -155,20 +157,14 @@ NtQueryDirectoryFile(
Status = IoCallDriver(FileObject->DeviceObject,Irp);
if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
{
if (FileObject->Flags & FO_ALERTABLE_IO)
{
KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,TRUE,NULL);
}
else
{
KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL);
}
Status = IoSB.Status;
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
KeWaitForSingleObject(&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}
return(Status);
}

View file

@ -1,4 +1,4 @@
/* $Id: file.c,v 1.27 2003/11/08 07:42:10 ekohl Exp $
/* $Id: file.c,v 1.28 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -42,6 +42,7 @@ NtQueryInformationFile(HANDLE FileHandle,
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr;
PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL);
assert(FileInformation != NULL);
@ -49,11 +50,13 @@ NtQueryInformationFile(HANDLE FileHandle,
DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
UserMode,
PreviousMode,
(PVOID *)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
@ -84,7 +87,7 @@ NtQueryInformationFile(HANDLE FileHandle,
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event;
@ -108,8 +111,8 @@ NtQueryInformationFile(HANDLE FileHandle,
{
KeWaitForSingleObject(&FileObject->Event,
Executive,
KernelMode,
FALSE,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}
@ -169,7 +172,7 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = &FileObject->Event;
@ -194,7 +197,7 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
KeWaitForSingleObject(&FileObject->Event,
Executive,
KernelMode,
FALSE,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock.Status;
}
@ -225,6 +228,7 @@ NtSetInformationFile(HANDLE FileHandle,
PIRP Irp;
NTSTATUS Status;
PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL)
assert(FileInformation != NULL)
@ -232,12 +236,14 @@ NtSetInformationFile(HANDLE FileHandle,
DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass);
PreviousMode = ExGetPreviousMode();
/* Get the file object from the file handle */
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_ATTRIBUTES,
IoFileObjectType,
UserMode,
PreviousMode,
(PVOID *)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
@ -261,7 +267,7 @@ NtSetInformationFile(HANDLE FileHandle,
Status = ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION)FileInformation)->IoCompletionHandle,
IO_COMPLETION_MODIFY_STATE,//???
ExIoCompletionType,
UserMode,
PreviousMode,
(PVOID*)&Queue,
NULL);
if (NT_SUCCESS(Status))
@ -305,7 +311,7 @@ NtSetInformationFile(HANDLE FileHandle,
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event;
@ -334,8 +340,8 @@ NtSetInformationFile(HANDLE FileHandle,
{
KeWaitForSingleObject(&FileObject->Event,
Executive,
KernelMode,
FALSE,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}

View file

@ -23,8 +23,8 @@ NTSTATUS
STDCALL
NtFlushWriteBuffer(VOID)
{
KeFlushWriteBuffer();
return STATUS_SUCCESS;
KeFlushWriteBuffer();
return STATUS_SUCCESS;
}
NTSTATUS
@ -48,12 +48,14 @@ NtFlushBuffersFile (
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
IO_STATUS_BLOCK IoSB;
KPROCESSOR_MODE PreviousMode;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA,
NULL,
UserMode,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (Status != STATUS_SUCCESS)
@ -67,23 +69,26 @@ NtFlushBuffersFile (
0,
NULL,
&FileObject->Event,
&IoSB);
IoStatusBlock);
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
Status = IoCallDriver(FileObject->DeviceObject,Irp);
if (Status==STATUS_PENDING)
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL);
Status = IoSB.Status;
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
KeWaitForSingleObject(&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}
return(Status);
}

View file

@ -1,4 +1,4 @@
/* $Id: fs.c,v 1.39 2003/11/27 00:50:05 gdalsnes Exp $
/* $Id: fs.c,v 1.40 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -77,7 +77,7 @@ NtFsControlFile (
PIRP Irp;
PEXTENDED_IO_STACK_LOCATION StackPtr;
PKEVENT ptrEvent;
IO_STATUS_BLOCK IoSB;
KPROCESSOR_MODE PreviousMode;
DPRINT("NtFsControlFile(DeviceHandle %x EventHandle %x ApcRoutine %x "
"ApcContext %x IoStatusBlock %x IoControlCode %x "
@ -87,10 +87,12 @@ NtFsControlFile (
IoControlCode,InputBuffer,InputBufferSize,OutputBuffer,
OutputBufferSize);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(DeviceHandle,
FILE_READ_DATA | FILE_WRITE_DATA,
NULL,
KernelMode,
PreviousMode,
(PVOID *) &FileObject,
NULL);
@ -104,7 +106,7 @@ NtFsControlFile (
Status = ObReferenceObjectByHandle (EventHandle,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
PreviousMode,
(PVOID*)&ptrEvent,
NULL);
if (!NT_SUCCESS(Status))
@ -130,11 +132,12 @@ NtFsControlFile (
OutputBufferSize,
FALSE,
ptrEvent,
&IoSB);
IoStatusBlock);
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -147,15 +150,16 @@ NtFsControlFile (
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
Status = IoCallDriver(DeviceObject,Irp);
if (Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
KeWaitForSingleObject(ptrEvent,Executive,KernelMode,FALSE,NULL);
Status = IoSB.Status;
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
KeWaitForSingleObject(ptrEvent,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}
return(Status);
}

View file

@ -1,4 +1,4 @@
/* $Id: ioctrl.c,v 1.22 2003/11/28 17:17:44 ekohl Exp $
/* $Id: ioctrl.c,v 1.23 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -37,13 +37,13 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength OPTIONAL)
{
IO_STATUS_BLOCK SafeIoStatusBlock;
NTSTATUS Status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PKEVENT EventObject;
KPROCESSOR_MODE PreviousMode;
DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
"UserApcContext %x IoStatusBlock %x IoControlCode %x "
@ -56,10 +56,12 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle (DeviceHandle,
FILE_READ_DATA | FILE_WRITE_DATA,
IoFileObjectType,
KernelMode,
PreviousMode,
(PVOID *) &FileObject,
NULL);
if (!NT_SUCCESS(Status))
@ -72,7 +74,7 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
Status = ObReferenceObjectByHandle (Event,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
PreviousMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
@ -97,11 +99,12 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
OutputBufferLength,
FALSE,
EventObject,
&SafeIoStatusBlock);
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
@ -114,13 +117,10 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
Status = IoCallDriver(DeviceObject,Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
BOOLEAN Alertable;
Alertable = (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE;
Status = KeWaitForSingleObject (EventObject,
Executive,
UserMode,
Alertable,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
@ -128,12 +128,9 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
return Status;
}
Status = SafeIoStatusBlock.Status;
Status = IoStatusBlock->Status;
}
IoStatusBlock->Status = SafeIoStatusBlock.Status;
IoStatusBlock->Information = SafeIoStatusBlock.Information;
return Status;
}

View file

@ -21,17 +21,16 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS
STDCALL
NtLockFileCompletionRoutine(
static NTSTATUS STDCALL
IopLockFileCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
ExFreePool(Context);
return STATUS_SUCCESS;
//FIXME: should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
ExFreePool(Context);
return STATUS_SUCCESS;
// FIXME: Should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
}
/*
@ -41,10 +40,10 @@ NTSTATUS
STDCALL
NtLockFile (
IN HANDLE FileHandle,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK UserIoStatusBlock,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
IN PULONG Key,
@ -52,158 +51,150 @@ NtLockFile (
IN BOOLEAN ExclusiveLock
)
{
NTSTATUS Status;
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PKEVENT Event = NULL;
PIRP Irp = NULL;
PEXTENDED_IO_STACK_LOCATION StackPtr;
IO_STATUS_BLOCK LocalIoStatusBlock;
PIO_STATUS_BLOCK IoStatusBlock;
PDEVICE_OBJECT DeviceObject;
ULONG FobFlags;
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PKEVENT Event = NULL;
PIRP Irp = NULL;
PEXTENDED_IO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
//FIXME: instead of this, use SEH when available?
if (!Length || !ByteOffset) {
Status = STATUS_INVALID_PARAMETER;
goto fail;
}
// FIXME: instead of this, use SEH when available?
if (!Length || !ByteOffset)
{
Status = STATUS_INVALID_PARAMETER;
goto fail;
}
Status = ObReferenceObjectByHandle(
FileHandle,
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
0,
IoFileObjectType,
ExGetPreviousMode(),
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
goto fail;
}
if (!NT_SUCCESS(Status)){
goto fail;
}
DeviceObject = IoGetRelatedDeviceObject(FileObject);
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp = IoAllocateIrp(
DeviceObject->StackSize,
TRUE
);
if (EventHandle != NULL && !FailImmediatedly)
{
Status = ObReferenceObjectByHandle(EventHandle,
SYNCHRONIZE,
ExEventObjectType,
PreviousMode,
(PVOID*)&Event,
NULL);
if (!NT_SUCCESS(Status))
{
goto fail;
}
}
else
{
Event = &FileObject->Event;
KeResetEvent(Event);
}
if (Irp == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
if (EventHandle != NULL && !FailImmediatedly) {
Status = ObReferenceObjectByHandle(
EventHandle,
SYNCHRONIZE,
ExEventObjectType,
ExGetPreviousMode(),
(PVOID*)&Event,
NULL);
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
if (!NT_SUCCESS(Status)) {
goto fail;
}
Irp->UserEvent = Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
}
else {
Event = &FileObject->Event;
KeResetEvent(Event);
}
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_LOCK;
StackPtr->FileObject = FileObject;
if ((FileObject->Flags & FO_SYNCHRONOUS_IO) || FailImmediatedly)
IoStatusBlock = &LocalIoStatusBlock;
else
IoStatusBlock = UserIoStatusBlock;
if (ExclusiveLock)
StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
if (FailImmediatedly)
StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
LocalLength = ExAllocatePoolWithTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
if (!LocalLength)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp->UserEvent = Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
*LocalLength = *Length;
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_LOCK;
StackPtr->FileObject = FileObject;
if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
LocalLength = ExAllocatePoolWithTag(
NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK
);
if (!LocalLength){
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
IoSetCompletionRoutine(Irp,
IopLockFileCompletionRoutine,
LocalLength,
TRUE,
TRUE,
TRUE);
*LocalLength = *Length;
/* Can't touch FileObject after IoCallDriver since it might be freed */
Status = IofCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
Status = KeWaitForSingleObject(Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
IoSetCompletionRoutine(
Irp,
NtLockFileCompletionRoutine,
LocalLength,
TRUE,
TRUE,
TRUE );
if (Status != STATUS_WAIT_0)
{
DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
/*
* FIXME: Should do some special processing here if alertable wait
* was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
*/
return Status; /* Set status to something else? */
}
//can't touch FileObject after IoCallDriver since it might be freed
FobFlags = FileObject->Flags;
Status = IofCallDriver(DeviceObject, Irp);
Status = IoStatusBlock->Status;
}
if (Status == STATUS_PENDING && (FobFlags & FO_SYNCHRONOUS_IO)) {
return Status;
Status = KeWaitForSingleObject(
Event,
Executive,
ExGetPreviousMode() ,
(FobFlags & FO_ALERTABLE_IO) ? TRUE : FALSE,
NULL
);
fail:;
if (LocalLength)
ExFreePool(LocalLength);
if (Status != STATUS_WAIT_0) {
DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
/*
FIXME: should do some special processing here if alertable wait
was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
*/
return Status; //set status to something else?
}
if (Irp)
IoFreeIrp(Irp);
Status = LocalIoStatusBlock.Status;
}
if (Event)
ObDereferenceObject(Event);
if (FobFlags & FO_SYNCHRONOUS_IO)
*UserIoStatusBlock = LocalIoStatusBlock;
return Status;
fail:;
if (LocalLength) ExFreePool(LocalLength);
if (Irp) IoFreeIrp(Irp);
if (Event) ObDereferenceObject(Event);
if (FileObject) ObDereferenceObject(FileObject);
return Status;
if (FileObject)
ObDereferenceObject(FileObject);
return Status;
}
/*
* @unimplemented
*/
@ -211,96 +202,97 @@ NTSTATUS
STDCALL
NtUnlockFile (
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK UserIoStatusBlock,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
OUT PULONG Key OPTIONAL
OUT PULONG Key OPTIONAL
)
{
NTSTATUS Status;
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PIRP Irp = NULL;
PEXTENDED_IO_STACK_LOCATION StackPtr;
IO_STATUS_BLOCK LocalIoStatusBlock;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PIRP Irp = NULL;
PEXTENDED_IO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
//FIXME: instead of this, use SEH when available
if (!Length || !ByteOffset) {
Status = STATUS_INVALID_PARAMETER;
goto fail;
}
// FIXME: instead of this, use SEH when available
if (!Length || !ByteOffset)
{
Status = STATUS_INVALID_PARAMETER;
goto fail;
}
/*
BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
It should ONLY fail if we desire an access that conflict with granted access!
*/
Status = ObReferenceObjectByHandle(
FileHandle,
FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
PreviousMode = ExGetPreviousMode();
/*
* BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
* It should ONLY fail if we desire an access that conflict with granted access!
*/
Status = ObReferenceObjectByHandle(FileHandle,
0, //FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
IoFileObjectType,
ExGetPreviousMode(),
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
goto fail;
}
if (!NT_SUCCESS(Status)){
goto fail;
}
DeviceObject = IoGetRelatedDeviceObject(FileObject);
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp = IoAllocateIrp(
DeviceObject->StackSize,
TRUE
);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
if (Irp == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
LocalLength = ExAllocatePoolWithTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
if (!LocalLength)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp->UserIosb = &LocalIoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
*LocalLength = *Length;
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
LocalLength = ExAllocatePoolWithTag(
NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK
);
if (!LocalLength){
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
/* Allways synchronous */
Status = IofCallDriver(DeviceObject, Irp);
*LocalLength = *Length;
ExFreePool(LocalLength);
StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
return Status;
//allways syncronious
Status = IofCallDriver(DeviceObject, Irp);
fail:;
if (LocalLength)
ExFreePool(LocalLength);
*UserIoStatusBlock = LocalIoStatusBlock;
if (Irp)
IoFreeIrp(Irp);
ExFreePool(LocalLength);
if (FileObject)
ObDereferenceObject(FileObject);
return Status;
fail:;
if (LocalLength) ExFreePool(LocalLength);
if (Irp) IoFreeIrp(Irp);
if (FileObject) ObDereferenceObject(FileObject);
return Status;
return Status;
}

View file

@ -1,4 +1,4 @@
/* $Id: rw.c,v 1.51 2003/11/30 19:59:41 gdalsnes Exp $
/* $Id: rw.c,v 1.52 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -43,13 +43,14 @@ NtReadFile (IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL;
DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
@ -59,10 +60,12 @@ NtReadFile (IN HANDLE FileHandle,
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_DATA,
IoFileObjectType,
UserMode,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
@ -88,7 +91,7 @@ NtReadFile (IN HANDLE FileHandle,
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
PreviousMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
@ -107,11 +110,13 @@ NtReadFile (IN HANDLE FileHandle,
Length,
ByteOffset,
EventObject,
IoStatusBlock);
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -121,19 +126,20 @@ NtReadFile (IN HANDLE FileHandle,
Status = IoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
{
Status = KeWaitForSingleObject (&FileObject->Event,
Executive,
UserMode,
FileObject->Flags & FO_ALERTABLE_IO,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = IoStatusBlock->Status;
Status = IoStatusBlock->Status;
}
return Status;
@ -162,13 +168,14 @@ NtWriteFile (IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL;
DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
@ -178,10 +185,12 @@ NtWriteFile (IN HANDLE FileHandle,
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA,
IoFileObjectType,
UserMode,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
@ -207,7 +216,7 @@ NtWriteFile (IN HANDLE FileHandle,
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
PreviousMode,
(PVOID*)&EventObject,
NULL);
@ -233,6 +242,8 @@ NtWriteFile (IN HANDLE FileHandle,
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -245,8 +256,8 @@ NtWriteFile (IN HANDLE FileHandle,
{
Status = KeWaitForSingleObject (&FileObject->Event,
Executive,
UserMode,
FileObject->Flags & FO_ALERTABLE_IO,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{

View file

@ -1,4 +1,4 @@
/* $Id: vpb.c,v 1.23 2003/10/12 17:05:45 hbirr Exp $
/* $Id: vpb.c,v 1.24 2003/12/13 14:36:42 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -65,16 +65,6 @@ IoAttachVpb(PDEVICE_OBJECT DeviceObject)
}
/*
* @implemented
*/
NTSTATUS STDCALL
NtQueryVolumeInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FsInformation,
IN ULONG Length,
IN FS_INFORMATION_CLASS FsInformationClass)
/*
* FUNCTION: Queries the volume information
* ARGUMENTS:
@ -96,7 +86,16 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
* FileFsMaximumInformation
*
* RETURNS: Status
*
* @implemented
*/
NTSTATUS STDCALL
NtQueryVolumeInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FsInformation,
IN ULONG Length,
IN FS_INFORMATION_CLASS FsInformationClass)
{
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
@ -104,17 +103,19 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
NTSTATUS Status;
PIO_STACK_LOCATION StackPtr;
PVOID SystemBuffer;
IO_STATUS_BLOCK IoSB;
KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL);
assert(FsInformation != NULL);
DPRINT("FsInformation %p\n", FsInformation);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
UserMode,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
@ -142,13 +143,14 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
return(STATUS_INSUFFICIENT_RESOURCES);
}
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = &IoSB;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
@ -168,10 +170,10 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
{
KeWaitForSingleObject(&FileObject->Event,
UserRequest,
KernelMode,
PreviousMode,
FALSE,
NULL);
Status = IoSB.Status;
Status = IoStatusBlock->Status;
}
DPRINT("Status %x\n", Status);
@ -180,12 +182,9 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
DPRINT("Information %lu\n", IoStatusBlock->Information);
MmSafeCopyToUser(FsInformation,
SystemBuffer,
IoSB.Information);
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
IoStatusBlock->Information);
}
ExFreePool(SystemBuffer);
return(Status);
@ -231,9 +230,9 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
return(STATUS_INSUFFICIENT_RESOURCES);
}
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = FsInformation;
KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event;
@ -289,12 +288,17 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
NTSTATUS Status;
PEXTENDED_IO_STACK_LOCATION StackPtr;
PVOID SystemBuffer;
IO_STATUS_BLOCK IoSB;
KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL);
assert(FsInformation != NULL);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_ATTRIBUTES,
NULL,
UserMode,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (Status != STATUS_SUCCESS)
@ -325,13 +329,13 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
FsInformation,
Length);
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = &IoSB;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
@ -350,15 +354,12 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
{
KeWaitForSingleObject(&FileObject->Event,
UserRequest,
KernelMode,
PreviousMode,
FALSE,
NULL);
Status = IoSB.Status;
Status = IoStatusBlock->Status;
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
}
ExFreePool(SystemBuffer);
return(Status);