Strange problem for recursive IRP_MJ_CREATE

I found a very strange problem.
my filter will work well in many WinXP,but in some WinXP(maybe add some
hotfix),my filter will meet a strange recursive IRP_MJ_CREATE.

I will describe it by the following example:
1.explorer.exe (PID 5ec,TID 750) open D:\1.txt
in my filter,I meet a IRP_MJ_CREATE for D:\1.txt
2.In this IRP_MJ_CREATE,I will call IoCreateFileSpecifyDeviceObjectHint for D:\1.txt ,
I issue it in the same thread context(PID 5ec,TID 750).
3.I will meet many recursive IRP_MJ_CREATE!
these IRP_MJ_CREATE is for:
C:\WINDOWS\system32\Msctf.dll

This problem is very strange.I’m not newbie in FSD filter.
please refer my code and windbg’s out.

In my filter IRP_MJ_CREATE handler:
my test code is following:
{
…g_timeout is 30 seconds…
NTSTATUS statusSyn;
statusSyn=KeWaitForSingleObject(g_pSyn_Test,Executive,KernelMode,FALSE,&g_timeout);
if (statusSyn==STATUS_TIMEOUT)
{
KdPrint((“\r\n@@@@@@timeout:%x,%x,%ws”,nThisPID,nThisTID,szFileName));
KdPrint((“\r\n!!!timeout”));
}
KdPrint((“\r\n—before Open :%x,%x,%ws”,nThisPID,nThisTID,szFileName));
HandleSmart(pDevObj,szFileName);//my call FSD
nRet=KfCallFileSystem(pDevObj,Irp);
KdPrint((“\r\n!!!after Open :%x,%x,%ws”,nThisPID,nThisTID,szFileName));
IoCompleteRequest(Irp,IO_NO_INCREMENT);
KdPrint((“\r\n^^^complete Open :%x,%x,%ws”,nThisPID,nThisTID,szFileName));
KeReleaseSemaphore(g_pSyn_Test,0,1,FALSE);
return nRet;
}

the function HandleSmart is:
void HandleSmart(PDEVICE_OBJECT pDevObj,PWCHAR fullpathname)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
UNICODE_STRING FileName;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status = STATUS_SUCCESS;
HANDLE hFile;

PWCHAR fullpathnameIO=NULL;
fullpathnameIO=(PWCHAR)ExAllocatePool(NonPagedPool,MAX_PATH_LEN*sizeof(WCHAR));
memset(fullpathnameIO,0,MAX_PATH_LEN*sizeof(WCHAR));

wcscpy(fullpathnameIO,L"\??\“);
wcscat(fullpathnameIO,fullpathname);
KdPrint((”\r\nMy FileName:%ws",fullpathnameIO));

RtlInitUnicodeString(&FileName, fullpathnameIO);
InitializeObjectAttributes(&ObjectAttributes, // ptr to structure
&FileName, // ptr to file spec
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, // attributes
NULL, // root directory handle
NULL ); // ptr to security descriptor

KdPrint((“\r\nOpeExistSmart Create 1 before:%ws”,fullpathname));
Status= IoCreateFileSpecifyDeviceObjectHint(
&hFile,
(SYNCHRONIZE | FILE_READ_DATA|FILE_READ_ATTRIBUTES),
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_IGNORE_SHARE_ACCESS_CHECK,
pDevExt->pFileSystemDeviceObject
);

KdPrint((“\r\nOpeExistSmart Create 2 after:%ws”,fullpathname));
if(!NT_SUCCESS(Status))
{
ExFreePool(fullpathnameIO);
return ;
}
ExFreePool(fullpathnameIO);
KdPrint((“\r\nOpeExistSmart Create close before:%ws”,fullpathname));
ZwClose(hFile);
KdPrint((“\r\nOpeExistSmart Create close after:%ws”,fullpathname));
}

When I single-click the D:\1.txt in Explorer.exe,the windbg’s output is:
—before Open :5ec,750,D:\1.txt
My FileName:??\D:\1.txt
OpeExistSmart Create 1 before:D:\1.txt
OpeExistSmart Create 2 after:D:\1.txt
OpeExistSmart Create close before:D:\1.txt
OpeExistSmart Create close after:D:\1.txt
!!!after Open :5ec,750,D:\1.txt
^^^complete Open :5ec,750,D:\1.txt
—before Open :5ec,750,D:\1.txt
My FileName:??\D:\1.txt
OpeExistSmart Create 1 before:D:\1.txt

OK,deadlock,after 30 seconds,the windbg’s output is:
@@@@@@timeout:264,f8,C:\WINDOWS\system32\Msctf.dll

the process 5ec is Explorer.exe
the process 264 is WinLogon.exe

Hi Clark,

I went through the code, but could not quite understand what you are trying to do. Check comments.

This problem is very strange.I’m not newbie in FSD filter.
please refer my code and windbg’s out.

nRet=KfCallFileSystem(pDevObj,Irp);

What’s this for?

IoCompleteRequest(Irp,IO_NO_INCREMENT);

What are you trying to complete the IRP for?

When I single-click the D:\1.txt in Explorer.exe,the windbg’s output is:
—before Open :5ec,750,D:\1.txt
My FileName:??\D:\1.txt
OpeExistSmart Create 1 before:D:\1.txt
OpeExistSmart Create 2 after:D:\1.txt
OpeExistSmart Create close before:D:\1.txt
OpeExistSmart Create close after:D:\1.txt
!!!after Open :5ec,750,D:\1.txt
^^^complete Open :5ec,750,D:\1.txt
—before Open :5ec,750,D:\1.txt
My FileName:??\D:\1.txt
OpeExistSmart Create 1 before:D:\1.txt

OK,deadlock,after 30 seconds,the windbg’s output is:
@@@@@@timeout:264,f8,C:\WINDOWS\system32\Msctf.dll

the process 5ec is Explorer.exe
the process 264 is WinLogon.exe

Is this really recursive? Think…
The call for C:\WINDOWS\system32\Msctf.dll is coming in the context of Winlogon.exe.
Whereas the original call was in the context of explorer.exe.

Regards,
Ayush Gupta

sorry,KfCallFileSystem is my function,just call down the IRP,and wait for complete.
My filter(and the test code) is work well in many WinXP,Win2K3,and work well in many month.
But in some WinXP,it can’t work.

the code:
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;
}

Hi clark,

Just after the call to KfCallFileSystem, you have completed the IRP. What’s that all about?
Do you own the IRP? I suppose NO. So basically you are first sending it to the FSD for processing and then you yourself are also completing the IRP. That is very strange. This is not correct I suppose. Try to explain why you are doing so…

Regards,
Ayush Gupta

Hi Clark,

Ignore the last post about IocompleteRequest. I got confused with something else.

Regards,

Ayush Gupta

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Ayush Gupta
Sent: Monday, January 14, 2008 2:29 AM
To: Windows File Systems Devs Interest List
Subject: RE: [ntfsd] Strange problem for recursive IRP_MJ_CREATE

Hi clark,

Just after the call to KfCallFileSystem, you have completed the IRP. What’s that all about?

Do you own the IRP? I suppose NO. So basically you are first sending it to the FSD for processing and then you yourself are also completing the IRP. That is very strange. This is not correct I suppose. Try to explain why you are doing so…

Regards,

Ayush Gupta


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi Clark,

So, what I can see right now is that IoCreateFileSpecifyDeviceObjectHint has hung up somewhere. But there is NO recursion.
You are seeing the IRP_MJ_CREATE for C:\WINDOWS\system32\Msctf.dll in a different thread context.
Since, the original call is still stuck somewhere in IoCreateFileSpecifyDeviceObjectHint, you have not been able to release the semaphore.
When the next call comes, it waits for 30 seconds and then timeout, and hence you are seeing the message.

Notice two things:

  1. This is not a recursive call.
  2. The call is getting stuck somewhere in IoCreateFileSpecifyDeviceObjectHint.

I would suggest you to find out why is it getting stuck in IoCreateFileSpecifyDeviceObjectHint. AFAIK, IoCreateFileSpecifyDeviceObjectHint causes the IRP_MJ_CREATE to enter top of the stack only when the DeviceObject parameter is set to NULL. But you have set it, so there should be no recursion.

Play with WinDbg a bit. :slight_smile:

Regards,
Ayush Gupta

IoCreateFileSpecifyDeviceObjectHint is hanged?maybe.
How can I find it?and find what the cause for hang?

>IoCreateFileSpecifyDeviceObjectHint is hanged?maybe.

How can I find it?and find what the cause for hang?

On a very high level view, try to trace the call stack from your call to IoCreateFileSpecifyDeviceObjectHint till Ntfs’s/ Fastfat’s create handler.
See the call stack and see what dispatch routines are being called.
If it is reaching Ntfs’s create handler, go deep (check the disassembly) and see what’s the problem. If it is not reaching there, this means it is getting stuck somewhere before that. Check the corresponding dispatch handler or the function that is getting stuck.

Just use the good-nice facility of *breakpoints* to find out where the call is getting stuck. Use combinations of t (trace),p(step) and g(go) to reach the point of the *black hole* (where the call gets stuck).

Regards,
Ayush Gupta

From the dbgprint output, it looks indeed like
IoCreateFileSpecifyDeviceObjectHint is not returning. What seems odd but
probably not the problem is that the KeReleaseSemaphore is called even in
the case a wait is not satisfied but timed out, increasing the semaphore
count regardless. Also may I suggest you check if your pool allocations have
succeeded before using the pointers.

/Daniel

wrote in message news:xxxxx@ntfsd…
>I found a very strange problem.
> my filter will work well in many WinXP,but in some WinXP(maybe add some
> hotfix),my filter will meet a strange recursive IRP_MJ_CREATE.
>
> I will describe it by the following example:
> 1.explorer.exe (PID 5ec,TID 750) open D:\1.txt
> in my filter,I meet a IRP_MJ_CREATE for D:\1.txt
> 2.In this IRP_MJ_CREATE,I will call IoCreateFileSpecifyDeviceObjectHint
> for D:\1.txt ,
> I issue it in the same thread context(PID 5ec,TID 750).
> 3.I will meet many recursive IRP_MJ_CREATE!
> these IRP_MJ_CREATE is for:
> C:\WINDOWS\system32\Msctf.dll
> …
>
> This problem is very strange.I’m not newbie in FSD filter.
> please refer my code and windbg’s out.
>
> In my filter IRP_MJ_CREATE handler:
> my test code is following:
> {
> …g_timeout is 30 seconds…
> NTSTATUS statusSyn;
> statusSyn=KeWaitForSingleObject(g_pSyn_Test,Executive,KernelMode,FALSE,&g_timeout);
> if (statusSyn==STATUS_TIMEOUT)
> {
> KdPrint((“\r\n@@@@@@timeout:%x,%x,%ws”,nThisPID,nThisTID,szFileName));
> KdPrint((“\r\n!!!timeout”));
> }
> KdPrint((“\r\n—before Open :%x,%x,%ws”,nThisPID,nThisTID,szFileName));
> HandleSmart(pDevObj,szFileName);//my call FSD
> nRet=KfCallFileSystem(pDevObj,Irp);
> KdPrint((“\r\n!!!after Open :%x,%x,%ws”,nThisPID,nThisTID,szFileName));
> IoCompleteRequest(Irp,IO_NO_INCREMENT);
> KdPrint((“\r\n^^^complete Open :%x,%x,%ws”,nThisPID,nThisTID,szFileName));
> KeReleaseSemaphore(g_pSyn_Test,0,1,FALSE);
> return nRet;
> }
>
> the function HandleSmart is:
> void HandleSmart(PDEVICE_OBJECT pDevObj,PWCHAR fullpathname)
> {
> PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
> UNICODE_STRING FileName;
> OBJECT_ATTRIBUTES ObjectAttributes;
> IO_STATUS_BLOCK IoStatus;
> NTSTATUS Status = STATUS_SUCCESS;
> HANDLE hFile;
>
> PWCHAR fullpathnameIO=NULL;
> fullpathnameIO=(PWCHAR)ExAllocatePool(NonPagedPool,MAX_PATH_LENsizeof(WCHAR));
> memset(fullpathnameIO,0,MAX_PATH_LEN
sizeof(WCHAR));
>
> wcscpy(fullpathnameIO,L"\??\“);
> wcscat(fullpathnameIO,fullpathname);
> KdPrint((”\r\nMy FileName:%ws",fullpathnameIO));
>
> RtlInitUnicodeString(&FileName, fullpathnameIO);
> InitializeObjectAttributes(&ObjectAttributes, // ptr to
> structure
> &FileName, // ptr to file spec
> OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, // attributes
> NULL, // root directory handle
> NULL ); // ptr to security descriptor
>
> KdPrint((“\r\nOpeExistSmart Create 1 before:%ws”,fullpathname));
> Status= IoCreateFileSpecifyDeviceObjectHint(
> &hFile,
> (SYNCHRONIZE | FILE_READ_DATA|FILE_READ_ATTRIBUTES),
> &ObjectAttributes,
> &IoStatus,
> NULL,
> FILE_ATTRIBUTE_NORMAL,
> 0,
> FILE_OPEN,
> FILE_SYNCHRONOUS_IO_NONALERT,
> NULL,
> 0,
> CreateFileTypeNone,
> NULL,
> IO_IGNORE_SHARE_ACCESS_CHECK,
> pDevExt->pFileSystemDeviceObject
> );
>
> KdPrint((“\r\nOpeExistSmart Create 2 after:%ws”,fullpathname));
> if(!NT_SUCCESS(Status))
> {
> ExFreePool(fullpathnameIO);
> return ;
> }
> ExFreePool(fullpathnameIO);
> KdPrint((“\r\nOpeExistSmart Create close before:%ws”,fullpathname));
> ZwClose(hFile);
> KdPrint((“\r\nOpeExistSmart Create close after:%ws”,fullpathname));
> }
>
>
>
>
> When I single-click the D:\1.txt in Explorer.exe,the windbg’s output is:
> —before Open :5ec,750,D:\1.txt
> My FileName:??\D:\1.txt
> OpeExistSmart Create 1 before:D:\1.txt
> OpeExistSmart Create 2 after:D:\1.txt
> OpeExistSmart Create close before:D:\1.txt
> OpeExistSmart Create close after:D:\1.txt
> !!!after Open :5ec,750,D:\1.txt
> ^^^complete Open :5ec,750,D:\1.txt
> —before Open :5ec,750,D:\1.txt
> My FileName:??\D:\1.txt
> OpeExistSmart Create 1 before:D:\1.txt
>
> OK,deadlock,after 30 seconds,the windbg’s output is:
> @@@@@@timeout:264,f8,C:\WINDOWS\system32\Msctf.dll
>
> the process 5ec is Explorer.exe
> the process 264 is WinLogon.exe
>
>
>

yes,you are right!
my call is handed,it can’t return!
I’m finding the cause