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}
原文链接:https://www.f2er.com/react/308374.html