hanged in IopParseDevice because my IoCreateFileSpecifyDeviceObjectHint

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 hang in IopParseDevice for my IoCreateFileSpecifyDeviceObjectHint.
anybody can clear it?Thanks!

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.that’s all OK!my IoCreateFileSpecifyDeviceObjectHint will return.
4.explorer.exe (PID 5ec,TID 750) open D:\1.txt again in my filter,I meet a IRP_MJ_CREATE for D:\1.txt
5.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).
6.hanged!the IoCreateFileSpecifyDeviceObjectHint can’t return!
in stack trace,it hanged in IopParseDevice .

please refer my code and windbg’s out.

In my filter IRP_MJ_CREATE handler:
my test code is following:
{
…if szFileName is not D:\1.xt,just pass through it…
KeWaitForSingleObject(g_pSyn_SF,Executive,KernelMode,FALSE,NULL);
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,hanged!

the stack:
f6908524 80501346 81f5ec38 81f5ebc8 804fabb0 nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])
f6908530 804fabb0 00000000 81f4b008 82042a88 nt!KiSwapThread+0x46 (FPO: [0,0,0])
f6908558 8057868b 00000000 00000000 00000000 nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
f690864c 805b490a 82075648 00000000 820003a0 nt!IopParseDevice+0xa2b (FPO: [Non-Fpo])
f69086d4 805b0deb 00000000 f6908714 00000240 nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo])
f6908728 8056b3b1 00000000 00000000 6d78a800 nt!ObOpenObjectByName+0xeb (FPO: [Non-Fpo])
f69087a4 8056bd28 f690894c 00100081 f6908928 nt!IopCreateFile+0x407 (FPO: [Non-Fpo])
f6908800 8056e3fa f690894c 00100081 f6908928 nt!IoCreateFileSpecifyDeviceObjectHint

I am not sure but under the impression that it’s not ok to call
IoCreateFileSpecifyDeviceObjectHint with exclusive access (0) and it may be
because of this that IopParseDevice is hanging. This is what says MSDN: “If
the IO_IGNORE_SHARE_ACCESS_CHECK flag is specified in the Options parameter,
the I/O manager ignores this parameter. However, the file system might still
perform access checks. Thus, it is important to specify the sharing mode you
would like for this parameter, even when using the
IO_IGNORE_SHARE_ACCESS_CHECK flag. For the greatest chance of avoiding
sharing violation errors, specify all of the following share access flags.”
I am not sure if these sharing violation can result in a deadlock but it
could make sense if some sync mechanism is used. If it won’t work, try
breaking in with the debugger and try to see what it is waiting for (good
luck). BTW you do have verifier on ?

/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 hang in IopParseDevice for my
> IoCreateFileSpecifyDeviceObjectHint.
> anybody can clear it?Thanks!
>
> 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.that’s all OK!my IoCreateFileSpecifyDeviceObjectHint will return.
> 4.explorer.exe (PID 5ec,TID 750) open D:\1.txt again in my filter,I meet a
> IRP_MJ_CREATE for D:\1.txt
> 5.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).
> 6.hanged!the IoCreateFileSpecifyDeviceObjectHint can’t return!
> in stack trace,it hanged in IopParseDevice .
>
> please refer my code and windbg’s out.
>
> In my filter IRP_MJ_CREATE handler:
> my test code is following:
> {
> …if szFileName is not D:\1.xt,just pass through
> it…
>
> KeWaitForSingleObject(g_pSyn_SF,Executive,KernelMode,FALSE,NULL);
> 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,hanged!
>
>
> the stack:
> f6908524 80501346 81f5ec38 81f5ebc8 804fabb0 nt!KiSwapContext+0x2e
> (FPO: [Uses EBP] [0,0,4])
> f6908530 804fabb0 00000000 81f4b008 82042a88 nt!KiSwapThread+0x46
> (FPO: [0,0,0])
> f6908558 8057868b 00000000 00000000 00000000
> nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
> f690864c 805b490a 82075648 00000000 820003a0
> nt!IopParseDevice+0xa2b (FPO: [Non-Fpo])
> f69086d4 805b0deb 00000000 f6908714 00000240
> nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo])
> f6908728 8056b3b1 00000000 00000000 6d78a800
> nt!ObOpenObjectByName+0xeb (FPO: [Non-Fpo])
> f69087a4 8056bd28 f690894c 00100081 f6908928 nt!IopCreateFile+0x407
> (FPO: [Non-Fpo])
> f6908800 8056e3fa f690894c 00100081 f6908928
> nt!IoCreateFileSpecifyDeviceObjectHint
> …
>
>

Hi Clark,

KeWaitForSingleObject(g_pSyn_SF,Executive,KernelMode,FALSE,NULL);

I am not sure of this but try setting the alertable parameter to TRUE and then try, because AFAIK, you can’t safely make File system calls with APCs disabled.

Regards,
Ayush Gupta

Hi,

f6908558 8057868b 00000000 00000000 00000000
nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
f690864c 805b490a 82075648 00000000 820003a0
nt!IopParseDevice+0xa2b (FPO: [Non-Fpo])

So, IopParseDevice has called IoCallDriver and waits on FileObject->Event
for the Irp completion due to STATUS_PENDING returned.

Also, can you explain the following excerpt from your code -

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);

If you complete a request( as I understand Irp was created by the Object
Manager, i.e. your driver is not this Irp creator) then you should set a
completion routine which returns STATUS_MORE_PROCESSING_REQUIRED. Have you
done this in KfCallFileSystem or before?


Slava Imameyev, xxxxx@hotmail.com

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 hang in IopParseDevice for my
> IoCreateFileSpecifyDeviceObjectHint.
> anybody can clear it?Thanks!
>
> 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.that’s all OK!my IoCreateFileSpecifyDeviceObjectHint will return.
> 4.explorer.exe (PID 5ec,TID 750) open D:\1.txt again in my filter,I meet a
> IRP_MJ_CREATE for D:\1.txt
> 5.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).
> 6.hanged!the IoCreateFileSpecifyDeviceObjectHint can’t return!
> in stack trace,it hanged in IopParseDevice .
>
> please refer my code and windbg’s out.
>
> In my filter IRP_MJ_CREATE handler:
> my test code is following:
> {
> …if szFileName is not D:\1.xt,just pass through
> it…
>
> KeWaitForSingleObject(g_pSyn_SF,Executive,KernelMode,FALSE,NULL);
> 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,hanged!
>
>
> the stack:
> f6908524 80501346 81f5ec38 81f5ebc8 804fabb0 nt!KiSwapContext+0x2e
> (FPO: [Uses EBP] [0,0,4])
> f6908530 804fabb0 00000000 81f4b008 82042a88 nt!KiSwapThread+0x46
> (FPO: [0,0,0])
> f6908558 8057868b 00000000 00000000 00000000
> nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
> f690864c 805b490a 82075648 00000000 820003a0
> nt!IopParseDevice+0xa2b (FPO: [Non-Fpo])
> f69086d4 805b0deb 00000000 f6908714 00000240
> nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo])
> f6908728 8056b3b1 00000000 00000000 6d78a800
> nt!ObOpenObjectByName+0xeb (FPO: [Non-Fpo])
> f69087a4 8056bd28 f690894c 00100081 f6908928 nt!IopCreateFile+0x407
> (FPO: [Non-Fpo])
> f6908800 8056e3fa f690894c 00100081 f6908928
> nt!IoCreateFileSpecifyDeviceObjectHint
> …
>
>

Hi Slava,

If you look at Mattias’s code, there is a KeWaitForSingleObject in which he
sets the thread’s state to non-alertable, before the call to HandleSmart
function in which he calls IoCreateFileSpecifyDeviceObjectHint.
Is it ok to enter a non alertable state and make a call to
IoCreateFileSpecifyDeviceObjectHint?

Regards,
Ayush Gupta

Oops! I meant Clark’s code… not Mattias… :slight_smile:
Got confused between the two OP names. Mattias had posted a different query.
I need some synchronization for stuff in my brain… :wink:

Regards,
Ayush Gupta

> Is it ok to enter a non alertable state and make a call to

IoCreateFileSpecifyDeviceObjectHint?

I think it is OK.
The alertable state is changed with each call to KeWaitFor() and has a
meaning only when a thread in a waiting state, and I suppose there is no
interference between consecutive calls to KeWaitFor().
Actually I don’t fully understand the question. I’ll try to explain
something.
Thread leaves KeWaitFor…( i.e. becomes scheduled for execution ) when

  • the object state is a signal state or
  • the thread is alerted( see below ) or
  • the Wait mode is UserMode and there is APC pending or
  • the timeout expired

the 2nd condition means that the waiting is alertable( i.e. Alertable ==
TRUE ) and at least one of the following conditions is fulfilled

  • the thread has been alerted( e.g. by NtAlertThread() or KeAlertThread() )
    for the waiting mode( either UserMode or KernelMode )
  • the thread waiting mode is UserMode and there is(are) APC(s) in the
    thread’s APC queue
  • the thread has been alerted for the kernel mode

So I don’t see any impact on a thread from KeWaitFor() with Alertable ==
FALSE except a possible hanging, but the thread’s stack says that the thread
hanged in IopParseDevice() calling KeWaitFor() after( as I guessed ) calling
IoCallDriver.

Could you mean KeEnterCriticalRegion() instead KeWaitFor()?


Slava Imameyev, xxxxx@hotmail.com

“Ayush Gupta” wrote in message news:xxxxx@ntfsd…
> Hi Slava,
>
> If you look at Mattias’s code, there is a KeWaitForSingleObject in which
> he
> sets the thread’s state to non-alertable, before the call to HandleSmart
> function in which he calls IoCreateFileSpecifyDeviceObjectHint.
> Is it ok to enter a non alertable state and make a call to
> IoCreateFileSpecifyDeviceObjectHint?
>
>
> Regards,
> Ayush Gupta
>
>

Hi Slava,
Thanks for the explanation.

Some questions:

So I don’t see any impact on a thread from KeWaitFor() with >Alertable == FALSE except a possible hanging

Can you please gime me a scenario for the same?

Could you mean KeEnterCriticalRegion() instead KeWaitFor()?

Actually I asked for KeWaitForSingleObject itself. But since you mentioned about KeEnterCriticalRegion, how will that differ?

Regards,
Ayush Gupta


Forgot the famous last words? Access your message archive online. Click here.

OK,I deleted the codes about KeWaitForSingleObject and KeReleaseSemaphore,the problem is still occured.

my test code is following:
{
…if szFileName is not D:\1.xt,just pass through it…

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));
return nRet;
}

according to windbg’s output,When I single-click D:\1.txt in explorer.exe,the explorer.exe will issued
IRP_MJ_CREATE twice.
When my filter meet the first IRP_MJ_CREATE,I call HandleSmart is OK(IoCreateFileSpecifyDeviceObjectHint will not hanged),but when my filter meet the second IRP_MJ_CREATE,I call IoCreateFileSpecifyDeviceObjectHint will hang.

Sorry,I forget giving the code about KfCallFileSystem.
But I think it is not the key.

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;
}

>Can you please gime me a scenario for the same?

Hard for the similar situation but I can imaging a scenario when a thread waiting in non-alertable state for a user-mode related event but the mode was erroneously set to KernelMode and the thread can’t be terminated or alerted from the user mode to break waiting.

Actually I asked for KeWaitForSingleObject itself. But since you mentioned about KeEnterCriticalRegion, how will that differ?

KeEnterCriticalRegion disables normal kernel-mode APCs delivering while KeWaitForSingleObject doesn’t. One of your post was about APCs so I decided that you meant blocking APCs delivering.


Slava Imameyev, xxxxx@hotmail.com

“Ayush Gupta” wrote in message news:xxxxx@ntfsd…
Hi Slava,
Thanks for the explanation.

Some questions:

>So I don’t see any impact on a thread from KeWaitFor() with >Alertable == FALSE except a possible hanging

Can you please gime me a scenario for the same?

>Could you mean KeEnterCriticalRegion() instead KeWaitFor()?

Actually I asked for KeWaitForSingleObject itself. But since you mentioned about KeEnterCriticalRegion, how will that differ?

Regards,
Ayush Gupta

------------------------------------------------------------------------------
Forgot the famous last words? Access your message archive online. Click here.

To put it more bluntly - KeWaitForSingleObject doesn’t prevent from APC delivering when thread exits from waiting state, when the thread in a waiting state APC delivering depends on wait mode and alertable state.
KeEnterCriticalRegion disables normal APC delivering until KeLeaveCriticalRegion is called.


Slava Imameyev, xxxxx@hotmail.com

“Slava Imameyev” wrote in message news:xxxxx@ntfsd…
>Can you please gime me a scenario for the same?

Hard for the similar situation but I can imaging a scenario when a thread waiting in non-alertable state for a user-mode related event but the mode was erroneously set to KernelMode and the thread can’t be terminated or alerted from the user mode to break waiting.

>Actually I asked for KeWaitForSingleObject itself. But since you mentioned about KeEnterCriticalRegion, how will that differ?

KeEnterCriticalRegion disables normal kernel-mode APCs delivering while KeWaitForSingleObject doesn’t. One of your post was about APCs so I decided that you meant blocking APCs delivering.


Slava Imameyev, xxxxx@hotmail.com

“Ayush Gupta” wrote in message news:xxxxx@ntfsd…
Hi Slava,
Thanks for the explanation.

Some questions:

>So I don’t see any impact on a thread from KeWaitFor() with >Alertable == FALSE except a possible hanging

Can you please gime me a scenario for the same?

>Could you mean KeEnterCriticalRegion() instead KeWaitFor()?

Actually I asked for KeWaitForSingleObject itself. But since you mentioned about KeEnterCriticalRegion, how will that differ?

Regards,
Ayush Gupta

----------------------------------------------------------------------------
Forgot the famous last words? Access your message archive online. Click here.

Thanks Slava.

What I thought (and probably read somewhere) was that if we call
KeWaitForSingleObject with alertable = FALSE and Waitmode = KernelMode, and
suppose somehow this thread got suspended (which is possible since normal
Kernel mode APCs can still be delivered), thus could get stuck.

Am I right/ wrong?

Regards,

Ayush Gupta

I have did some test.
1.When I meet IRP_MJ_CREATE for the D:\1.txt,I still call IoCreateFileSpecifyDeviceObjectHint ,but I change the paramter “(SYNCHRONIZE | FILE_READ_DATA|FILE_READ_ATTRIBUTES)” to “(SYNCHRONIZE | FILE_READ_ATTRIBUTES)”.
OK!IoCreateFileSpecifyDeviceObjectHint will not hang.
2.When I meet IRP_MJ_CREATE for D:\1.txt,I still call IoCreateFileSpecifyDeviceObjectHint ,but I change the target file “D:\1.txt” to “D:\test\1.txt”(D:\test\1.txt is a existed file).
OK!IoCreateFileSpecifyDeviceObjectHint will not hang.

I find a important problem!
In some WinXP,my filter works well,in this WinXP,the Explorer.exe work flow for D:\1.txt is:
1.IRP_MJ_CREATE
2.IRP_MJ_QUERYINFORMATION
3.IRP_MJ_CLEANUP
4.IRP_MJ_CREATE
5.IRP_MJ_QUREYINFORMATION
6.IRP_MJ_CLEANUP

but,in the WinXP my filter can’t work,the work flow for D:\1.txt is:
1.IRP_MJ_CREATE
2.IRP_MJ_CREATE
3.IRP_MJ_QUERYINFOMATION
4.IRP_MJ_CLEANUP

in this situation,my filter call IoCreateFileSpecifyDeviceObjectHint will hang When my filter meet the second IRP_MJ_CREATE(will not hang when my filter meet the first IRP_MJ_CREATE).

OK,I change my test code.I change the IoCreateFileSpecifyDeviceObjectHint parameters,I change the shareaccess from 0(execlusive) to (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE).OK!my filter call IoCreateFileSpecifyDeviceObjectHint will not hang!

> What I thought (and probably read somewhere) was that if we call KeWaitForSingleObject with alertable = FALSE and Waitmode = KernelMode, and suppose somehow this thread got suspended (which is possible since normal Kernel mode APCs can still be delivered), thus could get stuck.

I think it is possible in a case when a thread waits with Alertable == FALSE and WaitMode == KernelMode and receives an APC which issues a synchronous request which can’t be completed until the waiting thread has exited from KeWaitFor() to complete the previous request - this is a classical deadlock and I think changing the alertable state to TRUE doesn’t help here because the wait is not aborted if WaitMode == KernelMode( only if WaitMode == UserMode the wait is aborted, if the WaitMode == KernelMode the wait is aborted by calling KeAlertThread( thread, KernelMode) ) and even if the wait has been aborted the thread would have deadlocked again in an APC just after or before leaving KeWaitFor().


Slava Imameyev, xxxxx@hotmail.com

“Ayush Gupta” wrote in message news:xxxxx@ntfsd…
Thanks Slava.

What I thought (and probably read somewhere) was that if we call KeWaitForSingleObject with alertable = FALSE and Waitmode = KernelMode, and suppose somehow this thread got suspended (which is possible since normal Kernel mode APCs can still be delivered), thus could get stuck.

Am I right/ wrong?

Regards,

Ayush Gupta

Hmm… You are right Slava.

But surely this is not the case here. The call is getting stuck in
IopParseDevice.

Clark, check what parameters are being passed to IopParseDevice. Also check
what has IopParseDevice done before calling KeWaitForSingleObject. Also,
turn on the driver verifier.

Regards,

Ayush Gupta

>> 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);

If you complete a request( as I understand Irp was created by the Object
Manager, i.e. your driver is not this Irp creator) then you should set a
completion routine which returns STATUS_MORE_PROCESSING_REQUIRED. Have you
done this in KfCallFileSystem or before?

You didn’t answer Slava’s question. He pointed out possible problem. Do you have setup completion routine ? …and do you really return STATUS_MORE_PROCESSING_REQUIRED from completion routine, so you interrupt completion done by FSD? IoCompleteRequest seems to me very suspicious in your (I guess legacy FSFilter ) code.
Note that IRP_MJ_CREATE can be processed asynchronously (on vista it is even desired). For this case is your code wrong.

If you need post processing of this request plan post processing from completion routine by work item. Then return STATUS_MORE_PROCESSING_REQUIRED from completion routine. IoCompleteRequest() must be called from work item routine. It is universal for both synchronous and asynchronous processing. Hence advantage.

If you don’t need post processing. Return STATUS_SUCCESS from completion routine or even don’t setup completion routine at all and remove from your code IoCompleteRequest().

Don’t try to write FSF from the scratch. Use WDK samples as the start point. Even if you understand it only partially. You will get knowledge later.

Good Luck
Bronislav Gabrhelik

It seems that KeWaitForSingleObject in IopParseDevice is on event for completion. But I am not sure. Verify in dissassembly that there is IoCallDriver() right before it. This wait is only in the case when FSD returns STATUS_PENDING. It proves that lower FSD processes IRP_MJ_CREATE asynchronously.

-bg