Log in
Register
What's new
Search
Search
Search titles only
By:
Menu
Log in
Register
What's new
Search
Search
Search titles only
By:
Forums
Tutorials
About
Rules
What's New
Driver Reference Table
Donate
Search titles only
By:
Latest activity
Register
Microsoft Support & Malware Removal
BSOD Crashes, Kernel Debugging
How do I fix Game BSOD? Where to start or finish?
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="Vir Gnarus" data-source="post: 20346" data-attributes="member: 60"><p>Yes, forensic analysis books such as what you have there is excellent material to get into. OS Design books are also preferable. I unfortunately have no personal preferences at this time to give you.</p><p></p><p>Unless you have the know-how to figure out to a T all that caused the crash, you'll eventually reach a point where you have to make an educated guess on what it could be. While this isn't the most optimal solution, the good thing is that your current knowledge should at least be able to explain what it could <strong>not</strong> be. To someone without knowledge, they would look at a BSOD and have no idea what could've generated it. However, you have been able to determine as far as it being related to the keyboard. As broad an estimate that is, it's still quite a improvement over being completely clueless! Someone else could be tinkering with their video card, not realizing it has absolutely nothing to do with this BSOD. So don't work yourself out just because you've only been able to go so far on your estimate. You've accomplished one step successfully, now go the other step by figure out just what happened with the I/O involving this keyboard that got all out of whack.</p><p></p><p>What I did is start with the DV error, in that some I/O problem occurred that DV caught, in that it detected a misbehaving driver. Ok, what did DV catch? Check the minor error code in Arg1 of the bugcheck: 0x23b, or "<em>The caller has changed the status field of an IRP it does not understand.</em>" Hold it! what does this mean? This is where understanding IRP handling is important, which you should read extensively from both the MSDN articles pertaining to IRPs as well as the Windows Internals book on I/O. Basically, IRPs pertaining to I/O gets passed down a stack of drivers relevant to that I/O, such as disk drivers and filter drivers (like A/V drivers) for file I/O. One of the elements of an IRP is the status field, which tells the drivers handling it the current status of the I/O that this IRP pertains too. Here's a breakdown of an IRP for ya:</p><p></p><p>[code]2: kd> dt !_IRP</p><p>nt!_IRP</p><p> +0x000 Type : Int2B</p><p> +0x002 Size : Uint2B</p><p> +0x008 MdlAddress : Ptr64 _MDL</p><p> +0x010 Flags : Uint4B</p><p> +0x018 AssociatedIrp : <unnamed-tag></p><p> +0x020 ThreadListEntry : _LIST_ENTRY</p><p> +0x030 <span style="color: #008000">IoStatus </span>: _IO_STATUS_BLOCK</p><p> +0x040 RequestorMode : Char</p><p> +0x041 PendingReturned : UChar</p><p> +0x042 StackCount : Char</p><p> +0x043 CurrentLocation : Char</p><p> +0x044 Cancel : UChar</p><p> +0x045 CancelIrql : UChar</p><p> +0x046 ApcEnvironment : Char</p><p> +0x047 AllocationFlags : UChar</p><p> +0x048 UserIosb : Ptr64 _IO_STATUS_BLOCK</p><p> +0x050 UserEvent : Ptr64 _KEVENT</p><p> +0x058 Overlay : <unnamed-tag></p><p> +0x068 CancelRoutine : Ptr64 void </p><p> +0x070 UserBuffer : Ptr64 Void</p><p> +0x078 Tail : <unnamed-tag></p><p></p><p><em><span style="color: #008000">There's the IoStatus substructure. We'll break it down further:</span></em></p><p></p><p>2: kd> dt !_IRP IoStatus.</p><p>nt!_IRP</p><p> +0x030 IoStatus : </p><p> +0x000 Status : Int4B</p><p> +0x000 Pointer : Ptr64 Void</p><p> +0x008 Information : Uint8B</p><p>[/code]</p><p></p><p>Ok, that's the structure of things. Now let's see what it is pertaining to the faulting IRP for your example, using the IRP address in Arg3 of the bugcheck:</p><p></p><p>[code]2: kd> dt !_IRP fffffa800a83fcf0</p><p>nt!_IRP</p><p> +0x000 Type : 0n6</p><p> +0x002 Size : 0x310</p><p> +0x008 MdlAddress : (null) </p><p> +0x010 Flags : 0x40000000</p><p> +0x018 AssociatedIrp : <unnamed-tag></p><p> +0x020 ThreadListEntry : _LIST_ENTRY [ 0xfffffa80`0a83fd10 - 0xfffffa80`0a83fd10 ]</p><p> +0x030 IoStatus : _IO_STATUS_BLOCK</p><p> +0x040 RequestorMode : 0 ''</p><p> +0x041 PendingReturned : 0 ''</p><p> +0x042 StackCount : 8 ''</p><p> +0x043 CurrentLocation : 7 ''</p><p> +0x044 Cancel : 0 ''</p><p> +0x045 CancelIrql : 0 ''</p><p> +0x046 ApcEnvironment : 0 ''</p><p> +0x047 AllocationFlags : 0x80 ''</p><p> +0x048 UserIosb : (null) </p><p> +0x050 UserEvent : (null) </p><p> +0x058 Overlay : <unnamed-tag></p><p> +0x068 CancelRoutine : (null) </p><p> +0x070 UserBuffer : (null) </p><p> +0x078 Tail : <unnamed-tag></p><p></p><p><span style="color: #008000"><em>Let's break it down further</em></span>:</p><p></p><p>2: kd> dt !_IRP IoStatus. fffffa800a83fcf0</p><p>nt!_IRP</p><p> +0x030 IoStatus : </p><p> +0x000 Status : 0n-<span style="color: #ff0000">1073741808</span></p><p> +0x000 Pointer : 0x00000000`<span style="color: #ff0000">c0000010 </span>Void</p><p> +0x008 Information : 0</p><p></p><p>[/code]</p><p></p><p>Both Pointer and Status are the same value, just presented differently (one in decimal, one in hex). It's obvious we're dealing with a valid error status code, because the format of it fits the pattern ("c000XXXX"). Let's look it up:</p><p></p><p>[code]2: kd> !error c0000010</p><p>Error code: (NTSTATUS) 0xc0000010 (3221225488) - The specified request is not a valid operation for the target device.</p><p>[/code]</p><p></p><p>Ah ha, so the status field that ultimately got passed was that the request was not valid for the target device. This is where we hit a crossroads in our analysis; we can either figure out why the request was not valid, or what the device was that didn't like it. Let's start with the device first, by looking up the IRP using <em>!irp</em>:</p><p></p><p>[code]2: kd> !irp fffffa800a83fcf0 1</p><p>Irp is active with 8 stacks 7 is current (= 0xfffffa800a83ff70)</p><p> No Mdl: No System Buffer: Thread 00000000: Irp stack trace. </p><p>Flags = 40000000</p><p>ThreadListEntry.Flink = fffffa800a83fd10</p><p>ThreadListEntry.Blink = fffffa800a83fd10</p><p>IoStatus.Status = <span style="color: #ff0000">c0000010</span></p><p>IoStatus.Information = 00000000</p><p>RequestorMode = 00000000</p><p>Cancel = 00</p><p>CancelIrql = 0</p><p>ApcEnvironment = 00</p><p>UserIosb = 00000000</p><p>UserEvent = 00000000</p><p>Overlay.AsynchronousParameters.UserApcRoutine = 00000000</p><p>Overlay.AsynchronousParameters.UserApcContext = 00000000</p><p>Overlay.AllocationSize = 00000000 - 00000000</p><p>CancelRoutine = 00000000 </p><p>UserBuffer = 00000000</p><p>&Tail.Overlay.DeviceQueueEntry = fffffa800a83fd68</p><p>Tail.Overlay.Thread = 00000000</p><p>Tail.Overlay.AuxiliaryBuffer = 00000000</p><p>Tail.Overlay.ListEntry.Flink = 00000000</p><p>Tail.Overlay.ListEntry.Blink = 00000000</p><p>Tail.Overlay.CurrentStackLocation = fffffa800a83ff70</p><p>Tail.Overlay.OriginalFileObject = 00000000</p><p>Tail.Apc = 00000000</p><p>Tail.CompletionKey = 00000000</p><p> cmd flg cl <span style="color: #008000">Device </span>File Completion-Context</p><p> [ 0, 0] 0 2 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 <span style="color: #ff0000">ffffffffc0000010</span></p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 17,ff] 0 2 <span style="color: #008000">fffffa800a38c060 </span>00000000 00000000-00000000 </p><p> \Driver\SaiMini</p><p> Args: fffffa800a384040 00000000 00000000 00000000</p><p>>[ 17,ff] 0 e0 <span style="color: #008000">fffffa800a38c060 </span>00000000 fffff80003709da0-fffffa800a83ffb8 Success Error Cancel </p><p> \Driver\SaiMini nt!IovpInternalCompletionTrap</p><p> Args: fffffa800a384040 00000000 00000000 00000000</p><p> [ 17,ff] 0 e0 <span style="color: #008000">fffffa800a389aa0 </span>00000000 fffff80003713240-fffff880031a1720 Success Error Cancel </p><p> \DRIVER\VERIFIER_FILTER nt!ViIrpSynchronousCompletionRoutine</p><p> Args: fffffa800a384040 00000000 00000000 00000000</p><p></p><p>[/code]</p><p></p><p>I added "1" in order to give us extra details on the IRP, which is really just providing us nothing different then what we did previously by dumping the !_IRP data structure. You can tell the IoStatus.Status subfield is easily visible here. Evidently this is the easier option to check this out, but I went the other route at first to show how to view data structures properly.</p><p></p><p>Now, what we're looking for is the device, which is shown in green. You'll discover there's two devices here. Let's start from the bottom one:</p><p></p><p>[code]2: kd> !devobj fffffa800a389aa0</p><p>Device object (fffffa800a389aa0) is for:</p><p><span style="color: #008000"> \DRIVER\VERIFIER_FILTER</span> DriverObject fffffa8008583cc0</p><p>Current Irp <span style="color: #ff0000">00000000 </span>RefCount 0 Type 00000022 Flags 00002010</p><p>DevExt fffffa800a389bf0 DevObjExt fffffa800a389c30 </p><p>ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO</p><p> Unknown flags 0x00000800</p><p>AttachedTo (Lower) fffffa800a38c060 \Driver\SaiMini</p><p>Device queue is not busy.</p><p>[/code]</p><p></p><p>This is the VERIFIER_FILTER device object, so we evidently shouldn't be worried about this. It's obvious this is what started the IRP since Driver Verifier was involved, and it also shows that this IRP is probably a fake IRP created by DV to test drivers for bugs. We'll extrapolate more on that later. For now, telling from the "Current IRP" being null, it's no longer involved. Let's move to the next device object. Note that it is listed as the lower device in the device stack in relation to the one we're looking at now, meaning it's "closer" to the actual device inside the OS kernel doing the I/O than this DV device object is. Remember that an OS is designed to be the medium between which applications (software) can interact with hardware to accomplish stuff. Anyways, let's move on:</p><p></p><p>[code]2: kd> !devobj fffffa800a38c060</p><p>Device object (fffffa800a38c060) is for:</p><p> <span style="color: #008000">_HID00000001</span> \Driver\<span style="color: #008000">SaiMini </span>DriverObject fffffa800a389e70</p><p>Current Irp <span style="color: #008000">fffffa800a83fcf0 </span>RefCount 0 Type 00000022 Flags 00002050</p><p>Dacl fffff9a100083df1 DevExt fffffa800a38c1b0 DevObjExt fffffa800a38c648 </p><p>ExtensionFlags (0xe0000800) DOE_RAW_FDO, DOE_BOTTOM_OF_FDO_STACK, </p><p> DOE_DESIGNATED_FDO</p><p> Unknown flags 0x00000800</p><p>AttachedDevice (Upper) fffffa800a389aa0 \DRIVER\VERIFIER_FILTER</p><p>AttachedTo (Lower) fffffa800a3893d0 \DRIVER\VERIFIER_FILTER</p><p>Device queue is not busy.</p><p>[/code]</p><p></p><p>Getting warmer. We can tell this device object is for the SaiMini drive and is currently handling the faulting IRP. We can also tell from the "_HID00000001" that it's dealing with a HID (Human Interface Device) like mouse or keyboard. Now, for a bit of a bigger picture. Let's look at the entire device stack this is involved with. Using any of the device object addresses aforementioned will do:</p><p></p><p>[code]2: kd> !devstack fffffa800a38c060</p><p> !DevObj !DrvObj !DevExt ObjectName</p><p> fffffa800a389aa0 \DRIVER\VERIFIER_FILTERfffffa800a389bf0 </p><p>> fffffa800a38c060 \Driver\SaiMini fffffa800a38c1b0 _HID00000001</p><p> fffffa800a3893d0 \DRIVER\VERIFIER_FILTERfffffa800a389520 </p><p> fffffa800a384040 \Driver\SaiNtBus fffffa800a384190 </p><p>!DevNode fffffa800a386010 :</p><p> DeviceInst is "<span style="color: #008000">SaitekMagicBus\SaitekKeyboard\1&31a7fa5&0&0000</span>"</p><p> ServiceName is "<span style="color: #008000">SaiMini</span>"</p><p>[/code]</p><p></p><p>All right! Just from looking at the device node info, we can easily determine this is a keyboard we're dealing with and not a mouse. We can also get the grand picture on the entire device stack involved with this IRP and how I/O flows. From the top, DV has a filter driver involved to watch out activity between SaiMini and user land (usermode environment: applications and services); then we have SaiMini which I guess is a minifilter driver (read in Windows Internals), followed by yet another DV filter driver to verify activity between SaiMini and the lowest driver in the stack, SaiNtBus. </p><p></p><p></p><p>Ok, now that we figured out the device involved, it's time to determine what the request was and why it was invalid. So we'll have to look back at the IRP, reprinted here for convenience:</p><p></p><p>[code]2: kd> !irp fffffa800a83fcf0</p><p>Irp is active with 8 stacks 7 is current (= 0xfffffa800a83ff70)</p><p> No Mdl: No System Buffer: Thread 00000000: Irp stack trace. </p><p> cmd flg cl Device File Completion-Context</p><p> [ 0, 0] 0 2 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 ffffffffc0000010</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ 0, 0] 0 0 00000000 00000000 00000000-00000000 </p><p></p><p> Args: 00000000 00000000 00000000 00000000</p><p> [ <span style="color: #008000">17,ff</span>] 0 2 fffffa800a38c060 00000000 00000000-00000000 </p><p> \Driver\SaiMini</p><p> Args: fffffa800a384040 00000000 00000000 00000000</p><p>>[ <span style="color: #008000">17,ff</span>] 0 e0 fffffa800a38c060 00000000 fffff80003709da0-fffffa800a83ffb8 Success Error Cancel </p><p> \Driver\SaiMini nt!IovpInternalCompletionTrap</p><p> Args: fffffa800a384040 00000000 00000000 00000000</p><p> [ <span style="color: #008000">17,ff</span>] 0 e0 fffffa800a389aa0 00000000 fffff80003713240-fffff880031a1720 Success Error Cancel </p><p> \DRIVER\VERIFIER_FILTER nt!ViIrpSynchronousCompletionRoutine</p><p> Args: fffffa800a384040 00000000 00000000 00000000</p><p></p><p>[/code]</p><p></p><p>The major (MJ) function code and the minor (MN) function code are what we are looking for, which is printed on the left of the <em>!irp</em> output, that being 17,ff, for major and minor, respectively. Let's look them up in the Windbg help manual for <em>!irp</em>. The MJ function code turns out to be IRP_MJ_SYSTEM_CONTROL. Looking up in MSDN you'll find the respective article <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff550813%28v=vs.85%29.aspx" target="_blank">here</a>. Judging by the description, it's a WMI function, so look back at the Windbg manual for <em>!irp</em> again but in the WMI minor function code table (description of its items are <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff566361%28v=vs.85%29.aspx" target="_blank">here</a>. Now this is funny, our current MN code value of 0xff is not in the list. What's the deal? Time to look at that article in the previous link that's on the WMI minor IRP codes for an idea. It's from here we discover:</p><p></p><p></p><p></p><p>The second line there is what's really important. Since the MN code of 0xff doesn't fit the bill with any listed options, any driver handling the IRP should not fiddle with it and just pass it down the line in the device stack. However, remember the c0000010 error concerning the device not being able to understand the request? This is the request it's referring too. What appears to be happening is DV is sending this fake request that <em>should</em> be passed down the line untouched but SaiMini is interfering with it by saying it doesn't understand it, and therefore is passing it down with the altered IoStatus. That's exactly what is explained in the bugcheck explanation. So, apparently, the driver wasn't coded properly to conform to WMI standards that it should not be tampering with IRPs that it has no right to do so, and therefore DV caught it and issued a bugcheck. Whether it's actually responsible for what's involved with the person's dilemma, I'm not sure, but it is a valid bug in the code of this driver, and looking at this and other related Saitek drivers being from 2010, I'd say it's probably out of date, too. If there's no updates for it, the only option probably is to either have them contact Saitek on this, or just uninstall the drivers and Saitek software for the keyboard and just rely on the basic Windows drivers, which should suffice in most cases.</p><p></p><p>Hope that helps. I too didn't understand much of this bugcheck until I did a little bit of research. Took me a couple hours but now I know a bit more about IRP handling which will help me in the future (unless I'm misguided somehow!).</p></blockquote><p></p>
[QUOTE="Vir Gnarus, post: 20346, member: 60"] Yes, forensic analysis books such as what you have there is excellent material to get into. OS Design books are also preferable. I unfortunately have no personal preferences at this time to give you. Unless you have the know-how to figure out to a T all that caused the crash, you'll eventually reach a point where you have to make an educated guess on what it could be. While this isn't the most optimal solution, the good thing is that your current knowledge should at least be able to explain what it could [B]not[/B] be. To someone without knowledge, they would look at a BSOD and have no idea what could've generated it. However, you have been able to determine as far as it being related to the keyboard. As broad an estimate that is, it's still quite a improvement over being completely clueless! Someone else could be tinkering with their video card, not realizing it has absolutely nothing to do with this BSOD. So don't work yourself out just because you've only been able to go so far on your estimate. You've accomplished one step successfully, now go the other step by figure out just what happened with the I/O involving this keyboard that got all out of whack. What I did is start with the DV error, in that some I/O problem occurred that DV caught, in that it detected a misbehaving driver. Ok, what did DV catch? Check the minor error code in Arg1 of the bugcheck: 0x23b, or "[I]The caller has changed the status field of an IRP it does not understand.[/I]" Hold it! what does this mean? This is where understanding IRP handling is important, which you should read extensively from both the MSDN articles pertaining to IRPs as well as the Windows Internals book on I/O. Basically, IRPs pertaining to I/O gets passed down a stack of drivers relevant to that I/O, such as disk drivers and filter drivers (like A/V drivers) for file I/O. One of the elements of an IRP is the status field, which tells the drivers handling it the current status of the I/O that this IRP pertains too. Here's a breakdown of an IRP for ya: [code]2: kd> dt !_IRP nt!_IRP +0x000 Type : Int2B +0x002 Size : Uint2B +0x008 MdlAddress : Ptr64 _MDL +0x010 Flags : Uint4B +0x018 AssociatedIrp : <unnamed-tag> +0x020 ThreadListEntry : _LIST_ENTRY +0x030 [COLOR=#008000]IoStatus [/COLOR]: _IO_STATUS_BLOCK +0x040 RequestorMode : Char +0x041 PendingReturned : UChar +0x042 StackCount : Char +0x043 CurrentLocation : Char +0x044 Cancel : UChar +0x045 CancelIrql : UChar +0x046 ApcEnvironment : Char +0x047 AllocationFlags : UChar +0x048 UserIosb : Ptr64 _IO_STATUS_BLOCK +0x050 UserEvent : Ptr64 _KEVENT +0x058 Overlay : <unnamed-tag> +0x068 CancelRoutine : Ptr64 void +0x070 UserBuffer : Ptr64 Void +0x078 Tail : <unnamed-tag> [I][COLOR=#008000]There's the IoStatus substructure. We'll break it down further:[/COLOR][/I] 2: kd> dt !_IRP IoStatus. nt!_IRP +0x030 IoStatus : +0x000 Status : Int4B +0x000 Pointer : Ptr64 Void +0x008 Information : Uint8B [/code] Ok, that's the structure of things. Now let's see what it is pertaining to the faulting IRP for your example, using the IRP address in Arg3 of the bugcheck: [code]2: kd> dt !_IRP fffffa800a83fcf0 nt!_IRP +0x000 Type : 0n6 +0x002 Size : 0x310 +0x008 MdlAddress : (null) +0x010 Flags : 0x40000000 +0x018 AssociatedIrp : <unnamed-tag> +0x020 ThreadListEntry : _LIST_ENTRY [ 0xfffffa80`0a83fd10 - 0xfffffa80`0a83fd10 ] +0x030 IoStatus : _IO_STATUS_BLOCK +0x040 RequestorMode : 0 '' +0x041 PendingReturned : 0 '' +0x042 StackCount : 8 '' +0x043 CurrentLocation : 7 '' +0x044 Cancel : 0 '' +0x045 CancelIrql : 0 '' +0x046 ApcEnvironment : 0 '' +0x047 AllocationFlags : 0x80 '' +0x048 UserIosb : (null) +0x050 UserEvent : (null) +0x058 Overlay : <unnamed-tag> +0x068 CancelRoutine : (null) +0x070 UserBuffer : (null) +0x078 Tail : <unnamed-tag> [COLOR=#008000][I]Let's break it down further[/I][/COLOR]: 2: kd> dt !_IRP IoStatus. fffffa800a83fcf0 nt!_IRP +0x030 IoStatus : +0x000 Status : 0n-[COLOR=#ff0000]1073741808[/COLOR] +0x000 Pointer : 0x00000000`[COLOR=#ff0000]c0000010 [/COLOR]Void +0x008 Information : 0 [/code] Both Pointer and Status are the same value, just presented differently (one in decimal, one in hex). It's obvious we're dealing with a valid error status code, because the format of it fits the pattern ("c000XXXX"). Let's look it up: [code]2: kd> !error c0000010 Error code: (NTSTATUS) 0xc0000010 (3221225488) - The specified request is not a valid operation for the target device. [/code] Ah ha, so the status field that ultimately got passed was that the request was not valid for the target device. This is where we hit a crossroads in our analysis; we can either figure out why the request was not valid, or what the device was that didn't like it. Let's start with the device first, by looking up the IRP using [I]!irp[/I]: [code]2: kd> !irp fffffa800a83fcf0 1 Irp is active with 8 stacks 7 is current (= 0xfffffa800a83ff70) No Mdl: No System Buffer: Thread 00000000: Irp stack trace. Flags = 40000000 ThreadListEntry.Flink = fffffa800a83fd10 ThreadListEntry.Blink = fffffa800a83fd10 IoStatus.Status = [COLOR=#ff0000]c0000010[/COLOR] IoStatus.Information = 00000000 RequestorMode = 00000000 Cancel = 00 CancelIrql = 0 ApcEnvironment = 00 UserIosb = 00000000 UserEvent = 00000000 Overlay.AsynchronousParameters.UserApcRoutine = 00000000 Overlay.AsynchronousParameters.UserApcContext = 00000000 Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = 00000000 UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = fffffa800a83fd68 Tail.Overlay.Thread = 00000000 Tail.Overlay.AuxiliaryBuffer = 00000000 Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink = 00000000 Tail.Overlay.CurrentStackLocation = fffffa800a83ff70 Tail.Overlay.OriginalFileObject = 00000000 Tail.Apc = 00000000 Tail.CompletionKey = 00000000 cmd flg cl [COLOR=#008000]Device [/COLOR]File Completion-Context [ 0, 0] 0 2 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 [COLOR=#ff0000]ffffffffc0000010[/COLOR] [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 17,ff] 0 2 [COLOR=#008000]fffffa800a38c060 [/COLOR]00000000 00000000-00000000 \Driver\SaiMini Args: fffffa800a384040 00000000 00000000 00000000 >[ 17,ff] 0 e0 [COLOR=#008000]fffffa800a38c060 [/COLOR]00000000 fffff80003709da0-fffffa800a83ffb8 Success Error Cancel \Driver\SaiMini nt!IovpInternalCompletionTrap Args: fffffa800a384040 00000000 00000000 00000000 [ 17,ff] 0 e0 [COLOR=#008000]fffffa800a389aa0 [/COLOR]00000000 fffff80003713240-fffff880031a1720 Success Error Cancel \DRIVER\VERIFIER_FILTER nt!ViIrpSynchronousCompletionRoutine Args: fffffa800a384040 00000000 00000000 00000000 [/code] I added "1" in order to give us extra details on the IRP, which is really just providing us nothing different then what we did previously by dumping the !_IRP data structure. You can tell the IoStatus.Status subfield is easily visible here. Evidently this is the easier option to check this out, but I went the other route at first to show how to view data structures properly. Now, what we're looking for is the device, which is shown in green. You'll discover there's two devices here. Let's start from the bottom one: [code]2: kd> !devobj fffffa800a389aa0 Device object (fffffa800a389aa0) is for: [COLOR=#008000] \DRIVER\VERIFIER_FILTER[/COLOR] DriverObject fffffa8008583cc0 Current Irp [COLOR=#ff0000]00000000 [/COLOR]RefCount 0 Type 00000022 Flags 00002010 DevExt fffffa800a389bf0 DevObjExt fffffa800a389c30 ExtensionFlags (0xc0000800) DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO Unknown flags 0x00000800 AttachedTo (Lower) fffffa800a38c060 \Driver\SaiMini Device queue is not busy. [/code] This is the VERIFIER_FILTER device object, so we evidently shouldn't be worried about this. It's obvious this is what started the IRP since Driver Verifier was involved, and it also shows that this IRP is probably a fake IRP created by DV to test drivers for bugs. We'll extrapolate more on that later. For now, telling from the "Current IRP" being null, it's no longer involved. Let's move to the next device object. Note that it is listed as the lower device in the device stack in relation to the one we're looking at now, meaning it's "closer" to the actual device inside the OS kernel doing the I/O than this DV device object is. Remember that an OS is designed to be the medium between which applications (software) can interact with hardware to accomplish stuff. Anyways, let's move on: [code]2: kd> !devobj fffffa800a38c060 Device object (fffffa800a38c060) is for: [COLOR=#008000]_HID00000001[/COLOR] \Driver\[COLOR=#008000]SaiMini [/COLOR]DriverObject fffffa800a389e70 Current Irp [COLOR=#008000]fffffa800a83fcf0 [/COLOR]RefCount 0 Type 00000022 Flags 00002050 Dacl fffff9a100083df1 DevExt fffffa800a38c1b0 DevObjExt fffffa800a38c648 ExtensionFlags (0xe0000800) DOE_RAW_FDO, DOE_BOTTOM_OF_FDO_STACK, DOE_DESIGNATED_FDO Unknown flags 0x00000800 AttachedDevice (Upper) fffffa800a389aa0 \DRIVER\VERIFIER_FILTER AttachedTo (Lower) fffffa800a3893d0 \DRIVER\VERIFIER_FILTER Device queue is not busy. [/code] Getting warmer. We can tell this device object is for the SaiMini drive and is currently handling the faulting IRP. We can also tell from the "_HID00000001" that it's dealing with a HID (Human Interface Device) like mouse or keyboard. Now, for a bit of a bigger picture. Let's look at the entire device stack this is involved with. Using any of the device object addresses aforementioned will do: [code]2: kd> !devstack fffffa800a38c060 !DevObj !DrvObj !DevExt ObjectName fffffa800a389aa0 \DRIVER\VERIFIER_FILTERfffffa800a389bf0 > fffffa800a38c060 \Driver\SaiMini fffffa800a38c1b0 _HID00000001 fffffa800a3893d0 \DRIVER\VERIFIER_FILTERfffffa800a389520 fffffa800a384040 \Driver\SaiNtBus fffffa800a384190 !DevNode fffffa800a386010 : DeviceInst is "[COLOR=#008000]SaitekMagicBus\SaitekKeyboard\1&31a7fa5&0&0000[/COLOR]" ServiceName is "[COLOR=#008000]SaiMini[/COLOR]" [/code] All right! Just from looking at the device node info, we can easily determine this is a keyboard we're dealing with and not a mouse. We can also get the grand picture on the entire device stack involved with this IRP and how I/O flows. From the top, DV has a filter driver involved to watch out activity between SaiMini and user land (usermode environment: applications and services); then we have SaiMini which I guess is a minifilter driver (read in Windows Internals), followed by yet another DV filter driver to verify activity between SaiMini and the lowest driver in the stack, SaiNtBus. Ok, now that we figured out the device involved, it's time to determine what the request was and why it was invalid. So we'll have to look back at the IRP, reprinted here for convenience: [code]2: kd> !irp fffffa800a83fcf0 Irp is active with 8 stacks 7 is current (= 0xfffffa800a83ff70) No Mdl: No System Buffer: Thread 00000000: Irp stack trace. cmd flg cl Device File Completion-Context [ 0, 0] 0 2 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 ffffffffc0000010 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 [ [COLOR=#008000]17,ff[/COLOR]] 0 2 fffffa800a38c060 00000000 00000000-00000000 \Driver\SaiMini Args: fffffa800a384040 00000000 00000000 00000000 >[ [COLOR=#008000]17,ff[/COLOR]] 0 e0 fffffa800a38c060 00000000 fffff80003709da0-fffffa800a83ffb8 Success Error Cancel \Driver\SaiMini nt!IovpInternalCompletionTrap Args: fffffa800a384040 00000000 00000000 00000000 [ [COLOR=#008000]17,ff[/COLOR]] 0 e0 fffffa800a389aa0 00000000 fffff80003713240-fffff880031a1720 Success Error Cancel \DRIVER\VERIFIER_FILTER nt!ViIrpSynchronousCompletionRoutine Args: fffffa800a384040 00000000 00000000 00000000 [/code] The major (MJ) function code and the minor (MN) function code are what we are looking for, which is printed on the left of the [I]!irp[/I] output, that being 17,ff, for major and minor, respectively. Let's look them up in the Windbg help manual for [I]!irp[/I]. The MJ function code turns out to be IRP_MJ_SYSTEM_CONTROL. Looking up in MSDN you'll find the respective article [URL="http://msdn.microsoft.com/en-us/library/windows/hardware/ff550813%28v=vs.85%29.aspx"]here[/URL]. Judging by the description, it's a WMI function, so look back at the Windbg manual for [I]!irp[/I] again but in the WMI minor function code table (description of its items are [URL="http://msdn.microsoft.com/en-us/library/windows/hardware/ff566361%28v=vs.85%29.aspx"]here[/URL]. Now this is funny, our current MN code value of 0xff is not in the list. What's the deal? Time to look at that article in the previous link that's on the WMI minor IRP codes for an idea. It's from here we discover: The second line there is what's really important. Since the MN code of 0xff doesn't fit the bill with any listed options, any driver handling the IRP should not fiddle with it and just pass it down the line in the device stack. However, remember the c0000010 error concerning the device not being able to understand the request? This is the request it's referring too. What appears to be happening is DV is sending this fake request that [I]should[/I] be passed down the line untouched but SaiMini is interfering with it by saying it doesn't understand it, and therefore is passing it down with the altered IoStatus. That's exactly what is explained in the bugcheck explanation. So, apparently, the driver wasn't coded properly to conform to WMI standards that it should not be tampering with IRPs that it has no right to do so, and therefore DV caught it and issued a bugcheck. Whether it's actually responsible for what's involved with the person's dilemma, I'm not sure, but it is a valid bug in the code of this driver, and looking at this and other related Saitek drivers being from 2010, I'd say it's probably out of date, too. If there's no updates for it, the only option probably is to either have them contact Saitek on this, or just uninstall the drivers and Saitek software for the keyboard and just rely on the basic Windows drivers, which should suffice in most cases. Hope that helps. I too didn't understand much of this bugcheck until I did a little bit of research. Took me a couple hours but now I know a bit more about IRP handling which will help me in the future (unless I'm misguided somehow!). [/QUOTE]
Insert quotes...
Verification
Post reply
Microsoft Support & Malware Removal
BSOD Crashes, Kernel Debugging
How do I fix Game BSOD? Where to start or finish?
Menu
Log in
Register
Top