mirror of
https://github.com/dockur/windows.git
synced 2026-08-03 12:37:20 +01:00
feat: Refactor Windows answer file handling into separate script (#1923)
This commit is contained in:
-856
@@ -1298,864 +1298,8 @@ validVersion() {
|
||||
return 1
|
||||
}
|
||||
|
||||
validateResolution() {
|
||||
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
local minimum="$3"
|
||||
local number
|
||||
|
||||
if [[ ! "$value" =~ ^[0-9]+$ ]] || [ "${#value}" -gt 5 ]; then
|
||||
error "The $name variable must be between $minimum and 16384!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
number=$((10#$value))
|
||||
|
||||
if [ "$number" -lt "$minimum" ] || [ "$number" -gt 16384 ]; then
|
||||
error "The $name variable must be between $minimum and 16384!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validateProductKey() {
|
||||
|
||||
local value="$1"
|
||||
|
||||
[ -z "$value" ] && return 0
|
||||
|
||||
if [[ ! "$value" =~ ^[A-Za-z0-9]{5}(-[A-Za-z0-9]{5}){4}$ ]]; then
|
||||
error "The KEY variable must contain a valid 25-character product key!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validateComputerName() {
|
||||
|
||||
local value="$1"
|
||||
|
||||
[ -z "$value" ] && return 0
|
||||
|
||||
if [ "${#value}" -gt 15 ]; then
|
||||
error "The HOST variable cannot contain more than 15 characters!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! "$value" =~ ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$ ]]; then
|
||||
error "The HOST variable may only contain letters, digits, and hyphens, and cannot start or end with a hyphen!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$value" =~ ^[0-9]+$ ]]; then
|
||||
error "The HOST variable cannot contain only digits!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validateWorkgroup() {
|
||||
|
||||
local value="$1"
|
||||
local safe=""
|
||||
|
||||
[ -z "$value" ] && return 0
|
||||
|
||||
if [ "${#value}" -gt 15 ]; then
|
||||
error "The WORKGROUP variable cannot contain more than 15 characters!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
safe=$(printf '%s' "$value" | tr -d '"/\\[]:;|=,+*?<>') || return 1
|
||||
|
||||
if [[ "$safe" != "$value" ]]; then
|
||||
error "The WORKGROUP variable contains characters that are not valid in a NetBIOS name!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$value" =~ ^[.[:space:]]+$ ]]; then
|
||||
error "The WORKGROUP variable cannot consist only of spaces or periods!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validateMembership() {
|
||||
|
||||
if [ -n "$DOMAIN" ] && [ -n "$WORKGROUP" ]; then
|
||||
error "The DOMAIN and WORKGROUP variables cannot be used together!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$DOMAIN_OU" ] && [ -z "$DOMAIN" ]; then
|
||||
error "The DOMAIN_OU variable requires DOMAIN to be specified!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
validateWorkgroup "$WORKGROUP" || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
validateLegacyText() {
|
||||
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
local desc="${3:-}"
|
||||
local suffix=""
|
||||
|
||||
[ -n "$desc" ] && suffix=" for $desc"
|
||||
|
||||
if [[ "$value" =~ [[:cntrl:]] ]]; then
|
||||
error "The $name variable cannot contain control characters$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$value" == *'"'* ]]; then
|
||||
error "The $name variable cannot contain double quotes$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validateLegacyUsername() {
|
||||
|
||||
local value="$1"
|
||||
local desc="${2:-}"
|
||||
local suffix=""
|
||||
|
||||
[ -n "$desc" ] && suffix=" for $desc"
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
error "The USERNAME variable cannot be empty$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "${#value}" -gt 20 ]; then
|
||||
error "The USERNAME variable cannot contain more than 20 characters$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$value" =~ [[:cntrl:]] ]]; then
|
||||
error "The USERNAME variable cannot contain control characters$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
case "$value" in
|
||||
*'"'* | *'/'* | *\\* | *'['* | *']'* | *':'* | *';'* | *'|'* | *'='* | *','* | *'+'* | *'*'* | *'?'* | *'<'* | *'>'* )
|
||||
error "The USERNAME variable contains unsupported characters$suffix!"
|
||||
return 1 ;;
|
||||
esac
|
||||
|
||||
if [[ "$value" == *"." ]]; then
|
||||
error "The USERNAME variable cannot end with a period$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$value" =~ ^[.[:space:]]+$ ]]; then
|
||||
error "The USERNAME variable cannot consist only of spaces or periods$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "${value^^}" == "GUEST" ]]; then
|
||||
error "The USERNAME value \"$value\" is reserved for a built-in Windows account$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
validatePassword() {
|
||||
|
||||
local value="$1"
|
||||
local desc="${2:-}"
|
||||
local suffix=""
|
||||
|
||||
[ -n "$desc" ] && suffix=" for $desc"
|
||||
|
||||
if [ "${#value}" -gt 127 ]; then
|
||||
error "The PASSWORD variable cannot contain more than 127 characters$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$value" =~ [[:cntrl:]] ]]; then
|
||||
error "The PASSWORD variable cannot contain control characters$suffix!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
escapeSIFValue() {
|
||||
|
||||
local s="$1"
|
||||
|
||||
s=${s//%/%%}
|
||||
s=${s//\"/\"\"}
|
||||
|
||||
printf '%s' "$s"
|
||||
return 0
|
||||
}
|
||||
|
||||
escapeRegistryValue() {
|
||||
|
||||
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'
|
||||
}
|
||||
|
||||
addFolder() {
|
||||
|
||||
local src="$1"
|
||||
local folder="/oem" file=""
|
||||
local dest="$src/\$OEM\$/\$1/OEM"
|
||||
|
||||
[ ! -d "$folder" ] && folder="/OEM"
|
||||
[ ! -d "$folder" ] && folder="$STORAGE/oem"
|
||||
[ ! -d "$folder" ] && folder="$STORAGE/OEM"
|
||||
[ ! -d "$folder" ] && folder=""
|
||||
|
||||
[ -z "$folder" ] && [ -z "$COMMAND" ] && return 0
|
||||
|
||||
local msg="Adding OEM files to image..."
|
||||
info "$msg" && html "$msg"
|
||||
|
||||
mkdir -p "$dest" || return 1
|
||||
|
||||
if [ -n "$folder" ]; then
|
||||
cp -Lr "$folder/." "$dest" || return 1
|
||||
fi
|
||||
|
||||
file=$(find "$dest" -maxdepth 1 -type f -iname install.bat -print -quit) || return 1
|
||||
|
||||
if [ -n "$COMMAND" ]; then
|
||||
|
||||
[ -z "$file" ] && file="$dest/install.bat"
|
||||
|
||||
if [ -s "$file" ]; then
|
||||
printf '\n' >> "$file" || return 1
|
||||
fi
|
||||
|
||||
printf '%s\n' "$COMMAND" >> "$file" || return 1
|
||||
|
||||
fi
|
||||
|
||||
if [ -f "$file" ]; then
|
||||
if ! unix2dos -q "$file"; then
|
||||
error "Failed to convert $file to DOS format!"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
prepareInstall() {
|
||||
|
||||
local pid=""
|
||||
local file=""
|
||||
local dir="$2"
|
||||
local desc="$3"
|
||||
local driver="$4"
|
||||
local drivers="/tmp/drivers"
|
||||
|
||||
if [ -n "$DOMAIN" ]; then
|
||||
error "The DOMAIN variable is not supported for $desc!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ETFS="[BOOT]/Boot-NoEmul.img"
|
||||
|
||||
if [ ! -f "$dir/$ETFS" ] || [ ! -s "$dir/$ETFS" ]; then
|
||||
error "Failed to locate file \"$ETFS\" in $desc ISO image!" && return 1
|
||||
fi
|
||||
|
||||
local arch target
|
||||
[ -d "$dir/AMD64" ] && arch="amd64" || arch="x86"
|
||||
[[ "${arch,,}" == "x86" ]] && target="$dir/I386" || target="$dir/AMD64"
|
||||
|
||||
if [ ! -d "$target" ]; then
|
||||
error "Failed to locate directory \"$target\" in $desc ISO image!" && return 1
|
||||
fi
|
||||
|
||||
if [[ "${driver,,}" == "xp" || "${driver,,}" == "2k3" ]]; then
|
||||
|
||||
local msg="Adding drivers to image..."
|
||||
info "$msg" && html "$msg"
|
||||
|
||||
rm -rf "$drivers" || return 1
|
||||
mkdir -p "$drivers" || return 1
|
||||
|
||||
if ! bsdtar -xf /var/drivers.txz -C "$drivers"; then
|
||||
error "Failed to extract drivers!" && return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$drivers/viostor/$driver/$arch/viostor.sys" ]; then
|
||||
error "Failed to locate required storage drivers!" && return 1
|
||||
fi
|
||||
|
||||
cp -L "$drivers/viostor/$driver/$arch/viostor.sys" "$target" || return 1
|
||||
|
||||
mkdir -p "$dir/\$OEM\$/\$1/Drivers/viostor" || return 1
|
||||
cp -L "$drivers/viostor/$driver/$arch/viostor.cat" "$dir/\$OEM\$/\$1/Drivers/viostor" || return 1
|
||||
cp -L "$drivers/viostor/$driver/$arch/viostor.inf" "$dir/\$OEM\$/\$1/Drivers/viostor" || return 1
|
||||
cp -L "$drivers/viostor/$driver/$arch/viostor.sys" "$dir/\$OEM\$/\$1/Drivers/viostor" || return 1
|
||||
|
||||
if [ ! -f "$drivers/NetKVM/$driver/$arch/netkvm.sys" ]; then
|
||||
error "Failed to locate required network drivers!" && return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$dir/\$OEM\$/\$1/Drivers/NetKVM" || return 1
|
||||
cp -L "$drivers/NetKVM/$driver/$arch/netkvm.cat" "$dir/\$OEM\$/\$1/Drivers/NetKVM" || return 1
|
||||
cp -L "$drivers/NetKVM/$driver/$arch/netkvm.inf" "$dir/\$OEM\$/\$1/Drivers/NetKVM" || return 1
|
||||
cp -L "$drivers/NetKVM/$driver/$arch/netkvm.sys" "$dir/\$OEM\$/\$1/Drivers/NetKVM" || return 1
|
||||
|
||||
file=$(find "$target" -maxdepth 1 -type f -iname TXTSETUP.SIF -print -quit) || return 1
|
||||
|
||||
if [ -z "$file" ]; then
|
||||
error "The file TXTSETUP.SIF could not be found!" && return 1
|
||||
fi
|
||||
|
||||
sed -i '/^\[SCSI.Load\]/s/$/\nviostor=viostor.sys,4/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\nviostor.sys=1,,,,,,4_,4,1,,,1,4/' "$file" || return 1
|
||||
sed -i '/^\[SCSI\]/s/$/\nviostor=\"Red Hat VirtIO SCSI Disk Device\"/' "$file" || return 1
|
||||
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00000000=\"viostor\"/' "$file" || return 1
|
||||
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00020000=\"viostor\"/' "$file" || return 1
|
||||
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00021AF4=\"viostor\"/' "$file" || return 1
|
||||
|
||||
if [ ! -d "$drivers/sata/xp/$arch" ]; then
|
||||
error "Failed to locate required SATA drivers!" && return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$dir/\$OEM\$/\$1/Drivers/sata" || return 1
|
||||
cp -Lr "$drivers/sata/xp/$arch/." "$dir/\$OEM\$/\$1/Drivers/sata" || return 1
|
||||
cp -Lr "$drivers/sata/xp/$arch/." "$target" || return 1
|
||||
|
||||
sed -i '/^\[SCSI.Load\]/s/$/\niaStor=iaStor.sys,4/' "$file" || return 1
|
||||
sed -i '/^\[FileFlags\]/s/$/\niaStor.sys = 16/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.cat = 1,,,,,,,1,0,0/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.inf = 1,,,,,,,1,0,0/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.sys = 1,,,,,,4_,4,1,,,1,4/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.sys = 1,,,,,,,1,0,0/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaahci.cat = 1,,,,,,,1,0,0/' "$file" || return 1
|
||||
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaAHCI.inf = 1,,,,,,,1,0,0/' "$file" || return 1
|
||||
sed -i '/^\[SCSI\]/s/$/\niaStor=\"Intel\(R\) SATA RAID\/AHCI Controller\"/' "$file" || return 1
|
||||
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_8086\&DEV_2922\&CC_0106=\"iaStor\"/' "$file" || return 1
|
||||
|
||||
rm -rf "$drivers" || return 1
|
||||
|
||||
fi
|
||||
|
||||
local key setup
|
||||
setup=$(find "$target" -maxdepth 1 -type f -iname setupp.ini -print -quit) || return 1
|
||||
|
||||
if [ -n "$setup" ] && [ -z "$KEY" ]; then
|
||||
|
||||
pid=$(<"$setup") || return 1
|
||||
pid="${pid%$'\r'}"
|
||||
|
||||
if [[ "$driver" == "2k" ]]; then
|
||||
|
||||
echo "${pid:0:$((${#pid})) - 3}270" > "$setup" || return 1
|
||||
|
||||
else
|
||||
|
||||
if [[ "$pid" == *"270" ]]; then
|
||||
|
||||
warn "this version of $desc requires a volume license key (VLK), it will ask for one during installation."
|
||||
|
||||
else
|
||||
|
||||
file=$(find "$target" -maxdepth 1 -type f -iname PID.INF -print -quit) || return 1
|
||||
|
||||
if [ -n "$file" ]; then
|
||||
|
||||
if [[ "$driver" == "2k3" ]]; then
|
||||
|
||||
key=$(grep -i -A 2 "StagingKey" "$file" | tail -n 2 | head -n 1) || key=""
|
||||
|
||||
else
|
||||
|
||||
key="${pid:$((${#pid})) - 8:5}"
|
||||
if [[ "${pid^^}" == *"OEM" ]]; then
|
||||
key=$(grep -i -A 2 "$key" "$file" | tail -n 2 | head -n 1) || key=""
|
||||
else
|
||||
key=$(grep -i -m 1 -A 2 "$key" "$file" | tail -n 2 | head -n 1) || key=""
|
||||
fi
|
||||
key="${key#*= }"
|
||||
|
||||
fi
|
||||
|
||||
key="${key%$'\r'}"
|
||||
[[ "${#key}" == "29" ]] && KEY="$key"
|
||||
|
||||
fi
|
||||
|
||||
if [ -z "$KEY" ]; then
|
||||
|
||||
# These are NOT pirated keys, they come from official MS documentation.
|
||||
|
||||
case "${driver,,}" in
|
||||
"xp" )
|
||||
|
||||
if [[ "${arch,,}" == "x86" ]]; then
|
||||
# Windows XP Professional x86 generic trial key (no activation)
|
||||
KEY="DR8GV-C8V6J-BYXHG-7PYJR-DB66Y"
|
||||
else
|
||||
# Windows XP Professional x64 generic trial key (no activation)
|
||||
KEY="B2RBK-7KPT9-4JP6X-QQFWM-PJD6G"
|
||||
fi ;;
|
||||
|
||||
"2k3" )
|
||||
|
||||
if [[ "${arch,,}" == "x86" ]]; then
|
||||
# Windows Server 2003 Standard x86 generic trial key (no activation)
|
||||
KEY="QKDCQ-TP2JM-G4MDG-VR6F2-P9C48"
|
||||
else
|
||||
# Windows Server 2003 Standard x64 generic trial key (no activation)
|
||||
KEY="P4WJG-WK3W7-3HM8W-RWHCK-8JTRY"
|
||||
fi ;;
|
||||
|
||||
esac
|
||||
|
||||
echo "${pid:0:$((${#pid})) - 3}000" > "$setup" || return 1
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
validateProductKey "$KEY" || return 1
|
||||
|
||||
local product=""
|
||||
[ -n "$KEY" ] && product="ProductID=$KEY"
|
||||
|
||||
mkdir -p "$dir/\$OEM\$" || return 1
|
||||
|
||||
if ! addFolder "$dir"; then
|
||||
error "Failed to add OEM folder to image!" && return 1
|
||||
fi
|
||||
|
||||
local oem=""
|
||||
local install="$dir/\$OEM\$/\$1/OEM/install.bat"
|
||||
[ -f "$install" ] && oem="\"Script\"=\"cmd /C start \\\"Install\\\" \\\"cmd /C C:\\\\OEM\\\\install.bat\\\"\""
|
||||
|
||||
[ -z "$WIDTH" ] && WIDTH="1280"
|
||||
[ -z "$HEIGHT" ] && HEIGHT="720"
|
||||
|
||||
validateResolution "WIDTH" "$WIDTH" 320 || return 1
|
||||
validateResolution "HEIGHT" "$HEIGHT" 200 || return 1
|
||||
validateMembership || return 1
|
||||
validateComputerName "$HOST" || return 1
|
||||
validateLegacyText "APP" "$APP" "$desc" || return 1
|
||||
validateLegacyText "ENGINE" "$ENGINE" "$desc" || return 1
|
||||
|
||||
XHEX=$(printf '%08x\n' "$((10#$WIDTH))") || return 1
|
||||
YHEX=$(printf '%08x\n' "$((10#$HEIGHT))") || return 1
|
||||
|
||||
local username="${USERNAME:-Docker}"
|
||||
local password="${PASSWORD:-admin}"
|
||||
local workgroup="${WORKGROUP:-WORKGROUP}"
|
||||
|
||||
local sifHost sifUsername sifPassword sifOrganization sifWorkgroup
|
||||
local regUsername regPassword
|
||||
|
||||
validateLegacyUsername "$username" "$desc" || return 1
|
||||
validatePassword "$password" "$desc" || return 1
|
||||
|
||||
sifHost=$(escapeSIFValue "${HOST:-*}") || return 1
|
||||
sifUsername=$(escapeSIFValue "$username") || return 1
|
||||
sifPassword=$(escapeSIFValue "$password") || return 1
|
||||
sifOrganization=$(escapeSIFValue "$APP for $ENGINE") || return 1
|
||||
sifWorkgroup=$(escapeSIFValue "$workgroup") || return 1
|
||||
regUsername=$(escapeRegistryValue "$username") || return 1
|
||||
regPassword=$(escapeRegistryValue "$password") || return 1
|
||||
|
||||
find "$target" -maxdepth 1 -type f -iname winnt.sif -delete || return 1
|
||||
|
||||
{ echo "[Data]"
|
||||
echo " AutoPartition=1"
|
||||
echo " MsDosInitiated=\"0\""
|
||||
echo " UnattendedInstall=\"Yes\""
|
||||
echo " AutomaticUpdates=\"Yes\""
|
||||
echo ""
|
||||
echo "[Unattended]"
|
||||
echo " UnattendSwitch=Yes"
|
||||
echo " UnattendMode=FullUnattended"
|
||||
echo " FileSystem=NTFS"
|
||||
echo " OemSkipEula=Yes"
|
||||
echo " OemPreinstall=Yes"
|
||||
echo " Repartition=Yes"
|
||||
echo " WaitForReboot=\"No\""
|
||||
echo " DriverSigningPolicy=\"Ignore\""
|
||||
echo " NonDriverSigningPolicy=\"Ignore\""
|
||||
printf '%s\n' " OemPnPDriversPath=\"Drivers\viostor;Drivers\NetKVM;Drivers\sata\""
|
||||
echo " NoWaitAfterTextMode=1"
|
||||
echo " NoWaitAfterGUIMode=1"
|
||||
echo " FileSystem=ConvertNTFS"
|
||||
echo " ExtendOemPartition=0"
|
||||
echo " Hibernation=\"No\""
|
||||
echo ""
|
||||
echo "[GuiUnattended]"
|
||||
echo " OEMSkipRegional=1"
|
||||
echo " OemSkipWelcome=1"
|
||||
echo " AdminPassword=\"$sifPassword\""
|
||||
echo " TimeZone=0"
|
||||
if disabled "$AUTOLOGIN"; then
|
||||
echo " AutoLogon=No"
|
||||
else
|
||||
echo " AutoLogon=Yes"
|
||||
echo " AutoLogonCount=65432"
|
||||
fi
|
||||
echo ""
|
||||
echo "[UserData]"
|
||||
echo " FullName=\"$sifUsername\""
|
||||
echo " ComputerName=\"$sifHost\""
|
||||
echo " OrgName=\"$sifOrganization\""
|
||||
echo " $product"
|
||||
echo ""
|
||||
echo "[Identification]"
|
||||
echo " JoinWorkgroup = \"$sifWorkgroup\""
|
||||
echo ""
|
||||
echo "[Display]"
|
||||
echo " BitsPerPel=32"
|
||||
echo " XResolution=$WIDTH"
|
||||
echo " YResolution=$HEIGHT"
|
||||
echo ""
|
||||
echo "[Networking]"
|
||||
echo " InstallDefaultComponents=Yes"
|
||||
echo ""
|
||||
echo "[Branding]"
|
||||
echo " BrandIEUsingUnattended=Yes"
|
||||
echo ""
|
||||
echo "[URL]"
|
||||
echo " Home_Page = http://www.google.com"
|
||||
echo " Search_Page = http://www.google.com"
|
||||
echo ""
|
||||
echo "[TerminalServices]"
|
||||
echo " AllowConnections=1"
|
||||
echo ""
|
||||
} | unix2dos > "$target/WINNT.SIF" || return 1
|
||||
|
||||
if [[ "$driver" == "2k3" ]]; then
|
||||
{ echo "[Components]"
|
||||
echo " TerminalServer=On"
|
||||
echo ""
|
||||
echo "[LicenseFilePrintData]"
|
||||
echo " AutoMode=PerServer"
|
||||
echo " AutoUsers=5"
|
||||
echo ""
|
||||
} | unix2dos >> "$target/WINNT.SIF" || return 1
|
||||
fi
|
||||
|
||||
{ echo "Windows Registry Editor Version 5.00"
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security]"
|
||||
echo "\"FirstRunDisabled\"=dword:00000001"
|
||||
echo "\"UpdatesDisableNotify\"=dword:00000001"
|
||||
echo "\"FirewallDisableNotify\"=dword:00000001"
|
||||
echo "\"AntiVirusDisableNotify\"=dword:00000001"
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wscsvc]"
|
||||
echo "\"Start\"=dword:00000004"
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List]"
|
||||
echo "\"3389:TCP\"=\"3389:TCP:*:Enabled:@xpsp2res.dll,-22009\""
|
||||
echo ""
|
||||
echo "[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Tour]"
|
||||
echo "\"RunCount\"=dword:00000000"
|
||||
echo ""
|
||||
echo "[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]"
|
||||
echo "\"HideFileExt\"=dword:00000000"
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer]"
|
||||
echo "\"NoWelcomeScreen\"=\"1\""
|
||||
echo ""
|
||||
echo "[HKEY_CURRENT_USER\Software\Microsoft\Internet Connection Wizard]"
|
||||
echo "\"Completed\"=\"1\""
|
||||
echo "\"Desktopchanged\"=\"1\""
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]"
|
||||
if disabled "$AUTOLOGIN"; then
|
||||
echo "\"AutoAdminLogon\"=\"0\""
|
||||
else
|
||||
echo "\"AutoAdminLogon\"=\"1\""
|
||||
echo "\"DefaultUserName\"=\"$regUsername\""
|
||||
echo "\"DefaultPassword\"=\"$regPassword\""
|
||||
echo "\"DefaultDomainName\"=\"Dockur\""
|
||||
fi
|
||||
echo ""
|
||||
printf '%s\n' "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]"
|
||||
echo "\"DefaultSettings.BitsPerPel\"=dword:00000020"
|
||||
echo "\"DefaultSettings.XResolution\"=dword:$XHEX"
|
||||
echo "\"DefaultSettings.YResolution\"=dword:$YHEX"
|
||||
echo ""
|
||||
printf '%s\n' "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Control\VIDEO\{23A77BF7-ED96-40EC-AF06-9B1F4867732A}\0000]"
|
||||
echo "\"DefaultSettings.BitsPerPel\"=dword:00000020"
|
||||
echo "\"DefaultSettings.XResolution\"=dword:$XHEX"
|
||||
echo "\"DefaultSettings.YResolution\"=dword:$YHEX"
|
||||
echo ""
|
||||
echo "[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]"
|
||||
printf '%s\n' "\"ScreenSaver\"=\"reg add \\\"HKCU\\\\Control Panel\\\\Desktop\\\" /f /v \\\"SCRNSAVE.EXE\\\" /t REG_SZ /d \\\"off\\\"\""
|
||||
printf '%s\n' "\"ScreenSaverOff\"=\"reg add \\\"HKCU\\\\Control Panel\\\\Desktop\\\" /f /v \\\"ScreenSaveActive\\\" /t REG_SZ /d \\\"0\\\"\""
|
||||
printf '%s\n' "\"SharedDrive\"=\"cmd /C net use Z: \\\\\\\\host.lan\\\\Data /persistent:yes\""
|
||||
echo "$oem"
|
||||
echo ""
|
||||
} | unix2dos > "$dir/\$OEM\$/install.reg" || return 1
|
||||
|
||||
if [[ "$driver" == "2k" ]]; then
|
||||
{ echo "[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Runonce]"
|
||||
echo "\"^SetupICWDesktop\"=-"
|
||||
echo ""
|
||||
} | unix2dos >> "$dir/\$OEM\$/install.reg" || return 1
|
||||
fi
|
||||
|
||||
if [[ "$driver" == "2k3" ]]; then
|
||||
{ echo "[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\srvWiz]"
|
||||
echo "@=dword:00000000"
|
||||
echo ""
|
||||
echo "[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ServerOOBE\SecurityOOBE]"
|
||||
echo "\"DontLaunchSecurityOOBE\"=dword:00000000"
|
||||
echo ""
|
||||
} | unix2dos >> "$dir/\$OEM\$/install.reg" || return 1
|
||||
fi
|
||||
|
||||
{ echo "Set WshShell = WScript.CreateObject(\"WScript.Shell\")"
|
||||
echo "Set WshNetwork = WScript.CreateObject(\"WScript.Network\")"
|
||||
echo "Set Domain = GetObject(\"WinNT://\" & WshNetwork.ComputerName)"
|
||||
echo ""
|
||||
echo "Function DecodeSID(binSID)"
|
||||
echo " ReDim o(LenB(binSID))"
|
||||
echo ""
|
||||
echo " For i = 1 To LenB(binSID)"
|
||||
echo " o(i-1) = AscB(MidB(binSID, i, 1))"
|
||||
echo " Next"
|
||||
echo ""
|
||||
echo " sid = \"S-\" & CStr(o(0)) & \"-\" & OctetArrayToString _"
|
||||
echo " (Array(o(2), o(3), o(4), o(5), o(6), o(7)))"
|
||||
echo " For i = 8 To (4 * o(1) + 4) Step 4"
|
||||
echo " sid = sid & \"-\" & OctetArrayToString _"
|
||||
echo " (Array(o(i+3), o(i+2), o(i+1), o(i)))"
|
||||
echo " Next"
|
||||
echo ""
|
||||
echo " DecodeSID = sid"
|
||||
echo "End Function"
|
||||
echo ""
|
||||
echo "Function OctetArrayToString(arr)"
|
||||
echo " v = 0"
|
||||
echo " For i = 0 To UBound(arr)"
|
||||
echo " v = v * 256 + arr(i)"
|
||||
echo " Next"
|
||||
echo ""
|
||||
echo " OctetArrayToString = CStr(v)"
|
||||
echo "End Function"
|
||||
echo ""
|
||||
echo "For Each DomainItem in Domain"
|
||||
echo " If DomainItem.Class = \"User\" Then"
|
||||
echo " sid = DecodeSID(DomainItem.Get(\"objectSID\"))"
|
||||
echo " If Left(sid, 9) = \"S-1-5-21-\" And Right(sid, 4) = \"-500\" Then"
|
||||
echo " LocalAdminADsPath = DomainItem.ADsPath"
|
||||
echo " Exit For"
|
||||
echo " End If"
|
||||
echo " End If"
|
||||
echo "Next"
|
||||
echo ""
|
||||
echo "Call Domain.MoveHere(LocalAdminADsPath, \"$username\")"
|
||||
echo ""
|
||||
echo "Set oLink = WshShell.CreateShortcut(WshShell.SpecialFolders(\"Desktop\") & \"\\Shared.lnk\")"
|
||||
echo "With oLink"
|
||||
printf '%s\n' " .TargetPath = \"\\\\host.lan\\Data\""
|
||||
echo " .Save"
|
||||
echo "End With"
|
||||
echo "Set oLink = Nothing"
|
||||
echo ""
|
||||
} | unix2dos > "$dir/\$OEM\$/install.vbs" || return 1
|
||||
|
||||
{ echo "[COMMANDS]"
|
||||
echo "\"REGEDIT /s install.reg\""
|
||||
echo "\"Wscript install.vbs\""
|
||||
echo ""
|
||||
} | unix2dos > "$dir/\$OEM\$/cmdlines.txt" || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
prepareLegacy() {
|
||||
|
||||
local iso="$1"
|
||||
local dir="$2"
|
||||
local desc="$3"
|
||||
|
||||
local tmp="$TMP/boot-images"
|
||||
local image="$tmp/eltorito_img1_bios.img"
|
||||
|
||||
ETFS="boot.img"
|
||||
|
||||
[ -s "$dir/$ETFS" ] && return 0
|
||||
rm -f "$dir/$ETFS" || return 1
|
||||
rm -rf "$tmp" || return 1
|
||||
|
||||
if ! LC_ALL=C xorriso \
|
||||
-no_rc \
|
||||
-osirrox on \
|
||||
-indev "$iso" \
|
||||
-extract_boot_images "$tmp" >/dev/null 2>&1; then
|
||||
rm -rf "$tmp" || true
|
||||
error "Failed to extract boot image from $desc ISO!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -s "$image" ]; then
|
||||
rm -rf "$tmp" || true
|
||||
error "Failed to locate BIOS boot image in $desc ISO!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! mv -f "$image" "$dir/$ETFS"; then
|
||||
rm -rf "$tmp" || true
|
||||
error "Failed to save boot image from $desc ISO!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "$tmp" || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
detectLegacy() {
|
||||
|
||||
local dir="$1"
|
||||
local find
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type d -iname WIN95 -print -quit)
|
||||
[ -n "$find" ] && DETECTED="win95" && return 0
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type d -iname WIN98 -print -quit)
|
||||
[ -n "$find" ] && DETECTED="win98" && return 0
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type d -iname WIN9X -print -quit)
|
||||
[ -n "$find" ] && DETECTED="win9x" && return 0
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_W.40 -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_S.40 -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_TS.40 -print -quit)
|
||||
[ -n "$find" ] && DETECTED="winnt4" && return 0
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_NT.5 -print -quit)
|
||||
|
||||
if [ -n "$find" ]; then
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_IA.5 -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_ID.5 -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_IP.5 -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname CDROM_IS.5 -print -quit)
|
||||
[ -n "$find" ] && DETECTED="win2k" && return 0
|
||||
|
||||
fi
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -iname WIN51 -print -quit)
|
||||
|
||||
if [ -n "$find" ]; then
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type f -iname WIN51AP -print -quit)
|
||||
[ -n "$find" ] && DETECTED="winxpx64" && return 0
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type f -iname WIN51IC -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51IP -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname setupxp.htm -print -quit)
|
||||
[ -n "$find" ] && DETECTED="winxpx86" && return 0
|
||||
|
||||
find=$(find "$dir" -maxdepth 1 -type f -iname WIN51IS -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51IA -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51IB -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51ID -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51IL -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51AA -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51AD -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51AS -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51MA -print -quit)
|
||||
[ -z "$find" ] && find=$(find "$dir" -maxdepth 1 -type f -iname WIN51MD -print -quit)
|
||||
[ -n "$find" ] && DETECTED="win2003r2" && return 0
|
||||
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
skipVersion() {
|
||||
|
||||
local id="$1"
|
||||
|
||||
case "${id,,}" in
|
||||
"win9"* | "winxp"* | "win2k"* | "win2003"* )
|
||||
return 0 ;;
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
isCompatible() {
|
||||
return 0
|
||||
}
|
||||
|
||||
setMachine() {
|
||||
|
||||
local id="$1"
|
||||
local iso="$2"
|
||||
local dir="$3"
|
||||
local desc="$4"
|
||||
|
||||
case "${id,,}" in
|
||||
"win9"* )
|
||||
ETFS="[BOOT]/Boot-1.44M.img" ;;
|
||||
"win2k"* )
|
||||
if ! prepareInstall "$iso" "$dir" "$desc" "2k"; then
|
||||
error "Failed to prepare $desc ISO!" && return 1
|
||||
fi ;;
|
||||
"winxp"* )
|
||||
if ! prepareInstall "$iso" "$dir" "$desc" "xp"; then
|
||||
error "Failed to prepare $desc ISO!" && return 1
|
||||
fi ;;
|
||||
"win2003"* )
|
||||
if ! prepareInstall "$iso" "$dir" "$desc" "2k3"; then
|
||||
error "Failed to prepare $desc ISO!" && return 1
|
||||
fi ;;
|
||||
esac
|
||||
|
||||
case "${id,,}" in
|
||||
"win9"* )
|
||||
USB="no"
|
||||
VGA="cirrus"
|
||||
DISK_TYPE="auto"
|
||||
MACHINE="pc-i440fx-2.4"
|
||||
BOOT_MODE="windows_legacy"
|
||||
[ -z "${ADAPTER:-}" ] && ADAPTER="pcnet" ;;
|
||||
"win2k"* )
|
||||
VGA="cirrus"
|
||||
MACHINE="pc"
|
||||
USB="pci-ohci"
|
||||
DISK_TYPE="auto"
|
||||
BOOT_MODE="windows_legacy"
|
||||
[ -z "${ADAPTER:-}" ] && ADAPTER="rtl8139" ;;
|
||||
"winxp"* | "win2003"* )
|
||||
DISK_TYPE="blk"
|
||||
BOOT_MODE="windows_legacy"
|
||||
[ -z "${SOUND:-}" ] && SOUND="usb-audio" ;;
|
||||
"winvista"* | "win7"* | "win2008"* )
|
||||
BOOT_MODE="windows_legacy" ;;
|
||||
esac
|
||||
|
||||
case "${id,,}" in
|
||||
"winxp"* | "win2003"* | "winvistax86"* | "win7x86"* | "win2008r2x86"* )
|
||||
# Prevent bluescreen if 64 bit PCI hole size is >2G.
|
||||
ARGS="-global q35-pcihost.x-pci-hole64-fix=false" ;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user