reactos操作系统实现(77)
因为PC里一条总线上可以连接很多设备,就像一棵树一样,需要遍历所有总线上所有子设备,并且为每一个子设备安装相应的驱动程序,下面这个函数,实现枚举所有子设备,实现代码如下: #001 NTSTATUS #002 IopEnumerateDevice( #003 IN PDEVICE_OBJECT DeviceObject) #004 {
获取设备的节点。 #005 PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); #006 DEVICETREE_TRAVERSE_CONTEXT Context; #007 PDEVICE_RELATIONS DeviceRelations; #008 PDEVICE_OBJECT ChildDeviceObject; #009 IO_STATUS_BLOCK IoStatusBlock; #010 PDEVICE_NODE ChildDeviceNode; #011 IO_STACK_LOCATION Stack; #012 NTSTATUS Status; #013 ULONG i; #014 #015 DPRINT("DeviceObject 0x%p/n",DeviceObject); #016 #017 DPRINT("Sending GUID_DEVICE_ARRIVAL/n"); #018
报告这个设备到用户模式的即插即用管理器。 #019 /* Report the device to the user-mode pnp manager */ #020 IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, #021 &DeviceNode->InstancePath); #022 #023 DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack/n"); #024 #025 Stack.Parameters.QueryDeviceRelations.Type = BusRelations; #026
发送查询设备之间相互关系。 #027 Status = IopInitiatePnpIrp( #028 DeviceObject, #029 &IoStatusBlock, #030 IRP_MN_QUERY_DEVICE_RELATIONS, #031 &Stack); #032 if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) #033 { #034 DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx/n",Status); #035 return Status; #036 } #037
获取设备相互关系。 #038 DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; #039 #040 if (!DeviceRelations) #041 { #042 DPRINT("No PDOs/n"); #043 return STATUS_UNSUCCESSFUL; #044 } #045 #046 DPRINT("Got %u PDOs/n",DeviceRelations->Count); #047
创建所有这个根设备下面的子设备。 #048 /* #049 * Create device nodes for all discovered devices #050 */ #051 for (i = 0; i < DeviceRelations->Count; i++) #052 { #053 ChildDeviceObject = DeviceRelations->Objects[i]; #054 ASSERT((ChildDeviceObject->Flags & DO_DEVICE_INITIALIZING) == 0); #055
获取子设备节点是否存在。 #056 ChildDeviceNode = IopGetDeviceNode(ChildDeviceObject); #057 if (!ChildDeviceNode) #058 {
如果不存在,就创建这个子设备节点。 #059 /* One doesn't exist,create it */ #060 Status = IopCreateDeviceNode( #061 DeviceNode, #062 ChildDeviceObject, #063 NULL, #064 &ChildDeviceNode); #065 if (NT_SUCCESS(Status)) #066 { #067 /* Mark the node as enumerated */ #068 ChildDeviceNode->Flags |= DNF_ENUMERATED; #069 #070 /* Mark the DO as bus enumerated */ #071 ChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE; #072 } #073 else #074 { #075 /* Ignore this DO */ #076 DPRINT1("IopCreateDeviceNode() failed with status 0x%08x. Skipping PDO %u/n",Status,i); #077 ObDereferenceObject(ChildDeviceNode); #078 } #079 } #080 else #081 { #082 /* Mark it as enumerated */ #083 ChildDeviceNode->Flags |= DNF_ENUMERATED; #084 ObDereferenceObject(ChildDeviceObject); #085 } #086 } #087 ExFreePool(DeviceRelations); #088
获取这个总线驱动程序上所有设备。 #089 /* #090 * Retrieve information about all discovered children from the bus driver #091 */ #092 IopInitDeviceTreeTraverseContext( #093 &Context, #094 DeviceNode, #095 IopActionInterrogateDeviceStack, #096 DeviceNode); #097 #098 Status = IopTraverseDeviceTree(&Context); #099 if (!NT_SUCCESS(Status)) #100 { #101 DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx/n",Status); #102 return Status; #103 } #104
获取这个总线驱动程序上所有注册表里的信息。 #105 /* #106 * Retrieve configuration from the registry for discovered children #107 */ #108 IopInitDeviceTreeTraverseContext( #109 &Context, #110 DeviceNode, #111 IopActionConfigureChildServices, #112 DeviceNode); #113 #114 Status = IopTraverseDeviceTree(&Context); #115 if (!NT_SUCCESS(Status)) #116 { #117 DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx/n",Status); #118 return Status; #119 } #120
初始化所有发现的PnP设备驱动程序。 #121 /* #122 * Initialize services for discovered children. #123 */ #124 Status = IopInitializePnpServices(DeviceNode); #125 if (!NT_SUCCESS(Status)) #126 { #127 DPRINT("IopInitializePnpServices() failed with status 0x%08lx/n",Status); #128 return Status; #129 } #130 #131 DPRINT("IopEnumerateDevice() finished/n"); #132 return STATUS_SUCCESS; #133 } #134 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |