DDK样例toaster分析(2)
来源:互联网 发布:我的世界为什么用java 编辑:程序博客网 时间:2024/05/16 05:44
前一篇 DDK样例toaster分析(1) 主要讨论了toaster样例中的busenum总线驱动。本篇将讨论从总线驱动过渡到功能驱动,也就是toaster.sys。
成功安装busenum.sys后,运行toaster/exe/enum目录下的enum程序模拟一个toaster设备插入:
enum -p 1前面busenum.sys!Bus_AddDevice创建Fdo的同时还为Fdo创建一个接口:
status = IoRegisterDeviceInterface ( PhysicalDeviceObject, (LPGUID) &GUID_DEVINTERFACE_BUSENUM_TOASTER, NULL, &deviceData->InterfaceName);DEFINE_GUID (GUID_DEVINTERFACE_BUSENUM_TOASTER, 0xD35F7840, 0x6A0C, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);// {D35F7840-6A0C-11d2-B841-00C04FAD5171}enum.exe通过SetupDi函数打开并通过ioctl访问这个接口:
hardwareDeviceInfo=SetupDiGetClassDevs(GUID_DEVINTERFACE_BUSENUM_TOASTER,...);SetupDiEnumDeviceInterfaces(hardwareDeviceInfo,...,&deviceInterfaceData);file = CreateFile ( deviceInterfaceDetailData->DevicePath,...);调用Ioctl后,最终进入到Bus_Ioctl中,因为是插入设备,所以最终会调用Bus_PlugInDevice
NTSTATUSBus_PlugInDevice ( PBUSENUM_PLUGIN_HARDWARE PlugIn, ULONG PlugInSize, PFDO_DEVICE_DATA FdoData )先看下FdoData中的内容,确定enum打开的是busenum.sys创建的Fdo:
kd> dd FdoData l10x81ec60e8kd> dt _FDO_DEVICE_DATA 81ec60e8busenum!_FDO_DEVICE_DATA+0x01c UnderlyingPDO : 0x823e73d0 _DEVICE_OBJECTkd> !devobj 0x823e73d0 Device object (823e73d0) is for: 00000034 \Driver\PnpManager DriverObject 823eb2b0Current Irp 00000000 RefCount 1 Type 00000004 Flags 00001040Dacl e1594174 DevExt 823e7488 DevObjExt 823e7490 DevNode 823e7288 ExtensionFlags (0000000000) AttachedDevice (Upper) 81ec6030 \Driver\busenumDevice queue is not busy.FdoData用UnderlyingPDO指出了堆叠在设备下面的设备。从windbg的输出看出,UnderlyingPDO就是busenum.sys所依赖的pnpmanager设备对象。
M$的帮助文档将busenum.sys!Bus_AddDevice创建的设备描述为Fdo,而将Bus_PlugInDevice创建的设备描述为Pdo。这是因为在Bus_PlugInDevice中创建出来的devobj代表了busenum总线对象,作为toaster.sys创建的设备对象的堆叠基石。另外也可以从windbg的输出看到,busenum新创建的设备对象并没有attach到任何已有设备对象上:
1).调用Bus_PlugInDevice!IoCreateDeviceSecure前,属于busenum.sys驱动对象的设备对象:
kd> !drvobj busenumDriver object (81dfdda0) is for: \Driver\busenumDriver Extension List: (id , addr)Device Object list:81ec6030 <---是attach在\Driver\PnpManager上的Fdo对象,上一张图中有描述
kd> !devstack 81ec6030 !DevObj !DrvObj !DevExt ObjectName> 81ec6030 \Driver\busenum 81ec60e8 823e73d0 \Driver\PnpManager 823e7488 00000034!DevNode 823e7288 : DeviceInst is "Root\UNKNOWN\0000" ServiceName is "busenum"上图中,busenum.sys只有一个设备对象
2).调用IoCreateDeviceSecure后,busenum.sys会新增一个设备对象:
kd> !drvobj busenumDriver object (81dfdda0) is for: \Driver\busenumDriver Extension List: (id , addr)Device Object list:82062408<---新加的设备对象 81ec6030 <---原有的设备对象kd> !devobj 82062408 Device object (82062408) is for: 0000008a \Driver\busenum DriverObject 81dfdda0Current Irp 00000000 RefCount 0 Type 0000002a Flags 000000c0Dacl e23ad84c DevExt 820624c0 DevObjExt 820624f8 ExtensionFlags (0000000000) Device queue is not busy.从windbg输出可以看到,这个新的设备对象下面并没有attach其他设备对象
之后,busenum为这个新创建的设备对象创建HardwareID(总线设备的职责不就是为新加入的设备分配设备ID吗?)
pdoData->HardwareIDs = ExAllocatePoolWithTag (NonPagedPool, length, BUSENUM_POOL_TAG);RtlCopyMemory (pdoData->HardwareIDs, PlugIn->HardwareIDs, length);后分配busenum pdo的HardwardIDkd> dd pdoData l1b21fdbec 820624c0kd> dt _PDO_DEVICE_DATA 820624c0busenum!_PDO_DEVICE_DATA+0x020 HardwareIDs : 0x8213aa50 -> 0x7bkd> du 0x8213aa50 <------注意,这是busenum.sys为pdo对象设置的硬件id,之后要按这个id匹配功能驱动8213aa50 "{B85B7C50-6A01-11d2-B841-00C04FA"8213aa90 "D5171}\MsToaster"
最后,Bus_PlugInDevice通过IoInvalidateDeviceRelations,通知pnp管理器:有新的设备加入设备树,pnp管理器要更新设备树关系(说人话,就是为新设备加载匹配的驱动)
由于系统中并没有安装这个Pdo的驱动,因此会跳出搜索驱动的对话框,这里选择手动安装,选择toaster/inf/sample.inf文件。至于为什么要选这个文件,因为sample.inf文件的硬件兼容列表里表示支持这个设备:
[Manufacturer]%StdMfg%=Standard[Standard]; DisplayName Section DeviceId; ----------- ------- --------%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster <---硬件兼容列表这个列表中的内容完全匹配新创建设备对象的HardwareID,因此系统加载sample.inf中指定的sys文件,并创建对应的服务,最后把执行权限交给toaster.sys:
[Version]Signature="$WINDOWS NT$"Class=TOASTERClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171}Provider=%MSFT%DriverVer=09/21/2006,6.0.5736.1CatalogFile=toaster.cat...[Toaster_Device.NT]CopyFiles=Toaster_Device.NT.Copy[Toaster_Device.NT.Copy]toaster.sys驱动安装后,设备管理器里多出一个toaster设备,查看Driver Detail可以看到驱动文件的信息:
扯点题外话,可以通过Update Driver替换新的inf文件,比如选择toasterf.inf(含设备过滤驱动的toaster.sys),并指定sys文件路径后,再查看Driver Detail可以看到功能驱动和过滤驱动:(tmd公司要做驱动测试,测试老问我加载过滤驱动后,怎么在设备管理器里看到!还一定要在设备管理器里看到,注册表里不算,我折腾很久才发现这个!!)
当然这种更新操作要底层设备支持disable/enable,像磁盘设备的,不支持disable/enable操作就不能这样更新驱动(这要感谢同事周AM的解释)
好好,扯远了,回到正题,执行权从busenum.sys过渡到toaster.sys。当然了进入toaster.sys后还会调用toaster的AddDevice函数ToasterAddDevice,因此要在这个函数上下断:
DriverEntrykd> !drvobj 8216db10 Driver object (8216db10) is for: \Driver\toasterDriver Extension List: (id , addr)Device Object list:
kd> bp toaster!ToasterAddDevice;gkd> dd DriverObject l1f8aed9e8 8216db10kd> !drvobj 8216db10Driver object (8216db10) is for: \Driver\toasterDriver Extension List: (id , addr)Device Object list:刚进入ToasterAddDevice时,驱动对象下还没有设备对象。顺带看下ToasterAddDevice的接口
NTSTATUSToasterAddDevice( __in PDRIVER_OBJECT DriverObject, __in PDEVICE_OBJECT PhysicalDeviceObject )DriverObject不用说肯定是toaster.sys的,PhysicalDeviceObject,则是前面busenum创建的pdo了(由于刚才更新驱动时停用启用过设备,设备对象跟上文不能连续了,不过还是能通过!drvobj !devstack来观察结果):
kd> dd PhysicalDeviceObject l1 ;<---PhysicalDeviceObject的值f8ae99ec 82062408kd> !devstack 82062408 ;<---通过设备堆栈证明这个是前面busenum创建的Pdo !DevObj !DrvObj !DevExt ObjectName> 82062408 \Driver\busenum 820624c0 0000008a ;<---这个设备对象下面并没有attach其他设备,跟上文的结论一下,因此可以认为是Pdo!DevNode 82266878 : DeviceInst is "{B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster\1&1aafb3d5&0&01" ServiceName is "toaster"kd> !drvobj busenum ;<---当然,有人不信,那只能列出busenum驱动对象下的设备对象Driver object (81dfdda0) is for: \Driver\busenumDriver Extension List: (id , addr)Device Object list:82062408 81ec6030 <---这个驱动对像目前只有2个设备对象,为了证明82062408对象是Pdo,只要证明81ec6030 是Fdo就行了,剩下的靠排除法就能证明
kd> !devstack 81ec6030 ;<---81ec6030的设备栈显示,这个就是Fdo,attach在pnpmanager设备对象上!DevObj !DrvObj !DevExt ObjectName> 81ec6030 \Driver\busenum 81ec60e8 823e73d0 \Driver\PnpManager 823e7488 00000034!DevNode 823e7288 : DeviceInst is "Root\UNKNOWN\0000" ServiceName is "busenum"
之后,Toaster.sys调用IoCreateDevice创建功能驱动(注意是toaster.sys的Fdo不是busenum.sys的Fdo),把这个Fdo堆叠到busenum.sys的Pdo上:
status = IoCreateDevice (DriverObject, sizeof (FDO_DATA), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject);...fdoData->NextLowerDriver = IoAttachDeviceToDeviceStack (deviceObject, PhysicalDeviceObject);
这样就完成了从busenum到toaster的过渡。
- DDK样例toaster分析(2)
- DDK样例toaster分析(1)
- DDK
- DDk
- OpenDaylight开发实例toaster实验过程记录(2)
- 局部升级Qmail Toaster
- Dojo 提示信息 Toaster
- odl开发toaster
- angular-toaster 入坑记
- AngularJS Toaster使用详解
- DDK中网络驱动器例子NulMrx测试和分析
- 装了一天DDK 、DriverStudio3.2
- vc6+DDK+DriverStudio3.2安装与配置
- VC6.0+XP-DDK+DriverStudio3.2
- TOASTER例子阅读(一)
- TOASTER例子阅读(一)
- 图像滤镜艺术--Toaster滤镜
- Toaster多功能 Android 吐司工具
- Spark源码学习(7)——Broadcast
- java多线程处理任务
- Leetcode题解 350. Intersection of Two Arrays II
- JNI 实战全面解析
- $.each()
- DDK样例toaster分析(2)
- 黄土赭色
- json字符串转换为xml格式输出
- LinearLayout(二)
- 构造函数和析构函数
- windows下安装apache并配置ssl过程
- 6款职场发型,造就你的气质不凡!
- g++生成共享库之参数fPIC
- Python爬虫入门之request函数定制