reactos操作系统实现(73)
即插即用(Plug and Play,PnP)是计算机系统I/O设备与部件配置的应用技术。PnP就是指插入就可以使用,不需要进行任何的硬件配置。其实还是需要安装相应的驱动程序才可以使用的。随着人们对计算机使用多样化,不断地需要添加各种各样的硬件卡到计算机的主板上,这样就需要配置硬件卡的中断、I/O所占用的资源,才能正常工作。这个过程是非常复杂的,经常需要手工配置,还需要查看计算机那里中断是空闲的,那些I/O端口是没有占用的。使用PnP技术以后,只需要操作系统做统一分配就行了。下面就来分析PnP初始化的实现代码: #001 VOID INIT_FUNCTION #002 PnpInit(VOID) #003 { #004 PDEVICE_OBJECT Pdo; #005 NTSTATUS Status; #006 #007 DPRINT("PnpInit()/n"); #008
初始化IO设备树锁。 #009 KeInitializeSpinLock(&IopDeviceTreeLock); #010
分配总线类型的GUID列表。 #011 /* Initialize the Bus Type GUID List */ #012 IopBusTypeGuidList = ExAllocatePool(PagedPool,sizeof(IO_BUS_TYPE_GUID_LIST)); #013 if (!IopBusTypeGuidList) { #014 DPRINT1("ExAllocatePool() failed/n"); #015 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,STATUS_NO_MEMORY,0); #016 } #017 #018 RtlZeroMemory(IopBusTypeGuidList,sizeof(IO_BUS_TYPE_GUID_LIST)); #019 ExInitializeFastMutex(&IopBusTypeGuidList->Lock); #020
初始化即插即用的事件通知支持。 #021 /* Initialize PnP-Event notification support */ #022 Status = IopInitPlugPlayEvents(); #023 if (!NT_SUCCESS(Status)) #024 { #025 DPRINT1("IopInitPlugPlayEvents() failed/n"); #026 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,Status,0); #027 } #028
创建一个根设备驱动程序节点,保存在IopRootDriverObject里面。 #029 /* #030 * Create root device node #031 */ #032 #033 Status = IopCreateDriver(NULL,PnpDriverInitializeEmpty,NULL,&IopRootDriverObject); #034 if (!NT_SUCCESS(Status)) #035 { #036 DPRINT1("IoCreateDriverObject() failed/n"); #037 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,0); #038 } #039
创建一个文件设备控制器对象保存到根驱动程序节点里。 #040 Status = IoCreateDevice(IopRootDriverObject,FILE_DEVICE_CONTROLLER, #041 0,FALSE,&Pdo); #042 if (!NT_SUCCESS(Status)) #043 { #044 DPRINT1("IoCreateDevice() failed/n"); #045 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,0); #046 } #047
创建一个文件设备控制器对象节点。 #048 Status = IopCreateDeviceNode(NULL,Pdo,&IopRootDeviceNode); #049 if (!NT_SUCCESS(Status)) #050 { #051 DPRINT1("Insufficient resources/n"); #052 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,0); #053 } #054
设置这个文件设备节点名称为HTREE//ROOT//。 #055 if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath, #056 L"HTREE//ROOT//0")) #057 { #058 DPRINT1("Failed to create the instance path!/n"); #059 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,0); #060 } #061
报告这个设备到用户模式的PNP管理器。 #062 /* Report the device to the user-mode pnp manager */ #063 IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, #064 &IopRootDeviceNode->InstancePath); #065 #066 IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE; #067 PnpRootDriverEntry(IopRootDriverObject,NULL); #068 IopRootDeviceNode->PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; #069 IopRootDriverObject->DriverExtension->AddDevice( #070 IopRootDriverObject, #071 IopRootDeviceNode->PhysicalDeviceObject); #072
下面开始把Freeloader检测到的硬件信息移到注册表SYSTEM/CurrentControlSet/Root/键里。 #073 /* Move information about devices detected by Freeloader to SYSTEM/CurrentControlSet/Root/ */ #074 Status = IopUpdateRootKey(); #075 if (!NT_SUCCESS(Status)) #076 { #077 DPRINT1("IopUpdateRootKey() failed/n"); #078 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED,0); #079 } #080} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |