IoQueryFileDosDeviceName hangs process

Hi all,

i am using IoQueryFileDosDeviceName routine to retrieve DOS name of
the file in pre-create. Everything goes right until i attach gdb to an
user process, what makes the process hangs and when i debug the
process with windbg i see that a thread is
frozen calling to “IoQueryFileDosDeviceName”. I following attach the
stack related to the thread.

THREAD 83a7f020 Cid 0140.0470 Teb: 7ffde000 Win32Thread:
00000000 READY
IRP List:
83d1dc90: (0006,0094) Flags: 00000070 Mdl: 00000000
83736008: (0006,01b4) Flags: 00000884 Mdl: 00000000
Not impersonating
DeviceMap e1640460
Owning Process 0 Image:
Attached Process 83d1b448 Image: useragent.exe
Wait Start TickCount 43834 Ticks: 0
Context Switch Count 674
UserTime 00:00:01.141
KernelTime 00:00:01.091
Win32 Start Address 0x77c0a341
Start Address 0x7c8106e9
Stack Init f473e000 Current f473d4f8 Base f473e000 Limit f473b000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 0
ChildEBP RetAddr Args to Child
f473d510 804dc0f7 83a7f090 83a7f020 804dc143
nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])
f473d51c 804dc143 00000000 83fd7d28 83d1dc90
nt!KiSwapThread+0x46 (FPO: [0,0,0])
f473d544 f7819dfc 00000000 00000000 00000000
nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
f473d570 804e37f7 83d1dd00 83fd7d44 00000200
MountMgr!MountMgrDeviceControl+0x2e (FPO: [Non-Fpo])
f473d580 805306d2 000000ee 83812148 e22e2bb8
nt!IopfCallDriver+0x31 (FPO: [0,0,0])
f473d7d0 805e7e52 83fdc900 e22e2bb8 6e446f49
nt!IoVolumeDeviceToDosName+0x210 (FPO: [Non-Fpo])
f473d834 80616299 83812148 00000001 00000001
nt!IopQueryNameInternal+0x92 (FPO: [Non-Fpo])
f473d864 f5b77e86 83812148 f473d898 01cb9187
nt!IoQueryFileDosDeviceName+0x2e (FPO: [Non-Fpo])

At this point, it never returns

f473d8e4 f5b649c8 83d5ca80 f473d920 f473d910
tsdlp!getNormalizedDosNameByFullPath+0x1c6 (FPO: [Non-Fpo]) (CONV:
stdcall) [c:\users\jmpulido\al\src\endpoint\fs_driver\nt_x86\dlpfilterfileandprocessmisc.c
@ 56]
f473d940 f5b68b23 83731f5c f473d9ac 01cb90ef
tsdlp!CheckFileBlocking+0xe8 (FPO: [Non-Fpo]) (CONV: stdcall)
[c:\users\jmpulido\al\src\endpoint\fs_driver\nt_x86\filefilteringutils.c
@ 150]
f473d98c f75e2888 83731f5c f473d9ac f473d9dc
tsdlp!DlpFilterPreCreate+0xb3 (FPO: [Non-Fpo]) (CONV: stdcall)
[c:\users\jmpulido\al\src\endpoint\fs_driver\nt_x86\dlpfiltercreate.c
@ 57]
f473d9ec f75e42a0 0073da30 83731f00 83736198
fltMgr!FltpPerformPreCallbacks+0x2d4 (FPO: [Non-Fpo])
f473da00 f75f1217 f473da30 f75ef6aa 00000000
fltMgr!FltpPassThroughInternal+0x32 (FPO: [Non-Fpo])
f473da18 f75f1742 f473da30 83ea52a0 83736018
fltMgr!FltpCreateInternal+0x63 (FPO: [Non-Fpo])
f473da4c 804e37f7 83cb8ee8 83736008 83736008
fltMgr!FltpCreate+0x258 (FPO: [Non-Fpo])
f473da5c 8056c712 83fdc8e8 837570ac f473dc04
nt!IopfCallDriver+0x31 (FPO: [0,0,0])
f473db3c 80563fec 83fdc900 00000000 83757008
nt!IopParseDevice+0xa12 (FPO: [Non-Fpo])
f473dbc4 805684da 00000000 f473dc04 00000042
nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo])
f473dc18 8056cbeb 00000000 00000000 00000001
nt!ObOpenObjectByName+0xeb (FPO: [Non-Fpo])
f473dc94 8056ccba 061df788 80100080 061df728
nt!IopCreateFile+0x407 (FPO: [Non-Fpo])
f473dcf0 8056cdf0 061df788 80100080 061df728
nt!IoCreateFile+0x8e (FPO: [Non-Fpo])
f473dd30 804de7ec 061df788 80100080 061df728
nt!NtCreateFile+0x30 (FPO: [Non-Fpo])
f473dd30 7c91e506 061df788 80100080 061df728
nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f473dd64)
061df6e4 7c91d09c 7c8109a6 061df788 80100080
ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])
061df6e8 7c8109a6 061df788 80100080 061df728
ntdll!ZwCreateFile+0xc (FPO: [11,0,0])
WARNING: Frame IP not in any known module. Following frames may be wrong.
061df780 7c801a53 00000000 80000000 00000003 0x7c8109a6
061df7a4 77bff45d 05f05374 80000000 00000003 0x7c801a53
061df7f0 77bff5ed 061df820 061df81c 05f05374 0x77bff45d
061df83c 77c13049 05f05374 00000000 00000040 0x77bff5ed
061df868 77c0efe9 05f05374 6fccbf19 00000040 0x77c13049
061df8ac 77c0f022 05f05374 6fccbf19 00000040 0x77c0efe9
061df8c0 6fc8ddbe 05f05374 6fccbf19 061df900 0x77c0f022
061df8e0 6fc8f6db 061df9c0 05f05374 00000008 0x6fc8ddbe
061df930 6fc98db5 061df998 05f05374 00000008 0x6fc8f6db
061df970 008194d3 061df990 05f05374 00000008 0x6fc98db5
061dfae0 7c9201bb 77bfc3c9 05840000 05f07958 0x8194d3
061dfb30 0081b7c0 05f3e720 061dfc1c 00000000
ntdll!RtlAllocateHeap+0xeac (FPO: [Non-Fpo])
061dfc30 0081b6bc 05f3e720 061dfc60 00000000 0x81b7c0
061dfc70 0052329f 05f3e720 061dfd40 061dfca7 0x81b6bc
061dfde8 7c91f63c 7c91f641 7c936405 7ffd7000 0x52329f

It seems that exists a synchronization issue between gdb and
IoQueryFileDosDeviceName, but i didn’t find any information and i
don’t know how to work around the problem.
Any help appreciated.

Thanks in advance
Fran

Why don’t you use KD or WinDbg? What’s the point of using gdb? Masochistic much?

Well, i use gdb to debug user-mode process because it is easy. I
didn’t know that i could debug both minifilter driver and user process
using windbg. Anyway, this is another issue.
The point is that not using gdb do not solve the problem and i am
curious about what cause IoQueryFileDosDeviceName to hangs because any
others processes could lead to the same problem.

Has IoQueryFileDosDeviceName any restriction that is not easy to find?
Any ideas?

Thanks for your help.
Fran

2011/7/26 :
> Why don’t you use KD or WinDbg? What’s the point of using gdb? Masochistic much?
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

Does the problem occur if you use WinDbg or any Visual Studio debugger to debug your application?

Sorry for my later response, full of work…

The problem does occur when i attach Visual Stuido debugger to the
same process and checking the stack it seems that some threads related
to debugger and the process are stopped at “IoQueryFileDosDeviceName”.
The stack is always the same

ChildEBP RetAddr Args to Child
f771350c 804dc0f7 ff577090 ff577020 804dc143
nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])
f7713518 804dc143 00000000 80ef6868 ff876008
nt!KiSwapThread+0x46 (FPO: [0,0,0])
f7713540 fab74dfc 00000000 00000000 00000000
nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
f771356c 804e37f7 ff876078 80ef6884 00000200
MountMgr!MountMgrDeviceControl+0x2e (FPO: [Non-Fpo])
f771357c 80530617 000000c8 ff57c258 e1f18258
nt!IopfCallDriver+0x31 (FPO: [0,0,0])
f77137cc 805e7e52 80ebd030 e1f18258 6e446f49
nt!IoVolumeDeviceToDosName+0x155 (FPO: [Non-Fpo])
f7713830 80616299 ff57c258 00000001 00000001
nt!IopQueryNameInternal+0x92 (FPO: [Non-Fpo])
f7713860 f9486d86 ff57c258 f7713894 0e3800be
nt!IoQueryFileDosDeviceName+0x2e (FPO: [Non-Fpo])
f77138e0 f94739eb 80d52d88 f7713920 f7713910
tsdlp!getNormalizedDosNameByFullPath+0x1c6 (FPO: [Non-Fpo]) (CONV:
stdcall) [c:\users\jmpulido\al\src\endpoint\fs_driver\nt_x86\dlpfilterfileandprocessmisc.c
@ 56]
f7713940 f9477b23 ff596f5c f77139ac 0e3801d2
tsdlp!CheckFileBlocking+0x10b (FPO: [Non-Fpo]) (CONV: stdcall)
[c:\users\jmpulido\al\src\endpoint\fs_driver\nt_x86\filefilteringutils.c
@ 159]
f771398c faa55888 ff596f5c f77139ac f77139dc
tsdlp!DlpFilterPreCreate+0xb3 (FPO: [Non-Fpo]) (CONV: stdcall)
[c:\users\jmpulido\al\src\endpoint\fs_driver\nt_x86\dlpfiltercreate.c
@ 58]
f77139ec faa572a0 00713a30 ff596f00 ff5762e0
fltMgr!FltpPerformPreCallbacks+0x2d4 (FPO: [Non-Fpo])
f7713a00 faa64217 f7713a30 faa626aa 00000000
fltMgr!FltpPassThroughInternal+0x32 (FPO: [Non-Fpo])
f7713a18 faa64742 f7713a30 ff602028 ff576160
fltMgr!FltpCreateInternal+0x63 (FPO: [Non-Fpo])
f7713a4c 804e37f7 80d49e20 ff576150 ff576150
fltMgr!FltpCreate+0x258 (FPO: [Non-Fpo])
f7713a5c 8056c712 80ebd018 ff64ba64 f7713c04
nt!IopfCallDriver+0x31 (FPO: [0,0,0])
f7713b3c 80563fec 80ebd030 00000000 ff64b9c0
nt!IopParseDevice+0xa12 (FPO: [Non-Fpo])
f7713bc4 805684da 00000000 f7713c04 00000040
nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo])
f7713c18 8056cbeb 00000000 00000000 00000001
nt!ObOpenObjectByName+0xeb (FPO: [Non-Fpo])
f7713c94 8056ccba 064ef2dc 80100080 064ef27c
nt!IopCreateFile+0x407 (FPO: [Non-Fpo])
f7713cf0 8056cdf0 064ef2dc 80100080 064ef27c
nt!IoCreateFile+0x8e (FPO: [Non-Fpo])
f7713d30 804de7ec 064ef2dc 80100080 064ef27c
nt!NtCreateFile+0x30 (FPO: [Non-Fpo])
f7713d30 7c91e506 064ef2dc 80100080 064ef27c
nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f7713d64)
064ef2d4 00000000 00000000 00000000 00000000
ntdll!KiIntSystemCall+0x6 (FPO: [0,0,0])

I don’t have a clue about what is going on. Any idea?

Thanks
Fran

2011/7/26 :
> Does the problem occur if you use WinDbg or any Visual Studio debugger to debug your application?
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

Do you hold a fast mutex, or call KeEnterCriticalRegion/KeEnterGuardedRegion in your driver while calling IoQueryFileDosDeviceName?

Hi

i worked around the problem using some code that i found. Basicly,
some kind of files are discarded.
The code:

// If some flag is enable, we do nothing.
if( FlagOn(Data->Iopb->OperationFlags, SL_OPEN_TARGET_DIRECTORY) ||
FlagOn(cpCreateOptions, FILE_OPEN_BY_FILE_ID) ||
FlagOn(cpCreateOptions, FILE_DIRECTORY_FILE) ||
FlagOn(Data->Iopb->TargetFileObject->Flags, FO_VOLUME_OPEN) )
{
retValue = FALSE; leave;
}

// Open file and check if is a directory
rStatus = OpenOriginalFile(Data, &originalFileHandle);
if(rStatus == FW_FILE_OPEN_ERROR){
retValue = FALSE; leave;
}
else if (fwrStatus == FW_FILE_NOT_FOUND){
retValue = FALSE;leave;
}

// Reference file object
status = ObReferenceObjectByHandle( originalFileHandle, FILE_ALL_ACCESS, NULL,
KernelMode, &originalFileObject, NULL );
if( !NT_SUCCESS(status) ){
//FWR_ASSERT(FALSE,
“[ERROR][IsRegularFileToInspect]-IsRegularFileToInspect Referencing
Object\n”);
retValue = FALSE; leave;
}

// If the file object represents a directory,
// or the file index number < 16, then the file doesn’t interest us.
status = FltQueryInformationFile(Data->Iopb->TargetInstance,
originalFileObject, &originalFileStandardInformation,
sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation, NULL);
if( !NT_SUCCESS(status) ){
retValue = FALSE; leave;
}

// If directory returns FALSE
if(originalFileStandardInformation.Directory == TRUE) {
retValue = FALSE; leave;
}

status = FltQueryInformationFile(Data->Iopb->TargetInstance,
originalFileObject, &originalFileInternalInformation,
sizeof(FILE_INTERNAL_INFORMATION), FileInternalInformation, NULL);
if( !NT_SUCCESS(status) ){
retValue = FALSE; leave;
}

if(originalFileInternalInformation.IndexNumber.QuadPart < 16){
retValue = FALSE; leave;
}

retValue = TRUE;

Where retValue indicates is the file is non discartable

Thanks for the help
Fran

2011/7/28 :
> Do you hold a fast mutex, or call KeEnterCriticalRegion/KeEnterGuardedRegion in your driver while calling IoQueryFileDosDeviceName?
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

Why do you event use that function. Just have saved in the instance context
the Dos device name of the device object you’re attached to and just replace
the \Device\Hard… with that instead of using that function which is
pretty inefficient as far as I know.

On Fri, Jul 29, 2011 at 1:01 PM, Fran Baena wrote:

> Hi
>
> i worked around the problem using some code that i found. Basicly,
> some kind of files are discarded.
> The code:
>
> // If some flag is enable, we do nothing.
> if( FlagOn(Data->Iopb->OperationFlags,
> SL_OPEN_TARGET_DIRECTORY) ||
> FlagOn(cpCreateOptions, FILE_OPEN_BY_FILE_ID) ||
> FlagOn(cpCreateOptions, FILE_DIRECTORY_FILE) ||
> FlagOn(Data->Iopb->TargetFileObject->Flags, FO_VOLUME_OPEN) )
> {
> retValue = FALSE; leave;
> }
>
> // Open file and check if is a directory
> rStatus = OpenOriginalFile(Data, &originalFileHandle);
> if(rStatus == FW_FILE_OPEN_ERROR){
> retValue = FALSE; leave;
> }
> else if (fwrStatus == FW_FILE_NOT_FOUND){
> retValue = FALSE;leave;
> }
>
> // Reference file object
> status = ObReferenceObjectByHandle( originalFileHandle,
> FILE_ALL_ACCESS, NULL,
>
> KernelMode, &originalFileObject, NULL );
> if( !NT_SUCCESS(status) ){
> //FWR_ASSERT(FALSE,
> “[ERROR][IsRegularFileToInspect]-IsRegularFileToInspect Referencing
> Object\n”);
> retValue = FALSE; leave;
> }
>
> // If the file object represents a directory,
> // or the file index number < 16, then the file doesn’t
> interest us.
> status = FltQueryInformationFile(Data->Iopb->TargetInstance,
> originalFileObject, &originalFileStandardInformation,
>
> sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation, NULL);
> if( !NT_SUCCESS(status) ){
> retValue = FALSE; leave;
> }
>
> // If directory returns FALSE
> if(originalFileStandardInformation.Directory == TRUE) {
> retValue = FALSE; leave;
> }
>
> status = FltQueryInformationFile(Data->Iopb->TargetInstance,
> originalFileObject, &originalFileInternalInformation,
>
> sizeof(FILE_INTERNAL_INFORMATION), FileInternalInformation, NULL);
> if( !NT_SUCCESS(status) ){
> retValue = FALSE; leave;
> }
>
> if(originalFileInternalInformation.IndexNumber.QuadPart <
> 16){
> retValue = FALSE; leave;
> }
>
> retValue = TRUE;
>
> Where retValue indicates is the file is non discartable
>
> Thanks for the help
> Fran
>
> 2011/7/28 :
> > Do you hold a fast mutex, or call
> KeEnterCriticalRegion/KeEnterGuardedRegion in your driver while calling
> IoQueryFileDosDeviceName?
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
> >
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Can APCs be delivered to your calling thread ?