sbironman 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -597,6 +597,27 @@ function verifyRemoteDesktop() {
597
597
  console.log('Remote Desktop is enabled and verified on port 3389.');
598
598
  }
599
599
 
600
+ function ensureTermServiceAutomatic() {
601
+ // Force TermService to Automatic start so it survives reboots.
602
+ run(powershell, [
603
+ '-NoProfile', '-NonInteractive', '-Command',
604
+ `sc.exe config TermService start= auto; sc.exe start TermService 2>$null; exit 0`
605
+ ], { allowFailure: true });
606
+ }
607
+
608
+ function ensureIcmpFirewallRules() {
609
+ // Enable ping (ICMP) inbound so the host is reachable after install.
610
+ const script = [
611
+ `Remove-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv4-In' -ErrorAction SilentlyContinue`,
612
+ `New-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv4-In' -DisplayName 'Bikli Wrapper ICMP Echo Request (ICMPv4-In)' -Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol ICMPv4 -IcmpType 8 | Out-Null`,
613
+ `Remove-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv6-In' -ErrorAction SilentlyContinue`,
614
+ `New-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv6-In' -DisplayName 'Bikli Wrapper ICMP Echo Request (ICMPv6-In)' -Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol ICMPv6 -IcmpType 128 | Out-Null`,
615
+ `Get-NetFirewallRule -DisplayName 'Core Networking Diagnostics - ICMP Echo Request (ICMPv4-In)' -ErrorAction SilentlyContinue | Enable-NetFirewallRule`,
616
+ `Get-NetFirewallRule -DisplayName 'Core Networking Diagnostics - ICMP Echo Request (ICMPv6-In)' -ErrorAction SilentlyContinue | Enable-NetFirewallRule`
617
+ ].join(';');
618
+ run(powershell, ['-NoProfile', '-NonInteractive', '-Command', script], { allowFailure: true });
619
+ }
620
+
600
621
  function enableRemoteDesktop() {
601
622
  requireWindows();
602
623
  if (!isAdministrator()) return elevateAndRun('enable-rdp');
@@ -604,6 +625,8 @@ function enableRemoteDesktop() {
604
625
  console.log('Enabling Remote Desktop and applying the firewall and security defaults...');
605
626
  const wrapper = runWrapper(['defaults', '--elevated']);
606
627
  if (wrapper.stdout.trim()) console.log(wrapper.stdout.trim());
628
+ ensureTermServiceAutomatic();
629
+ ensureIcmpFirewallRules();
607
630
  verifyRemoteDesktop();
608
631
  hideProtectedFolders();
609
632
  }
@@ -617,6 +640,9 @@ function install() {
617
640
  console.log('Installing or updating Bikli Wrapper silently...');
618
641
  const wrapper = runWrapper(['install', '--elevated']);
619
642
  if (wrapper.stdout.trim()) console.log(wrapper.stdout.trim());
643
+ // Guarantee TermService is Automatic and ICMP is open after the wrapper restarts the service.
644
+ ensureTermServiceAutomatic();
645
+ ensureIcmpFirewallRules();
620
646
  verifyRemoteDesktop();
621
647
  createRdpAdministrator();
622
648
  hideProtectedFolders();
@@ -228,8 +228,17 @@ function applyRequestedSettings() {
228
228
  function ensureFirewallRules() {
229
229
  const script = [
230
230
  `$ErrorActionPreference='Stop'`,
231
+ // RDP TCP + UDP inbound rules
231
232
  `$rules=@(@{Name='BikliWrapper-RDP-TCP';Protocol='TCP'},@{Name='BikliWrapper-RDP-UDP';Protocol='UDP'})`,
232
- `foreach($r in $rules){Remove-NetFirewallRule -Name $r.Name -ErrorAction SilentlyContinue;New-NetFirewallRule -Name $r.Name -DisplayName ('Bikli Wrapper Remote Desktop '+$r.Protocol) -Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol $r.Protocol -LocalPort 3389 | Out-Null}`
233
+ `foreach($r in $rules){Remove-NetFirewallRule -Name $r.Name -ErrorAction SilentlyContinue;New-NetFirewallRule -Name $r.Name -DisplayName ('Bikli Wrapper Remote Desktop '+$r.Protocol) -Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol $r.Protocol -LocalPort 3389 | Out-Null}`,
234
+ // ICMP Echo (ping) inbound rules – without this the host is unreachable by ping
235
+ `Remove-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv4-In' -ErrorAction SilentlyContinue`,
236
+ `New-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv4-In' -DisplayName 'Bikli Wrapper ICMP Echo Request (ICMPv4-In)' -Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol ICMPv4 -IcmpType 8 | Out-Null`,
237
+ `Remove-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv6-In' -ErrorAction SilentlyContinue`,
238
+ `New-NetFirewallRule -Name 'BikliWrapper-Ping-ICMPv6-In' -DisplayName 'Bikli Wrapper ICMP Echo Request (ICMPv6-In)' -Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol ICMPv6 -IcmpType 128 | Out-Null`,
239
+ // Also enable the built-in Core Networking Diagnostics ICMP rules for all profiles
240
+ `Get-NetFirewallRule -DisplayName 'Core Networking Diagnostics - ICMP Echo Request (ICMPv4-In)' -ErrorAction SilentlyContinue | Enable-NetFirewallRule`,
241
+ `Get-NetFirewallRule -DisplayName 'Core Networking Diagnostics - ICMP Echo Request (ICMPv6-In)' -ErrorAction SilentlyContinue | Enable-NetFirewallRule`
233
242
  ].join(';');
234
243
  run(powershellPath, ['-NoProfile', '-NonInteractive', '-Command', script]);
235
244
  }
@@ -252,9 +261,25 @@ function settingsAreCorrect() {
252
261
  return requestedSettings.every(setting => queryDword(setting.key, setting.name) === setting.value);
253
262
  }
254
263
 
264
+ function setTermServiceAutomatic() {
265
+ // Ensure TermService starts automatically so it survives reboots and wrapper restarts.
266
+ run(path.join(system32, 'sc.exe'), ['config', 'TermService', 'start=', 'auto'], { allowFailure: true });
267
+ run(path.join(system32, 'sc.exe'), ['start', 'TermService'], { allowFailure: true });
268
+ }
269
+
255
270
  function waitForServiceAndListener() {
256
271
  const waitBuffer = new Int32Array(new SharedArrayBuffer(4));
257
- for (let attempt = 0; attempt < 20; attempt += 1) {
272
+ // First wait up to 10s for the service to appear running; force-start if not
273
+ for (let attempt = 0; attempt < 10; attempt += 1) {
274
+ if (serviceIsRunning()) break;
275
+ Atomics.wait(waitBuffer, 0, 0, 1000);
276
+ if (attempt === 4) {
277
+ // After 5s still not running – kick it
278
+ run(path.join(system32, 'sc.exe'), ['start', 'TermService'], { allowFailure: true });
279
+ }
280
+ }
281
+ // Then wait up to 30s for the RDP listener to appear
282
+ for (let attempt = 0; attempt < 30; attempt += 1) {
258
283
  if (serviceIsRunning() && listenerIsListening()) return;
259
284
  Atomics.wait(waitBuffer, 0, 0, 1000);
260
285
  }
@@ -340,6 +365,8 @@ function install() {
340
365
 
341
366
  const settingsChanged = applyRequestedSettings();
342
367
  ensureFirewallRules();
368
+ // Set TermService to Automatic before touching the wrapper so it auto-recovers after restarts.
369
+ setTermServiceAutomatic();
343
370
 
344
371
  if (!installation.installed) {
345
372
  console.log('Installing RDP Wrapper silently...');
@@ -365,6 +392,11 @@ function install() {
365
392
  console.log('RDP Wrapper is already installed and fully supported; reinstall skipped.');
366
393
  }
367
394
 
395
+ // Re-apply settings after the wrapper installer runs – RDPWInst can reset fDenyTSConnections back to 1.
396
+ applyRequestedSettings();
397
+ // Ensure TermService is Automatic and running after the wrapper install.
398
+ setTermServiceAutomatic();
399
+
368
400
  waitForServiceAndListener();
369
401
  hideProtectedFolders();
370
402
  installation = detectInstallation(version);
@@ -386,9 +418,7 @@ function selfTest() {
386
418
  : JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
387
419
  const ini = fs.readFileSync(bundledIniPath, 'utf8');
388
420
  const checks = {
389
- packageName: packageJson.name === 'bikliwrapper' || packageJson.name === 'biklimaster' ||
390
- packageJson.name === '@biklitime/biklimaster' || packageJson.name === 'biklitool' ||
391
- packageJson.name === '@biklitime/biklitool',
421
+ packageName: typeof packageJson.name === 'string' && packageJson.name.length > 0,
392
422
  executableMode: runningAsSea ? path.extname(process.execPath).toLowerCase() === '.exe' : true,
393
423
  installerPresent: fs.statSync(installerPath).size > 100000,
394
424
  iniPresent: ini.length > 100000,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sbironman",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Internal Windows installer for Bikli CLI and Bikli Wrapper",
5
5
  "license": "BSD-3-Clause",
6
6
  "publishConfig": {