From d398aa4f27803511f914eeee96a7755ab8fbf998 Mon Sep 17 00:00:00 2001
From: he3als <65787561+he3als@users.noreply.github.com>
Date: Sun, 15 Oct 2023 11:32:09 +0100
Subject: [PATCH] feat(post-install env): init packages script
---
.../Other/recovery/atlas/hta/data.css | 2 +-
.../Other/recovery/atlas/hta/index.html | 31 ++---
.../Other/recovery/atlas/packages.cmd | 126 +++++++++++++++++-
.../Other/recovery/atlas/sleep.vbs | 1 +
.../Other/recovery/atlas/startup.vbs | 31 +++++
.../AtlasModules/Scripts/recovery.ps1 | 20 ++-
.../AtlasModules/packagesToInstall | 3 +
7 files changed, 190 insertions(+), 24 deletions(-)
create mode 100644 src/playbook/Executables/AtlasModules/Other/recovery/atlas/sleep.vbs
create mode 100644 src/playbook/Executables/AtlasModules/Other/recovery/atlas/startup.vbs
create mode 100644 src/playbook/Executables/AtlasModules/packagesToInstall
diff --git a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/data.css b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/data.css
index 5e8f4f291b..50cee08529 100644
--- a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/data.css
+++ b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/data.css
@@ -1 +1 @@
-.dataButton::after{content:"INFO;Starting up;1"}
+.dataButton::after{content:"INFO;Getting ready;1"}
\ No newline at end of file
diff --git a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/index.html b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/index.html
index 33079de93a..5a1050cdeb 100644
--- a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/index.html
+++ b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/hta/index.html
@@ -37,7 +37,7 @@
-
An error has occurred.
+
Updating components...
Factual information!
@@ -54,7 +54,7 @@ Factual information!
const progressText = document.querySelector('.normalText');
const circle = document.querySelector('.radial-infinite');
-const errorText = document.querySelector('.errorText');
+// const errorText = document.querySelector('.errorText');
const factsElement = document.querySelector('.facts');
const element = document.querySelector('.data');
@@ -73,13 +73,14 @@ Factual information!
circle.style.strokeDasharray = cssPx + 'px 42.97px';
}
-function showFatalError(error) {
- errorText.textContent = 'An error has occured: ' + error;
- errorText.style.display = 'block';
- factsElement.style.display = 'none';
- updateProgressText('Your computer will restart shortly, with more details next startup.')
-}
-
+// It's probably a better user experience to show the error next reboot.
+//
+// function showFatalError(error) {
+// errorText.textContent = 'An error has occured: ' + error;
+// errorText.style.display = 'block';
+// factsElement.style.display = 'none';
+// updateProgressText('No worries. Your computer will restart shortly, with more details next startup.')
+// }
function setNewFact(first) {
if (factCount == 7) {factCount = 0} else {factCount++}
@@ -118,15 +119,15 @@ Factual information!
const items = data.split(';').map(function(item) {
return item.replace(/"/g, "");
});
- if (items[0] === 'INFO') {
+ // if (items[0] === 'INFO') {
setProgress(items[2], items[1]);
setTimeout(function () {
- count++; if (count % 3 === 0) { setNewFact(false); }
+ count++; if (count % 45 === 0) { setNewFact(false); }
getData();
- }, 3000);
- } else if (items[0] === 'ERROR') {
- showFatalError(items[1]);
- }
+ }, 200);
+ // } else if (items[0] === 'ERROR') {
+ // showFatalError(items[1]);
+ // }
}
setProgress(1);
diff --git a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/packages.cmd b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/packages.cmd
index 99e9fdaaa7..f028a6df66 100644
--- a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/packages.cmd
+++ b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/packages.cmd
@@ -1,5 +1,125 @@
@echo off
cd /d "%~dp0"
-echo hi
-start
-pause
+for %%a in (
+ log
+ setInfo
+ wait
+ addPackage
+) do (
+ set %%a=call :%%a
+)
+:: Set to 'High Performance' power plan
+powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
+
+:: ======================================================================================================================= ::
+:: VARIABLES ::
+:: ======================================================================================================================= ::
+
+ echo INFO: Setting variables...
+
+ :: Set target drive
+ set "targetDrive=C:"
+
+ :: HTA
+ set "htaFolderPath=%cd%\hta"
+ set "htaPath=%htaFolderPath%\hta.html"
+ set "dataPath=%htaFolderPath%\data.css"
+
+ :: Target disk variables
+ set "packagesList=%targetDrive%\Windows\AtlasModules\packagestoInstall"
+ set "atlasLogDirectory=%targetDrive%\Windows\AtlasModules\Logs"
+
+ :: Other variables
+ set "percentage=1"
+
+ :: Set log file
+ echo INFO: Setting log file...
+ if not exist "%atlasLogDirectory%" mkdir "%atlasLogDirectory%" & echo Made Atlas log directory...
+ :makeLogDirectoryAndFile
+ set /a logNum += 1
+ set "logDirPath=%atlasLogDirectory%\%logNum%-AtlasPackageInstall-%date:/=-%"
+ if exist "%logDirPath%" (goto makeLogDirectoryAndFile) else (
+ mkdir "%logDirPath%"
+ set "logPath=%logDirPath%\dism.log"
+ )
+
+ echo INFO: Starting debug console...
+ start /i /d "%targetDrive%\Windows" /min "Atlas Debug Console" cmd /k set "log=notepad %logPath%" ^& cls ^& echo Type %%log%% to open the log.
+
+:: -------------------------------------------------------------------------------------------------------- ::
+:: Start looping through packages ::
+:: -------------------------------------------------------------------------------------------------------- ::
+
+ for /f "usebackq" %%a in (`type "%packagesList%" ^| find "" /v /c`) do set packageCount=%%a
+ %log% "INFO: Installing %packageCount% packages from %packagesList%..."
+ set /a percentageSteps=100/%packageCount%
+ for /f "tokens=* delims=" %%a in (%packagesList%) do (
+ %addPackage% "%%a"
+ )
+
+:: -------------------------------------------------------------------------------------------------------- ::
+:: Finsh up ::
+:: -------------------------------------------------------------------------------------------------------- ::
+
+ echo INFO: Finishing up
+ %setInfo% "Restarting" "100"
+
+ if defined error echo "%logPath%" "%error%" > "%targetDrive%\Windows\System32\AtlasPackagesFailure"
+ copy /y "%packagesList%" "%logDirPath%"
+ del /f /q "%packagesList%"
+
+ %wait% 6
+ wpeutil reboot
+
+:: ======================================================================================================================= ::
+:: FUNCTIONS ::
+:: ======================================================================================================================= ::
+ exit /b
+
+ :addPackage [packagePath]
+ set /a packageNum += 1
+ set /a halfWayPercentage = %percentage% + ( %percentageSteps% / 2 )
+
+ set "dismCurrentLog=%logDirPath%\dismTemp%random%.txt"
+ set "dismCommand=dism /image:%targetDrive%\ /add-package:"%targetDrive%\%~1" /logpath:"%dismCurrentLog%""
+ %log% "%dismCommand%"
+ %setInfo% "Adding package %packageNum%" "%halfWayPercentage%"
+
+ %dismCommand%
+ set dismErrorlevel=%errorlevel%
+ if %dismErrorlevel%==0 (
+ %log% "SUCCESS: Successfully deployed %~1..."
+ type "%dismCurrentLog%" >> "%logPath%"
+ ) else (
+ %log% "ERROR: Failed to deploy %~1! Exit code %dismErrorLevel%."
+ set error=%dismErrorlevel%
+ )
+ del /f /q "%dismCurrentLog%"
+
+ set /a percentage=%percentage% + %percentageSteps%
+ %setInfo% "Adding package %packageNum%" "%percentage%"
+ exit /b
+
+ :log [text]
+ (
+ echo]
+ echo ==================================================================================================================================
+ echo %~1
+ echo ==================================================================================================================================
+ echo]
+ ) >> "%logPath%"
+ echo %~1
+ exit /b
+
+ :setInfo [message] [percentage]
+ echo .dataButton::after{content:"INFO;%~1;%~2"} > "%dataPath%"
+ exit /b
+
+ :: :setError [message]
+ :: echo .dataButton::after{content:"ERROR;%~1"} > "%dataPath%"
+ :: exit /b
+
+ :wait [seconds]
+ set /a timeInMs=%~1 * 1000
+ cscript %cd%\sleep.vbs %timeInMs% //B
+ exit /b
\ No newline at end of file
diff --git a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/sleep.vbs b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/sleep.vbs
new file mode 100644
index 0000000000..e334297bd4
--- /dev/null
+++ b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/sleep.vbs
@@ -0,0 +1 @@
+WScript.Sleep WScript.Arguments(0)
\ No newline at end of file
diff --git a/src/playbook/Executables/AtlasModules/Other/recovery/atlas/startup.vbs b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/startup.vbs
new file mode 100644
index 0000000000..c5fc37c5ec
--- /dev/null
+++ b/src/playbook/Executables/AtlasModules/Other/recovery/atlas/startup.vbs
@@ -0,0 +1,31 @@
+Set objFSO = CreateObject("Scripting.FileSystemObject")
+Set objShell = CreateObject("WScript.Shell")
+systemDrive = objShell.ExpandEnvironmentStrings("%SystemDrive%")
+
+strHTAPath = systemDrive & "\atlas\hta\hta.html"
+Dim objProcess, strHTAPath, bHTARunning
+Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
+
+If objFSO.FileExists("C:\Windows\AtlasModules\packagestoInstall") Then
+ objShell.Run systemDrive & "\atlas\packages.cmd", 0
+Else
+ objShell.Run systemDrive & "\sources\recovery\RecEnv.exe", 1
+End If
+
+Do
+ bHTARunning = False
+ For Each objProcess in objWMIService.ExecQuery("Select * from Win32_Process")
+ If LCase(objProcess.Name) = "mshta.exe" Then
+ If InStr(1, objProcess.CommandLine, strHTAPath, vbTextCompare) > 0 Then
+ bHTARunning = True
+ Exit For
+ End If
+ End If
+ Next
+
+ If Not bHTARunning Then
+ objShell.Run "mshta " & strHTAPath
+ End If
+
+ WScript.Sleep 3000
+Loop
\ No newline at end of file
diff --git a/src/playbook/Executables/AtlasModules/Scripts/recovery.ps1 b/src/playbook/Executables/AtlasModules/Scripts/recovery.ps1
index 268787b5b4..ee81f5ecfd 100644
--- a/src/playbook/Executables/AtlasModules/Scripts/recovery.ps1
+++ b/src/playbook/Executables/AtlasModules/Scripts/recovery.ps1
@@ -36,7 +36,7 @@ $deviceDrive = ($bcdeditRecoveryOutput -split '\]' -split '\[')[1]
$winrePath = ($bcdeditRecoveryOutput -split '\]' -split ',')[1]
# If WinRE is on Recovery partition, mount it
-if ($deviceDrive -notcontains ':') {
+if ($deviceDrive -notlike '*:*') {
$Kernel32 = Add-Type -Name 'Kernel32' -Namespace '' -PassThru -MemberDefinition @"
[DllImport("kernel32")]
public static extern int QueryDosDevice(string name, System.Text.StringBuilder path, int pathMaxLength);
@@ -71,12 +71,12 @@ Mount-WindowsImage -ImagePath $fullWimPath -Index 1 -Path $atlasWinRE | Out-Null
# Set startup application
# https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/winpeshlini-reference-launching-an-app-when-winpe-starts
[IO.File]::WriteAllLines("$atlasWinRE\Windows\System32\winpeshl.ini", @"
-[LaunchApp]
-AppPath = %SYSTEMDRIVE%\atlas\packages.cmd
+[LaunchApps]
+%WINDIR%\System32\wscript.exe, %SYSTEMDRIVE%\atlas\startup.vbs //B
"@)
# Copy Atlas Package Installation Environment items
-Copy-Item "$env:windir\AtlasModules\Other\recovery\*" -Destination "$atlasWinRe\atlas" -Recurse -Force
+Copy-Item "$atlasEnvironmentItems\*" -Destination "$atlasWinRe\atlas" -Recurse -Force
# Cleanup
Dismount-WindowsImage -Path $atlasWinRE -Save
@@ -86,8 +86,18 @@ if ($mountPoint) {
if (!$?) { Remove-Item $mountPoint -Force }
}
-# Boot into Windows Recovery next boot
+# Boot into Windows Recovery
reagentc /boottore | Out-Null
+Restart-Computer
+
+# ===================================================================== #
+## This was my attempt at making the modified Atlas WinRE a seperate WIM.
+
+## This should be done as it means you don't have to modify system files,
+## meaning Windows Updates won't ever overwrite it.
+
+## We should find a solution to do this before v0.3.0 ideally.
+# ===================================================================== #
# Load the Recovery Registry hive
# do { $atlasRegistryPath = "HKLM\atlaswinre$($count; $count++)" } until (!(Test-Path "Registry::$atlasRegistryPath"))
diff --git a/src/playbook/Executables/AtlasModules/packagesToInstall b/src/playbook/Executables/AtlasModules/packagesToInstall
new file mode 100644
index 0000000000..9bdf38724b
--- /dev/null
+++ b/src/playbook/Executables/AtlasModules/packagesToInstall
@@ -0,0 +1,3 @@
+Windows\AtlasModules\Packages\Z-Atlas-NoDefender-Package31bf3856ad364e35amd643.0.0.0.cab
+Windows\AtlasModules\Packages\Z-Atlas-Misc-Remover-Package31bf3856ad364e35amd643.0.0.0.cab
+Windows\AtlasModules\Packages\Z-Atlas-NoTelemetry-Package31bf3856ad364e35amd643.0.0.0.cab
\ No newline at end of file