reactos操作系统实现(148)
在小端口驱动程序里,主要调用视频驱动程序API来实现相关的功能,下面就来分析小端口驱动程序里调用的初始化函数VideoPortInitialize,它的实现代码在文件reactos/drivers/video/videoprt/videoprt.c里,如下:
#001 ULONG NTAPI
#002 VideoPortInitialize(
#003 IN PVOID Context1,
#004 IN PVOID Context2,
#005 IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
#006 IN PVOID HwContext)
#007 {
驱动程序对象参数。
#008 PDRIVER_OBJECT DriverObject = Context1;
注册表路径。
#009 PUNICODE_STRING RegistryPath = Context2;
#010 NTSTATUS Status;
#011 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
#012 BOOLEAN PnpDriver = FALSE, LegacyDetection = FALSE;
#013
#014 TRACE_(VIDEOPRT, "VideoPortInitialize/n");
#015
#016 /*
#017 * As a first thing do parameter checks.
#018 */
#019
首先做参数检查,如果失败就返回出错。
#020 if (HwInitializationData->HwInitDataSize > sizeof(VIDEO_HW_INITIALIZATION_DATA))
#021 {
#022 return STATUS_REVISION_MISMATCH;
#023 }
#024
#025 if (HwInitializationData->HwFindAdapter == NULL ||
#026 HwInitializationData->HwInitialize == NULL ||
#027 HwInitializationData->HwStartIO == NULL)
#028 {
#029 return STATUS_INVALID_PARAMETER;
#030 }
#031
根据初始化的数据结构大小来区分不同的系统版本。
#032 switch (HwInitializationData->HwInitDataSize)
#033 {
#034 /*
#035 * NT4 drivers are special case, because we must use legacy method
#036 * of detection instead of the Plug & Play one.
#037 */
#038
#039 case SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA:
#040 INFO_(VIDEOPRT, "We were loaded by a Windows NT miniport driver./n");
#041 break;
#042
#043 case SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA:
#044 INFO_(VIDEOPRT, "We were loaded by a Windows 2000 miniport driver./n");
#045 break;
#046
#047 case sizeof(VIDEO_HW_INITIALIZATION_DATA):
#048 INFO_(VIDEOPRT, "We were loaded by a Windows XP or later miniport driver./n");
#049 break;
#050
#051 default:
#052 WARN_(VIDEOPRT, "Invalid HwInitializationData size./n");
#053 return STATUS_UNSUCCESSFUL;
#054 }
#055
设置驱动程序处理功能函数。
#056 /* Set dispatching routines */
#057 DriverObject->MajorFunction[IRP_MJ_CREATE] = IntVideoPortDispatchOpen;
#058 DriverObject->MajorFunction[IRP_MJ_CLOSE] = IntVideoPortDispatchClose;
#059 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
#060 IntVideoPortDispatchDeviceControl;
#061 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
#062 IntVideoPortDispatchDeviceControl;
#063 DriverObject->MajorFunction[IRP_MJ_WRITE] =
#064 IntVideoPortDispatchWrite; // ReactOS-specific hack
#065 DriverObject->DriverUnload = IntVideoPortUnload;
#066
检查小端口驱动程序是什么类型。
#067 /* Determine type of the miniport driver */
#068 if ((HwInitializationData->HwInitDataSize >=
#069 FIELD_OFFSET(VIDEO_HW_INITIALIZATION_DATA, HwQueryInterface))
#070 && HwInitializationData->HwSetPowerState
#071 && HwInitializationData->HwGetPowerState
#072 && HwInitializationData->HwGetVideoChildDescriptor)
#073 {
这里检测到小端口驱动程序是即插即用驱动程序。
#074 INFO_(VIDEOPRT, "The miniport is a PnP miniport driver/n");
#075 PnpDriver = TRUE;
#076 }
#077
检查是否旧的驱动程序模式。
#078 /* Check if legacy detection should be applied */
#079 if (!PnpDriver || HwContext)
#080 {
#081 INFO_(VIDEOPRT, "Legacy detection for adapter interface %d/n",
#082 HwInitializationData->AdapterInterfaceType);
#083
#084 /* FIXME: Move the code for legacy detection
#085 to another function and call it here */
#086 LegacyDetection = TRUE;
#087 }
#088
#089 /*
#090 * NOTE:
#091 * The driver extension can be already allocated in case that we were
#092 * called by legacy driver and failed detecting device. Some miniport
#093 * drivers in that case adjust parameters and call VideoPortInitialize
#094 * again.
#095 */
#096
尝试获取驱动程序扩展数据。
#097 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
#098 if (DriverExtension == NULL)
#099 {
如果没有分配驱动程序扩展,就在这里分配。
#100 Status = IoAllocateDriverObjectExtension(
#101 DriverObject,
#102 DriverObject,
#103 sizeof(VIDEO_PORT_DRIVER_EXTENSION),
#104 (PVOID *)&DriverExtension);
#105
#106 if (!NT_SUCCESS(Status))
#107 {
#108 return Status;
#109 }
#110
#111 /*
#112 * Save the registry path. This should be done only once even if
#113 * VideoPortInitialize is called multiple times.
#114 */
#115
保存当前驱动程序在注册表里的路径。
#116 if (RegistryPath->Length != 0)
#117 {
#118 DriverExtension->RegistryPath.Length = 0;
#119 DriverExtension->RegistryPath.MaximumLength =
#120 RegistryPath->Length + sizeof(UNICODE_NULL);
#121 DriverExtension->RegistryPath.Buffer =
#122 ExAllocatePoolWithTag(
#123 PagedPool,
#124 DriverExtension->RegistryPath.MaximumLength,
#125 TAG('U', 'S', 'T', 'R'));
#126 if (DriverExtension->RegistryPath.Buffer == NULL)
#127 {
#128 RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL);
#129 return STATUS_INSUFFICIENT_RESOURCES;
#130 }
#131
#132 RtlCopyUnicodeString(&DriverExtension->RegistryPath, RegistryPath);
#133 INFO_(VIDEOPRT, "RegistryPath: %wZ/n", &DriverExtension->RegistryPath);
#134 }
#135 else
#136 {
#137 RtlInitUnicodeString(&DriverExtension->RegistryPath, NULL);
#138 }
#139 }
#140
#141 /*
#142 * Copy the correct miniport initialization data to the device extension.
#143 */
#144
拷贝初始化数据。
#145 RtlCopyMemory(
#146 &DriverExtension->InitializationData,
#147 HwInitializationData,
#148 HwInitializationData->HwInitDataSize);
#149 if (HwInitializationData->HwInitDataSize <
#150 sizeof(VIDEO_HW_INITIALIZATION_DATA))
#151 {
#152 RtlZeroMemory((PVOID)((ULONG_PTR)&DriverExtension->InitializationData +
#153 HwInitializationData->HwInitDataSize),
#154 sizeof(VIDEO_HW_INITIALIZATION_DATA) -
#155 HwInitializationData->HwInitDataSize);
#156 }
#157 DriverExtension->HwContext = HwContext;
#158
#159 /*
#160 * Plug & Play drivers registers the device in AddDevice routine. For
#161 * legacy drivers we must do it now.
#162 */
#163
旧的驱动程序进行功能回调函数设置。
#164 if (LegacyDetection)
#165 {
#166 PDEVICE_OBJECT DeviceObject;
#167
#168 if (HwInitializationData->HwInitDataSize != SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA)
#169 {
#170 /* power management */
#171 DriverObject->MajorFunction[IRP_MJ_POWER] = IntVideoPortDispatchPower;
#172 }
#173 Status = IntVideoPortCreateAdapterDeviceObject(DriverObject, DriverExtension,
#174 NULL, &DeviceObject);
#175 INFO_(VIDEOPRT, "IntVideoPortCreateAdapterDeviceObject returned 0x%x/n", Status);
#176 if (!NT_SUCCESS(Status))
#177 return Status;
这里调用函数IntVideoPortFindAdapter来注册本显示驱动程序到对象管理器,以便创建设备DC时使用。
#178 Status = IntVideoPortFindAdapter(DriverObject, DriverExtension, DeviceObject);
#179 INFO_(VIDEOPRT, "IntVideoPortFindAdapter returned 0x%x/n", Status);
#180 if (NT_SUCCESS(Status))
#181 VideoPortDeviceNumber++;
#182 return Status;
#183 }
#184 else
#185 {
即插即用的驱动程序的回调函数设置。
#186 DriverObject->DriverExtension->AddDevice = IntVideoPortAddDevice;
#187 DriverObject->MajorFunction[IRP_MJ_PNP] = IntVideoPortDispatchPnp;
#188 DriverObject->MajorFunction[IRP_MJ_POWER] = IntVideoPortDispatchPower;
#189 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IntVideoPortDispatchSystemControl;
#190
#191 return STATUS_SUCCESS;
#192 }
#193 }
相关文章
- SqlServer如何通过SQL语句获取处理器(CPU)、内存(Memory)、磁盘(Disk)以及操作系统相关信息
- 使用Linux操作系统实现GSoap技术(linuxgsoap)
- 表 Linux 注册表:实现操作系统有力管理 (linux注册)
- 操作系统在Linux5上运行源自操作系统(linuxas5)
- 操作系统的设计和实现过程
- Linux操作系统:实现安全的网络环境(linux操作系统安全)
- Linux 启动过程详解:一步步实现操作系统的唤醒(linux启动详解)
- Linux分支:丰富多样的操作系统选择(linux的分支)
- 操作系统学习Linux的分支操作系统——实现灵活操作(linux的分支)
- Linux操作系统针对Oracle的关闭方法(linux关闭oracle)
- Linux的应用前景愈发光明,成为企业和开发人员的首选操作系统(linux的应用前景)
- 评估Linux:对操作系统的全面评价(evallinux)
- :20Linux:改变世界的开源操作系统(linux长度)
- 运行脚本实现Linux脚本运行的步骤(在linux操作系统)
- 串Linux操作系统中插入字符串的技巧(linux插入字符)
- Linux文件操作系统:应用与实现(linuxfops)
- 驱动解决Linux操作系统的联想打印机驱动指南(linux联想打印机)
- 系统搭建Linux X窗口系统构建:一步一步实现操作系统奇迹(linuxx窗口)
- “探索Linux主机:深入了解最受欢迎的操作系统的基础知识与应用”。(linux主机)
- 打造完美家庭服务器,使用Linux操作系统(家庭服务器linux)
- Linux:提高计算效率的高性能操作系统(linux高性能计算)
- Linux虚拟机使用指南:轻松实现跨操作系统的迁移(linux虚拟机使用教程)
- 掌握Oracle操作系统,轻松实现数据库管理(oracle os)