#pragma once #include "baseobject.h" typedef struct _QXL_FLAGS { UINT DriverStarted : 1; // ( 1) 1 after StartDevice and 0 after StopDevice UINT Unused : 31; } QXL_FLAGS; #define MAX_CHILDREN 1 #define MAX_VIEWS 1 #pragma pack(push) #pragma pack(1) typedef struct { CHAR Signature[4]; USHORT Version; ULONG OemStringPtr; LONG Capabilities; ULONG VideoModePtr; USHORT TotalMemory; USHORT OemSoftwareRevision; ULONG OemVendorNamePtr; ULONG OemProductNamePtr; ULONG OemProductRevPtr; CHAR Reserved[222]; // CHAR OemData[256]; } VBE_INFO, *PVBE_INFO; typedef struct { /* Mandatory information for all VBE revisions */ USHORT ModeAttributes; UCHAR WinAAttributes; UCHAR WinBAttributes; USHORT WinGranularity; USHORT WinSize; USHORT WinASegment; USHORT WinBSegment; ULONG WinFuncPtr; USHORT BytesPerScanLine; /* Mandatory information for VBE 1.2 and above */ USHORT XResolution; USHORT YResolution; UCHAR XCharSize; UCHAR YCharSize; UCHAR NumberOfPlanes; UCHAR BitsPerPixel; UCHAR NumberOfBanks; UCHAR MemoryModel; UCHAR BankSize; UCHAR NumberOfImagePages; UCHAR Reserved1; /* Direct Color fields (required for Direct/6 and YUV/7 memory models) */ UCHAR RedMaskSize; UCHAR RedFieldPosition; UCHAR GreenMaskSize; UCHAR GreenFieldPosition; UCHAR BlueMaskSize; UCHAR BlueFieldPosition; UCHAR ReservedMaskSize; UCHAR ReservedFieldPosition; UCHAR DirectColorModeInfo; /* Mandatory information for VBE 2.0 and above */ ULONG PhysBasePtr; ULONG Reserved2; USHORT Reserved3; /* Mandatory information for VBE 3.0 and above */ USHORT LinBytesPerScanLine; UCHAR BnkNumberOfImagePages; UCHAR LinNumberOfImagePages; UCHAR LinRedMaskSize; UCHAR LinRedFieldPosition; UCHAR LinGreenMaskSize; UCHAR LinGreenFieldPosition; UCHAR LinBlueMaskSize; UCHAR LinBlueFieldPosition; UCHAR LinReservedMaskSize; UCHAR LinReservedFieldPosition; ULONG MaxPixelClock; CHAR Reserved4[189]; } VBE_MODEINFO, *PVBE_MODEINFO; #pragma pack(pop) typedef struct _X86BIOS_REGISTERS // invented names { ULONG Eax; ULONG Ecx; ULONG Edx; ULONG Ebx; ULONG Ebp; ULONG Esi; ULONG Edi; USHORT SegDs; USHORT SegEs; } X86BIOS_REGISTERS, *PX86BIOS_REGISTERS; /* Undocumented imports from the HAL */ #ifdef __cplusplus extern "C" { #endif NTHALAPI BOOLEAN x86BiosCall (ULONG, PX86BIOS_REGISTERS); NTHALAPI NTSTATUS x86BiosAllocateBuffer (ULONG *, USHORT *, USHORT *); NTHALAPI NTSTATUS x86BiosFreeBuffer (USHORT, USHORT); NTHALAPI NTSTATUS x86BiosReadMemory (USHORT, USHORT, PVOID, ULONG); NTHALAPI NTSTATUS x86BiosWriteMemory (USHORT, USHORT, PVOID, ULONG); #ifdef __cplusplus } #endif class QxlDod : public BaseObject { private: DEVICE_OBJECT* m_pPhysicalDevice; DXGKRNL_INTERFACE m_DxgkInterface; DXGK_DEVICE_INFO m_DeviceInfo; DEVICE_POWER_STATE m_MonitorPowerState; DEVICE_POWER_STATE m_AdapterPowerState; QXL_FLAGS m_Flags; PVBE_MODEINFO m_ModeInfo; ULONG m_ModeCount; PUSHORT m_ModeNumbers; USHORT m_CurrentMode; public: QxlDod(_In_ DEVICE_OBJECT* pPhysicalDeviceObject); ~QxlDod(void); #pragma code_seg(push) #pragma code_seg() BOOLEAN IsDriverActive() const { return m_Flags.DriverStarted; } #pragma code_seg(pop) NTSTATUS StartDevice(_In_ DXGK_START_INFO* pDxgkStartInfo, _In_ DXGKRNL_INTERFACE* pDxgkInterface, _Out_ ULONG* pNumberOfViews, _Out_ ULONG* pNumberOfChildren); NTSTATUS StopDevice(VOID); // Must be Non-Paged VOID ResetDevice(VOID); NTSTATUS DispatchIoRequest(_In_ ULONG VidPnSourceId, _In_ VIDEO_REQUEST_PACKET* pVideoRequestPacket); NTSTATUS SetPowerState(_In_ ULONG HardwareUid, _In_ DEVICE_POWER_STATE DevicePowerState, _In_ POWER_ACTION ActionType); // Report back child capabilities NTSTATUS QueryChildRelations(_Out_writes_bytes_(ChildRelationsSize) DXGK_CHILD_DESCRIPTOR* pChildRelations, _In_ ULONG ChildRelationsSize); NTSTATUS QueryChildStatus(_Inout_ DXGK_CHILD_STATUS* pChildStatus, _In_ BOOLEAN NonDestructiveOnly); // Return EDID if previously retrieved NTSTATUS QueryDeviceDescriptor(_In_ ULONG ChildUid, _Inout_ DXGK_DEVICE_DESCRIPTOR* pDeviceDescriptor); // Must be Non-Paged // BDD doesn't have interrupts, so just returns false BOOLEAN InterruptRoutine(_In_ ULONG MessageNumber); VOID DpcRoutine(VOID); // Return DriverCaps, doesn't support other queries though NTSTATUS QueryAdapterInfo(_In_ CONST DXGKARG_QUERYADAPTERINFO* pQueryAdapterInfo); NTSTATUS SetPointerPosition(_In_ CONST DXGKARG_SETPOINTERPOSITION* pSetPointerPosition); NTSTATUS SetPointerShape(_In_ CONST DXGKARG_SETPOINTERSHAPE* pSetPointerShape); NTSTATUS Escape(_In_ CONST DXGKARG_ESCAPE* pEscape); NTSTATUS PresentDisplayOnly(_In_ CONST DXGKARG_PRESENT_DISPLAYONLY* pPresentDisplayOnly); NTSTATUS QueryInterface(_In_ CONST PQUERY_INTERFACE QueryInterface); NTSTATUS IsSupportedVidPn(_Inout_ DXGKARG_ISSUPPORTEDVIDPN* pIsSupportedVidPn); NTSTATUS RecommendFunctionalVidPn(_In_ CONST DXGKARG_RECOMMENDFUNCTIONALVIDPN* CONST pRecommendFunctionalVidPn); NTSTATUS RecommendVidPnTopology(_In_ CONST DXGKARG_RECOMMENDVIDPNTOPOLOGY* CONST pRecommendVidPnTopology); NTSTATUS RecommendMonitorModes(_In_ CONST DXGKARG_RECOMMENDMONITORMODES* CONST pRecommendMonitorModes); NTSTATUS EnumVidPnCofuncModality(_In_ CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModality); NTSTATUS SetVidPnSourceVisibility(_In_ CONST DXGKARG_SETVIDPNSOURCEVISIBILITY* pSetVidPnSourceVisibility); NTSTATUS CommitVidPn(_In_ CONST DXGKARG_COMMITVIDPN* CONST pCommitVidPn); NTSTATUS UpdateActiveVidPnPresentPath(_In_ CONST DXGKARG_UPDATEACTIVEVIDPNPRESENTPATH* CONST pUpdateActiveVidPnPresentPath); NTSTATUS QueryVidPnHWCapability(_Inout_ DXGKARG_QUERYVIDPNHWCAPABILITY* pVidPnHWCaps); // Part of PnPStop (PnP instance only), returns current mode information (which will be passed to fallback instance by dxgkrnl) NTSTATUS StopDeviceAndReleasePostDisplayOwnership(_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId, _Out_ DXGK_DISPLAY_INFORMATION* pDisplayInfo); // Must be Non-Paged // Call to initialize as part of bugcheck NTSTATUS SystemDisplayEnable(_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID TargetId, _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS Flags, _Out_ UINT* pWidth, _Out_ UINT* pHeight, _Out_ D3DDDIFORMAT* pColorFormat); // Must be Non-Paged // Write out pixels as part of bugcheck VOID SystemDisplayWrite(_In_reads_bytes_(SourceHeight * SourceStride) VOID* pSource, _In_ UINT SourceWidth, _In_ UINT SourceHeight, _In_ UINT SourceStride, _In_ INT PositionX, _In_ INT PositionY); private: VOID CleanUp(VOID); NTSTATUS WriteHWInfoStr(_In_ HANDLE DevInstRegKeyHandle, _In_ PCWSTR pszwValueName, _In_ PCSTR pszValue); NTSTATUS RegisterHWInfo(); NTSTATUS VbeGetModeList(); NTSTATUS VbeQueryCurrentMode(PVIDEO_MODE RequestedMode); NTSTATUS VbeSetCurrentMode(PVIDEO_MODE RequestedMode); NTSTATUS VbeSetPowerState(POWER_ACTION ActionType); };