go my file uploader
This commit is contained in:
17
plugins/HardwareDevices/CHANGELOG.txt
Normal file
17
plugins/HardwareDevices/CHANGELOG.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
1.4
|
||||
* Fixed incorrect drive letters
|
||||
* Fixed drive letter and panel clipping issue
|
||||
|
||||
1.3
|
||||
* Fixed Vista support
|
||||
* Adapter information is now updated regardless of whether System Information is open
|
||||
* Added disk statistics support
|
||||
|
||||
1.2
|
||||
* Added network adapter details window
|
||||
|
||||
1.1
|
||||
* Added native network driver statistics support
|
||||
|
||||
1.0
|
||||
* Initial release
|
||||
402
plugins/HardwareDevices/HardwareDevices.rc
Normal file
402
plugins/HardwareDevices/HardwareDevices.rc
Normal file
@@ -0,0 +1,402 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (Australia) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
|
||||
#pragma code_page(1252)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,4,0,0
|
||||
PRODUCTVERSION 1,4,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "0c0904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "dmex"
|
||||
VALUE "FileDescription", "Hardware Devices plugin for Process Hacker"
|
||||
VALUE "FileVersion", "1.4"
|
||||
VALUE "InternalName", "HardwareDevices"
|
||||
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
|
||||
VALUE "OriginalFilename", "HardwareDevices.dll"
|
||||
VALUE "ProductName", "Hardware Devices plugin for Process Hacker"
|
||||
VALUE "ProductVersion", "1.4"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0xc09, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_NETADAPTER_OPTIONS DIALOGEX 0, 0, 265, 177
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Network Adapters"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_NETADAPTERS_LISTVIEW,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,7,7,251,146
|
||||
CONTROL "Show hidden adapters",IDC_SHOW_HIDDEN_ADAPTERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,159,87,10
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_DIALOG DIALOGEX 0, 0, 269, 130
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "",IDC_GRAPH_LAYOUT,0,21,269,53,NOT WS_VISIBLE | WS_BORDER
|
||||
LTEXT "Static",IDC_ADAPTERNAME,0,0,269,21
|
||||
LTEXT "Panel layout",IDC_LAYOUT,0,91,268,36,NOT WS_VISIBLE
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_PANEL DIALOGEX 0, 0, 254, 50
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "Link speed",IDC_STATIC,7,11,35,8
|
||||
RTEXT "Static",IDC_LINK_SPEED,50,11,54,8,SS_ENDELLIPSIS
|
||||
GROUPBOX "Adapter",IDC_STATIC,0,0,111,34
|
||||
LTEXT "Link state",IDC_STATIC,7,23,32,8
|
||||
RTEXT "Static",IDC_LINK_STATE,50,23,54,8,SS_ENDELLIPSIS
|
||||
GROUPBOX "Statistics",IDC_STATIC,116,0,136,45
|
||||
LTEXT "Bytes sent",IDC_STATIC,125,11,36,8
|
||||
LTEXT "Bytes received",IDC_STATIC,125,22,50,8
|
||||
RTEXT "Static",IDC_STAT_BSENT,182,11,62,8,SS_ENDELLIPSIS
|
||||
RTEXT "Static",IDC_STAT_BRECEIVED,182,22,62,8,SS_ENDELLIPSIS
|
||||
LTEXT "Bytes total",IDC_STATIC,125,33,37,8
|
||||
RTEXT "Static",IDC_STAT_BTOTAL,182,33,62,8,SS_ENDELLIPSIS
|
||||
PUSHBUTTON "Details",IDC_DETAILS,0,35,50,14
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_DETAILS DIALOGEX 0, 0, 309, 265
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
CAPTION "Adapter Details"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
PUSHBUTTON "Close",IDOK,253,244,50,14
|
||||
CONTROL "",IDC_DETAILS_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,295,235
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_OPTIONS DIALOGEX 0, 0, 265, 177
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Disk Drives"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_DISKDRIVE_LISTVIEW,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,7,7,251,163
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DIALOG DIALOGEX 0, 0, 315, 135
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "",IDC_GRAPH_LAYOUT,0,21,314,60,NOT WS_VISIBLE | WS_BORDER
|
||||
LTEXT "Disk",IDC_DISKMOUNTPATH,0,0,105,21
|
||||
LTEXT "Panel layout",IDC_LAYOUT,0,98,314,36,NOT WS_VISIBLE
|
||||
RTEXT "Disk name",IDC_DISKNAME,107,4,207,16,SS_WORDELLIPSIS
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_PANEL DIALOGEX 0, 0, 330, 50
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Statistics",IDC_STATIC,139,0,136,44
|
||||
LTEXT "Bytes read",IDC_STATIC,148,11,38,8
|
||||
LTEXT "Bytes written",IDC_STATIC,148,22,45,8
|
||||
RTEXT "Static",IDC_STAT_BREAD,205,11,62,8,SS_ENDELLIPSIS
|
||||
RTEXT "Static",IDC_STAT_BWRITE,205,22,62,8,SS_ENDELLIPSIS
|
||||
LTEXT "Bytes total",IDC_STATIC,148,33,37,8
|
||||
RTEXT "Static",IDC_STAT_BTOTAL,205,33,62,8,SS_ENDELLIPSIS
|
||||
LTEXT "Active time",IDC_STATIC,8,11,53,8,SS_ENDELLIPSIS
|
||||
LTEXT "Response time",IDC_STATIC,8,22,64,8,SS_ENDELLIPSIS
|
||||
LTEXT "Queue length",IDC_STATIC,8,33,57,8,SS_ENDELLIPSIS
|
||||
GROUPBOX "Disk",IDC_STATIC,0,0,135,44
|
||||
PUSHBUTTON "Details",IDC_DETAILS,278,30,50,14,NOT WS_VISIBLE
|
||||
RTEXT "Static",IDC_STAT_ACTIVE,65,11,62,8,SS_ENDELLIPSIS
|
||||
RTEXT "Static",IDC_STAT_RESPONSETIME,65,22,62,8,SS_ENDELLIPSIS
|
||||
RTEXT "Static",IDC_STAT_QUEUELENGTH,65,33,62,8,SS_ENDELLIPSIS
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_SMART DIALOGEX 0, 0, 309, 265
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "SMART"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_DETAILS_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,295,182
|
||||
EDITTEXT IDC_EDIT1,7,200,295,58,ES_MULTILINE | ES_READONLY | WS_VSCROLL
|
||||
LTEXT "Description:",IDC_DESCRIPTION,7,190,39,8
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_FILESYSTEM DIALOGEX 0, 0, 309, 265
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Volume(s)"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_DETAILS_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,295,182
|
||||
EDITTEXT IDC_EDIT1,7,200,295,58,ES_MULTILINE | ES_READONLY | WS_VSCROLL
|
||||
LTEXT "Description:",IDC_DESCRIPTION,7,190,39,8
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_GENERAL DIALOGEX 0, 0, 275, 262
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_GPU_DIALOG DIALOGEX 0, 0, 315, 191
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "GPU",IDC_TITLE,0,0,72,21
|
||||
RTEXT "GPU Name",IDC_GPUNAME,83,4,232,16,SS_WORDELLIPSIS
|
||||
LTEXT "Panel layout",IDC_LAYOUT,0,145,315,46,NOT WS_VISIBLE
|
||||
LTEXT "Graph layout",IDC_GRAPH_LAYOUT,0,22,315,120,NOT WS_VISIBLE
|
||||
LTEXT "GPU:",IDC_GPU_L,73,0,17,8
|
||||
LTEXT "Memory:",IDC_MEMORY_L,73,5,29,8
|
||||
LTEXT "Memory Controller:",IDC_SHARED_L,74,11,62,8
|
||||
LTEXT "Bus Interface:",IDC_BUS_L,74,18,47,8
|
||||
END
|
||||
|
||||
IDD_GPU_PANEL DIALOGEX 0, 0, 372, 47
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Clocks",IDC_STATIC,0,0,118,43
|
||||
LTEXT "Core",IDC_STATIC,8,10,16,8
|
||||
LTEXT "Memory",IDC_STATIC,8,21,26,8
|
||||
RTEXT "Static",IDC_CLOCK_CORE,55,10,54,8,SS_ENDELLIPSIS
|
||||
RTEXT "Static",IDC_CLOCK_MEMORY,55,21,54,8,SS_ENDELLIPSIS
|
||||
GROUPBOX "Fan",IDC_STATIC,122,0,124,22
|
||||
LTEXT "Speed",IDC_STATIC,130,10,21,8
|
||||
RTEXT "Static",IDC_FAN_PERCENT,158,10,78,8,SS_ENDELLIPSIS
|
||||
LTEXT "Shader",IDC_STATIC,8,32,24,8
|
||||
RTEXT "Static",IDC_CLOCK_SHADER,55,32,54,8,SS_ENDELLIPSIS
|
||||
GROUPBOX "Temperature",IDC_STATIC,122,22,124,21
|
||||
LTEXT "Core",IDC_STATIC,130,32,16,8
|
||||
RTEXT "Static",IDC_TEMP_VALUE,158,32,78,8,SS_ENDELLIPSIS
|
||||
GROUPBOX "Voltage",IDC_STATIC,248,0,124,22
|
||||
LTEXT "Core",IDC_STATIC,256,10,16,8
|
||||
RTEXT "Static",IDC_VOLTAGE,284,10,78,8,SS_ENDELLIPSIS
|
||||
PUSHBUTTON "Details",IDC_DETAILS,249,27,50,14,NOT WS_VISIBLE
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_NETADAPTER_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 258
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 170
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_DIALOG, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_PANEL, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 253
|
||||
TOPMARGIN, 1
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_DETAILS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 302
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 258
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 258
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 170
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DIALOG, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 314
|
||||
BOTTOMMARGIN, 134
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_PANEL, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 329
|
||||
BOTTOMMARGIN, 49
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_SMART, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 302
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 258
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_FILESYSTEM, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 302
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 258
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_GENERAL, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 268
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 255
|
||||
END
|
||||
|
||||
IDD_GPU_DIALOG, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_GPU_PANEL, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AFX_DIALOG_LAYOUT
|
||||
//
|
||||
|
||||
IDD_NETADAPTER_PANEL AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_DETAILS AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_OPTIONS AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_NETADAPTER_DIALOG AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_OPTIONS AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DIALOG AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_PANEL AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_SMART AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_FILESYSTEM AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_DISKDRIVE_DETAILS_GENERAL AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_GPU_DIALOG AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
IDD_GPU_PANEL AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
#endif // English (Australia) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
120
plugins/HardwareDevices/HardwareDevices.vcxproj
Normal file
120
plugins/HardwareDevices/HardwareDevices.vcxproj
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5F0D72C4-8319-4B61-9E13-6084B680EB90}</ProjectGuid>
|
||||
<RootNamespace>HardwareDevices</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectName>HardwareDevices</ProjectName>
|
||||
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\Plugins.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug64</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;setupapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;setupapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;setupapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;setupapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;setupapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;setupapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Link>
|
||||
<AdditionalDependencies>iphlpapi.lib;setupapi.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>iphlpapi.dll;setupapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="adapter.c" />
|
||||
<ClCompile Include="diskdetails.c" />
|
||||
<ClCompile Include="disknotify.c" />
|
||||
<ClCompile Include="gpugraph.c" />
|
||||
<ClCompile Include="netdetails.c" />
|
||||
<ClCompile Include="diskgraph.c" />
|
||||
<ClCompile Include="diskoptions.c" />
|
||||
<ClCompile Include="disk.c" />
|
||||
<ClCompile Include="netgraph.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="ndis.c" />
|
||||
<ClCompile Include="netoptions.c" />
|
||||
<ClCompile Include="nvidia.c" />
|
||||
<ClCompile Include="storage.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="devices.h" />
|
||||
<ClInclude Include="nvapi\nvapi.h" />
|
||||
<ClInclude Include="nvapi\nvapi_lite_common.h" />
|
||||
<ClInclude Include="nvidia.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="HardwareDevices.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CHANGELOG.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
95
plugins/HardwareDevices/HardwareDevices.vcxproj.filters
Normal file
95
plugins/HardwareDevices/HardwareDevices.vcxproj.filters
Normal file
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{47359E56-A930-4DDC-A651-E2E99D48E957}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4965CB7A-371A-4B22-AC3F-E70DC77C5D24}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{00475F04-2369-42D8-9A52-9DB77E37AE62}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Disk">
|
||||
<UniqueIdentifier>{1ccecf79-cd82-4ae5-b891-64a0a2d18e8e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Network">
|
||||
<UniqueIdentifier>{c7c48d78-64cd-4559-87c1-74e2141dcd2e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Graphics">
|
||||
<UniqueIdentifier>{17660e06-b187-4eca-81d7-f6d3548f3c2f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Graphics">
|
||||
<UniqueIdentifier>{987f6036-c8df-4352-abc3-060d5a1bc7e4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="devices.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nvapi\nvapi.h">
|
||||
<Filter>Header Files\Graphics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nvapi\nvapi_lite_common.h">
|
||||
<Filter>Header Files\Graphics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="nvidia.h">
|
||||
<Filter>Header Files\Graphics</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="diskoptions.c">
|
||||
<Filter>Source Files\Disk</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ndis.c">
|
||||
<Filter>Source Files\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="storage.c">
|
||||
<Filter>Source Files\Disk</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="adapter.c">
|
||||
<Filter>Source Files\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="netgraph.c">
|
||||
<Filter>Source Files\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="netoptions.c">
|
||||
<Filter>Source Files\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="netdetails.c">
|
||||
<Filter>Source Files\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="disk.c">
|
||||
<Filter>Source Files\Disk</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="diskgraph.c">
|
||||
<Filter>Source Files\Disk</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="diskdetails.c">
|
||||
<Filter>Source Files\Disk</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="disknotify.c">
|
||||
<Filter>Source Files\Disk</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gpugraph.c">
|
||||
<Filter>Source Files\Graphics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="nvidia.c">
|
||||
<Filter>Source Files\Graphics</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CHANGELOG.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="HardwareDevices.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
292
plugins/HardwareDevices/adapter.c
Normal file
292
plugins/HardwareDevices/adapter.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
VOID AdapterEntryDeleteProcedure(
|
||||
_In_ PVOID Object,
|
||||
_In_ ULONG Flags
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY entry = Object;
|
||||
|
||||
PhAcquireQueuedLockExclusive(&NetworkAdaptersListLock);
|
||||
PhRemoveItemList(NetworkAdaptersList, PhFindItemList(NetworkAdaptersList, entry));
|
||||
PhReleaseQueuedLockExclusive(&NetworkAdaptersListLock);
|
||||
|
||||
DeleteNetAdapterId(&entry->Id);
|
||||
PhClearReference(&entry->AdapterName);
|
||||
|
||||
PhDeleteCircularBuffer_ULONG64(&entry->InboundBuffer);
|
||||
PhDeleteCircularBuffer_ULONG64(&entry->OutboundBuffer);
|
||||
}
|
||||
|
||||
VOID NetAdaptersInitialize(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
NetworkAdaptersList = PhCreateList(1);
|
||||
NetAdapterEntryType = PhCreateObjectType(L"NetAdapterEntry", 0, AdapterEntryDeleteProcedure);
|
||||
}
|
||||
|
||||
VOID NetAdaptersUpdate(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
static ULONG runCount = 0; // MUST keep in sync with runCount in process provider
|
||||
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
|
||||
{
|
||||
HANDLE deviceHandle = NULL;
|
||||
PDV_NETADAPTER_ENTRY entry;
|
||||
ULONG64 networkInOctets = 0;
|
||||
ULONG64 networkOutOctets = 0;
|
||||
ULONG64 networkRcvSpeed = 0;
|
||||
ULONG64 networkXmitSpeed = 0;
|
||||
NDIS_MEDIA_CONNECT_STATE mediaState = MediaConnectStateUnknown;
|
||||
|
||||
entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_NDIS))
|
||||
{
|
||||
if (NT_SUCCESS(NetworkAdapterCreateHandle(&deviceHandle, entry->Id.InterfaceGuid)))
|
||||
{
|
||||
if (!entry->CheckedDeviceSupport)
|
||||
{
|
||||
// Check the network adapter supports the OIDs we're going to be using.
|
||||
if (NetworkAdapterQuerySupported(deviceHandle))
|
||||
{
|
||||
entry->DeviceSupported = TRUE;
|
||||
}
|
||||
|
||||
entry->CheckedDeviceSupport = TRUE;
|
||||
}
|
||||
|
||||
if (!entry->DeviceSupported)
|
||||
{
|
||||
// Device is faulty. Close the handle so we can fallback to GetIfEntry.
|
||||
NtClose(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceHandle)
|
||||
{
|
||||
NDIS_STATISTICS_INFO interfaceStats;
|
||||
NDIS_LINK_STATE interfaceState;
|
||||
|
||||
memset(&interfaceStats, 0, sizeof(NDIS_STATISTICS_INFO));
|
||||
|
||||
NetworkAdapterQueryStatistics(deviceHandle, &interfaceStats);
|
||||
|
||||
if (NT_SUCCESS(NetworkAdapterQueryLinkState(deviceHandle, &interfaceState)))
|
||||
{
|
||||
mediaState = interfaceState.MediaConnectState;
|
||||
}
|
||||
|
||||
if (!(interfaceStats.SupportedStatistics & NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV))
|
||||
networkInOctets = NetworkAdapterQueryValue(deviceHandle, OID_GEN_BYTES_RCV);
|
||||
else
|
||||
networkInOctets = interfaceStats.ifHCInOctets;
|
||||
|
||||
if (!(interfaceStats.SupportedStatistics & NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT))
|
||||
networkOutOctets = NetworkAdapterQueryValue(deviceHandle, OID_GEN_BYTES_XMIT);
|
||||
else
|
||||
networkOutOctets = interfaceStats.ifHCOutOctets;
|
||||
|
||||
networkRcvSpeed = networkInOctets - entry->LastInboundValue;
|
||||
networkXmitSpeed = networkOutOctets - entry->LastOutboundValue;
|
||||
|
||||
// HACK: Pull the Adapter name from the current query.
|
||||
if (!entry->AdapterName)
|
||||
{
|
||||
entry->AdapterName = NetworkAdapterQueryName(deviceHandle, entry->Id.InterfaceGuid);
|
||||
}
|
||||
|
||||
entry->DevicePresent = TRUE;
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
else if (WindowsVersion >= WINDOWS_VISTA && GetIfEntry2)
|
||||
{
|
||||
MIB_IF_ROW2 interfaceRow;
|
||||
|
||||
if (QueryInterfaceRowVista(&entry->Id, &interfaceRow))
|
||||
{
|
||||
networkInOctets = interfaceRow.InOctets;
|
||||
networkOutOctets = interfaceRow.OutOctets;
|
||||
mediaState = interfaceRow.MediaConnectState;
|
||||
networkRcvSpeed = networkInOctets - entry->LastInboundValue;
|
||||
networkXmitSpeed = networkOutOctets - entry->LastOutboundValue;
|
||||
|
||||
// HACK: Pull the Adapter name from the current query.
|
||||
if (!entry->AdapterName && PhCountStringZ(interfaceRow.Description) > 0)
|
||||
{
|
||||
entry->AdapterName = PhCreateString(interfaceRow.Description);
|
||||
}
|
||||
|
||||
entry->DevicePresent = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->DevicePresent = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MIB_IFROW interfaceRow;
|
||||
|
||||
if (QueryInterfaceRowXP(&entry->Id, &interfaceRow))
|
||||
{
|
||||
networkInOctets = interfaceRow.dwInOctets;
|
||||
networkOutOctets = interfaceRow.dwOutOctets;
|
||||
mediaState = interfaceRow.dwOperStatus == IF_OPER_STATUS_OPERATIONAL ? MediaConnectStateConnected : MediaConnectStateDisconnected;
|
||||
networkRcvSpeed = networkInOctets - entry->LastInboundValue;
|
||||
networkXmitSpeed = networkOutOctets - entry->LastOutboundValue;
|
||||
|
||||
// HACK: Pull the Adapter name from the current query.
|
||||
if (!entry->AdapterName && strlen(interfaceRow.bDescr) > 0)
|
||||
{
|
||||
entry->AdapterName = PhConvertMultiByteToUtf16(interfaceRow.bDescr);
|
||||
}
|
||||
|
||||
entry->DevicePresent = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->DevicePresent = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaState == MediaConnectStateUnknown)
|
||||
{
|
||||
// We don't want incorrect data when the adapter is disabled.
|
||||
networkRcvSpeed = 0;
|
||||
networkXmitSpeed = 0;
|
||||
}
|
||||
|
||||
if (!entry->HaveFirstSample)
|
||||
{
|
||||
// The first sample must be zero.
|
||||
networkRcvSpeed = 0;
|
||||
networkXmitSpeed = 0;
|
||||
entry->HaveFirstSample = TRUE;
|
||||
}
|
||||
|
||||
if (runCount != 0)
|
||||
{
|
||||
PhAddItemCircularBuffer_ULONG64(&entry->InboundBuffer, networkRcvSpeed);
|
||||
PhAddItemCircularBuffer_ULONG64(&entry->OutboundBuffer, networkXmitSpeed);
|
||||
}
|
||||
|
||||
//context->LinkSpeed = networkLinkSpeed;
|
||||
entry->InboundValue = networkRcvSpeed;
|
||||
entry->OutboundValue = networkXmitSpeed;
|
||||
entry->LastInboundValue = networkInOctets;
|
||||
entry->LastOutboundValue = networkOutOctets;
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
runCount++;
|
||||
}
|
||||
|
||||
VOID InitializeNetAdapterId(
|
||||
_Out_ PDV_NETADAPTER_ID Id,
|
||||
_In_ NET_IFINDEX InterfaceIndex,
|
||||
_In_ IF_LUID InterfaceLuid,
|
||||
_In_ PPH_STRING InterfaceGuid
|
||||
)
|
||||
{
|
||||
Id->InterfaceIndex = InterfaceIndex;
|
||||
Id->InterfaceLuid = InterfaceLuid;
|
||||
PhSetReference(&Id->InterfaceGuid, InterfaceGuid);
|
||||
}
|
||||
|
||||
VOID CopyNetAdapterId(
|
||||
_Out_ PDV_NETADAPTER_ID Destination,
|
||||
_In_ PDV_NETADAPTER_ID Source
|
||||
)
|
||||
{
|
||||
InitializeNetAdapterId(
|
||||
Destination,
|
||||
Source->InterfaceIndex,
|
||||
Source->InterfaceLuid,
|
||||
Source->InterfaceGuid
|
||||
);
|
||||
}
|
||||
|
||||
VOID DeleteNetAdapterId(
|
||||
_Inout_ PDV_NETADAPTER_ID Id
|
||||
)
|
||||
{
|
||||
PhClearReference(&Id->InterfaceGuid);
|
||||
}
|
||||
|
||||
BOOLEAN EquivalentNetAdapterId(
|
||||
_In_ PDV_NETADAPTER_ID Id1,
|
||||
_In_ PDV_NETADAPTER_ID Id2
|
||||
)
|
||||
{
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
if (Id1->InterfaceLuid.Value == Id2->InterfaceLuid.Value)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Id1->InterfaceIndex == Id2->InterfaceIndex)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PDV_NETADAPTER_ENTRY CreateNetAdapterEntry(
|
||||
_In_ PDV_NETADAPTER_ID Id
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY entry;
|
||||
|
||||
entry = PhCreateObject(sizeof(DV_NETADAPTER_ENTRY), NetAdapterEntryType);
|
||||
memset(entry, 0, sizeof(DV_NETADAPTER_ENTRY));
|
||||
|
||||
CopyNetAdapterId(&entry->Id, Id);
|
||||
|
||||
PhInitializeCircularBuffer_ULONG64(&entry->InboundBuffer, PhGetIntegerSetting(L"SampleCount"));
|
||||
PhInitializeCircularBuffer_ULONG64(&entry->OutboundBuffer, PhGetIntegerSetting(L"SampleCount"));
|
||||
|
||||
PhAcquireQueuedLockExclusive(&NetworkAdaptersListLock);
|
||||
PhAddItemList(NetworkAdaptersList, entry);
|
||||
PhReleaseQueuedLockExclusive(&NetworkAdaptersListLock);
|
||||
|
||||
return entry;
|
||||
}
|
||||
773
plugins/HardwareDevices/devices.h
Normal file
773
plugins/HardwareDevices/devices.h
Normal file
@@ -0,0 +1,773 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _DEVICES_H_
|
||||
#define _DEVICES_H_
|
||||
|
||||
#define PLUGIN_NAME L"ProcessHacker.HardwareDevices"
|
||||
#define SETTING_NAME_ENABLE_NDIS (PLUGIN_NAME L".EnableNDIS")
|
||||
#define SETTING_NAME_INTERFACE_LIST (PLUGIN_NAME L".NetworkList")
|
||||
#define SETTING_NAME_DISK_LIST (PLUGIN_NAME L".DiskList")
|
||||
#ifdef _NV_GPU_BUILD
|
||||
#define SETTING_NAME_ENABLE_GPU (PLUGIN_NAME L".EnableGpu")
|
||||
#define SETTING_NAME_ENABLE_FAHRENHEIT (PLUGIN_NAME L".ShowFahrenheit")
|
||||
#endif
|
||||
|
||||
#define CINTERFACE
|
||||
#define COBJMACROS
|
||||
#include <phdk.h>
|
||||
#include <phappresource.h>
|
||||
|
||||
#include <windowsx.h>
|
||||
#include <uxtheme.h>
|
||||
#include <ws2def.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <nldef.h>
|
||||
#include <netioapi.h>
|
||||
//#include <WinSock2.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#define WM_SHOWDIALOG (WM_APP + 1)
|
||||
#define UPDATE_MSG (WM_APP + 2)
|
||||
|
||||
extern PPH_PLUGIN PluginInstance;
|
||||
|
||||
extern PPH_OBJECT_TYPE NetAdapterEntryType;
|
||||
extern PPH_LIST NetworkAdaptersList;
|
||||
extern PH_QUEUED_LOCK NetworkAdaptersListLock;
|
||||
|
||||
extern PPH_OBJECT_TYPE DiskDriveEntryType;
|
||||
extern PPH_LIST DiskDrivesList;
|
||||
extern PH_QUEUED_LOCK DiskDrivesListLock;
|
||||
|
||||
// main.c
|
||||
|
||||
PPH_STRING TrimString(
|
||||
_In_ PPH_STRING String
|
||||
);
|
||||
|
||||
INT AddListViewGroup(
|
||||
_In_ HWND ListViewHandle,
|
||||
_In_ INT Index,
|
||||
_In_ PWSTR Text
|
||||
);
|
||||
|
||||
INT AddListViewItemGroupId(
|
||||
_In_ HWND ListViewHandle,
|
||||
_In_ INT GroupId,
|
||||
_In_ INT Index,
|
||||
_In_ PWSTR Text,
|
||||
_In_opt_ PVOID Param
|
||||
);
|
||||
|
||||
ULONG64 RegQueryUlong64(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PWSTR ValueName
|
||||
);
|
||||
|
||||
VOID ShowDeviceMenu(
|
||||
_In_ HWND ParentWindow,
|
||||
_In_ PPH_STRING DeviceInstance
|
||||
);
|
||||
|
||||
// adapter.c
|
||||
|
||||
typedef struct _DV_NETADAPTER_ID
|
||||
{
|
||||
NET_IFINDEX InterfaceIndex;
|
||||
IF_LUID InterfaceLuid;
|
||||
PPH_STRING InterfaceGuid;
|
||||
} DV_NETADAPTER_ID, *PDV_NETADAPTER_ID;
|
||||
|
||||
typedef struct _DV_NETADAPTER_ENTRY
|
||||
{
|
||||
DV_NETADAPTER_ID Id;
|
||||
PPH_STRING AdapterName;
|
||||
|
||||
union
|
||||
{
|
||||
BOOLEAN BitField;
|
||||
struct
|
||||
{
|
||||
BOOLEAN UserReference : 1;
|
||||
BOOLEAN HaveFirstSample : 1;
|
||||
BOOLEAN CheckedDeviceSupport : 1;
|
||||
BOOLEAN DeviceSupported : 1;
|
||||
BOOLEAN DevicePresent : 1;
|
||||
BOOLEAN Spare : 3;
|
||||
};
|
||||
};
|
||||
|
||||
//ULONG64 LinkSpeed;
|
||||
ULONG64 InboundValue;
|
||||
ULONG64 OutboundValue;
|
||||
ULONG64 LastInboundValue;
|
||||
ULONG64 LastOutboundValue;
|
||||
|
||||
PH_CIRCULAR_BUFFER_ULONG64 InboundBuffer;
|
||||
PH_CIRCULAR_BUFFER_ULONG64 OutboundBuffer;
|
||||
} DV_NETADAPTER_ENTRY, *PDV_NETADAPTER_ENTRY;
|
||||
|
||||
typedef struct _DV_NETADAPTER_SYSINFO_CONTEXT
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY AdapterEntry;
|
||||
PPH_STRING SectionName;
|
||||
|
||||
HWND WindowHandle;
|
||||
HWND PanelWindowHandle;
|
||||
HWND GraphHandle;
|
||||
|
||||
PPH_SYSINFO_SECTION SysinfoSection;
|
||||
PH_GRAPH_STATE GraphState;
|
||||
PH_LAYOUT_MANAGER LayoutManager;
|
||||
} DV_NETADAPTER_SYSINFO_CONTEXT, *PDV_NETADAPTER_SYSINFO_CONTEXT;
|
||||
|
||||
typedef struct _DV_NETADAPTER_DETAILS_CONTEXT
|
||||
{
|
||||
PPH_STRING AdapterName;
|
||||
DV_NETADAPTER_ID AdapterId;
|
||||
|
||||
union
|
||||
{
|
||||
BOOLEAN BitField;
|
||||
struct
|
||||
{
|
||||
BOOLEAN HaveFirstSample : 1;
|
||||
BOOLEAN CheckedDeviceSupport : 1;
|
||||
BOOLEAN DeviceSupported : 1;
|
||||
BOOLEAN Spare : 5;
|
||||
};
|
||||
};
|
||||
|
||||
HWND WindowHandle;
|
||||
HWND ParentHandle;
|
||||
HWND ListViewHandle;
|
||||
|
||||
HANDLE NotifyHandle;
|
||||
|
||||
PH_LAYOUT_MANAGER LayoutManager;
|
||||
PH_CALLBACK_REGISTRATION ProcessesUpdatedRegistration;
|
||||
|
||||
ULONG64 LastDetailsInboundValue;
|
||||
ULONG64 LastDetailsIOutboundValue;
|
||||
} DV_NETADAPTER_DETAILS_CONTEXT, *PDV_NETADAPTER_DETAILS_CONTEXT;
|
||||
|
||||
typedef struct _DV_NETADAPTER_CONTEXT
|
||||
{
|
||||
HWND ListViewHandle;
|
||||
//HIMAGELIST ImageList;
|
||||
BOOLEAN OptionsChanged;
|
||||
BOOLEAN EnumeratingAdapters;
|
||||
BOOLEAN UseAlternateMethod;
|
||||
} DV_NETADAPTER_CONTEXT, *PDV_NETADAPTER_CONTEXT;
|
||||
|
||||
VOID NetAdaptersLoadList(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID ShowOptionsDialog(
|
||||
_In_ HWND ParentHandle
|
||||
);
|
||||
|
||||
// adapter.c
|
||||
|
||||
VOID NetAdaptersInitialize(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID NetAdaptersUpdate(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID InitializeNetAdapterId(
|
||||
_Out_ PDV_NETADAPTER_ID Id,
|
||||
_In_ NET_IFINDEX InterfaceIndex,
|
||||
_In_ IF_LUID InterfaceLuid,
|
||||
_In_ PPH_STRING InterfaceGuid
|
||||
);
|
||||
|
||||
VOID CopyNetAdapterId(
|
||||
_Out_ PDV_NETADAPTER_ID Destination,
|
||||
_In_ PDV_NETADAPTER_ID Source
|
||||
);
|
||||
|
||||
VOID DeleteNetAdapterId(
|
||||
_Inout_ PDV_NETADAPTER_ID Id
|
||||
);
|
||||
|
||||
BOOLEAN EquivalentNetAdapterId(
|
||||
_In_ PDV_NETADAPTER_ID Id1,
|
||||
_In_ PDV_NETADAPTER_ID Id2
|
||||
);
|
||||
|
||||
PDV_NETADAPTER_ENTRY CreateNetAdapterEntry(
|
||||
_In_ PDV_NETADAPTER_ID Id
|
||||
);
|
||||
|
||||
// dialog.c
|
||||
|
||||
typedef enum _NETADAPTER_DETAILS_CATEGORY
|
||||
{
|
||||
NETADAPTER_DETAILS_CATEGORY_ADAPTER,
|
||||
NETADAPTER_DETAILS_CATEGORY_UNICAST,
|
||||
NETADAPTER_DETAILS_CATEGORY_BROADCAST,
|
||||
NETADAPTER_DETAILS_CATEGORY_MULTICAST,
|
||||
NETADAPTER_DETAILS_CATEGORY_ERRORS
|
||||
} NETADAPTER_DETAILS_CATEGORY;
|
||||
|
||||
typedef enum _NETADAPTER_DETAILS_INDEX
|
||||
{
|
||||
NETADAPTER_DETAILS_INDEX_STATE,
|
||||
//NETADAPTER_DETAILS_INDEX_CONNECTIVITY,
|
||||
|
||||
NETADAPTER_DETAILS_INDEX_IPADDRESS,
|
||||
NETADAPTER_DETAILS_INDEX_SUBNET,
|
||||
NETADAPTER_DETAILS_INDEX_GATEWAY,
|
||||
NETADAPTER_DETAILS_INDEX_DNS,
|
||||
NETADAPTER_DETAILS_INDEX_DOMAIN,
|
||||
|
||||
NETADAPTER_DETAILS_INDEX_LINKSPEED,
|
||||
NETADAPTER_DETAILS_INDEX_SENT,
|
||||
NETADAPTER_DETAILS_INDEX_RECEIVED,
|
||||
NETADAPTER_DETAILS_INDEX_TOTAL,
|
||||
NETADAPTER_DETAILS_INDEX_SENDING,
|
||||
NETADAPTER_DETAILS_INDEX_RECEIVING,
|
||||
NETADAPTER_DETAILS_INDEX_UTILIZATION,
|
||||
|
||||
NETADAPTER_DETAILS_INDEX_UNICAST_SENTPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_UNICAST_RECVPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_UNICAST_TOTALPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_UNICAST_SENT,
|
||||
NETADAPTER_DETAILS_INDEX_UNICAST_RECEIVED,
|
||||
NETADAPTER_DETAILS_INDEX_UNICAST_TOTAL,
|
||||
//NETADAPTER_DETAILS_INDEX_UNICAST_SENDING,
|
||||
//NETADAPTER_DETAILS_INDEX_UNICAST_RECEIVING,
|
||||
//NETADAPTER_DETAILS_INDEX_UNICAST_UTILIZATION,
|
||||
|
||||
NETADAPTER_DETAILS_INDEX_BROADCAST_SENTPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_BROADCAST_RECVPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_BROADCAST_TOTALPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_BROADCAST_SENT,
|
||||
NETADAPTER_DETAILS_INDEX_BROADCAST_RECEIVED,
|
||||
NETADAPTER_DETAILS_INDEX_BROADCAST_TOTAL,
|
||||
|
||||
NETADAPTER_DETAILS_INDEX_MULTICAST_SENTPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_MULTICAST_RECVPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_MULTICAST_TOTALPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_MULTICAST_SENT,
|
||||
NETADAPTER_DETAILS_INDEX_MULTICAST_RECEIVED,
|
||||
NETADAPTER_DETAILS_INDEX_MULTICAST_TOTAL,
|
||||
|
||||
NETADAPTER_DETAILS_INDEX_ERRORS_SENTPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_ERRORS_RECVPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_ERRORS_TOTALPKTS,
|
||||
NETADAPTER_DETAILS_INDEX_ERRORS_SENT,
|
||||
NETADAPTER_DETAILS_INDEX_ERRORS_RECEIVED,
|
||||
NETADAPTER_DETAILS_INDEX_ERRORS_TOTAL
|
||||
} NETADAPTER_DETAILS_INDEX;
|
||||
|
||||
VOID ShowNetAdapterDetailsDialog(
|
||||
_In_ PDV_NETADAPTER_SYSINFO_CONTEXT Context
|
||||
);
|
||||
|
||||
// ndis.c
|
||||
|
||||
#define BITS_IN_ONE_BYTE 8
|
||||
#define NDIS_UNIT_OF_MEASUREMENT 100
|
||||
|
||||
// dmex: rev
|
||||
typedef ULONG (WINAPI* _GetInterfaceDescriptionFromGuid)(
|
||||
_Inout_ PGUID InterfaceGuid,
|
||||
_Out_opt_ PWSTR InterfaceDescription,
|
||||
_Inout_ PSIZE_T LengthAddress,
|
||||
PVOID Unknown1,
|
||||
PVOID Unknown2
|
||||
);
|
||||
|
||||
NTSTATUS NetworkAdapterCreateHandle(
|
||||
_Out_ PHANDLE DeviceHandle,
|
||||
_In_ PPH_STRING InterfaceGuid
|
||||
);
|
||||
|
||||
BOOLEAN NetworkAdapterQuerySupported(
|
||||
_In_ HANDLE DeviceHandle
|
||||
);
|
||||
|
||||
BOOLEAN NetworkAdapterQueryNdisVersion(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_opt_ PUINT MajorVersion,
|
||||
_Out_opt_ PUINT MinorVersion
|
||||
);
|
||||
|
||||
PPH_STRING NetworkAdapterQueryName(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ PPH_STRING InterfaceGuid
|
||||
);
|
||||
|
||||
NTSTATUS NetworkAdapterQueryStatistics(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PNDIS_STATISTICS_INFO Info
|
||||
);
|
||||
|
||||
NTSTATUS NetworkAdapterQueryLinkState(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PNDIS_LINK_STATE State
|
||||
);
|
||||
|
||||
BOOLEAN NetworkAdapterQueryMediaType(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PNDIS_PHYSICAL_MEDIUM Medium
|
||||
);
|
||||
|
||||
NTSTATUS NetworkAdapterQueryLinkSpeed(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PULONG64 LinkSpeed
|
||||
);
|
||||
|
||||
ULONG64 NetworkAdapterQueryValue(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ NDIS_OID OpCode
|
||||
);
|
||||
|
||||
BOOLEAN QueryInterfaceRowVista(
|
||||
_In_ PDV_NETADAPTER_ID Id,
|
||||
_Out_ PMIB_IF_ROW2 InterfaceRow
|
||||
);
|
||||
|
||||
BOOLEAN QueryInterfaceRowXP(
|
||||
_In_ PDV_NETADAPTER_ID Id,
|
||||
_Out_ PMIB_IFROW InterfaceRow
|
||||
);
|
||||
|
||||
// netoptions.c
|
||||
|
||||
INT_PTR CALLBACK NetworkAdapterOptionsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
);
|
||||
|
||||
// diskoptions.c
|
||||
|
||||
INT_PTR CALLBACK DiskDriveOptionsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
);
|
||||
|
||||
// disk.c
|
||||
|
||||
typedef struct _DV_DISK_ID
|
||||
{
|
||||
PPH_STRING DevicePath;
|
||||
} DV_DISK_ID, *PDV_DISK_ID;
|
||||
|
||||
typedef struct _DV_DISK_ENTRY
|
||||
{
|
||||
DV_DISK_ID Id;
|
||||
|
||||
PPH_STRING DiskName;
|
||||
PPH_STRING DiskIndexName;
|
||||
ULONG DiskIndex;
|
||||
|
||||
union
|
||||
{
|
||||
BOOLEAN BitField;
|
||||
struct
|
||||
{
|
||||
BOOLEAN UserReference : 1;
|
||||
BOOLEAN HaveFirstSample : 1;
|
||||
BOOLEAN DevicePresent : 1;
|
||||
BOOLEAN Spare : 5;
|
||||
};
|
||||
};
|
||||
|
||||
PH_CIRCULAR_BUFFER_ULONG64 ReadBuffer;
|
||||
PH_CIRCULAR_BUFFER_ULONG64 WriteBuffer;
|
||||
|
||||
PH_UINT64_DELTA BytesReadDelta;
|
||||
PH_UINT64_DELTA BytesWrittenDelta;
|
||||
PH_UINT64_DELTA ReadTimeDelta;
|
||||
PH_UINT64_DELTA WriteTimeDelta;
|
||||
PH_UINT64_DELTA IdleTimeDelta;
|
||||
PH_UINT32_DELTA ReadCountDelta;
|
||||
PH_UINT32_DELTA WriteCountDelta;
|
||||
PH_UINT64_DELTA QueryTimeDelta;
|
||||
|
||||
FLOAT ResponseTime;
|
||||
FLOAT ActiveTime;
|
||||
ULONG QueueDepth;
|
||||
ULONG SplitCount;
|
||||
} DV_DISK_ENTRY, *PDV_DISK_ENTRY;
|
||||
|
||||
typedef struct _DV_DISK_SYSINFO_CONTEXT
|
||||
{
|
||||
PDV_DISK_ENTRY DiskEntry;
|
||||
PPH_STRING SectionName;
|
||||
|
||||
HWND WindowHandle;
|
||||
HWND PanelWindowHandle;
|
||||
HWND GraphHandle;
|
||||
|
||||
PPH_SYSINFO_SECTION SysinfoSection;
|
||||
PH_GRAPH_STATE GraphState;
|
||||
PH_LAYOUT_MANAGER LayoutManager;
|
||||
} DV_DISK_SYSINFO_CONTEXT, *PDV_DISK_SYSINFO_CONTEXT;
|
||||
|
||||
typedef struct _DV_DISK_OPTIONS_CONTEXT
|
||||
{
|
||||
HWND ListViewHandle;
|
||||
//HIMAGELIST ImageList;
|
||||
BOOLEAN OptionsChanged;
|
||||
BOOLEAN EnumeratingDisks;
|
||||
} DV_DISK_OPTIONS_CONTEXT, *PDV_DISK_OPTIONS_CONTEXT;
|
||||
|
||||
VOID DiskDrivesInitialize(VOID);
|
||||
VOID DiskDrivesLoadList(VOID);
|
||||
VOID DiskDrivesUpdate(VOID);
|
||||
|
||||
VOID DiskDriveUpdateDeviceInfo(
|
||||
_In_opt_ HANDLE DeviceHandle,
|
||||
_In_ PDV_DISK_ENTRY DiskEntry
|
||||
);
|
||||
|
||||
VOID InitializeDiskId(
|
||||
_Out_ PDV_DISK_ID Id,
|
||||
_In_ PPH_STRING DevicePath
|
||||
);
|
||||
VOID CopyDiskId(
|
||||
_Out_ PDV_DISK_ID Destination,
|
||||
_In_ PDV_DISK_ID Source
|
||||
);
|
||||
VOID DeleteDiskId(
|
||||
_Inout_ PDV_DISK_ID Id
|
||||
);
|
||||
BOOLEAN EquivalentDiskId(
|
||||
_In_ PDV_DISK_ID Id1,
|
||||
_In_ PDV_DISK_ID Id2
|
||||
);
|
||||
PDV_DISK_ENTRY CreateDiskEntry(
|
||||
_In_ PDV_DISK_ID Id
|
||||
);
|
||||
|
||||
// diskdetails.c
|
||||
|
||||
VOID ShowDiskDriveDetailsDialog(
|
||||
_In_ PDV_DISK_SYSINFO_CONTEXT Context
|
||||
);
|
||||
|
||||
// disknotify.c
|
||||
|
||||
VOID AddRemoveDeviceChangeCallback(
|
||||
VOID
|
||||
);
|
||||
|
||||
// storage.c
|
||||
|
||||
NTSTATUS DiskDriveCreateHandle(
|
||||
_Out_ PHANDLE DeviceHandle,
|
||||
_In_ PPH_STRING DevicePath
|
||||
);
|
||||
|
||||
PPH_STRING DiskDriveQueryDosMountPoints(
|
||||
_In_ ULONG DeviceNumber
|
||||
);
|
||||
|
||||
BOOLEAN DiskDriveQueryDeviceInformation(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_opt_ PPH_STRING* DiskVendor,
|
||||
_Out_opt_ PPH_STRING* DiskModel,
|
||||
_Out_opt_ PPH_STRING* DiskRevision,
|
||||
_Out_opt_ PPH_STRING* DiskSerial
|
||||
);
|
||||
|
||||
NTSTATUS DiskDriveQueryDeviceTypeAndNumber(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_opt_ PULONG DeviceNumber,
|
||||
_Out_opt_ DEVICE_TYPE* DeviceType
|
||||
);
|
||||
|
||||
NTSTATUS DiskDriveQueryStatistics(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PDISK_PERFORMANCE Info
|
||||
);
|
||||
|
||||
PPH_STRING DiskDriveQueryGeometry(
|
||||
_In_ HANDLE DeviceHandle
|
||||
);
|
||||
|
||||
BOOLEAN DiskDriveQueryImminentFailure(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PPH_LIST* DiskSmartAttributes
|
||||
);
|
||||
|
||||
typedef struct _DISK_HANDLE_ENTRY
|
||||
{
|
||||
WCHAR DeviceLetter;
|
||||
HANDLE DeviceHandle;
|
||||
} DISK_HANDLE_ENTRY, *PDISK_HANDLE_ENTRY;
|
||||
|
||||
PPH_LIST DiskDriveQueryMountPointHandles(
|
||||
_In_ ULONG DeviceNumber
|
||||
);
|
||||
|
||||
typedef struct _NTFS_FILESYSTEM_STATISTICS
|
||||
{
|
||||
FILESYSTEM_STATISTICS FileSystemStatistics;
|
||||
NTFS_STATISTICS NtfsStatistics;
|
||||
} NTFS_FILESYSTEM_STATISTICS, *PNTFS_FILESYSTEM_STATISTICS;
|
||||
|
||||
typedef struct _FAT_FILESYSTEM_STATISTICS
|
||||
{
|
||||
FILESYSTEM_STATISTICS FileSystemStatistics;
|
||||
NTFS_STATISTICS FatStatistics;
|
||||
} FAT_FILESYSTEM_STATISTICS, *PFAT_FILESYSTEM_STATISTICS;
|
||||
|
||||
typedef struct _EXFAT_FILESYSTEM_STATISTICS
|
||||
{
|
||||
FILESYSTEM_STATISTICS FileSystemStatistics;
|
||||
EXFAT_STATISTICS ExFatStatistics;
|
||||
} EXFAT_FILESYSTEM_STATISTICS, *PEXFAT_FILESYSTEM_STATISTICS;
|
||||
|
||||
BOOLEAN DiskDriveQueryFileSystemInfo(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ USHORT* FileSystemType,
|
||||
_Out_ PVOID* FileSystemStatistics
|
||||
);
|
||||
|
||||
typedef struct _NTFS_VOLUME_INFO
|
||||
{
|
||||
NTFS_VOLUME_DATA_BUFFER VolumeData;
|
||||
NTFS_EXTENDED_VOLUME_DATA ExtendedVolumeData;
|
||||
} NTFS_VOLUME_INFO, *PNTFS_VOLUME_INFO;
|
||||
|
||||
BOOLEAN DiskDriveQueryNtfsVolumeInfo(
|
||||
_In_ HANDLE DosDeviceHandle,
|
||||
_Out_ PNTFS_VOLUME_INFO VolumeInfo
|
||||
);
|
||||
|
||||
BOOLEAN DiskDriveQueryRefsVolumeInfo(
|
||||
_In_ HANDLE DosDeviceHandle,
|
||||
_Out_ PREFS_VOLUME_DATA_BUFFER VolumeInfo
|
||||
);
|
||||
|
||||
NTSTATUS DiskDriveQueryVolumeInformation(
|
||||
_In_ HANDLE DosDeviceHandle,
|
||||
_Out_ PFILE_FS_VOLUME_INFORMATION* VolumeInfo
|
||||
);
|
||||
|
||||
NTSTATUS DiskDriveQueryVolumeAttributes(
|
||||
_In_ HANDLE DosDeviceHandle,
|
||||
_Out_ PFILE_FS_ATTRIBUTE_INFORMATION* AttributeInfo
|
||||
);
|
||||
|
||||
typedef enum _SMART_ATTRIBUTE_ID
|
||||
{
|
||||
SMART_ATTRIBUTE_ID_READ_ERROR_RATE = 0x01,
|
||||
SMART_ATTRIBUTE_ID_THROUGHPUT_PERFORMANCE = 0x02,
|
||||
SMART_ATTRIBUTE_ID_SPIN_UP_TIME = 0x03,
|
||||
SMART_ATTRIBUTE_ID_START_STOP_COUNT = 0x04,
|
||||
SMART_ATTRIBUTE_ID_REALLOCATED_SECTORS_COUNT = 0x05,
|
||||
SMART_ATTRIBUTE_ID_READ_CHANNEL_MARGIN = 0x06,
|
||||
SMART_ATTRIBUTE_ID_SEEK_ERROR_RATE = 0x07,
|
||||
SMART_ATTRIBUTE_ID_SEEK_TIME_PERFORMANCE = 0x08,
|
||||
SMART_ATTRIBUTE_ID_POWER_ON_HOURS = 0x09,
|
||||
SMART_ATTRIBUTE_ID_SPIN_RETRY_COUNT = 0x0A,
|
||||
SMART_ATTRIBUTE_ID_CALIBRATION_RETRY_COUNT = 0x0B,
|
||||
SMART_ATTRIBUTE_ID_POWER_CYCLE_COUNT = 0x0C,
|
||||
SMART_ATTRIBUTE_ID_SOFT_READ_ERROR_RATE = 0x0D,
|
||||
// Unknown values 14-182
|
||||
SMART_ATTRIBUTE_ID_SATA_DOWNSHIFT_ERROR_COUNT = 0xB7,
|
||||
SMART_ATTRIBUTE_ID_END_TO_END_ERROR = 0xB8,
|
||||
SMART_ATTRIBUTE_ID_HEAD_STABILITY = 0xB9,
|
||||
SMART_ATTRIBUTE_ID_INDUCED_OP_VIBRATION_DETECTION = 0xBA,
|
||||
SMART_ATTRIBUTE_ID_REPORTED_UNCORRECTABLE_ERRORS = 0xBB,
|
||||
SMART_ATTRIBUTE_ID_COMMAND_TIMEOUT = 0xBC,
|
||||
SMART_ATTRIBUTE_ID_HIGH_FLY_WRITES = 0xBD,
|
||||
SMART_ATTRIBUTE_ID_TEMPERATURE_DIFFERENCE_FROM_100 = 0xBE, // AirflowTemperature
|
||||
SMART_ATTRIBUTE_ID_GSENSE_ERROR_RATE = 0xBF,
|
||||
SMART_ATTRIBUTE_ID_POWER_OFF_RETRACT_COUNT = 0xC0,
|
||||
SMART_ATTRIBUTE_ID_LOAD_CYCLE_COUNT = 0xC1,
|
||||
SMART_ATTRIBUTE_ID_TEMPERATURE = 0xC2,
|
||||
SMART_ATTRIBUTE_ID_HARDWARE_ECC_RECOVERED = 0xC3,
|
||||
SMART_ATTRIBUTE_ID_REALLOCATION_EVENT_COUNT = 0xC4,
|
||||
SMART_ATTRIBUTE_ID_CURRENT_PENDING_SECTOR_COUNT = 0xC5,
|
||||
SMART_ATTRIBUTE_ID_UNCORRECTABLE_SECTOR_COUNT = 0xC6,
|
||||
SMART_ATTRIBUTE_ID_ULTRADMA_CRC_ERROR_COUNT = 0xC7,
|
||||
SMART_ATTRIBUTE_ID_MULTI_ZONE_ERROR_RATE = 0xC8,
|
||||
SMART_ATTRIBUTE_ID_OFFTRACK_SOFT_READ_ERROR_RATE = 0xC9,
|
||||
SMART_ATTRIBUTE_ID_DATA_ADDRESS_MARK_ERRORS = 0xCA,
|
||||
SMART_ATTRIBUTE_ID_RUN_OUT_CANCEL = 0xCB,
|
||||
SMART_ATTRIBUTE_ID_SOFT_ECC_CORRECTION = 0xCC,
|
||||
SMART_ATTRIBUTE_ID_THERMAL_ASPERITY_RATE_TAR = 0xCD,
|
||||
SMART_ATTRIBUTE_ID_FLYING_HEIGHT = 0xCE,
|
||||
SMART_ATTRIBUTE_ID_SPIN_HIGH_CURRENT = 0xCF,
|
||||
SMART_ATTRIBUTE_ID_SPIN_BUZZ = 0xD0,
|
||||
SMART_ATTRIBUTE_ID_OFFLINE_SEEK_PERFORMANCE = 0xD1,
|
||||
SMART_ATTRIBUTE_ID_VIBRATION_DURING_WRITE = 0xD3,
|
||||
SMART_ATTRIBUTE_ID_SHOCK_DURING_WRITE = 0xD4,
|
||||
SMART_ATTRIBUTE_ID_DISK_SHIFT = 0xDC,
|
||||
SMART_ATTRIBUTE_ID_GSENSE_ERROR_RATE_ALT = 0xDD,
|
||||
SMART_ATTRIBUTE_ID_LOADED_HOURS = 0xDE,
|
||||
SMART_ATTRIBUTE_ID_LOAD_UNLOAD_RETRY_COUNT = 0xDF,
|
||||
SMART_ATTRIBUTE_ID_LOAD_FRICTION = 0xE0,
|
||||
SMART_ATTRIBUTE_ID_LOAD_UNLOAD_CYCLE_COUNT = 0xE1,
|
||||
SMART_ATTRIBUTE_ID_LOAD_IN_TIME = 0xE2,
|
||||
SMART_ATTRIBUTE_ID_TORQUE_AMPLIFICATION_COUNT = 0xE3,
|
||||
SMART_ATTRIBUTE_ID_POWER_OFF_RETTRACT_CYCLE = 0xE4,
|
||||
// Unknown values 229
|
||||
SMART_ATTRIBUTE_ID_GMR_HEAD_AMPLITUDE = 0xE6,
|
||||
SMART_ATTRIBUTE_ID_DRIVE_TEMPERATURE = 0xE7,
|
||||
// Unknown values 232-239
|
||||
SMART_ATTRIBUTE_ID_HEAD_FLYING_HOURS = 0xF0,
|
||||
SMART_ATTRIBUTE_ID_TOTAL_LBA_WRITTEN = 0xF1,
|
||||
SMART_ATTRIBUTE_ID_TOTAL_LBA_READ = 0xF2,
|
||||
// Unknown values 243-249
|
||||
SMART_ATTRIBUTE_ID_READ_ERROR_RETY_RATE = 0xFA,
|
||||
// Unknown values 251-253
|
||||
SMART_ATTRIBUTE_ID_FREE_FALL_PROTECTION = 0xFE,
|
||||
} SMART_ATTRIBUTE_ID;
|
||||
|
||||
|
||||
#define SMART_HEADER_SIZE 2
|
||||
|
||||
#include <pshpack1.h>
|
||||
typedef struct _SMART_ATTRIBUTE
|
||||
{
|
||||
BYTE Id;
|
||||
USHORT Flags;
|
||||
BYTE CurrentValue;
|
||||
BYTE WorstValue;
|
||||
BYTE RawValue[6];
|
||||
BYTE Reserved;
|
||||
} SMART_ATTRIBUTE, *PSMART_ATTRIBUTE;
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct _SMART_ATTRIBUTES
|
||||
{
|
||||
SMART_ATTRIBUTE_ID AttributeId;
|
||||
UINT CurrentValue;
|
||||
UINT WorstValue;
|
||||
UINT RawValue;
|
||||
|
||||
// Pre-fail/Advisory bit
|
||||
// This bit is applicable only when the value of this attribute is less than or equal to its threshhold.
|
||||
// 0 : Advisory: The device has exceeded its intended design life period.
|
||||
// 1 : Pre-failure notification : Failure is predicted within 24 hours.
|
||||
BOOLEAN Advisory;
|
||||
BOOLEAN FailureImminent;
|
||||
|
||||
// Online data collection bit
|
||||
// 0 : This value of this attribute is only updated during offline activities.
|
||||
// 1 : The value of this attribute is updated during both normal operation and offline activities.
|
||||
BOOLEAN OnlineDataCollection;
|
||||
|
||||
// TRUE: This attribute characterizes a performance aspect of the drive,
|
||||
// degradation of which may indicate imminent drive failure, such as data throughput, seektimes, spin up time, etc.
|
||||
BOOLEAN Performance;
|
||||
|
||||
// TRUE: This attribute is based on the expected, non-fatal errors that are inherent in disk drives,
|
||||
// increases in which may indicate imminent drive failure, such as ECC errors, seek errors, etc.
|
||||
BOOLEAN ErrorRate;
|
||||
|
||||
// TRUE: This attribute counts events, of which an excessive number of which may
|
||||
// indicate imminent drive failure, such as number of re-allocated sectors, etc.
|
||||
BOOLEAN EventCount;
|
||||
|
||||
// TRUE: This type is used to specify an attribute that is collected and saved by the drive automatically.
|
||||
BOOLEAN SelfPreserving;
|
||||
} SMART_ATTRIBUTES, *PSMART_ATTRIBUTES;
|
||||
|
||||
PWSTR SmartAttributeGetText(
|
||||
_In_ SMART_ATTRIBUTE_ID AttributeId
|
||||
);
|
||||
|
||||
PWSTR SmartAttributeGetDescription(
|
||||
_In_ SMART_ATTRIBUTE_ID AttributeId
|
||||
);
|
||||
|
||||
// diskgraph.c
|
||||
|
||||
VOID DiskDriveSysInfoInitializing(
|
||||
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers,
|
||||
_In_ _Assume_refs_(1) PDV_DISK_ENTRY DiskEntry
|
||||
);
|
||||
|
||||
// netgraph.c
|
||||
|
||||
VOID NetAdapterSysInfoInitializing(
|
||||
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers,
|
||||
_In_ _Assume_refs_(1) PDV_NETADAPTER_ENTRY AdapterEntry
|
||||
);
|
||||
|
||||
#ifdef _NV_GPU_BUILD
|
||||
// Graphics
|
||||
extern BOOLEAN NvApiInitialized;
|
||||
extern ULONG GpuMemoryLimit;
|
||||
extern FLOAT GpuCurrentGpuUsage;
|
||||
extern FLOAT GpuCurrentCoreUsage;
|
||||
extern FLOAT GpuCurrentBusUsage;
|
||||
extern ULONG GpuCurrentMemUsage;
|
||||
extern ULONG GpuCurrentMemSharedUsage;
|
||||
extern ULONG GpuCurrentCoreTemp;
|
||||
extern ULONG GpuCurrentBoardTemp;
|
||||
extern ULONG GpuCurrentCoreClock;
|
||||
extern ULONG GpuCurrentMemoryClock;
|
||||
extern ULONG GpuCurrentShaderClock;
|
||||
extern ULONG GpuCurrentVoltage;
|
||||
extern PH_CIRCULAR_BUFFER_FLOAT GpuUtilizationHistory;
|
||||
extern PH_CIRCULAR_BUFFER_ULONG GpuMemoryHistory;
|
||||
extern PH_CIRCULAR_BUFFER_FLOAT GpuBoardHistory;
|
||||
extern PH_CIRCULAR_BUFFER_FLOAT GpuBusHistory;
|
||||
|
||||
VOID NvGpuSysInfoInitializing(
|
||||
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers
|
||||
);
|
||||
|
||||
VOID NvApiInitialize(VOID);
|
||||
BOOLEAN DestroyNvApi(VOID);
|
||||
PPH_STRING NvGpuQueryDriverVersion(VOID);
|
||||
PPH_STRING NvGpuQueryVbiosVersionString(VOID);
|
||||
PPH_STRING NvGpuQueryName(VOID);
|
||||
PPH_STRING NvGpuQueryShortName(VOID);
|
||||
PPH_STRING NvGpuQueryRevision(VOID);
|
||||
PPH_STRING NvGpuQueryRamType(VOID);
|
||||
PPH_STRING NvGpuQueryFoundry(VOID);
|
||||
PPH_STRING NvGpuQueryDeviceId(VOID);
|
||||
PPH_STRING NvGpuQueryRopsCount(VOID);
|
||||
PPH_STRING NvGpuQueryShaderCount(VOID);
|
||||
PPH_STRING NvGpuQueryPciInfo(VOID);
|
||||
PPH_STRING NvGpuQueryBusWidth(VOID);
|
||||
PPH_STRING NvGpuQueryPcbValue(VOID);
|
||||
PPH_STRING NvGpuQueryDriverSettings(VOID);
|
||||
PPH_STRING NvGpuQueryFanSpeed(VOID);
|
||||
BOOLEAN NvGpuDriverIsWHQL(VOID);
|
||||
VOID NvGpuUpdate(VOID);
|
||||
#endif
|
||||
|
||||
#endif _DEVICES_H_
|
||||
303
plugins/HardwareDevices/disk.c
Normal file
303
plugins/HardwareDevices/disk.c
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
VOID DiskEntryDeleteProcedure(
|
||||
_In_ PVOID Object,
|
||||
_In_ ULONG Flags
|
||||
)
|
||||
{
|
||||
PDV_DISK_ENTRY entry = Object;
|
||||
|
||||
PhAcquireQueuedLockExclusive(&DiskDrivesListLock);
|
||||
PhRemoveItemList(DiskDrivesList, PhFindItemList(DiskDrivesList, entry));
|
||||
PhReleaseQueuedLockExclusive(&DiskDrivesListLock);
|
||||
|
||||
DeleteDiskId(&entry->Id);
|
||||
PhClearReference(&entry->DiskName);
|
||||
|
||||
PhDeleteCircularBuffer_ULONG64(&entry->ReadBuffer);
|
||||
PhDeleteCircularBuffer_ULONG64(&entry->WriteBuffer);
|
||||
|
||||
AddRemoveDeviceChangeCallback();
|
||||
}
|
||||
|
||||
VOID DiskDrivesInitialize(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
DiskDrivesList = PhCreateList(1);
|
||||
DiskDriveEntryType = PhCreateObjectType(L"DiskDriveEntry", 0, DiskEntryDeleteProcedure);
|
||||
}
|
||||
|
||||
VOID DiskDrivesUpdate(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
static ULONG runCount = 0; // MUST keep in sync with runCount in process provider
|
||||
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
HANDLE deviceHandle;
|
||||
PDV_DISK_ENTRY entry;
|
||||
|
||||
entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (NT_SUCCESS(DiskDriveCreateHandle(&deviceHandle, entry->Id.DevicePath)))
|
||||
{
|
||||
DISK_PERFORMANCE diskPerformance;
|
||||
|
||||
if (NT_SUCCESS(DiskDriveQueryStatistics(deviceHandle, &diskPerformance)))
|
||||
{
|
||||
ULONG64 readTime;
|
||||
ULONG64 writeTime;
|
||||
ULONG64 idleTime;
|
||||
ULONG readCount;
|
||||
ULONG writeCount;
|
||||
ULONG64 queryTime;
|
||||
|
||||
PhUpdateDelta(&entry->BytesReadDelta, diskPerformance.BytesRead.QuadPart);
|
||||
PhUpdateDelta(&entry->BytesWrittenDelta, diskPerformance.BytesWritten.QuadPart);
|
||||
PhUpdateDelta(&entry->ReadTimeDelta, diskPerformance.ReadTime.QuadPart);
|
||||
PhUpdateDelta(&entry->WriteTimeDelta, diskPerformance.WriteTime.QuadPart);
|
||||
PhUpdateDelta(&entry->IdleTimeDelta, diskPerformance.IdleTime.QuadPart);
|
||||
PhUpdateDelta(&entry->ReadCountDelta, diskPerformance.ReadCount);
|
||||
PhUpdateDelta(&entry->WriteCountDelta, diskPerformance.WriteCount);
|
||||
PhUpdateDelta(&entry->QueryTimeDelta, diskPerformance.QueryTime.QuadPart);
|
||||
|
||||
readTime = entry->ReadTimeDelta.Delta;
|
||||
writeTime = entry->WriteTimeDelta.Delta;
|
||||
idleTime = entry->IdleTimeDelta.Delta;
|
||||
readCount = entry->ReadCountDelta.Delta;
|
||||
writeCount = entry->WriteCountDelta.Delta;
|
||||
queryTime = entry->QueryTimeDelta.Delta;
|
||||
|
||||
if (readCount + writeCount != 0)
|
||||
entry->ResponseTime = ((FLOAT)readTime + (FLOAT)writeTime) / (readCount + writeCount);
|
||||
else
|
||||
entry->ResponseTime = 0;
|
||||
|
||||
if (queryTime != 0)
|
||||
entry->ActiveTime = (FLOAT)(queryTime - idleTime) / queryTime * 100;
|
||||
else
|
||||
entry->ActiveTime = 0.0f;
|
||||
|
||||
if (entry->ActiveTime > 100.f)
|
||||
entry->ActiveTime = 0.f;
|
||||
if (entry->ActiveTime < 0.f)
|
||||
entry->ActiveTime = 0.f;
|
||||
|
||||
entry->QueueDepth = diskPerformance.QueueDepth;
|
||||
entry->SplitCount = diskPerformance.SplitCount;
|
||||
entry->DiskIndex = diskPerformance.StorageDeviceNumber;
|
||||
entry->DevicePresent = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disk has been disconnected or dismounted.
|
||||
PhInitializeDelta(&entry->BytesReadDelta);
|
||||
PhInitializeDelta(&entry->BytesWrittenDelta);
|
||||
PhInitializeDelta(&entry->ReadTimeDelta);
|
||||
PhInitializeDelta(&entry->WriteTimeDelta);
|
||||
PhInitializeDelta(&entry->IdleTimeDelta);
|
||||
PhInitializeDelta(&entry->ReadCountDelta);
|
||||
PhInitializeDelta(&entry->WriteCountDelta);
|
||||
PhInitializeDelta(&entry->QueryTimeDelta);
|
||||
|
||||
entry->ResponseTime = 0;
|
||||
entry->ActiveTime = 0.0f;
|
||||
entry->QueueDepth = 0;
|
||||
entry->SplitCount = 0;
|
||||
entry->DiskIndex = ULONG_MAX;
|
||||
entry->DevicePresent = FALSE;
|
||||
PhClearReference(&entry->DiskIndexName);
|
||||
}
|
||||
|
||||
if (runCount > 1)
|
||||
{
|
||||
// Delay the first query for the disk name, index and type.
|
||||
// 1) This information is not needed until the user opens the sysinfo window.
|
||||
// 2) Try not to query this information while opening the sysinfo window (e.g. delay).
|
||||
// 3) Try not to query this information during startup (e.g. delay).
|
||||
//
|
||||
// Note: If the user opens the Sysinfo window before we query the disk info,
|
||||
// we have a second check in diskgraph.c that queries the information on demand.
|
||||
DiskDriveUpdateDeviceInfo(deviceHandle, entry);
|
||||
}
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disk has been disconnected or dismounted.
|
||||
PhInitializeDelta(&entry->BytesReadDelta);
|
||||
PhInitializeDelta(&entry->BytesWrittenDelta);
|
||||
PhInitializeDelta(&entry->ReadTimeDelta);
|
||||
PhInitializeDelta(&entry->WriteTimeDelta);
|
||||
PhInitializeDelta(&entry->IdleTimeDelta);
|
||||
PhInitializeDelta(&entry->ReadCountDelta);
|
||||
PhInitializeDelta(&entry->WriteCountDelta);
|
||||
PhInitializeDelta(&entry->QueryTimeDelta);
|
||||
|
||||
entry->ResponseTime = 0;
|
||||
entry->ActiveTime = 0.0f;
|
||||
entry->QueueDepth = 0;
|
||||
entry->SplitCount = 0;
|
||||
entry->DiskIndex = ULONG_MAX;
|
||||
entry->DevicePresent = FALSE;
|
||||
PhClearReference(&entry->DiskIndexName);
|
||||
}
|
||||
|
||||
if (!entry->HaveFirstSample)
|
||||
{
|
||||
// The first sample must be zero.
|
||||
entry->BytesReadDelta.Delta = 0;
|
||||
entry->BytesWrittenDelta.Delta = 0;
|
||||
entry->HaveFirstSample = TRUE;
|
||||
}
|
||||
|
||||
if (runCount != 0)
|
||||
{
|
||||
PhAddItemCircularBuffer_ULONG64(&entry->ReadBuffer, entry->BytesReadDelta.Delta);
|
||||
PhAddItemCircularBuffer_ULONG64(&entry->WriteBuffer, entry->BytesWrittenDelta.Delta);
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
runCount++;
|
||||
}
|
||||
|
||||
VOID DiskDriveUpdateDeviceInfo(
|
||||
_In_opt_ HANDLE DeviceHandle,
|
||||
_In_ PDV_DISK_ENTRY DiskEntry
|
||||
)
|
||||
{
|
||||
if (!DiskEntry->DiskName || DiskEntry->DiskIndex == ULONG_MAX)
|
||||
{
|
||||
HANDLE deviceHandle = NULL;
|
||||
|
||||
if (!DeviceHandle)
|
||||
{
|
||||
DiskDriveCreateHandle(&deviceHandle, DiskEntry->Id.DevicePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceHandle = DeviceHandle;
|
||||
}
|
||||
|
||||
if (deviceHandle)
|
||||
{
|
||||
if (!DiskEntry->DiskName)
|
||||
{
|
||||
PPH_STRING diskName = NULL;
|
||||
|
||||
if (NT_SUCCESS(DiskDriveQueryDeviceInformation(deviceHandle, NULL, &diskName, NULL, NULL)))
|
||||
{
|
||||
DiskEntry->DiskName = diskName;
|
||||
}
|
||||
}
|
||||
|
||||
if (DiskEntry->DiskIndex == ULONG_MAX)
|
||||
{
|
||||
ULONG diskIndex = ULONG_MAX; // Note: Do not initialize to zero.
|
||||
|
||||
if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(deviceHandle, &diskIndex, NULL)))
|
||||
{
|
||||
DiskEntry->DiskIndex = diskIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DeviceHandle)
|
||||
{
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID InitializeDiskId(
|
||||
_Out_ PDV_DISK_ID Id,
|
||||
_In_ PPH_STRING DevicePath
|
||||
)
|
||||
{
|
||||
PhSetReference(&Id->DevicePath, DevicePath);
|
||||
}
|
||||
|
||||
VOID CopyDiskId(
|
||||
_Out_ PDV_DISK_ID Destination,
|
||||
_In_ PDV_DISK_ID Source
|
||||
)
|
||||
{
|
||||
InitializeDiskId(
|
||||
Destination,
|
||||
Source->DevicePath
|
||||
);
|
||||
}
|
||||
|
||||
VOID DeleteDiskId(
|
||||
_Inout_ PDV_DISK_ID Id
|
||||
)
|
||||
{
|
||||
PhClearReference(&Id->DevicePath);
|
||||
}
|
||||
|
||||
BOOLEAN EquivalentDiskId(
|
||||
_In_ PDV_DISK_ID Id1,
|
||||
_In_ PDV_DISK_ID Id2
|
||||
)
|
||||
{
|
||||
return PhEqualString(Id1->DevicePath, Id2->DevicePath, TRUE);
|
||||
}
|
||||
|
||||
PDV_DISK_ENTRY CreateDiskEntry(
|
||||
_In_ PDV_DISK_ID Id
|
||||
)
|
||||
{
|
||||
PDV_DISK_ENTRY entry;
|
||||
|
||||
entry = PhCreateObject(sizeof(DV_DISK_ENTRY), DiskDriveEntryType);
|
||||
memset(entry, 0, sizeof(DV_DISK_ENTRY));
|
||||
|
||||
entry->DiskIndex = ULONG_MAX;
|
||||
CopyDiskId(&entry->Id, Id);
|
||||
|
||||
PhInitializeCircularBuffer_ULONG64(&entry->ReadBuffer, PhGetIntegerSetting(L"SampleCount"));
|
||||
PhInitializeCircularBuffer_ULONG64(&entry->WriteBuffer, PhGetIntegerSetting(L"SampleCount"));
|
||||
|
||||
PhAcquireQueuedLockExclusive(&DiskDrivesListLock);
|
||||
PhAddItemList(DiskDrivesList, entry);
|
||||
PhReleaseQueuedLockExclusive(&DiskDrivesListLock);
|
||||
|
||||
AddRemoveDeviceChangeCallback();
|
||||
|
||||
return entry;
|
||||
}
|
||||
1092
plugins/HardwareDevices/diskdetails.c
Normal file
1092
plugins/HardwareDevices/diskdetails.c
Normal file
File diff suppressed because it is too large
Load Diff
504
plugins/HardwareDevices/diskgraph.c
Normal file
504
plugins/HardwareDevices/diskgraph.c
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
VOID DiskDriveUpdateGraphs(
|
||||
_Inout_ PDV_DISK_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
Context->GraphState.Valid = FALSE;
|
||||
Context->GraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(Context->GraphHandle, 1);
|
||||
Graph_Draw(Context->GraphHandle);
|
||||
Graph_UpdateTooltip(Context->GraphHandle);
|
||||
InvalidateRect(Context->GraphHandle, NULL, FALSE);
|
||||
}
|
||||
|
||||
VOID DiskDriveUpdatePanel(
|
||||
_Inout_ PDV_DISK_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_BREAD, PhaFormatSize(Context->DiskEntry->BytesReadDelta.Value, -1)->Buffer);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_BWRITE, PhaFormatSize(Context->DiskEntry->BytesWrittenDelta.Value, -1)->Buffer);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_BTOTAL, PhaFormatSize(Context->DiskEntry->BytesReadDelta.Value + Context->DiskEntry->BytesWrittenDelta.Value, -1)->Buffer);
|
||||
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_ACTIVE,
|
||||
PhaFormatString(L"%.0f%%", Context->DiskEntry->ActiveTime)->Buffer
|
||||
);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_RESPONSETIME,
|
||||
PhaFormatString(L"%.1f ms", Context->DiskEntry->ResponseTime / PH_TICKS_PER_MS)->Buffer
|
||||
);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_QUEUELENGTH,
|
||||
PhaFormatString(L"%lu", Context->DiskEntry->QueueDepth)->Buffer
|
||||
);
|
||||
}
|
||||
|
||||
VOID UpdateDiskDriveDialog(
|
||||
_Inout_ PDV_DISK_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
if (Context->DiskEntry->DiskName)
|
||||
SetDlgItemText(Context->WindowHandle, IDC_DISKNAME, Context->DiskEntry->DiskName->Buffer);
|
||||
else
|
||||
SetDlgItemText(Context->WindowHandle, IDC_DISKNAME, L"Unknown disk");
|
||||
|
||||
if (Context->DiskEntry->DiskIndexName)
|
||||
SetDlgItemText(Context->WindowHandle, IDC_DISKMOUNTPATH, Context->DiskEntry->DiskIndexName->Buffer);
|
||||
else
|
||||
SetDlgItemText(Context->WindowHandle, IDC_DISKMOUNTPATH, L"Unknown disk");
|
||||
|
||||
DiskDriveUpdateGraphs(Context);
|
||||
DiskDriveUpdatePanel(Context);
|
||||
}
|
||||
|
||||
VOID UpdateDiskIndexText(
|
||||
_Inout_ PDV_DISK_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
// If our delayed lookup of the disk name, index and type hasn't fired then query the information now.
|
||||
DiskDriveUpdateDeviceInfo(NULL, Context->DiskEntry);
|
||||
|
||||
// TODO: Move into DiskDriveUpdateDeviceInfo.
|
||||
if (Context->DiskEntry->DiskIndex != ULONG_MAX && !Context->DiskEntry->DiskIndexName)
|
||||
{
|
||||
// Query the disk DosDevices mount points.
|
||||
PPH_STRING diskMountPoints = PH_AUTO_T(PH_STRING, DiskDriveQueryDosMountPoints(Context->DiskEntry->DiskIndex));
|
||||
|
||||
if (!PhIsNullOrEmptyString(diskMountPoints))
|
||||
{
|
||||
PhMoveReference(&Context->DiskEntry->DiskIndexName, PhFormatString(
|
||||
L"Disk %lu (%s)",
|
||||
Context->DiskEntry->DiskIndex,
|
||||
diskMountPoints->Buffer
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
PhMoveReference(&Context->DiskEntry->DiskIndexName, PhFormatString(
|
||||
L"Disk %lu",
|
||||
Context->DiskEntry->DiskIndex
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DiskDrivePanelDialogProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_DISK_SYSINFO_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_DISK_SYSINFO_CONTEXT)lParam;
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_DISK_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_NCDESTROY)
|
||||
{
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
case IDC_DETAILS:
|
||||
ShowDiskDriveDetailsDialog(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DiskDriveDialogProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_DISK_SYSINFO_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_DISK_SYSINFO_CONTEXT)lParam;
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_DISK_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
PhDeleteGraphState(&context->GraphState);
|
||||
|
||||
if (context->GraphHandle)
|
||||
DestroyWindow(context->GraphHandle);
|
||||
|
||||
if (context->PanelWindowHandle)
|
||||
DestroyWindow(context->PanelWindowHandle);
|
||||
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
PPH_LAYOUT_ITEM graphItem;
|
||||
PPH_LAYOUT_ITEM panelItem;
|
||||
|
||||
context->WindowHandle = hwndDlg;
|
||||
|
||||
PhInitializeGraphState(&context->GraphState);
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_DISKMOUNTPATH), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_DISKNAME), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_TOP | PH_LAYOUT_FORCE_INVALIDATE);
|
||||
graphItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GRAPH_LAYOUT), NULL, PH_ANCHOR_ALL);
|
||||
panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LAYOUT), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
|
||||
|
||||
SendMessage(GetDlgItem(hwndDlg, IDC_DISKMOUNTPATH), WM_SETFONT, (WPARAM)context->SysinfoSection->Parameters->LargeFont, FALSE);
|
||||
SendMessage(GetDlgItem(hwndDlg, IDC_DISKNAME), WM_SETFONT, (WPARAM)context->SysinfoSection->Parameters->MediumFont, FALSE);
|
||||
|
||||
if (context->DiskEntry->DiskIndexName)
|
||||
SetDlgItemText(hwndDlg, IDC_DISKMOUNTPATH, context->DiskEntry->DiskIndexName->Buffer);
|
||||
else
|
||||
SetDlgItemText(hwndDlg, IDC_DISKMOUNTPATH, L"Unknown disk");
|
||||
|
||||
if (context->DiskEntry->DiskName)
|
||||
SetDlgItemText(hwndDlg, IDC_DISKNAME, context->DiskEntry->DiskName->Buffer);
|
||||
else
|
||||
SetDlgItemText(hwndDlg, IDC_DISKNAME, L"Unknown disk");
|
||||
|
||||
context->PanelWindowHandle = CreateDialogParam(PluginInstance->DllBase, MAKEINTRESOURCE(IDD_DISKDRIVE_PANEL), hwndDlg, DiskDrivePanelDialogProc, (LPARAM)context);
|
||||
ShowWindow(context->PanelWindowHandle, SW_SHOW);
|
||||
PhAddLayoutItemEx(&context->LayoutManager, context->PanelWindowHandle, NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM, panelItem->Margin);
|
||||
|
||||
// Create the graph control.
|
||||
context->GraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
hwndDlg,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(context->GraphHandle, TRUE);
|
||||
|
||||
PhAddLayoutItemEx(&context->LayoutManager, context->GraphHandle, NULL, PH_ANCHOR_ALL, graphItem->Margin);
|
||||
|
||||
UpdateDiskDriveDialog(context);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMHDR* header = (NMHDR*)lParam;
|
||||
|
||||
if (header->hwndFrom == context->GraphHandle)
|
||||
{
|
||||
switch (header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2;
|
||||
context->SysinfoSection->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite"));
|
||||
|
||||
PhGraphStateGetDrawInfo(
|
||||
&context->GraphState,
|
||||
getDrawInfo,
|
||||
context->DiskEntry->ReadBuffer.Count
|
||||
);
|
||||
|
||||
if (!context->GraphState.Valid)
|
||||
{
|
||||
FLOAT max = 1024 * 1024; // minimum scaling of 1 MB.
|
||||
|
||||
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
FLOAT data1;
|
||||
FLOAT data2;
|
||||
|
||||
context->GraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskEntry->ReadBuffer, i);
|
||||
context->GraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskEntry->WriteBuffer, i);
|
||||
|
||||
if (max < data1 + data2)
|
||||
max = data1 + data2;
|
||||
}
|
||||
|
||||
if (max != 0)
|
||||
{
|
||||
// Scale the data.
|
||||
PhDivideSinglesBySingle(
|
||||
context->GraphState.Data1,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
|
||||
// Scale the data.
|
||||
PhDivideSinglesBySingle(
|
||||
context->GraphState.Data2,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
}
|
||||
|
||||
drawInfo->LabelYFunction = PhSiSizeLabelYFunction;
|
||||
drawInfo->LabelYFunctionParameter = max;
|
||||
|
||||
context->GraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)header;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (context->GraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
ULONG64 diskReadValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->DiskEntry->ReadBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
ULONG64 diskWriteValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->DiskEntry->WriteBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
PhMoveReference(&context->GraphState.TooltipText, PhFormatString(
|
||||
L"R: %s\nW: %s\n%s",
|
||||
PhaFormatSize(diskReadValue, -1)->Buffer,
|
||||
PhaFormatSize(diskWriteValue, -1)->Buffer,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
}
|
||||
|
||||
getTooltipText->Text = context->GraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UPDATE_MSG:
|
||||
{
|
||||
UpdateDiskDriveDialog(context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN DiskDriveSectionCallback(
|
||||
_In_ PPH_SYSINFO_SECTION Section,
|
||||
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||
_In_opt_ PVOID Parameter1,
|
||||
_In_opt_ PVOID Parameter2
|
||||
)
|
||||
{
|
||||
PDV_DISK_SYSINFO_CONTEXT context = (PDV_DISK_SYSINFO_CONTEXT)Section->Context;
|
||||
|
||||
switch (Message)
|
||||
{
|
||||
case SysInfoCreate:
|
||||
{
|
||||
UpdateDiskIndexText(context);
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoDestroy:
|
||||
{
|
||||
PhDereferenceObject(context->DiskEntry);
|
||||
PhDereferenceObject(context->SectionName);
|
||||
PhFree(context);
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoTick:
|
||||
{
|
||||
UpdateDiskIndexText(context);
|
||||
|
||||
if (context->WindowHandle)
|
||||
PostMessage(context->WindowHandle, UPDATE_MSG, 0, 0);
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoCreateDialog:
|
||||
{
|
||||
PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1;
|
||||
|
||||
createDialog->Instance = PluginInstance->DllBase;
|
||||
createDialog->Template = MAKEINTRESOURCE(IDD_DISKDRIVE_DIALOG);
|
||||
createDialog->DialogProc = DiskDriveDialogProc;
|
||||
createDialog->Parameter = context;
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphGetDrawInfo:
|
||||
{
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite"));
|
||||
PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->DiskEntry->ReadBuffer.Count);
|
||||
|
||||
if (!Section->GraphState.Valid)
|
||||
{
|
||||
FLOAT max = 1024 * 1024; // minimum scaling of 1 MB.
|
||||
|
||||
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
FLOAT data1;
|
||||
FLOAT data2;
|
||||
|
||||
Section->GraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskEntry->ReadBuffer, i);
|
||||
Section->GraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->DiskEntry->WriteBuffer, i);
|
||||
|
||||
if (max < data1 + data2)
|
||||
max = data1 + data2;
|
||||
}
|
||||
|
||||
if (max != 0)
|
||||
{
|
||||
// Scale the data.
|
||||
PhDivideSinglesBySingle(
|
||||
Section->GraphState.Data1,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
|
||||
// Scale the data.
|
||||
PhDivideSinglesBySingle(
|
||||
Section->GraphState.Data2,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
}
|
||||
|
||||
drawInfo->LabelYFunction = PhSiSizeLabelYFunction;
|
||||
drawInfo->LabelYFunctionParameter = max;
|
||||
|
||||
Section->GraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphGetTooltipText:
|
||||
{
|
||||
PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1;
|
||||
|
||||
ULONG64 diskReadValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->DiskEntry->ReadBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
ULONG64 diskWriteValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->DiskEntry->WriteBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
PhMoveReference(&Section->GraphState.TooltipText, PhFormatString(
|
||||
L"R: %s\nW: %s\n%s",
|
||||
PhaFormatSize(diskReadValue, -1)->Buffer,
|
||||
PhaFormatSize(diskWriteValue, -1)->Buffer,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
|
||||
getTooltipText->Text = Section->GraphState.TooltipText->sr;
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphDrawPanel:
|
||||
{
|
||||
PPH_SYSINFO_DRAW_PANEL drawPanel = (PPH_SYSINFO_DRAW_PANEL)Parameter1;
|
||||
|
||||
PhSetReference(&drawPanel->Title, context->DiskEntry->DiskIndexName);
|
||||
drawPanel->SubTitle = PhFormatString(
|
||||
L"R: %s\nW: %s",
|
||||
PhaFormatSize(context->DiskEntry->BytesReadDelta.Delta, -1)->Buffer,
|
||||
PhaFormatSize(context->DiskEntry->BytesWrittenDelta.Delta, -1)->Buffer
|
||||
);
|
||||
|
||||
if (!drawPanel->Title)
|
||||
drawPanel->Title = PhCreateString(L"Unknown disk");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID DiskDriveSysInfoInitializing(
|
||||
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers,
|
||||
_In_ _Assume_refs_(1) PDV_DISK_ENTRY DiskEntry
|
||||
)
|
||||
{
|
||||
PH_SYSINFO_SECTION section;
|
||||
PDV_DISK_SYSINFO_CONTEXT context;
|
||||
|
||||
context = (PDV_DISK_SYSINFO_CONTEXT)PhAllocate(sizeof(DV_DISK_SYSINFO_CONTEXT));
|
||||
memset(context, 0, sizeof(DV_DISK_SYSINFO_CONTEXT));
|
||||
memset(§ion, 0, sizeof(PH_SYSINFO_SECTION));
|
||||
|
||||
context->DiskEntry = DiskEntry;
|
||||
context->SectionName = PhConcatStrings2(L"Disk ", DiskEntry->Id.DevicePath->Buffer);
|
||||
|
||||
section.Context = context;
|
||||
section.Callback = DiskDriveSectionCallback;
|
||||
section.Name = context->SectionName->sr;
|
||||
|
||||
context->SysinfoSection = Pointers->CreateSection(§ion);
|
||||
}
|
||||
119
plugins/HardwareDevices/disknotify.c
Normal file
119
plugins/HardwareDevices/disknotify.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2016 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
#include <Dbt.h>
|
||||
|
||||
static BOOLEAN SubclassActive = FALSE;
|
||||
|
||||
LRESULT CALLBACK MainWndDevicesSubclassProc(
|
||||
_In_ HWND hWnd,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam,
|
||||
_In_ UINT_PTR uIdSubclass,
|
||||
_In_ ULONG_PTR dwRefData
|
||||
)
|
||||
{
|
||||
// Subclassing the main window just to process drive letter notifications
|
||||
// is bad and I don't know of any other way to achieve this.
|
||||
// The IOCTL_MOUNTMGR_CHANGE_NOTIFY callback would have been preferred but
|
||||
// doesn't work from non-elevated processes.
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_DEVICECHANGE:
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case DBT_DEVICEARRIVAL: // Drive letter added
|
||||
case DBT_DEVICEREMOVECOMPLETE: // Drive letter removed
|
||||
{
|
||||
DEV_BROADCAST_HDR* deviceBroadcast = (DEV_BROADCAST_HDR*)lParam;
|
||||
|
||||
if (deviceBroadcast->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME deviceVolume = (PDEV_BROADCAST_VOLUME)deviceBroadcast;
|
||||
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
PDV_DISK_ENTRY entry;
|
||||
|
||||
entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
// Reset the DiskIndex so we can re-query the index on the next interval update.
|
||||
entry->DiskIndex = ULONG_MAX;
|
||||
// Reset the DiskIndexName so we can re-query the name on the next interval update.
|
||||
PhClearReference(&entry->DiskIndexName);
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goto DefaultWndProc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||
|
||||
DefaultWndProc:
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
VOID AddRemoveDeviceChangeCallback(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
// We get called during the plugin LoadCallback, don't do anything.
|
||||
if (!PhMainWndHandle)
|
||||
return;
|
||||
|
||||
// Add the subclass only when disks are being monitored, remove when no longer needed.
|
||||
if (DiskDrivesList->Count != 0)
|
||||
{
|
||||
if (!SubclassActive)
|
||||
{
|
||||
// We have a disk device, subclass the main window to detect drive letter changes.
|
||||
SetWindowSubclass(PhMainWndHandle, MainWndDevicesSubclassProc, 0, 0);
|
||||
SubclassActive = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SubclassActive)
|
||||
{
|
||||
// The user has removed the last disk device, remove the subclass.
|
||||
RemoveWindowSubclass(PhMainWndHandle, MainWndDevicesSubclassProc, 0);
|
||||
SubclassActive = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
695
plugins/HardwareDevices/diskoptions.c
Normal file
695
plugins/HardwareDevices/diskoptions.c
Normal file
@@ -0,0 +1,695 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
#include <Setupapi.h>
|
||||
|
||||
#define ITEM_CHECKED (INDEXTOSTATEIMAGEMASK(2))
|
||||
#define ITEM_UNCHECKED (INDEXTOSTATEIMAGEMASK(1))
|
||||
|
||||
typedef struct _DISK_ENUM_ENTRY
|
||||
{
|
||||
ULONG DeviceIndex;
|
||||
BOOLEAN DevicePresent;
|
||||
PPH_STRING DevicePath;
|
||||
PPH_STRING DeviceName;
|
||||
PPH_STRING DeviceMountPoints;
|
||||
} DISK_ENUM_ENTRY, *PDISK_ENUM_ENTRY;
|
||||
|
||||
static int __cdecl DiskEntryCompareFunction(
|
||||
_In_ const void *elem1,
|
||||
_In_ const void *elem2
|
||||
)
|
||||
{
|
||||
PDISK_ENUM_ENTRY entry1 = *(PDISK_ENUM_ENTRY *)elem1;
|
||||
PDISK_ENUM_ENTRY entry2 = *(PDISK_ENUM_ENTRY *)elem2;
|
||||
|
||||
return uint64cmp(entry1->DeviceIndex, entry2->DeviceIndex);
|
||||
}
|
||||
|
||||
VOID DiskDrivesLoadList(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
PPH_STRING settingsString;
|
||||
PH_STRINGREF remaining;
|
||||
|
||||
settingsString = PhaGetStringSetting(SETTING_NAME_DISK_LIST);
|
||||
remaining = settingsString->sr;
|
||||
|
||||
while (remaining.Length != 0)
|
||||
{
|
||||
PH_STRINGREF part;
|
||||
DV_DISK_ID id;
|
||||
PDV_DISK_ENTRY entry;
|
||||
|
||||
if (remaining.Length == 0)
|
||||
break;
|
||||
|
||||
PhSplitStringRefAtChar(&remaining, ',', &part, &remaining);
|
||||
|
||||
InitializeDiskId(&id, PhCreateString2(&part));
|
||||
entry = CreateDiskEntry(&id);
|
||||
DeleteDiskId(&id);
|
||||
|
||||
entry->UserReference = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID DiskDrivesSaveList(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
PH_STRING_BUILDER stringBuilder;
|
||||
PPH_STRING settingsString;
|
||||
|
||||
PhInitializeStringBuilder(&stringBuilder, 260);
|
||||
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (entry->UserReference)
|
||||
{
|
||||
PhAppendFormatStringBuilder(
|
||||
&stringBuilder,
|
||||
L"%s,",
|
||||
entry->Id.DevicePath->Buffer // This value is SAFE and does not change.
|
||||
);
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
if (stringBuilder.String->Length != 0)
|
||||
PhRemoveEndStringBuilder(&stringBuilder, 1);
|
||||
|
||||
settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder));
|
||||
PhSetStringSetting2(SETTING_NAME_DISK_LIST, &settingsString->sr);
|
||||
}
|
||||
|
||||
BOOLEAN FindDiskEntry(
|
||||
_In_ PDV_DISK_ID Id,
|
||||
_In_ BOOLEAN RemoveUserReference
|
||||
)
|
||||
{
|
||||
BOOLEAN found = FALSE;
|
||||
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
PDV_DISK_ENTRY currentEntry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!currentEntry)
|
||||
continue;
|
||||
|
||||
found = EquivalentDiskId(¤tEntry->Id, Id);
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (RemoveUserReference)
|
||||
{
|
||||
if (currentEntry->UserReference)
|
||||
{
|
||||
PhDereferenceObjectDeferDelete(currentEntry);
|
||||
currentEntry->UserReference = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(currentEntry);
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
PhDereferenceObjectDeferDelete(currentEntry);
|
||||
}
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
VOID AddDiskDriveToListView(
|
||||
_In_ PDV_DISK_OPTIONS_CONTEXT Context,
|
||||
_In_ BOOLEAN DiskPresent,
|
||||
_In_ PPH_STRING DiskPath,
|
||||
_In_ PPH_STRING DiskName
|
||||
)
|
||||
{
|
||||
DV_DISK_ID adapterId;
|
||||
INT lvItemIndex;
|
||||
BOOLEAN found = FALSE;
|
||||
PDV_DISK_ID newId = NULL;
|
||||
|
||||
InitializeDiskId(&adapterId, DiskPath);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (EquivalentDiskId(&entry->Id, &adapterId))
|
||||
{
|
||||
newId = PhAllocate(sizeof(DV_DISK_ID));
|
||||
CopyDiskId(newId, &entry->Id);
|
||||
|
||||
if (entry->UserReference)
|
||||
found = TRUE;
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
|
||||
if (newId)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newId)
|
||||
{
|
||||
newId = PhAllocate(sizeof(DV_DISK_ID));
|
||||
CopyDiskId(newId, &adapterId);
|
||||
PhMoveReference(&newId->DevicePath, DiskPath);
|
||||
}
|
||||
|
||||
lvItemIndex = AddListViewItemGroupId(
|
||||
Context->ListViewHandle,
|
||||
DiskPresent ? 0 : 1,
|
||||
MAXINT,
|
||||
DiskName->Buffer,
|
||||
newId
|
||||
);
|
||||
|
||||
if (found)
|
||||
ListView_SetItemState(Context->ListViewHandle, lvItemIndex, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
|
||||
|
||||
DeleteDiskId(&adapterId);
|
||||
}
|
||||
|
||||
VOID FreeListViewDiskDriveEntries(
|
||||
_In_ PDV_DISK_OPTIONS_CONTEXT Context
|
||||
)
|
||||
{
|
||||
ULONG index = -1;
|
||||
|
||||
while ((index = PhFindListViewItemByFlags(
|
||||
Context->ListViewHandle,
|
||||
index,
|
||||
LVNI_ALL
|
||||
)) != -1)
|
||||
{
|
||||
PDV_DISK_ID param;
|
||||
|
||||
if (PhGetListViewItemParam(Context->ListViewHandle, index, ¶m))
|
||||
{
|
||||
DeleteDiskId(param);
|
||||
PhFree(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID FindDiskDrives(
|
||||
_In_ PDV_DISK_OPTIONS_CONTEXT Context
|
||||
)
|
||||
{
|
||||
PPH_LIST deviceList;
|
||||
HDEVINFO deviceInfoHandle;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
|
||||
SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail;
|
||||
ULONG deviceInfoLength = 0;
|
||||
|
||||
if ((deviceInfoHandle = SetupDiGetClassDevs(
|
||||
&GUID_DEVINTERFACE_DISK,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_DEVICEINTERFACE
|
||||
)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
deviceList = PH_AUTO(PhCreateList(1));
|
||||
|
||||
for (ULONG i = 0; SetupDiEnumDeviceInterfaces(deviceInfoHandle, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++)
|
||||
{
|
||||
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
|
||||
))
|
||||
{
|
||||
HANDLE deviceHandle;
|
||||
PDISK_ENUM_ENTRY diskEntry;
|
||||
WCHAR diskFriendlyName[MAX_PATH] = L"";
|
||||
|
||||
// This crashes on XP with error 0xC06D007F
|
||||
//SetupDiGetDeviceProperty(
|
||||
// deviceInfoHandle,
|
||||
// &deviceInfoData,
|
||||
// &DEVPKEY_Device_FriendlyName,
|
||||
// &devicePropertyType,
|
||||
// (PBYTE)diskFriendlyName,
|
||||
// ARRAYSIZE(diskFriendlyName),
|
||||
// NULL,
|
||||
// 0
|
||||
// );
|
||||
|
||||
if (!SetupDiGetDeviceRegistryProperty(
|
||||
deviceInfoHandle,
|
||||
&deviceInfoData,
|
||||
SPDRP_FRIENDLYNAME,
|
||||
NULL,
|
||||
(PBYTE)diskFriendlyName,
|
||||
ARRAYSIZE(diskFriendlyName),
|
||||
NULL
|
||||
))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
diskEntry = PhAllocate(sizeof(DISK_ENUM_ENTRY));
|
||||
memset(diskEntry, 0, sizeof(DISK_ENUM_ENTRY));
|
||||
|
||||
diskEntry->DeviceIndex = ULONG_MAX; // Note: Do not initialize to zero.
|
||||
diskEntry->DeviceName = PhCreateString(diskFriendlyName);
|
||||
diskEntry->DevicePath = PhCreateString(deviceInterfaceDetail->DevicePath);
|
||||
|
||||
if (NT_SUCCESS(DiskDriveCreateHandle(
|
||||
&deviceHandle,
|
||||
diskEntry->DevicePath
|
||||
)))
|
||||
{
|
||||
ULONG diskIndex = ULONG_MAX; // Note: Do not initialize to zero
|
||||
|
||||
if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber(
|
||||
deviceHandle,
|
||||
&diskIndex,
|
||||
NULL
|
||||
)))
|
||||
{
|
||||
PPH_STRING diskMountPoints = PH_AUTO_T(PH_STRING, DiskDriveQueryDosMountPoints(diskIndex));
|
||||
|
||||
diskEntry->DeviceIndex = diskIndex;
|
||||
diskEntry->DevicePresent = TRUE;
|
||||
|
||||
if (!PhIsNullOrEmptyString(diskMountPoints))
|
||||
{
|
||||
diskEntry->DeviceMountPoints = PhFormatString(
|
||||
L"Disk %lu (%s) [%s]",
|
||||
diskIndex,
|
||||
diskMountPoints->Buffer,
|
||||
diskFriendlyName
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
diskEntry->DeviceMountPoints = PhFormatString(
|
||||
L"Disk %lu [%s]",
|
||||
diskIndex,
|
||||
diskFriendlyName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
|
||||
PhAddItemList(deviceList, diskEntry);
|
||||
}
|
||||
|
||||
PhFree(deviceInterfaceDetail);
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoHandle);
|
||||
|
||||
// Sort the entries
|
||||
qsort(deviceList->Items, deviceList->Count, sizeof(PVOID), DiskEntryCompareFunction);
|
||||
|
||||
Context->EnumeratingDisks = TRUE;
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < deviceList->Count; i++)
|
||||
{
|
||||
PDISK_ENUM_ENTRY entry = deviceList->Items[i];
|
||||
|
||||
AddDiskDriveToListView(
|
||||
Context,
|
||||
entry->DevicePresent,
|
||||
entry->DevicePath,
|
||||
entry->DeviceMountPoints ? entry->DeviceMountPoints : entry->DeviceName
|
||||
);
|
||||
|
||||
if (entry->DeviceMountPoints)
|
||||
PhDereferenceObject(entry->DeviceMountPoints);
|
||||
if (entry->DeviceName)
|
||||
PhDereferenceObject(entry->DeviceName);
|
||||
// Note: DevicePath is disposed by WM_DESTROY.
|
||||
|
||||
PhFree(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
Context->EnumeratingDisks = FALSE;
|
||||
|
||||
|
||||
// HACK: Show all unknown devices.
|
||||
Context->EnumeratingDisks = TRUE;
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
ULONG index = -1;
|
||||
BOOLEAN found = FALSE;
|
||||
PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
while ((index = PhFindListViewItemByFlags(
|
||||
Context->ListViewHandle,
|
||||
index,
|
||||
LVNI_ALL
|
||||
)) != -1)
|
||||
{
|
||||
PDV_DISK_ID param;
|
||||
|
||||
if (PhGetListViewItemParam(Context->ListViewHandle, index, ¶m))
|
||||
{
|
||||
if (EquivalentDiskId(param, &entry->Id))
|
||||
{
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
PPH_STRING description;
|
||||
|
||||
if (description = PhCreateString(L"Unknown disk"))
|
||||
{
|
||||
AddDiskDriveToListView(
|
||||
Context,
|
||||
FALSE,
|
||||
entry->Id.DevicePath,
|
||||
description
|
||||
);
|
||||
|
||||
PhDereferenceObject(description);
|
||||
}
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
Context->EnumeratingDisks = FALSE;
|
||||
}
|
||||
|
||||
PPH_STRING FindDiskDeviceInstance(
|
||||
_In_ PPH_STRING DevicePath
|
||||
)
|
||||
{
|
||||
PPH_STRING deviceIdString = NULL;
|
||||
HDEVINFO deviceInfoHandle;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
|
||||
SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail;
|
||||
ULONG deviceInfoLength = 0;
|
||||
|
||||
if ((deviceInfoHandle = SetupDiGetClassDevs(
|
||||
&GUID_DEVINTERFACE_DISK,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_DEVICEINTERFACE
|
||||
)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (ULONG i = 0; SetupDiEnumDeviceInterfaces(deviceInfoHandle, NULL, &GUID_DEVINTERFACE_DISK, i, &deviceInterfaceData); i++)
|
||||
{
|
||||
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
|
||||
))
|
||||
{
|
||||
if (PhEqualStringZ(deviceInterfaceDetail->DevicePath, DevicePath->Buffer, TRUE))
|
||||
{
|
||||
deviceIdString = PhCreateStringEx(NULL, 0x100);
|
||||
|
||||
SetupDiGetDeviceInstanceId(
|
||||
deviceInfoHandle,
|
||||
&deviceInfoData,
|
||||
deviceIdString->Buffer,
|
||||
(ULONG)deviceIdString->Length,
|
||||
NULL
|
||||
);
|
||||
|
||||
PhTrimToNullTerminatorString(deviceIdString);
|
||||
}
|
||||
}
|
||||
|
||||
PhFree(deviceInterfaceDetail);
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoHandle);
|
||||
|
||||
return deviceIdString;
|
||||
}
|
||||
|
||||
//VOID LoadDiskDriveImages(
|
||||
// _In_ PDV_DISK_OPTIONS_CONTEXT Context
|
||||
// )
|
||||
//{
|
||||
// HICON smallIcon = NULL;
|
||||
//
|
||||
// Context->ImageList = ImageList_Create(
|
||||
// GetSystemMetrics(SM_CXSMICON),
|
||||
// GetSystemMetrics(SM_CYSMICON),
|
||||
// ILC_COLOR32,
|
||||
// 1,
|
||||
// 1
|
||||
// );
|
||||
//
|
||||
// // We could use SetupDiLoadClassIcon but this works.
|
||||
// // Copied from HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4d36e967-e325-11ce-bfc1-08002be10318}\\IconPath
|
||||
// // The index is only valid on Vista and above.
|
||||
// ExtractIconEx(
|
||||
// L"%SystemRoot%\\system32\\imageres.dll",
|
||||
// -32,
|
||||
// NULL,
|
||||
// &smallIcon,
|
||||
// 1
|
||||
// );
|
||||
//
|
||||
// if (smallIcon)
|
||||
// {
|
||||
// ImageList_AddIcon(Context->ImageList, smallIcon);
|
||||
// DestroyIcon(smallIcon);
|
||||
//
|
||||
// // Set the imagelist only if the image was loaded.
|
||||
// ListView_SetImageList(
|
||||
// Context->ListViewHandle,
|
||||
// Context->ImageList,
|
||||
// LVSIL_SMALL
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
|
||||
INT_PTR CALLBACK DiskDriveOptionsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_DISK_OPTIONS_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_DISK_OPTIONS_CONTEXT)PhAllocate(sizeof(DV_DISK_OPTIONS_CONTEXT));
|
||||
memset(context, 0, sizeof(DV_DISK_OPTIONS_CONTEXT));
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_DISK_OPTIONS_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
if (context->OptionsChanged)
|
||||
DiskDrivesSaveList();
|
||||
|
||||
FreeListViewDiskDriveEntries(context);
|
||||
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
PhFree(context);
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
// Center the property sheet.
|
||||
PhCenterWindow(GetParent(hwndDlg), GetParent(GetParent(hwndDlg)));
|
||||
// Hide the OK button.
|
||||
ShowWindow(GetDlgItem(GetParent(hwndDlg), IDOK), SW_HIDE);
|
||||
// Set the Cancel button text.
|
||||
Button_SetText(GetDlgItem(GetParent(hwndDlg), IDCANCEL), L"Close");
|
||||
|
||||
context->ListViewHandle = GetDlgItem(hwndDlg, IDC_DISKDRIVE_LISTVIEW);
|
||||
PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
|
||||
ListView_SetExtendedListViewStyleEx(context->ListViewHandle, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
|
||||
PhSetControlTheme(context->ListViewHandle, L"explorer");
|
||||
PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 350, L"Disk Drives");
|
||||
PhSetExtendedListView(context->ListViewHandle);
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
ListView_EnableGroupView(context->ListViewHandle, TRUE);
|
||||
AddListViewGroup(context->ListViewHandle, 0, L"Connected");
|
||||
AddListViewGroup(context->ListViewHandle, 1, L"Disconnected");
|
||||
}
|
||||
|
||||
FindDiskDrives(context);
|
||||
|
||||
context->OptionsChanged = FALSE;
|
||||
|
||||
EnableThemeDialogTexture(hwndDlg, ETDT_ENABLETAB);
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR header = (LPNMHDR)lParam;
|
||||
|
||||
if (header->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
LPNM_LISTVIEW listView = (LPNM_LISTVIEW)lParam;
|
||||
|
||||
if (context->EnumeratingDisks)
|
||||
break;
|
||||
|
||||
if (listView->uChanged & LVIF_STATE)
|
||||
{
|
||||
switch (listView->uNewState & LVIS_STATEIMAGEMASK)
|
||||
{
|
||||
case 0x2000: // checked
|
||||
{
|
||||
PDV_DISK_ID param = (PDV_DISK_ID)listView->lParam;
|
||||
|
||||
if (!FindDiskEntry(param, FALSE))
|
||||
{
|
||||
PDV_DISK_ENTRY entry;
|
||||
|
||||
entry = CreateDiskEntry(param);
|
||||
entry->UserReference = TRUE;
|
||||
}
|
||||
|
||||
context->OptionsChanged = TRUE;
|
||||
}
|
||||
break;
|
||||
case 0x1000: // unchecked
|
||||
{
|
||||
PDV_DISK_ID param = (PDV_DISK_ID)listView->lParam;
|
||||
|
||||
FindDiskEntry(param, TRUE);
|
||||
|
||||
context->OptionsChanged = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (header->code == NM_RCLICK)
|
||||
{
|
||||
PDV_DISK_ID param;
|
||||
PPH_STRING deviceInstance;
|
||||
|
||||
if (param = PhGetSelectedListViewItemParam(context->ListViewHandle))
|
||||
{
|
||||
if (deviceInstance = FindDiskDeviceInstance(param->DevicePath))
|
||||
{
|
||||
ShowDeviceMenu(hwndDlg, deviceInstance);
|
||||
PhDereferenceObject(deviceInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
793
plugins/HardwareDevices/gpugraph.c
Normal file
793
plugins/HardwareDevices/gpugraph.c
Normal file
@@ -0,0 +1,793 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
#ifdef _NV_GPU_BUILD
|
||||
|
||||
#define ET_GPU_PADDING 3
|
||||
static RECT NormalGraphTextMargin = { 5, 5, 5, 5 };
|
||||
static RECT NormalGraphTextPadding = { 3, 3, 3, 3 };
|
||||
|
||||
static PPH_STRING GpuName;
|
||||
static HWND WindowHandle;
|
||||
static HWND DetailsHandle;
|
||||
static PPH_SYSINFO_SECTION Section;
|
||||
static PH_LAYOUT_MANAGER LayoutManager;
|
||||
|
||||
static RECT GpuGraphMargin;
|
||||
static HWND GpuPanel;
|
||||
static HWND GpuLabelHandle;
|
||||
static HWND MemLabelHandle;
|
||||
static HWND SharedLabelHandle;
|
||||
static HWND BusLabelHandle;
|
||||
static HWND GpuGraphHandle;
|
||||
static HWND MemGraphHandle;
|
||||
static HWND SharedGraphHandle;
|
||||
static HWND BusGraphHandle;
|
||||
|
||||
static PH_GRAPH_STATE GpuGraphState;
|
||||
static PH_GRAPH_STATE MemGraphState;
|
||||
static PH_GRAPH_STATE SharedGraphState;
|
||||
static PH_GRAPH_STATE BusGraphState;
|
||||
|
||||
PH_CIRCULAR_BUFFER_FLOAT GpuUtilizationHistory;
|
||||
PH_CIRCULAR_BUFFER_ULONG GpuMemoryHistory;
|
||||
PH_CIRCULAR_BUFFER_FLOAT GpuBoardHistory;
|
||||
PH_CIRCULAR_BUFFER_FLOAT GpuBusHistory;
|
||||
|
||||
INT_PTR CALLBACK NvGpuPanelDialogProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID NvGpuCreateGraphs(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
GpuGraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
WindowHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(GpuGraphHandle, TRUE);
|
||||
|
||||
MemGraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
WindowHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(MemGraphHandle, TRUE);
|
||||
|
||||
SharedGraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
WindowHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(SharedGraphHandle, TRUE);
|
||||
|
||||
BusGraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
WindowHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(BusGraphHandle, TRUE);
|
||||
}
|
||||
|
||||
VOID NvGpuLayoutGraphs(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
RECT clientRect;
|
||||
RECT labelRect;
|
||||
ULONG graphWidth;
|
||||
ULONG graphHeight;
|
||||
HDWP deferHandle;
|
||||
ULONG y;
|
||||
|
||||
PhLayoutManagerLayout(&LayoutManager);
|
||||
|
||||
GetClientRect(WindowHandle, &clientRect);
|
||||
GetClientRect(GpuLabelHandle, &labelRect);
|
||||
|
||||
graphWidth = clientRect.right - GpuGraphMargin.left - GpuGraphMargin.right;
|
||||
graphHeight = (clientRect.bottom - GpuGraphMargin.top - GpuGraphMargin.bottom - labelRect.bottom * 4 - ET_GPU_PADDING * 5) / 4;
|
||||
|
||||
deferHandle = BeginDeferWindowPos(8);
|
||||
y = GpuGraphMargin.top;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
GpuLabelHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
0,
|
||||
0,
|
||||
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += labelRect.bottom + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
GpuGraphHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
graphWidth,
|
||||
graphHeight,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += graphHeight + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
MemLabelHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
0,
|
||||
0,
|
||||
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += labelRect.bottom + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
MemGraphHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
graphWidth,
|
||||
graphHeight,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += graphHeight + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
SharedLabelHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
0,
|
||||
0,
|
||||
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += labelRect.bottom + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
SharedGraphHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
graphWidth,
|
||||
graphHeight,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += graphHeight + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
BusLabelHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
0,
|
||||
0,
|
||||
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
y += labelRect.bottom + ET_GPU_PADDING;
|
||||
|
||||
deferHandle = DeferWindowPos(
|
||||
deferHandle,
|
||||
BusGraphHandle,
|
||||
NULL,
|
||||
GpuGraphMargin.left,
|
||||
y,
|
||||
graphWidth,
|
||||
clientRect.bottom - GpuGraphMargin.bottom - y,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER
|
||||
);
|
||||
|
||||
EndDeferWindowPos(deferHandle);
|
||||
}
|
||||
|
||||
VOID NvGpuNotifyUsageGraph(
|
||||
_In_ NMHDR *Header
|
||||
)
|
||||
{
|
||||
switch (Header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
|
||||
PhGraphStateGetDrawInfo(&GpuGraphState, getDrawInfo, GpuUtilizationHistory.Count);
|
||||
|
||||
if (PhGetIntegerSetting(L"GraphShowText"))
|
||||
{
|
||||
HDC hdc = Graph_GetBufferedContext(GpuGraphHandle);
|
||||
|
||||
PhMoveReference(&GpuGraphState.Text,
|
||||
PhFormatString(L"%.0f%%", GpuCurrentGpuUsage * 100)
|
||||
);
|
||||
|
||||
SelectObject(hdc, PhApplicationFont);
|
||||
PhSetGraphText(hdc, drawInfo, &GpuGraphState.Text->sr,
|
||||
&NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->Text.Buffer = NULL;
|
||||
}
|
||||
|
||||
if (!GpuGraphState.Valid)
|
||||
{
|
||||
PhCopyCircularBuffer_FLOAT(&GpuUtilizationHistory, GpuGraphState.Data1, drawInfo->LineDataCount);
|
||||
GpuGraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (GpuGraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
FLOAT gpuUsageValue;
|
||||
|
||||
gpuUsageValue = PhGetItemCircularBuffer_FLOAT(&GpuUtilizationHistory, getTooltipText->Index);
|
||||
|
||||
PhMoveReference(&GpuGraphState.TooltipText, PhFormatString(
|
||||
L"%.0f%%\n%s",
|
||||
gpuUsageValue * 100,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
}
|
||||
|
||||
getTooltipText->Text = GpuGraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID NvGpuNotifyMemoryGraph(
|
||||
_In_ NMHDR *Header
|
||||
)
|
||||
{
|
||||
switch (Header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0);
|
||||
PhGraphStateGetDrawInfo(&MemGraphState, getDrawInfo, GpuMemoryHistory.Count);
|
||||
|
||||
if (PhGetIntegerSetting(L"GraphShowText"))
|
||||
{
|
||||
HDC hdc = Graph_GetBufferedContext(MemGraphHandle);
|
||||
|
||||
PhMoveReference(&MemGraphState.Text, PhFormatString(
|
||||
L"%s / %s (%.2f%%)",
|
||||
PhaFormatSize(UInt32x32To64(GpuCurrentMemUsage, 1024), -1)->Buffer,
|
||||
PhaFormatSize(UInt32x32To64(GpuMemoryLimit, 1024), -1)->Buffer,
|
||||
(FLOAT)GpuCurrentMemUsage / GpuMemoryLimit * 100
|
||||
));
|
||||
|
||||
SelectObject(hdc, PhApplicationFont);
|
||||
PhSetGraphText(hdc, drawInfo, &MemGraphState.Text->sr,
|
||||
&NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->Text.Buffer = NULL;
|
||||
}
|
||||
|
||||
if (!MemGraphState.Valid)
|
||||
{
|
||||
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
MemGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&GpuMemoryHistory, i);
|
||||
}
|
||||
|
||||
if (GpuMemoryLimit != 0)
|
||||
{
|
||||
// Scale the data.
|
||||
PhDivideSinglesBySingle(
|
||||
MemGraphState.Data1,
|
||||
(FLOAT)GpuMemoryLimit,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
}
|
||||
|
||||
MemGraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (MemGraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
ULONG usedPages;
|
||||
|
||||
usedPages = PhGetItemCircularBuffer_ULONG(&GpuMemoryHistory, getTooltipText->Index);
|
||||
|
||||
PhMoveReference(&MemGraphState.TooltipText, PhFormatString(
|
||||
L"%s / %s (%.2f%%)\n%s",
|
||||
PhaFormatSize(UInt32x32To64(usedPages, 1024), -1)->Buffer,
|
||||
PhaFormatSize(UInt32x32To64(GpuMemoryLimit, 1024), -1)->Buffer,
|
||||
(FLOAT)usedPages / GpuMemoryLimit * 100,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
}
|
||||
|
||||
getTooltipText->Text = MemGraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID NvGpuNotifySharedGraph(
|
||||
_In_ NMHDR *Header
|
||||
)
|
||||
{
|
||||
switch (Header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
|
||||
PhGraphStateGetDrawInfo(&SharedGraphState, getDrawInfo, GpuBoardHistory.Count);
|
||||
|
||||
if (PhGetIntegerSetting(L"GraphShowText"))
|
||||
{
|
||||
HDC hdc = Graph_GetBufferedContext(SharedGraphHandle);
|
||||
|
||||
PhMoveReference(&SharedGraphState.Text, PhFormatString(
|
||||
L"%.0f%%",
|
||||
(FLOAT)GpuCurrentCoreUsage * 100
|
||||
));
|
||||
|
||||
SelectObject(hdc, PhApplicationFont);
|
||||
PhSetGraphText(hdc, drawInfo, &SharedGraphState.Text->sr,
|
||||
&NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->Text.Buffer = NULL;
|
||||
}
|
||||
|
||||
if (!SharedGraphState.Valid)
|
||||
{
|
||||
PhCopyCircularBuffer_FLOAT(&GpuBoardHistory, SharedGraphState.Data1, drawInfo->LineDataCount);
|
||||
SharedGraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (SharedGraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
FLOAT usedPages;
|
||||
|
||||
usedPages = PhGetItemCircularBuffer_FLOAT(&GpuBoardHistory, getTooltipText->Index);
|
||||
|
||||
PhMoveReference(&SharedGraphState.TooltipText, PhFormatString(
|
||||
L"%.0f%%\n%s",
|
||||
usedPages * 100,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
}
|
||||
|
||||
getTooltipText->Text = SharedGraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID NvGpuNotifyBusGraph(
|
||||
_In_ NMHDR *Header
|
||||
)
|
||||
{
|
||||
switch (Header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
|
||||
PhGraphStateGetDrawInfo(&BusGraphState, getDrawInfo, GpuBusHistory.Count);
|
||||
|
||||
if (PhGetIntegerSetting(L"GraphShowText"))
|
||||
{
|
||||
HDC hdc = Graph_GetBufferedContext(BusGraphHandle);
|
||||
|
||||
PhMoveReference(&BusGraphState.Text, PhFormatString(
|
||||
L"%.0f%%",
|
||||
(FLOAT)GpuCurrentBusUsage * 100
|
||||
));
|
||||
|
||||
SelectObject(hdc, PhApplicationFont);
|
||||
PhSetGraphText(hdc, drawInfo, &BusGraphState.Text->sr,
|
||||
&NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawInfo->Text.Buffer = NULL;
|
||||
}
|
||||
|
||||
if (!BusGraphState.Valid)
|
||||
{
|
||||
PhCopyCircularBuffer_FLOAT(&GpuBusHistory, BusGraphState.Data1, drawInfo->LineDataCount);
|
||||
BusGraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (BusGraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
FLOAT busUsage;
|
||||
|
||||
busUsage = PhGetItemCircularBuffer_FLOAT(&GpuBusHistory, getTooltipText->Index);
|
||||
|
||||
PhMoveReference(&BusGraphState.TooltipText, PhFormatString(
|
||||
L"%.0f%%\n%s",
|
||||
busUsage * 100,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
}
|
||||
|
||||
getTooltipText->Text = BusGraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID NvGpuUpdateGraphs(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
GpuGraphState.Valid = FALSE;
|
||||
GpuGraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(GpuGraphHandle, 1);
|
||||
Graph_Draw(GpuGraphHandle);
|
||||
Graph_UpdateTooltip(GpuGraphHandle);
|
||||
InvalidateRect(GpuGraphHandle, NULL, FALSE);
|
||||
|
||||
MemGraphState.Valid = FALSE;
|
||||
MemGraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(MemGraphHandle, 1);
|
||||
Graph_Draw(MemGraphHandle);
|
||||
Graph_UpdateTooltip(MemGraphHandle);
|
||||
InvalidateRect(MemGraphHandle, NULL, FALSE);
|
||||
|
||||
SharedGraphState.Valid = FALSE;
|
||||
SharedGraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(SharedGraphHandle, 1);
|
||||
Graph_Draw(SharedGraphHandle);
|
||||
Graph_UpdateTooltip(SharedGraphHandle);
|
||||
InvalidateRect(SharedGraphHandle, NULL, FALSE);
|
||||
|
||||
BusGraphState.Valid = FALSE;
|
||||
BusGraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(BusGraphHandle, 1);
|
||||
Graph_Draw(BusGraphHandle);
|
||||
Graph_UpdateTooltip(BusGraphHandle);
|
||||
InvalidateRect(BusGraphHandle, NULL, FALSE);
|
||||
}
|
||||
|
||||
VOID NvGpuUpdatePanel(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
SetDlgItemText(GpuPanel, IDC_CLOCK_CORE, PhaFormatString(L"%lu MHz", GpuCurrentCoreClock)->Buffer);
|
||||
SetDlgItemText(GpuPanel, IDC_CLOCK_MEMORY, PhaFormatString(L"%lu MHz", GpuCurrentMemoryClock)->Buffer);
|
||||
SetDlgItemText(GpuPanel, IDC_CLOCK_SHADER, PhaFormatString(L"%lu MHz", GpuCurrentShaderClock)->Buffer);
|
||||
SetDlgItemText(GpuPanel, IDC_FAN_PERCENT, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryFanSpeed()))->Buffer);
|
||||
|
||||
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_FAHRENHEIT))
|
||||
{
|
||||
FLOAT fahrenheit = (FLOAT)(GpuCurrentCoreTemp * 1.8 + 32);
|
||||
|
||||
SetDlgItemText(GpuPanel, IDC_TEMP_VALUE, PhaFormatString(L"%.1f\u00b0F", fahrenheit)->Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDlgItemText(GpuPanel, IDC_TEMP_VALUE, PhaFormatString(L"%lu\u00b0C", GpuCurrentCoreTemp)->Buffer);
|
||||
}
|
||||
|
||||
//SetDlgItemText(GpuPanel, IDC_TEMP_VALUE, PhaFormatString(L"%s\u00b0C", PhaFormatUInt64(GpuCurrentBoardTemp, TRUE)->Buffer)->Buffer);
|
||||
SetDlgItemText(GpuPanel, IDC_VOLTAGE, PhaFormatString(L"%lu mV", GpuCurrentVoltage)->Buffer);
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK NvGpuDialogProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
//PhDeleteLayoutManager(&LayoutManager);
|
||||
|
||||
//PhDeleteGraphState(&GpuGraphState);
|
||||
//PhDeleteGraphState(&MemGraphState);
|
||||
//PhDeleteGraphState(&SharedGraphState);
|
||||
//PhDeleteGraphState(&BusGraphState);
|
||||
|
||||
//if (GpuGraphHandle)
|
||||
// DestroyWindow(GpuGraphHandle);
|
||||
//if (MemGraphHandle)
|
||||
// DestroyWindow(MemGraphHandle);
|
||||
//if (SharedGraphHandle)
|
||||
// DestroyWindow(SharedGraphHandle);
|
||||
//if (BusGraphHandle)
|
||||
// DestroyWindow(BusGraphHandle);
|
||||
//if (GpuPanel)
|
||||
// DestroyWindow(GpuPanel);
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
PPH_LAYOUT_ITEM graphItem;
|
||||
PPH_LAYOUT_ITEM panelItem;
|
||||
|
||||
WindowHandle = hwndDlg;
|
||||
|
||||
GpuLabelHandle = GetDlgItem(hwndDlg, IDC_GPU_L);
|
||||
MemLabelHandle = GetDlgItem(hwndDlg, IDC_MEMORY_L);
|
||||
SharedLabelHandle = GetDlgItem(hwndDlg, IDC_SHARED_L);
|
||||
BusLabelHandle = GetDlgItem(hwndDlg, IDC_BUS_L);
|
||||
|
||||
PhInitializeGraphState(&GpuGraphState);
|
||||
PhInitializeGraphState(&MemGraphState);
|
||||
PhInitializeGraphState(&SharedGraphState);
|
||||
PhInitializeGraphState(&BusGraphState);
|
||||
|
||||
PhInitializeLayoutManager(&LayoutManager, hwndDlg);
|
||||
PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_GPUNAME), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE);
|
||||
graphItem = PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_GRAPH_LAYOUT), NULL, PH_ANCHOR_ALL);
|
||||
GpuGraphMargin = graphItem->Margin;
|
||||
panelItem = PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_LAYOUT), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
|
||||
|
||||
SendMessage(GetDlgItem(hwndDlg, IDC_TITLE), WM_SETFONT, (WPARAM)Section->Parameters->LargeFont, FALSE);
|
||||
SendMessage(GetDlgItem(hwndDlg, IDC_GPUNAME), WM_SETFONT, (WPARAM)Section->Parameters->MediumFont, FALSE);
|
||||
SetDlgItemText(hwndDlg, IDC_GPUNAME, GpuName->Buffer);
|
||||
|
||||
GpuPanel = CreateDialog(PluginInstance->DllBase, MAKEINTRESOURCE(IDD_GPU_PANEL), hwndDlg, NvGpuPanelDialogProc);
|
||||
ShowWindow(GpuPanel, SW_SHOW);
|
||||
PhAddLayoutItemEx(&LayoutManager, GpuPanel, NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM, panelItem->Margin);
|
||||
|
||||
NvGpuCreateGraphs();
|
||||
|
||||
NvGpuUpdate();
|
||||
NvGpuUpdateGraphs();
|
||||
NvGpuUpdatePanel();
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
NvGpuLayoutGraphs();
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMHDR* header = (NMHDR*)lParam;
|
||||
|
||||
if (header->hwndFrom == GpuGraphHandle)
|
||||
{
|
||||
NvGpuNotifyUsageGraph(header);
|
||||
}
|
||||
else if (header->hwndFrom == MemGraphHandle)
|
||||
{
|
||||
NvGpuNotifyMemoryGraph(header);
|
||||
}
|
||||
else if (header->hwndFrom == SharedGraphHandle)
|
||||
{
|
||||
NvGpuNotifySharedGraph(header);
|
||||
}
|
||||
else if (header->hwndFrom == BusGraphHandle)
|
||||
{
|
||||
NvGpuNotifyBusGraph(header);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UPDATE_MSG:
|
||||
{
|
||||
NvGpuUpdateGraphs();
|
||||
NvGpuUpdatePanel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN NvGpuSectionCallback(
|
||||
_In_ PPH_SYSINFO_SECTION Section,
|
||||
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||
_In_opt_ PVOID Parameter1,
|
||||
_In_opt_ PVOID Parameter2
|
||||
)
|
||||
{
|
||||
switch (Message)
|
||||
{
|
||||
case SysInfoCreate:
|
||||
return TRUE;
|
||||
case SysInfoDestroy:
|
||||
return TRUE;
|
||||
case SysInfoTick:
|
||||
{
|
||||
if (WindowHandle)
|
||||
PostMessage(WindowHandle, UPDATE_MSG, 0, 0);
|
||||
|
||||
if (DetailsHandle)
|
||||
PostMessage(DetailsHandle, UPDATE_MSG, 0, 0);
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoCreateDialog:
|
||||
{
|
||||
PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1;
|
||||
|
||||
createDialog->Instance = PluginInstance->DllBase;
|
||||
createDialog->Template = MAKEINTRESOURCE(IDD_GPU_DIALOG);
|
||||
createDialog->DialogProc = NvGpuDialogProc;
|
||||
//createDialog->Parameter = context;
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphGetDrawInfo:
|
||||
{
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
|
||||
PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, GpuUtilizationHistory.Count);
|
||||
|
||||
if (!Section->GraphState.Valid)
|
||||
{
|
||||
PhCopyCircularBuffer_FLOAT(&GpuUtilizationHistory, Section->GraphState.Data1, drawInfo->LineDataCount);
|
||||
Section->GraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphGetTooltipText:
|
||||
{
|
||||
FLOAT gpuUsageValue;
|
||||
PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1;
|
||||
|
||||
gpuUsageValue = PhGetItemCircularBuffer_FLOAT(&GpuUtilizationHistory, getTooltipText->Index);
|
||||
|
||||
PhMoveReference(&Section->GraphState.TooltipText, PhFormatString(
|
||||
L"%.0f%%\n%s",
|
||||
gpuUsageValue * 100,
|
||||
((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
|
||||
getTooltipText->Text = Section->GraphState.TooltipText->sr;
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphDrawPanel:
|
||||
{
|
||||
PPH_SYSINFO_DRAW_PANEL drawPanel = (PPH_SYSINFO_DRAW_PANEL)Parameter1;
|
||||
|
||||
drawPanel->Title = PhCreateString(Section->Name.Buffer);
|
||||
drawPanel->SubTitle = PhFormatString(
|
||||
L"%.0f%%",
|
||||
GpuCurrentGpuUsage * 100
|
||||
);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID NvGpuSysInfoInitializing(
|
||||
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers
|
||||
)
|
||||
{
|
||||
PH_SYSINFO_SECTION section;
|
||||
|
||||
if (!PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU))
|
||||
return;
|
||||
|
||||
if (!NvApiInitialized)
|
||||
return;
|
||||
|
||||
memset(§ion, 0, sizeof(PH_SYSINFO_SECTION));
|
||||
|
||||
section.Callback = NvGpuSectionCallback;
|
||||
|
||||
GpuName = NvGpuQueryName();
|
||||
PhInitializeStringRef(§ion.Name, GpuName->Buffer);
|
||||
|
||||
Section = Pointers->CreateSection(§ion);
|
||||
}
|
||||
|
||||
#endif
|
||||
407
plugins/HardwareDevices/main.c
Normal file
407
plugins/HardwareDevices/main.c
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
PPH_PLUGIN PluginInstance = NULL;
|
||||
|
||||
PPH_OBJECT_TYPE NetAdapterEntryType = NULL;
|
||||
PPH_LIST NetworkAdaptersList = NULL;
|
||||
PH_QUEUED_LOCK NetworkAdaptersListLock = PH_QUEUED_LOCK_INIT;
|
||||
|
||||
PPH_OBJECT_TYPE DiskDriveEntryType = NULL;
|
||||
PPH_LIST DiskDrivesList = NULL;
|
||||
PH_QUEUED_LOCK DiskDrivesListLock = PH_QUEUED_LOCK_INIT;
|
||||
|
||||
PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION MainWindowShowingCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION ProcessesUpdatedCallbackRegistration;
|
||||
PH_CALLBACK_REGISTRATION SystemInformationInitializingCallbackRegistration;
|
||||
|
||||
VOID NTAPI LoadCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
DiskDrivesInitialize();
|
||||
NetAdaptersInitialize();
|
||||
|
||||
DiskDrivesLoadList();
|
||||
NetAdaptersLoadList();
|
||||
|
||||
#ifdef _NV_GPU_BUILD
|
||||
NvApiInitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID NTAPI UnloadCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
NOTHING;
|
||||
}
|
||||
|
||||
VOID NTAPI ShowOptionsCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
PROPSHEETHEADER propSheetHeader = { sizeof(propSheetHeader) };
|
||||
PROPSHEETPAGE propSheetPage;
|
||||
HPROPSHEETPAGE pages[2];
|
||||
|
||||
propSheetHeader.dwFlags =
|
||||
PSH_NOAPPLYNOW |
|
||||
PSH_NOCONTEXTHELP;
|
||||
propSheetHeader.hwndParent = (HWND)Parameter;
|
||||
propSheetHeader.pszCaption = L"Hardware Devices Plugin";
|
||||
propSheetHeader.nPages = 0;
|
||||
propSheetHeader.nStartPage = 0;
|
||||
propSheetHeader.phpage = pages;
|
||||
|
||||
// Disk Drives
|
||||
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
|
||||
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
|
||||
propSheetPage.hInstance = PluginInstance->DllBase;
|
||||
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_DISKDRIVE_OPTIONS);
|
||||
propSheetPage.pfnDlgProc = DiskDriveOptionsDlgProc;
|
||||
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
|
||||
|
||||
// Network Adapters
|
||||
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
|
||||
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
|
||||
propSheetPage.hInstance = PluginInstance->DllBase;
|
||||
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_NETADAPTER_OPTIONS);
|
||||
propSheetPage.pfnDlgProc = NetworkAdapterOptionsDlgProc;
|
||||
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
|
||||
|
||||
PhModalPropertySheet(&propSheetHeader);
|
||||
}
|
||||
|
||||
VOID NTAPI MainWindowShowingCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
AddRemoveDeviceChangeCallback();
|
||||
}
|
||||
|
||||
VOID NTAPI ProcessesUpdatedCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
DiskDrivesUpdate();
|
||||
NetAdaptersUpdate();
|
||||
|
||||
#ifdef _NV_GPU_BUILD
|
||||
NvGpuUpdate();
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID NTAPI SystemInformationInitializingCallback(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
PPH_PLUGIN_SYSINFO_POINTERS pluginEntry = (PPH_PLUGIN_SYSINFO_POINTERS)Parameter;
|
||||
|
||||
// Disk Drives
|
||||
|
||||
PhAcquireQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
for (ULONG i = 0; i < DiskDrivesList->Count; i++)
|
||||
{
|
||||
PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (entry->DevicePresent)
|
||||
{
|
||||
DiskDriveSysInfoInitializing(pluginEntry, entry);
|
||||
}
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&DiskDrivesListLock);
|
||||
|
||||
// Network Adapters
|
||||
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (entry->DevicePresent)
|
||||
{
|
||||
NetAdapterSysInfoInitializing(pluginEntry, entry);
|
||||
}
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
// Graphics cards
|
||||
#ifdef _NV_GPU_BUILD
|
||||
NvGpuSysInfoInitializing(pluginEntry);
|
||||
#endif
|
||||
}
|
||||
|
||||
PPH_STRING TrimString(
|
||||
_In_ PPH_STRING String
|
||||
)
|
||||
{
|
||||
static PH_STRINGREF whitespace = PH_STRINGREF_INIT(L" \t\r\n");
|
||||
PH_STRINGREF sr = String->sr;
|
||||
PhTrimStringRef(&sr, &whitespace, 0);
|
||||
return PhCreateString2(&sr);
|
||||
}
|
||||
|
||||
INT AddListViewGroup(
|
||||
_In_ HWND ListViewHandle,
|
||||
_In_ INT GroupId,
|
||||
_In_ PWSTR Text
|
||||
)
|
||||
{
|
||||
LVGROUP group;
|
||||
|
||||
group.cbSize = LVGROUP_V5_SIZE;
|
||||
group.mask = LVGF_HEADER;
|
||||
group.pszHeader = Text;
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
group.cbSize = sizeof(LVGROUP);
|
||||
group.mask |= LVGF_ALIGN | LVGF_STATE | LVGF_GROUPID;
|
||||
group.uAlign = LVGA_HEADER_LEFT;
|
||||
group.state = LVGS_COLLAPSIBLE;
|
||||
group.iGroupId = GroupId;
|
||||
}
|
||||
|
||||
return (INT)ListView_InsertGroup(ListViewHandle, MAXINT, &group);
|
||||
}
|
||||
|
||||
INT AddListViewItemGroupId(
|
||||
_In_ HWND ListViewHandle,
|
||||
_In_ INT GroupId,
|
||||
_In_ INT Index,
|
||||
_In_ PWSTR Text,
|
||||
_In_opt_ PVOID Param
|
||||
)
|
||||
{
|
||||
LVITEM item;
|
||||
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iItem = Index;
|
||||
item.iSubItem = 0;
|
||||
item.pszText = Text;
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
item.mask |= LVIF_GROUPID;
|
||||
item.iGroupId = GroupId;
|
||||
}
|
||||
|
||||
if (Param)
|
||||
{
|
||||
item.mask |= LVIF_PARAM;
|
||||
item.lParam = (LPARAM)Param;
|
||||
}
|
||||
|
||||
return ListView_InsertItem(ListViewHandle, &item);
|
||||
}
|
||||
|
||||
ULONG64 RegQueryUlong64(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PWSTR ValueName
|
||||
)
|
||||
{
|
||||
ULONG64 value = 0;
|
||||
PH_STRINGREF valueName;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION buffer;
|
||||
|
||||
PhInitializeStringRef(&valueName, ValueName);
|
||||
|
||||
if (NT_SUCCESS(PhQueryValueKey(KeyHandle, &valueName, KeyValuePartialInformation, &buffer)))
|
||||
{
|
||||
if (buffer->Type == REG_DWORD || buffer->Type == REG_QWORD)
|
||||
{
|
||||
value = *(ULONG64*)buffer->Data;
|
||||
}
|
||||
|
||||
PhFree(buffer);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
VOID ShowDeviceMenu(
|
||||
_In_ HWND ParentWindow,
|
||||
_In_ PPH_STRING DeviceInstance
|
||||
)
|
||||
{
|
||||
POINT cursorPos;
|
||||
PPH_EMENU menu;
|
||||
PPH_EMENU_ITEM selectedItem;
|
||||
|
||||
GetCursorPos(&cursorPos);
|
||||
|
||||
menu = PhCreateEMenu();
|
||||
//PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 0, L"Enable", NULL, NULL), -1);
|
||||
//PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Disable", NULL, NULL), -1);
|
||||
//PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
|
||||
PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Properties", NULL, NULL), -1);
|
||||
|
||||
selectedItem = PhShowEMenu(
|
||||
menu,
|
||||
PhMainWndHandle,
|
||||
PH_EMENU_SHOW_LEFTRIGHT,
|
||||
PH_ALIGN_LEFT | PH_ALIGN_TOP,
|
||||
cursorPos.x,
|
||||
cursorPos.y
|
||||
);
|
||||
|
||||
if (selectedItem && selectedItem->Id != -1)
|
||||
{
|
||||
switch (selectedItem->Id)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
HMODULE devMgrHandle;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff548181.aspx
|
||||
VOID (WINAPI *DeviceProperties_RunDLL_I)(
|
||||
_In_ HWND hwndStub,
|
||||
_In_ HINSTANCE hAppInstance,
|
||||
_In_ PWSTR lpCmdLine,
|
||||
_In_ INT nCmdShow
|
||||
);
|
||||
|
||||
if (devMgrHandle = LoadLibrary(L"devmgr.dll"))
|
||||
{
|
||||
if (DeviceProperties_RunDLL_I = (PVOID)GetProcAddress(devMgrHandle, "DeviceProperties_RunDLLW"))
|
||||
{
|
||||
// This will sometimes re-throw an RPC error during debugging and can be safely ignored.
|
||||
DeviceProperties_RunDLL_I(
|
||||
GetParent(ParentWindow),
|
||||
NULL,
|
||||
PhaFormatString(L"/DeviceID %s", DeviceInstance->Buffer)->Buffer,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
FreeLibrary(devMgrHandle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PhDestroyEMenu(menu);
|
||||
}
|
||||
|
||||
LOGICAL DllMain(
|
||||
_In_ HINSTANCE Instance,
|
||||
_In_ ULONG Reason,
|
||||
_Reserved_ PVOID Reserved
|
||||
)
|
||||
{
|
||||
switch (Reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
PPH_PLUGIN_INFORMATION info;
|
||||
PH_SETTING_CREATE settings[] =
|
||||
{
|
||||
{ IntegerSettingType, SETTING_NAME_ENABLE_NDIS, L"1" },
|
||||
{ StringSettingType, SETTING_NAME_INTERFACE_LIST, L"" },
|
||||
{ StringSettingType, SETTING_NAME_DISK_LIST, L"" },
|
||||
#ifdef _NV_GPU_BUILD
|
||||
{ IntegerSettingType, SETTING_NAME_ENABLE_GPU, L"1" },
|
||||
{ IntegerSettingType, SETTING_NAME_ENABLE_FAHRENHEIT, L"0" }
|
||||
#endif
|
||||
};
|
||||
|
||||
PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
|
||||
|
||||
if (!PluginInstance)
|
||||
return FALSE;
|
||||
|
||||
info->DisplayName = L"Hardware Devices";
|
||||
info->Author = L"dmex, wj32";
|
||||
info->Description = L"Plugin for monitoring hardware devices like Disk drives and Network adapters via the System Information window.";
|
||||
info->Url = L"https://wj32.org/processhacker/forums/viewtopic.php?t=1820";
|
||||
info->HasOptions = TRUE;
|
||||
|
||||
PhRegisterCallback(
|
||||
PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
|
||||
LoadCallback,
|
||||
NULL,
|
||||
&PluginLoadCallbackRegistration
|
||||
);
|
||||
PhRegisterCallback(
|
||||
PhGetPluginCallback(PluginInstance, PluginCallbackUnload),
|
||||
UnloadCallback,
|
||||
NULL,
|
||||
&PluginUnloadCallbackRegistration
|
||||
);
|
||||
PhRegisterCallback(
|
||||
PhGetPluginCallback(PluginInstance, PluginCallbackShowOptions),
|
||||
ShowOptionsCallback,
|
||||
NULL,
|
||||
&PluginShowOptionsCallbackRegistration
|
||||
);
|
||||
PhRegisterCallback(
|
||||
PhGetGeneralCallback(GeneralCallbackMainWindowShowing),
|
||||
MainWindowShowingCallback,
|
||||
NULL,
|
||||
&MainWindowShowingCallbackRegistration
|
||||
);
|
||||
|
||||
PhRegisterCallback(
|
||||
&PhProcessesUpdatedEvent,
|
||||
ProcessesUpdatedCallback,
|
||||
NULL,
|
||||
&ProcessesUpdatedCallbackRegistration
|
||||
);
|
||||
|
||||
PhRegisterCallback(
|
||||
PhGetGeneralCallback(GeneralCallbackSystemInformationInitializing),
|
||||
SystemInformationInitializingCallback,
|
||||
NULL,
|
||||
&SystemInformationInitializingCallbackRegistration
|
||||
);
|
||||
|
||||
PhAddSettings(settings, ARRAYSIZE(settings));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
597
plugins/HardwareDevices/ndis.c
Normal file
597
plugins/HardwareDevices/ndis.c
Normal file
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
#include <objbase.h>
|
||||
|
||||
PVOID IphlpHandle = NULL;
|
||||
_GetInterfaceDescriptionFromGuid GetInterfaceDescriptionFromGuid_I = NULL;
|
||||
|
||||
NTSTATUS NetworkAdapterCreateHandle(
|
||||
_Out_ PHANDLE DeviceHandle,
|
||||
_In_ PPH_STRING InterfaceGuid
|
||||
)
|
||||
{
|
||||
// NOTE: Do not cache this handle. The user will be unable to enable, disable or change adapter configuration.
|
||||
return PhCreateFileWin32(
|
||||
DeviceHandle,
|
||||
PhaConcatStrings(2, L"\\\\.\\", InterfaceGuid->Buffer)->Buffer,
|
||||
FILE_GENERIC_READ,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
|
||||
);
|
||||
}
|
||||
|
||||
BOOLEAN NetworkAdapterQuerySupported(
|
||||
_In_ HANDLE DeviceHandle
|
||||
)
|
||||
{
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
BOOLEAN ndisQuerySupported = FALSE;
|
||||
BOOLEAN adapterNameSupported = FALSE;
|
||||
BOOLEAN adapterStatsSupported = FALSE;
|
||||
BOOLEAN adapterLinkStateSupported = FALSE;
|
||||
BOOLEAN adapterLinkSpeedSupported = FALSE;
|
||||
PNDIS_OID ndisObjectIdentifiers = NULL;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569642.aspx
|
||||
opcode = OID_GEN_SUPPORTED_LIST;
|
||||
|
||||
// TODO: 4096 objects might be too small...
|
||||
ndisObjectIdentifiers = PhAllocate(PAGE_SIZE * sizeof(NDIS_OID));
|
||||
memset(ndisObjectIdentifiers, 0, PAGE_SIZE * sizeof(NDIS_OID));
|
||||
|
||||
if (NT_SUCCESS(NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS, // https://msdn.microsoft.com/en-us/library/windows/hardware/ff548975.aspx
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
ndisObjectIdentifiers,
|
||||
PAGE_SIZE * sizeof(NDIS_OID)
|
||||
)))
|
||||
{
|
||||
ndisQuerySupported = TRUE;
|
||||
|
||||
for (ULONG i = 0; i < (ULONG)isb.Information / sizeof(NDIS_OID); i++)
|
||||
{
|
||||
NDIS_OID opcode = ndisObjectIdentifiers[i];
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case OID_GEN_FRIENDLY_NAME:
|
||||
adapterNameSupported = TRUE;
|
||||
break;
|
||||
case OID_GEN_STATISTICS:
|
||||
adapterStatsSupported = TRUE;
|
||||
break;
|
||||
case OID_GEN_LINK_STATE:
|
||||
adapterLinkStateSupported = TRUE;
|
||||
break;
|
||||
case OID_GEN_LINK_SPEED:
|
||||
adapterLinkSpeedSupported = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhFree(ndisObjectIdentifiers);
|
||||
|
||||
if (!adapterNameSupported)
|
||||
ndisQuerySupported = FALSE;
|
||||
if (!adapterStatsSupported)
|
||||
ndisQuerySupported = FALSE;
|
||||
if (!adapterLinkStateSupported)
|
||||
ndisQuerySupported = FALSE;
|
||||
if (!adapterLinkSpeedSupported)
|
||||
ndisQuerySupported = FALSE;
|
||||
|
||||
return ndisQuerySupported;
|
||||
}
|
||||
|
||||
BOOLEAN NetworkAdapterQueryNdisVersion(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_opt_ PUINT MajorVersion,
|
||||
_Out_opt_ PUINT MinorVersion
|
||||
)
|
||||
{
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
ULONG versionResult = 0;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569582.aspx
|
||||
opcode = OID_GEN_DRIVER_VERSION; // OID_GEN_VENDOR_DRIVER_VERSION
|
||||
|
||||
if (NT_SUCCESS(NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
&versionResult,
|
||||
sizeof(versionResult)
|
||||
)))
|
||||
{
|
||||
if (MajorVersion)
|
||||
{
|
||||
*MajorVersion = HIBYTE(versionResult);
|
||||
}
|
||||
|
||||
if (MinorVersion)
|
||||
{
|
||||
*MinorVersion = LOBYTE(versionResult);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PPH_STRING NetworkAdapterQueryName(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ PPH_STRING InterfaceGuid
|
||||
)
|
||||
{
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
WCHAR adapterName[NDIS_IF_MAX_STRING_SIZE + 1] = L"";
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569584.aspx
|
||||
opcode = OID_GEN_FRIENDLY_NAME;
|
||||
|
||||
if (NT_SUCCESS(NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
adapterName,
|
||||
sizeof(adapterName)
|
||||
)))
|
||||
{
|
||||
return PhCreateString(adapterName);
|
||||
}
|
||||
|
||||
if (!GetInterfaceDescriptionFromGuid_I)
|
||||
{
|
||||
if (IphlpHandle = LoadLibrary(L"iphlpapi.dll"))
|
||||
{
|
||||
GetInterfaceDescriptionFromGuid_I = PhGetProcedureAddress(IphlpHandle, "NhGetInterfaceDescriptionFromGuid", 0);
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: Query adapter description using undocumented function.
|
||||
if (GetInterfaceDescriptionFromGuid_I)
|
||||
{
|
||||
GUID deviceGuid = GUID_NULL;
|
||||
UNICODE_STRING guidStringUs;
|
||||
|
||||
PhStringRefToUnicodeString(&InterfaceGuid->sr, &guidStringUs);
|
||||
|
||||
if (NT_SUCCESS(RtlGUIDFromString(&guidStringUs, &deviceGuid)))
|
||||
{
|
||||
WCHAR adapterDescription[NDIS_IF_MAX_STRING_SIZE + 1] = L"";
|
||||
SIZE_T adapterDescriptionLength = sizeof(adapterDescription);
|
||||
|
||||
if (SUCCEEDED(GetInterfaceDescriptionFromGuid_I(&deviceGuid, adapterDescription, &adapterDescriptionLength, NULL, NULL)))
|
||||
{
|
||||
return PhCreateString(adapterDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PhCreateString(L"Unknown Network Adapter");
|
||||
}
|
||||
|
||||
NTSTATUS NetworkAdapterQueryStatistics(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PNDIS_STATISTICS_INFO Info
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
NDIS_STATISTICS_INFO result;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569640.aspx
|
||||
opcode = OID_GEN_STATISTICS;
|
||||
|
||||
memset(&result, 0, sizeof(NDIS_STATISTICS_INFO));
|
||||
result.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
|
||||
result.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
|
||||
result.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
|
||||
|
||||
status = NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
&result,
|
||||
sizeof(result)
|
||||
);
|
||||
|
||||
*Info = result;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS NetworkAdapterQueryLinkState(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PNDIS_LINK_STATE State
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
NDIS_LINK_STATE result;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569595.aspx
|
||||
opcode = OID_GEN_LINK_STATE; // OID_GEN_MEDIA_CONNECT_STATUS;
|
||||
|
||||
memset(&result, 0, sizeof(NDIS_LINK_STATE));
|
||||
result.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
|
||||
result.Header.Revision = NDIS_LINK_STATE_REVISION_1;
|
||||
result.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1;
|
||||
|
||||
status = NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
&result,
|
||||
sizeof(result)
|
||||
);
|
||||
|
||||
*State = result;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOLEAN NetworkAdapterQueryMediaType(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PNDIS_PHYSICAL_MEDIUM Medium
|
||||
)
|
||||
{
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
NDIS_PHYSICAL_MEDIUM adapterMediaType = NdisPhysicalMediumUnspecified;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569622.aspx
|
||||
opcode = OID_GEN_PHYSICAL_MEDIUM_EX;
|
||||
|
||||
if (NT_SUCCESS(NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
&adapterMediaType,
|
||||
sizeof(adapterMediaType)
|
||||
)))
|
||||
{
|
||||
*Medium = adapterMediaType;
|
||||
}
|
||||
|
||||
if (adapterMediaType != NdisPhysicalMediumUnspecified)
|
||||
return TRUE;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569621.aspx
|
||||
opcode = OID_GEN_PHYSICAL_MEDIUM;
|
||||
adapterMediaType = NdisPhysicalMediumUnspecified;
|
||||
memset(&isb, 0, sizeof(IO_STATUS_BLOCK));
|
||||
|
||||
if (NT_SUCCESS(NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
&adapterMediaType,
|
||||
sizeof(adapterMediaType)
|
||||
)))
|
||||
{
|
||||
*Medium = adapterMediaType;
|
||||
}
|
||||
|
||||
if (adapterMediaType != NdisPhysicalMediumUnspecified)
|
||||
return TRUE;
|
||||
|
||||
//NDIS_MEDIUM adapterMediaType = NdisMediumMax;
|
||||
//opcode = OID_GEN_MEDIA_IN_USE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS NetworkAdapterQueryLinkSpeed(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_Out_ PULONG64 LinkSpeed
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
NDIS_OID opcode;
|
||||
IO_STATUS_BLOCK isb;
|
||||
NDIS_LINK_SPEED result;
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569593.aspx
|
||||
opcode = OID_GEN_LINK_SPEED;
|
||||
|
||||
memset(&result, 0, sizeof(NDIS_LINK_SPEED));
|
||||
|
||||
status = NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&opcode,
|
||||
sizeof(NDIS_OID),
|
||||
&result,
|
||||
sizeof(result)
|
||||
);
|
||||
|
||||
*LinkSpeed = UInt32x32To64(result.XmitLinkSpeed, NDIS_UNIT_OF_MEASUREMENT);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
ULONG64 NetworkAdapterQueryValue(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ NDIS_OID OpCode
|
||||
)
|
||||
{
|
||||
IO_STATUS_BLOCK isb;
|
||||
ULONG64 result = 0;
|
||||
|
||||
if (NT_SUCCESS(NtDeviceIoControlFile(
|
||||
DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&isb,
|
||||
IOCTL_NDIS_QUERY_GLOBAL_STATS,
|
||||
&OpCode,
|
||||
sizeof(NDIS_OID),
|
||||
&result,
|
||||
sizeof(result)
|
||||
)))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOLEAN QueryInterfaceRowVista(
|
||||
_In_ PDV_NETADAPTER_ID Id,
|
||||
_Out_ PMIB_IF_ROW2 InterfaceRow
|
||||
)
|
||||
{
|
||||
BOOLEAN result = FALSE;
|
||||
MIB_IF_ROW2 interfaceRow;
|
||||
|
||||
memset(&interfaceRow, 0, sizeof(MIB_IF_ROW2));
|
||||
|
||||
interfaceRow.InterfaceLuid = Id->InterfaceLuid;
|
||||
interfaceRow.InterfaceIndex = Id->InterfaceIndex;
|
||||
|
||||
if (GetIfEntry2)
|
||||
{
|
||||
if (GetIfEntry2(&interfaceRow) == NO_ERROR)
|
||||
{
|
||||
result = TRUE;
|
||||
*InterfaceRow = interfaceRow;
|
||||
}
|
||||
}
|
||||
|
||||
//MIB_IPINTERFACE_ROW interfaceTable;
|
||||
//memset(&interfaceTable, 0, sizeof(MIB_IPINTERFACE_ROW));
|
||||
//interfaceTable.Family = AF_INET;
|
||||
//interfaceTable.InterfaceLuid.Value = Context->AdapterEntry->InterfaceLuidValue;
|
||||
//interfaceTable.InterfaceIndex = Context->AdapterEntry->InterfaceIndex;
|
||||
//GetIpInterfaceEntry(&interfaceTable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOLEAN QueryInterfaceRowXP(
|
||||
_In_ PDV_NETADAPTER_ID Id,
|
||||
_Out_ PMIB_IFROW InterfaceRow
|
||||
)
|
||||
{
|
||||
BOOLEAN result = FALSE;
|
||||
MIB_IFROW interfaceRow;
|
||||
|
||||
memset(&interfaceRow, 0, sizeof(MIB_IFROW));
|
||||
|
||||
interfaceRow.dwIndex = Id->InterfaceIndex;
|
||||
|
||||
if (GetIfEntry(&interfaceRow) == NO_ERROR)
|
||||
{
|
||||
result = TRUE;
|
||||
*InterfaceRow = interfaceRow;
|
||||
}
|
||||
|
||||
//MIB_IPINTERFACE_ROW interfaceTable;
|
||||
//memset(&interfaceTable, 0, sizeof(MIB_IPINTERFACE_ROW));
|
||||
//interfaceTable.Family = AF_INET;
|
||||
//interfaceTable.InterfaceIndex = Context->AdapterEntry->InterfaceIndex;
|
||||
//GetIpInterfaceEntry(&interfaceTable);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//BOOLEAN NetworkAdapterQueryInternet(
|
||||
// _Inout_ PDV_NETADAPTER_SYSINFO_CONTEXT Context,
|
||||
// _In_ PPH_STRING IpAddress
|
||||
// )
|
||||
//{
|
||||
// // https://technet.microsoft.com/en-us/library/cc766017.aspx
|
||||
// BOOLEAN socketResult = FALSE;
|
||||
// WSADATA wsadata;
|
||||
// DNS_STATUS dnsQueryStatus = DNS_ERROR_RCODE_NO_ERROR;
|
||||
// PDNS_RECORD dnsQueryRecords = NULL;
|
||||
//
|
||||
// WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
//
|
||||
// __try
|
||||
// {
|
||||
// if ((dnsQueryStatus = DnsQuery(
|
||||
// L"www.msftncsi.com",
|
||||
// DNS_TYPE_A,
|
||||
// DNS_QUERY_NO_HOSTS_FILE | DNS_QUERY_BYPASS_CACHE,
|
||||
// NULL,
|
||||
// &dnsQueryRecords,
|
||||
// NULL
|
||||
// )) != DNS_ERROR_RCODE_NO_ERROR)
|
||||
// {
|
||||
// __leave;
|
||||
// }
|
||||
//
|
||||
// for (PDNS_RECORD i = dnsQueryRecords; i != NULL; i = i->pNext)
|
||||
// {
|
||||
// if (i->wType == DNS_TYPE_A)
|
||||
// {
|
||||
// SOCKET socketHandle = INVALID_SOCKET;
|
||||
//
|
||||
// if ((socketHandle = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0)) == INVALID_SOCKET)
|
||||
// continue;
|
||||
//
|
||||
// IN_ADDR sockAddr;
|
||||
// InetPton(AF_INET, IpAddress->Buffer, &sockAddr);
|
||||
//
|
||||
// SOCKADDR_IN localaddr = { 0 };
|
||||
// localaddr.sin_family = AF_INET;
|
||||
// localaddr.sin_addr.s_addr = sockAddr.s_addr;
|
||||
//
|
||||
// if (bind(socketHandle, (PSOCKADDR)&localaddr, sizeof(localaddr)) == SOCKET_ERROR)
|
||||
// {
|
||||
// closesocket(socketHandle);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// SOCKADDR_IN remoteAddr;
|
||||
// remoteAddr.sin_family = AF_INET;
|
||||
// remoteAddr.sin_port = htons(80);
|
||||
// remoteAddr.sin_addr.s_addr = i->Data.A.IpAddress;
|
||||
//
|
||||
// if (WSAConnect(socketHandle, (PSOCKADDR)&remoteAddr, sizeof(remoteAddr), NULL, NULL, NULL, NULL) != SOCKET_ERROR)
|
||||
// {
|
||||
// socketResult = TRUE;
|
||||
// closesocket(socketHandle);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// closesocket(socketHandle);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// __finally
|
||||
// {
|
||||
// if (dnsQueryRecords)
|
||||
// {
|
||||
// DnsFree(dnsQueryRecords, DnsFreeRecordList);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// __try
|
||||
// {
|
||||
// if ((dnsQueryStatus = DnsQuery(
|
||||
// L"ipv6.msftncsi.com",
|
||||
// DNS_TYPE_AAAA,
|
||||
// DNS_QUERY_NO_HOSTS_FILE | DNS_QUERY_BYPASS_CACHE, // | DNS_QUERY_DUAL_ADDR
|
||||
// NULL,
|
||||
// &dnsQueryRecords,
|
||||
// NULL
|
||||
// )) != DNS_ERROR_RCODE_NO_ERROR)
|
||||
// {
|
||||
// __leave;
|
||||
// }
|
||||
//
|
||||
// for (PDNS_RECORD i = dnsQueryRecords; i != NULL; i = i->pNext)
|
||||
// {
|
||||
// if (i->wType == DNS_TYPE_AAAA)
|
||||
// {
|
||||
// SOCKET socketHandle = INVALID_SOCKET;
|
||||
//
|
||||
// if ((socketHandle = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0)) == INVALID_SOCKET)
|
||||
// continue;
|
||||
//
|
||||
// IN6_ADDR sockAddr;
|
||||
// InetPton(AF_INET6, IpAddress->Buffer, &sockAddr);
|
||||
//
|
||||
// SOCKADDR_IN6 remoteAddr = { 0 };
|
||||
// remoteAddr.sin6_family = AF_INET6;
|
||||
// remoteAddr.sin6_port = htons(80);
|
||||
// memcpy(&remoteAddr.sin6_addr.u.Byte, i->Data.AAAA.Ip6Address.IP6Byte, sizeof(i->Data.AAAA.Ip6Address.IP6Byte));
|
||||
//
|
||||
// if (WSAConnect(socketHandle, (PSOCKADDR)&remoteAddr, sizeof(SOCKADDR_IN6), NULL, NULL, NULL, NULL) != SOCKET_ERROR)
|
||||
// {
|
||||
// socketResult = TRUE;
|
||||
// closesocket(socketHandle);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// closesocket(socketHandle);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// __finally
|
||||
// {
|
||||
// if (dnsQueryRecords)
|
||||
// {
|
||||
// DnsFree(dnsQueryRecords, DnsFreeRecordList);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// WSACleanup();
|
||||
//
|
||||
// return socketResult;
|
||||
//}
|
||||
787
plugins/HardwareDevices/netdetails.c
Normal file
787
plugins/HardwareDevices/netdetails.c
Normal file
@@ -0,0 +1,787 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
VOID NTAPI NetAdapterProcessesUpdatedHandler(
|
||||
_In_opt_ PVOID Parameter,
|
||||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_DETAILS_CONTEXT context = Context;
|
||||
|
||||
if (context->WindowHandle)
|
||||
{
|
||||
PostMessage(context->WindowHandle, UPDATE_MSG, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
VOID NetAdapterAddListViewItemGroups(
|
||||
_In_ HWND ListViewHandle
|
||||
)
|
||||
{
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
ListView_EnableGroupView(ListViewHandle, TRUE);
|
||||
AddListViewGroup(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, L"Adapter");
|
||||
AddListViewGroup(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, L"Unicast");
|
||||
AddListViewGroup(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, L"Broadcast");
|
||||
AddListViewGroup(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, L"Multicast");
|
||||
AddListViewGroup(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, L"Errors");
|
||||
}
|
||||
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_STATE, L"State", NULL);
|
||||
//AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_CONNECTIVITY, L"Connectivity");
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_IPADDRESS, L"IP address", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_SUBNET, L"Subnet mask", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_GATEWAY, L"Default gateway", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_DNS, L"DNS", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_DOMAIN, L"Domain", NULL);
|
||||
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_LINKSPEED, L"Link speed", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_SENT, L"Sent", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_RECEIVED, L"Received", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_TOTAL, L"Total", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_SENDING, L"Sending", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_RECEIVING, L"Receiving", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ADAPTER, NETADAPTER_DETAILS_INDEX_UTILIZATION, L"Utilization", NULL);
|
||||
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_SENTPKTS, L"Sent packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_RECVPKTS, L"Received packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_TOTALPKTS, L"Total packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_SENT, L"Sent", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_RECEIVED, L"Received", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_TOTAL, L"Total", NULL);
|
||||
//AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_SENDING, L"Sending");
|
||||
//AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_RECEIVING, L"Receiving");
|
||||
//AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_UNICAST, NETADAPTER_DETAILS_INDEX_UNICAST_UTILIZATION, L"Utilization");
|
||||
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, NETADAPTER_DETAILS_INDEX_BROADCAST_SENTPKTS, L"Sent packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, NETADAPTER_DETAILS_INDEX_BROADCAST_RECVPKTS, L"Received packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, NETADAPTER_DETAILS_INDEX_BROADCAST_TOTALPKTS, L"Total packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, NETADAPTER_DETAILS_INDEX_BROADCAST_SENT, L"Sent", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, NETADAPTER_DETAILS_INDEX_BROADCAST_RECEIVED, L"Received", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_BROADCAST, NETADAPTER_DETAILS_INDEX_BROADCAST_TOTAL, L"Total", NULL);
|
||||
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, NETADAPTER_DETAILS_INDEX_MULTICAST_SENTPKTS, L"Sent packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, NETADAPTER_DETAILS_INDEX_MULTICAST_RECVPKTS, L"Received packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, NETADAPTER_DETAILS_INDEX_MULTICAST_TOTALPKTS, L"Total packets", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, NETADAPTER_DETAILS_INDEX_MULTICAST_SENT, L"Sent", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, NETADAPTER_DETAILS_INDEX_MULTICAST_RECEIVED, L"Received", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_MULTICAST, NETADAPTER_DETAILS_INDEX_MULTICAST_TOTAL, L"Total", NULL);
|
||||
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, NETADAPTER_DETAILS_INDEX_ERRORS_SENTPKTS, L"Send errors", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, NETADAPTER_DETAILS_INDEX_ERRORS_RECVPKTS, L"Receive errors", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, NETADAPTER_DETAILS_INDEX_ERRORS_TOTALPKTS, L"Total errors", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, NETADAPTER_DETAILS_INDEX_ERRORS_SENT, L"Send discards", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, NETADAPTER_DETAILS_INDEX_ERRORS_RECEIVED, L"Receive discards", NULL);
|
||||
AddListViewItemGroupId(ListViewHandle, NETADAPTER_DETAILS_CATEGORY_ERRORS, NETADAPTER_DETAILS_INDEX_ERRORS_TOTAL, L"Total discards", NULL);
|
||||
}
|
||||
|
||||
PVOID NetAdapterGetAddresses(
|
||||
_In_ ULONG Family
|
||||
)
|
||||
{
|
||||
ULONG flags;
|
||||
ULONG bufferLength = 0;
|
||||
PIP_ADAPTER_ADDRESSES buffer = NULL;
|
||||
|
||||
flags = GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
flags |= GAA_FLAG_INCLUDE_ALL_INTERFACES;
|
||||
}
|
||||
|
||||
if (GetAdaptersAddresses(Family, flags, NULL, NULL, &bufferLength) != ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = PhAllocate(bufferLength);
|
||||
memset(buffer, 0, bufferLength);
|
||||
|
||||
if (GetAdaptersAddresses(Family, flags, NULL, buffer, &bufferLength) != ERROR_SUCCESS)
|
||||
{
|
||||
PhFree(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
VOID NetAdapterEnumerateAddresses(
|
||||
_In_ PVOID AddressesBuffer,
|
||||
_In_ ULONG64 InterfaceLuid,
|
||||
_In_ PPH_STRING_BUILDER DomainBuffer,
|
||||
_In_ PPH_STRING_BUILDER IpAddressBuffer,
|
||||
_In_ PPH_STRING_BUILDER SubnetAddressBuffer,
|
||||
_In_ PPH_STRING_BUILDER GatewayAddressBuffer,
|
||||
_In_ PPH_STRING_BUILDER DnsAddressBuffer
|
||||
)
|
||||
{
|
||||
PIP_ADAPTER_ADDRESSES addressesBuffer;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS unicastAddress;
|
||||
PIP_ADAPTER_GATEWAY_ADDRESS gatewayAddress;
|
||||
PIP_ADAPTER_DNS_SERVER_ADDRESS dnsAddress;
|
||||
|
||||
for (addressesBuffer = AddressesBuffer; addressesBuffer; addressesBuffer = addressesBuffer->Next)
|
||||
{
|
||||
if (addressesBuffer->Luid.Value != InterfaceLuid)
|
||||
continue;
|
||||
|
||||
if (addressesBuffer->DnsSuffix && PhCountStringZ(addressesBuffer->DnsSuffix) > 0)
|
||||
{
|
||||
PhAppendFormatStringBuilder(DomainBuffer, L"%s, ", addressesBuffer->DnsSuffix);
|
||||
}
|
||||
|
||||
for (unicastAddress = addressesBuffer->FirstUnicastAddress; unicastAddress; unicastAddress = unicastAddress->Next)
|
||||
{
|
||||
if (unicastAddress->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
PSOCKADDR_IN sockAddrIn = { 0 };
|
||||
IN_ADDR subnetMask = { 0 };
|
||||
WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
|
||||
WCHAR subnetAddressString[INET_ADDRSTRLEN] = L"";
|
||||
|
||||
sockAddrIn = (PSOCKADDR_IN)unicastAddress->Address.lpSockaddr;
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA && ConvertLengthToIpv4Mask)
|
||||
{
|
||||
ConvertLengthToIpv4Mask(unicastAddress->OnLinkPrefixLength, &subnetMask.s_addr);
|
||||
}
|
||||
|
||||
if (RtlIpv4AddressToString(&sockAddrIn->sin_addr, ipv4AddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(IpAddressBuffer, L"%s, ", ipv4AddressString);
|
||||
}
|
||||
|
||||
if (RtlIpv4AddressToString(&subnetMask, subnetAddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(SubnetAddressBuffer, L"%s, ", subnetAddressString);
|
||||
}
|
||||
}
|
||||
|
||||
if (unicastAddress->Address.lpSockaddr->sa_family == AF_INET6)
|
||||
{
|
||||
PSOCKADDR_IN6 sockAddrIn6 = { 0 };
|
||||
WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
|
||||
|
||||
sockAddrIn6 = (PSOCKADDR_IN6)unicastAddress->Address.lpSockaddr;
|
||||
|
||||
if (RtlIpv6AddressToString(&sockAddrIn6->sin6_addr, ipv6AddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(IpAddressBuffer, L"%s, ", ipv6AddressString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (gatewayAddress = addressesBuffer->FirstGatewayAddress; gatewayAddress; gatewayAddress = gatewayAddress->Next)
|
||||
{
|
||||
if (gatewayAddress->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
PSOCKADDR_IN sockAddrIn = { 0 };
|
||||
WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
|
||||
|
||||
sockAddrIn = (PSOCKADDR_IN)gatewayAddress->Address.lpSockaddr;
|
||||
|
||||
if (RtlIpv4AddressToString(&sockAddrIn->sin_addr, ipv4AddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(GatewayAddressBuffer, L"%s, ", ipv4AddressString);
|
||||
}
|
||||
}
|
||||
|
||||
if (gatewayAddress->Address.lpSockaddr->sa_family == AF_INET6)
|
||||
{
|
||||
PSOCKADDR_IN6 sockAddrIn6 = (PSOCKADDR_IN6)gatewayAddress->Address.lpSockaddr;
|
||||
WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
|
||||
|
||||
if (RtlIpv6AddressToString(&sockAddrIn6->sin6_addr, ipv6AddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(GatewayAddressBuffer, L"%s, ", ipv6AddressString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (dnsAddress = addressesBuffer->FirstDnsServerAddress; dnsAddress; dnsAddress = dnsAddress->Next)
|
||||
{
|
||||
if (dnsAddress->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
PSOCKADDR_IN sockAddrIn = (PSOCKADDR_IN)dnsAddress->Address.lpSockaddr;
|
||||
WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
|
||||
|
||||
if (RtlIpv4AddressToString(&sockAddrIn->sin_addr, ipv4AddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(DnsAddressBuffer, L"%s, ", ipv4AddressString);
|
||||
}
|
||||
}
|
||||
else if (dnsAddress->Address.lpSockaddr->sa_family == AF_INET6)
|
||||
{
|
||||
PSOCKADDR_IN6 sockAddrIn6 = (PSOCKADDR_IN6)dnsAddress->Address.lpSockaddr;
|
||||
WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
|
||||
|
||||
if (RtlIpv6AddressToString(&sockAddrIn6->sin6_addr, ipv6AddressString))
|
||||
{
|
||||
PhAppendFormatStringBuilder(DnsAddressBuffer, L"%s, ", ipv6AddressString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID NetAdapterLookupConfig(
|
||||
_Inout_ PDV_NETADAPTER_DETAILS_CONTEXT Context
|
||||
)
|
||||
{
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
PVOID addressesBuffer = NULL;
|
||||
PPH_STRING domainString = NULL;
|
||||
PPH_STRING ipAddressString = NULL;
|
||||
PPH_STRING subnetAddressString = NULL;
|
||||
PPH_STRING gatewayAddressString = NULL;
|
||||
PPH_STRING dnsAddressString = NULL;
|
||||
PH_STRING_BUILDER domainBuffer;
|
||||
PH_STRING_BUILDER ipAddressBuffer;
|
||||
PH_STRING_BUILDER subnetAddressBuffer;
|
||||
PH_STRING_BUILDER gatewayAddressBuffer;
|
||||
PH_STRING_BUILDER dnsAddressBuffer;
|
||||
|
||||
PhInitializeStringBuilder(&domainBuffer, 64);
|
||||
PhInitializeStringBuilder(&ipAddressBuffer, 64);
|
||||
PhInitializeStringBuilder(&subnetAddressBuffer, 64);
|
||||
PhInitializeStringBuilder(&gatewayAddressBuffer, 64);
|
||||
PhInitializeStringBuilder(&dnsAddressBuffer, 64);
|
||||
|
||||
if (addressesBuffer = NetAdapterGetAddresses(AF_INET))
|
||||
{
|
||||
NetAdapterEnumerateAddresses(
|
||||
addressesBuffer,
|
||||
Context->AdapterId.InterfaceLuid.Value,
|
||||
&domainBuffer,
|
||||
&ipAddressBuffer,
|
||||
&subnetAddressBuffer,
|
||||
&gatewayAddressBuffer,
|
||||
&dnsAddressBuffer
|
||||
);
|
||||
PhFree(addressesBuffer);
|
||||
}
|
||||
|
||||
if (addressesBuffer = NetAdapterGetAddresses(AF_INET6))
|
||||
{
|
||||
NetAdapterEnumerateAddresses(
|
||||
addressesBuffer,
|
||||
Context->AdapterId.InterfaceLuid.Value,
|
||||
&domainBuffer,
|
||||
&ipAddressBuffer,
|
||||
&subnetAddressBuffer,
|
||||
&gatewayAddressBuffer,
|
||||
&dnsAddressBuffer
|
||||
);
|
||||
PhFree(addressesBuffer);
|
||||
}
|
||||
|
||||
if (domainBuffer.String->Length > 2)
|
||||
PhRemoveEndStringBuilder(&domainBuffer, 2);
|
||||
if (ipAddressBuffer.String->Length > 2)
|
||||
PhRemoveEndStringBuilder(&ipAddressBuffer, 2);
|
||||
if (subnetAddressBuffer.String->Length > 2)
|
||||
PhRemoveEndStringBuilder(&subnetAddressBuffer, 2);
|
||||
if (gatewayAddressBuffer.String->Length > 2)
|
||||
PhRemoveEndStringBuilder(&gatewayAddressBuffer, 2);
|
||||
if (dnsAddressBuffer.String->Length > 2)
|
||||
PhRemoveEndStringBuilder(&dnsAddressBuffer, 2);
|
||||
|
||||
domainString = PhFinalStringBuilderString(&domainBuffer);
|
||||
ipAddressString = PhFinalStringBuilderString(&ipAddressBuffer);
|
||||
subnetAddressString = PhFinalStringBuilderString(&subnetAddressBuffer);
|
||||
gatewayAddressString = PhFinalStringBuilderString(&gatewayAddressBuffer);
|
||||
dnsAddressString = PhFinalStringBuilderString(&dnsAddressBuffer);
|
||||
|
||||
//PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_CONNECTIVITY, 1, internet ? L"Internet" : L"Local");
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_IPADDRESS, 1, ipAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_SUBNET, 1, subnetAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_GATEWAY, 1, gatewayAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_DNS, 1, dnsAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_DOMAIN, 1, domainString->Buffer);
|
||||
|
||||
PhDeleteStringBuilder(&domainBuffer);
|
||||
PhDeleteStringBuilder(&ipAddressBuffer);
|
||||
PhDeleteStringBuilder(&subnetAddressBuffer);
|
||||
PhDeleteStringBuilder(&gatewayAddressBuffer);
|
||||
PhDeleteStringBuilder(&dnsAddressBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
static PH_STRINGREF tcpIpv4KeyName = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
|
||||
HANDLE keyHandle;
|
||||
PPH_STRING keyNameIpV4;
|
||||
|
||||
keyNameIpV4 = PhConcatStringRef2(&tcpIpv4KeyName, &Context->AdapterId.InterfaceGuid->sr);
|
||||
|
||||
if (NT_SUCCESS(PhOpenKey(
|
||||
&keyHandle,
|
||||
KEY_READ,
|
||||
PH_KEY_LOCAL_MACHINE,
|
||||
&keyNameIpV4->sr,
|
||||
0
|
||||
)))
|
||||
{
|
||||
PPH_STRING domainString = NULL;
|
||||
PPH_STRING ipAddressString = NULL;
|
||||
PPH_STRING subnetAddressString = NULL;
|
||||
PPH_STRING gatewayAddressString = NULL;
|
||||
|
||||
domainString = PhQueryRegistryString(keyHandle, L"DhcpDomain");
|
||||
ipAddressString = PhQueryRegistryString(keyHandle, L"DhcpIPAddress");
|
||||
subnetAddressString = PhQueryRegistryString(keyHandle, L"DhcpSubnetMask");
|
||||
gatewayAddressString = PhQueryRegistryString(keyHandle, L"DhcpDefaultGateway");
|
||||
|
||||
if (PhIsNullOrEmptyString(domainString))
|
||||
PhMoveReference(&domainString, PhQueryRegistryString(keyHandle, L"Domain"));
|
||||
|
||||
if (PhIsNullOrEmptyString(ipAddressString))
|
||||
PhMoveReference(&ipAddressString, PhQueryRegistryString(keyHandle, L"IPAddress"));
|
||||
|
||||
if (PhIsNullOrEmptyString(subnetAddressString))
|
||||
PhMoveReference(&subnetAddressString, PhQueryRegistryString(keyHandle, L"SubnetMask"));
|
||||
|
||||
if (PhIsNullOrEmptyString(gatewayAddressString))
|
||||
PhMoveReference(&gatewayAddressString, PhQueryRegistryString(keyHandle, L"DefaultGateway"));
|
||||
|
||||
//PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_CONNECTIVITY, 1, internet ? L"Internet" : L"Local");
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_IPADDRESS, 1, PhIsNullOrEmptyString(ipAddressString) ? L"" : ipAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_SUBNET, 1, PhIsNullOrEmptyString(subnetAddressString) ? L"" : subnetAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_GATEWAY, 1, PhIsNullOrEmptyString(gatewayAddressString) ? L"" : gatewayAddressString->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_DOMAIN, 1, PhIsNullOrEmptyString(domainString) ? L"" : domainString->Buffer);
|
||||
|
||||
PhClearReference(&domainString);
|
||||
PhClearReference(&ipAddressString);
|
||||
PhClearReference(&subnetAddressString);
|
||||
PhClearReference(&gatewayAddressString);
|
||||
|
||||
NtClose(keyHandle);
|
||||
}
|
||||
|
||||
PhDereferenceObject(keyNameIpV4);
|
||||
}
|
||||
}
|
||||
|
||||
VOID NETIOAPI_API_ NetAdapterChangeCallback(
|
||||
_In_ PVOID CallerContext,
|
||||
_In_opt_ PMIB_IPINTERFACE_ROW Row,
|
||||
_In_ MIB_NOTIFICATION_TYPE NotificationType
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_DETAILS_CONTEXT context = CallerContext;
|
||||
|
||||
if (NotificationType == MibInitialNotification)
|
||||
{
|
||||
NetAdapterLookupConfig(context);
|
||||
}
|
||||
else if (NotificationType == MibParameterNotification)
|
||||
{
|
||||
if (Row->InterfaceLuid.Value = context->AdapterId.InterfaceLuid.Value)
|
||||
{
|
||||
NetAdapterLookupConfig(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID NetAdapterUpdateDetails(
|
||||
_Inout_ PDV_NETADAPTER_DETAILS_CONTEXT Context
|
||||
)
|
||||
{
|
||||
ULONG64 interfaceLinkSpeed = 0;
|
||||
ULONG64 interfaceRcvSpeed = 0;
|
||||
ULONG64 interfaceXmitSpeed = 0;
|
||||
NDIS_STATISTICS_INFO interfaceStats = { 0 };
|
||||
NDIS_MEDIA_CONNECT_STATE mediaState = MediaConnectStateUnknown;
|
||||
HANDLE deviceHandle = NULL;
|
||||
|
||||
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_NDIS))
|
||||
{
|
||||
// Create the handle to the network device
|
||||
if (NT_SUCCESS(NetworkAdapterCreateHandle(&deviceHandle, Context->AdapterId.InterfaceGuid)))
|
||||
{
|
||||
if (!Context->CheckedDeviceSupport)
|
||||
{
|
||||
// Check the network adapter supports the OIDs we're going to be using.
|
||||
if (NetworkAdapterQuerySupported(deviceHandle))
|
||||
{
|
||||
Context->DeviceSupported = TRUE;
|
||||
}
|
||||
|
||||
Context->CheckedDeviceSupport = TRUE;
|
||||
}
|
||||
|
||||
if (!Context->DeviceSupported)
|
||||
{
|
||||
// Device is faulty. Close the handle so we can fallback to GetIfEntry.
|
||||
NtClose(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceHandle)
|
||||
{
|
||||
NDIS_LINK_STATE interfaceState;
|
||||
|
||||
NetworkAdapterQueryStatistics(deviceHandle, &interfaceStats);
|
||||
|
||||
if (NT_SUCCESS(NetworkAdapterQueryLinkState(deviceHandle, &interfaceState)))
|
||||
{
|
||||
mediaState = interfaceState.MediaConnectState;
|
||||
interfaceLinkSpeed = interfaceState.XmitLinkSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkAdapterQueryLinkSpeed(deviceHandle, &interfaceLinkSpeed);
|
||||
}
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WindowsVersion >= WINDOWS_VISTA && GetIfEntry2)
|
||||
{
|
||||
MIB_IF_ROW2 interfaceRow;
|
||||
|
||||
if (QueryInterfaceRowVista(&Context->AdapterId, &interfaceRow))
|
||||
{
|
||||
interfaceStats.ifInDiscards = interfaceRow.InDiscards;
|
||||
interfaceStats.ifInErrors = interfaceRow.InErrors;
|
||||
interfaceStats.ifHCInOctets = interfaceRow.InOctets;
|
||||
interfaceStats.ifHCInUcastPkts = interfaceRow.InUcastPkts;
|
||||
//interfaceStats.ifHCInMulticastPkts;
|
||||
//interfaceStats.ifHCInBroadcastPkts;
|
||||
interfaceStats.ifHCOutOctets = interfaceRow.OutOctets;
|
||||
interfaceStats.ifHCOutUcastPkts = interfaceRow.OutUcastPkts;
|
||||
//interfaceStats.ifHCOutMulticastPkts;
|
||||
//interfaceStats.ifHCOutBroadcastPkts;
|
||||
interfaceStats.ifOutErrors = interfaceRow.OutErrors;
|
||||
interfaceStats.ifOutDiscards = interfaceRow.OutDiscards;
|
||||
interfaceStats.ifHCInUcastOctets = interfaceRow.InUcastOctets;
|
||||
interfaceStats.ifHCInMulticastOctets = interfaceRow.InMulticastOctets;
|
||||
interfaceStats.ifHCInBroadcastOctets = interfaceRow.InBroadcastOctets;
|
||||
interfaceStats.ifHCOutUcastOctets = interfaceRow.OutUcastOctets;
|
||||
interfaceStats.ifHCOutMulticastOctets = interfaceRow.OutMulticastOctets;
|
||||
interfaceStats.ifHCOutBroadcastOctets = interfaceRow.OutBroadcastOctets;
|
||||
//interfaceRow.InNUcastPkts;
|
||||
//interfaceRow.InUnknownProtos;
|
||||
//interfaceRow.OutNUcastPkts;
|
||||
//interfaceRow.OutQLen;
|
||||
|
||||
mediaState = interfaceRow.MediaConnectState;
|
||||
interfaceLinkSpeed = interfaceRow.TransmitLinkSpeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MIB_IFROW interfaceRow;
|
||||
|
||||
if (QueryInterfaceRowXP(&Context->AdapterId, &interfaceRow))
|
||||
{
|
||||
interfaceStats.ifInDiscards = interfaceRow.dwInDiscards;
|
||||
interfaceStats.ifInErrors = interfaceRow.dwInErrors;
|
||||
interfaceStats.ifHCInOctets = interfaceRow.dwInOctets;
|
||||
interfaceStats.ifHCInUcastPkts = interfaceRow.dwInUcastPkts;
|
||||
//interfaceStats.ifHCInMulticastPkts;
|
||||
//interfaceStats.ifHCInBroadcastPkts;
|
||||
interfaceStats.ifHCOutOctets = interfaceRow.dwOutOctets;
|
||||
interfaceStats.ifHCOutUcastPkts = interfaceRow.dwOutUcastPkts;
|
||||
//interfaceStats.ifHCOutMulticastPkts;
|
||||
//interfaceStats.ifHCOutBroadcastPkts;
|
||||
interfaceStats.ifOutErrors = interfaceRow.dwOutErrors;
|
||||
interfaceStats.ifOutDiscards = interfaceRow.dwOutDiscards;
|
||||
//interfaceStats.ifHCInUcastOctets;
|
||||
//interfaceStats.ifHCInMulticastOctets;
|
||||
//interfaceStats.ifHCInBroadcastOctets;
|
||||
//interfaceStats.ifHCOutUcastOctets;
|
||||
//interfaceStats.ifHCOutMulticastOctets;
|
||||
//interfaceStats.ifHCOutBroadcastOctets;
|
||||
//interfaceRow.InNUcastPkts;
|
||||
//interfaceRow.InUnknownProtos;
|
||||
//interfaceRow.OutNUcastPkts;
|
||||
//interfaceRow.OutQLen;
|
||||
|
||||
mediaState = interfaceRow.dwOperStatus == IF_OPER_STATUS_OPERATIONAL ? MediaConnectStateConnected : MediaConnectStateDisconnected;
|
||||
interfaceLinkSpeed = interfaceRow.dwSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interfaceRcvSpeed = interfaceStats.ifHCInOctets - Context->LastDetailsInboundValue;
|
||||
interfaceXmitSpeed = interfaceStats.ifHCOutOctets - Context->LastDetailsIOutboundValue;
|
||||
//interfaceRcvUnicastSpeed = interfaceStats.ifHCInUcastOctets - Context->LastDetailsInboundUnicastValue;
|
||||
//interfaceXmitUnicastSpeed = interfaceStats.ifHCOutUcastOctets - Context->LastDetailsIOutboundUnicastValue;
|
||||
|
||||
if (!Context->HaveFirstSample)
|
||||
{
|
||||
interfaceRcvSpeed = 0;
|
||||
interfaceXmitSpeed = 0;
|
||||
Context->HaveFirstSample = TRUE;
|
||||
}
|
||||
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_STATE, 1, mediaState == MediaConnectStateConnected ? L"Connected" : L"Disconnected");
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_LINKSPEED, 1, PhaFormatString(L"%s/s", PhaFormatSize(interfaceLinkSpeed / BITS_IN_ONE_BYTE, -1)->Buffer)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_SENT, 1, PhaFormatSize(interfaceStats.ifHCOutOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_RECEIVED, 1, PhaFormatSize(interfaceStats.ifHCInOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_TOTAL, 1, PhaFormatSize(interfaceStats.ifHCInOctets + interfaceStats.ifHCOutOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_SENDING, 1, interfaceXmitSpeed != 0 ? PhaFormatString(L"%s/s", PhaFormatSize(interfaceXmitSpeed, -1)->Buffer)->Buffer : L"");
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_RECEIVING, 1, interfaceRcvSpeed != 0 ? PhaFormatString(L"%s/s", PhaFormatSize(interfaceRcvSpeed, -1)->Buffer)->Buffer : L"");
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UTILIZATION, 1, PhaFormatString(L"%.2f%%", (FLOAT)(interfaceRcvSpeed + interfaceXmitSpeed) / (interfaceLinkSpeed / BITS_IN_ONE_BYTE) * 100)->Buffer);
|
||||
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_SENTPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCOutUcastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_RECVPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCInUcastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_TOTALPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCInUcastPkts + interfaceStats.ifHCOutUcastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_SENT, 1, PhaFormatSize(interfaceStats.ifHCOutUcastOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_RECEIVED, 1, PhaFormatSize(interfaceStats.ifHCInUcastOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_TOTAL, 1, PhaFormatSize(interfaceStats.ifHCInUcastOctets + interfaceStats.ifHCOutUcastOctets, -1)->Buffer);
|
||||
//PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_SENDING, 1, interfaceXmitUnicastSpeed != 0 ? PhaFormatString(L"%s/s", PhaFormatSize(interfaceXmitUnicastSpeed, -1)->Buffer)->Buffer : L"");
|
||||
//PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_RECEIVING, 1, interfaceRcvUnicastSpeed != 0 ? PhaFormatString(L"%s/s", PhaFormatSize(interfaceRcvUnicastSpeed, -1)->Buffer)->Buffer : L"");
|
||||
//PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_UNICAST_UTILIZATION, 1, PhaFormatString(L"%.2f%%", utilization2)->Buffer);
|
||||
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_BROADCAST_SENTPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCOutBroadcastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_BROADCAST_RECVPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCInBroadcastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_BROADCAST_TOTALPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCInBroadcastPkts + interfaceStats.ifHCOutBroadcastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_BROADCAST_SENT, 1, PhaFormatSize(interfaceStats.ifHCOutBroadcastOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_BROADCAST_RECEIVED, 1, PhaFormatSize(interfaceStats.ifHCInBroadcastOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_BROADCAST_TOTAL, 1, PhaFormatSize(interfaceStats.ifHCInBroadcastOctets + interfaceStats.ifHCOutBroadcastOctets, -1)->Buffer);
|
||||
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_MULTICAST_SENTPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCOutMulticastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_MULTICAST_RECVPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCInMulticastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_MULTICAST_TOTALPKTS, 1, PhaFormatUInt64(interfaceStats.ifHCInMulticastPkts + interfaceStats.ifHCOutMulticastPkts, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_MULTICAST_SENT, 1, PhaFormatSize(interfaceStats.ifHCOutMulticastOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_MULTICAST_RECEIVED, 1, PhaFormatSize(interfaceStats.ifHCInMulticastOctets, -1)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_MULTICAST_TOTAL, 1, PhaFormatSize(interfaceStats.ifHCInMulticastOctets + interfaceStats.ifHCOutMulticastOctets, -1)->Buffer);
|
||||
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_ERRORS_SENTPKTS, 1, PhaFormatUInt64(interfaceStats.ifOutErrors, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_ERRORS_RECVPKTS, 1, PhaFormatUInt64(interfaceStats.ifInErrors, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_ERRORS_TOTALPKTS, 1, PhaFormatUInt64(interfaceStats.ifInErrors + interfaceStats.ifOutErrors, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_ERRORS_SENT, 1, PhaFormatUInt64(interfaceStats.ifOutDiscards, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_ERRORS_RECEIVED, 1, PhaFormatUInt64(interfaceStats.ifInDiscards, TRUE)->Buffer);
|
||||
PhSetListViewSubItem(Context->ListViewHandle, NETADAPTER_DETAILS_INDEX_ERRORS_TOTAL, 1, PhaFormatUInt64(interfaceStats.ifInDiscards + interfaceStats.ifOutDiscards, TRUE)->Buffer);
|
||||
|
||||
Context->LastDetailsInboundValue = interfaceStats.ifHCInOctets;
|
||||
Context->LastDetailsIOutboundValue = interfaceStats.ifHCOutOctets;
|
||||
//Context->LastDetailsInboundUnicastValue = interfaceStats.ifHCInUcastOctets;
|
||||
//Context->LastDetailsIOutboundUnicastValue = interfaceStats.ifHCOutUcastOctets;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK NetAdapterDetailsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_DETAILS_CONTEXT context;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_NETADAPTER_DETAILS_CONTEXT)lParam;
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_NETADAPTER_DETAILS_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
context->WindowHandle = hwndDlg;
|
||||
context->ListViewHandle = GetDlgItem(hwndDlg, IDC_DETAILS_LIST);
|
||||
|
||||
if (context->AdapterName)
|
||||
SetWindowText(hwndDlg, context->AdapterName->Buffer);
|
||||
else
|
||||
SetWindowText(hwndDlg, L"Unknown network adapter");
|
||||
|
||||
PhCenterWindow(hwndDlg, context->ParentHandle);
|
||||
|
||||
PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
|
||||
PhSetControlTheme(context->ListViewHandle, L"explorer");
|
||||
PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 315, L"Property");
|
||||
PhAddListViewColumn(context->ListViewHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Value");
|
||||
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhAddLayoutItem(&context->LayoutManager, context->ListViewHandle, NULL, PH_ANCHOR_ALL);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
|
||||
|
||||
NetAdapterAddListViewItemGroups(context->ListViewHandle);
|
||||
|
||||
PhRegisterCallback(
|
||||
&PhProcessesUpdatedEvent,
|
||||
NetAdapterProcessesUpdatedHandler,
|
||||
context,
|
||||
&context->ProcessesUpdatedRegistration
|
||||
);
|
||||
|
||||
NetAdapterLookupConfig(context);
|
||||
NetAdapterUpdateDetails(context);
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA && NotifyIpInterfaceChange)
|
||||
{
|
||||
NotifyIpInterfaceChange(
|
||||
AF_UNSPEC,
|
||||
NetAdapterChangeCallback,
|
||||
context,
|
||||
FALSE,
|
||||
&context->NotifyHandle
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PhUnregisterCallback(
|
||||
&PhProcessesUpdatedEvent,
|
||||
&context->ProcessesUpdatedRegistration
|
||||
);
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA && CancelMibChangeNotify2 && context->NotifyHandle)
|
||||
{
|
||||
CancelMibChangeNotify2(context->NotifyHandle);
|
||||
}
|
||||
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
DestroyWindow(hwndDlg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
}
|
||||
break;
|
||||
case WM_SHOWDIALOG:
|
||||
{
|
||||
if (IsMinimized(hwndDlg))
|
||||
ShowWindow(hwndDlg, SW_RESTORE);
|
||||
else
|
||||
ShowWindow(hwndDlg, SW_SHOW);
|
||||
|
||||
SetForegroundWindow(hwndDlg);
|
||||
}
|
||||
break;
|
||||
case UPDATE_MSG:
|
||||
{
|
||||
NetAdapterUpdateDetails(context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID FreeNetAdapterDetailsContext(
|
||||
_In_ PDV_NETADAPTER_DETAILS_CONTEXT Context
|
||||
)
|
||||
{
|
||||
DeleteNetAdapterId(&Context->AdapterId);
|
||||
PhClearReference(&Context->AdapterName);
|
||||
PhFree(Context);
|
||||
}
|
||||
|
||||
NTSTATUS ShowNetAdapterDetailsDialogThread(
|
||||
_In_ PVOID Parameter
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_DETAILS_CONTEXT context = (PDV_NETADAPTER_DETAILS_CONTEXT)Parameter;
|
||||
BOOL result;
|
||||
MSG message;
|
||||
HWND dialogHandle;
|
||||
PH_AUTO_POOL autoPool;
|
||||
|
||||
PhInitializeAutoPool(&autoPool);
|
||||
|
||||
dialogHandle = CreateDialogParam(
|
||||
PluginInstance->DllBase,
|
||||
MAKEINTRESOURCE(IDD_NETADAPTER_DETAILS),
|
||||
NULL,
|
||||
NetAdapterDetailsDlgProc,
|
||||
(LPARAM)context
|
||||
);
|
||||
|
||||
PostMessage(dialogHandle, WM_SHOWDIALOG, 0, 0);
|
||||
|
||||
while (result = GetMessage(&message, NULL, 0, 0))
|
||||
{
|
||||
if (result == -1)
|
||||
break;
|
||||
|
||||
if (!IsDialogMessage(dialogHandle, &message))
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
DispatchMessage(&message);
|
||||
}
|
||||
|
||||
PhDrainAutoPool(&autoPool);
|
||||
}
|
||||
|
||||
PhDeleteAutoPool(&autoPool);
|
||||
|
||||
FreeNetAdapterDetailsContext(context);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID ShowNetAdapterDetailsDialog(
|
||||
_In_ PDV_NETADAPTER_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
HANDLE dialogThread = NULL;
|
||||
PDV_NETADAPTER_DETAILS_CONTEXT context;
|
||||
|
||||
context = PhAllocate(sizeof(DV_NETADAPTER_DETAILS_CONTEXT));
|
||||
memset(context, 0, sizeof(DV_NETADAPTER_DETAILS_CONTEXT));
|
||||
|
||||
context->ParentHandle = Context->WindowHandle;
|
||||
PhSetReference(&context->AdapterName, Context->AdapterEntry->AdapterName);
|
||||
CopyNetAdapterId(&context->AdapterId, &Context->AdapterEntry->Id);
|
||||
|
||||
if (dialogThread = PhCreateThread(0, ShowNetAdapterDetailsDialogThread, context))
|
||||
NtClose(dialogThread);
|
||||
else
|
||||
FreeNetAdapterDetailsContext(context);
|
||||
}
|
||||
549
plugins/HardwareDevices/netgraph.c
Normal file
549
plugins/HardwareDevices/netgraph.c
Normal file
@@ -0,0 +1,549 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
VOID NetAdapterUpdateGraphs(
|
||||
_Inout_ PDV_NETADAPTER_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
Context->GraphState.Valid = FALSE;
|
||||
Context->GraphState.TooltipIndex = -1;
|
||||
Graph_MoveGrid(Context->GraphHandle, 1);
|
||||
Graph_Draw(Context->GraphHandle);
|
||||
Graph_UpdateTooltip(Context->GraphHandle);
|
||||
InvalidateRect(Context->GraphHandle, NULL, FALSE);
|
||||
}
|
||||
|
||||
VOID NetAdapterUpdatePanel(
|
||||
_Inout_ PDV_NETADAPTER_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
ULONG64 inOctets = 0;
|
||||
ULONG64 outOctets = 0;
|
||||
ULONG64 linkSpeed = 0;
|
||||
NDIS_MEDIA_CONNECT_STATE mediaState = MediaConnectStateUnknown;
|
||||
HANDLE deviceHandle = NULL;
|
||||
|
||||
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_NDIS))
|
||||
{
|
||||
// Create the handle to the network device
|
||||
if (NT_SUCCESS(NetworkAdapterCreateHandle(&deviceHandle, Context->AdapterEntry->Id.InterfaceGuid)))
|
||||
{
|
||||
if (!Context->AdapterEntry->CheckedDeviceSupport)
|
||||
{
|
||||
// Check the network adapter supports the OIDs we're going to be using.
|
||||
if (NetworkAdapterQuerySupported(deviceHandle))
|
||||
{
|
||||
Context->AdapterEntry->DeviceSupported = TRUE;
|
||||
}
|
||||
|
||||
Context->AdapterEntry->CheckedDeviceSupport = TRUE;
|
||||
}
|
||||
|
||||
if (!Context->AdapterEntry->DeviceSupported)
|
||||
{
|
||||
// Device is faulty. Close the handle so we can fallback to GetIfEntry.
|
||||
NtClose(deviceHandle);
|
||||
deviceHandle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceHandle)
|
||||
{
|
||||
NDIS_STATISTICS_INFO interfaceStats;
|
||||
NDIS_LINK_STATE interfaceState;
|
||||
|
||||
if (NT_SUCCESS(NetworkAdapterQueryStatistics(deviceHandle, &interfaceStats)))
|
||||
{
|
||||
if (!(interfaceStats.SupportedStatistics & NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV))
|
||||
inOctets = NetworkAdapterQueryValue(deviceHandle, OID_GEN_BYTES_RCV);
|
||||
else
|
||||
inOctets = interfaceStats.ifHCInOctets;
|
||||
|
||||
if (!(interfaceStats.SupportedStatistics & NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT))
|
||||
outOctets = NetworkAdapterQueryValue(deviceHandle, OID_GEN_BYTES_XMIT);
|
||||
else
|
||||
outOctets = interfaceStats.ifHCOutOctets;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: The above code fails for some drivers that don't implement statistics (even though statistics are mandatory).
|
||||
// NDIS handles these two OIDs for all miniport drivers and we can use these for those special cases.
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569443.aspx
|
||||
inOctets = NetworkAdapterQueryValue(deviceHandle, OID_GEN_BYTES_RCV);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff569445.aspx
|
||||
outOctets = NetworkAdapterQueryValue(deviceHandle, OID_GEN_BYTES_XMIT);
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(NetworkAdapterQueryLinkState(deviceHandle, &interfaceState)))
|
||||
{
|
||||
mediaState = interfaceState.MediaConnectState;
|
||||
linkSpeed = interfaceState.XmitLinkSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
NetworkAdapterQueryLinkSpeed(deviceHandle, &linkSpeed);
|
||||
}
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
else if (WindowsVersion >= WINDOWS_VISTA && GetIfEntry2)
|
||||
{
|
||||
MIB_IF_ROW2 interfaceRow;
|
||||
|
||||
if (QueryInterfaceRowVista(&Context->AdapterEntry->Id, &interfaceRow))
|
||||
{
|
||||
inOctets = interfaceRow.InOctets;
|
||||
outOctets = interfaceRow.OutOctets;
|
||||
mediaState = interfaceRow.MediaConnectState;
|
||||
linkSpeed = interfaceRow.TransmitLinkSpeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MIB_IFROW interfaceRow;
|
||||
|
||||
if (QueryInterfaceRowXP(&Context->AdapterEntry->Id, &interfaceRow))
|
||||
{
|
||||
inOctets = interfaceRow.dwInOctets;
|
||||
outOctets = interfaceRow.dwOutOctets;
|
||||
mediaState = interfaceRow.dwOperStatus == IF_OPER_STATUS_OPERATIONAL ? MediaConnectStateConnected : MediaConnectStateUnknown;
|
||||
linkSpeed = interfaceRow.dwSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaState == MediaConnectStateConnected)
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_LINK_STATE, L"Connected");
|
||||
else
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_LINK_STATE, L"Disconnected");
|
||||
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_LINK_SPEED, PhaFormatString(L"%s/s", PhaFormatSize(linkSpeed / BITS_IN_ONE_BYTE, -1)->Buffer)->Buffer);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_BSENT, PhaFormatSize(outOctets, -1)->Buffer);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_BRECEIVED, PhaFormatSize(inOctets, -1)->Buffer);
|
||||
SetDlgItemText(Context->PanelWindowHandle, IDC_STAT_BTOTAL, PhaFormatSize(inOctets + outOctets, -1)->Buffer);
|
||||
}
|
||||
|
||||
VOID UpdateNetAdapterDialog(
|
||||
_Inout_ PDV_NETADAPTER_SYSINFO_CONTEXT Context
|
||||
)
|
||||
{
|
||||
if (Context->AdapterEntry->AdapterName)
|
||||
SetDlgItemText(Context->WindowHandle, IDC_ADAPTERNAME, Context->AdapterEntry->AdapterName->Buffer);
|
||||
else
|
||||
SetDlgItemText(Context->WindowHandle, IDC_ADAPTERNAME, L"Unknown network adapter");
|
||||
|
||||
NetAdapterUpdateGraphs(Context);
|
||||
NetAdapterUpdatePanel(Context);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK NetAdapterPanelDialogProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_SYSINFO_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_NETADAPTER_SYSINFO_CONTEXT)lParam;
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_NETADAPTER_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_NCDESTROY)
|
||||
{
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
case IDC_DETAILS:
|
||||
ShowNetAdapterDetailsDialog(context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK NetAdapterDialogProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_SYSINFO_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_NETADAPTER_SYSINFO_CONTEXT)lParam;
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_NETADAPTER_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
PhDeleteGraphState(&context->GraphState);
|
||||
|
||||
if (context->GraphHandle)
|
||||
DestroyWindow(context->GraphHandle);
|
||||
|
||||
if (context->PanelWindowHandle)
|
||||
DestroyWindow(context->PanelWindowHandle);
|
||||
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
PPH_LAYOUT_ITEM graphItem;
|
||||
PPH_LAYOUT_ITEM panelItem;
|
||||
|
||||
context->WindowHandle = hwndDlg;
|
||||
|
||||
PhInitializeGraphState(&context->GraphState);
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ADAPTERNAME), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE);
|
||||
graphItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GRAPH_LAYOUT), NULL, PH_ANCHOR_ALL);
|
||||
panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LAYOUT), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
|
||||
|
||||
SendMessage(GetDlgItem(hwndDlg, IDC_ADAPTERNAME), WM_SETFONT, (WPARAM)context->SysinfoSection->Parameters->LargeFont, FALSE);
|
||||
|
||||
if (context->AdapterEntry->AdapterName)
|
||||
SetDlgItemText(hwndDlg, IDC_ADAPTERNAME, context->AdapterEntry->AdapterName->Buffer);
|
||||
else
|
||||
SetDlgItemText(hwndDlg, IDC_ADAPTERNAME, L"Unknown network adapter");
|
||||
|
||||
context->PanelWindowHandle = CreateDialogParam(PluginInstance->DllBase, MAKEINTRESOURCE(IDD_NETADAPTER_PANEL), hwndDlg, NetAdapterPanelDialogProc, (LPARAM)context);
|
||||
ShowWindow(context->PanelWindowHandle, SW_SHOW);
|
||||
PhAddLayoutItemEx(&context->LayoutManager, context->PanelWindowHandle, NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM, panelItem->Margin);
|
||||
|
||||
// Create the graph control.
|
||||
context->GraphHandle = CreateWindow(
|
||||
PH_GRAPH_CLASSNAME,
|
||||
NULL,
|
||||
WS_VISIBLE | WS_CHILD | WS_BORDER,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
3,
|
||||
hwndDlg,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
Graph_SetTooltip(context->GraphHandle, TRUE);
|
||||
|
||||
PhAddLayoutItemEx(&context->LayoutManager, context->GraphHandle, NULL, PH_ANCHOR_ALL, graphItem->Margin);
|
||||
|
||||
UpdateNetAdapterDialog(context);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMHDR* header = (NMHDR*)lParam;
|
||||
|
||||
if (header->hwndFrom == context->GraphHandle)
|
||||
{
|
||||
switch (header->code)
|
||||
{
|
||||
case GCN_GETDRAWINFO:
|
||||
{
|
||||
PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)header;
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2;
|
||||
context->SysinfoSection->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite"));
|
||||
|
||||
PhGraphStateGetDrawInfo(
|
||||
&context->GraphState,
|
||||
getDrawInfo,
|
||||
context->AdapterEntry->InboundBuffer.Count
|
||||
);
|
||||
|
||||
if (!context->GraphState.Valid)
|
||||
{
|
||||
ULONG i;
|
||||
FLOAT max = 4 * 1024; // Minimum scaling 4KB
|
||||
|
||||
for (i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
FLOAT data1;
|
||||
FLOAT data2;
|
||||
|
||||
context->GraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->AdapterEntry->InboundBuffer, i);
|
||||
context->GraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->AdapterEntry->OutboundBuffer, i);
|
||||
|
||||
if (max < data1 + data2)
|
||||
max = data1 + data2;
|
||||
}
|
||||
|
||||
if (max != 0)
|
||||
{
|
||||
// Scale the data.
|
||||
|
||||
PhDivideSinglesBySingle(
|
||||
context->GraphState.Data1,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
PhDivideSinglesBySingle(
|
||||
context->GraphState.Data2,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
}
|
||||
|
||||
drawInfo->LabelYFunction = PhSiSizeLabelYFunction;
|
||||
drawInfo->LabelYFunctionParameter = max;
|
||||
|
||||
context->GraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GCN_GETTOOLTIPTEXT:
|
||||
{
|
||||
PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)header;
|
||||
|
||||
if (getTooltipText->Index < getTooltipText->TotalCount)
|
||||
{
|
||||
if (context->GraphState.TooltipIndex != getTooltipText->Index)
|
||||
{
|
||||
ULONG64 adapterInboundValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->AdapterEntry->InboundBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
ULONG64 adapterOutboundValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->AdapterEntry->OutboundBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
PhMoveReference(&context->GraphState.TooltipText, PhFormatString(
|
||||
L"R: %s\nS: %s\n%s",
|
||||
PhaFormatSize(adapterInboundValue, -1)->Buffer,
|
||||
PhaFormatSize(adapterOutboundValue, -1)->Buffer,
|
||||
((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
}
|
||||
|
||||
getTooltipText->Text = context->GraphState.TooltipText->sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UPDATE_MSG:
|
||||
{
|
||||
UpdateNetAdapterDialog(context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN NetAdapterSectionCallback(
|
||||
_In_ PPH_SYSINFO_SECTION Section,
|
||||
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||
_In_opt_ PVOID Parameter1,
|
||||
_In_opt_ PVOID Parameter2
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_SYSINFO_CONTEXT context = (PDV_NETADAPTER_SYSINFO_CONTEXT)Section->Context;
|
||||
|
||||
switch (Message)
|
||||
{
|
||||
case SysInfoCreate:
|
||||
return TRUE;
|
||||
case SysInfoDestroy:
|
||||
{
|
||||
PhDereferenceObject(context->AdapterEntry);
|
||||
PhDereferenceObject(context->SectionName);
|
||||
PhFree(context);
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoTick:
|
||||
{
|
||||
if (context->WindowHandle)
|
||||
PostMessage(context->WindowHandle, UPDATE_MSG, 0, 0);
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoCreateDialog:
|
||||
{
|
||||
PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1;
|
||||
|
||||
createDialog->Instance = PluginInstance->DllBase;
|
||||
createDialog->Template = MAKEINTRESOURCE(IDD_NETADAPTER_DIALOG);
|
||||
createDialog->DialogProc = NetAdapterDialogProc;
|
||||
createDialog->Parameter = context;
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphGetDrawInfo:
|
||||
{
|
||||
PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1;
|
||||
|
||||
drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y | PH_GRAPH_LABEL_MAX_Y | PH_GRAPH_USE_LINE_2;
|
||||
Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorIoReadOther"), PhGetIntegerSetting(L"ColorIoWrite"));
|
||||
PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, context->AdapterEntry->InboundBuffer.Count);
|
||||
|
||||
if (!Section->GraphState.Valid)
|
||||
{
|
||||
FLOAT max = 4 * 1024; // Minimum scaling 4KB
|
||||
|
||||
for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
|
||||
{
|
||||
FLOAT data1;
|
||||
FLOAT data2;
|
||||
|
||||
Section->GraphState.Data1[i] = data1 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->AdapterEntry->InboundBuffer, i);
|
||||
Section->GraphState.Data2[i] = data2 = (FLOAT)PhGetItemCircularBuffer_ULONG64(&context->AdapterEntry->OutboundBuffer, i);
|
||||
|
||||
if (max < data1 + data2)
|
||||
max = data1 + data2;
|
||||
}
|
||||
|
||||
if (max != 0)
|
||||
{
|
||||
// Scale the data.
|
||||
|
||||
PhDivideSinglesBySingle(
|
||||
Section->GraphState.Data1,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
PhDivideSinglesBySingle(
|
||||
Section->GraphState.Data2,
|
||||
max,
|
||||
drawInfo->LineDataCount
|
||||
);
|
||||
}
|
||||
|
||||
drawInfo->LabelYFunction = PhSiSizeLabelYFunction;
|
||||
drawInfo->LabelYFunctionParameter = max;
|
||||
|
||||
Section->GraphState.Valid = TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphGetTooltipText:
|
||||
{
|
||||
PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1;
|
||||
|
||||
ULONG64 adapterInboundValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->AdapterEntry->InboundBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
ULONG64 adapterOutboundValue = PhGetItemCircularBuffer_ULONG64(
|
||||
&context->AdapterEntry->OutboundBuffer,
|
||||
getTooltipText->Index
|
||||
);
|
||||
|
||||
PhMoveReference(&Section->GraphState.TooltipText, PhFormatString(
|
||||
L"R: %s\nS: %s\n%s",
|
||||
PhaFormatSize(adapterInboundValue, -1)->Buffer,
|
||||
PhaFormatSize(adapterOutboundValue, -1)->Buffer,
|
||||
((PPH_STRING)PH_AUTO(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
|
||||
));
|
||||
|
||||
getTooltipText->Text = Section->GraphState.TooltipText->sr;
|
||||
}
|
||||
return TRUE;
|
||||
case SysInfoGraphDrawPanel:
|
||||
{
|
||||
PPH_SYSINFO_DRAW_PANEL drawPanel = (PPH_SYSINFO_DRAW_PANEL)Parameter1;
|
||||
|
||||
PhSetReference(&drawPanel->Title, context->AdapterEntry->AdapterName);
|
||||
drawPanel->SubTitle = PhFormatString(
|
||||
L"R: %s\nS: %s",
|
||||
PhaFormatSize(context->AdapterEntry->InboundValue, -1)->Buffer,
|
||||
PhaFormatSize(context->AdapterEntry->OutboundValue, -1)->Buffer
|
||||
);
|
||||
|
||||
if (!drawPanel->Title)
|
||||
drawPanel->Title = PhCreateString(L"Unknown network adapter");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID NetAdapterSysInfoInitializing(
|
||||
_In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers,
|
||||
_In_ _Assume_refs_(1) PDV_NETADAPTER_ENTRY AdapterEntry
|
||||
)
|
||||
{
|
||||
PH_SYSINFO_SECTION section;
|
||||
PDV_NETADAPTER_SYSINFO_CONTEXT context;
|
||||
|
||||
context = (PDV_NETADAPTER_SYSINFO_CONTEXT)PhAllocate(sizeof(DV_NETADAPTER_SYSINFO_CONTEXT));
|
||||
memset(context, 0, sizeof(DV_NETADAPTER_SYSINFO_CONTEXT));
|
||||
memset(§ion, 0, sizeof(PH_SYSINFO_SECTION));
|
||||
|
||||
context->AdapterEntry = AdapterEntry;
|
||||
context->SectionName = PhConcatStrings2(L"NetAdapter ", AdapterEntry->Id.InterfaceGuid->Buffer);
|
||||
|
||||
section.Context = context;
|
||||
section.Callback = NetAdapterSectionCallback;
|
||||
section.Name = context->SectionName->sr;
|
||||
|
||||
context->SysinfoSection = Pointers->CreateSection(§ion);
|
||||
}
|
||||
736
plugins/HardwareDevices/netoptions.c
Normal file
736
plugins/HardwareDevices/netoptions.c
Normal file
@@ -0,0 +1,736 @@
|
||||
/*
|
||||
* Process Hacker Plugins -
|
||||
* Hardware Devices Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 dmex
|
||||
* Copyright (C) 2016 wj32
|
||||
*
|
||||
* 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 <Setupapi.h>
|
||||
#include <ndisguid.h>
|
||||
|
||||
#define ITEM_CHECKED (INDEXTOSTATEIMAGEMASK(2))
|
||||
#define ITEM_UNCHECKED (INDEXTOSTATEIMAGEMASK(1))
|
||||
|
||||
typedef struct _NET_ENUM_ENTRY
|
||||
{
|
||||
BOOLEAN DevicePresent;
|
||||
IF_LUID DeviceLuid;
|
||||
PPH_STRING DeviceGuid;
|
||||
PPH_STRING DeviceName;
|
||||
} NET_ENUM_ENTRY, *PNET_ENUM_ENTRY;
|
||||
|
||||
static int __cdecl AdapterEntryCompareFunction(
|
||||
_In_ const void *elem1,
|
||||
_In_ const void *elem2
|
||||
)
|
||||
{
|
||||
PNET_ENUM_ENTRY entry1 = *(PNET_ENUM_ENTRY *)elem1;
|
||||
PNET_ENUM_ENTRY entry2 = *(PNET_ENUM_ENTRY *)elem2;
|
||||
|
||||
return uint64cmp(entry1->DeviceLuid.Value, entry2->DeviceLuid.Value);
|
||||
}
|
||||
|
||||
VOID NetAdaptersLoadList(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
PPH_STRING settingsString;
|
||||
PH_STRINGREF remaining;
|
||||
|
||||
settingsString = PhaGetStringSetting(SETTING_NAME_INTERFACE_LIST);
|
||||
remaining = settingsString->sr;
|
||||
|
||||
while (remaining.Length != 0)
|
||||
{
|
||||
ULONG64 ifindex;
|
||||
ULONG64 luid64;
|
||||
PH_STRINGREF part1;
|
||||
PH_STRINGREF part2;
|
||||
PH_STRINGREF part3;
|
||||
IF_LUID ifLuid;
|
||||
DV_NETADAPTER_ID id;
|
||||
PDV_NETADAPTER_ENTRY entry;
|
||||
|
||||
if (remaining.Length == 0)
|
||||
break;
|
||||
|
||||
PhSplitStringRefAtChar(&remaining, ',', &part1, &remaining);
|
||||
PhSplitStringRefAtChar(&remaining, ',', &part2, &remaining);
|
||||
PhSplitStringRefAtChar(&remaining, ',', &part3, &remaining);
|
||||
|
||||
PhStringToInteger64(&part1, 10, &ifindex);
|
||||
PhStringToInteger64(&part2, 10, &luid64);
|
||||
|
||||
ifLuid.Value = luid64;
|
||||
InitializeNetAdapterId(&id, (IF_INDEX)ifindex, ifLuid, PhCreateString2(&part3));
|
||||
entry = CreateNetAdapterEntry(&id);
|
||||
DeleteNetAdapterId(&id);
|
||||
|
||||
entry->UserReference = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID NetAdaptersSaveList(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
PH_STRING_BUILDER stringBuilder;
|
||||
PPH_STRING settingsString;
|
||||
|
||||
PhInitializeStringBuilder(&stringBuilder, 260);
|
||||
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (entry->UserReference)
|
||||
{
|
||||
PhAppendFormatStringBuilder(
|
||||
&stringBuilder,
|
||||
L"%lu,%I64u,%s,",
|
||||
entry->Id.InterfaceIndex, // This value is UNSAFE and may change after reboot.
|
||||
entry->Id.InterfaceLuid.Value, // This value is SAFE and does not change (Vista+).
|
||||
entry->Id.InterfaceGuid->Buffer
|
||||
);
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
if (stringBuilder.String->Length != 0)
|
||||
PhRemoveEndStringBuilder(&stringBuilder, 1);
|
||||
|
||||
settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder));
|
||||
PhSetStringSetting2(SETTING_NAME_INTERFACE_LIST, &settingsString->sr);
|
||||
}
|
||||
|
||||
BOOLEAN FindAdapterEntry(
|
||||
_In_ PDV_NETADAPTER_ID Id,
|
||||
_In_ BOOLEAN RemoveUserReference
|
||||
)
|
||||
{
|
||||
BOOLEAN found = FALSE;
|
||||
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY currentEntry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);
|
||||
|
||||
if (!currentEntry)
|
||||
continue;
|
||||
|
||||
found = EquivalentNetAdapterId(¤tEntry->Id, Id);
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (RemoveUserReference)
|
||||
{
|
||||
if (currentEntry->UserReference)
|
||||
{
|
||||
PhDereferenceObjectDeferDelete(currentEntry);
|
||||
currentEntry->UserReference = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(currentEntry);
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
PhDereferenceObjectDeferDelete(currentEntry);
|
||||
}
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
VOID AddNetworkAdapterToListView(
|
||||
_In_ PDV_NETADAPTER_CONTEXT Context,
|
||||
_In_ BOOLEAN AdapterPresent,
|
||||
_In_ IF_INDEX IfIndex,
|
||||
_In_ IF_LUID Luid,
|
||||
_In_ PPH_STRING Guid,
|
||||
_In_ PPH_STRING Description
|
||||
)
|
||||
{
|
||||
DV_NETADAPTER_ID adapterId;
|
||||
INT lvItemIndex;
|
||||
BOOLEAN found = FALSE;
|
||||
PDV_NETADAPTER_ID newId = NULL;
|
||||
|
||||
InitializeNetAdapterId(&adapterId, IfIndex, Luid, NULL);
|
||||
|
||||
for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
if (EquivalentNetAdapterId(&entry->Id, &adapterId))
|
||||
{
|
||||
newId = PhAllocate(sizeof(DV_NETADAPTER_ID));
|
||||
CopyNetAdapterId(newId, &entry->Id);
|
||||
|
||||
if (entry->UserReference)
|
||||
found = TRUE;
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
|
||||
if (newId)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newId)
|
||||
{
|
||||
newId = PhAllocate(sizeof(DV_NETADAPTER_ID));
|
||||
CopyNetAdapterId(newId, &adapterId);
|
||||
PhMoveReference(&newId->InterfaceGuid, Guid);
|
||||
}
|
||||
|
||||
lvItemIndex = AddListViewItemGroupId(
|
||||
Context->ListViewHandle,
|
||||
AdapterPresent ? 0 : 1,
|
||||
MAXINT,
|
||||
Description->Buffer,
|
||||
newId
|
||||
);
|
||||
|
||||
if (found)
|
||||
ListView_SetItemState(Context->ListViewHandle, lvItemIndex, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
|
||||
|
||||
DeleteNetAdapterId(&adapterId);
|
||||
}
|
||||
|
||||
VOID FreeListViewAdapterEntries(
|
||||
_In_ PDV_NETADAPTER_CONTEXT Context
|
||||
)
|
||||
{
|
||||
ULONG index = -1;
|
||||
|
||||
while ((index = PhFindListViewItemByFlags(
|
||||
Context->ListViewHandle,
|
||||
index,
|
||||
LVNI_ALL
|
||||
)) != -1)
|
||||
{
|
||||
PDV_NETADAPTER_ID param;
|
||||
|
||||
if (PhGetListViewItemParam(Context->ListViewHandle, index, ¶m))
|
||||
{
|
||||
DeleteNetAdapterId(param);
|
||||
PhFree(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID FindNetworkAdapters(
|
||||
_In_ PDV_NETADAPTER_CONTEXT Context
|
||||
)
|
||||
{
|
||||
if (Context->UseAlternateMethod)
|
||||
{
|
||||
ULONG bufferLength = 0;
|
||||
PVOID buffer = NULL;
|
||||
ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
flags |= GAA_FLAG_INCLUDE_ALL_INTERFACES;
|
||||
}
|
||||
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &bufferLength) != ERROR_BUFFER_OVERFLOW)
|
||||
return;
|
||||
|
||||
buffer = PhAllocate(bufferLength);
|
||||
memset(buffer, 0, bufferLength);
|
||||
|
||||
if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, buffer, &bufferLength) == ERROR_SUCCESS)
|
||||
{
|
||||
Context->EnumeratingAdapters = TRUE;
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (PIP_ADAPTER_ADDRESSES i = buffer; i; i = i->Next)
|
||||
{
|
||||
PPH_STRING description;
|
||||
|
||||
if (description = PhCreateString(i->Description))
|
||||
{
|
||||
AddNetworkAdapterToListView(
|
||||
Context,
|
||||
TRUE,
|
||||
i->IfIndex,
|
||||
i->Luid,
|
||||
PhConvertMultiByteToUtf16(i->AdapterName),
|
||||
description
|
||||
);
|
||||
|
||||
PhDereferenceObject(description);
|
||||
}
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
Context->EnumeratingAdapters = FALSE;
|
||||
}
|
||||
|
||||
PhFree(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
PPH_LIST deviceList;
|
||||
HDEVINFO deviceInfoHandle;
|
||||
SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
|
||||
|
||||
if ((deviceInfoHandle = SetupDiGetClassDevs(
|
||||
&GUID_DEVINTERFACE_NET,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_DEVICEINTERFACE
|
||||
)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
deviceList = PH_AUTO(PhCreateList(1));
|
||||
|
||||
for (ULONG i = 0; SetupDiEnumDeviceInfo(deviceInfoHandle, i, &deviceInfoData); i++)
|
||||
{
|
||||
HANDLE keyHandle;
|
||||
DEVPROPTYPE devicePropertyType;
|
||||
WCHAR adapterDescription[MAX_PATH] = L"";
|
||||
|
||||
// DEVPKEY_Device_DeviceDesc doesn't give us the full adapter name.
|
||||
// DEVPKEY_Device_FriendlyName does give us the full adapter name but is only
|
||||
// supported on Windows 8 and above.
|
||||
// We use our NetworkAdapterQueryName function to query the full adapter name
|
||||
// from the NDIS driver directly, if that fails then we use one of the above properties.
|
||||
if (!SetupDiGetDeviceProperty(
|
||||
deviceInfoHandle,
|
||||
&deviceInfoData,
|
||||
WindowsVersion >= WINDOWS_8 ? &DEVPKEY_Device_FriendlyName : &DEVPKEY_Device_DeviceDesc,
|
||||
&devicePropertyType,
|
||||
(PBYTE)adapterDescription,
|
||||
ARRAYSIZE(adapterDescription),
|
||||
NULL,
|
||||
0
|
||||
))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyHandle = SetupDiOpenDevRegKey(
|
||||
deviceInfoHandle,
|
||||
&deviceInfoData,
|
||||
DICS_FLAG_GLOBAL,
|
||||
0,
|
||||
DIREG_DRV,
|
||||
KEY_QUERY_VALUE
|
||||
))
|
||||
{
|
||||
PNET_ENUM_ENTRY adapterEntry;
|
||||
HANDLE deviceHandle;
|
||||
|
||||
adapterEntry = PhAllocate(sizeof(NET_ENUM_ENTRY));
|
||||
memset(adapterEntry, 0, sizeof(NET_ENUM_ENTRY));
|
||||
|
||||
adapterEntry->DeviceGuid = PhQueryRegistryString(keyHandle, L"NetCfgInstanceId");
|
||||
adapterEntry->DeviceLuid.Info.IfType = RegQueryUlong64(keyHandle, L"*IfType");
|
||||
adapterEntry->DeviceLuid.Info.NetLuidIndex = RegQueryUlong64(keyHandle, L"NetLuidIndex");
|
||||
|
||||
if (NT_SUCCESS(NetworkAdapterCreateHandle(&deviceHandle, adapterEntry->DeviceGuid)))
|
||||
{
|
||||
PPH_STRING adapterName;
|
||||
|
||||
// Try query the full adapter name
|
||||
if (adapterName = NetworkAdapterQueryName(deviceHandle, adapterEntry->DeviceGuid))
|
||||
adapterEntry->DeviceName = adapterName;
|
||||
|
||||
adapterEntry->DevicePresent = TRUE;
|
||||
|
||||
NtClose(deviceHandle);
|
||||
}
|
||||
|
||||
if (!adapterEntry->DeviceName)
|
||||
adapterEntry->DeviceName = PhCreateString(adapterDescription);
|
||||
|
||||
PhAddItemList(deviceList, adapterEntry);
|
||||
|
||||
NtClose(keyHandle);
|
||||
}
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoHandle);
|
||||
|
||||
// Sort the entries
|
||||
qsort(deviceList->Items, deviceList->Count, sizeof(PVOID), AdapterEntryCompareFunction);
|
||||
|
||||
Context->EnumeratingAdapters = TRUE;
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (ULONG i = 0; i < deviceList->Count; i++)
|
||||
{
|
||||
PNET_ENUM_ENTRY entry = deviceList->Items[i];
|
||||
|
||||
AddNetworkAdapterToListView(
|
||||
Context,
|
||||
entry->DevicePresent,
|
||||
0,
|
||||
entry->DeviceLuid,
|
||||
entry->DeviceGuid,
|
||||
entry->DeviceName
|
||||
);
|
||||
|
||||
if (entry->DeviceName)
|
||||
PhDereferenceObject(entry->DeviceName);
|
||||
// Note: DeviceGuid is disposed by WM_DESTROY.
|
||||
|
||||
PhFree(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
Context->EnumeratingAdapters = FALSE;
|
||||
}
|
||||
|
||||
|
||||
// HACK: Show all unknown devices.
|
||||
Context->EnumeratingAdapters = TRUE;
|
||||
PhAcquireQueuedLockShared(&NetworkAdaptersListLock);
|
||||
|
||||
for (ULONG i = 0; i < NetworkAdaptersList->Count; i++)
|
||||
{
|
||||
ULONG index = -1;
|
||||
BOOLEAN found = FALSE;
|
||||
PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]);
|
||||
|
||||
if (!entry)
|
||||
continue;
|
||||
|
||||
while ((index = PhFindListViewItemByFlags(
|
||||
Context->ListViewHandle,
|
||||
index,
|
||||
LVNI_ALL
|
||||
)) != -1)
|
||||
{
|
||||
PDV_NETADAPTER_ID param;
|
||||
|
||||
if (PhGetListViewItemParam(Context->ListViewHandle, index, ¶m))
|
||||
{
|
||||
if (EquivalentNetAdapterId(param, &entry->Id))
|
||||
{
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
PPH_STRING description;
|
||||
|
||||
if (description = PhCreateString(L"Unknown network adapter"))
|
||||
{
|
||||
AddNetworkAdapterToListView(
|
||||
Context,
|
||||
FALSE,
|
||||
entry->Id.InterfaceIndex,
|
||||
entry->Id.InterfaceLuid,
|
||||
entry->Id.InterfaceGuid,
|
||||
description
|
||||
);
|
||||
|
||||
PhDereferenceObject(description);
|
||||
}
|
||||
}
|
||||
|
||||
PhDereferenceObjectDeferDelete(entry);
|
||||
}
|
||||
|
||||
PhReleaseQueuedLockShared(&NetworkAdaptersListLock);
|
||||
Context->EnumeratingAdapters = FALSE;
|
||||
}
|
||||
|
||||
PPH_STRING FindNetworkDeviceInstance(
|
||||
_In_ PPH_STRING DevicePath
|
||||
)
|
||||
{
|
||||
PPH_STRING deviceIdString = NULL;
|
||||
HANDLE keyHandle;
|
||||
HDEVINFO deviceInfoHandle;
|
||||
SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
|
||||
|
||||
if ((deviceInfoHandle = SetupDiGetClassDevs(
|
||||
&GUID_DEVINTERFACE_NET,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_DEVICEINTERFACE
|
||||
)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (ULONG i = 0; SetupDiEnumDeviceInfo(deviceInfoHandle, i, &deviceInfoData); i++)
|
||||
{
|
||||
if (keyHandle = SetupDiOpenDevRegKey(
|
||||
deviceInfoHandle,
|
||||
&deviceInfoData,
|
||||
DICS_FLAG_GLOBAL,
|
||||
0,
|
||||
DIREG_DRV,
|
||||
KEY_QUERY_VALUE
|
||||
))
|
||||
{
|
||||
PPH_STRING deviceGuid;
|
||||
|
||||
if (deviceGuid = PhQueryRegistryString(keyHandle, L"NetCfgInstanceId"))
|
||||
{
|
||||
if (PhEqualString(deviceGuid, DevicePath, TRUE))
|
||||
{
|
||||
deviceIdString = PhCreateStringEx(NULL, 0x100);
|
||||
|
||||
SetupDiGetDeviceInstanceId(
|
||||
deviceInfoHandle,
|
||||
&deviceInfoData,
|
||||
deviceIdString->Buffer,
|
||||
(ULONG)deviceIdString->Length,
|
||||
NULL
|
||||
);
|
||||
|
||||
PhTrimToNullTerminatorString(deviceIdString);
|
||||
}
|
||||
|
||||
PhDereferenceObject(deviceGuid);
|
||||
}
|
||||
|
||||
NtClose(keyHandle);
|
||||
}
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoHandle);
|
||||
|
||||
return deviceIdString;
|
||||
}
|
||||
|
||||
//VOID LoadNetworkAdapterImages(
|
||||
// _In_ PDV_NETADAPTER_CONTEXT Context
|
||||
// )
|
||||
//{
|
||||
// HICON smallIcon = NULL;
|
||||
//
|
||||
// Context->ImageList = ImageList_Create(
|
||||
// GetSystemMetrics(SM_CXSMICON),
|
||||
// GetSystemMetrics(SM_CYSMICON),
|
||||
// ILC_COLOR32,
|
||||
// 1,
|
||||
// 1
|
||||
// );
|
||||
//
|
||||
// // We could use SetupDiLoadClassIcon but this works.
|
||||
// // Copied from HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\\IconPath
|
||||
// // The path and index hasn't changed since Win2k.
|
||||
// ExtractIconEx(
|
||||
// L"%SystemRoot%\\system32\\setupapi.dll",
|
||||
// -5,
|
||||
// NULL,
|
||||
// &smallIcon,
|
||||
// 1
|
||||
// );
|
||||
//
|
||||
// if (smallIcon)
|
||||
// {
|
||||
// ImageList_AddIcon(Context->ImageList, smallIcon);
|
||||
// DestroyIcon(smallIcon);
|
||||
//
|
||||
// // Set the imagelist only if the image was loaded.
|
||||
// ListView_SetImageList(
|
||||
// Context->ListViewHandle,
|
||||
// Context->ImageList,
|
||||
// LVSIL_SMALL
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
|
||||
INT_PTR CALLBACK NetworkAdapterOptionsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PDV_NETADAPTER_CONTEXT context = NULL;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = (PDV_NETADAPTER_CONTEXT)PhAllocate(sizeof(DV_NETADAPTER_CONTEXT));
|
||||
memset(context, 0, sizeof(DV_NETADAPTER_CONTEXT));
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PDV_NETADAPTER_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
if (context->OptionsChanged)
|
||||
NetAdaptersSaveList();
|
||||
|
||||
FreeListViewAdapterEntries(context);
|
||||
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
PhFree(context);
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
context->ListViewHandle = GetDlgItem(hwndDlg, IDC_NETADAPTERS_LISTVIEW);
|
||||
PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
|
||||
ListView_SetExtendedListViewStyleEx(context->ListViewHandle, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
|
||||
PhSetControlTheme(context->ListViewHandle, L"explorer");
|
||||
PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 350, L"Network Adapters");
|
||||
PhSetExtendedListView(context->ListViewHandle);
|
||||
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
ListView_EnableGroupView(context->ListViewHandle, TRUE);
|
||||
AddListViewGroup(context->ListViewHandle, 0, L"Connected");
|
||||
AddListViewGroup(context->ListViewHandle, 1, L"Disconnected");
|
||||
|
||||
context->UseAlternateMethod = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Button_Enable(GetDlgItem(hwndDlg, IDC_SHOW_HIDDEN_ADAPTERS), FALSE);
|
||||
context->UseAlternateMethod = TRUE;
|
||||
}
|
||||
|
||||
FindNetworkAdapters(context);
|
||||
|
||||
context->OptionsChanged = FALSE;
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
{
|
||||
case IDC_SHOW_HIDDEN_ADAPTERS:
|
||||
{
|
||||
if (WindowsVersion >= WINDOWS_VISTA)
|
||||
{
|
||||
context->UseAlternateMethod = !context->UseAlternateMethod;
|
||||
|
||||
if (context->UseAlternateMethod)
|
||||
{
|
||||
ListView_EnableGroupView(context->ListViewHandle, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ListView_EnableGroupView(context->ListViewHandle, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
FreeListViewAdapterEntries(context);
|
||||
ListView_DeleteAllItems(context->ListViewHandle);
|
||||
|
||||
FindNetworkAdapters(context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR header = (LPNMHDR)lParam;
|
||||
|
||||
if (header->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
LPNM_LISTVIEW listView = (LPNM_LISTVIEW)lParam;
|
||||
|
||||
if (context->EnumeratingAdapters)
|
||||
break;
|
||||
|
||||
if (listView->uChanged & LVIF_STATE)
|
||||
{
|
||||
switch (listView->uNewState & LVIS_STATEIMAGEMASK)
|
||||
{
|
||||
case 0x2000: // checked
|
||||
{
|
||||
PDV_NETADAPTER_ID param = (PDV_NETADAPTER_ID)listView->lParam;
|
||||
|
||||
if (!FindAdapterEntry(param, FALSE))
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY entry;
|
||||
|
||||
entry = CreateNetAdapterEntry(param);
|
||||
entry->UserReference = TRUE;
|
||||
}
|
||||
|
||||
context->OptionsChanged = TRUE;
|
||||
}
|
||||
break;
|
||||
case 0x1000: // unchecked
|
||||
{
|
||||
PDV_NETADAPTER_ID param = (PDV_NETADAPTER_ID)listView->lParam;
|
||||
|
||||
FindAdapterEntry(param, TRUE);
|
||||
|
||||
context->OptionsChanged = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (header->code == NM_RCLICK)
|
||||
{
|
||||
PDV_NETADAPTER_ENTRY param;
|
||||
PPH_STRING deviceInstance;
|
||||
|
||||
if (param = PhGetSelectedListViewItemParam(context->ListViewHandle))
|
||||
{
|
||||
if (deviceInstance = FindNetworkDeviceInstance(param->Id.InterfaceGuid))
|
||||
{
|
||||
ShowDeviceMenu(hwndDlg, deviceInstance);
|
||||
PhDereferenceObject(deviceInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
9305
plugins/HardwareDevices/nvapi/nvapi.h
Normal file
9305
plugins/HardwareDevices/nvapi/nvapi.h
Normal file
File diff suppressed because it is too large
Load Diff
429
plugins/HardwareDevices/nvapi/nvapi_lite_common.h
Normal file
429
plugins/HardwareDevices/nvapi/nvapi_lite_common.h
Normal file
@@ -0,0 +1,429 @@
|
||||
#pragma once
|
||||
|
||||
#include <pshpack8.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER) && (_MSC_VER > 1399) && !defined(NVAPI_INTERNAL) && !defined(NVAPI_DEPRECATED_OLD)
|
||||
#ifndef __nvapi_deprecated_function
|
||||
#define __nvapi_deprecated_function(message) __declspec(deprecated(message))
|
||||
#endif
|
||||
#ifndef __nvapi_deprecated_datatype
|
||||
#define __nvapi_deprecated_datatype(FirstRelease) __declspec(deprecated("Do not use this data type - it is deprecated in release " #FirstRelease "."))
|
||||
#endif
|
||||
#else
|
||||
#ifndef __nvapi_deprecated_function
|
||||
#define __nvapi_deprecated_function(message)
|
||||
#endif
|
||||
#ifndef __nvapi_deprecated_datatype
|
||||
#define __nvapi_deprecated_datatype(FirstRelease)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 64-bit types for compilers that support them, plus some obsolete variants */
|
||||
#if defined(__GNUC__) || defined(__arm) || defined(__IAR_SYSTEMS_ICC__) || defined(__ghs__) || defined(_WIN64)
|
||||
typedef unsigned long long NvU64; /* 0 to 18446744073709551615 */
|
||||
typedef long long NvS64; /* -9223372036854775808 to 9223372036854775807 */
|
||||
#else
|
||||
typedef unsigned __int64 NvU64; /* 0 to 18446744073709551615 */
|
||||
typedef __int64 NvS64; /* -9223372036854775808 to 9223372036854775807 */
|
||||
#endif
|
||||
|
||||
// mac os 32-bit still needs this
|
||||
#if (defined(macintosh) || defined(__APPLE__)) && !defined(__LP64__)
|
||||
typedef signed long NvS32; /* -2147483648 to 2147483647 */
|
||||
#else
|
||||
typedef signed int NvS32; /* -2147483648 to 2147483647 */
|
||||
#endif
|
||||
|
||||
// mac os 32-bit still needs this
|
||||
#if ( (defined(macintosh) && defined(__LP64__) && (__NVAPI_RESERVED0__)) || (!defined(macintosh) && defined(__NVAPI_RESERVED0__)) )
|
||||
typedef unsigned int NvU32; /* 0 to 4294967295 */
|
||||
#else
|
||||
typedef unsigned long NvU32; /* 0 to 4294967295 */
|
||||
#endif
|
||||
|
||||
typedef signed short NvS16;
|
||||
typedef unsigned short NvU16;
|
||||
typedef unsigned char NvU8;
|
||||
typedef signed char NvS8;
|
||||
|
||||
typedef struct _NV_RECT
|
||||
{
|
||||
NvU32 left;
|
||||
NvU32 top;
|
||||
NvU32 right;
|
||||
NvU32 bottom;
|
||||
} NV_RECT;
|
||||
|
||||
#define NVAPI_INTERFACE extern __success(return == NVAPI_OK) NvAPI_Status __cdecl
|
||||
|
||||
#define NV_DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
|
||||
|
||||
//! \addtogroup nvapihandles
|
||||
//! NVAPI Handles - These handles are retrieved from various calls and passed in to others in NvAPI
|
||||
//! These are meant to be opaque types. Do not assume they correspond to indices, HDCs,
|
||||
//! display indexes or anything else.
|
||||
//!
|
||||
//! Most handles remain valid until a display re-configuration (display mode set) or GPU
|
||||
//! reconfiguration (going into or out of SLI modes) occurs. If NVAPI_HANDLE_INVALIDATED
|
||||
//! is received by an app, it should discard all handles, and re-enumerate them.
|
||||
//! @{
|
||||
NV_DECLARE_HANDLE(NvDisplayHandle); //!< Display Device driven by NVIDIA GPU(s) (an attached display)
|
||||
NV_DECLARE_HANDLE(NvMonitorHandle); //!< Monitor handle
|
||||
NV_DECLARE_HANDLE(NvUnAttachedDisplayHandle); //!< Unattached Display Device driven by NVIDIA GPU(s)
|
||||
NV_DECLARE_HANDLE(NvLogicalGpuHandle); //!< One or more physical GPUs acting in concert (SLI)
|
||||
NV_DECLARE_HANDLE(NvPhysicalGpuHandle); //!< A single physical GPU
|
||||
NV_DECLARE_HANDLE(NvEventHandle); //!< A handle to an event registration instance
|
||||
NV_DECLARE_HANDLE(NvVisualComputingDeviceHandle); //!< A handle to a Visual Computing Device
|
||||
NV_DECLARE_HANDLE(NvHICHandle); //!< A handle to a Host Interface Card
|
||||
NV_DECLARE_HANDLE(NvGSyncDeviceHandle); //!< A handle to a Sync device
|
||||
NV_DECLARE_HANDLE(NvVioHandle); //!< A handle to an SDI device
|
||||
NV_DECLARE_HANDLE(NvTransitionHandle); //!< A handle to address a single transition request
|
||||
NV_DECLARE_HANDLE(NvAudioHandle); //!< NVIDIA HD Audio Device
|
||||
NV_DECLARE_HANDLE(Nv3DVPContextHandle); //!< A handle for a 3D Vision Pro (3DVP) context
|
||||
NV_DECLARE_HANDLE(Nv3DVPTransceiverHandle); //!< A handle for a 3DVP RF transceiver
|
||||
NV_DECLARE_HANDLE(Nv3DVPGlassesHandle); //!< A handle for a pair of 3DVP RF shutter glasses
|
||||
NV_DECLARE_HANDLE(NvSourceHandle); //!< Unique source handle on the system
|
||||
NV_DECLARE_HANDLE(NvTargetHandle); //!< Unique target handle on the system
|
||||
//! @}
|
||||
|
||||
//! \ingroup nvapihandles
|
||||
//! @{
|
||||
#define NVAPI_DEFAULT_HANDLE 0
|
||||
#define NV_BIT(x) (1 << (x))
|
||||
//! @}
|
||||
|
||||
//! \addtogroup nvapitypes
|
||||
//! @{
|
||||
#define NVAPI_GENERIC_STRING_MAX 4096
|
||||
#define NVAPI_LONG_STRING_MAX 256
|
||||
#define NVAPI_SHORT_STRING_MAX 64
|
||||
|
||||
typedef struct _NvSBox
|
||||
{
|
||||
NvS32 sX;
|
||||
NvS32 sY;
|
||||
NvS32 sWidth;
|
||||
NvS32 sHeight;
|
||||
} NvSBox;
|
||||
|
||||
#ifndef NvGUID_Defined
|
||||
#define NvGUID_Defined
|
||||
|
||||
typedef struct _NvGUID
|
||||
{
|
||||
NvU32 data1;
|
||||
NvU16 data2;
|
||||
NvU16 data3;
|
||||
NvU8 data4[8];
|
||||
} NvGUID, NvLUID;
|
||||
|
||||
#endif //#ifndef NvGUID_Defined
|
||||
|
||||
#define NVAPI_MAX_PHYSICAL_GPUS 64
|
||||
#define NVAPI_MAX_PHYSICAL_BRIDGES 100
|
||||
#define NVAPI_PHYSICAL_GPUS 32
|
||||
#define NVAPI_MAX_LOGICAL_GPUS 64
|
||||
#define NVAPI_MAX_AVAILABLE_GPU_TOPOLOGIES 256
|
||||
#define NVAPI_MAX_AVAILABLE_SLI_GROUPS 256
|
||||
#define NVAPI_MAX_GPU_TOPOLOGIES NVAPI_MAX_PHYSICAL_GPUS
|
||||
#define NVAPI_MAX_GPU_PER_TOPOLOGY 8
|
||||
#define NVAPI_MAX_DISPLAY_HEADS 2
|
||||
#define NVAPI_ADVANCED_DISPLAY_HEADS 4
|
||||
#define NVAPI_MAX_DISPLAYS NVAPI_PHYSICAL_GPUS * NVAPI_ADVANCED_DISPLAY_HEADS
|
||||
#define NVAPI_MAX_ACPI_IDS 16
|
||||
#define NVAPI_MAX_VIEW_MODES 8
|
||||
#define NV_MAX_HEADS 4 //!< Maximum heads, each with NVAPI_DESKTOP_RES resolution
|
||||
#define NVAPI_MAX_HEADS_PER_GPU 32
|
||||
|
||||
#define NV_MAX_HEADS 4 //!< Maximum number of heads, each with #NVAPI_DESKTOP_RES resolution
|
||||
#define NV_MAX_VID_STREAMS 4 //!< Maximum number of input video streams, each with a #NVAPI_VIDEO_SRC_INFO
|
||||
#define NV_MAX_VID_PROFILES 4 //!< Maximum number of output video profiles supported
|
||||
|
||||
#define NVAPI_SYSTEM_MAX_DISPLAYS NVAPI_MAX_PHYSICAL_GPUS * NV_MAX_HEADS
|
||||
|
||||
#define NVAPI_SYSTEM_MAX_HWBCS 128
|
||||
#define NVAPI_SYSTEM_HWBC_INVALID_ID 0xffffffff
|
||||
#define NVAPI_MAX_AUDIO_DEVICES 16
|
||||
|
||||
|
||||
typedef char NvAPI_String[NVAPI_GENERIC_STRING_MAX];
|
||||
typedef char NvAPI_LongString[NVAPI_LONG_STRING_MAX];
|
||||
typedef char NvAPI_ShortString[NVAPI_SHORT_STRING_MAX];
|
||||
//! @}
|
||||
|
||||
|
||||
// =========================================================================================
|
||||
//! NvAPI Version Definition \n
|
||||
//! Maintain per structure specific version define using the MAKE_NVAPI_VERSION macro. \n
|
||||
//! Usage: #define NV_GENLOCK_STATUS_VER MAKE_NVAPI_VERSION(NV_GENLOCK_STATUS, 1)
|
||||
//! \ingroup nvapitypes
|
||||
// =========================================================================================
|
||||
#define MAKE_NVAPI_VERSION(typeName,ver) (NvU32)(sizeof(typeName) | ((ver) << 16))
|
||||
|
||||
//! \ingroup nvapitypes
|
||||
#define GET_NVAPI_VERSION(ver) (NvU32)((ver)>>16)
|
||||
|
||||
//! \ingroup nvapitypes
|
||||
#define GET_NVAPI_SIZE(ver) (NvU32)((ver) & 0xffff)
|
||||
|
||||
|
||||
// ====================================================
|
||||
//! NvAPI Status Values
|
||||
//! All NvAPI functions return one of these codes.
|
||||
//! \ingroup nvapistatus
|
||||
// ====================================================
|
||||
|
||||
typedef enum _NvAPI_Status
|
||||
{
|
||||
NVAPI_OK = 0, //!< Success. Request is completed.
|
||||
NVAPI_ERROR = -1, //!< Generic error
|
||||
NVAPI_LIBRARY_NOT_FOUND = -2, //!< NVAPI support library cannot be loaded.
|
||||
NVAPI_NO_IMPLEMENTATION = -3, //!< not implemented in current driver installation
|
||||
NVAPI_API_NOT_INITIALIZED = -4, //!< NvAPI_Initialize has not been called (successfully)
|
||||
NVAPI_INVALID_ARGUMENT = -5, //!< The argument/parameter value is not valid or NULL.
|
||||
NVAPI_NVIDIA_DEVICE_NOT_FOUND = -6, //!< No NVIDIA display driver, or NVIDIA GPU driving a display, was found.
|
||||
NVAPI_END_ENUMERATION = -7, //!< No more items to enumerate
|
||||
NVAPI_INVALID_HANDLE = -8, //!< Invalid handle
|
||||
NVAPI_INCOMPATIBLE_STRUCT_VERSION = -9, //!< An argument's structure version is not supported
|
||||
NVAPI_HANDLE_INVALIDATED = -10, //!< The handle is no longer valid (likely due to GPU or display re-configuration)
|
||||
NVAPI_OPENGL_CONTEXT_NOT_CURRENT = -11, //!< No NVIDIA OpenGL context is current (but needs to be)
|
||||
NVAPI_INVALID_POINTER = -14, //!< An invalid pointer, usually NULL, was passed as a parameter
|
||||
NVAPI_NO_GL_EXPERT = -12, //!< OpenGL Expert is not supported by the current drivers
|
||||
NVAPI_INSTRUMENTATION_DISABLED = -13, //!< OpenGL Expert is supported, but driver instrumentation is currently disabled
|
||||
NVAPI_NO_GL_NSIGHT = -15, //!< OpenGL does not support Nsight
|
||||
|
||||
NVAPI_EXPECTED_LOGICAL_GPU_HANDLE = -100, //!< Expected a logical GPU handle for one or more parameters
|
||||
NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE = -101, //!< Expected a physical GPU handle for one or more parameters
|
||||
NVAPI_EXPECTED_DISPLAY_HANDLE = -102, //!< Expected an NV display handle for one or more parameters
|
||||
NVAPI_INVALID_COMBINATION = -103, //!< The combination of parameters is not valid.
|
||||
NVAPI_NOT_SUPPORTED = -104, //!< Requested feature is not supported in the selected GPU
|
||||
NVAPI_PORTID_NOT_FOUND = -105, //!< No port ID was found for the I2C transaction
|
||||
NVAPI_EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106, //!< Expected an unattached display handle as one of the input parameters.
|
||||
NVAPI_INVALID_PERF_LEVEL = -107, //!< Invalid perf level
|
||||
NVAPI_DEVICE_BUSY = -108, //!< Device is busy; request not fulfilled
|
||||
NVAPI_NV_PERSIST_FILE_NOT_FOUND = -109, //!< NV persist file is not found
|
||||
NVAPI_PERSIST_DATA_NOT_FOUND = -110, //!< NV persist data is not found
|
||||
NVAPI_EXPECTED_TV_DISPLAY = -111, //!< Expected a TV output display
|
||||
NVAPI_EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112, //!< Expected a TV output on the D Connector - HDTV_EIAJ4120.
|
||||
NVAPI_NO_ACTIVE_SLI_TOPOLOGY = -113, //!< SLI is not active on this device.
|
||||
NVAPI_SLI_RENDERING_MODE_NOTALLOWED = -114, //!< Setup of SLI rendering mode is not possible right now.
|
||||
NVAPI_EXPECTED_DIGITAL_FLAT_PANEL = -115, //!< Expected a digital flat panel.
|
||||
NVAPI_ARGUMENT_EXCEED_MAX_SIZE = -116, //!< Argument exceeds the expected size.
|
||||
NVAPI_DEVICE_SWITCHING_NOT_ALLOWED = -117, //!< Inhibit is ON due to one of the flags in NV_GPU_DISPLAY_CHANGE_INHIBIT or SLI active.
|
||||
NVAPI_TESTING_CLOCKS_NOT_SUPPORTED = -118, //!< Testing of clocks is not supported.
|
||||
NVAPI_UNKNOWN_UNDERSCAN_CONFIG = -119, //!< The specified underscan config is from an unknown source (e.g. INF)
|
||||
NVAPI_TIMEOUT_RECONFIGURING_GPU_TOPO = -120, //!< Timeout while reconfiguring GPUs
|
||||
NVAPI_DATA_NOT_FOUND = -121, //!< Requested data was not found
|
||||
NVAPI_EXPECTED_ANALOG_DISPLAY = -122, //!< Expected an analog display
|
||||
NVAPI_NO_VIDLINK = -123, //!< No SLI video bridge is present
|
||||
NVAPI_REQUIRES_REBOOT = -124, //!< NVAPI requires a reboot for the settings to take effect
|
||||
NVAPI_INVALID_HYBRID_MODE = -125, //!< The function is not supported with the current Hybrid mode.
|
||||
NVAPI_MIXED_TARGET_TYPES = -126, //!< The target types are not all the same
|
||||
NVAPI_SYSWOW64_NOT_SUPPORTED = -127, //!< The function is not supported from 32-bit on a 64-bit system.
|
||||
NVAPI_IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128, //!< There is no implicit GPU topology active. Use NVAPI_SetHybridMode to change topology.
|
||||
NVAPI_REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129, //!< Prompt the user to close all non-migratable applications.
|
||||
NVAPI_OUT_OF_MEMORY = -130, //!< Could not allocate sufficient memory to complete the call.
|
||||
NVAPI_WAS_STILL_DRAWING = -131, //!< The previous operation that is transferring information to or from this surface is incomplete.
|
||||
NVAPI_FILE_NOT_FOUND = -132, //!< The file was not found.
|
||||
NVAPI_TOO_MANY_UNIQUE_STATE_OBJECTS = -133, //!< There are too many unique instances of a particular type of state object.
|
||||
NVAPI_INVALID_CALL = -134, //!< The method call is invalid. For example, a method's parameter may not be a valid pointer.
|
||||
NVAPI_D3D10_1_LIBRARY_NOT_FOUND = -135, //!< d3d10_1.dll cannot be loaded.
|
||||
NVAPI_FUNCTION_NOT_FOUND = -136, //!< Couldn't find the function in the loaded DLL.
|
||||
NVAPI_INVALID_USER_PRIVILEGE = -137, //!< Current User is not Admin.
|
||||
NVAPI_EXPECTED_NON_PRIMARY_DISPLAY_HANDLE = -138, //!< The handle corresponds to GDIPrimary.
|
||||
NVAPI_EXPECTED_COMPUTE_GPU_HANDLE = -139, //!< Setting Physx GPU requires that the GPU is compute-capable.
|
||||
NVAPI_STEREO_NOT_INITIALIZED = -140, //!< The Stereo part of NVAPI failed to initialize completely. Check if the stereo driver is installed.
|
||||
NVAPI_STEREO_REGISTRY_ACCESS_FAILED = -141, //!< Access to stereo-related registry keys or values has failed.
|
||||
NVAPI_STEREO_REGISTRY_PROFILE_TYPE_NOT_SUPPORTED = -142, //!< The given registry profile type is not supported.
|
||||
NVAPI_STEREO_REGISTRY_VALUE_NOT_SUPPORTED = -143, //!< The given registry value is not supported.
|
||||
NVAPI_STEREO_NOT_ENABLED = -144, //!< Stereo is not enabled and the function needed it to execute completely.
|
||||
NVAPI_STEREO_NOT_TURNED_ON = -145, //!< Stereo is not turned on and the function needed it to execute completely.
|
||||
NVAPI_STEREO_INVALID_DEVICE_INTERFACE = -146, //!< Invalid device interface.
|
||||
NVAPI_STEREO_PARAMETER_OUT_OF_RANGE = -147, //!< Separation percentage or JPEG image capture quality is out of [0-100] range.
|
||||
NVAPI_STEREO_FRUSTUM_ADJUST_MODE_NOT_SUPPORTED = -148, //!< The given frustum adjust mode is not supported.
|
||||
NVAPI_TOPO_NOT_POSSIBLE = -149, //!< The mosaic topology is not possible given the current state of the hardware.
|
||||
NVAPI_MODE_CHANGE_FAILED = -150, //!< An attempt to do a display resolution mode change has failed.
|
||||
NVAPI_D3D11_LIBRARY_NOT_FOUND = -151, //!< d3d11.dll/d3d11_beta.dll cannot be loaded.
|
||||
NVAPI_INVALID_ADDRESS = -152, //!< Address is outside of valid range.
|
||||
NVAPI_STRING_TOO_SMALL = -153, //!< The pre-allocated string is too small to hold the result.
|
||||
NVAPI_MATCHING_DEVICE_NOT_FOUND = -154, //!< The input does not match any of the available devices.
|
||||
NVAPI_DRIVER_RUNNING = -155, //!< Driver is running.
|
||||
NVAPI_DRIVER_NOTRUNNING = -156, //!< Driver is not running.
|
||||
NVAPI_ERROR_DRIVER_RELOAD_REQUIRED = -157, //!< A driver reload is required to apply these settings.
|
||||
NVAPI_SET_NOT_ALLOWED = -158, //!< Intended setting is not allowed.
|
||||
NVAPI_ADVANCED_DISPLAY_TOPOLOGY_REQUIRED = -159, //!< Information can't be returned due to "advanced display topology".
|
||||
NVAPI_SETTING_NOT_FOUND = -160, //!< Setting is not found.
|
||||
NVAPI_SETTING_SIZE_TOO_LARGE = -161, //!< Setting size is too large.
|
||||
NVAPI_TOO_MANY_SETTINGS_IN_PROFILE = -162, //!< There are too many settings for a profile.
|
||||
NVAPI_PROFILE_NOT_FOUND = -163, //!< Profile is not found.
|
||||
NVAPI_PROFILE_NAME_IN_USE = -164, //!< Profile name is duplicated.
|
||||
NVAPI_PROFILE_NAME_EMPTY = -165, //!< Profile name is empty.
|
||||
NVAPI_EXECUTABLE_NOT_FOUND = -166, //!< Application not found in the Profile.
|
||||
NVAPI_EXECUTABLE_ALREADY_IN_USE = -167, //!< Application already exists in the other profile.
|
||||
NVAPI_DATATYPE_MISMATCH = -168, //!< Data Type mismatch
|
||||
NVAPI_PROFILE_REMOVED = -169, //!< The profile passed as parameter has been removed and is no longer valid.
|
||||
NVAPI_UNREGISTERED_RESOURCE = -170, //!< An unregistered resource was passed as a parameter.
|
||||
NVAPI_ID_OUT_OF_RANGE = -171, //!< The DisplayId corresponds to a display which is not within the normal outputId range.
|
||||
NVAPI_DISPLAYCONFIG_VALIDATION_FAILED = -172, //!< Display topology is not valid so the driver cannot do a mode set on this configuration.
|
||||
NVAPI_DPMST_CHANGED = -173, //!< Display Port Multi-Stream topology has been changed.
|
||||
NVAPI_INSUFFICIENT_BUFFER = -174, //!< Input buffer is insufficient to hold the contents.
|
||||
NVAPI_ACCESS_DENIED = -175, //!< No access to the caller.
|
||||
NVAPI_MOSAIC_NOT_ACTIVE = -176, //!< The requested action cannot be performed without Mosaic being enabled.
|
||||
NVAPI_SHARE_RESOURCE_RELOCATED = -177, //!< The surface is relocated away from video memory.
|
||||
NVAPI_REQUEST_USER_TO_DISABLE_DWM = -178, //!< The user should disable DWM before calling NvAPI.
|
||||
NVAPI_D3D_DEVICE_LOST = -179, //!< D3D device status is D3DERR_DEVICELOST or D3DERR_DEVICENOTRESET - the user has to reset the device.
|
||||
NVAPI_INVALID_CONFIGURATION = -180, //!< The requested action cannot be performed in the current state.
|
||||
NVAPI_STEREO_HANDSHAKE_NOT_DONE = -181, //!< Call failed as stereo handshake not completed.
|
||||
NVAPI_EXECUTABLE_PATH_IS_AMBIGUOUS = -182, //!< The path provided was too short to determine the correct NVDRS_APPLICATION
|
||||
NVAPI_DEFAULT_STEREO_PROFILE_IS_NOT_DEFINED = -183, //!< Default stereo profile is not currently defined
|
||||
NVAPI_DEFAULT_STEREO_PROFILE_DOES_NOT_EXIST = -184, //!< Default stereo profile does not exist
|
||||
NVAPI_CLUSTER_ALREADY_EXISTS = -185, //!< A cluster is already defined with the given configuration.
|
||||
NVAPI_DPMST_DISPLAY_ID_EXPECTED = -186, //!< The input display id is not that of a multi stream enabled connector or a display device in a multi stream topology
|
||||
NVAPI_INVALID_DISPLAY_ID = -187, //!< The input display id is not valid or the monitor associated to it does not support the current operation
|
||||
NVAPI_STREAM_IS_OUT_OF_SYNC = -188, //!< While playing secure audio stream, stream goes out of sync
|
||||
NVAPI_INCOMPATIBLE_AUDIO_DRIVER = -189, //!< Older audio driver version than required
|
||||
NVAPI_VALUE_ALREADY_SET = -190, //!< Value already set, setting again not allowed.
|
||||
NVAPI_TIMEOUT = -191, //!< Requested operation timed out
|
||||
NVAPI_GPU_WORKSTATION_FEATURE_INCOMPLETE = -192, //!< The requested workstation feature set has incomplete driver internal allocation resources
|
||||
NVAPI_STEREO_INIT_ACTIVATION_NOT_DONE = -193, //!< Call failed because InitActivation was not called.
|
||||
NVAPI_SYNC_NOT_ACTIVE = -194, //!< The requested action cannot be performed without Sync being enabled.
|
||||
NVAPI_SYNC_MASTER_NOT_FOUND = -195, //!< The requested action cannot be performed without Sync Master being enabled.
|
||||
NVAPI_INVALID_SYNC_TOPOLOGY = -196, //!< Invalid displays passed in the NV_GSYNC_DISPLAY pointer.
|
||||
NVAPI_ECID_SIGN_ALGO_UNSUPPORTED = -197, //!< The specified signing algorithm is not supported. Either an incorrect value was entered or the current installed driver/hardware does not support the input value.
|
||||
NVAPI_ECID_KEY_VERIFICATION_FAILED = -198, //!< The encrypted public key verification has failed.
|
||||
} NvAPI_Status;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_SYS_GetDriverAndBranchVersion
|
||||
//
|
||||
//! DESCRIPTION: This API returns display driver version and driver-branch string.
|
||||
//!
|
||||
//! SUPPORTED OS: Windows XP and higher
|
||||
//!
|
||||
//!
|
||||
//! \param [out] pDriverVersion Contains the driver version after successful return.
|
||||
//! \param [out] szBuildBranchString Contains the driver-branch string after successful return.
|
||||
//!
|
||||
//! \retval ::NVAPI_INVALID_ARGUMENT: either pDriverVersion is NULL or enum index too big
|
||||
//! \retval ::NVAPI_OK - completed request
|
||||
//! \retval ::NVAPI_API_NOT_INTIALIZED - NVAPI not initialized
|
||||
//! \retval ::NVAPI_ERROR - miscellaneous error occurred
|
||||
//!
|
||||
//! \ingroup driverapi
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_SYS_GetDriverAndBranchVersion)(_Out_ NvU32* pDriverVersion, _Out_ NvAPI_ShortString szBuildBranchString);
|
||||
_NvAPI_SYS_GetDriverAndBranchVersion NvAPI_SYS_GetDriverAndBranchVersion;
|
||||
|
||||
|
||||
//! \ingroup driverapi
|
||||
//! Used in NvAPI_GPU_GetMemoryInfo().
|
||||
typedef struct _NV_DISPLAY_DRIVER_MEMORY_INFO_V1
|
||||
{
|
||||
NvU32 version; //!< Version info
|
||||
NvU32 dedicatedVideoMemory; //!< Size(in kb) of the physical framebuffer.
|
||||
NvU32 availableDedicatedVideoMemory; //!< Size(in kb) of the available physical framebuffer for allocating video memory surfaces.
|
||||
NvU32 systemVideoMemory; //!< Size(in kb) of system memory the driver allocates at load time.
|
||||
NvU32 sharedSystemMemory; //!< Size(in kb) of shared system memory that driver is allowed to commit for surfaces across all allocations.
|
||||
} NV_DISPLAY_DRIVER_MEMORY_INFO_V1;
|
||||
|
||||
|
||||
//! \ingroup driverapi
|
||||
//! Used in NvAPI_GPU_GetMemoryInfo().
|
||||
typedef struct _NV_DISPLAY_DRIVER_MEMORY_INFO_V2
|
||||
{
|
||||
NvU32 version; //!< Version info
|
||||
NvU32 dedicatedVideoMemory; //!< Size(in kb) of the physical framebuffer.
|
||||
NvU32 availableDedicatedVideoMemory; //!< Size(in kb) of the available physical framebuffer for allocating video memory surfaces.
|
||||
NvU32 systemVideoMemory; //!< Size(in kb) of system memory the driver allocates at load time.
|
||||
NvU32 sharedSystemMemory; //!< Size(in kb) of shared system memory that driver is allowed to commit for surfaces across all allocations.
|
||||
NvU32 curAvailableDedicatedVideoMemory; //!< Size(in kb) of the current available physical framebuffer for allocating video memory surfaces.
|
||||
} NV_DISPLAY_DRIVER_MEMORY_INFO_V2;
|
||||
|
||||
|
||||
//! \ingroup driverapi
|
||||
typedef NV_DISPLAY_DRIVER_MEMORY_INFO_V2 NV_DISPLAY_DRIVER_MEMORY_INFO;
|
||||
|
||||
//! \ingroup driverapi
|
||||
//! Macro for constructing the version field of NV_DISPLAY_DRIVER_MEMORY_INFO_V1
|
||||
#define NV_DISPLAY_DRIVER_MEMORY_INFO_VER_1 MAKE_NVAPI_VERSION(NV_DISPLAY_DRIVER_MEMORY_INFO_V1, 1)
|
||||
|
||||
//! \ingroup driverapi
|
||||
//! Macro for constructing the version field of NV_DISPLAY_DRIVER_MEMORY_INFO_V2
|
||||
#define NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2 MAKE_NVAPI_VERSION(NV_DISPLAY_DRIVER_MEMORY_INFO_V2, 2)
|
||||
|
||||
//! \ingroup driverapi
|
||||
#define NV_DISPLAY_DRIVER_MEMORY_INFO_VER NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_GetMemoryInfo
|
||||
//
|
||||
//! DESCRIPTION: This function retrieves the available driver memory footprint for the specified GPU.
|
||||
//!
|
||||
//! SUPPORTED OS: Windows XP and higher
|
||||
//!
|
||||
//!
|
||||
//! TCC_SUPPORTED
|
||||
//!
|
||||
//! \since Release: 177
|
||||
//!
|
||||
//! \param [in] hPhysicalGpu Handle of the physical GPU for which the memory information is to be extracted.
|
||||
//! \param [out] pMemoryInfo The memory footprint available in the driver. See NV_DISPLAY_DRIVER_MEMORY_INFO.
|
||||
//!
|
||||
//! \retval NVAPI_INVALID_ARGUMENT pMemoryInfo is NULL.
|
||||
//! \retval NVAPI_OK Call successful.
|
||||
//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
|
||||
//! \retval NVAPI_INCOMPATIBLE_STRUCT_VERSION NV_DISPLAY_DRIVER_MEMORY_INFO structure version mismatch.
|
||||
//!
|
||||
//! \ingroup driverapi
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetMemoryInfo)(NvDisplayHandle hNvDisplay, NV_DISPLAY_DRIVER_MEMORY_INFO *pMemoryInfo);
|
||||
_NvAPI_GPU_GetMemoryInfo NvAPI_GPU_GetMemoryInfo;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_EnumPhysicalGPUs
|
||||
//
|
||||
//! This function returns an array of physical GPU handles.
|
||||
//! Each handle represents a physical GPU present in the system.
|
||||
//! That GPU may be part of an SLI configuration, or may not be visible to the OS directly.
|
||||
//!
|
||||
//! At least one GPU must be present in the system and running an NVIDIA display driver.
|
||||
//!
|
||||
//! The array nvGPUHandle will be filled with physical GPU handle values. The returned
|
||||
//! gpuCount determines how many entries in the array are valid.
|
||||
//!
|
||||
//! \note In drivers older than 105.00, all physical GPU handles get invalidated on a
|
||||
//! modeset. So the calling applications need to renum the handles after every modeset.\n
|
||||
//! With drivers 105.00 and up, all physical GPU handles are constant.
|
||||
//! Physical GPU handles are constant as long as the GPUs are not physically moved and
|
||||
//! the SBIOS VGA order is unchanged.
|
||||
//!
|
||||
//! For GPU handles in TCC MODE please use NvAPI_EnumTCCPhysicalGPUs()
|
||||
//!
|
||||
//! SUPPORTED OS: Windows XP and higher, Mac OS X
|
||||
//!
|
||||
//!
|
||||
//! \par Introduced in
|
||||
//! \since Release: 80
|
||||
//!
|
||||
//! \retval NVAPI_INVALID_ARGUMENT nvGPUHandle or pGpuCount is NULL
|
||||
//! \retval NVAPI_OK One or more handles were returned
|
||||
//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
|
||||
//! \ingroup gpu
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_EnumPhysicalGPUs)(NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS], NvU32* pGpuCount);
|
||||
_NvAPI_EnumPhysicalGPUs NvAPI_EnumPhysicalGPUs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <poppack.h>
|
||||
1035
plugins/HardwareDevices/nvidia.c
Normal file
1035
plugins/HardwareDevices/nvidia.c
Normal file
File diff suppressed because it is too large
Load Diff
617
plugins/HardwareDevices/nvidia.h
Normal file
617
plugins/HardwareDevices/nvidia.h
Normal file
@@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Process Hacker Extra Plugins -
|
||||
* Nvidia GPU Plugin
|
||||
*
|
||||
* Copyright (C) 2015-2016 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/>.
|
||||
*/
|
||||
|
||||
#include "devices.h"
|
||||
#include <pshpack8.h>
|
||||
|
||||
// These structures and types have been gathered from nvapi leaks and symbols, as well as reverse engineering and guessing.
|
||||
|
||||
// rev
|
||||
#define NVAPI_MAX_USAGES_PER_GPU 0x21
|
||||
#define NVAPI_MAX_CLOCKS_PER_GPU 0x120
|
||||
#define NVAPI_MAX_COOLERS_PER_GPU 0x3
|
||||
#define NVAPI_MIN_COOLER_LEVEL 0x0
|
||||
#define NVAPI_MAX_COOLER_LEVEL 0x64
|
||||
#define NVAPI_MAX_COOLER_LEVELS 0x18
|
||||
#define NVAPI_MAX_PROCESSES 0x80
|
||||
|
||||
// rev
|
||||
typedef PVOID (__cdecl *_NvAPI_QueryInterface)(_In_ NvU32 FunctionOffset);
|
||||
_NvAPI_QueryInterface NvAPI_QueryInterface;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetShaderPipeCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pShaderPipeCount);
|
||||
_NvAPI_GPU_GetShaderPipeCount NvAPI_GPU_GetShaderPipeCount;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetShaderSubPipeCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pShaderSubPipeCount);
|
||||
_NvAPI_GPU_GetShaderSubPipeCount NvAPI_GPU_GetShaderSubPipeCount;
|
||||
|
||||
|
||||
// rev
|
||||
typedef enum _NV_RAM_TYPE
|
||||
{
|
||||
NV_RAM_TYPE_NONE,
|
||||
NV_RAM_TYPE_SDRAM,
|
||||
NV_RAM_TYPE_DDR1,
|
||||
NV_RAM_TYPE_DDR2,
|
||||
NV_RAM_TYPE_GDDR2,
|
||||
NV_RAM_TYPE_GDDR3,
|
||||
NV_RAM_TYPE_GDDR4,
|
||||
NV_RAM_TYPE_DDR3,
|
||||
NV_RAM_TYPE_GDDR5,
|
||||
NV_RAM_TYPE_LPDDR2
|
||||
} NV_RAM_TYPE;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetRamType)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NV_RAM_TYPE* pRamType);
|
||||
_NvAPI_GPU_GetRamType NvAPI_GPU_GetRamType;
|
||||
|
||||
|
||||
// rev
|
||||
typedef enum _NV_RAM_MAKER
|
||||
{
|
||||
NV_RAM_MAKER_NONE,
|
||||
NV_RAM_MAKER_SAMSUNG,
|
||||
NV_RAM_MAKER_QIMONDA,
|
||||
NV_RAM_MAKER_ELPIDA,
|
||||
NV_RAM_MAKER_ETRON,
|
||||
NV_RAM_MAKER_NANYA,
|
||||
NV_RAM_MAKER_HYNIX,
|
||||
NV_RAM_MAKER_MOSEL,
|
||||
NV_RAM_MAKER_WINBOND,
|
||||
NV_RAM_MAKER_ELITE,
|
||||
NV_RAM_MAKER_MICRON
|
||||
} NV_RAM_MAKER;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetRamType)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NV_RAM_MAKER* pRamMaker);
|
||||
_NvAPI_GPU_GetRamType NvAPI_GPU_GetRamMaker;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetRamBusWidth)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBusWidth);
|
||||
_NvAPI_GPU_GetRamBusWidth NvAPI_GPU_GetRamBusWidth;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetRamBankCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBankCount);
|
||||
_NvAPI_GPU_GetRamBankCount NvAPI_GPU_GetRamBankCount;
|
||||
|
||||
|
||||
|
||||
typedef enum _NV_FOUNDRY
|
||||
{
|
||||
NV_FOUNDRY_NONE,
|
||||
NV_FOUNDRY_TSMC,
|
||||
NV_FOUNDRY_UMC,
|
||||
NV_FOUNDRY_IBM,
|
||||
NV_FOUNDRY_SMIC,
|
||||
NV_FOUNDRY_CSM,
|
||||
NV_FOUNDRY_TOSHIBA
|
||||
} NV_FOUNDRY;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetFoundry)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NV_FOUNDRY* pFoundry);
|
||||
_NvAPI_GPU_GetFoundry NvAPI_GPU_GetFoundry;
|
||||
|
||||
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetFBWidthAndLocation)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pWidth, NvU32* pLocation);
|
||||
_NvAPI_GPU_GetFBWidthAndLocation NvAPI_GPU_GetFBWidthAndLocation;
|
||||
|
||||
|
||||
// rev (This has a different offset than the NvAPI_GPU_GetMemoryInfo function despite both returning the same struct).
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverMemoryInfo)(_In_ NvDisplayHandle NvDispHandle, _Inout_ NV_DISPLAY_DRIVER_MEMORY_INFO* pMemoryInfo);
|
||||
_NvAPI_GetDisplayDriverMemoryInfo NvAPI_GetDisplayDriverMemoryInfo;
|
||||
|
||||
|
||||
|
||||
// rev
|
||||
typedef enum _NV_COOLER_TYPE
|
||||
{
|
||||
NVAPI_COOLER_TYPE_NONE = 0,
|
||||
NVAPI_COOLER_TYPE_FAN,
|
||||
NVAPI_COOLER_TYPE_WATER,
|
||||
NVAPI_COOLER_TYPE_LIQUID_NO2,
|
||||
} NV_COOLER_TYPE;
|
||||
|
||||
// rev
|
||||
typedef enum _NV_COOLER_CONTROLLER
|
||||
{
|
||||
NVAPI_COOLER_CONTROLLER_NONE = 0,
|
||||
NVAPI_COOLER_CONTROLLER_ADI,
|
||||
NVAPI_COOLER_CONTROLLER_INTERNAL,
|
||||
} NV_COOLER_CONTROLLER;
|
||||
|
||||
// rev
|
||||
typedef enum _NV_COOLER_POLICY
|
||||
{
|
||||
NVAPI_COOLER_POLICY_NONE = 0,
|
||||
NVAPI_COOLER_POLICY_MANUAL, // Manual adjustment of cooler level. Gets applied right away independent of temperature or performance level.
|
||||
NVAPI_COOLER_POLICY_PERF, // GPU performance controls the cooler level.
|
||||
NVAPI_COOLER_POLICY_TEMPERATURE_DISCRETE = 4, // Discrete thermal levels control the cooler level.
|
||||
NVAPI_COOLER_POLICY_TEMPERATURE_CONTINUOUS = 8, // Cooler level adjusted at continuous thermal levels.
|
||||
NVAPI_COOLER_POLICY_HYBRID, // Hybrid of performance and temperature levels.
|
||||
} NV_COOLER_POLICY;
|
||||
|
||||
// rev
|
||||
typedef enum _NV_COOLER_TARGET
|
||||
{
|
||||
NVAPI_COOLER_TARGET_NONE = 0,
|
||||
NVAPI_COOLER_TARGET_GPU,
|
||||
NVAPI_COOLER_TARGET_MEMORY,
|
||||
NVAPI_COOLER_TARGET_POWER_SUPPLY = 4,
|
||||
NVAPI_COOLER_TARGET_ALL = 7 // This cooler cools all of the components related to its target gpu.
|
||||
} NV_COOLER_TARGET;
|
||||
|
||||
// rev
|
||||
typedef enum _NV_COOLER_CONTROL
|
||||
{
|
||||
NVAPI_COOLER_CONTROL_NONE = 0,
|
||||
NVAPI_COOLER_CONTROL_TOGGLE, // ON/OFF
|
||||
NVAPI_COOLER_CONTROL_VARIABLE, // Suppports variable control.
|
||||
} NV_COOLER_CONTROL;
|
||||
|
||||
// rev
|
||||
typedef enum _NV_COOLER_ACTIVITY_LEVEL
|
||||
{
|
||||
NVAPI_INACTIVE = 0, // inactive or unsupported
|
||||
NVAPI_ACTIVE = 1, // active and spinning in case of fan
|
||||
} NV_COOLER_ACTIVITY_LEVEL;
|
||||
|
||||
// rev
|
||||
typedef struct _NV_GPU_COOLER_SETTINGS
|
||||
{
|
||||
NvU32 version; // structure version
|
||||
NvU32 count; // number of associated coolers with the selected GPU
|
||||
struct
|
||||
{
|
||||
NV_COOLER_TYPE type; // type of cooler - FAN, WATER, LIQUID_NO2...
|
||||
NV_COOLER_CONTROLLER controller; // internal, ADI...
|
||||
NvU32 defaultMinLevel; // the min default value % of the cooler
|
||||
NvU32 defaultMaxLevel; // the max default value % of the cooler
|
||||
NvU32 currentMinLevel; // the current allowed min value % of the cooler
|
||||
NvU32 currentMaxLevel; // the current allowed max value % of the cooler
|
||||
NvU32 currentLevel; // the current value % of the cooler
|
||||
NV_COOLER_POLICY defaultPolicy; // cooler control policy - auto-perf, auto-thermal, manual, hybrid...
|
||||
NV_COOLER_POLICY currentPolicy; // cooler control policy - auto-perf, auto-thermal, manual, hybrid...
|
||||
NV_COOLER_TARGET target; // cooling target - GPU, memory, chipset, powersupply, canoas...
|
||||
NV_COOLER_CONTROL controlType; // toggle or variable
|
||||
NV_COOLER_ACTIVITY_LEVEL active; // is the cooler active - fan spinning...
|
||||
} cooler[NVAPI_MAX_COOLERS_PER_GPU];
|
||||
} NV_GPU_COOLER_SETTINGS, *PNV_GPU_COOLER_SETTINGS;
|
||||
|
||||
#define NV_GPU_COOLER_SETTINGS_VER MAKE_NVAPI_VERSION(NV_GPU_COOLER_SETTINGS, 1)
|
||||
|
||||
// rev
|
||||
typedef struct _NV_GPU_SETCOOLER_LEVEL
|
||||
{
|
||||
NvU32 version; //structure version
|
||||
struct
|
||||
{
|
||||
NvU32 currentLevel; // the new value % of the cooler
|
||||
NV_COOLER_POLICY currentPolicy; // the new cooler control policy - auto-perf, auto-thermal, manual, hybrid...
|
||||
} cooler[NVAPI_MAX_COOLERS_PER_GPU];
|
||||
} NV_GPU_SETCOOLER_LEVEL;
|
||||
|
||||
#define NV_GPU_SETCOOLER_LEVEL_VER MAKE_NVAPI_VERSION(NV_GPU_SETCOOLER_LEVEL, 1)
|
||||
|
||||
// rev
|
||||
typedef struct _NV_GPU_COOLER_POLICY_TABLE
|
||||
{
|
||||
NvU32 version; //structure version
|
||||
NV_COOLER_POLICY policy; //selected policy to update the cooler levels for, example NVAPI_COOLER_POLICY_PERF
|
||||
struct
|
||||
{
|
||||
NvU32 levelId; // level indicator for a policy
|
||||
NvU32 currentLevel; // new cooler level for the selected policy level indicator.
|
||||
NvU32 defaultLevel; // default cooler level for the selected policy level indicator.
|
||||
} policyCoolerLevel[NVAPI_MAX_COOLER_LEVELS];
|
||||
} NV_GPU_COOLER_POLICY_TABLE;
|
||||
|
||||
#define NV_GPU_COOLER_POLICY_TABLE_VER MAKE_NVAPI_VERSION(NV_GPU_COOLER_POLICY_TABLE, 1)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_GetCoolerSettings
|
||||
//
|
||||
// DESCRIPTION: Retrieves the cooler information of all coolers or a specific cooler associated with the selected GPU.
|
||||
// Coolers are indexed 0 to NVAPI_MAX_COOLERS_PER_GPU-1.
|
||||
// To retrieve specific cooler info set the coolerIndex to the appropriate cooler index.
|
||||
// To retrieve info for all cooler set coolerIndex to NVAPI_COOLER_TARGET_ALL.
|
||||
//
|
||||
// PARAMETERS : hPhysicalGPU(IN) - GPU selection.
|
||||
// coolerIndex(IN) - Explict cooler index selection.
|
||||
// pCoolerInfo(OUT) - Array of cooler settings.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetCoolerSettings)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_COOLER_SETTINGS* pCoolerInfo);
|
||||
_NvAPI_GPU_GetCoolerSettings NvAPI_GPU_GetCoolerSettings;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_SetCoolerLevels
|
||||
//
|
||||
// DESCRIPTION: Set the cooler levels for all coolers or a specific cooler associated with the selected GPU.
|
||||
// Coolers are indexed 0 to NVAPI_MAX_COOLERS_PER_GPU-1. Every cooler level with non-zero currentpolicy gets applied.
|
||||
// The new level should be in the range of minlevel and maxlevel retrieved from GetCoolerSettings API or between
|
||||
// and NVAPI_MIN_COOLER_LEVEL to MAX_COOLER_LEVEL.
|
||||
// To set level for a specific cooler set the coolerIndex to the appropriate cooler index.
|
||||
// To set level for all coolers set coolerIndex to NVAPI_COOLER_TARGET_ALL.
|
||||
// NOTE: To lock the fan speed independent of the temperature or performance changes set the cooler currentPolicy to
|
||||
// NVAPI_COOLER_POLICY_MANUAL else set it to the current policy retrieved from the GetCoolerSettings API.
|
||||
// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
|
||||
// coolerIndex(IN) - Explict cooler index selection.
|
||||
// pCoolerLevels(IN) - Updated cooler level and cooler policy.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_SetCoolerLevels)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_SETCOOLER_LEVEL *pCoolerLevels);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_RestoreCoolerSettings
|
||||
//
|
||||
// DESCRIPTION: Restore the modified cooler settings to NVIDIA defaults.
|
||||
//
|
||||
// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
|
||||
// pCoolerIndex(IN) - Array containing absolute cooler indexes to restore. Pass NULL restore all coolers.
|
||||
// CoolerCount - Number of coolers to restore.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_RestoreCoolerSettings)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pCoolerIndex, NvU32 coolerCount);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_GetCoolerPolicyTable
|
||||
//
|
||||
// DESCRIPTION: Retrieves the table of cooler and policy levels for the selected policy. Supported only for NVAPI_COOLER_POLICY_PERF.
|
||||
//
|
||||
// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
|
||||
// coolerIndex(IN) - cooler index selection.
|
||||
// pCoolerTable(OUT) - Table of policy levels and associated cooler levels.
|
||||
// count(OUT) - Count of the number of valid levels for the selected policy.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetCoolerPolicyTable)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_COOLER_POLICY_TABLE *pCoolerTable, NvU32 *count);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_SetCoolerPolicyTable
|
||||
//
|
||||
// DESCRIPTION: Restore the modified cooler settings to NVIDIA defaults. Supported only for NVAPI_COOLER_POLICY_PERF.
|
||||
//
|
||||
// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
|
||||
// coolerIndex(IN) - cooler index selection.
|
||||
// pCoolerTable(IN) - Updated table of policy levels and associated cooler levels. Every non-zero policy level gets updated.
|
||||
// count(IN) - Number of valid levels in the policy table.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_SetCoolerPolicyTable)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_COOLER_POLICY_TABLE *pCoolerTable, NvU32 count);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FUNCTION NAME: NvAPI_GPU_RestoreCoolerPolicyTable
|
||||
//
|
||||
// DESCRIPTION: Restores the perf table policy levels to the defaults.
|
||||
//
|
||||
// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
|
||||
// coolerIndex(IN) - cooler index selection.
|
||||
// pCoolerIndex(IN) - Array containing absolute cooler indexes to restore. Pass NULL restore all coolers.
|
||||
// coolerCount - Number of coolers to restore.
|
||||
// policy - restore for the selected policy
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_RestoreCoolerPolicyTable)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pCoolerIndex, NvU32 coolerCount, NV_COOLER_POLICY policy);
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_GetUsages
|
||||
typedef struct _NV_USAGES_INFO
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 usages[NVAPI_MAX_USAGES_PER_GPU];
|
||||
} NV_USAGES_INFO;
|
||||
|
||||
#define NV_USAGES_INFO_VER MAKE_NVAPI_VERSION(NV_USAGES_INFO, 1)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetUsages)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_USAGES_INFO* pUsagesInfo);
|
||||
_NvAPI_GPU_GetUsages NvAPI_GPU_GetUsages;
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_GetAllClocks
|
||||
typedef struct _NV_CLOCKS_INFO
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 clocks[NVAPI_MAX_CLOCKS_PER_GPU];
|
||||
} NV_CLOCKS_INFO;
|
||||
|
||||
#define NV_CLOCKS_INFO_VER MAKE_NVAPI_VERSION(NV_CLOCKS_INFO, 2)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetAllClocks)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_CLOCKS_INFO* pClocksInfo);
|
||||
_NvAPI_GPU_GetAllClocks NvAPI_GPU_GetAllClocks;
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_GetVoltageDomainsStatus
|
||||
typedef struct _NV_VOLTAGE_DOMAINS
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 flags; //!< Reserved for future use. Must be set to 0
|
||||
NvU32 max;
|
||||
struct
|
||||
{
|
||||
NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId; //!< ID of the voltage domain
|
||||
NvU32 mvolt; //!< Voltage in mV
|
||||
} domain[NVAPI_MAX_GPU_PERF_VOLTAGES];
|
||||
} NV_VOLTAGE_DOMAINS;
|
||||
|
||||
#define NV_VOLTAGE_DOMAIN_INFO_VER MAKE_NVAPI_VERSION(NV_VOLTAGE_DOMAINS, 1)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetVoltageDomainsStatus)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_VOLTAGE_DOMAINS* pVoltageDomainsStatus);
|
||||
_NvAPI_GPU_GetVoltageDomainsStatus NvAPI_GPU_GetVoltageDomainsStatus;
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_GetVoltages
|
||||
typedef struct _NV_VOLTAGES_INFO
|
||||
{
|
||||
NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId; //!< ID of the voltage domain
|
||||
NvU32 unknown1;
|
||||
NvU32 max;
|
||||
|
||||
struct
|
||||
{
|
||||
NvU32 unknown2;
|
||||
NvU32 mvolt; //!< Voltage in mV
|
||||
} info[128];
|
||||
} NV_VOLTAGES_INFO;
|
||||
|
||||
// rev
|
||||
typedef struct _NV_VOLTAGES
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 flags; //!< Reserved for future use. Must be set to 0
|
||||
NvU32 max;
|
||||
NV_VOLTAGES_INFO voltages[NVAPI_MAX_GPU_PERF_VOLTAGES];
|
||||
} NV_VOLTAGES;
|
||||
|
||||
#define NV_VOLTAGES_INFO_VER MAKE_NVAPI_VERSION(NV_VOLTAGES, 1)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetVoltages)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_VOLTAGES* pPerfVoltages);
|
||||
_NvAPI_GPU_GetVoltages NvAPI_GPU_GetVoltages;
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_GetPerfClocks
|
||||
typedef struct _NV_PERF_CLOCKS_UNKNOWN_2
|
||||
{
|
||||
NvU32 unknown1;
|
||||
NvU32 unknown2;
|
||||
NvU32 unknown3;
|
||||
NvU32 unknown4;
|
||||
NvU32 unknown5;
|
||||
NvU32 unknown6;
|
||||
NvU32 unknown7;
|
||||
} NV_PERF_CLOCKS_UNKNOWN_2;
|
||||
|
||||
// rev
|
||||
typedef struct _NV_PERF_CLOCKS_UNKNOWN_1
|
||||
{
|
||||
NvU32 unknown1;
|
||||
NvU32 unknown2;
|
||||
NV_PERF_CLOCKS_UNKNOWN_2 unknown3[32];
|
||||
} NV_PERF_CLOCKS_UNKNOWN_1;
|
||||
|
||||
// rev
|
||||
typedef struct _NV_PERF_CLOCKS
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 unknown1;
|
||||
NvU32 unknown2;
|
||||
NvU32 unknown3;
|
||||
NvU32 unknown4;
|
||||
NV_PERF_CLOCKS_UNKNOWN_1 unknown5[12];
|
||||
} NV_PERF_CLOCKS;
|
||||
|
||||
#define NV_PERF_CLOCKS_INFO_VER MAKE_NVAPI_VERSION(NV_PERF_CLOCKS, 1)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetPerfClocks)(_In_ NvPhysicalGpuHandle hPhysicalGPU, INT i, _Inout_ NV_PERF_CLOCKS* pPerfClocks);
|
||||
_NvAPI_GPU_GetPerfClocks NvAPI_GPU_GetPerfClocks;
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_QueryActiveApps
|
||||
typedef struct _NV_ACTIVE_APP
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 processPID;
|
||||
NvAPI_LongString processName;
|
||||
} NV_ACTIVE_APP;
|
||||
|
||||
#define NV_ACTIVE_APPS_INFO_VER MAKE_NVAPI_VERSION(NV_ACTIVE_APP, 2)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status(__cdecl *_NvAPI_GPU_QueryActiveApps)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_ACTIVE_APP pActiveApps[NVAPI_MAX_PROCESSES], _Inout_ NvU32* pTotal);
|
||||
_NvAPI_GPU_QueryActiveApps NvAPI_GPU_QueryActiveApps;
|
||||
|
||||
|
||||
|
||||
// rev - NvAPI_GPU_GetPowerMizerInfo
|
||||
typedef enum _PowerSourceInfo
|
||||
{
|
||||
PowerSourceInfo_Unknown1 = 1,
|
||||
PowerSourceInfo_Unknown2,
|
||||
PowerSourceInfo_Unknown3 = 8738
|
||||
} PowerSourceInfo;
|
||||
|
||||
// rev
|
||||
typedef enum _SelectSource
|
||||
{
|
||||
SelectSource_Unknown1 = 1,
|
||||
SelectSource_Unknown2,
|
||||
SelectSource_Unknown3
|
||||
} SelectSource;
|
||||
|
||||
// rev
|
||||
typedef enum _LevelInfo
|
||||
{
|
||||
LevelInfo_Unknown1 = 1,
|
||||
LevelInfo_Unknown2,
|
||||
LevelInfo_Unknown3,
|
||||
LevelInfo_Unknown4,
|
||||
LevelInfo_Unknown5,
|
||||
LevelInfo_Unknown6,
|
||||
LevelInfo_Unknown7
|
||||
} LevelInfo;
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPowerMizerInfo)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PowerSourceInfo powerSourceInfo, SelectSource select, LevelInfo* pLevelInfo);
|
||||
_NvAPI_GPU_GetPowerMizerInfo NvAPI_GPU_GetPowerMizerInfo;
|
||||
|
||||
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverRegistryPath)(_In_ NvDisplayHandle hNvDisplay, _Inout_ NvAPI_LongString szDriverRegistryPath);
|
||||
_NvAPI_GetDisplayDriverRegistryPath NvAPI_GetDisplayDriverRegistryPath;
|
||||
|
||||
|
||||
|
||||
// rev
|
||||
//typedef NvAPI_Status (__cdecl *_NvAPI_RestartDisplayDriver)(_In_ NvU32 NvDriverIndex);
|
||||
//_NvAPI_RestartDisplayDriver NvAPI_RestartDisplayDriver;
|
||||
|
||||
|
||||
typedef enum _NV_POWER_TOPOLOGY_FLAGS
|
||||
{
|
||||
NV_POWER_TOPOLOGY_FLAG_DISABLED, // Unsure if name is correct
|
||||
NV_POWER_TOPOLOGY_FLAG_ENABLED // Unsure if name is correct
|
||||
} NV_POWER_TOPOLOGY_FLAGS;
|
||||
|
||||
|
||||
typedef struct _NV_POWER_TOPOLOGY_1
|
||||
{
|
||||
NvU32 unknown1;
|
||||
NvU32 unknown2;
|
||||
NvU32 unknown3;
|
||||
|
||||
// return this.unknown1 & 1u;
|
||||
// return (this.unknown1 & 4294967294u) / 2u;
|
||||
} NV_POWER_TOPOLOGY_1;
|
||||
|
||||
|
||||
typedef struct _NV_POWER_TOPOLOGY_2
|
||||
{
|
||||
NV_POWER_TOPOLOGY_FLAGS flags;
|
||||
NV_POWER_TOPOLOGY_1 unknown;
|
||||
} NV_POWER_TOPOLOGY_2;
|
||||
|
||||
typedef struct _NV_POWER_TOPOLOGY_STATUS
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 count;
|
||||
|
||||
NV_POWER_TOPOLOGY_2 unknown[4];
|
||||
} NV_POWER_TOPOLOGY_STATUS;
|
||||
|
||||
#define NV_POWER_TOPOLOGY_STATUS_VER MAKE_NVAPI_VERSION(NV_POWER_TOPOLOGY_STATUS, 1)
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_ClientPowerTopologyGetStatus)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_POWER_TOPOLOGY_STATUS* pClientPowerTopologyStatus);
|
||||
_NvAPI_GPU_ClientPowerTopologyGetStatus NvAPI_GPU_ClientPowerTopologyGetStatus;
|
||||
|
||||
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetShortName)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NvAPI_ShortString szName);
|
||||
_NvAPI_GPU_GetShortName NvAPI_GPU_GetShortName;
|
||||
|
||||
|
||||
// rev
|
||||
typedef struct _NV_ARCH_INFO
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NvU32 unknown[3];
|
||||
} NV_ARCH_INFO;
|
||||
|
||||
#define NV_ARCH_INFO_VER MAKE_NVAPI_VERSION(NV_ARCH_INFO, 2)
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetArchInfo)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_ARCH_INFO* pArchInfo);
|
||||
_NvAPI_GPU_GetArchInfo NvAPI_GPU_GetArchInfo;
|
||||
|
||||
|
||||
|
||||
// rev
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPartitionCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Out_ NvU32* pCount);
|
||||
_NvAPI_GPU_GetPartitionCount NvAPI_GPU_GetPartitionCount;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct _NV_PCIE_INFO_UNKNOWN
|
||||
{
|
||||
NvU32 unknown0;
|
||||
NvU32 unknown1;
|
||||
NvU32 unknown2;
|
||||
NvU32 unknown3;
|
||||
NvU32 unknown4;
|
||||
NvU32 unknown5;
|
||||
NvU32 unknown6;
|
||||
NvU32 unknown7;
|
||||
} NV_PCIE_INFO_UNKNOWN;
|
||||
|
||||
typedef struct _NV_PCIE_INFO
|
||||
{
|
||||
NvU32 version; //!< Structure version
|
||||
NV_PCIE_INFO_UNKNOWN info[5];
|
||||
} NV_PCIE_INFO;
|
||||
|
||||
#define NV_PCIE_INFO_VER MAKE_NVAPI_VERSION(NV_PCIE_INFO, 2)
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPCIEInfo)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_PCIE_INFO* pPciInfo);
|
||||
_NvAPI_GPU_GetPCIEInfo NvAPI_GPU_GetPCIEInfo;
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverBuildTitle)(_In_ NvDisplayHandle hNvDisplay, NvAPI_ShortString pDriverBuildTitle);
|
||||
_NvAPI_GetDisplayDriverBuildTitle NvAPI_GetDisplayDriverBuildTitle;
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverCompileType)(_In_ NvDisplayHandle hNvDisplay, NvU32* pDriverCompileType);
|
||||
_NvAPI_GetDisplayDriverCompileType NvAPI_GetDisplayDriverCompileType;
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverSecurityLevel)(_In_ NvDisplayHandle hNvDisplay, NvU32* pDriverSecurityLevel);
|
||||
_NvAPI_GetDisplayDriverSecurityLevel NvAPI_GetDisplayDriverSecurityLevel;
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetVPECount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pVPECount);
|
||||
_NvAPI_GPU_GetVPECount NvAPI_GPU_GetVPECount;
|
||||
|
||||
//typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetExtendedMinorRevision)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBankCount);
|
||||
//typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetSerialNumber)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PBYTE pRamBankCount);
|
||||
|
||||
typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetTargetID)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PBYTE pRamBankCount);
|
||||
_NvAPI_GPU_GetTargetID NvAPI_GPU_GetTargetID;
|
||||
|
||||
|
||||
#include <poppack.h>
|
||||
61
plugins/HardwareDevices/resource.h
Normal file
61
plugins/HardwareDevices/resource.h
Normal file
@@ -0,0 +1,61 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by HardwareDevices.rc
|
||||
//
|
||||
#define IDD_NETADAPTER_OPTIONS 101
|
||||
#define IDD_NETADAPTER_DIALOG 102
|
||||
#define IDD_NETADAPTER_PANEL 104
|
||||
#define IDD_NETADAPTER_DETAILS 105
|
||||
#define IDD_DISKDRIVE_DETAILS_FILESYSTEM 109
|
||||
#define IDD_DISKDRIVE_DETAILS_GENERAL 111
|
||||
#define IDD_GPU_DIALOG 1077
|
||||
#define IDD_DISKDRIVE_OPTIONS 1013
|
||||
#define IDD_DISKDRIVE_DIALOG 1014
|
||||
#define IDD_DISKDRIVE_PANEL 1016
|
||||
#define IDD_DISKDRIVE_DETAILS_SMART 1017
|
||||
#define IDC_GRAPH_LAYOUT 103
|
||||
#define IDC_NETADAPTERS_LISTVIEW 1001
|
||||
#define IDC_LINK_SPEED 1002
|
||||
#define IDC_ADAPTERNAME 1003
|
||||
#define IDC_LAYOUT 1004
|
||||
#define IDC_LINK_STATE 1005
|
||||
#define IDC_STAT_BSENT 1006
|
||||
#define IDC_STAT_BRECEIVED 1007
|
||||
#define IDC_STAT_BTOTAL 1008
|
||||
#define IDC_DETAILS 1010
|
||||
#define IDC_DETAILS_LIST 1011
|
||||
#define IDC_SHOW_HIDDEN_ADAPTERS 1012
|
||||
#define IDC_EDIT1 1015
|
||||
#define IDC_DISKDRIVE_LISTVIEW 1017
|
||||
#define IDC_DESCRIPTION 1017
|
||||
#define IDC_DISKMOUNTPATH 1018
|
||||
#define IDC_TITLE 1019
|
||||
#define IDC_STAT_BREAD 1020
|
||||
#define IDC_STAT_BWRITE 1021
|
||||
#define IDC_STAT_ACTIVE 1023
|
||||
#define IDC_STAT_RESPONSETIME 1024
|
||||
#define IDC_STAT_QUEUELENGTH 1025
|
||||
#define IDC_DISKNAME 1076
|
||||
#define IDC_GPUNAME 1078
|
||||
#define IDC_GPU_L 1079
|
||||
#define IDC_MEMORY_L 1080
|
||||
#define IDC_SHARED_L 1081
|
||||
#define IDC_BUS_L 1082
|
||||
#define IDD_GPU_PANEL 1083
|
||||
#define IDC_CLOCK_CORE 211
|
||||
#define IDC_CLOCK_MEMORY 212
|
||||
#define IDC_FAN_PERCENT 213
|
||||
#define IDC_TEMP_VALUE 214
|
||||
#define IDC_CLOCK_SHADER 215
|
||||
#define IDC_VOLTAGE 217
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 114
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1020
|
||||
#define _APS_NEXT_SYMED_VALUE 106
|
||||
#endif
|
||||
#endif
|
||||
1570
plugins/HardwareDevices/storage.c
Normal file
1570
plugins/HardwareDevices/storage.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user