2025-05-13 19:45:22 +03:00

1035 lines
33 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
#define INITGUID
#include "devices.h"
#include "nvapi\nvapi.h"
#include "nvidia.h"
#ifdef _NV_GPU_BUILD
BOOLEAN NvApiInitialized = FALSE;
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;
static VOID NvGpuEnumPhysicalHandles(VOID)
{
NvU32 gpuCount = 0;
NvPhysicalGpuHandle gpuHandles[NVAPI_MAX_PHYSICAL_GPUS];
memset(gpuHandles, 0, sizeof(gpuHandles));
if (NvAPI_EnumPhysicalGPUs(gpuHandles, &gpuCount) == NVAPI_OK)
{
PhAddItemsList(NvGpuPhysicalHandleList, gpuHandles, gpuCount);
}
}
static VOID NvGpuEnumDisplayHandles(VOID)
{
for (NvU32 i = 0; i < NVAPI_MAX_DISPLAYS; i++)
{
NvDisplayHandle displayHandle;
if (NvAPI_EnumNvidiaDisplayHandle(i, &displayHandle) == NVAPI_END_ENUMERATION)
{
break;
}
PhAddItemList(NvGpuDisplayHandleList, displayHandle);
}
}
VOID NvApiInitialize(VOID)
{
ULONG sampleCount;
if (!PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU))
return;
sampleCount = PhGetIntegerSetting(L"SampleCount");
PhInitializeCircularBuffer_FLOAT(&GpuUtilizationHistory, sampleCount);
PhInitializeCircularBuffer_ULONG(&GpuMemoryHistory, sampleCount);
PhInitializeCircularBuffer_FLOAT(&GpuBoardHistory, sampleCount);
PhInitializeCircularBuffer_FLOAT(&GpuBusHistory, sampleCount);
NvGpuPhysicalHandleList = PhCreateList(1);
NvGpuDisplayHandleList = PhCreateList(1);
#ifdef _M_IX86
if (!(NvApiLibrary = LoadLibrary(L"nvapi.dll")))
return;
#else
if (!(NvApiLibrary = LoadLibrary(L"nvapi64.dll")))
return;
#endif
// Retrieve the NvAPI_QueryInterface function address
if (!(NvAPI_QueryInterface = PhGetProcedureAddress(NvApiLibrary, "nvapi_QueryInterface", 0)))
return;
// Initialization functions
if (!(NvAPI_Initialize = NvAPI_QueryInterface(0x150E828UL)))
return;
if (!(NvAPI_Unload = NvAPI_QueryInterface(0xD22BDD7EUL)))
return;
// Error functions
NvAPI_GetErrorMessage = NvAPI_QueryInterface(0x6C2D048CUL);
// Handle functions
NvAPI_EnumPhysicalGPUs = NvAPI_QueryInterface(0xE5AC921FUL);
NvAPI_EnumNvidiaDisplayHandle = NvAPI_QueryInterface(0x9ABDD40DUL);
// 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 functions below
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);
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);
NvAPI_GetDisplayDriverBuildTitle = NvAPI_QueryInterface(0x7562E947);
NvAPI_GetDisplayDriverCompileType = NvAPI_QueryInterface(0x988AEA78);
NvAPI_GetDisplayDriverSecurityLevel = NvAPI_QueryInterface(0x9D772BBA);
NvAPI_GPU_GetVPECount = NvAPI_QueryInterface(0xD8CBF37B);
NvAPI_GPU_GetTargetID = NvAPI_QueryInterface(0x35B5FD2F);
//NvAPI_GPU_GetExtendedMinorRevision = NvAPI_QueryInterface(0x025F17421);
//NvAPI_GPU_GetSerialNumber = NvAPI_QueryInterface(0x14B83A5F);
if (NvAPI_Initialize() == NVAPI_OK)
{
NvGpuEnumPhysicalHandles();
NvGpuEnumDisplayHandles();
NvApiInitialized = TRUE;
}
}
BOOLEAN DestroyNvApi(VOID)
{
NvApiInitialized = FALSE;
if (NvGpuDisplayHandleList)
PhDereferenceObject(NvGpuDisplayHandleList);
if (NvGpuPhysicalHandleList)
PhDereferenceObject(NvGpuPhysicalHandleList);
if (NvAPI_Unload)
NvAPI_Unload();
if (NvApiLibrary)
FreeLibrary(NvApiLibrary);
return TRUE;
}
PPH_STRING NvGpuQueryDriverVersion(VOID)
{
if (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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)
{
if (NvApiInitialized)
{
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);
}
return PhCreateString(L"N/A");
}
PPH_STRING NvGpuQueryFoundry(VOID)
{
if (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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 (NvApiInitialized && 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_ENABLED)
{
return PhFormatString(L"PMU: %.2f%%", (FLOAT)powerTopology.unknown.unknown2 / 1000);
}
}
}
}
return PhCreateString(L"N/A");
}
PPH_STRING NvGpuQueryDriverSettings(VOID)
{
if (NvApiInitialized && 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 (!NvApiInitialized)
// __leave;
// 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 (NvApiInitialized)
{
if (NvAPI_GPU_GetTachReading(NvGpuPhysicalHandleList->Items[0], &tachValue) == NVAPI_OK)
{
if (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(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK)
{
return PhFormatString(L"%lu%%", coolerInfo.cooler[0].currentLevel);
}
}
}
return PhCreateString(L"N/A");
}
VOID NvGpuUpdate(VOID)
{
NV_USAGES_INFO usagesInfo = { NV_USAGES_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 };
ULONG totalMemory = 0;
ULONG sharedMemory = 0;
ULONG freeMemory = 0;
ULONG usedMemory = 0;
if (!NvApiInitialized)
return;
for (ULONG i = 0; i < NvGpuDisplayHandleList->Count; i++)
{
NvDisplayHandle nvDisplayHandle;
NV_DISPLAY_DRIVER_MEMORY_INFO memoryInfo = { NV_DISPLAY_DRIVER_MEMORY_INFO_VER };
nvDisplayHandle = NvGpuDisplayHandleList->Items[i];
if (NvAPI_GPU_GetMemoryInfo(nvDisplayHandle, &memoryInfo) == NVAPI_OK)
{
totalMemory += memoryInfo.dedicatedVideoMemory;
sharedMemory += memoryInfo.sharedSystemMemory;
freeMemory += memoryInfo.curAvailableDedicatedVideoMemory;
usedMemory += totalMemory - freeMemory;
}
}
GpuMemoryLimit = totalMemory;
GpuCurrentMemUsage = usedMemory;
GpuCurrentMemSharedUsage = sharedMemory;
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);
PhAddItemCircularBuffer_FLOAT(&GpuUtilizationHistory, GpuCurrentGpuUsage);
PhAddItemCircularBuffer_ULONG(&GpuMemoryHistory, GpuCurrentMemUsage);
PhAddItemCircularBuffer_FLOAT(&GpuBoardHistory, GpuCurrentCoreUsage);
PhAddItemCircularBuffer_FLOAT(&GpuBusHistory, GpuCurrentBusUsage);
}
#endif