阅读量:0
KMOD驱动是微软提供的一个Display Only驱动。Windows驱动的入口函数是DriverEntry,所以显示Mini小端口驱动程序也不例外。和其它Mini小端口驱动的入口函数实现一致,在其DriverEntry只做一件事,就是分配系统指定的一个结构体,然后调用框架提供的接口函数即可。
extern "C" NTSTATUS DriverEntry(_In_ DRIVER_OBJECT* pDriverObject, _In_ UNICODE_STRING* pRegistryPath) { PAGED_CODE(); WPP_INIT_TRACING(NULL, NULL); DbgPrint(TRACE_LEVEL_FATAL, ("---> KMDOD build on on %s %s\n", __DATE__, __TIME__)); RTL_OSVERSIONINFOW versionInfo; versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); RtlGetVersion(&versionInfo); // VSync control is NOT planned to be enabled on Win10 builds // before RS1. Enabling it on DOD driver causes OS to stop the driver // with error 43 when the system turns off display due to idle setting. // On Windows 8.1 (9200 and 9600) till now no problem observed // (OS does not send VSync enable command) // On Windows 10RS1 (14393) enabling VSync control activates // watchdog policy and creates high sensitivity to long (> 2 sec) // processing in PresentDisplayOnly callback (stop with error 43) if (versionInfo.dwBuildNumber >= 14393 || versionInfo.dwBuildNumber <= 9600) { // we will uncomment the line below after we address all the problems // related to enabled VSync control in Win10RS1 //g_bSupportVSync = TRUE; // for support/troubleshooting be able to disable VSync on specific machine QueryVSyncSetting(g_bSupportVSync, pRegistryPath); } DbgPrint(TRACE_LEVEL_WARNING, ("VSync support %sabled for %d.%d.%d\n", g_bSupportVSync ? "en" : "dis", versionInfo.dwMajorVersion, versionInfo.dwMinorVersion, versionInfo.dwBuildNumber)); // Initialize DDI function pointers and dxgkrnl KMDDOD_INITIALIZATION_DATA InitialData = {0}; InitialData.Version = DXGKDDI_INTERFACE_VERSION; //1、关于PNP处理的回调函数:这些回调函数用于处理设备创建,起始,停止,电源相关和子设备的相关回调。 InitialData.DxgkDdiAddDevice = DodAddDevice; InitialData.DxgkDdiStartDevice = DodStartDevice; InitialData.DxgkDdiStopDevice = DodStopDevice; InitialData.DxgkDdiResetDevice = DodResetDevice; InitialData.DxgkDdiRemoveDevice = DodRemoveDevice; InitialData.DxgkDdiUnload = DodUnload; InitialData.DxgkDdiDispatchIoRequest = DodDispatchIoRequest; InitialData.DxgkDdiInterruptRoutine = DodInterruptRoutine; InitialData.DxgkDdiDpcRoutine = DodDpcRoutine; //2、与总线子设备上报相关的:类示总线设备的IRP_MN_QUERY_DEVICE_RELATIONS及有PNP子设备 InitialData.DxgkDdiQueryChildRelations = DodQueryChildRelations; InitialData.DxgkDdiQueryChildStatus = DodQueryChildStatus; InitialData.DxgkDdiQueryDeviceDescriptor = DodQueryDeviceDescriptor; InitialData.DxgkDdiSetPowerState = DodSetPowerState; InitialData.DxgkDdiQueryAdapterInfo = DodQueryAdapterInfo; InitialData.DxgkDdiQueryInterface = DodQueryInterface; //3、为与硬件相关的IRP处理:如中断及DPC处理的DxgkDdiInterruptRoutine和DxgkDdiDpcRoutine,有获取设备属性,读写设备帧内存、显示桌面内容(Present)等函数。 if (g_bSupportVSync) { InitialData.DxgkDdiControlInterrupt = DodControlInterrupt; InitialData.DxgkDdiGetScanLine = DodGetScanLine; } InitialData.DxgkDdiPresentDisplayOnly = DodPresentDisplayOnly; InitialData.DxgkDdiSystemDisplayEnable = DodSystemDisplayEnable; InitialData.DxgkDdiSystemDisplayWrite = DodSystemDisplayWrite; //4、与显卡输出相关的操作,如包括对鼠标位置的更新,显示器Mode的枚举和设置等函数: InitialData.DxgkDdiSetPointerPosition = DodSetPointerPosition; InitialData.DxgkDdiSetPointerShape = DodSetPointerShape; InitialData.DxgkDdiQueryVidPnHWCapability = DodQueryVidPnHWCapability; InitialData.DxgkDdiEscape = DodEscape; InitialData.DxgkDdiIsSupportedVidPn = DodIsSupportedVidPn; InitialData.DxgkDdiRecommendFunctionalVidPn = DodRecommendFunctionalVidPn; InitialData.DxgkDdiEnumVidPnCofuncModality = DodEnumVidPnCofuncModality; InitialData.DxgkDdiSetVidPnSourceVisibility = DodSetVidPnSourceVisibility; InitialData.DxgkDdiCommitVidPn = DodCommitVidPn; InitialData.DxgkDdiUpdateActiveVidPnPresentPath = DodUpdateActiveVidPnPresentPath; InitialData.DxgkDdiRecommendMonitorModes = DodRecommendMonitorModes; InitialData.DxgkDdiStopDeviceAndReleasePostDisplayOwnership = DodStopDeviceAndReleasePostDisplayOwnership; NTSTATUS Status = DxgkInitializeDisplayOnlyDriver(pDriverObject, pRegistryPath, &InitialData); if (!NT_SUCCESS(Status)) { DbgPrint(TRACE_LEVEL_ERROR, ("DxgkInitializeDisplayOnlyDriver failed with Status: 0x%X\n", Status)); } DbgPrint(TRACE_LEVEL_INFORMATION, ("<--- %s\n", __FUNCTION__)); return Status; }
主要过程 *操作系统调用display miniport驱动程序的DriverEntry函数。* DriverEntry分配一个 DRIVER_INITIALIZATION_DATA 结构,并初始化其成员变量 Version为DXGKDDI_INTERFACE_VERSION 和其它指针变量(主要是回调函数)。* DriverEntry调用DxgkInitialize函数来加载Microsoft DirectX图形内核子系统(DXGKNL.sys)并为DirectX图形内核子系统提供指向显示微型端口驱动程序的其他入口点函数的指针。* DxgkInitialize返回后,DriverEntry将DxgkInitialize的返回值传播回操作系统。