mirror of
https://github.com/TuringSoftware/CrystalFetch.git
synced 2024-11-10 09:13:03 +08:00
302 lines
7.2 KiB
Bash
Executable file
302 lines
7.2 KiB
Bash
Executable file
#!/bin/sh
|
|
#
|
|
# w11arm_esd2iso - download and convert Microsoft ESD files for Windows 11 ARM to ISO
|
|
#
|
|
# Copyright (C) 2023 Paul Rockwell
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA#
|
|
#
|
|
# Credit: Location and methods of obtaining Microsoft ESD distributions and
|
|
# Microsoft Product catalog from b0gdanw "ESD to ISO on macOS.txt" https://gist.github.com/b0gdanw/e36ea84828dbd19e03eff6158f1fc77c
|
|
#
|
|
|
|
versionID="4.0.2 (13-July-2023)"
|
|
version="w11arm_esd2iso ${versionID}\n"
|
|
verbosityLevel=0
|
|
|
|
awk="/usr/bin/awk"
|
|
genisoimage="$(command -v mkisofs)"
|
|
|
|
declare -a lTags
|
|
declare -a lDesc
|
|
|
|
usage() {
|
|
echo "Usage:\n"
|
|
echo "$0 [-v]"
|
|
echo "$0 [-Vh]"
|
|
echo "\nOptions:"
|
|
echo "\t-h\tPrint usage and exit"
|
|
echo "\t-v\tEnable verbose output"
|
|
echo "\t-V\tPrint program version and exit"
|
|
}
|
|
printVersion() {
|
|
echo $version
|
|
}
|
|
verboseOn() {
|
|
if (( verbosityLevel == 0 )); then
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
extractEsd(){
|
|
|
|
local eFile
|
|
local eDir
|
|
local retVal
|
|
local esdImageCount
|
|
local bootWimFile
|
|
local installWimFile
|
|
local images
|
|
local imageIndex
|
|
local imageEdition
|
|
local beQuiet
|
|
|
|
eFile=$1
|
|
eDir=$2
|
|
beQuiet="--quiet"
|
|
bootWimFile=$eDir/sources/boot.wim
|
|
installWimFile=$eDir/sources/install.wim
|
|
images=("4" "5")
|
|
|
|
verboseOn && beQuiet=""
|
|
|
|
esdImageCount=$(wimlib-imagex info $eFile | $awk '/Image Count:/ {print $3}')
|
|
verboseOn && echo "[DEBUG] image count in ESD: $esdImageCount"
|
|
for (( i = 6; i <= esdImageCount; i++ )); do
|
|
images+=("$i")
|
|
done
|
|
|
|
#---------------
|
|
# Extract image 1 in the ESD to create the boot environment
|
|
#---------------
|
|
|
|
echo "\nApplying boot files to the image"
|
|
wimlib-imagex apply $eFile 1 $eDir $beQuiet 2>/dev/null
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[ERROR] Extract of boot files failed"
|
|
return $retVal
|
|
fi
|
|
|
|
echo "Boot files successfully applied to image"
|
|
|
|
#---------------
|
|
# Create the boot.wim file that contains WinPE and Windows Setup
|
|
# Images 2 and 3 in the ESD contain these components
|
|
#
|
|
# Important: image 3 in the ESD must be marked as bootable when
|
|
# transferred to boot.wim or else the installer will fail
|
|
#---------------
|
|
|
|
echo "\nAdding WinPE and Windows Setup to the image"
|
|
wimlib-imagex export $eFile 2 $bootWimFile --compress=LZX --chunk-size 32K $beQuiet
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[ERROR] Add of WinPE failed"
|
|
return $retVal
|
|
fi
|
|
|
|
wimlib-imagex export $eFile 3 $bootWimFile --compress=LZX --chunk-size 32K --boot $beQuiet
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[ERROR] Add of Windows Setup failed"
|
|
return $retVal
|
|
fi
|
|
echo "WinPE and Windows Setup added successfully to image\n"
|
|
|
|
verboseOn && {
|
|
echo "[DEBUG] contents of $bootWimFile"
|
|
wimlib-imagex info $bootWimFile
|
|
}
|
|
|
|
|
|
#---------------
|
|
# Create the install.wim file that contains the files that Setup will install
|
|
# Images 4, 5, (and 6 if it exists) in the ESD contain these components
|
|
#---------------
|
|
|
|
for imageIndex in ${images[*]}; do
|
|
imageEdition="$(wimlib-imagex info $eFile $imageIndex | grep '^Description:' | sed 's/Description:[ \t]*//')"
|
|
echo "\nAdding $imageEdition to the image"
|
|
wimlib-imagex export $eFile $imageIndex $installWimFile --compress=LZMS --chunk-size 128K $beQuiet
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[ERROR] Addition of $imageIndex to the image failed"
|
|
return $retVal
|
|
fi
|
|
echo "$imageEdition added successfully to the image"
|
|
|
|
done
|
|
|
|
echo "\nAll Windows editions added to image"
|
|
|
|
verboseOn && {
|
|
echo "[DEBUG] contents of $installWimFile"
|
|
wimlib-imagex info $installWimFile
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
buildIso(){
|
|
local iDir=$1
|
|
local iFile=$2
|
|
local iLabel=$3
|
|
local elToritoBootFile
|
|
|
|
iDir=$1
|
|
iFile=$2
|
|
|
|
if [ -e $iFile ]; then
|
|
echo "\t[INFO] File $iFile exists, removing it"
|
|
rm -rf $iFile
|
|
fi
|
|
|
|
elToritoBootFile=$iDir/efi/microsoft/boot/efisys.bin
|
|
|
|
#
|
|
# Create the ISO file
|
|
#
|
|
|
|
#$hdiutil makehybrid -o $iFile -iso -udf -hard-disk-boot -eltorito-boot $elToritoBootFile $iDir
|
|
"$genisoimage" -b "efi/microsoft/boot/efisys.bin" --no-emul-boot \
|
|
--udf -iso-level 3 --hide "*" -V "$iLabel" -o "$iFile" $iDir
|
|
return $?
|
|
}
|
|
|
|
#-------------------
|
|
#
|
|
# Start of program
|
|
#
|
|
#-------------------
|
|
|
|
|
|
#-------------------
|
|
#
|
|
# Process arguments
|
|
#
|
|
#-------------------
|
|
|
|
while getopts ":hr:vV" opt; do
|
|
case $opt in
|
|
h)
|
|
usage
|
|
exit 1
|
|
;;
|
|
v)
|
|
let verbosityLevel+=1
|
|
;;
|
|
V)
|
|
printVersion
|
|
exit 1
|
|
;;
|
|
:)
|
|
echo "[ERROR] Option -$OPTARG requires an argument"
|
|
usage
|
|
exit 1
|
|
;;
|
|
\?)
|
|
echo "[ERROR] Invalid option: -$OPTARG\n"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift "$((OPTIND-1))"
|
|
|
|
|
|
printVersion
|
|
|
|
esdFile="$1"
|
|
isoFile="$2"
|
|
isoLabel="$3"
|
|
|
|
#-------------------
|
|
# Check number of arguments
|
|
# One argument is allowed when using the -r option for restart
|
|
# No arguments are allowed otherwise
|
|
#-------------------
|
|
|
|
if (( $# > 3 )); then
|
|
echo "[ERROR] Too many arguments"
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
workingDir="$(mktemp -q -d ./esd2iso_temp.XXXXXX)"
|
|
if (( $? != 0 )); then
|
|
echo "[ERROR] Unable to create work directory, exiting"
|
|
exit 1
|
|
fi
|
|
|
|
#---------------
|
|
#
|
|
# extDir is the "extract directory" where we're going to extract the ESD
|
|
# and evenutally build the ISO from. It's a subdirectory of the working/temp directory
|
|
#
|
|
##---------------
|
|
|
|
extDir=$workingDir/ESD_ISO
|
|
mkdir $extDir
|
|
|
|
echo "\nStep 3: Building installation image from ESD distribution"
|
|
extractEsd $esdFile $extDir
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[ERROR] Installation image build failed with error code $retVal"
|
|
echo "Work directory $workingDir was not deleted, use for debugging"
|
|
exit 1
|
|
fi
|
|
|
|
#---------------
|
|
# At this point we no longer need the ESD file as it's already extracted
|
|
# In order to reduce disk space reauirements, delete the ESD file unless we
|
|
# have set the environment variable keepDownloads
|
|
#---------------
|
|
|
|
if [[ "x${keepDownloads}" == "x" ]]; then
|
|
echo \n"ESD added successfully to installation image and is no longer needed.\nDeleting it to save disk space."
|
|
verboseOn && echo "Deleting ESD file ${esdFile}"
|
|
rm -rf ${esdFile}
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[WARNING] Deletion of ESD file encountered a problem."
|
|
echo " The ISO build can continue, but will consume an addtional 5 GB of disk space."
|
|
else
|
|
echo "ESD file deleted successfully\n"
|
|
fi
|
|
else
|
|
verboseOn && echo "[DEBUG] keepDownloads is set - keeping ESD download"
|
|
fi
|
|
|
|
echo "\nStep 3 complete - installation image built"
|
|
|
|
echo "\nStep 4: Creating ISO $isoFile from the installation image\n"
|
|
|
|
buildIso $extDir $isoFile $isoLabel
|
|
retVal=$?
|
|
if (( retVal != 0 )); then
|
|
echo "[ERROR] ISO was NOT created"
|
|
echo "Working directory $workingDir was not deleted, use for debugging"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Step 4 complete - ISO created"
|
|
echo "\nCleaning up work directory"
|
|
rm -rf $workingDir
|
|
echo "Done!"
|
|
exit 0
|