IoStatusBlock is _not_ an optional parameter.

Fixed synchronous file access bug in NtDeviceIoControlFile().

svn path=/trunk/; revision=6549
This commit is contained in:
Eric Kohl 2003-11-06 18:05:54 +00:00
parent 98682c7937
commit 261cc33f7f
3 changed files with 191 additions and 221 deletions

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.68 2003/09/25 20:04:27 ekohl Exp $
/* $Id: create.c,v 1.69 2003/11/06 18:05:54 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -327,7 +327,7 @@ NTSTATUS STDCALL
IoCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
@ -343,7 +343,6 @@ IoCreateFile(OUT PHANDLE FileHandle,
NTSTATUS Status;
PIRP Irp;
PIO_STACK_LOCATION StackLoc;
IO_STATUS_BLOCK IoSB;
IO_SECURITY_CONTEXT SecurityContext;
DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
@ -352,7 +351,10 @@ IoCreateFile(OUT PHANDLE FileHandle,
ObjectAttributes->ObjectName->Buffer);
assert_irql(PASSIVE_LEVEL);
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
*FileHandle = 0;
Status = ObCreateObject(ExGetPreviousMode(),
@ -420,7 +422,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserIosb = &IoSB; //return iostatus
Irp->UserIosb = IoStatusBlock;
Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
@ -477,7 +479,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
KernelMode,
FALSE,
NULL);
Status = IoSB.Status;
Status = IoStatusBlock->Status;
}
if (!NT_SUCCESS(Status))
{
@ -487,10 +489,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
ZwClose(*FileHandle);
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
}
assert_irql(PASSIVE_LEVEL);
DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));

View file

@ -1,11 +1,11 @@
/* $Id: ioctrl.c,v 1.18 2003/07/10 15:47:00 royce Exp $
/* $Id: ioctrl.c,v 1.19 2003/11/06 18:05:54 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/ioctrl.c
* PURPOSE: Device IO control
* PROGRAMMER: David Welch (welch@mcmail.com)
* Eric Kohl (ekohl@abo.rhein-zeitung.de)
* Eric Kohl (ekohl@rz-online.de)
* UPDATE HISTORY:
* Created 22/05/98
* Filled in ZwDeviceIoControlFile 22/02/99
@ -25,99 +25,112 @@
/*
* @implemented
*/
NTSTATUS STDCALL NtDeviceIoControlFile (IN HANDLE DeviceHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE UserApcRoutine,
IN PVOID UserApcContext,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferSize)
NTSTATUS STDCALL
NtDeviceIoControlFile (IN HANDLE DeviceHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
IN PVOID UserApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength OPTIONAL,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PKEVENT ptrEvent;
IO_STATUS_BLOCK IoSB;
NTSTATUS Status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PKEVENT EventObject;
DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
"UserApcContext %x IoStatusBlock %x IoControlCode %x "
"InputBuffer %x InputBufferSize %x OutputBuffer %x "
"OutputBufferSize %x)\n",
DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
IoControlCode,InputBuffer,InputBufferSize,OutputBuffer,
OutputBufferSize);
DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
"UserApcContext %x IoStatusBlock %x IoControlCode %x "
"InputBuffer %x InputBufferLength %x OutputBuffer %x "
"OutputBufferLength %x)\n",
DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,
OutputBufferLength);
Status = ObReferenceObjectByHandle(DeviceHandle,
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
Status = ObReferenceObjectByHandle (DeviceHandle,
FILE_READ_DATA | FILE_WRITE_DATA,
IoFileObjectType,
KernelMode,
(PVOID *) &FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (Event != NULL)
{
Status = ObReferenceObjectByHandle (Event,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (FileObject);
return Status;
}
}
if (Event != NULL)
else
{
Status = ObReferenceObjectByHandle (Event,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
(PVOID*)&ptrEvent,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
return Status;
}
}
else
{
KeResetEvent (&FileObject->Event);
ptrEvent = &FileObject->Event;
}
EventObject = &FileObject->Event;
KeResetEvent (EventObject);
}
DeviceObject = FileObject->DeviceObject;
DeviceObject = FileObject->DeviceObject;
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
Irp = IoBuildDeviceIoControlRequest (IoControlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
InputBufferLength,
OutputBuffer,
OutputBufferSize,
OutputBufferLength,
FALSE,
ptrEvent,
Event ? IoStatusBlock : &IoSB);
EventObject,
IoStatusBlock);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->DeviceObject = DeviceObject;
StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->DeviceObject = DeviceObject;
StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
Status = IoCallDriver(DeviceObject,Irp);
if (Event == NULL && Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
{
KeWaitForSingleObject(ptrEvent,Executive,KernelMode,FALSE,NULL);
Status = IoSB.Status;
}
if (IoStatusBlock)
{
*IoStatusBlock = IoSB;
}
return(Status);
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,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return Status;
}
Status = IoStatusBlock->Status;
}
return Status;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: rw.c,v 1.45 2003/07/11 01:23:14 royce Exp $
/* $Id: rw.c,v 1.46 2003/11/06 18:05:54 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -35,28 +35,30 @@
*
* @implemented
*/
NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
HANDLE EventHandle,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK UserIoStatusBlock,
PVOID Buffer,
ULONG Length,
PLARGE_INTEGER ByteOffset,
PULONG Key)
NTSTATUS STDCALL
NtReadFile (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PKEVENT Event = NULL;
IO_STATUS_BLOCK Iosb;
PIO_STATUS_BLOCK IoStatusBlock;
PKEVENT EventObject = NULL;
DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
IoStatusBlock);
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_DATA,
IoFileObjectType,
@ -67,19 +69,19 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
{
return(Status);
}
if (ByteOffset == NULL)
{
ByteOffset = &FileObject->CurrentByteOffset;
}
if (EventHandle != NULL)
if (Event != NULL)
{
Status = ObReferenceObjectByHandle(EventHandle,
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
(PVOID*)&Event,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
@ -88,35 +90,26 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
}
}
else
{
Event = &FileObject->Event;
KeResetEvent(Event);
}
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
IoStatusBlock = &Iosb;
}
else
{
IoStatusBlock = UserIoStatusBlock;
EventObject = &FileObject->Event;
KeResetEvent(EventObject);
}
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
FileObject->DeviceObject,
Buffer,
Length,
ByteOffset,
Event,
EventObject,
IoStatusBlock);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
if (Key != NULL)
@ -127,42 +120,28 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
{
StackPtr->Parameters.Read.Key = 0;
}
Status = IoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
{
BOOLEAN Alertable;
if (FileObject->Flags & FO_ALERTABLE_IO)
{
Alertable = TRUE;
}
else
{
Alertable = FALSE;
}
Status = KeWaitForSingleObject(Event,
{
BOOLEAN Alertable;
Alertable = (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE;
Status = KeWaitForSingleObject (EventObject,
Executive,
UserMode,
Alertable,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = Iosb.Status;
return(Status);
}
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
*UserIoStatusBlock = Iosb;
Status = IoStatusBlock->Status;
}
return(Status);
return Status;
}
@ -180,28 +159,30 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
*
* @implemented
*/
NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
HANDLE EventHandle,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK UserIoStatusBlock,
PVOID Buffer,
ULONG Length,
PLARGE_INTEGER ByteOffset,
PULONG Key)
NTSTATUS STDCALL
NtWriteFile (IN HANDLE FileHandle,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PKEVENT Event = NULL;
IO_STATUS_BLOCK Iosb;
PIO_STATUS_BLOCK IoStatusBlock;
PKEVENT EventObject = NULL;
DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
IoStatusBlock);
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_DATA,
IoFileObjectType,
@ -212,51 +193,41 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
{
return(Status);
}
if (ByteOffset == NULL)
{
ByteOffset = &FileObject->CurrentByteOffset;
}
if (EventHandle != NULL)
{
Status = ObReferenceObjectByHandle(EventHandle,
SYNCHRONIZE,
ExEventObjectType,
UserMode,
(PVOID*)&Event,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
return(Status);
}
}
else
{
Event = &FileObject->Event;
KeResetEvent(Event);
}
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
IoStatusBlock = &Iosb;
}
else
{
IoStatusBlock = UserIoStatusBlock;
EventObject = &FileObject->Event;
KeResetEvent(EventObject);
}
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
FileObject->DeviceObject,
Buffer,
Length,
ByteOffset,
Event,
EventObject,
IoStatusBlock);
//trigger FileObject/Event dereferencing
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
@ -275,38 +246,25 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
Status = IoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && FileObject->Flags & FO_SYNCHRONOUS_IO)
{
BOOLEAN Alertable;
if (FileObject->Flags & FO_ALERTABLE_IO)
{
Alertable = TRUE;
}
else
{
Alertable = FALSE;
}
Status = KeWaitForSingleObject(Event,
{
BOOLEAN Alertable;
Alertable = (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE;
Status = KeWaitForSingleObject (EventObject,
Executive,
UserMode,
Alertable,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = Iosb.Status;
return(Status);
}
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
*UserIoStatusBlock = Iosb;
Status = IoStatusBlock->Status;
}
return(Status);
return Status;
}
@ -325,14 +283,14 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
NTSTATUS
STDCALL
NtReadFileScatter (
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
IN PVOID UserApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK UserIoStatusBlock,
IN FILE_SEGMENT_ELEMENT BufferDescription [],
IN ULONG BufferLength,
IN PLARGE_INTEGER ByteOffset,
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
IN PVOID UserApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK UserIoStatusBlock,
IN FILE_SEGMENT_ELEMENT BufferDescription [],
IN ULONG BufferLength,
IN PLARGE_INTEGER ByteOffset,
IN PULONG Key OPTIONAL
)
{
@ -355,14 +313,14 @@ NtReadFileScatter (
NTSTATUS
STDCALL
NtWriteFileGather (
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN FILE_SEGMENT_ELEMENT BufferDescription [],
IN ULONG BufferLength,
IN PLARGE_INTEGER ByteOffset,
IN ULONG BufferLength,
IN PLARGE_INTEGER ByteOffset,
IN PULONG Key OPTIONAL
)
{