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; FileObject = IoStack->FileObject;
if (DeviceObject->Flags & DO_BUFFERED_IO) if (DeviceObject->Flags & DO_BUFFERED_IO)
{ {
if (IoStack->MajorFunction == IRP_MJ_READ) if (IoStack->MajorFunction == IRP_MJ_READ)
{ {
@ -235,7 +235,17 @@ IoSecondStageCompletion(
if (Irp->UserIosb!=NULL) 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) if (Irp->UserEvent)
@ -248,19 +258,19 @@ IoSecondStageCompletion(
{ {
if (Irp->UserEvent == NULL) 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) 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 //Windows NT File System Internals, page 154
if (!(Irp->Flags & IRP_PAGING_IO) && OriginalFileObject) if (!(Irp->Flags & IRP_PAGING_IO) && OriginalFileObject)
{ {
// if the event is not the one in the file object, it needs dereferenced // if the event is not the one in the file object, it needs dereferenced
if (Irp->UserEvent && Irp->UserEvent != &OriginalFileObject->Event) if (Irp->UserEvent && Irp->UserEvent != &OriginalFileObject->Event)
{ {
ObDereferenceObject(Irp->UserEvent); ObDereferenceObject(Irp->UserEvent);
} }
@ -302,5 +312,4 @@ IoSecondStageCompletion(
} }
IoFreeIrp(Irp); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -344,6 +344,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackLoc; PIO_STACK_LOCATION StackLoc;
IO_SECURITY_CONTEXT SecurityContext; IO_SECURITY_CONTEXT SecurityContext;
KPROCESSOR_MODE PreviousMode;
DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, " DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
"ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n", "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
@ -357,10 +358,12 @@ IoCreateFile(OUT PHANDLE FileHandle,
*FileHandle = 0; *FileHandle = 0;
Status = ObCreateObject(ExGetPreviousMode(), PreviousMode = ExGetPreviousMode();
Status = ObCreateObject(PreviousMode,
IoFileObjectType, IoFileObjectType,
ObjectAttributes, ObjectAttributes,
ExGetPreviousMode(), PreviousMode,
NULL, NULL,
sizeof(FILE_OBJECT), sizeof(FILE_OBJECT),
0, 0,
@ -421,7 +424,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
//trigger FileObject/Event dereferencing //trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock; Irp->UserIosb = IoStatusBlock;
Irp->AssociatedIrp.SystemBuffer = EaBuffer; Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters; Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
@ -476,7 +479,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
{ {
KeWaitForSingleObject(&FileObject->Event, KeWaitForSingleObject(&FileObject->Event,
Executive, Executive,
KernelMode, PreviousMode,
FALSE, FALSE,
NULL); NULL);
Status = IoStatusBlock->Status; 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -92,14 +92,16 @@ NtQueryDirectoryFile(
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
NTSTATUS Status; NTSTATUS Status;
PEXTENDED_IO_STACK_LOCATION IoStack; PEXTENDED_IO_STACK_LOCATION IoStack;
IO_STATUS_BLOCK IoSB; KPROCESSOR_MODE PreviousMode;
DPRINT("NtQueryDirectoryFile()\n"); DPRINT("NtQueryDirectoryFile()\n");
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY, FILE_LIST_DIRECTORY,
IoFileObjectType, IoFileObjectType,
UserMode, PreviousMode,
(PVOID *)&FileObject, (PVOID *)&FileObject,
NULL); NULL);
@ -117,10 +119,10 @@ NtQueryDirectoryFile(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
//trigger FileObject/Event dereferencing /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = &IoSB; Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp->UserBuffer=FileInformation; Irp->UserBuffer=FileInformation;
@ -155,20 +157,14 @@ NtQueryDirectoryFile(
Status = IoCallDriver(FileObject->DeviceObject,Irp); Status = IoCallDriver(FileObject->DeviceObject,Irp);
if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO)) if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
{ {
if (FileObject->Flags & FO_ALERTABLE_IO) KeWaitForSingleObject(&FileObject->Event,
{ Executive,
KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,TRUE,NULL); PreviousMode,
} FileObject->Flags & FO_ALERTABLE_IO,
else NULL);
{ Status = IoStatusBlock->Status;
KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL);
}
Status = IoSB.Status;
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
} }
return(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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -42,6 +42,7 @@ NtQueryInformationFile(HANDLE FileHandle,
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
PVOID SystemBuffer; PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL); assert(IoStatusBlock != NULL);
assert(FileInformation != NULL); assert(FileInformation != NULL);
@ -49,11 +50,13 @@ NtQueryInformationFile(HANDLE FileHandle,
DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d " DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation, "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass); Length, FileInformationClass);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_ATTRIBUTES, FILE_READ_ATTRIBUTES,
IoFileObjectType, IoFileObjectType,
UserMode, PreviousMode,
(PVOID *)&FileObject, (PVOID *)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -84,7 +87,7 @@ NtQueryInformationFile(HANDLE FileHandle,
/* Trigger FileObject/Event dereferencing */ /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = IoStatusBlock; Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
@ -108,8 +111,8 @@ NtQueryInformationFile(HANDLE FileHandle,
{ {
KeWaitForSingleObject(&FileObject->Event, KeWaitForSingleObject(&FileObject->Event,
Executive, Executive,
KernelMode, PreviousMode,
FALSE, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
Status = IoStatusBlock->Status; Status = IoStatusBlock->Status;
} }
@ -169,7 +172,7 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
/* Trigger FileObject/Event dereferencing */ /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = FileInformation; Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->UserIosb = &IoStatusBlock; Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
@ -194,7 +197,7 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
KeWaitForSingleObject(&FileObject->Event, KeWaitForSingleObject(&FileObject->Event,
Executive, Executive,
KernelMode, KernelMode,
FALSE, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
Status = IoStatusBlock.Status; Status = IoStatusBlock.Status;
} }
@ -225,6 +228,7 @@ NtSetInformationFile(HANDLE FileHandle,
PIRP Irp; PIRP Irp;
NTSTATUS Status; NTSTATUS Status;
PVOID SystemBuffer; PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL) assert(IoStatusBlock != NULL)
assert(FileInformation != NULL) assert(FileInformation != NULL)
@ -232,12 +236,14 @@ NtSetInformationFile(HANDLE FileHandle,
DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d " DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation, "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass); Length, FileInformationClass);
PreviousMode = ExGetPreviousMode();
/* Get the file object from the file handle */ /* Get the file object from the file handle */
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_ATTRIBUTES, FILE_WRITE_ATTRIBUTES,
IoFileObjectType, IoFileObjectType,
UserMode, PreviousMode,
(PVOID *)&FileObject, (PVOID *)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -261,7 +267,7 @@ NtSetInformationFile(HANDLE FileHandle,
Status = ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION)FileInformation)->IoCompletionHandle, Status = ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION)FileInformation)->IoCompletionHandle,
IO_COMPLETION_MODIFY_STATE,//??? IO_COMPLETION_MODIFY_STATE,//???
ExIoCompletionType, ExIoCompletionType,
UserMode, PreviousMode,
(PVOID*)&Queue, (PVOID*)&Queue,
NULL); NULL);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
@ -305,7 +311,7 @@ NtSetInformationFile(HANDLE FileHandle,
/* Trigger FileObject/Event dereferencing */ /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = IoStatusBlock; Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
@ -334,8 +340,8 @@ NtSetInformationFile(HANDLE FileHandle,
{ {
KeWaitForSingleObject(&FileObject->Event, KeWaitForSingleObject(&FileObject->Event,
Executive, Executive,
KernelMode, PreviousMode,
FALSE, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
Status = IoStatusBlock->Status; Status = IoStatusBlock->Status;
} }

View file

@ -23,8 +23,8 @@ NTSTATUS
STDCALL STDCALL
NtFlushWriteBuffer(VOID) NtFlushWriteBuffer(VOID)
{ {
KeFlushWriteBuffer(); KeFlushWriteBuffer();
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
@ -48,12 +48,14 @@ NtFlushBuffersFile (
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK IoSB; KPROCESSOR_MODE PreviousMode;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA, FILE_WRITE_DATA,
NULL, NULL,
UserMode, PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (Status != STATUS_SUCCESS) if (Status != STATUS_SUCCESS)
@ -67,23 +69,26 @@ NtFlushBuffersFile (
0, 0,
NULL, NULL,
&FileObject->Event, &FileObject->Event,
&IoSB); IoStatusBlock);
//trigger FileObject/Event dereferencing /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject; StackPtr->FileObject = FileObject;
Status = IoCallDriver(FileObject->DeviceObject,Irp); Status = IoCallDriver(FileObject->DeviceObject,Irp);
if (Status==STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL); KeWaitForSingleObject(&FileObject->Event,
Status = IoSB.Status; Executive,
} PreviousMode,
if (IoStatusBlock) FileObject->Flags & FO_ALERTABLE_IO,
{ NULL);
*IoStatusBlock = IoSB; Status = IoStatusBlock->Status;
} }
return(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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -77,7 +77,7 @@ NtFsControlFile (
PIRP Irp; PIRP Irp;
PEXTENDED_IO_STACK_LOCATION StackPtr; PEXTENDED_IO_STACK_LOCATION StackPtr;
PKEVENT ptrEvent; PKEVENT ptrEvent;
IO_STATUS_BLOCK IoSB; KPROCESSOR_MODE PreviousMode;
DPRINT("NtFsControlFile(DeviceHandle %x EventHandle %x ApcRoutine %x " DPRINT("NtFsControlFile(DeviceHandle %x EventHandle %x ApcRoutine %x "
"ApcContext %x IoStatusBlock %x IoControlCode %x " "ApcContext %x IoStatusBlock %x IoControlCode %x "
@ -87,10 +87,12 @@ NtFsControlFile (
IoControlCode,InputBuffer,InputBufferSize,OutputBuffer, IoControlCode,InputBuffer,InputBufferSize,OutputBuffer,
OutputBufferSize); OutputBufferSize);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(DeviceHandle, Status = ObReferenceObjectByHandle(DeviceHandle,
FILE_READ_DATA | FILE_WRITE_DATA, FILE_READ_DATA | FILE_WRITE_DATA,
NULL, NULL,
KernelMode, PreviousMode,
(PVOID *) &FileObject, (PVOID *) &FileObject,
NULL); NULL);
@ -104,7 +106,7 @@ NtFsControlFile (
Status = ObReferenceObjectByHandle (EventHandle, Status = ObReferenceObjectByHandle (EventHandle,
SYNCHRONIZE, SYNCHRONIZE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&ptrEvent, (PVOID*)&ptrEvent,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -130,11 +132,12 @@ NtFsControlFile (
OutputBufferSize, OutputBufferSize,
FALSE, FALSE,
ptrEvent, ptrEvent,
&IoSB); IoStatusBlock);
//trigger FileObject/Event dereferencing /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -147,15 +150,16 @@ NtFsControlFile (
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL; StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
Status = IoCallDriver(DeviceObject,Irp); 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); KeWaitForSingleObject(ptrEvent,
Status = IoSB.Status; Executive,
} PreviousMode,
if (IoStatusBlock) FileObject->Flags & FO_ALERTABLE_IO,
{ NULL);
*IoStatusBlock = IoSB; Status = IoStatusBlock->Status;
} }
return(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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -37,13 +37,13 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
OUT PVOID OutputBuffer, OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength OPTIONAL) IN ULONG OutputBufferLength OPTIONAL)
{ {
IO_STATUS_BLOCK SafeIoStatusBlock;
NTSTATUS Status; NTSTATUS Status;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
PKEVENT EventObject; PKEVENT EventObject;
KPROCESSOR_MODE PreviousMode;
DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x " DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
"UserApcContext %x IoStatusBlock %x IoControlCode %x " "UserApcContext %x IoStatusBlock %x IoControlCode %x "
@ -56,10 +56,12 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
if (IoStatusBlock == NULL) if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION; return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle (DeviceHandle, Status = ObReferenceObjectByHandle (DeviceHandle,
FILE_READ_DATA | FILE_WRITE_DATA, FILE_READ_DATA | FILE_WRITE_DATA,
IoFileObjectType, IoFileObjectType,
KernelMode, PreviousMode,
(PVOID *) &FileObject, (PVOID *) &FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -72,7 +74,7 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
Status = ObReferenceObjectByHandle (Event, Status = ObReferenceObjectByHandle (Event,
SYNCHRONIZE, SYNCHRONIZE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&EventObject, (PVOID*)&EventObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -97,11 +99,12 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
OutputBufferLength, OutputBufferLength,
FALSE, FALSE,
EventObject, EventObject,
&SafeIoStatusBlock); IoStatusBlock);
/* Trigger FileObject/Event dereferencing */ /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
@ -114,13 +117,10 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
Status = IoCallDriver(DeviceObject,Irp); Status = IoCallDriver(DeviceObject,Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{ {
BOOLEAN Alertable;
Alertable = (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE;
Status = KeWaitForSingleObject (EventObject, Status = KeWaitForSingleObject (EventObject,
Executive, Executive,
UserMode, PreviousMode,
Alertable, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
if (Status != STATUS_WAIT_0) if (Status != STATUS_WAIT_0)
{ {
@ -128,12 +128,9 @@ NtDeviceIoControlFile (IN HANDLE DeviceHandle,
return Status; return Status;
} }
Status = SafeIoStatusBlock.Status; Status = IoStatusBlock->Status;
} }
IoStatusBlock->Status = SafeIoStatusBlock.Status;
IoStatusBlock->Information = SafeIoStatusBlock.Information;
return Status; return Status;
} }

View file

@ -21,17 +21,16 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS static NTSTATUS STDCALL
STDCALL IopLockFileCompletionRoutine(
NtLockFileCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PIRP Irp,
IN PVOID Context IN PVOID Context
) )
{ {
ExFreePool(Context); ExFreePool(Context);
return STATUS_SUCCESS; return STATUS_SUCCESS;
//FIXME: should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED? // FIXME: Should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
} }
/* /*
@ -41,10 +40,10 @@ NTSTATUS
STDCALL STDCALL
NtLockFile ( NtLockFile (
IN HANDLE FileHandle, IN HANDLE FileHandle,
IN HANDLE EventHandle OPTIONAL, IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL, IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK UserIoStatusBlock, OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length, IN PLARGE_INTEGER Length,
IN PULONG Key, IN PULONG Key,
@ -52,158 +51,150 @@ NtLockFile (
IN BOOLEAN ExclusiveLock IN BOOLEAN ExclusiveLock
) )
{ {
NTSTATUS Status; PFILE_OBJECT FileObject = NULL;
PFILE_OBJECT FileObject = NULL; PLARGE_INTEGER LocalLength = NULL;
PLARGE_INTEGER LocalLength = NULL; PKEVENT Event = NULL;
PKEVENT Event = NULL; PIRP Irp = NULL;
PIRP Irp = NULL; PEXTENDED_IO_STACK_LOCATION StackPtr;
PEXTENDED_IO_STACK_LOCATION StackPtr; PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK LocalIoStatusBlock; KPROCESSOR_MODE PreviousMode;
PIO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
ULONG FobFlags;
//FIXME: instead of this, use SEH when available? // FIXME: instead of this, use SEH when available?
if (!Length || !ByteOffset) { if (!Length || !ByteOffset)
Status = STATUS_INVALID_PARAMETER; {
goto fail; Status = STATUS_INVALID_PARAMETER;
} goto fail;
}
Status = ObReferenceObjectByHandle( PreviousMode = ExGetPreviousMode();
FileHandle,
Status = ObReferenceObjectByHandle(FileHandle,
0, 0,
IoFileObjectType, IoFileObjectType,
ExGetPreviousMode(), PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status))
{
goto fail;
}
if (!NT_SUCCESS(Status)){ DeviceObject = IoGetRelatedDeviceObject(FileObject);
goto fail;
}
DeviceObject = IoGetRelatedDeviceObject(FileObject); Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp = IoAllocateIrp( if (EventHandle != NULL && !FailImmediatedly)
DeviceObject->StackSize, {
TRUE Status = ObReferenceObjectByHandle(EventHandle,
); SYNCHRONIZE,
ExEventObjectType,
PreviousMode,
(PVOID*)&Event,
NULL);
if (!NT_SUCCESS(Status))
{
goto fail;
}
}
else
{
Event = &FileObject->Event;
KeResetEvent(Event);
}
if (Irp == NULL) { /* Trigger FileObject/Event dereferencing */
Status = STATUS_INSUFFICIENT_RESOURCES; Irp->Tail.Overlay.OriginalFileObject = FileObject;
goto fail;
}
if (EventHandle != NULL && !FailImmediatedly) { Irp->RequestorMode = PreviousMode;
Status = ObReferenceObjectByHandle( Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
EventHandle, Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
SYNCHRONIZE,
ExEventObjectType,
ExGetPreviousMode(),
(PVOID*)&Event,
NULL);
if (!NT_SUCCESS(Status)) { Irp->UserEvent = Event;
goto fail; Irp->UserIosb = IoStatusBlock;
} Irp->Tail.Overlay.Thread = PsGetCurrentThread();
} StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
else { StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
Event = &FileObject->Event; StackPtr->MinorFunction = IRP_MN_LOCK;
KeResetEvent(Event); StackPtr->FileObject = FileObject;
}
if ((FileObject->Flags & FO_SYNCHRONOUS_IO) || FailImmediatedly) if (ExclusiveLock)
IoStatusBlock = &LocalIoStatusBlock; StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
else
IoStatusBlock = UserIoStatusBlock;
//trigger FileObject/Event dereferencing if (FailImmediatedly)
Irp->Tail.Overlay.OriginalFileObject = FileObject; StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; LocalLength = ExAllocatePoolWithTag(NonPagedPool,
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; sizeof(LARGE_INTEGER),
TAG_LOCK);
if (!LocalLength)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp->UserEvent = Event; *LocalLength = *Length;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp); StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL; StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->MinorFunction = IRP_MN_LOCK; StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
StackPtr->FileObject = FileObject;
if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
LocalLength = ExAllocatePoolWithTag( IoSetCompletionRoutine(Irp,
NonPagedPool, IopLockFileCompletionRoutine,
sizeof(LARGE_INTEGER), LocalLength,
TAG_LOCK TRUE,
); TRUE,
if (!LocalLength){ TRUE);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
*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; if (Status != STATUS_WAIT_0)
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset; {
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0; DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
/*
IoSetCompletionRoutine( * FIXME: Should do some special processing here if alertable wait
Irp, * was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
NtLockFileCompletionRoutine, */
LocalLength, return Status; /* Set status to something else? */
TRUE, }
TRUE,
TRUE );
//can't touch FileObject after IoCallDriver since it might be freed Status = IoStatusBlock->Status;
FobFlags = FileObject->Flags; }
Status = IofCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING && (FobFlags & FO_SYNCHRONOUS_IO)) { return Status;
Status = KeWaitForSingleObject( fail:;
Event, if (LocalLength)
Executive, ExFreePool(LocalLength);
ExGetPreviousMode() ,
(FobFlags & FO_ALERTABLE_IO) ? TRUE : FALSE,
NULL
);
if (Status != STATUS_WAIT_0) { if (Irp)
DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n"); IoFreeIrp(Irp);
/*
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?
}
Status = LocalIoStatusBlock.Status; if (Event)
} ObDereferenceObject(Event);
if (FobFlags & FO_SYNCHRONOUS_IO) if (FileObject)
*UserIoStatusBlock = LocalIoStatusBlock; ObDereferenceObject(FileObject);
return Status;
fail:;
if (LocalLength) ExFreePool(LocalLength);
if (Irp) IoFreeIrp(Irp);
if (Event) ObDereferenceObject(Event);
if (FileObject) ObDereferenceObject(FileObject);
return Status;
return Status;
} }
/* /*
* @unimplemented * @unimplemented
*/ */
@ -211,96 +202,97 @@ NTSTATUS
STDCALL STDCALL
NtUnlockFile ( NtUnlockFile (
IN HANDLE FileHandle, IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK UserIoStatusBlock, OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length, IN PLARGE_INTEGER Length,
OUT PULONG Key OPTIONAL OUT PULONG Key OPTIONAL
) )
{ {
NTSTATUS Status; PFILE_OBJECT FileObject = NULL;
PFILE_OBJECT FileObject = NULL; PLARGE_INTEGER LocalLength = NULL;
PLARGE_INTEGER LocalLength = NULL; PIRP Irp = NULL;
PIRP Irp = NULL; PEXTENDED_IO_STACK_LOCATION StackPtr;
PEXTENDED_IO_STACK_LOCATION StackPtr; PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK LocalIoStatusBlock; KPROCESSOR_MODE PreviousMode;
PDEVICE_OBJECT DeviceObject; NTSTATUS Status;
//FIXME: instead of this, use SEH when available // FIXME: instead of this, use SEH when available
if (!Length || !ByteOffset) { if (!Length || !ByteOffset)
Status = STATUS_INVALID_PARAMETER; {
goto fail; Status = STATUS_INVALID_PARAMETER;
} goto fail;
}
/* 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! /*
*/ * BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
Status = ObReferenceObjectByHandle( * It should ONLY fail if we desire an access that conflict with granted access!
FileHandle, */
FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to! Status = ObReferenceObjectByHandle(FileHandle,
0, //FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
IoFileObjectType, IoFileObjectType,
ExGetPreviousMode(), PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status))
{
goto fail;
}
if (!NT_SUCCESS(Status)){ DeviceObject = IoGetRelatedDeviceObject(FileObject);
goto fail;
}
DeviceObject = IoGetRelatedDeviceObject(FileObject); Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp = IoAllocateIrp( /* Trigger FileObject/Event dereferencing */
DeviceObject->StackSize, Irp->Tail.Overlay.OriginalFileObject = FileObject;
TRUE Irp->RequestorMode = PreviousMode;
); Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
if (Irp == NULL) { StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
Status = STATUS_INSUFFICIENT_RESOURCES; StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
goto fail; StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
} StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
//trigger FileObject/Event dereferencing LocalLength = ExAllocatePoolWithTag(NonPagedPool,
Irp->Tail.Overlay.OriginalFileObject = FileObject; sizeof(LARGE_INTEGER),
TAG_LOCK);
if (!LocalLength)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp->UserIosb = &LocalIoStatusBlock; *LocalLength = *Length;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp); StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL; StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE; StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
LocalLength = ExAllocatePoolWithTag( /* Allways synchronous */
NonPagedPool, Status = IofCallDriver(DeviceObject, Irp);
sizeof(LARGE_INTEGER),
TAG_LOCK
);
if (!LocalLength){
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
*LocalLength = *Length; ExFreePool(LocalLength);
StackPtr->Parameters.LockControl.Length = LocalLength; return Status;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
//allways syncronious fail:;
Status = IofCallDriver(DeviceObject, Irp); if (LocalLength)
ExFreePool(LocalLength);
*UserIoStatusBlock = LocalIoStatusBlock; if (Irp)
IoFreeIrp(Irp);
ExFreePool(LocalLength); if (FileObject)
ObDereferenceObject(FileObject);
return Status; return Status;
fail:;
if (LocalLength) ExFreePool(LocalLength);
if (Irp) IoFreeIrp(Irp);
if (FileObject) ObDereferenceObject(FileObject);
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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -43,13 +43,14 @@ NtReadFile (IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer, OUT PVOID Buffer,
IN ULONG Length, 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) IN PULONG Key OPTIONAL)
{ {
NTSTATUS Status; NTSTATUS Status;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL; PKEVENT EventObject = NULL;
DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
@ -59,10 +60,12 @@ NtReadFile (IN HANDLE FileHandle,
if (IoStatusBlock == NULL) if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION; return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_DATA, FILE_READ_DATA,
IoFileObjectType, IoFileObjectType,
UserMode, PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -88,7 +91,7 @@ NtReadFile (IN HANDLE FileHandle,
Status = ObReferenceObjectByHandle(Event, Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE, SYNCHRONIZE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&EventObject, (PVOID*)&EventObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -107,11 +110,13 @@ NtReadFile (IN HANDLE FileHandle,
Length, Length,
ByteOffset, ByteOffset,
EventObject, EventObject,
IoStatusBlock); IoStatusBlock);
/* Trigger FileObject/Event dereferencing */ /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -121,19 +126,20 @@ NtReadFile (IN HANDLE FileHandle,
Status = IoCallDriver(FileObject->DeviceObject, Irp); Status = IoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{ {
Status = KeWaitForSingleObject (&FileObject->Event, Status = KeWaitForSingleObject (&FileObject->Event,
Executive, Executive,
UserMode, PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
if (Status != STATUS_WAIT_0) if (Status != STATUS_WAIT_0)
{ {
/* Wait failed. */ /* Wait failed. */
return(Status); return(Status);
} }
Status = IoStatusBlock->Status; Status = IoStatusBlock->Status;
} }
return Status; return Status;
@ -162,13 +168,14 @@ NtWriteFile (IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer, IN PVOID Buffer,
IN ULONG Length, 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) IN PULONG Key OPTIONAL)
{ {
NTSTATUS Status; NTSTATUS Status;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL; PKEVENT EventObject = NULL;
DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
@ -178,10 +185,12 @@ NtWriteFile (IN HANDLE FileHandle,
if (IoStatusBlock == NULL) if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION; return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA, FILE_WRITE_DATA,
IoFileObjectType, IoFileObjectType,
UserMode, PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -207,7 +216,7 @@ NtWriteFile (IN HANDLE FileHandle,
Status = ObReferenceObjectByHandle(Event, Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE, SYNCHRONIZE,
ExEventObjectType, ExEventObjectType,
UserMode, PreviousMode,
(PVOID*)&EventObject, (PVOID*)&EventObject,
NULL); NULL);
@ -233,6 +242,8 @@ NtWriteFile (IN HANDLE FileHandle,
/* Trigger FileObject/Event dereferencing */ /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -245,8 +256,8 @@ NtWriteFile (IN HANDLE FileHandle,
{ {
Status = KeWaitForSingleObject (&FileObject->Event, Status = KeWaitForSingleObject (&FileObject->Event,
Executive, Executive,
UserMode, PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
if (Status != STATUS_WAIT_0) 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * 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 * FUNCTION: Queries the volume information
* ARGUMENTS: * ARGUMENTS:
@ -96,7 +86,16 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
* FileFsMaximumInformation * FileFsMaximumInformation
* *
* RETURNS: Status * 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; PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
@ -104,17 +103,19 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
NTSTATUS Status; NTSTATUS Status;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
PVOID SystemBuffer; PVOID SystemBuffer;
IO_STATUS_BLOCK IoSB; KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL); assert(IoStatusBlock != NULL);
assert(FsInformation != NULL); assert(FsInformation != NULL);
DPRINT("FsInformation %p\n", FsInformation); DPRINT("FsInformation %p\n", FsInformation);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_ATTRIBUTES, FILE_READ_ATTRIBUTES,
IoFileObjectType, IoFileObjectType,
UserMode, PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -142,13 +143,14 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
} }
//trigger FileObject/Event dereferencing /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = &IoSB; Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
@ -168,10 +170,10 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
{ {
KeWaitForSingleObject(&FileObject->Event, KeWaitForSingleObject(&FileObject->Event,
UserRequest, UserRequest,
KernelMode, PreviousMode,
FALSE, FALSE,
NULL); NULL);
Status = IoSB.Status; Status = IoStatusBlock->Status;
} }
DPRINT("Status %x\n", Status); DPRINT("Status %x\n", Status);
@ -180,12 +182,9 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
DPRINT("Information %lu\n", IoStatusBlock->Information); DPRINT("Information %lu\n", IoStatusBlock->Information);
MmSafeCopyToUser(FsInformation, MmSafeCopyToUser(FsInformation,
SystemBuffer, SystemBuffer,
IoSB.Information); IoStatusBlock->Information);
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
} }
ExFreePool(SystemBuffer); ExFreePool(SystemBuffer);
return(Status); return(Status);
@ -231,9 +230,9 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
} }
//trigger FileObject/Event dereferencing /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = FsInformation; Irp->AssociatedIrp.SystemBuffer = FsInformation;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
@ -289,12 +288,17 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
NTSTATUS Status; NTSTATUS Status;
PEXTENDED_IO_STACK_LOCATION StackPtr; PEXTENDED_IO_STACK_LOCATION StackPtr;
PVOID SystemBuffer; PVOID SystemBuffer;
IO_STATUS_BLOCK IoSB; KPROCESSOR_MODE PreviousMode;
assert(IoStatusBlock != NULL);
assert(FsInformation != NULL);
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_ATTRIBUTES, FILE_WRITE_ATTRIBUTES,
NULL, NULL,
UserMode, PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (Status != STATUS_SUCCESS) if (Status != STATUS_SUCCESS)
@ -325,13 +329,13 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
FsInformation, FsInformation,
Length); Length);
//trigger FileObject/Event dereferencing /* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = &IoSB; Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp); StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
@ -350,15 +354,12 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
{ {
KeWaitForSingleObject(&FileObject->Event, KeWaitForSingleObject(&FileObject->Event,
UserRequest, UserRequest,
KernelMode, PreviousMode,
FALSE, FALSE,
NULL); NULL);
Status = IoSB.Status; Status = IoStatusBlock->Status;
} }
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
}
ExFreePool(SystemBuffer); ExFreePool(SystemBuffer);
return(Status); return(Status);