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,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} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |