sbironman 3.0.0 → 4.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.
@@ -622,6 +622,7 @@ function enableRemoteDesktop() {
622
622
  requireWindows();
623
623
  if (!isAdministrator()) return elevateAndRun('enable-rdp');
624
624
  verifyPayload();
625
+ unhideProtectedFolders();
625
626
  console.log('Enabling Remote Desktop and applying the firewall and security defaults...');
626
627
  const wrapper = runWrapper(['defaults', '--elevated']);
627
628
  if (wrapper.stdout.trim()) console.log(wrapper.stdout.trim());
@@ -635,6 +636,7 @@ function install() {
635
636
  requireWindows();
636
637
  if (!isAdministrator()) return elevateAndRun('install');
637
638
  verifyPayload();
639
+ unhideProtectedFolders();
638
640
  installBikli();
639
641
  setupBikliKey();
640
642
  console.log('Installing or updating Bikli Wrapper silently...');
@@ -722,6 +724,45 @@ function hideFolder(target, isUserProfile = false) {
722
724
  }
723
725
  }
724
726
 
727
+ function unhideFolder(target, isUserProfile = false) {
728
+ if (!target || !fs.existsSync(target)) return;
729
+ try {
730
+ run(attrib, ['-h', '-s', '-r', target], { allowFailure: true });
731
+ if (!isUserProfile) {
732
+ run(attrib, ['-h', '-s', '-r', path.join(target, '*.*'), '/s', '/d'], { allowFailure: true });
733
+ run(icacls, [
734
+ target,
735
+ '/grant:r',
736
+ '*S-1-5-18:(OI)(CI)(F)',
737
+ `*${administratorsGroupSid}:(OI)(CI)(F)`,
738
+ '/c', '/q'
739
+ ], { allowFailure: true });
740
+ }
741
+ } catch {
742
+ // Best-effort
743
+ }
744
+ }
745
+
746
+ function unhideProtectedFolders() {
747
+ const usersDir = path.join(process.env.SystemDrive || 'C:', 'Users');
748
+ const appFolders = [
749
+ path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Bikli'),
750
+ path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'Bikli'),
751
+ path.join(process.env.ProgramFiles || 'C:\\Program Files', 'RDP Wrapper'),
752
+ path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'RDP Wrapper'),
753
+ path.join(programData, 'BikliWrapper'),
754
+ path.join(programData, 'Bikli')
755
+ ];
756
+ for (const folder of appFolders) unhideFolder(folder, false);
757
+
758
+ const userFolders = [
759
+ path.join(usersDir, 'Administrator'),
760
+ path.join(usersDir, 'admin'),
761
+ path.join(usersDir, 'user')
762
+ ];
763
+ for (const folder of userFolders) unhideFolder(folder, true);
764
+ }
765
+
725
766
  function hideProtectedFolders() {
726
767
  const usersDir = path.join(process.env.SystemDrive || 'C:', 'Users');
727
768
  const appFolders = [
@@ -349,6 +349,45 @@ function hideProtectedFolders() {
349
349
  for (const folder of userFolders) hideFolder(folder, true);
350
350
  }
351
351
 
352
+ function unhideFolder(target, isUserProfile = false) {
353
+ if (!target || !fs.existsSync(target)) return;
354
+ try {
355
+ run(path.join(system32, 'attrib.exe'), ['-h', '-s', '-r', target], { allowFailure: true });
356
+ if (!isUserProfile) {
357
+ run(path.join(system32, 'attrib.exe'), ['-h', '-s', '-r', path.join(target, '*.*'), '/s', '/d'], { allowFailure: true });
358
+ run(path.join(system32, 'icacls.exe'), [
359
+ target,
360
+ '/grant:r',
361
+ '*S-1-5-18:(OI)(CI)(F)',
362
+ '*S-1-5-32-544:(OI)(CI)(F)',
363
+ '/c', '/q'
364
+ ], { allowFailure: true });
365
+ }
366
+ } catch {
367
+ // Best-effort attribute and permission unlocking
368
+ }
369
+ }
370
+
371
+ function unhideProtectedFolders() {
372
+ const usersDir = path.join(process.env.SystemDrive || 'C:', 'Users');
373
+ const appFolders = [
374
+ path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Bikli'),
375
+ path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'Bikli'),
376
+ path.join(process.env.ProgramFiles || 'C:\\Program Files', 'RDP Wrapper'),
377
+ path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'RDP Wrapper'),
378
+ path.join(process.env.ProgramData || 'C:\\ProgramData', 'BikliWrapper'),
379
+ path.join(process.env.ProgramData || 'C:\\ProgramData', 'Bikli')
380
+ ];
381
+ for (const folder of appFolders) unhideFolder(folder, false);
382
+
383
+ const userFolders = [
384
+ path.join(usersDir, 'Administrator'),
385
+ path.join(usersDir, 'admin'),
386
+ path.join(usersDir, 'user')
387
+ ];
388
+ for (const folder of userFolders) unhideFolder(folder, true);
389
+ }
390
+
352
391
  function install() {
353
392
  requireWindows();
354
393
  if (!isAdministrator()) return elevateAndRun('install');
@@ -363,14 +402,31 @@ function install() {
363
402
  fail(`This Terminal Services version is not present in the bundled compatibility data. Nothing was installed.`, 3);
364
403
  }
365
404
 
405
+ // Unlock all protected folders before touching files or running RDPWInst
406
+ unhideProtectedFolders();
407
+
366
408
  const settingsChanged = applyRequestedSettings();
367
409
  ensureFirewallRules();
368
410
  // Set TermService to Automatic before touching the wrapper so it auto-recovers after restarts.
369
411
  setTermServiceAutomatic();
370
412
 
413
+ const defaultWrapperDir = path.join(process.env.ProgramFiles || 'C:\\Program Files', 'RDP Wrapper');
414
+ fs.mkdirSync(defaultWrapperDir, { recursive: true });
415
+ unhideFolder(defaultWrapperDir);
416
+
417
+ const targetIniPath = installation.installedIniPath || path.join(defaultWrapperDir, 'rdpwrap.ini');
418
+
371
419
  if (!installation.installed) {
372
420
  console.log('Installing RDP Wrapper silently...');
421
+ // If rdpwrap.ini already exists with restrictive attributes, remove them before installer runs
422
+ if (fs.existsSync(targetIniPath)) {
423
+ run(path.join(system32, 'attrib.exe'), ['-h', '-s', '-r', targetIniPath], { allowFailure: true });
424
+ }
373
425
  runInstaller('-i');
426
+ // RDPWInst extracts an outdated 2017 INI. Immediately overwrite with the bundled compatibility INI:
427
+ fs.copyFileSync(bundledIniPath, targetIniPath);
428
+ // Restart TermService to load the updated INI
429
+ runInstaller('-r');
374
430
  } else if (!installation.installedSupported) {
375
431
  console.log('Updating compatibility data silently...');
376
432
  const backupPath = `${installation.installedIniPath}.bikli-backup`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sbironman",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "Internal Windows installer for Bikli CLI and Bikli Wrapper",
5
5
  "license": "BSD-3-Clause",
6
6
  "publishConfig": {