I had posted a message on 15 April. Since I have some more details, I am
resubmitting this.
I have a filter driver that is causing system lockups when Symantec
Antivirus is installed. I am trying to find what could be the reason.
I have noticed that if I call IoCallDriver directly from the Create
dispatch thread, things work fine. On the other hand, if I do it through a
thread created from Create dispatch handler, system hangs.
The call hangs after the following steps
- I have called IoCallDriver as part of handling IRP_MJ_CREATE
- Then, some lower driver (probably Symantec antivirus ) generates
another create call to the same file - I make again a second call to IoCallDriver.
After this, I never see the call reaching my completion routine which
happens easily when I have the “same thread model”. Is there something
very obviosuly wrong here? Is there somewhere i can see a sample code that
does something similar to what I am trying? Below is the code snippet.
WHEN IT WORKS FINE (CREATE DISPATCH HANDLER CALLS IoCallDriver directly)
Create Dispatch Routine:
IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent( &eWaitEvent,NotificationEvent, FALSE );
pDispatch->eWaitEvent = &eWaitEvent;
IoSetCompletionRoutine(Irp,CompletionRoutine,LocalContext,
TRUE,TRUE,TRUE);
RC = IoCallDriver(PtrTargetDeviceObject, Irp);
if (STATUS_PENDING == RC)
{
RC = KeWaitForSingleObject( &eWaitEvent,Executive,KernelMode,
FALSE,NULL );
ASSERT(STATUS_SUCCESS == RC);
}
ASSERT(KeReadStateEvent(&eWaitEvent) ||
!NT_SUCCESS(Irp->IoStatus.Status));
try_return(RC = STATUS_PENDING);
Create Completion Routine
ExInitializeWorkItem(&(ptrIrpCompletionWorkItem->WorkItem),
IrpCompletionWIroutine, ptrIrpCompletionWorkItem );
ExQueueWorkItem(&(ptrIrpCompletionWorkItem->WorkItem),
CriticalWorkQueue);
try_return ( ntstatus=STATUS_MORE_PROCESSING_REQUIRED ) ;
Later on in the worker thread I make the call
IoCompleteRequest(Irp, IO_NO_INCREMENT);
WHEN IT DOES NOT WORK (ASYNCHRONOUS MODEL)
Create Dispatch Routine:
RC = PsCreateSystemThread( &hThreadNotUsed, 0L, NULL, (HANDLE)-1,
NULL, MJ_CREATE_ThreadProc, pThreadContext);
//Whether I wait here or not for an event to be set at the end of
MJ_CREATE_ThreadProc, ,
//in either case there is a problem
return STATUS_PENDING;