zl程序教程

您现在的位置是:首页 >  系统

当前栏目

reactos操作系统实现(148)

操作系统 实现 reactos
2023-09-14 09:10:39 时间

在小端口驱动程序里,主要调用视频驱动程序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  }