@cryptotaxi247 / netdata-1 / commits / 6d6e52238

Improve installer (Windows.plugin) (#21911)

thiagoftsm committed Mar 11, 2026 at 23:06 UTC 6d6e52238d3ce5b18ba7b6da874e3c60fea806c5
9 files changed +259 -13
.github/workflows/build.yml
+1 -1
@@ -389,7 +389,7 @@ jobs:
389 signing-account-name: Netdata
390 certificate-profile-name: Netdata
391 files-folder: ${{ github.workspace }}\build
392 - files-folder-filter: exe,dll,sys
392 + files-folder-filter: exe,dll,sys,inf
393 files-folder-recurse: true
394 file-digest: SHA256
395 timestamp-rfc3161: "http://timestamp.acs.microsoft.com"
CMakeLists.txt
+10 -4
@@ -2021,8 +2021,8 @@ set(WINDOWS_PLUGIN_FILES
2021 )
2022
2023 set(WINDOWS_PLUGIN_DRIVER
2024 - src/collectors/windows.plugin/netdata_win_driver.c
2025 - src/collectors/windows.plugin/netdata_win_driver.h
2024 + src/collectors/windows.plugin/driver/netdata_driver.c
2025 + src/collectors/windows.plugin/driver/netdata_driver.h
2026 )
2027
2028 set(PROC_PLUGIN_FILES
@@ -3069,6 +3069,7 @@ if(OS_WINDOWS)
3069 configure_file(packaging/windows/eula.rtf eula.rtf COPYONLY)
3070 configure_file(packaging/windows/Top.bmp Top.bmp COPYONLY)
3071 configure_file(packaging/windows/BackGround.bmp BackGround.bmp COPYONLY)
3072 + configure_file(src/collectors/windows.plugin/driver/netdata_driver.inf netdata_driver.inf COPYONLY)
3073 endif()
3074
3075 add_executable(netdata
@@ -3089,12 +3090,13 @@ if(OS_WINDOWS)
3090 target_compile_options(NetdataClaim PUBLIC -mwindows)
3091
3092 set(NETDATA_DRIVER_FILE "${CMAKE_BINARY_DIR}/netdata_driver.sys")
3093 + set(NETDATA_DRIVER_FILE_INF "${CMAKE_BINARY_DIR}/netdata_driver.inf")
3094
3095 add_library(netdata_driver SHARED ${WINDOWS_PLUGIN_DRIVER})
3096 set_target_properties(netdata_driver PROPERTIES LIBRARY_OUTPUT_NAME "netdata_driver")
3097 set_target_properties(netdata_driver PROPERTIES PREFIX "")
3098 set_target_properties(netdata_driver PROPERTIES SUFFIX ".sys")
3097 - target_include_directories(netdata_driver PRIVATE BEFORE "/mingw64/include/ddk" "${CMAKE_SOURCE_DIR}/src/collectors/windows.plugin")
3099 + target_include_directories(netdata_driver PRIVATE BEFORE "/mingw64/include/ddk" "${CMAKE_SOURCE_DIR}/src/collectors/windows.plugin" "${CMAKE_SOURCE_DIR}/src/collectors/windows.plugin/driver")
3100 target_compile_options(netdata_driver PRIVATE
3101 -Wall
3102 -Wextra
@@ -3114,7 +3116,11 @@ if(OS_WINDOWS)
3116 target_link_libraries(netdata_driver kernel32 ntoskrnl)
3117
3118 install(FILES "${NETDATA_DRIVER_FILE}"
3117 - COMPONENT netdata_win_driver
3119 + COMPONENT netdata_driver
3120 + DESTINATION "${BINDIR}")
3121 +
3122 + install(FILES "${NETDATA_DRIVER_FILE_INF}"
3123 + COMPONENT netdata_driver_inf
3124 DESTINATION "${BINDIR}")
3125 endif()
3126
packaging/windows/generate-driver-catalog.ps1 new
+95
@@ -0,0 +1,95 @@
1 +# Generate the Netdata driver catalog file required by WiX packaging.
2 +#
3 +# Requires INF and SYS files already staged in the target directory.
4 +
5 +#Requires -Version 4.0
6 +
7 +param(
8 + [Parameter(Mandatory = $true)]
9 + [string]$DriverDirectory,
10 +
11 + [Parameter()]
12 + [string]$OsTargets = "10_GE_X64,10_25H2_X64,Server2025_X64,10_NI_X64,10_CO_X64,ServerFE_X64,10_VB_X64,10_19H1_X64,10_RS5_X64,ServerRS5_X64,10_RS4_X64,10_RS3_X64,10_RS2_X64,10_AU_X64,10_X64,Server10_X64"
13 +)
14 +
15 +$ErrorActionPreference = "Stop"
16 +
17 +function Find-Inf2Cat {
18 + $command = Get-Command Inf2Cat.exe -ErrorAction SilentlyContinue
19 + if ($null -ne $command) {
20 + return $command.Source
21 + }
22 +
23 + $kitRoots = @(
24 + (Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\bin"),
25 + (Join-Path $env:ProgramFiles "Windows Kits\10\bin")
26 + )
27 +
28 + $candidates = @()
29 + foreach ($root in $kitRoots) {
30 + if (Test-Path $root) {
31 + # Prefer the typical WDK/SDK layout: Windows Kits\10\bin\<version>\x64\Inf2Cat.exe
32 + $patternX64 = Join-Path $root '*\x64\Inf2Cat.exe'
33 + $found = Get-ChildItem -Path $patternX64 -File -ErrorAction SilentlyContinue
34 + if (-not $found) {
35 + # Fallback: any versioned subfolder directly under bin containing Inf2Cat.exe
36 + $patternAnyArch = Join-Path $root '*\Inf2Cat.exe'
37 + $found = Get-ChildItem -Path $patternAnyArch -File -ErrorAction SilentlyContinue
38 + if ($found) {
39 + $candidates += $found
40 + }
41 + }
42 + }
43 + }
44 +
45 + if ($candidates.Count -eq 0) {
46 + throw "Inf2Cat.exe not found. Install Windows Driver Kit (WDK) or Windows SDK tools with Inf2Cat."
47 + }
48 +
49 + $x64Candidates = $candidates | Where-Object { $_.FullName -match '\\x64\\Inf2Cat\.exe$' }
50 + if ($x64Candidates.Count -gt 0) {
51 + $candidates = $x64Candidates
52 + }
53 +
54 + $latest = $candidates |
55 + Sort-Object -Property {
56 + $match = [regex]::Match($_.FullName, '\\10\\bin\\(?<ver>\d+\.\d+\.\d+\.\d+)\\')
57 + if ($match.Success) {
58 + [version]$match.Groups['ver'].Value
59 + } else {
60 + [version]"0.0.0.0"
61 + }
62 + } -Descending |
63 + Select-Object -First 1
64 +
65 + return $latest.FullName
66 +}
67 +
68 +$driverDir = (Resolve-Path -LiteralPath $DriverDirectory).Path
69 +$driverInf = Join-Path $driverDir "netdata_driver.inf"
70 +$driverSys = Join-Path $driverDir "netdata_driver.sys"
71 +$driverCat = Join-Path $driverDir "netdata_driver.cat"
72 +
73 +if (-not (Test-Path $driverInf)) {
74 + throw "Missing driver INF: $driverInf"
75 +}
76 +
77 +if (-not (Test-Path $driverSys)) {
78 + throw "Missing driver SYS: $driverSys"
79 +}
80 +
81 +$inf2cat = Find-Inf2Cat
82 +Write-Host "Using Inf2Cat: $inf2cat"
83 +Write-Host "Generating driver catalog in: $driverDir"
84 +
85 +& $inf2cat "/driver:$driverDir" "/os:$OsTargets"
86 +
87 +if ($LastExitCode -ne 0) {
88 + throw "Inf2Cat failed with exit code $LastExitCode"
89 +}
90 +
91 +if (-not (Test-Path $driverCat)) {
92 + throw "Catalog generation failed, missing output: $driverCat"
93 +}
94 +
95 +Write-Host "Generated driver catalog: $driverCat"
packaging/windows/netdata.wxs.in
+15 -1
@@ -171,7 +171,18 @@
171 </Package>
172
173 <Fragment>
174 + <UI>
175 + <ProgressText Action="NDKillProcess" Message="Stopping Netdata service before update..." />
176 + <ProgressText Action="NDStopDriverSrv" Message="Stopping Netdata driver service..." />
177 + <ProgressText Action="NDRemoveDriverSrv" Message="Removing Netdata driver service..." />
178 + </UI>
179 +
180 <StandardDirectory Id="System64Folder">
181 + <Directory Id="DRIVERDIR" Name="drivers" />
182 + </StandardDirectory>
183 +
184 + <StandardDirectory Id="WindowsFolder">
185 + <Directory Id="INFDIR" Name="INF" />
186 </StandardDirectory>
187
188 <!-- All the files except for the ones we need to handle specially -->
@@ -181,6 +192,7 @@
192 <Exclude Files="C:\msys64\opt\netdata\usr\bin\wevt_netdata_manifest.xml" />
193 <Exclude Files="C:\msys64\opt\netdata\usr\bin\wevt_netdata.dll" />
194 <Exclude Files="C:\msys64\opt\netdata\usr\bin\netdata_driver.sys" />
195 + <Exclude Files="C:\msys64\opt\netdata\usr\bin\netdata_driver.inf" />
196 </Files>
197 </ComponentGroup>
198
@@ -254,7 +266,9 @@
266
267 <!-- Install netdata driver file -->
268 <FeatureGroup Id="NetdataDriver">
257 - <File Id="NetdataDrv" Name="netdata_driver.sys" Directory="System64Folder" Source="C:\msys64\opt\netdata\usr\bin\netdata_driver.sys" Condition="NDDRVINST=1">
269 + <File Id="NetdataDrv" Name="netdata_driver.sys" Directory="DRIVERDIR" Source="C:\msys64\opt\netdata\usr\bin\netdata_driver.sys" Condition="NDDRVINST=1">
270 + </File>
271 + <File Id="NetdataDrvInf" Name="netdata_driver.inf" Directory="INFDIR" Source="C:\msys64\opt\netdata\usr\bin\netdata_driver.inf" Condition="NDDRVINST=1">
272 </File>
273 </FeatureGroup>
274
packaging/windows/package-windows.sh
+7
@@ -50,3 +50,10 @@ if [ ! -f "/opt/netdata/etc/profile" ]; then
50 fi
51 ${GITHUB_ACTIONS+echo "::endgroup::"}
52
53 +# TODO: We will have a PR to adjust CAB file creation and sign. This is only adding necessary structure
54 +#${GITHUB_ACTIONS+echo "::group::CAB file"}
55 +#mkdir "${build}/driver"
56 +#cp "${build}/usr/bin/netdata_driver.*" "${build}/driver"
57 +#powershell.exe -ExecutionPolicy Bypass -File "${repo_root}/packaging/windows/generate-driver-catalog.ps1"
58 +#${GITHUB_ACTIONS+echo "::endgroup::"}
59 +
src/collectors/windows.plugin/GetHardwareInfo.c
+86 -7
@@ -3,10 +3,10 @@
3 #include "windows_plugin.h"
4 #include "windows-internals.h"
5
6 -#include "netdata_win_driver.h"
6 +#include "driver/netdata_driver.h"
7
8 static const char *srv_name = "NetdataDriver";
9 -static const char *drv_path = "%SystemRoot%\\system32\\netdata_driver.sys";
9 +static const char *drv_path = "%SystemRoot%\\system32\\drivers\\netdata_driver.sys";
10
11 struct cpu_data {
12 RRDDIM *rd_cpu_temp;
@@ -99,6 +99,32 @@ int netdata_install_driver()
99
100 if (unlikely(!service)) {
101 if (GetLastError() == ERROR_SERVICE_EXISTS) {
102 + SC_HANDLE existing = OpenServiceA(scm, srv_name, SERVICE_CHANGE_CONFIG);
103 + if (!existing) {
104 + nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot open existing service. Error= %lu \n", GetLastError());
105 + CloseServiceHandle(scm);
106 + return -1;
107 + }
108 +
109 + if (!ChangeServiceConfigA(
110 + existing,
111 + SERVICE_KERNEL_DRIVER,
112 + SERVICE_DEMAND_START,
113 + SERVICE_ERROR_NORMAL,
114 + expanded_path,
115 + NULL,
116 + NULL,
117 + NULL,
118 + NULL,
119 + NULL,
120 + NULL)) {
121 + nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot reconfigure existing service. Error= %lu \n", GetLastError());
122 + CloseServiceHandle(existing);
123 + CloseServiceHandle(scm);
124 + return -1;
125 + }
126 +
127 + CloseServiceHandle(existing);
128 CloseServiceHandle(scm);
129 return 0;
130 }
@@ -114,6 +140,16 @@ int netdata_install_driver()
140 return 0;
141 }
142
143 +static inline void log_invalid_image_hash_error(void)
144 +{
145 + nd_log(
146 + NDLS_COLLECTORS,
147 + NDLP_ERR,
148 + "Driver failed to start: ERROR_INVALID_IMAGE_HASH (577). "
149 + "This usually indicates a driver signature verification failure. "
150 + "The driver binary may be corrupted, unsigned, or signed with an untrusted certificate.\n");
151 +}
152 +
153 int netdata_start_driver()
154 {
155 SC_HANDLE scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
@@ -124,22 +160,65 @@ int netdata_start_driver()
160
161 SC_HANDLE service = OpenServiceA(scm, srv_name, SERVICE_START | SERVICE_QUERY_STATUS);
162 if (unlikely(!service)) {
163 + DWORD open_err = GetLastError();
164 CloseServiceHandle(scm);
128 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot open Service. Error= %lu \n", GetLastError());
129 - return -1;
165 + scm = NULL;
166 +
167 + // Service missing: attempt self-healing install then retry
168 + if (open_err == ERROR_SERVICE_DOES_NOT_EXIST) {
169 + nd_log(NDLS_COLLECTORS, NDLP_INFO, "Service not found, attempting to install driver and retry start\n");
170 +
171 + if (netdata_install_driver() != 0) {
172 + nd_log(NDLS_COLLECTORS, NDLP_ERR, "Failed to install driver during self-healing\n");
173 + return -1;
174 + }
175 +
176 + scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
177 + if (unlikely(!scm)) {
178 + nd_log(
179 + NDLS_COLLECTORS,
180 + NDLP_ERR,
181 + "Cannot open Service Manager after install. Error= %lu \n",
182 + GetLastError());
183 + return -1;
184 + }
185 +
186 + service = OpenServiceA(scm, srv_name, SERVICE_START | SERVICE_QUERY_STATUS);
187 + if (unlikely(!service)) {
188 + nd_log(
189 + NDLS_COLLECTORS,
190 + NDLP_ERR,
191 + "Cannot open Service after install. Error= %lu \n",
192 + GetLastError());
193 + CloseServiceHandle(scm);
194 + return -1;
195 + }
196 + // fall through to StartServiceA with the newly opened handle
197 + } else {
198 + nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot open Service. Error= %lu \n", open_err);
199 + return -1;
200 + }
201 }
202
203 int ret = 0;
204 if (!StartServiceA(service, 0, NULL)) {
205 DWORD err = GetLastError();
135 - if (err != ERROR_SERVICE_ALREADY_RUNNING) {
206 +
207 + if (err == ERROR_SERVICE_ALREADY_RUNNING) {
208 + ret = 0;
209 + } else if (err == ERROR_INVALID_IMAGE_HASH) {
210 + log_invalid_image_hash_error();
211 + ret = -1;
212 + } else {
213 nd_log(NDLS_COLLECTORS, NDLP_ERR, "Cannot start Service. Error= %lu \n", err);
214 ret = -1;
215 }
216 }
217
141 - CloseServiceHandle(service);
142 - CloseServiceHandle(scm);
218 + if (service)
219 + CloseServiceHandle(service);
220 + if (scm)
221 + CloseServiceHandle(scm);
222 return ret;
223 }
224
src/collectors/windows.plugin/driver/netdata_driver.c renamed
src/collectors/windows.plugin/driver/netdata_driver.h renamed
src/collectors/windows.plugin/driver/netdata_driver.inf new
+45
@@ -0,0 +1,45 @@
1 +;
2 +; Netdata Driver INF File
3 +;
4 +
5 +[Version]
6 +Signature="$Windows NT$"
7 +Class=System
8 +ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
9 +Provider=%Provider%
10 +DriverVer=03/07/2026,1.0.0.0
11 +CatalogFile=netdata_driver.cat
12 +
13 +[DestinationDirs]
14 +DefaultDestDir = 12
15 +
16 +[DefaultInstall.NTamd64]
17 +CopyFiles = DriverCopyFiles
18 +
19 +[DefaultInstall.NTamd64.Services]
20 +AddService = NetdataDriver,,DriverServiceInstall
21 +
22 +[DefaultUninstall.NTamd64]
23 +LegacyUninstall=1
24 +DelFiles = DriverCopyFiles
25 +
26 +[DriverCopyFiles]
27 +netdata_driver.sys
28 +
29 +[SourceDisksFiles]
30 +netdata_driver.sys = 1
31 +
32 +[SourceDisksNames]
33 +1 = %DiskName%,,,""
34 +
35 +[DriverServiceInstall]
36 +DisplayName = %DeviceDesc%
37 +ServiceType = 1
38 +StartType = 3
39 +ErrorControl = 1
40 +ServiceBinary = %12%\netdata_driver.sys
41 +
42 +[Strings]
43 +Provider = "Netdata"
44 +DeviceDesc = "Netdata Driver"
45 +DiskName = "Netdata Driver Disk"