I develop a FSFilter.In my filter,I find a hang situation.
I do a test for describing it:
1.I implement shadowdevice.
2.When a IRP_MJ_CREATE coming,I ZwCreateFile the file by shadowdevice at first,and then I CallDown this IRP.
3.for test,I implement the IRP_MJ_CREATE dispatch routine for shadowdeviceobject,but my completionroutine never been called.
the IRP_MJ_CREATE dispatch routine:
NTSTATUS TestCreate(IN PDEVICE_OBJECT pDevObj, IN PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDevExt;
PDEVICE_OBJECT pRealDevObj;
…//get the filename;and I just handle \1.txt,others will passthrough
pDevExt=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;
if (pDevExt->nType==2) //Shadow DO
{
NTSTATUS status;
pRealDevObj=pDevExt->pRelatedDeviceObject;
status=KfCallFileSystem(pRealDevObj,Irp);
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return status;
}
if (pDevExt->nType==3) //volume DO
{
HandleSmart(pDevObj,szFileName);
status=KfCallFileSystem(pDevObj,Irp);
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return status;
}
}
void HandleSmart(PDEVICE_OBJECT pDevObj,PWCHAR fullpathname)
{
…;//initial the shadowDO+filename,ObjectAttributes
status = ZwCreateFile(&hFile,
(SYNCHRONIZE|FILE_READ_DATA|FILE_READ_ATTRIBUTES), &ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
if(!NT_SUCCESS(Status))
{
return ;
}
ZwClose(hFile);
}
NTSTATUS KfCallFileSystem(
IN PDEVICE_OBJECT pDevObj,
IN PIRP Irp
)
{
KEVENT event;
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pDevExt =
(PDEVICE_EXTENSION) pDevObj->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(Irp, &KfCommonCompletion, &event, TRUE, TRUE, TRUE);
status = IoCallDriver(pDevExt->pFileSystemDeviceObject, Irp);
if(status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
status = Irp->IoStatus.Status;
}
return status;
}
NTSTATUS KfCommonCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID pContext
)
{
KdPrint((“\r\nCompletion called:%p”,pContext));
PKEVENT SynchronizingEvent = (PKEVENT)pContext;
KeSetEvent( SynchronizingEvent, IO_NO_INCREMENT, FALSE );
return STATUS_MORE_PROCESSING_REQUIRED;
}
the run result is very strange!
In most Win2K,WinXP,Win2K3,these works fine!
But in some WinXP(maybe add some newest hotfix?),the result is hang!
the details for the hang:
1.I single-click D:\1.txt in Explorer.exe
2.the first IRP_MJ_CREATE for D:\1.txt come to my filter,TestCreate is called.
So,I call HandleSmart.
I call ZwCreateFile in HandleSmart.
a IRP_MJ_CREATE for Test19000:\1.txt (my shadowdevice) come to my filter,TestCreate is called.
KfCallFileSystem is called(for Test19000:\1.txt).
the KfCommonCompletion(for Test19000:\1.txt) is called.
Everything is OK!
…
3.the second IRP_MJ_CREATE for D:\1.txt come to myfilter,TestCreate is called.
So,I call HandleSmart.
I call ZwCreateFile in HandleSmart.
a IRP_MJ_CREATE for Test19000:\1.txt (my shadowdevice) come to my filter,TestCreate is called.
KfCallFileSystem is called(for Test19000:\1.txt).
the KfCommonCompletion(for Test19000:\1.txt) never been called!!!
hang!!!
Explorer.exe will issue many IRP_MJ_CREATE.
when the first IRP_MJ_CREATE is issued,explorer.exe will issue the second IRP_MJ_CREATE immediately(no IRP_MJ_CLEANUP.Thus,the two IRP_MJ_CREATE is shared open the D:\1.txt).
the first IRP_MJ_CREATE comes to my filter,everything is OK.
the second IRP_MJ_CREATE comes to my filter,hang!But if I modify the shareaccess from 0 to (FILE_SHARE_READ|FILE_SHARE_WRITE) in ZwCreateFile in HandleSmart,everything is OK(not hang!).
When hang,the IoCallDriver returns STATUS_PENDING.But,because the completionroutine never been called,so my KeWaitForSingleObject in KfCallFileSystem will hang!
thanks for any suggestion.