在小端口驱动程序里,主要调用视频驱动程序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,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}
原文链接:/react/308375.html