DeviceIOControl and GetLastError returning 0

We have a USB device which works well for years but seeing some abnormal behavior on specific hosts running server 2008.
Occasionally DeviceIOControl returns 0 as error and if I try to find the error GetLastError also returns 0. So I do not get any clue what is the problem.
How to debug this?

Hmmm… break point in the DeviceIoControl routine in the driver? Trap any error returns from DeviceIoControl in the driver and THEN breakpoint?

I’d say your first order of business is to determine the NT_STATUS that’s being returned, and from THAT determine from whence in the driver that status code is being returned. Perhaps running something like the IRPTracker utility could help with this?

Peter
OSR

Show the code around DeviceIoControl through GetLastError.

well you can also kinda brute through the returns with a conditional
breakpoint like this

sxe -ibp ; .reboot ;
after reboot

kd> bu ntdll!NtDeviceIoControlFile “gu;r eax;!gle;?? (char
*)(@$proc)->ImageFileName;g”
kd> bl
0 eu 0001 (0001) (ntdll!NtDeviceIoControlFile) “gu;r
eax;!gle;?? (char *)(@$proc)->ImageFileName;g”

kd> g
eax=00000000
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0 - STATUS_WAIT_0
char * 0xffb8ad44
“winlogon.exe”
eax=00000000
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0xc000003a - {Path Not Found} The path
%hs does not exist.
char * 0xffb88aac
“csrss.exe”
eax=00000000
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0xc000003a - {Path Not Found} The path
%hs does not exist.
char * 0xffb88aac
“csrss.exe”
eax=00000000
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0xc000003a - {Path Not Found} The path
%hs does not exist.
char * 0xffb88aac
“csrss.exe”

cut

Single step exception - code 80000004 (first chance)
eax=80000005
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0 - STATUS_WAIT_0
char * 0xffb8ad44
“winlogon.exe”
eax=00000000
LastErrorValue: (Win32) 0xea (234) - More data is available.
LastStatusValue: (NTSTATUS) 0x80000005 - {Buffer Overflow} The data
was too large to fit into the specified buffer.
char * 0xffb8ad44
“winlogon.exe”
eax=c0000001
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0 - STATUS_WAIT_0
char * 0xffb8ad44
“winlogon.exe”
eax=00000000
LastErrorValue: (Win32) 0 (0) - The operation completed successfully.
LastStatusValue: (NTSTATUS) 0xc0000034 - Object Name not found.
char * 0xffb8ad44
“winlogon.exe”
Single step exception - code 80000004 (first chance)
eax=00000000
LastErrorValue: (Win32) 0x7e (126) - The specified module could not be found.
LastStatusValue: (NTSTATUS) 0xc0000135 - {Unable To Locate Component}
This application has failed to start because %hs was not found.
Re-installing the application may fix this problem.
char * 0xffb82ba4
“svchost.exe”

this is a time consuming and critical path break so expect this to run forever
change first chance exceptions to output etc etc (debug event filters)
set filters like matching process /p or matching threads /t at
appropriate places to curtail the breaks to a manageable level

else start this one day and come back to see the results another day

On 10/3/12, xxxxx@broadcom.com wrote:
> Show the code around DeviceIoControl through GetLastError.
>
> —
> 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
>

Set a process-specific breakpoint, so you won’t get those for every other process.

On 10/3/12, xxxxx@broadcom.com wrote:
> Set a process-specific breakpoint, so you won’t get those for every other
> process.

i assume you mean using bu /p “address” “condition” bp
if so any simple ways to
set a process specific break point for a process that hasn’t yet started ?

i mean i dont have the yet
!process 0 0 “myprocess.exe” wont show any result

and when i can grab it it might be too late for my bp to get hit (say
on a non repetitive one time function call or for a repetitive
function call but a special argument that is passed only once kind of
scenarios)

say i need to set a deviceioctrl break on smss.exe on entering kd
with sxe ibp;.reboot
how do i go about it

sxe cpr:process

wont work in kernel mode will work only in user mode as per documentation

sxe ld:say explorer.exe
never breaks in kd possibly due to deferred symbol loading or
something else that i am not aware of

OK, how about showing code for DeviceIoControl through GetLastError call call?

> say i need to set a deviceioctrl break on smss.exe on entering kd with

sxe ibp;.reboot how do i go about it

sxe cpr:process

wont work in kernel mode will work only in user mode as per documentation

sxe ld:say explorer.exe
never breaks in kd possibly due to deferred symbol loading or something
else that i am not aware of

Here’s how you do it:

g nt!NtCreateUserProcess
!gflag +ksl
sxe ld smss.exe
g

The first command (g nt!NtCreateUserProcess) is necessary to get past system init code which resets NtGlobalFlag to 0.

@ alex grigora

did you reply to me asking code "you already asked the OP for code "
i dont have any code i asked a question related to your comment set
process specific breakpoint

Thanks Pavel ill check that out

i also made a generic script which i posted in the thread
does $scmp take expression in windbg list which lets me break on any
process right from
.reboot till windows alg.exe service

On 10/4/12, Pavel Lebedynskiy wrote:
>> say i need to set a deviceioctrl break on smss.exe on entering kd with
>> sxe ibp;.reboot how do i go about it
>>
>> sxe cpr:process
>>
>> wont work in kernel mode will work only in user mode as per documentation
>>
>> sxe ld:say explorer.exe
>> never breaks in kd possibly due to deferred symbol loading or something
>> else that i am not aware of
>
> Here’s how you do it:
>
> g nt!NtCreateUserProcess
> !gflag +ksl
> sxe ld smss.exe
> g
>
> The first command (g nt!NtCreateUserProcess) is necessary to get past system
> init code which resets NtGlobalFlag to 0.
>
>
>
> —
> 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
>

>did you reply to me asking code "you already asked the OP for code "

I thought the OP just prefers jumping through the debugging hoops, rather than let us review the code for possible obvious error. But it’s just me.

So in what case the last error can be in disagreement with the return code? For example, if the IRP completes in line, and the returned status doesn’t match Irp->IoStatus.Status. DriverVerifier would find that probably.

On 10/4/12, Pavel Lebedynskiy wrote:

> Here’s how you do it:
>
> g nt!NtCreateUserProcess
> !gflag +ksl
> sxe ld smss.exe
> g
>
> The first command (g nt!NtCreateUserProcess) is necessary to get past system
> init code which resets NtGlobalFlag to 0.

pavel You Mean nt!RtlCreateUserProcess isnt it ?

anyway sxe ld module always works only once until reboot is what i experienced
is there a way around it ?

>> The first command (g nt!NtCreateUserProcess) is necessary to get past

> system init code which resets NtGlobalFlag to 0.

pavel You Mean nt!RtlCreateUserProcess isnt it ?

Either one will work. The goal is to let the system boot to a point where the +ksl setting will persist.

anyway sxe ld module always works only once until reboot is what i experienced is there a way around it ?

Unfortunately, no.

But you can catch the first load of a DLL/EXE using sxe ld, and then set a write breakpoint on the address of nt!_CONTROL_AREA.NumberOfMappedViews. You can get the address of the control area from !vad 1.

Or, if you know that the image always remains loaded in at least one process and therefore its ASLR base address will not change, you can set a write breakpoint on the address of the PTE that corresponds to the image base VA (you can get it from !pte ).

What type the USB device is, and are there any upper filters on its driver stack in the problematic systems?
Are you using overlapped IO?
How do you call DeviceIoControl (repeating this question again)?
Why don’t you just set a breakpoint in your code after DIOC call, instead of trying to to it in ntdll?

On 10/5/12, Pavel Lebedynskiy wrote:

> Unfortunately, no.
thanks for clarification

You can get the address of the control area from !vad 1.

!vad isnt documented to take an ImageBase it is supposed to take
VadRoot which can be gleaned from !process 0 0

http://msdn.microsoft.com/en-us/library/windows/hardware/ff565574(v=vs.85).aspx

but on sxe ld break doesnt exist yet
so thanks for this partially documented usage scenerio (yes i saw
some va being used in !vad in the Mapping Symbols When the PEB is
Paged Out documentation though it is for itanium

sure enough it works great though

kd> sxe ld calc.exe
nt!DebugService2+0x10:
80506d3e cc int 3
kd> lm m cal*
start end module name
01000000 0101f000 calc (deferred)

kd> .foreach /pS 4 /ps 4 (place {lm m cal* } ) {!vad place 1}

VAD @ ffaf6d58
Start VPN 1000 End VPN 101e Control Area ffae4d90
FirstProtoPte e1e6f268 LastPte fffffffc Commit Charge 2 (2.)
Secured.Flink 0 Blink 0 Banked/Extend 0
File Offset 0
ImageMap ViewShare EXECUTE_WRITECOPY

ControlArea @ ffae4d90
Segment e1e6f230 Flink 00000000 Blink 00000000
Section Ref 1 Pfn Ref 1 Mapped Views 1
User Ref 2 WaitForDel 0 Flush Count 0
File Object ffafb878 ModWriteCount 0 System Views 0

kd> ba w4 ffae4d90+14

kd> bl
0 e ffae4da4 w 4 0001 (0001)

kd> g
Breakpoint 0 hit closed calc.exe mapped view being removed

nt!MiRemoveMappedView+0x23c:
804f1d82 ff7508 push dword ptr [ebp+8]
kd> dt nt!_CONTROL_AREA ffae4d90
+0x000 Segment : 0xe1e6f230 _SEGMENT
+0x004 DereferenceList : _LIST_ENTRY [0x0 - 0x0]
+0x00c NumberOfSectionReferences : 0
+0x010 NumberOfPfnReferences : 0x1d
+0x014 NumberOfMappedViews : 0 <---------------------------------

kd> g
Breakpoint 0 hit reopen calc.exe mapped view incremented by 1
nt!MiCheckPurgeAndUpMapCount+0xcf:
804f2001 8a4dff mov cl,byte ptr [ebp-1]
kd> ub
804f1ffe ff4714 inc dword ptr [edi+14h]
kd> r edi
edi=ffae4d90
kd> dt nt!_CONTROL_AREA @edi
+0x000 Segment : 0xe1e6f230 _SEGMENT
+0x004 DereferenceList : _LIST_ENTRY [0x0 - 0x0]
+0x00c NumberOfSectionReferences : 1
+0x010 NumberOfPfnReferences : 0x1d
+0x014 NumberOfMappedViews : 1 <-----------------------------

kd> g
Breakpoint 0 hit reopen calc.exe mapped view incremented by 1
nt!MiCheckPurgeAndUpMapCount+0xcf:
804f2001 8a4dff mov cl,byte ptr [ebp-1]

kd> dt nt!_CONTROL_AREA @edi
+0x000 Segment : 0xe1e6f230 _SEGMENT
+0x004 DereferenceList : _LIST_ENTRY [0x0 - 0x0]
+0x00c NumberOfSectionReferences : 2
+0x010 NumberOfPfnReferences : 0x1d
+0x014 NumberOfMappedViews : 2 <------------------------

kd> g
Breakpoint 0 hit reopen calc.exe mapped view incremented by 1
nt!MiCheckPurgeAndUpMapCount+0xcf:
804f2001 8a4dff mov cl,byte ptr [ebp-1]
kd> dt nt!_CONTROL_AREA @edi
+0x000 Segment : 0xe1e6f230 _SEGMENT
+0x004 DereferenceList : _LIST_ENTRY [0x0 - 0x0]
+0x00c NumberOfSectionReferences : 3 <----------------------
+0x010 NumberOfPfnReferences : 0x1d
+0x014 NumberOfMappedViews : 3

thanks once again
btw can i quote this thread and submit feed back on the doc link

i updated my debugger.chm to reflect this info :slight_smile:

Syntax
!vad VAD-Root [Flags]

Parameters
VAD-Root
Specifies the hexadecimal address of the root of the VAD tree to be displayed.
ImageBase
Specifies the hexadecimal address of the ImageBase Of Module for VAD
tree to be displayed.

Guys, you’re taking the long route. Stop futzing with the breakpoints.

alex

the OP went mia and the thread has been hijacked beyond repair so this
thread now
isn’t about any route at all now it has taken a new direction and is
flying above routes

maybe one of the list slaves cut paste these posts from me and pavel
to another thread so that if op comes back he wouldn’t be befuddled

On 10/5/12, xxxxx@broadcom.com wrote:
> Guys, you’re taking the long route. Stop futzing with the breakpoints.
>
> —
> 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
>

> btw can i quote this thread and submit feed back on the doc link

Sure.

Thanks for helping make the docs better.

bluffer is me hardly bluffs !!!. Just using his sharp knife:). It
always helps to get to know these stuff…

-pro