From cdaed196029161e93d3592fedddc19096cb56b6c Mon Sep 17 00:00:00 2001 From: mikhailm-coder Date: Tue, 15 Sep 2026 13:02:59 +0200 Subject: [PATCH] fix(agent): derive the Windows OS name from the registry, not WMI os.Name's win32 branch ran a synchronous require('win-wmi').query for Win32_OperatingSystem on every control-channel connect. That call blocks the single microstack thread with no timeout; when the WMI provider host (WmiPrvSE) can't register with DCOM, it never returns, the chain watchdog (ILibChain_WATCHDOG_TIMEOUT, 10 min) exits the process after two stuck cycles, SCM restarts it ~5s later, and it wedges again -- a ~20-minute crash loop. On a Windows RDS host this ran 50+ times, saturated the Service Control Manager, and deadlocked Remote Desktop until a reboot. Read the OS name from the registry instead (ProductName + CurrentBuild + DisplayVersion), which cannot hang. A CurrentBuild >= 22000 check corrects the known-stale Windows 11 ProductName. win32 branch only; linux/darwin/ freebsd unchanged. The value is a display/search label (MeshCentral console + coreinfo.osdesc); no consumer parses its format. Co-Authored-By: Claude Opus 4.8 --- microscript/ILibDuktape_ScriptContainer.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/microscript/ILibDuktape_ScriptContainer.c b/microscript/ILibDuktape_ScriptContainer.c index b206cf010..a3d6747f0 100644 --- a/microscript/ILibDuktape_ScriptContainer.c +++ b/microscript/ILibDuktape_ScriptContainer.c @@ -2506,23 +2506,18 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain) }\ catch(zz)\ {}\ + /* OpenFrame: OS name from the registry, not WMI - the WMI query blocks the microstack thread until the 10min x2 watchdog kills the agent when WmiPrvSE is starved; the build-number check corrects the stale Win11 ProductName. */\ + var build = '';\ + try { build = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\MICROSOFT\\\\WINDOWS NT\\\\CurrentVersion', 'CurrentBuild'); } catch(zz) {}\ try\ {\ - ret = require('win-wmi').query('ROOT\\\\CIMV2', \"SELECT * FROM Win32_OperatingSystem\", ['Caption','BuildNumber']);\ - ret = ret[0].Caption + ' - ' + friendly + ret[0].BuildNumber;\ + ret = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\MICROSOFT\\\\WINDOWS NT\\\\CurrentVersion', 'ProductName');\ + if (parseInt(build) >= 22000 && ret.indexOf('Windows 10') == 0) { ret = ret.replace('Windows 10', 'Windows 11'); }\ + ret = ret + ' - ' + friendly + build;\ }\ - catch(zz)\ + catch(zzz)\ {\ - try\ - {\ - ret = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\MICROSOFT\\\\WINDOWS NT\\\\CurrentVersion', 'ProductName');\ - ret = ret + ' - ' + friendly + require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\MICROSOFT\\\\WINDOWS NT\\\\CurrentVersion', 'CurrentBuild');\ - }\ - catch(zzz)\ - {\ - ret = 'Windows (UNKNOWN) - ' + friendly;\ - }\ - ret += (' [WMI ERROR] ');\ + ret = 'Windows (UNKNOWN) - ' + friendly + build;\ }\ break;\ case 'linux':\