/// <summary> /// Allocate page for PTE table /// </summary> /// <param name="pEPT">CPU EPT data</param> /// <returns>Allocated page or NULL</returns> PEPT_MMPTE EptpAllocatePage( IN PEPT_DATA pEPT ) { // at IRQL > DISPATCH_LEVEL memory allocation routines don't work if (KeGetCurrentIrql() > DISPATCH_LEVEL) return EptpAllocatePageHighIRQL( pEPT ); PHYSICAL_ADDRESS Highest = { 0 }, Lowest = { 0 }; Highest.QuadPart = ~0; PEPT_MMPTE ptr = (PEPT_MMPTE)MmAllocateContiguousMemorySpecifyCache( PAGE_SIZE, Lowest, Highest, Lowest, MmNonCached ); // Save page ptr in array if (ptr) { pEPT->TotalPages++; RtlZeroMemory( ptr, PAGE_SIZE ); BOOLEAN allocEntry = FALSE; PEPT_PAGES_ENTRY pEntry = NULL; if (IsListEmpty( &pEPT->PageList )) { allocEntry = TRUE; } else { pEntry = CONTAINING_RECORD( pEPT->PageList.Flink, EPT_PAGES_ENTRY, link ); if (pEntry->count >= PAGES_PER_ENTRY) allocEntry = TRUE; } if (allocEntry) { pEntry = ExAllocatePoolWithTag( NonPagedPoolNx, sizeof( EPT_PAGES_ENTRY ), HB_POOL_TAG ); if (pEntry == NULL) { DPRINT( "HyperBone: CPU %d: %s: Failed to allocate EPT_PAGES_ENTRY struct\n", CPU_IDX, __FUNCTION__ ); return ptr; } RtlZeroMemory( pEntry, sizeof( EPT_PAGES_ENTRY ) ); pEntry->pages[pEntry->count] = ptr; pEntry->count++; InsertHeadList( &pEPT->PageList, &pEntry->link ); } else { pEntry->pages[pEntry->count] = ptr; pEntry->count++; } } else { DPRINT( "HyperBone: CPU %d: %s: Failed to allocate EPT page\n", CPU_IDX, __FUNCTION__ ); ASSERT( FALSE ); } return ptr; }
NTSTATUS AllocateVmxProcessorData(PVOID *VirtualAddress, PHYSICAL_ADDRESS *PhysicalAddress, SIZE_T *Size) { if (!VirtualAddress || !PhysicalAddress || !Size) return STATUS_INVALID_PARAMETER; // // Read the MSR information to get the base size // Default to 4096 bytes // VMX_BASIC_MSR msr; TO_ULL(msr) = __readmsr(MSR_IA32_VMX_BASIC); if (*Size <= 0) { // In rare cases this isn't set (*COUGH* *VMWARE*) if (msr.szVmxOnRegion > 0) *Size = msr.szVmxOnRegion; else *Size = 0x1000; *Size = ROUND_TO_PAGES(*Size); } // // Allocate CONTIGUOUS physical memory // MmCached = Stored in CPU L1/L2/L3 cache if possible // PHYSICAL_ADDRESS l1, l2, l3; l1.QuadPart = 0; l2.QuadPart = -1; l3.QuadPart = 0x200000; PVOID address = MmAllocateContiguousMemorySpecifyCache(*Size, l1, l2, l3, MmCached); if (!address) return STATUS_NO_MEMORY; RtlSecureZeroMemory(address, *Size); // // Set the revision id // *(ULONG *)address = msr.RevId; // // Done // *VirtualAddress = address; *PhysicalAddress = MmGetPhysicalAddress(address); return STATUS_SUCCESS; }
PVOID AllocateContiguousMemory(ULONG size) { PVOID Address; PHYSICAL_ADDRESS l1, l2, l3; l1.QuadPart = 0; l2.QuadPart = -1; l3.QuadPart = 0x200000; Address = MmAllocateContiguousMemorySpecifyCache(size, l1, l2, l3, MmCached); if (Address == NULL) { return NULL; } RtlZeroMemory(Address, size); return Address; }
NTSTATUS RosKmdGlobal::DriverEntry(__in IN DRIVER_OBJECT* pDriverObject, __in IN UNICODE_STRING* pRegistryPath) { NTSTATUS Status; DRIVER_INITIALIZATION_DATA DriverInitializationData; NT_ASSERT(!RosKmdGlobal::s_pDriverObject); RosKmdGlobal::s_pDriverObject = pDriverObject; // // Initialize logging // { WPP_INIT_TRACING(pDriverObject, pRegistryPath); RECORDER_CONFIGURE_PARAMS recorderConfigureParams; RECORDER_CONFIGURE_PARAMS_INIT(&recorderConfigureParams); WppRecorderConfigure(&recorderConfigureParams); WPP_RECORDER_LEVEL_FILTER(ROS_TRACING_VIDPN) = FALSE; WPP_RECORDER_LEVEL_FILTER(ROS_TRACING_PRESENT) = FALSE; #if DBG WPP_RECORDER_LEVEL_FILTER(ROS_TRACING_DEFAULT) = TRUE; #endif // DBG } ROS_LOG_INFORMATION( "Initializing roskmd. (pDriverObject=0x%p, pRegistryPath=%wZ)", pDriverObject, pRegistryPath); if (s_bDoNotInstall) { ROS_LOG_INFORMATION("s_bDoNotInstall is set; aborting driver initialization."); return STATUS_UNSUCCESSFUL; } // // Allocate physically contiguous memory to represent cpu visible video memory // PHYSICAL_ADDRESS lowestAcceptableAddress; lowestAcceptableAddress.QuadPart = 0; PHYSICAL_ADDRESS highestAcceptableAddress; highestAcceptableAddress.QuadPart = -1; PHYSICAL_ADDRESS boundaryAddressMultiple; boundaryAddressMultiple.QuadPart = 0; s_videoMemorySize = kMaxVideoMemorySize; while (s_pVideoMemory == NULL) { // // The allocated contiguous memory is mapped as cached // // TODO[indyz]: Evaluate if flushing CPU cache for GPU access is the best option // // Use this option because GenerateRenderControlList has data alignment issue // s_pVideoMemory = MmAllocateContiguousMemorySpecifyCache( s_videoMemorySize, lowestAcceptableAddress, highestAcceptableAddress, boundaryAddressMultiple, MmCached); if (s_pVideoMemory != NULL) { break; } s_videoMemorySize >>= 1; } s_videoMemoryPhysicalAddress = MmGetPhysicalAddress(s_pVideoMemory); // // Query the driver registry key to see whether we're render only // { OBJECT_ATTRIBUTES attributes; InitializeObjectAttributes( &attributes, pRegistryPath, OBJ_KERNEL_HANDLE, nullptr, // RootDirectory nullptr); // SecurityDescriptor HANDLE keyHandle; Status = ZwOpenKey(&keyHandle, GENERIC_READ, &attributes); if (!NT_SUCCESS(Status)) { ROS_LOG_ERROR( "Failed to open driver registry key. (Status=%!STATUS!, pRegistryPath=%wZ, pDriverObject=0x%p)", Status, pRegistryPath, pDriverObject); return Status; } auto closeRegKey = ROS_FINALLY::Do([&] { PAGED_CODE(); NTSTATUS tempStatus = ZwClose(keyHandle); UNREFERENCED_PARAMETER(tempStatus); NT_ASSERT(NT_SUCCESS(tempStatus)); }); DECLARE_CONST_UNICODE_STRING(renderOnlyValueName, L"RenderOnly"); #pragma warning(disable:4201) // nameless struct/union union { KEY_VALUE_PARTIAL_INFORMATION PartialInfo; struct { ULONG TitleIndex; ULONG Type; ULONG DataLength; ULONG Data; } DUMMYSTRUCTNAME; } valueInfo; #pragma warning(default:4201) // nameless struct/union ULONG resultLength; Status = ZwQueryValueKey( keyHandle, const_cast<UNICODE_STRING*>(&renderOnlyValueName), KeyValuePartialInformation, &valueInfo.PartialInfo, sizeof(valueInfo), &resultLength); if (NT_SUCCESS(Status)) { if (valueInfo.Type == REG_DWORD) { NT_ASSERT(valueInfo.DataLength == sizeof(valueInfo.Data)); if (valueInfo.Data != 0) { ROS_LOG_INFORMATION("Configuring driver as render-only."); s_bRenderOnly = true; } } else { ROS_LOG_WARNING( "RenderOnly registry value was found, but is not a REG_DWORD. (valueInfo.Type=%d, valueInfo.DataLength=%d)", valueInfo.Type, valueInfo.DataLength); } } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) { ROS_LOG_ASSERTION( "Unexpected error occurred querying RenderOnly registry key. (Status=%!STATUS!)", Status); // an unexpected type in the registry could cause us to get here, // so don't stop the show. } } // RenderOnly // // Fill in the DriverInitializationData structure and call DlInitialize() // memset(&DriverInitializationData, 0, sizeof(DriverInitializationData)); DriverInitializationData.Version = DXGKDDI_INTERFACE_VERSION; DriverInitializationData.DxgkDdiAddDevice = RosKmdDdi::DdiAddAdapter; DriverInitializationData.DxgkDdiStartDevice = RosKmdDdi::DdiStartAdapter; DriverInitializationData.DxgkDdiStopDevice = RosKmdDdi::DdiStopAdapter; DriverInitializationData.DxgkDdiRemoveDevice = RosKmdDdi::DdiRemoveAdapter; DriverInitializationData.DxgkDdiDispatchIoRequest = RosKmdDdi::DdiDispatchIoRequest; DriverInitializationData.DxgkDdiInterruptRoutine = RosKmdDdi::DdiInterruptRoutine; DriverInitializationData.DxgkDdiDpcRoutine = RosKmdDdi::DdiDpcRoutine; DriverInitializationData.DxgkDdiQueryChildRelations = RosKmdDdi::DdiQueryChildRelations; DriverInitializationData.DxgkDdiQueryChildStatus = RosKmdDdi::DdiQueryChildStatus; DriverInitializationData.DxgkDdiQueryDeviceDescriptor = RosKmdDdi::DdiQueryDeviceDescriptor; DriverInitializationData.DxgkDdiSetPowerState = RosKmdDdi::DdiSetPowerState; DriverInitializationData.DxgkDdiNotifyAcpiEvent = RosKmdDdi::DdiNotifyAcpiEvent; DriverInitializationData.DxgkDdiResetDevice = RosKmdDdi::DdiResetDevice; DriverInitializationData.DxgkDdiUnload = RosKmdGlobal::DdiUnload; DriverInitializationData.DxgkDdiQueryInterface = RosKmdDdi::DdiQueryInterface; DriverInitializationData.DxgkDdiControlEtwLogging = RosKmdGlobal::DdiControlEtwLogging; DriverInitializationData.DxgkDdiQueryAdapterInfo = RosKmdDdi::DdiQueryAdapterInfo; DriverInitializationData.DxgkDdiCreateDevice = RosKmDevice::DdiCreateDevice; DriverInitializationData.DxgkDdiCreateAllocation = RosKmdDdi::DdiCreateAllocation; DriverInitializationData.DxgkDdiDestroyAllocation = RosKmdDdi::DdiDestroyAllocation; DriverInitializationData.DxgkDdiDescribeAllocation = RosKmdDdi::DdiDescribeAllocation; DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = RosKmdDdi::DdiGetStandardAllocationDriverData; // DriverInitializationData.DxgkDdiAcquireSwizzlingRange = RosKmdAcquireSwizzlingRange; // DriverInitializationData.DxgkDdiReleaseSwizzlingRange = RosKmdReleaseSwizzlingRange; DriverInitializationData.DxgkDdiOpenAllocation = RosKmdDdi::DdiOpenAllocation; DriverInitializationData.DxgkDdiCloseAllocation = RosKmDevice::DdiCloseAllocation; DriverInitializationData.DxgkDdiPatch = RosKmdDdi::DdiPatch; DriverInitializationData.DxgkDdiSubmitCommand = RosKmdDdi::DdiSubmitCommand; DriverInitializationData.DxgkDdiBuildPagingBuffer = RosKmdDdi::DdiBuildPagingBuffer; DriverInitializationData.DxgkDdiPreemptCommand = RosKmdDdi::DdiPreemptCommand; DriverInitializationData.DxgkDdiDestroyDevice = RosKmDevice::DdiDestroyDevice; DriverInitializationData.DxgkDdiRender = RosKmContext::DdiRender; DriverInitializationData.DxgkDdiPresent = RosKmdDdi::DdiPresent; DriverInitializationData.DxgkDdiResetFromTimeout = RosKmdDdi::DdiResetFromTimeout; DriverInitializationData.DxgkDdiRestartFromTimeout = RosKmdDdi::DdiRestartFromTimeout; DriverInitializationData.DxgkDdiEscape = RosKmdDdi::DdiEscape; DriverInitializationData.DxgkDdiCollectDbgInfo = RosKmdDdi::DdiCollectDbgInfo; DriverInitializationData.DxgkDdiQueryCurrentFence = RosKmdDdi::DdiQueryCurrentFence; DriverInitializationData.DxgkDdiControlInterrupt = RosKmdDdi::DdiControlInterrupt; DriverInitializationData.DxgkDdiCreateContext = RosKmContext::DdiCreateContext; DriverInitializationData.DxgkDdiDestroyContext = RosKmContext::DdiDestroyContext; DriverInitializationData.DxgkDdiRenderKm = RosKmdDdi::DdiRenderKm; // // Fill in DDI routines for resetting individual engine // DriverInitializationData.DxgkDdiQueryDependentEngineGroup = RosKmdDdi::DdiQueryDependentEngineGroup; DriverInitializationData.DxgkDdiQueryEngineStatus = RosKmdDdi::DdiQueryEngineStatus; DriverInitializationData.DxgkDdiResetEngine = RosKmdDdi::DdiResetEngine; // // Fill in DDI for canceling DMA buffers // DriverInitializationData.DxgkDdiCancelCommand = RosKmdDdi::DdiCancelCommand; // // Fill in DDI for component power management // DriverInitializationData.DxgkDdiSetPowerComponentFState = RosKmdDdi::DdiSetPowerComponentFState; DriverInitializationData.DxgkDdiPowerRuntimeControlRequest = RosKmdDdi::DdiPowerRuntimeControlRequest; DriverInitializationData.DxgkDdiGetNodeMetadata = RosKmdDdi::DdiGetNodeMetadata; DriverInitializationData.DxgkDdiSubmitCommandVirtual = RosKmdDdi::DdiSubmitCommandVirtual; DriverInitializationData.DxgkDdiCreateProcess = RosKmdDdi::DdiCreateProcess; DriverInitializationData.DxgkDdiDestroyProcess = RosKmdDdi::DdiDestroyProcess; DriverInitializationData.DxgkDdiCalibrateGpuClock = RosKmdDdi::DdiCalibrateGpuClock; DriverInitializationData.DxgkDdiSetStablePowerState = RosKmdDdi::DdiSetStablePowerState; // // Register display subsystem DDIS. // Refer to adapterdisplay.cxx:ADAPTER_DISPLAY::CreateDisplayCore() for // required DDIs. // if (!IsRenderOnly()) { DriverInitializationData.DxgkDdiSetPalette = RosKmdDisplayDdi::DdiSetPalette; DriverInitializationData.DxgkDdiSetPointerPosition = RosKmdDisplayDdi::DdiSetPointerPosition; DriverInitializationData.DxgkDdiSetPointerShape = RosKmdDisplayDdi::DdiSetPointerShape; DriverInitializationData.DxgkDdiIsSupportedVidPn = RosKmdDisplayDdi::DdiIsSupportedVidPn; DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = RosKmdDisplayDdi::DdiRecommendFunctionalVidPn; DriverInitializationData.DxgkDdiEnumVidPnCofuncModality = RosKmdDisplayDdi::DdiEnumVidPnCofuncModality; DriverInitializationData.DxgkDdiSetVidPnSourceAddress = RosKmdDisplayDdi::DdiSetVidPnSourceAddress; DriverInitializationData.DxgkDdiSetVidPnSourceVisibility = RosKmdDisplayDdi::DdiSetVidPnSourceVisibility; DriverInitializationData.DxgkDdiCommitVidPn = RosKmdDisplayDdi::DdiCommitVidPn; DriverInitializationData.DxgkDdiUpdateActiveVidPnPresentPath = RosKmdDisplayDdi::DdiUpdateActiveVidPnPresentPath; DriverInitializationData.DxgkDdiRecommendMonitorModes = RosKmdDisplayDdi::DdiRecommendMonitorModes; DriverInitializationData.DxgkDdiGetScanLine = RosKmdDisplayDdi::DdiGetScanLine; DriverInitializationData.DxgkDdiQueryVidPnHWCapability = RosKmdDisplayDdi::DdiQueryVidPnHWCapability; DriverInitializationData.DxgkDdiStopDeviceAndReleasePostDisplayOwnership = RosKmdDisplayDdi::DdiStopDeviceAndReleasePostDisplayOwnership; } Status = DxgkInitialize(pDriverObject, pRegistryPath, &DriverInitializationData); if (!NT_SUCCESS(Status)) { return Status; } return Status; }
NTSTATUS RosKmdGlobal::DriverEntry(__in IN DRIVER_OBJECT* pDriverObject, __in IN UNICODE_STRING* pRegistryPath) { NTSTATUS Status; DRIVER_INITIALIZATION_DATA DriverInitializationData; // Only break into the debugger on driver entry if debugger is present if (KdRefreshDebuggerNotPresent() == FALSE) { DbgBreakPoint(); } DbgPrintEx(DPFLTR_IHVVIDEO_ID, DPFLTR_TRACE_LEVEL, "DriverEntry\n"); if (s_bDoNotInstall) { return STATUS_NO_MEMORY; } // // Allocate physically contiguous memory to represent cpu visible video memory // PHYSICAL_ADDRESS lowestAcceptableAddress; lowestAcceptableAddress.QuadPart = 0; PHYSICAL_ADDRESS highestAcceptableAddress; highestAcceptableAddress.QuadPart = -1; PHYSICAL_ADDRESS boundaryAddressMultiple; boundaryAddressMultiple.QuadPart = 0; s_videoMemorySize = kMaxVideoMemorySize; while (s_pVideoMemory == NULL) { // // The allocated contiguous memory is mapped as cached // // TODO[indyz]: Evaluate if flushing CPU cache for GPU access is the best option // // Use this option because GenerateRenderControlList has data alignment issue // s_pVideoMemory = MmAllocateContiguousMemorySpecifyCache( s_videoMemorySize, lowestAcceptableAddress, highestAcceptableAddress, boundaryAddressMultiple, MmCached); if (s_pVideoMemory != NULL) { break; } s_videoMemorySize >>= 1; } s_videoMemoryPhysicalAddress = MmGetPhysicalAddress(s_pVideoMemory); // // Fill in the DriverInitializationData structure and call DlInitialize() // memset(&DriverInitializationData, 0, sizeof(DriverInitializationData)); DriverInitializationData.Version = DXGKDDI_INTERFACE_VERSION; DriverInitializationData.DxgkDdiAddDevice = RosKmdDdi::DdiAddAdapter; DriverInitializationData.DxgkDdiStartDevice = RosKmdDdi::DdiStartAdapter; DriverInitializationData.DxgkDdiStopDevice = RosKmdDdi::DdiStopAdapter; DriverInitializationData.DxgkDdiRemoveDevice = RosKmdDdi::DdiRemoveAdapter; DriverInitializationData.DxgkDdiDispatchIoRequest = RosKmdDdi::DdiDispatchIoRequest; DriverInitializationData.DxgkDdiInterruptRoutine = RosKmdDdi::DdiInterruptRoutine; DriverInitializationData.DxgkDdiDpcRoutine = RosKmdDdi::DdiDpcRoutine; DriverInitializationData.DxgkDdiQueryChildRelations = RosKmdDdi::DdiQueryChildRelations; DriverInitializationData.DxgkDdiQueryChildStatus = RosKmdDdi::DdiQueryChildStatus; DriverInitializationData.DxgkDdiQueryDeviceDescriptor = RosKmdDdi::DdiQueryDeviceDescriptor; DriverInitializationData.DxgkDdiSetPowerState = RosKmdDdi::DdiSetPowerState; DriverInitializationData.DxgkDdiNotifyAcpiEvent = RosKmdDdi::DdiNotifyAcpiEvent; DriverInitializationData.DxgkDdiResetDevice = RosKmdDdi::DdiResetDevice; DriverInitializationData.DxgkDdiUnload = RosKmdGlobal::DdiUnload; DriverInitializationData.DxgkDdiQueryInterface = RosKmdDdi::DdiQueryInterface; DriverInitializationData.DxgkDdiControlEtwLogging = RosKmdGlobal::DdiControlEtwLogging; DriverInitializationData.DxgkDdiQueryAdapterInfo = RosKmdDdi::DdiQueryAdapterInfo; DriverInitializationData.DxgkDdiCreateDevice = RosKmDevice::DdiCreateDevice; DriverInitializationData.DxgkDdiCreateAllocation = RosKmdDdi::DdiCreateAllocation; DriverInitializationData.DxgkDdiDestroyAllocation = RosKmdDdi::DdiDestroyAllocation; DriverInitializationData.DxgkDdiDescribeAllocation = RosKmdDdi::DdiDescribeAllocation; DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = RosKmdDdi::DdiGetStandardAllocationDriverData; // DriverInitializationData.DxgkDdiAcquireSwizzlingRange = RosKmdAcquireSwizzlingRange; // DriverInitializationData.DxgkDdiReleaseSwizzlingRange = RosKmdReleaseSwizzlingRange; DriverInitializationData.DxgkDdiOpenAllocation = RosKmDevice::DdiOpenAllocation; DriverInitializationData.DxgkDdiCloseAllocation = RosKmDevice::DdiCloseAllocation; DriverInitializationData.DxgkDdiPatch = RosKmdDdi::DdiPatch; DriverInitializationData.DxgkDdiSubmitCommand = RosKmdDdi::DdiSubmitCommand; DriverInitializationData.DxgkDdiBuildPagingBuffer = RosKmdDdi::DdiBuildPagingBuffer; DriverInitializationData.DxgkDdiPreemptCommand = RosKmdDdi::DdiPreemptCommand; DriverInitializationData.DxgkDdiDestroyDevice = RosKmDevice::DdiDestroyDevice; DriverInitializationData.DxgkDdiRender = RosKmContext::DdiRender; DriverInitializationData.DxgkDdiPresent = RosKmdDdi::DdiPresent; DriverInitializationData.DxgkDdiResetFromTimeout = RosKmdDdi::DdiResetFromTimeout; DriverInitializationData.DxgkDdiRestartFromTimeout = RosKmdDdi::DdiRestartFromTimeout; DriverInitializationData.DxgkDdiEscape = RosKmdDdi::DdiEscape; DriverInitializationData.DxgkDdiCollectDbgInfo = RosKmdDdi::DdiCollectDbgInfo; DriverInitializationData.DxgkDdiQueryCurrentFence = RosKmdDdi::DdiQueryCurrentFence; DriverInitializationData.DxgkDdiControlInterrupt = RosKmdDdi::DdiControlInterrupt; DriverInitializationData.DxgkDdiCreateContext = RosKmContext::DdiCreateContext; DriverInitializationData.DxgkDdiDestroyContext = RosKmContext::DdiDestroyContext; DriverInitializationData.DxgkDdiRenderKm = RosKmdDdi::DdiRenderKm; // // Fill in DDI routines for resetting individual engine // DriverInitializationData.DxgkDdiQueryDependentEngineGroup = RosKmdDdi::DdiQueryDependentEngineGroup; DriverInitializationData.DxgkDdiQueryEngineStatus = RosKmdDdi::DdiQueryEngineStatus; DriverInitializationData.DxgkDdiResetEngine = RosKmdDdi::DdiResetEngine; // // Fill in DDI for canceling DMA buffers // DriverInitializationData.DxgkDdiCancelCommand = RosKmdDdi::DdiCancelCommand; // // Fill in DDI for component power management // DriverInitializationData.DxgkDdiSetPowerComponentFState = RosKmdDdi::DdiSetPowerComponentFState; DriverInitializationData.DxgkDdiPowerRuntimeControlRequest = RosKmdDdi::DdiPowerRuntimeControlRequest; DriverInitializationData.DxgkDdiGetNodeMetadata = RosKmdDdi::DdiGetNodeMetadata; DriverInitializationData.DxgkDdiSubmitCommandVirtual = RosKmdDdi::DdiSubmitCommandVirtual; DriverInitializationData.DxgkDdiCreateProcess = RosKmdDdi::DdiCreateProcess; DriverInitializationData.DxgkDdiDestroyProcess = RosKmdDdi::DdiDestroyProcess; DriverInitializationData.DxgkDdiCalibrateGpuClock = RosKmdDdi::DdiCalibrateGpuClock; DriverInitializationData.DxgkDdiSetStablePowerState = RosKmdDdi::DdiSetStablePowerState; Status = DxgkInitialize(pDriverObject, pRegistryPath, &DriverInitializationData); if (!NT_SUCCESS(Status)) { return Status; } return Status; }