2025-05-13 19:49:49 +03:00

1018 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 "main.h"
#include "nvapi\nvapi.h"
#include "nvidia.h"
#pragma comment(lib, "Setupapi.lib")
#include <Setupapi.h>
#include <Ntddvdeo.h>
#include <devpkey.h>
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);
}