/* * Process Hacker Extra Plugins - * Nvidia GPU Plugin * * Copyright (C) 2015 dmex * * This file is part of Process Hacker. * * Process Hacker is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Process Hacker is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Process Hacker. If not, see . */ #define INITGUID #include "main.h" #include "nvapi\nvapi.h" #include "nvidia.h" #pragma comment(lib, "Setupapi.lib") #include #include #include static PVOID NvApiLibrary = NULL; static PPH_LIST NvGpuPhysicalHandleList = NULL; static PPH_LIST NvGpuDisplayHandleList = NULL; static NvU32 GpuArchType = 0; ULONG GpuMemoryLimit = 0; FLOAT GpuCurrentGpuUsage = 0.0f; FLOAT GpuCurrentCoreUsage = 0.0f; FLOAT GpuCurrentBusUsage = 0.0f; ULONG GpuCurrentMemUsage = 0; ULONG GpuCurrentMemSharedUsage = 0; ULONG GpuCurrentCoreTemp = 0; ULONG GpuCurrentBoardTemp = 0; ULONG GpuCurrentCoreClock = 0; ULONG GpuCurrentMemoryClock = 0; ULONG GpuCurrentShaderClock = 0; ULONG GpuCurrentVoltage = 0; //NVAPI_GPU_PERF_DECREASE GpuPerfDecreaseReason = NV_GPU_PERF_DECREASE_NONE; VOID NvGpuEnumPhysicalHandles(VOID) { NvU32 gpuCount = 0; NvPhysicalGpuHandle gpuHandles[NVAPI_MAX_PHYSICAL_GPUS]; memset(gpuHandles, 0, sizeof(gpuHandles)); if (NvAPI_EnumPhysicalGPUs && NvAPI_EnumPhysicalGPUs(gpuHandles, &gpuCount) == NVAPI_OK) { PhAddItemsList(NvGpuPhysicalHandleList, gpuHandles, gpuCount); } } VOID NvGpuEnumDisplayHandles(VOID) { if (!NvAPI_EnumNvidiaDisplayHandle) return; for (NvU32 i = 0; i < NVAPI_MAX_DISPLAYS; i++) { NvDisplayHandle displayHandle; if (NvAPI_EnumNvidiaDisplayHandle(i, &displayHandle) == NVAPI_END_ENUMERATION) { break; } PhAddItemList(NvGpuDisplayHandleList, displayHandle); } } BOOLEAN InitializeNvApi(VOID) { NvGpuPhysicalHandleList = PhCreateList(1); NvGpuDisplayHandleList = PhCreateList(1); #ifdef _M_IX86 if (!(NvApiLibrary = LoadLibrary(L"nvapi.dll"))) return FALSE; #else if (!(NvApiLibrary = LoadLibrary(L"nvapi64.dll"))) return FALSE; #endif // Retrieve the NvAPI_QueryInterface function address if (!(NvAPI_QueryInterface = PhGetProcedureAddress(NvApiLibrary, "nvapi_QueryInterface", 0))) return FALSE; // Initialization functions if (!(NvAPI_Initialize = NvAPI_QueryInterface(0x150E828UL))) return FALSE; if (!(NvAPI_Unload = NvAPI_QueryInterface(0xD22BDD7EUL))) return FALSE; // Error functions if (!(NvAPI_GetErrorMessage = NvAPI_QueryInterface(0x6C2D048CUL))) return FALSE; // Handle functions if (!(NvAPI_EnumPhysicalGPUs = NvAPI_QueryInterface(0xE5AC921FUL))) return FALSE; if (!(NvAPI_EnumNvidiaDisplayHandle = NvAPI_QueryInterface(0x9ABDD40DUL))) return FALSE; // Information functions NvAPI_SYS_GetDriverAndBranchVersion = NvAPI_QueryInterface(0x2926AAADUL); NvAPI_GPU_GetFullName = NvAPI_QueryInterface(0xCEEE8E9FUL); // Query functions NvAPI_GPU_GetMemoryInfo = NvAPI_QueryInterface(0x774AA982UL); NvAPI_GPU_GetThermalSettings = NvAPI_QueryInterface(0xE3640A56UL); NvAPI_GPU_GetCoolerSettings = NvAPI_QueryInterface(0xDA141340UL); NvAPI_GPU_GetPerfDecreaseInfo = NvAPI_QueryInterface(0x7F7F4600UL); NvAPI_GPU_GetTachReading = NvAPI_QueryInterface(0x5F608315UL); NvAPI_GPU_GetAllClockFrequencies = NvAPI_QueryInterface(0xDCB616C3UL); // Undocumented Query functions NvAPI_GPU_GetUsages = NvAPI_QueryInterface(0x189A1FDFUL); NvAPI_GPU_GetAllClocks = NvAPI_QueryInterface(0x1BD69F49UL); NvAPI_GPU_GetVoltageDomainsStatus = NvAPI_QueryInterface(0xC16C7E2CUL); //NvAPI_GPU_GetPerfClocks = NvAPI_QueryInterface(0x1EA54A3B); //NvAPI_GPU_GetVoltages = NvAPI_QueryInterface(0x7D656244); //NvAPI_GPU_QueryActiveApps = NvAPI_QueryInterface(0x65B1C5F5); //NvAPI_GPU_GetShaderPipeCount = NvAPI_QueryInterface(0x63E2F56F); //NvAPI_GPU_GetShaderSubPipeCount = NvAPI_QueryInterface(0x0BE17923); NvAPI_GPU_GetRamBusWidth = NvAPI_QueryInterface(0x7975C581); // ADD ME NvAPI_GPU_GetRamBankCount = NvAPI_QueryInterface(0x17073A3CUL); NvAPI_GPU_GetRamType = NvAPI_QueryInterface(0x57F7CAACUL); NvAPI_GPU_GetRamMaker = NvAPI_QueryInterface(0x42AEA16AUL); NvAPI_GPU_GetFoundry = NvAPI_QueryInterface(0x5D857A00UL); //NvAPI_GetDisplayDriverMemoryInfo = NvAPI_QueryInterface(0x774AA982); //NvAPI_GetPhysicalGPUsFromDisplay = NvAPI_QueryInterface(0x34EF9506); NvAPI_GetDisplayDriverVersion = NvAPI_QueryInterface(0xF951A4D1UL); NvAPI_GetDisplayDriverRegistryPath = NvAPI_QueryInterface(0x0E24CEEEUL); //NvAPI_RestartDisplayDriver = NvAPI_QueryInterface(0xB4B26B65UL); //NvAPI_GPU_GetBoardInfo = NvAPI_QueryInterface(0x22D54523); //NvAPI_GPU_GetBusType = NvAPI_QueryInterface(0x1BB18724); //NvAPI_GPU_GetIRQ = NvAPI_QueryInterface(0xE4715417); NvAPI_GPU_GetVbiosVersionString = NvAPI_QueryInterface(0xA561FD7DUL); NvAPI_GPU_GetShortName = NvAPI_QueryInterface(0xD988F0F3UL); NvAPI_GPU_GetArchInfo = NvAPI_QueryInterface(0xD8265D24UL); NvAPI_GPU_GetPCIIdentifiers = NvAPI_QueryInterface(0x2DDFB66EUL); NvAPI_GPU_GetPartitionCount = NvAPI_QueryInterface(0x86F05D7AUL); NvAPI_GPU_GetGpuCoreCount = NvAPI_QueryInterface(0xC7026A87UL); NvAPI_GPU_GetPCIEInfo = NvAPI_QueryInterface(0xE3795199UL); NvAPI_GPU_GetFBWidthAndLocation = NvAPI_QueryInterface(0x11104158UL); NvAPI_GPU_ClientPowerTopologyGetStatus = NvAPI_QueryInterface(0x0EDCF624EUL); typedef NvAPI_Status(__cdecl *_NvAPI_GetDisplayDriverBuildTitle)(_In_ NvDisplayHandle hNvDisplay, NvAPI_ShortString pDriverBuildTitle); _NvAPI_GetDisplayDriverBuildTitle NvAPI_GetDisplayDriverBuildTitle; NvAPI_GetDisplayDriverBuildTitle = NvAPI_QueryInterface(0x7562E947); typedef NvAPI_Status(__cdecl *_NvAPI_GetDisplayDriverCompileType)(_In_ NvDisplayHandle hNvDisplay, NvU32* pDriverCompileType); _NvAPI_GetDisplayDriverCompileType NvAPI_GetDisplayDriverCompileType; NvAPI_GetDisplayDriverCompileType = NvAPI_QueryInterface(0x988AEA78); typedef NvAPI_Status(__cdecl *_NvAPI_GetDisplayDriverSecurityLevel)(_In_ NvDisplayHandle hNvDisplay, NvU32* pDriverSecurityLevel); _NvAPI_GetDisplayDriverSecurityLevel NvAPI_GetDisplayDriverSecurityLevel; NvAPI_GetDisplayDriverSecurityLevel = NvAPI_QueryInterface(0x9D772BBA); typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetVPECount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pVPECount); _NvAPI_GPU_GetVPECount NvAPI_GPU_GetVPECount; NvAPI_GPU_GetVPECount = NvAPI_QueryInterface(0xD8CBF37B); //typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetExtendedMinorRevision)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBankCount); //_NvAPI_GPU_GetExtendedMinorRevision NvAPI_GPU_GetExtendedMinorRevision; //NvAPI_GPU_GetExtendedMinorRevision = NvAPI_QueryInterface(0x025F17421); //typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetSerialNumber)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PBYTE pRamBankCount); //_NvAPI_GPU_GetSerialNumber NvAPI_GPU_GetSerialNumber; //NvAPI_GPU_GetSerialNumber = NvAPI_QueryInterface(0x14B83A5F); typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetTargetID)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PBYTE pRamBankCount); _NvAPI_GPU_GetTargetID NvAPI_GPU_GetTargetID; NvAPI_GPU_GetTargetID = NvAPI_QueryInterface(0x35B5FD2F); if (NvAPI_Initialize() == NVAPI_OK) { NvGpuEnumPhysicalHandles(); NvGpuEnumDisplayHandles(); BYTE buffer[260] = { 0 }; NvAPI_Status status = NvAPI_GPU_GetTargetID( NvGpuPhysicalHandleList->Items[0], buffer ); return TRUE; } return FALSE; } BOOLEAN DestroyNvApi(VOID) { NvApiInitialized = FALSE; if (NvGpuDisplayHandleList) { //PhClearList(NvGpuDisplayHandleList); PhDereferenceObject(NvGpuDisplayHandleList); } if (NvGpuPhysicalHandleList) { //PhClearList(NvGpuPhysicalHandleList); PhDereferenceObject(NvGpuPhysicalHandleList); } if (NvAPI_Unload) NvAPI_Unload(); if (NvApiLibrary) FreeLibrary(NvApiLibrary); return TRUE; } PPH_STRING NvGpuQueryDriverVersion(VOID) { if (NvAPI_SYS_GetDriverAndBranchVersion) { NvU32 driverVersion = 0; NvAPI_ShortString driverAndBranchString = ""; if (NvAPI_SYS_GetDriverAndBranchVersion(&driverVersion, driverAndBranchString) == NVAPI_OK) { return PhFormatString( L"%lu.%lu [%hs]", driverVersion / 100, driverVersion % 100, driverAndBranchString ); } } if (NvAPI_GetDisplayDriverVersion) { NV_DISPLAY_DRIVER_VERSION nvDisplayDriverVersion = { NV_DISPLAY_DRIVER_VERSION_VER }; if (NvAPI_GetDisplayDriverVersion(NvGpuDisplayHandleList->Items[0], &nvDisplayDriverVersion) == NVAPI_OK) { return PhFormatString( L"%lu.%lu [%hs]", nvDisplayDriverVersion.drvVersion / 100, nvDisplayDriverVersion.drvVersion % 100, nvDisplayDriverVersion.szBuildBranchString ); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryVbiosVersionString(VOID) { if (NvAPI_GPU_GetVbiosVersionString) { NvAPI_ShortString biosRevision = ""; if (NvAPI_GPU_GetVbiosVersionString(NvGpuPhysicalHandleList->Items[0], biosRevision) == NVAPI_OK) { return PhConvertMultiByteToUtf16(biosRevision); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryName(VOID) { if (NvAPI_GPU_GetFullName) { NvAPI_ShortString nvNameAnsiString = ""; if (NvAPI_GPU_GetFullName(NvGpuPhysicalHandleList->Items[0], nvNameAnsiString) == NVAPI_OK) { return PhConvertMultiByteToUtf16(nvNameAnsiString); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryShortName(VOID) { if (NvAPI_GPU_GetShortName) { NvAPI_ShortString nvShortNameAnsiString = ""; if (NvAPI_GPU_GetShortName(NvGpuPhysicalHandleList->Items[0], nvShortNameAnsiString) == NVAPI_OK) { return PhConvertMultiByteToUtf16(nvShortNameAnsiString); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryRevision(VOID) { if (NvAPI_GPU_GetArchInfo) { NV_ARCH_INFO nvArchInfo = { NV_ARCH_INFO_VER }; if (NvAPI_GPU_GetArchInfo(NvGpuPhysicalHandleList->Items[0], &nvArchInfo) == NVAPI_OK) { GpuArchType = nvArchInfo.unknown[0]; return PhFormatString(L"%02X", nvArchInfo.unknown[2]); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryRamType(VOID) { PPH_STRING ramTypeString = NULL; PPH_STRING ramMakerString = NULL; NV_RAM_TYPE nvRamType = NV_RAM_TYPE_NONE; NV_RAM_MAKER nvRamMaker = NV_RAM_MAKER_NONE; if (NvAPI_GPU_GetRamType) { NvAPI_GPU_GetRamType(NvGpuPhysicalHandleList->Items[0], &nvRamType); } if (NvAPI_GPU_GetRamMaker) { NvAPI_GPU_GetRamMaker(NvGpuPhysicalHandleList->Items[0], &nvRamMaker); } switch (nvRamType) { case NV_RAM_TYPE_SDRAM: ramTypeString = PhaCreateString(L"SDRAM"); break; case NV_RAM_TYPE_DDR1: ramTypeString = PhaCreateString(L"DDR1"); break; case NV_RAM_TYPE_DDR2: ramTypeString = PhaCreateString(L"DDR2"); break; case NV_RAM_TYPE_GDDR2: ramTypeString = PhaCreateString(L"GDDR2"); break; case NV_RAM_TYPE_GDDR3: ramTypeString = PhaCreateString(L"GDDR3"); break; case NV_RAM_TYPE_GDDR4: ramTypeString = PhaCreateString(L"GDDR4"); break; case NV_RAM_TYPE_DDR3: ramTypeString = PhaCreateString(L"DDR3"); break; case NV_RAM_TYPE_GDDR5: ramTypeString = PhaCreateString(L"GDDR5"); break; case NV_RAM_TYPE_LPDDR2: ramTypeString = PhaCreateString(L"LPDDR2"); break; default: ramTypeString = PhaFormatString(L"Unknown: %lu", nvRamType); break; } switch (nvRamMaker) { case NV_RAM_MAKER_SAMSUNG: ramMakerString = PhaCreateString(L"Samsung"); break; case NV_RAM_MAKER_QIMONDA: ramMakerString = PhaCreateString(L"Qimonda"); break; case NV_RAM_MAKER_ELPIDA: ramMakerString = PhaCreateString(L"Elpida"); break; case NV_RAM_MAKER_ETRON: ramMakerString = PhaCreateString(L"Etron"); break; case NV_RAM_MAKER_NANYA: ramMakerString = PhaCreateString(L"Nanya"); break; case NV_RAM_MAKER_HYNIX: ramMakerString = PhaCreateString(L"Hynix"); break; case NV_RAM_MAKER_MOSEL: ramMakerString = PhaCreateString(L"Mosel"); break; case NV_RAM_MAKER_WINBOND: ramMakerString = PhaCreateString(L"Winbond"); break; case NV_RAM_MAKER_ELITE: ramMakerString = PhaCreateString(L"Elite"); break; case NV_RAM_MAKER_MICRON: ramMakerString = PhaCreateString(L"Micron"); break; default: ramMakerString = PhaFormatString(L"Unknown: %lu", nvRamMaker); break; } return PhFormatString(L"%s (%s)", ramTypeString->Buffer, ramMakerString->Buffer); } PPH_STRING NvGpuQueryFoundry(VOID) { if (NvAPI_GPU_GetFoundry) { NV_FOUNDRY nvFoundryType = NV_FOUNDRY_NONE; if (NvAPI_GPU_GetFoundry(NvGpuPhysicalHandleList->Items[0], &nvFoundryType) == NVAPI_OK) { switch (nvFoundryType) { case NV_FOUNDRY_TSMC: return PhCreateString(L"Taiwan Semiconductor Manufacturing Company (TSMC)"); case NV_FOUNDRY_UMC: return PhCreateString(L"United Microelectronics Corporation (UMC)"); case NV_FOUNDRY_IBM: return PhCreateString(L"IBM Microelectronics"); case NV_FOUNDRY_SMIC: return PhCreateString(L"Semiconductor Manufacturing International Corporation (SMIC)"); case NV_FOUNDRY_CSM: return PhCreateString(L"Chartered Semiconductor Manufacturing (CSM)"); case NV_FOUNDRY_TOSHIBA: return PhCreateString(L"Toshiba Corporation"); default: return PhFormatString(L"Unknown: %lu", nvFoundryType); } } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryDeviceId(VOID) { if (NvAPI_GPU_GetPCIIdentifiers) { NvU32 pDeviceId = 0; NvU32 pSubSystemId = 0; NvU32 pRevisionId = 0; NvU32 pExtDeviceId = 0; if (NvAPI_GPU_GetPCIIdentifiers(NvGpuPhysicalHandleList->Items[0], &pDeviceId, &pSubSystemId, &pRevisionId, &pExtDeviceId) == NVAPI_OK) { return PhFormatString(L"%04X - %04X", pDeviceId & 65535, pDeviceId >> 16); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryRopsCount(VOID) { if (NvAPI_GPU_GetPartitionCount) { NvU32 pCount = 0; if (NvAPI_GPU_GetPartitionCount(NvGpuPhysicalHandleList->Items[0], &pCount) == NVAPI_OK) { if (GpuArchType >= 0x120) { return PhFormatString(L"%lu", pCount * 16); } else if (GpuArchType >= 0x0c0) { return PhFormatString(L"%lu", pCount * 8); } else { return PhFormatString(L"%lu", pCount * 4); } } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryShaderCount(VOID) { if (NvAPI_GPU_GetGpuCoreCount) { NvU32 pCount = 0; if (NvAPI_GPU_GetGpuCoreCount(NvGpuPhysicalHandleList->Items[0], &pCount) == NVAPI_OK) { return PhFormatString(L"%lu Unified", pCount); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryPciInfo(VOID) { if (NvAPI_GPU_GetPCIEInfo) { NV_PCIE_INFO pciInfo = { NV_PCIE_INFO_VER }; if (NvAPI_GPU_GetPCIEInfo(NvGpuPhysicalHandleList->Items[0], &pciInfo) == NVAPI_OK) { return PhFormatString(L"%lu @ %lu %lu", pciInfo.info[1].unknown1, pciInfo.info[0].unknown5, pciInfo.info[0].unknown6 ); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryBusWidth(VOID) { if (NvAPI_GPU_GetFBWidthAndLocation) { NvU32 pWidth = 0; NvU32 pLocation = 0; if (NvAPI_GPU_GetFBWidthAndLocation(NvGpuPhysicalHandleList->Items[0], &pWidth, &pLocation) == NVAPI_OK) { return PhFormatString(L"%lu Bit", pWidth); } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryPcbValue(VOID) { if (NvAPI_GPU_ClientPowerTopologyGetStatus) { NV_POWER_TOPOLOGY_STATUS nvPowerTopologyStatus = { NV_POWER_TOPOLOGY_STATUS_VER }; if (NvAPI_GPU_ClientPowerTopologyGetStatus(NvGpuPhysicalHandleList->Items[0], &nvPowerTopologyStatus) == NVAPI_OK) { for (NvU32 i = 0; i < nvPowerTopologyStatus.count; i++) { NV_POWER_TOPOLOGY_2 powerTopology = nvPowerTopologyStatus.unknown[i]; if (powerTopology.flags == NV_POWER_TOPOLOGY_FLAG_UNKNOWN2) { return PhFormatString(L"PMU: %.2f%%", (FLOAT)powerTopology.unknown.unknown2 / 1000); } } } } return PhCreateString(L"N/A"); } PPH_STRING NvGpuQueryDriverSettings(VOID) { if (NvAPI_GetDisplayDriverRegistryPath) { NvAPI_LongString nvKeyPathAnsiString = ""; if (NvAPI_GetDisplayDriverRegistryPath(NvGpuDisplayHandleList->Items[0], nvKeyPathAnsiString) == NVAPI_OK) { HANDLE keyHandle; PPH_STRING keyPath; keyPath = PhConvertMultiByteToUtf16(nvKeyPathAnsiString); if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyPath->sr, 0 ))) { PPH_STRING driverDateString = NULL;// PhQueryRegistryString(keyHandle, L"DriverDate"); PPH_STRING driverVersionString = PhQueryRegistryString(keyHandle, L"DriverVersion"); UNICODE_STRING valueName; PKEY_VALUE_PARTIAL_INFORMATION buffer = NULL; ULONG bufferSize; RtlInitUnicodeString(&valueName, L"DriverDateData"); if (NtQueryValueKey( keyHandle, &valueName, KeyValuePartialInformation, NULL, 0, &bufferSize ) == STATUS_BUFFER_TOO_SMALL) { buffer = PhAllocate(bufferSize); if (NT_SUCCESS(NtQueryValueKey( keyHandle, &valueName, KeyValuePartialInformation, buffer, bufferSize, &bufferSize ))) { if (buffer->Type == REG_BINARY && buffer->DataLength == sizeof(FILETIME)) { SYSTEMTIME systemTime; SYSTEMTIME localTime; FileTimeToSystemTime((CONST FILETIME*)buffer->Data, &systemTime); SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime); driverDateString = PhFormatDate(&localTime, NULL); } } PhFree(buffer); } NtClose(keyHandle); PhDereferenceObject(keyPath); PhAutoDereferenceObject(driverVersionString); if (driverDateString) { PhAutoDereferenceObject(driverDateString); return PhFormatString(L"%s [%s]", driverVersionString->Buffer, driverDateString->Buffer); } else { return PhFormatString(L"%s", driverVersionString->Buffer); } } PhDereferenceObject(keyPath); } } return PhCreateString(L"N/A"); } BOOLEAN NvGpuDriverIsWHQL(VOID) { BOOLEAN nvGpuDriverIsWHQL = FALSE; NvAPI_LongString nvNameAnsiString = ""; HANDLE keyHandle; //HANDLE keySettingsHandle; PPH_STRING keyPath; PPH_STRING matchingDeviceIdString; //PPH_STRING keySettingsPath; PPH_STRING keyServicePath; WCHAR displayInstancePath[MAX_PATH] = L""; HDEVINFO deviceInfoHandle = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) }; SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) }; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = NULL; ULONG deviceInfoLength = 0; __try { if (!NvAPI_GetDisplayDriverRegistryPath) __leave; if (NvAPI_GetDisplayDriverRegistryPath(NvGpuDisplayHandleList->Items[0], nvNameAnsiString) != NVAPI_OK) __leave; keyPath = PhConvertMultiByteToUtf16(nvNameAnsiString); if (!NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyPath->sr, 0 ))) { __leave; } matchingDeviceIdString = PhQueryRegistryString(keyHandle, L"MatchingDeviceId"); //keySettingsPath = PhConcatStrings2(keyPath->Buffer, L"\\VolatileSettings"); //if (NT_SUCCESS(PhOpenKey( // &keySettingsHandle, // KEY_READ, // PH_KEY_LOCAL_MACHINE, // &keySettingsPath->sr, // 0 // ))) //{ // GUID settingsKey = GUID_DEVINTERFACE_DISPLAY_ADAPTER; // PPH_STRING guidString = PhFormatGuid(&settingsKey); // // ULONG dwType = REG_BINARY; // LONG length = MAX_PATH; // // if (RegQueryValueEx( // keySettingsHandle, // guidString->Buffer, // 0, // &dwType, // (PBYTE)displayInstancePath, // &length // ) != ERROR_SUCCESS) // { // //__leave; // } // // NtClose(keySettingsHandle); // PhDereferenceObject(guidString); //} if ((deviceInfoHandle = SetupDiGetClassDevs( &GUID_DEVINTERFACE_DISPLAY_ADAPTER, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE )) == INVALID_HANDLE_VALUE) { __leave; } for (ULONG i = 0; i < 1000; i++) { ULONG devicePropertyLength = 0; DEVPROPTYPE devicePropertyType = 0; HANDLE keyServiceHandle; WCHAR matchingDeviceId[MAX_PATH] = L""; WCHAR deviceServiceName[MAX_PATH] = L""; if (!SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &GUID_DEVINTERFACE_DISPLAY_ADAPTER, i, &deviceInterfaceData)) break; if (SetupDiGetDeviceInterfaceDetail( deviceInfoHandle, &deviceInterfaceData, 0, 0, &deviceInfoLength, &deviceInfoData ) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { continue; } deviceInterfaceDetail = PhAllocate(deviceInfoLength); deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail( deviceInfoHandle, &deviceInterfaceData, deviceInterfaceDetail, deviceInfoLength, &deviceInfoLength, &deviceInfoData )) { continue; } if (!SetupDiGetDeviceProperty( deviceInfoHandle, &deviceInfoData, &DEVPKEY_Device_MatchingDeviceId, &devicePropertyType, (PBYTE)&matchingDeviceId, sizeof(matchingDeviceId), &devicePropertyLength, 0 )) { continue; } //if (PhEqualStringZ(deviceInterfaceDetail->DevicePath, displayInstancePath, TRUE)) if (!PhEqualStringZ(matchingDeviceId, matchingDeviceIdString->Buffer, TRUE)) continue; if (!SetupDiGetDeviceProperty( deviceInfoHandle, &deviceInfoData, &DEVPKEY_Device_Service, &devicePropertyType, (PBYTE)&deviceServiceName, sizeof(deviceServiceName), &devicePropertyLength, 0 )) { continue; } keyServicePath = PhConcatStrings2(L"System\\CurrentControlSet\\Services\\", deviceServiceName); if (NT_SUCCESS(PhOpenKey( &keyServiceHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyServicePath->sr, 0 ))) { PPH_STRING driverNtPathString = NULL; PPH_STRING driverDosPathString = NULL; if (driverNtPathString = PhQueryRegistryString(keyServiceHandle, L"ImagePath")) { driverDosPathString = PhGetFileName(driverNtPathString); PhDereferenceObject(driverNtPathString); } if (driverDosPathString) { PPH_STRING fileSignerName = NULL; //PH_MAPPED_IMAGE fileMappedImage; // //if (NT_SUCCESS(PhLoadMappedImage(driverDosPathString->Buffer, NULL, TRUE, &fileMappedImage))) //{ // LARGE_INTEGER time; // SYSTEMTIME systemTime; // PPH_STRING string; // // RtlSecondsSince1970ToTime(fileMappedImage.NtHeaders->FileHeader.TimeDateStamp, &time); // PhLargeIntegerToLocalSystemTime(&systemTime, &time); // // string = PhFormatDateTime(&systemTime); // //SetDlgItemText(hwndDlg, IDC_TIMESTAMP, string->Buffer); // PhDereferenceObject(string); // // PhUnloadMappedImage(&fileMappedImage); //} if (PhVerifyFile(driverDosPathString->Buffer, &fileSignerName) == VrTrusted) { if (PhEqualString2(fileSignerName, L"Microsoft Windows Hardware Compatibility Publisher", TRUE)) { nvGpuDriverIsWHQL = TRUE; } } if (fileSignerName) PhDereferenceObject(fileSignerName); PhDereferenceObject(driverDosPathString); } NtClose(keyServiceHandle); } } } __finally { if (deviceInfoHandle != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(deviceInfoHandle); } if (keyHandle) { NtClose(keyHandle); } if (deviceInterfaceDetail) { PhFree(deviceInterfaceDetail); } if (keyPath) { PhDereferenceObject(keyPath); } } return nvGpuDriverIsWHQL; } PPH_STRING NvGpuQueryFanSpeed(VOID) { NvU32 tachValue = 0; NV_GPU_COOLER_SETTINGS coolerInfo = { NV_GPU_COOLER_SETTINGS_VER }; if (NvAPI_GPU_GetTachReading && NvAPI_GPU_GetTachReading(NvGpuPhysicalHandleList->Items[0], &tachValue) == NVAPI_OK) { if (NvAPI_GPU_GetCoolerSettings && NvAPI_GPU_GetCoolerSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK) { return PhFormatString(L"%lu RPM (%lu%%)", tachValue, coolerInfo.cooler[0].currentLevel); } return PhFormatString(L"%lu RPM", tachValue); } else { if (NvAPI_GPU_GetCoolerSettings && NvAPI_GPU_GetCoolerSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK) { return PhFormatString(L"%lu%%", coolerInfo.cooler[0].currentLevel); } } return PhCreateString(L"N/A"); } VOID NvGpuUpdateValues(VOID) { NV_USAGES_INFO usagesInfo = { NV_USAGES_INFO_VER }; NV_DISPLAY_DRIVER_MEMORY_INFO memoryInfo = { NV_DISPLAY_DRIVER_MEMORY_INFO_VER }; NV_GPU_THERMAL_SETTINGS thermalSettings = { NV_GPU_THERMAL_SETTINGS_VER }; NV_GPU_CLOCK_FREQUENCIES clkFreqs = { NV_GPU_CLOCK_FREQUENCIES_VER }; NV_CLOCKS_INFO clocksInfo = { NV_CLOCKS_INFO_VER }; NV_VOLTAGE_DOMAINS voltageDomains = { NV_VOLTAGE_DOMAIN_INFO_VER }; if (NvAPI_GPU_GetMemoryInfo(NvGpuDisplayHandleList->Items[0], &memoryInfo) == NVAPI_OK) { GpuMemoryLimit = memoryInfo.availableDedicatedVideoMemory; GpuCurrentMemSharedUsage = memoryInfo.sharedSystemMemory; GpuCurrentMemUsage = memoryInfo.availableDedicatedVideoMemory - memoryInfo.curAvailableDedicatedVideoMemory; } if (NvAPI_GPU_GetUsages(NvGpuPhysicalHandleList->Items[0], &usagesInfo) == NVAPI_OK) { GpuCurrentGpuUsage = (FLOAT)usagesInfo.usages[2] / 100; GpuCurrentCoreUsage = (FLOAT)usagesInfo.usages[6] / 100; GpuCurrentBusUsage = (FLOAT)usagesInfo.usages[14] / 100; } if (NvAPI_GPU_GetThermalSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_THERMAL_TARGET_ALL, &thermalSettings) == NVAPI_OK) { GpuCurrentCoreTemp = thermalSettings.sensor[0].currentTemp; GpuCurrentBoardTemp = thermalSettings.sensor[1].currentTemp; } if (NvAPI_GPU_GetAllClockFrequencies(NvGpuPhysicalHandleList->Items[0], &clkFreqs) == NVAPI_OK) { //if (clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].bIsPresent) GpuCurrentCoreClock = clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].frequency / 1000; //if (clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY].bIsPresent) GpuCurrentMemoryClock = clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY].frequency / 1000; //if (clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR].bIsPresent) GpuCurrentShaderClock = clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR].frequency / 1000; } if (NvAPI_GPU_GetAllClocks(NvGpuPhysicalHandleList->Items[0], &clocksInfo) == NVAPI_OK) { if (GpuCurrentCoreClock == 0) GpuCurrentCoreClock = clocksInfo.clocks[0] / 1000; if (GpuCurrentMemoryClock == 0) GpuCurrentMemoryClock = clocksInfo.clocks[1] / 1000; if (GpuCurrentShaderClock == 0) GpuCurrentShaderClock = clocksInfo.clocks[2] / 1000; if (clocksInfo.clocks[30] != 0) { if (GpuCurrentCoreClock == 0) GpuCurrentCoreClock = (ULONG)(clocksInfo.clocks[30] * 0.0005f); if (GpuCurrentShaderClock == 0) GpuCurrentShaderClock = (ULONG)(clocksInfo.clocks[30] * 0.001f); } } if (NvAPI_GPU_GetVoltageDomainsStatus(NvGpuPhysicalHandleList->Items[0], &voltageDomains) == NVAPI_OK) { GpuCurrentVoltage = voltageDomains.domain[0].mvolt / 1000; //for (NvU32 i = 0; i < voltageDomains.max; i++) //{ // if (voltageDomains.domain[i].domainId == NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_CORE) // { // OutputDebugString(PhaFormatString(L"Voltage: [%lu] %lu\r\n", i, voltageDomains.domain[0].mvolt / 1000))->Buffer); // } //} } //if (NvAPI_GPU_GetPerfDecreaseInfo(NvGpuPhysicalHandleList->Items[0], &GpuPerfDecreaseReason) != NVAPI_OK) //{ // GpuPerfDecreaseReason = NV_GPU_PERF_DECREASE_REASON_UNKNOWN; //} //NvU32 totalApps = 0; //NV_ACTIVE_APPS activeApps[NVAPI_MAX_PROCESSES] = { NV_ACTIVE_APPS_INFO_VER }; //NvAPI_GPU_QueryActiveApps(NvGpuPhysicalHandleList->Items[0], activeApps, &totalApps); //NV_VOLTAGES voltages = { NV_VOLTAGES_INFO_VER }; //NvAPI_GPU_GetVoltages(NvGpuPhysicalHandleList->Items[0], &voltages); //Nv120 clockInfo = { NV_PERF_CLOCKS_INFO_VER }; //NvAPI_GPU_GetPerfClocks(NvGpuPhysicalHandleList->Items[0], 0, &clockInfo); }