您的位置:首页 > Web前端 > React

reactos操作系统实现(149)

2009-12-02 23:11 381 查看
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,
"HwFindAdapter call failed with error 0x%X/n", 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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: