reactos操作系统实现(149)
IntVideoPortFindAdapter函数主要用来查找到相应显示卡,并且把显示卡驱动安装到对象管理器里,以便GUI界面调用时,可以找到相应驱动程序显示。具体实现代码如下: #001 NTSTATUS NTAPI #002 IntVideoPortFindAdapter( #003 IN PDRIVER_OBJECT DriverObject, #004 IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension, #005 IN PDEVICE_OBJECT DeviceObject) #006 { #007 WCHAR DeviceVideoBuffer[20]; #008 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; #009 ULONG Size; #010 NTSTATUS Status; #011 VIDEO_PORT_CONFIG_INFO ConfigInfo; #012 SYSTEM_BASIC_INFORMATION SystemBasicInfo; #013 UCHAR Again = FALSE; #014 WCHAR DeviceBuffer[20]; #015 UNICODE_STRING DeviceName; #016 WCHAR SymlinkBuffer[20]; #017 UNICODE_STRING SymlinkName; #018 BOOL LegacyDetection = FALSE; #019 ULONG DeviceNumber; #020
获取驱动程序扩展。 #021 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
获取显示卡的设备号。 #022 DeviceNumber = DeviceExtension->DeviceNumber; #023 #024 /* #025 * Setup a ConfigInfo structure that we will pass to HwFindAdapter. #026 */ #027
设置配置信息结构,传送给查找显示卡函数。 #028 RtlZeroMemory(&ConfigInfo,sizeof(VIDEO_PORT_CONFIG_INFO)); #029 ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO); #030 ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType; #031 if (ConfigInfo.AdapterInterfaceType == PCIBus) #032 ConfigInfo.InterruptMode = LevelSensitive; #033 else #034 ConfigInfo.InterruptMode = Latched;
驱动程序注册表路径。 #035 ConfigInfo.DriverRegistryPath = DriverExtension->RegistryPath.Buffer; #036 ConfigInfo.VideoPortGetProcAddress = IntVideoPortGetProcAddress; #037 ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; #038 ConfigInfo.BusInterruptLevel = DeviceExtension->InterruptLevel; #039 ConfigInfo.BusInterruptVector = DeviceExtension->InterruptVector; #040
查询系统的基本信息。 #041 Size = sizeof(SystemBasicInfo); #042 Status = ZwQuerySystemInformation( #043 SystemBasicInformation, #044 &SystemBasicInfo, #045 Size, #046 &Size); #047 #048 if (NT_SUCCESS(Status)) #049 { #050 ConfigInfo.SystemMemorySize = #051 SystemBasicInfo.NumberOfPhysicalPages * #052 SystemBasicInfo.PageSize; #053 } #054 #055 /* #056 * Call miniport HwVidFindAdapter entry point to detect if #057 * particular device is present. There are two possible code #058 * paths. The first one is for Legacy drivers (NT4) and cases #059 * when we don't have information about what bus we're on. The #060 * second case is the standard one for Plug & Play drivers. #061 */
如果物理设备对象为空,说明是旧的驱动程序。 #062 if (DeviceExtension->PhysicalDeviceObject == NULL) #063 { #064 LegacyDetection = TRUE; #065 } #066 #067 if (LegacyDetection) #068 { #069 ULONG BusNumber,MaxBuses; #070
分析总线上所有设备。 #071 MaxBuses = DeviceExtension->AdapterInterfaceType == PCIBus ? 8 : 1; #072 #073 for (BusNumber = 0; BusNumber < MaxBuses; BusNumber++) #074 { #075 DeviceExtension->SystemIoBusNumber = #076 ConfigInfo.SystemIoBusNumber = BusNumber; #077 #078 RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, #079 DriverExtension->InitializationData.HwDeviceExtensionSize); #080 #081 /* FIXME: Need to figure out what string to pass as param 3. */
查找设备是否存在。 #082 Status = DriverExtension->InitializationData.HwFindAdapter( #083 &DeviceExtension->MiniPortDeviceExtension, #084 DriverExtension->HwContext, #085 NULL, #086 &ConfigInfo, #087 &Again); #088 #089 if (Status == ERROR_DEV_NOT_EXIST) #090 { #091 continue; #092 } #093 else if (Status == NO_ERROR) #094 { #095 break; #096 } #097 else #098 { #099 WARN_(VIDEOPRT,"HwFindAdapter call failed with error 0x%X/n",Status); #100 RtlFreeUnicodeString(&DeviceExtension->RegistryPath); #101 IoDeleteDevice(DeviceObject); #102 #103 return Status; #104 } #105 } #106 } #107 else #108 { #109 /* FIXME: Need to figure out what string to pass as param 3. */ #110 Status = DriverExtension->InitializationData.HwFindAdapter( #111 &DeviceExtension->MiniPortDeviceExtension, #112 DriverExtension->HwContext, #113 NULL, #114 &ConfigInfo, #115 &Again); #116 } #117 #118 if (Status != NO_ERROR) #119 { #120 WARN_(VIDEOPRT,Status); #121 RtlFreeUnicodeString(&DeviceExtension->RegistryPath); #122 IoDeleteDevice(DeviceObject); #123 return Status; #124 } #125
到这里已经发现设备已经存在,下面开始创建符号连接,并关联到设备对象里,还设置了显示卡的中断和定时器。 #126 /* #127 * Now we know the device is present,so let's do all additional tasks #128 * such as creating symlinks or setting up interrupts and timer. #129 */ #130
创建UNICODE的设备名称。 #131 /* Create a unicode device name. */ #132 swprintf(DeviceBuffer,L"//Device//Video%lu",DeviceNumber); #133 RtlInitUnicodeString(&DeviceName,DeviceBuffer); #134
创建显示设备的符号连接。 #135 /* Create symbolic link "/??/DISPLAYx" */ #136 swprintf(SymlinkBuffer,L"//??//DISPLAY%lu",DeviceNumber + 1); #137 RtlInitUnicodeString(&SymlinkName,SymlinkBuffer); #138 IoCreateSymbolicLink(&SymlinkName,&DeviceName); #139
添加显示设备到注册表。 #140 /* Add entry to DEVICEMAP/VIDEO key in registry. */ #141 swprintf(DeviceVideoBuffer,L"//Device//Video%d",DeviceNumber); #142 RtlWriteRegistryValue( #143 RTL_REGISTRY_DEVICEMAP, #144 L"VIDEO", #145 DeviceVideoBuffer, #146 REG_SZ, #147 DeviceExtension->RegistryPath.Buffer, #148 DeviceExtension->RegistryPath.MaximumLength); #149 #150 RtlWriteRegistryValue( #151 RTL_REGISTRY_DEVICEMAP, #152 L"VIDEO", #153 L"MaxObjectNumber", #154 REG_DWORD, #155 &DeviceNumber, #156 sizeof(DeviceNumber)); #157 #158 /* FIXME: Allocate hardware resources for device. */ #159 #160 /* #161 * Allocate interrupt for device. #162 */ #163
分配中断号给显示设备。 #164 if (!IntVideoPortSetupInterrupt(DeviceObject,DriverExtension,&ConfigInfo)) #165 { #166 RtlFreeUnicodeString(&DeviceExtension->RegistryPath); #167 IoDeleteDevice(DeviceObject); #168 return STATUS_INSUFFICIENT_RESOURCES; #169 } #170 #171 /* #172 * Allocate timer for device. #173 */ #174
分配定时器给显示设备。 #175 if (!IntVideoPortSetupTimer(DeviceObject,DriverExtension)) #176 { #177 if (DeviceExtension->InterruptObject != NULL) #178 IoDisconnectInterrupt(DeviceExtension->InterruptObject); #179 RtlFreeUnicodeString(&DeviceExtension->RegistryPath); #180 IoDeleteDevice(DeviceObject); #181 WARN_(VIDEOPRT,"STATUS_INSUFFICIENT_RESOURCES/n"); #182 return STATUS_INSUFFICIENT_RESOURCES; #183 } #184
查询显示设备的子设备。 #185 /* #186 * Query children of the device. #187 */ #188 VideoPortEnumerateChildren(&DeviceExtension->MiniPortDeviceExtension,NULL); #189 #190 INFO_(VIDEOPRT,"STATUS_SUCCESS/n"); #191 return STATUS_SUCCESS; #192} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |