Hardware Sensor Architecture & Driver Implementation
LocalTelemetry reads low-level hardware registers directly from kernel drivers, vendor-provided dynamic link libraries, and Windows performance counters.
Hardware Sensor Architecture
Hardware Sensor Sources Summary
| Metric Category | Primary API Source | Fallback / Alternative |
|---|---|---|
| CPU Usage | GetSystemTimes (Win32 kernel32 API) | Per-core \Processor Information(*)\% Processor Utility (PDH) |
| CPU Temperature | PawnIO IntelMSR (MSR 0x1B1 / 0x1A2) | PawnIO RyzenSMU (AMD PM Table) / IntelPowerGadget.cs |
| CPU Frequency | PawnIO APERF/MPERF MSR delta | IntelPowerGadget.cs (live clocks) / CallNtPowerInformation baseline |
| CPU Package Power | RAPL Energy Status MSRs (0x606 / 0x611) | IntelPowerGadget.cs / Estimated TDP calculation |
| RAM Usage | GlobalMemoryStatusEx (Win32 API) | N/A |
| GPU Utilization | NVML (NVIDIA) / ADL (AMD) / IGCL (Intel) | WddmGpuMonitor.cs (WDDM Engine Counters via D3DKMT) |
| GPU Temperature | nvmlDeviceGetTemperature | ADL_Overdrive6_Temperature_Get / IGCL |
| GPU VRAM Usage | nvmlDeviceGetMemoryInfo | ADL VRAM queries / WDDM VRAM Counters |
| Disk Throughput | \PhysicalDisk(*)\Disk Read & Write Bytes | DiskQuery.cs (Win32 IOCTLs) |
| Network Speeds | NetworkInterface.GetIPv4Statistics() delta | EseNetworkUsageReader.cs (Windows ESE SRUDB database) |
| Battery Level & W | GetSystemPowerStatus & root\wmi | N/A (Desktop systems return empty / disabled) |
Kernel Access with PawnIo
PawnIo Driver Architecture & Micro-Scripts
To read CPU package temperatures, MSR (Model-Specific Register) values, and AMD Ryzen SMU metrics, LocalTelemetry utilizes the PawnIo kernel driver interface located in src/LocalTelemetry.Core/Hardware/PawnIo/:
- Silent Elevation Setup:
PawnIoDevice.TryInstallexecutesPawnIO_setup.exe -install -silentand configures thePawnIOkernel service. Because the host process is elevated at launch viaapp.manifest, the installation runs without prompting for additional UAC confirmations. - Embedded Binary Scripts (
.binResources):LocalTelemetry.Coreembeds pre-compiled PawnIO hardware definition micro-scripts uploaded to the driver on initialization:AMDFamily0F.bin,AMDFamily10.bin,AMDFamily17.bin: AMD CPU family models and MSR/SMU routinesRyzenSMU.bin: Ryzen SMU mailbox interface for Zen 2, Zen 3, Zen 4, and Zen 5 architecturesIntelMSR.bin,IntelMCHBAR.bin: Intel MSR and memory controller hub BAR accessIntelOOBMSM.bin,IntelPCHThermal.bin: Intel Out-of-Band management and PCH thermal sensorsDellSMM.bin: Dell System Management Mode fan and thermal controlsIsaBridgeEC.bin,LpcCrOSEC.bin,LpcIO.bin: Embedded Controller (EC) and Super I/O chip accessSmbusI801.bin,SmbusIntelSkylakeIMC.bin,SmbusNCT6793.bin,SmbusPIIX4.bin: SMBus controller interfaces
Driver Handle Management & IOCTL Dispatch
- Transport communication occurs via
DeviceIoControlwith Windows kernel driver handles (\\.\PawnIO). - Handles are safely wrapped in disposable abstractions (
IPawnIoTransport) and closed during application shutdown to avoid leaving dangling driver locks.
CPU Telemetry: Intel vs AMD
CPU Architecture Detection
At startup, HardwareMonitor.cs inspects the processor vendor string via CPUID instruction queries to route queries to dedicated readers:
GenuineIntel: Routes toIntelMsrReader.csandIntelPowerGadget.csAuthenticAMD: Routes toAmdMsrReader.cs
Intel Package Temperature & TjMax (MSR 0x1A2 & 0x1B1)
In IntelMsrReader.cs, Intel processor temperatures are computed using package-level thermal status:
Target Temperature (
MSR_IA32_TEMPERATURE_TARGET=0x1A2): Reads target junction limit:csharpint tjMax = (int)((tjTarget >> 16) & 0xFF);Package Thermal Status (
MSR_IA32_PACKAGE_THERM_STATUS=0x1B1): Reads digital readout delta relative to TjMax:csharpint digitalReadout = (int)((thermStatus >> 16) & 0xFF);Current Package Temperature: $$\text{Temperature (°C)} = \text{tjMax} - \text{digitalReadout}$$
AMD Ryzen Temperature Resolution & Fallback Hierarchy
In AmdMsrReader.cs and HardwareMonitor.cs, AMD processor temperatures resolve across a 3-tier hierarchy:
Primary: SMN Register 0x00059800 (
THM_TCON_CUR_TMP):Supported across AMD Zen 1 through Zen 5 architectures using
AMDFamily17.bin.Dispatches
ioctl_read_smntargeting System Management Network (SMN) register0x00059800.Decodes temperature bitfields:
csharpuint raw = (uint)(result[0] & 0xFFFFFFFF); uint curTemp = (raw >> 21) & 0x7FF; float temp = curTemp * 0.125f;Validates that decoded temperature falls between
10°Cand125°C.
Secondary Fallback: SMU Power Management Table (PM Table):
- Falls back to
RyzenSMU.binon legacy Ryzen platforms or when SMN yields zero. - Calls
ioctl_resolve_pm_tableto locate the SMU PM table structure in memory. - Invokes
ioctl_update_pm_tableto refresh telemetry data. - Iterates across
PM_TABLE_ENTRY_COUNT = 128entries. Decodes valid entries usingTryDecodeTemperatureto return peak package temperature.
- Falls back to
Tertiary Fallback: ACPI Thermal Zone WMI Query:
If kernel driver calls fail or return zero,
HardwareMonitor.csqueries Windows Management Instrumentation (root\wmi).Queries
SELECT CurrentTemperature FROM MSAcpi_ThermalZoneTemperature.Converts raw tenth-degree Kelvin values to Celsius:
$$\text{Temperature (°C)} = \frac{\text{rawKelvin10} - 2732}{10.0}$$
Validates that computed temperature falls between
15°Cand125°C.
Dynamic GPU Reset & TDR Recovery
When Windows display adapters restart (e.g. driver update, GPU TDR recovery, or waking from sleep), hardware monitors must re-initialize without crashing the host process:
HardwareMonitor.csimplementsResetGpuMonitors(string reason):_nvGpu?.Reset(): Re-initializes NVML handles and device contexts._wddmGpu?.Reset(): Flushes cached D3DKMT adapter handles and re-queries adapter statistics._amdGpu?.Reset(): Rebinds ADL context._intelGpu?.Reset(): Rebinds Intel ControlLib context.
- When waking from system standby,
HardwareLifecycleManagerdelays recovery by3000 msto allow PCIe buses and graphics drivers to reach operational power states before querying registers.
Disk Telemetry: Performance Counters & IOCTL Storage Queries
PhysicalDisk Performance Counters (I/O Rates)
- Read and write speeds are polled directly through Windows
PhysicalDiskPerformance Counters:\PhysicalDisk(_Total)\Disk Read Bytes/sec&Disk Write Bytes/sec- Per-disk instance counters:
\PhysicalDisk(0 C:)\...,\PhysicalDisk(1 D:)\...
- Disks are registered dynamically in
Metrics.RegisterDisk("disk0", "DISK0")to allow per-drive layout customization.
Win32 Storage IOCTL & Boot Drive Detection (DiskQuery)
DiskQuery.csqueries physical drive descriptors:IOCTL_STORAGE_QUERY_PROPERTY: Queries storage bus type (NVMe,SATA,SCSI,USB), device media type (SSD vs HDD), and vendor labels.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: Maps logical Windows drive letters (C:,D:) to underlying physical disk indices.- Resolves the official Windows
Bootdrive badge. - Standardized display labels: single drive of a type displays without an index (
NVMeR,SATAR), while multiple drives append a 1-based index (NVMe1R,NVMe2R,SATA1W).
Historical Bandwidth Extraction (EseNetworkUsageReader)
EseNetworkUsageReader.csqueries the Windows System Resource Usage Monitor database (C:\Windows\System32\sru\SRUDB.dat).- Uses the native Windows Extensible Storage Engine (
esent.dll) P/Invoke interface:- Attaches to the database in read-only recovery mode.
- Scans table
{973F5D5C-1D90-4944-BE8E-24B94231A174}for network interface data usage. - Maps interface GUIDs to physical adapter names.
- Feeds historical daily upload and download octets into
TrafficHistoryStore.csfor calendar display.
- Backup Importer Subsystems:
JsonlTrafficImporter.csparses line-delimited JSON usage records frominternet_usage.jsonlbackup files.DatImporter.csparses legacy plaintext.datfiles. Both merge records intoTrafficHistoryStore.cs.
Battery Telemetry: Win32 & WMI Subsystems
- Charge State & Level: Samples remaining battery percentage and AC power connection status via
GetSystemPowerStatus. - Real-Time Charge / Discharge Rate: Queries WMI
root\wmi:BatteryStatusto sample remaining milliwatt-hours (mWh). Delta over time intervals calculates real-time rate in Watts (W). - Hardware Metadata Extraction: Inspects WMI
root\wmi:BatteryStaticDataandWin32_Batteryto extract authentic manufacturer name, device model, designed capacity, and full charge capacity. - Battery Health & Wear Percentage:
SystemInfo.GetBatteryHealthPct()computes health via(FullChargedCapacity / DesignCapacity) * 100.SystemInfo.GetBatteryWearLevelPct()calculates wear percentage. - Charge Cycle Count:
SystemInfo.GetBatteryCycleCount()queriesroot\wmi:BatteryCycleCountfor total lifetime hardware charge cycles. - Virtual Battery Filtering: Automatically filters out virtual battery stubs (e.g.
-Virtual Battery 0-,CRB Battery 0), prioritizing physical battery hardware.
Driver Security & Cleanup Protocols
- Driver Whitelist Verification: All binary scripts uploaded to
PawnIOare signed embedded resources compiled directly intoLocalTelemetry.Core.dll. - Driver Uninstallation & DriverStore Removal:
- The Inno Setup uninstaller and portable
Uninstall.batinvokepnputil.exe /delete-driver <oem.inf> /uninstall /forceto purgepawnio.inffrom the Windows DriverStore. - If Windows reports that the kernel driver handle is locked in memory (exit code
3010), the user is prompted to restart the system before reinstalling.
- The Inno Setup uninstaller and portable