1018 lines
33 KiB
C
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);
|
|
} |