编写USB驱动程序,发出内部IOCTL给USB总线驱动程序,使用IoBuildDeviceIoControlRequest函数可以方便的构造IOCTL和内部IOCTL IRP,如果传递一个已经初始化了的时间,就可以通过等待该事件触发来等待IRP完成,而不需要设置完成例程。usb内部IOCTL不使用标准输入和输出缓冲区,而必须设置下一个栈单元的字段-- Parameter.Other.Argument1.将它指向URB指针。
windbg中指定进制形式,0x/0n/0t/0y 分别表示 16/10/8/2 进制。
使用windbg查看locals中的变量时,若发现诸如fdo、pdx等结构变量指针,展开后,很多域显示:MEMORY ACCESS ERROR,是因为没有执行创建出对应结构。
故而其没有相应的内容。
在调试一个usb驱动的时候,总是蓝屏,后来windbg显示崩溃是在adddevice里出现的,经过观察,原来是因为一个 NT_STATUS(ntStatus)前没有加 “ ! ”。结果自然后正确状态下退出,错误装态下继续执行,自然会蓝屏。
同样是它,改正上面那个错误后,依旧不对,逐个函数加输出语句: KdPrint(("enter AddDevice\r\n")); 。
结果发现时一插入usb设备,例程执行顺序是:DriverEntry --> AddDevice --> pnp中的remove。很奇怪为什么会直接插上就remove设备了呢。
经过分析,原来是adddevice函数里面的 ntStatus = IoCreateSymbolicLink ( &UserDeviceLinkUnicode, &KernelDeviceNameUnicode );
其中的 ntStatus 值在 windbg的locals窗口 里显示值为 0n-17??????(具体数值忘记了,自己转换出十六进制的数为0x0000003A,然后翻了半天网页,好像应该是 0xC000003A,不知道哪里算错了,也不知道为毛windbg显示的是十进制的数。。。)可以在上面那条语句下面加上一句
KdPrint(("status is %x !\r\n",ntStatus));//显示十六进制的status值
这样就可以在windbg中看status的十六进制值了。
回过头来,继续说是什么错误, 0xC000003A 对应的错误内容为 STATUS_OBJECT_PATH_NOT_FOUND
(可以为微软网站找到NTSTATUS的值对应的原因:http://msdn.microsoft.com/en-us/library/cc704588.aspx )
原来是我的符号链接名字用的是 WCHAR UserDeviceLinkBuffer[] =L"\\DOSDevice\\DONGUSB-O" ; 而 \DOSDevice 这个路径在winXP里面没有。只要把DOS去掉就好了。为什么就不知道了,以后再找原因吧。