-Fixed FileObject/Event dereferencing at IRP completion problem

-Reworked IRP completion rotuines
-io/irp.c: Reworked IoIsOperationSynchronous
-afd/opnclose.c: Fixed bug where CCB was freed twice
-io/create.c: changed Lock event in FileObject from NotificationEvent to SynchronizationEvent

svn path=/trunk/; revision=4739
This commit is contained in:
Gunnar Dalsnes 2003-05-22 00:47:04 +00:00
parent 5af5f51b74
commit e76a3a5ab0
17 changed files with 260 additions and 232 deletions

View file

@ -242,13 +242,16 @@ AfdClose(
case IRP_MJ_CLEANUP: case IRP_MJ_CLEANUP:
FCB->OpenHandleCount--; FCB->OpenHandleCount--;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
ExFreePool(CCB);
break; break;
default: default:
Status = STATUS_INVALID_DEVICE_REQUEST; Status = STATUS_INVALID_DEVICE_REQUEST;
} }
ExFreePool(CCB); // ExFreePool(CCB);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;

View file

@ -169,7 +169,7 @@ LONG STDCALL
KeInsertQueue(IN PKQUEUE Queue, KeInsertQueue(IN PKQUEUE Queue,
IN PLIST_ENTRY Entry); IN PLIST_ENTRY Entry);
VOID STDCALL KeInsertQueueApc (PKAPC Apc, BOOLEAN STDCALL KeInsertQueueApc (PKAPC Apc,
PVOID SystemArgument1, PVOID SystemArgument1,
PVOID SystemArgument2, PVOID SystemArgument2,
UCHAR Mode); UCHAR Mode);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: io.h,v 1.30 2003/05/13 21:28:26 chorns Exp $ /* $Id: io.h,v 1.31 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -271,7 +271,13 @@ IoMountVolume(IN PDEVICE_OBJECT DeviceObject,
POBJECT IoOpenSymlink(POBJECT SymbolicLink); POBJECT IoOpenSymlink(POBJECT SymbolicLink);
POBJECT IoOpenFileOnDevice(POBJECT SymbolicLink, PWCHAR Name); POBJECT IoOpenFileOnDevice(POBJECT SymbolicLink, PWCHAR Name);
VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost); VOID STDCALL
IoSecondStageCompletion(
PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2);
NTSTATUS STDCALL NTSTATUS STDCALL
IopCreateFile(PVOID ObjectBody, IopCreateFile(PVOID ObjectBody,

View file

@ -20,52 +20,6 @@
#include <internal/debug.h> #include <internal/debug.h>
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
VOID STDCALL
IopCompleteRequest1(struct _KAPC* Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
{
PIRP Irp;
CCHAR PriorityBoost;
PIO_STACK_LOCATION IoStack;
PFILE_OBJECT FileObject;
DPRINT("IopCompleteRequest1()\n");
Irp = (PIRP)(*SystemArgument1);
PriorityBoost = (CCHAR)(LONG)(*SystemArgument2);
IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
FileObject = IoStack->FileObject;
(*SystemArgument1) = (PVOID)Irp->UserIosb;
(*SystemArgument2) = (PVOID)Irp->IoStatus.Information;
if (Irp->UserIosb!=NULL)
{
*Irp->UserIosb=Irp->IoStatus;
}
if (Irp->UserEvent)
{
KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
}
if (!(Irp->Flags & IRP_PAGING_IO) && FileObject)
{
if (IoStack->MajorFunction != IRP_MJ_CLOSE)
{
ObDereferenceObject(FileObject);
}
}
IoFreeIrp(Irp);
}
VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject, VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject,
PIRP Irp, PIRP Irp,
PIO_STACK_LOCATION IoStack) PIO_STACK_LOCATION IoStack)
@ -171,99 +125,155 @@ VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
{ {
} }
VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost)
VOID STDCALL
IoSecondStageCompletion_KernelApcRoutine(
IN PKAPC Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
)
{
IoFreeIrp((PIRP)(*SystemArgument1));
}
VOID STDCALL
IoSecondStageCompletion_RundownApcRoutine(
IN PKAPC Apc
)
{
PIRP Irp;
Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
IoFreeIrp(Irp);
}
/* /*
* FUNCTION: Performs the second stage of irp completion for read/write irps * FUNCTION: Performs the second stage of irp completion for read/write irps
* ARGUMENTS: *
* Irp = Irp to completion * Called as a special kernel APC or directly from IofCompleteRequest()
* FromDevice = True if the operation transfered data from the device
*/ */
VOID STDCALL
IoSecondStageCompletion(
PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
{ {
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject; PFILE_OBJECT OriginalFileObject;
PIRP Irp;
DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n", CCHAR PriorityBoost;
Irp, PriorityBoost);
OriginalFileObject = (PFILE_OBJECT)(*NormalContext);
Irp = (PIRP)(*SystemArgument1);
PriorityBoost = (CCHAR)(LONG)(*SystemArgument2);
IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation]; IoStack = &Irp->Stack[(ULONG)Irp->CurrentLocation];
FileObject = IoStack->FileObject;
DeviceObject = IoStack->DeviceObject; DeviceObject = IoStack->DeviceObject;
DPRINT("IoSecondStageCompletion(Irp %x, PriorityBoost %d)\n", Irp, PriorityBoost);
switch (IoStack->MajorFunction) switch (IoStack->MajorFunction)
{ {
case IRP_MJ_CREATE: case IRP_MJ_CREATE:
case IRP_MJ_FLUSH_BUFFERS: case IRP_MJ_FLUSH_BUFFERS:
/* NOP */ /* NOP */
break; break;
case IRP_MJ_READ: case IRP_MJ_READ:
case IRP_MJ_WRITE: case IRP_MJ_WRITE:
IoReadWriteCompletion(DeviceObject,Irp,IoStack); IoReadWriteCompletion(DeviceObject,Irp,IoStack);
break; break;
case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_DEVICE_CONTROL:
case IRP_MJ_INTERNAL_DEVICE_CONTROL: case IRP_MJ_INTERNAL_DEVICE_CONTROL:
IoDeviceControlCompletion(DeviceObject, Irp, IoStack); IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
break; break;
case IRP_MJ_QUERY_VOLUME_INFORMATION: case IRP_MJ_QUERY_VOLUME_INFORMATION:
case IRP_MJ_SET_VOLUME_INFORMATION: case IRP_MJ_SET_VOLUME_INFORMATION:
IoVolumeInformationCompletion(DeviceObject, Irp, IoStack); IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
break; break;
default: default:
break; break;
} }
if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
{
PKTHREAD Thread;
PKNORMAL_ROUTINE UserApcRoutine;
PVOID UserApcContext;
DPRINT("Dispatching APC\n");
Thread = &Irp->Tail.Overlay.Thread->Tcb;
UserApcRoutine = (PKNORMAL_ROUTINE)
Irp->Overlay.AsynchronousParameters.UserApcRoutine;
UserApcContext = (PVOID)
Irp->Overlay.AsynchronousParameters.UserApcContext;
KeInitializeApc(&Irp->Tail.Apc,
Thread,
0,
IopCompleteRequest1,
NULL,
UserApcRoutine,
UserMode,
UserApcContext);
KeInsertQueueApc(&Irp->Tail.Apc,
Irp,
(PVOID)(LONG)PriorityBoost,
KernelMode);
return;
}
DPRINT("Irp->UserIosb %x &Irp->UserIosb %x\n",
Irp->UserIosb,
&Irp->UserIosb);
if (Irp->UserIosb!=NULL) if (Irp->UserIosb!=NULL)
{ {
*Irp->UserIosb=Irp->IoStatus; *Irp->UserIosb=Irp->IoStatus;
} }
if (Irp->UserEvent) if (Irp->UserEvent)
{ {
KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE); KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
} }
if (!(Irp->Flags & IRP_PAGING_IO) && FileObject) //Windows NT File System Internals, page 169
if (OriginalFileObject)
{ {
if (IoStack->MajorFunction != IRP_MJ_CLOSE) if (Irp->UserEvent == NULL)
{ {
ObDereferenceObject(FileObject); KeSetEvent(&OriginalFileObject->Event,PriorityBoost,FALSE);
}
else if (OriginalFileObject->Flags & FO_SYNCHRONOUS_IO && Irp->UserEvent != &OriginalFileObject->Event)
{
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)
{
ObDereferenceObject(Irp->UserEvent);
}
if (IoStack->MajorFunction != IRP_MJ_CLOSE)
{
ObDereferenceObject(OriginalFileObject);
}
}
if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
{
PKNORMAL_ROUTINE UserApcRoutine;
PVOID UserApcContext;
DPRINT("Dispatching user APC\n");
UserApcRoutine = (PKNORMAL_ROUTINE)Irp->Overlay.AsynchronousParameters.UserApcRoutine;
UserApcContext = (PVOID)Irp->Overlay.AsynchronousParameters.UserApcContext;
KeInitializeApc( &Irp->Tail.Apc,
KeGetCurrentThread(),
0,
IoSecondStageCompletion_KernelApcRoutine,
IoSecondStageCompletion_RundownApcRoutine,
UserApcRoutine,
UserMode,
UserApcContext);
KeInsertQueueApc( &Irp->Tail.Apc,
Irp,
NULL,
KernelMode);
//NOTE: kernel (or rundown) routine frees the IRP
return;
}
IoFreeIrp(Irp); IoFreeIrp(Irp);
} }

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.63 2003/05/12 10:00:46 ekohl Exp $ /* $Id: create.c,v 1.64 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -378,7 +378,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
SecurityContext.DesiredAccess = DesiredAccess; SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0; /* ?? */ SecurityContext.FullCreateOptions = 0; /* ?? */
KeInitializeEvent(&FileObject->Lock, NotificationEvent, TRUE); KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE); KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
DPRINT("FileObject %x\n", FileObject); DPRINT("FileObject %x\n", FileObject);
@ -394,6 +394,9 @@ IoCreateFile(OUT PHANDLE FileHandle,
ZwClose(*FileHandle); ZwClose(*FileHandle);
return (STATUS_UNSUCCESSFUL); return (STATUS_UNSUCCESSFUL);
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserIosb = &IoSB; //return iostatus Irp->UserIosb = &IoSB; //return iostatus
Irp->AssociatedIrp.SystemBuffer = EaBuffer; Irp->AssociatedIrp.SystemBuffer = EaBuffer;

View file

@ -1,4 +1,4 @@
/* $Id: dir.c,v 1.15 2002/09/08 10:23:24 chorns Exp $ /* $Id: dir.c,v 1.16 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -111,6 +111,8 @@ NtQueryDirectoryFile(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserIosb = &IoSB; Irp->UserIosb = &IoSB;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;

View file

@ -1,4 +1,4 @@
/* $Id: file.c,v 1.23 2003/03/23 14:46:09 ekohl Exp $ /* $Id: file.c,v 1.24 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -80,6 +80,9 @@ NtQueryInformationFile(HANDLE FileHandle,
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = &IoSB; Irp->UserIosb = &IoSB;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
@ -161,6 +164,9 @@ IoQueryFileInformation(IN PFILE_OBJECT FileObject,
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->AssociatedIrp.SystemBuffer = FileInformation; Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->UserIosb = &IoStatusBlock; Irp->UserIosb = &IoStatusBlock;
@ -293,6 +299,9 @@ NtSetInformationFile(HANDLE FileHandle,
FileInformation, FileInformation,
Length); Length);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = &IoSB; Irp->UserIosb = &IoSB;
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;

View file

@ -69,6 +69,9 @@ NtFlushBuffersFile (
&FileObject->Event, &FileObject->Event,
&IoSB); &IoSB);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject; StackPtr->FileObject = FileObject;

View file

@ -1,4 +1,4 @@
/* $Id: fs.c,v 1.32 2003/05/13 21:28:26 chorns Exp $ /* $Id: fs.c,v 1.33 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -129,6 +129,9 @@ NtFsControlFile (
ptrEvent, ptrEvent,
&IoSB); &IoSB);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;

View file

@ -1,4 +1,4 @@
/* $Id: ioctrl.c,v 1.16 2002/09/08 10:23:25 chorns Exp $ /* $Id: ioctrl.c,v 1.17 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -92,6 +92,9 @@ NTSTATUS STDCALL NtDeviceIoControlFile (IN HANDLE DeviceHandle,
ptrEvent, ptrEvent,
Event ? IoStatusBlock : &IoSB); Event ? IoStatusBlock : &IoSB);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;

View file

@ -1,4 +1,4 @@
/* $Id: iomgr.c,v 1.32 2003/05/13 21:28:26 chorns Exp $ /* $Id: iomgr.c,v 1.33 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -58,11 +58,15 @@ IopCloseFile(PVOID ObjectBody,
{ {
return; return;
} }
#if 0
//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
ObReferenceObjectByPointer(FileObject, ObReferenceObjectByPointer(FileObject,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
IoFileObjectType, IoFileObjectType,
UserMode); UserMode);
#endif
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP, Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
@ -94,11 +98,14 @@ IopDeleteFile(PVOID ObjectBody)
if (FileObject->DeviceObject) if (FileObject->DeviceObject)
{ {
#if 0
//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
ObReferenceObjectByPointer(ObjectBody, ObReferenceObjectByPointer(ObjectBody,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
IoFileObjectType, IoFileObjectType,
UserMode); UserMode);
#endif
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE, Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
FileObject->DeviceObject, FileObject->DeviceObject,

View file

@ -1,4 +1,4 @@
/* $Id: irp.c,v 1.49 2003/05/17 00:25:39 chorns Exp $ /* $Id: irp.c,v 1.50 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -191,25 +191,9 @@ IoAllocateIrp(CCHAR StackSize,
} }
VOID STDCALL
IopCompleteRequest(struct _KAPC* Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
{
DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
Apc,
SystemArgument1,
*SystemArgument1);
IoSecondStageCompletion((PIRP)(*SystemArgument1),
(KPRIORITY)(*SystemArgument2));
}
VOID FASTCALL VOID FASTCALL
IofCompleteRequest(PIRP Irp, IofCompleteRequest(PIRP Irp,
CCHAR PriorityBoost) CCHAR PriorityBoost)
/* /*
* FUNCTION: Indicates the caller has finished all processing for a given * FUNCTION: Indicates the caller has finished all processing for a given
* I/O request and is returning the given IRP to the I/O manager * I/O request and is returning the given IRP to the I/O manager
@ -222,6 +206,7 @@ IofCompleteRequest(PIRP Irp,
ULONG i; ULONG i;
NTSTATUS Status; NTSTATUS Status;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT OriginalFileObject;
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n", DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread()); Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
@ -275,30 +260,42 @@ IofCompleteRequest(PIRP Irp,
} }
} }
//Windows NT File System Internals, page 154
OriginalFileObject = Irp->Tail.Overlay.OriginalFileObject;
if (Irp->PendingReturned) if (Irp->PendingReturned)
{ {
DPRINT("Dispatching APC\n"); BOOLEAN bStatus;
KeInitializeApc(&Irp->Tail.Apc,
&Irp->Tail.Overlay.Thread->Tcb, DPRINT("Dispatching APC\n");
0, KeInitializeApc( &Irp->Tail.Apc,
IopCompleteRequest, &Irp->Tail.Overlay.Thread->Tcb,
NULL, 0,
(PKNORMAL_ROUTINE) IoSecondStageCompletion,
NULL, NULL,
KernelMode, (PKNORMAL_ROUTINE) NULL,
NULL); KernelMode,
KeInsertQueueApc(&Irp->Tail.Apc, OriginalFileObject);
(PVOID)Irp,
(PVOID)(ULONG)PriorityBoost, bStatus = KeInsertQueueApc(&Irp->Tail.Apc,
KernelMode); (PVOID)Irp,
DPRINT("Finished dispatching APC\n"); (PVOID)(ULONG)PriorityBoost,
} KernelMode);
if (bStatus == FALSE)
{
DPRINT1("Error queueing APC for thread. Thread has probably exited.\n");
}
DPRINT("Finished dispatching APC\n");
}
else else
{ {
DPRINT("Calling completion routine directly\n"); DPRINT("Calling IoSecondStageCompletion routine directly\n");
IoSecondStageCompletion(Irp,PriorityBoost); IoSecondStageCompletion(NULL,NULL,(PVOID)&OriginalFileObject,(PVOID) &Irp,(PVOID) &PriorityBoost);
DPRINT("Finished completition routine\n"); DPRINT("Finished completition routine\n");
} }
} }
@ -328,31 +325,28 @@ IoCompleteRequest(PIRP Irp,
BOOLEAN STDCALL BOOLEAN STDCALL
IoIsOperationSynchronous(IN PIRP Irp) IoIsOperationSynchronous(IN PIRP Irp)
{ {
PFILE_OBJECT FileObject = NULL; PFILE_OBJECT FileObject = NULL;
ULONG Flags = 0;
/* Check the FILE_OBJECT's flags first. */ FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
if (!(FO_SYNCHRONOUS_IO & FileObject->Flags)) if (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO)
{ {
/* Check IRP's flags. */ return TRUE;
Flags = Irp->Flags; }
if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
{
return(FALSE);
}
}
/* Check more IRP's flags. */ if (Irp->Flags & IRP_PAGING_IO)
Flags = Irp->Flags; {
if (!(IRP_PAGING_IO & Flags) return FALSE;
|| (IRP_SYNCHRONOUS_PAGING_IO & Flags)) }
{
return(TRUE);
}
/* Otherwise, it is an asynchronous operation. */ //NOTE: Windows 2000 crash if IoStack->FileObject == NULL, so I guess we should too;-)
return(FALSE); if (Irp->Flags & IRP_SYNCHRONOUS_API || FileObject->Flags & FO_SYNCHRONOUS_IO)
{
return TRUE;
}
/* Otherwise, it is an asynchronous operation. */
return FALSE;
} }

View file

@ -114,6 +114,9 @@ NtLockFile (
else else
IoStatusBlock = UserIoStatusBlock; IoStatusBlock = UserIoStatusBlock;
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -250,6 +253,9 @@ NtUnlockFile (
goto fail; goto fail;
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserIosb = &LocalIoStatusBlock; Irp->UserIosb = &LocalIoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->Tail.Overlay.Thread = PsGetCurrentThread();

View file

@ -1,4 +1,4 @@
/* $Id: rw.c,v 1.42 2003/05/16 12:03:11 chorns Exp $ /* $Id: rw.c,v 1.43 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -21,23 +21,6 @@
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
NTSTATUS STDCALL
IopReadWriteIoComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
PIO_STACK_LOCATION IrpStack;
DPRINT("IopReadWriteIoComplete(DeviceObject %p Irp %p Context %p) called\n",
DeviceObject, Irp, Context);
IrpStack = IoGetCurrentIrpStackLocation(Irp);
ObDereferenceObject(Irp->UserEvent);
return STATUS_SUCCESS;
}
/********************************************************************** /**********************************************************************
* NAME EXPORTED * NAME EXPORTED
* NtReadFile * NtReadFile
@ -68,7 +51,6 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
PKEVENT Event = NULL; PKEVENT Event = NULL;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
PIO_STATUS_BLOCK IoStatusBlock; PIO_STATUS_BLOCK IoStatusBlock;
BOOLEAN SetIoCompletionRoutine;
DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset, "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
@ -103,13 +85,12 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return(Status); return(Status);
} }
SetIoCompletionRoutine = TRUE;
} }
else else
{ {
Event = &FileObject->Event; Event = &FileObject->Event;
KeResetEvent(Event); KeResetEvent(Event);
SetIoCompletionRoutine = FALSE;
} }
if (FileObject->Flags & FO_SYNCHRONOUS_IO) if (FileObject->Flags & FO_SYNCHRONOUS_IO)
@ -128,6 +109,9 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
ByteOffset, ByteOffset,
Event, Event,
IoStatusBlock); IoStatusBlock);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -143,16 +127,6 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle,
StackPtr->Parameters.Read.Key = 0; StackPtr->Parameters.Read.Key = 0;
} }
if (SetIoCompletionRoutine)
{
/* Set completion routine */
IoSetCompletionRoutine(Irp,
IopReadWriteIoComplete,
NULL,
TRUE,
TRUE,
TRUE);
}
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)
@ -221,7 +195,6 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
PKEVENT Event = NULL; PKEVENT Event = NULL;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
PIO_STATUS_BLOCK IoStatusBlock; PIO_STATUS_BLOCK IoStatusBlock;
BOOLEAN SetIoCompletionRoutine;
DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset, "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
@ -256,13 +229,12 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return(Status); return(Status);
} }
SetIoCompletionRoutine = TRUE;
} }
else else
{ {
Event = &FileObject->Event; Event = &FileObject->Event;
KeResetEvent(Event); KeResetEvent(Event);
SetIoCompletionRoutine = FALSE;
} }
if (FileObject->Flags & FO_SYNCHRONOUS_IO) if (FileObject->Flags & FO_SYNCHRONOUS_IO)
@ -282,6 +254,9 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
Event, Event,
IoStatusBlock); IoStatusBlock);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
@ -296,17 +271,6 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle,
StackPtr->Parameters.Write.Key = 0; StackPtr->Parameters.Write.Key = 0;
} }
if (SetIoCompletionRoutine)
{
/* Set completion routine */
IoSetCompletionRoutine(Irp,
IopReadWriteIoComplete,
NULL,
TRUE,
TRUE,
TRUE);
}
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)
{ {

View file

@ -1,4 +1,4 @@
/* $Id: vpb.c,v 1.19 2002/09/08 10:23:26 chorns Exp $ /* $Id: vpb.c,v 1.20 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -139,6 +139,9 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;
@ -221,6 +224,9 @@ IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES); return(STATUS_INSUFFICIENT_RESOURCES);
} }
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->AssociatedIrp.SystemBuffer = FsInformation; Irp->AssociatedIrp.SystemBuffer = FsInformation;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
@ -310,6 +316,9 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
FsInformation, FsInformation,
Length); Length);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->AssociatedIrp.SystemBuffer = SystemBuffer; Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
KeResetEvent( &FileObject->Event ); KeResetEvent( &FileObject->Event );
Irp->UserEvent = &FileObject->Event; Irp->UserEvent = &FileObject->Event;

View file

@ -287,7 +287,7 @@ KiDeliverApc(ULONG Unknown1,
KeReleaseSpinLock(&PiApcLock, oldlvl); KeReleaseSpinLock(&PiApcLock, oldlvl);
} }
VOID STDCALL BOOLEAN STDCALL
KeInsertQueueApc (PKAPC Apc, KeInsertQueueApc (PKAPC Apc,
PVOID SystemArgument1, PVOID SystemArgument1,
PVOID SystemArgument2, PVOID SystemArgument2,
@ -300,6 +300,7 @@ KeInsertQueueApc (PKAPC Apc,
* Mode = TBD * Mode = TBD
*/ */
{ {
//FIXME: return FALSE if APC can't be queued to target thread (thread has ended)
KIRQL oldlvl; KIRQL oldlvl;
PKTHREAD TargetThread; PKTHREAD TargetThread;
@ -343,7 +344,7 @@ KeInsertQueueApc (PKAPC Apc,
Apc->NormalRoutine == NULL) Apc->NormalRoutine == NULL)
{ {
KeReleaseSpinLock(&PiApcLock, oldlvl); KeReleaseSpinLock(&PiApcLock, oldlvl);
return; return TRUE;
} }
/* /*
@ -397,6 +398,7 @@ KeInsertQueueApc (PKAPC Apc,
STATUS_USER_APC); STATUS_USER_APC);
} }
KeReleaseSpinLock(&PiApcLock, oldlvl); KeReleaseSpinLock(&PiApcLock, oldlvl);
return TRUE;
} }
BOOLEAN STDCALL BOOLEAN STDCALL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: input.c,v 1.6 2003/05/18 17:16:17 ea Exp $ /* $Id: input.c,v 1.7 2003/05/22 00:47:04 gdalsnes Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -226,6 +226,10 @@ InitInputImpl(VOID)
TRUE, TRUE,
&FileObject->Event, &FileObject->Event,
&Iosb); &Iosb);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject; StackPtr->FileObject = FileObject;
StackPtr->DeviceObject = FileObject->DeviceObject; StackPtr->DeviceObject = FileObject->DeviceObject;