feat(releng): add fws-windows-bcdfix script for windows bcd repair
Add new script to make Windows bootable by executing bcdboot in WinPE launched once via BootNext after FWS installation. The script: 1. Stages bootable WinPE from ISO (bootmgr + BCD + boot.wim) to ESP 2. Injects automation (winpeshl.ini + fwspe.cmd) into boot.wim boot image - WinPE finds Windows drive and ESP partition - Executes bcdboot and reboots 3. Creates UEFI entry with one-shot BootNext to WinPE Note: Not validated on real hardware. Recommended path: bcdboot writes correct BCD with one automatic WinPE reboot before returning to FWS.
This commit is contained in:
@@ -0,0 +1,85 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================================
|
||||||
|
# fws-windows-bcdfix — rend Windows bootable en exécutant le VRAI `bcdboot`
|
||||||
|
# dans une WinPE lancée UNE FOIS (BootNext), juste après l'install FWS.
|
||||||
|
#
|
||||||
|
# ⚠ NON VALIDÉ SUR MATÉRIEL RÉEL. Voie RECOMMANDÉE par défaut : bcdboot écrit un
|
||||||
|
# BCD correct. Coût : 1 reboot automatique en WinPE, puis retour à FWS
|
||||||
|
# (BootOrder[0]=FWS réasserté par fws-windows-deploy + fws-gameboot-bootfix).
|
||||||
|
#
|
||||||
|
# Mécanique :
|
||||||
|
# 1. Copier la WinPE bootable de l'ISO (bootmgr + BCD WinPE + boot.wim) sur l'ESP.
|
||||||
|
# 2. Injecter winpeshl.ini + fwspe.cmd DANS l'image AMORÇABLE de boot.wim
|
||||||
|
# (Boot Index, typiquement 2 « Setup », + index 1 en ceinture) : au démarrage,
|
||||||
|
# WinPE lance fwspe.cmd → trouve le lecteur Windows (\Windows\System32\
|
||||||
|
# winload.efi) et l'ESP (label WINESP via diskpart) → bcdboot → wpeutil reboot.
|
||||||
|
# 3. Poser une entrée UEFI + BootNext one-shot vers cette WinPE.
|
||||||
|
#
|
||||||
|
# Args : <ISO_MOUNT> <ESP_MOUNT> <WIN_DISK> <ESP_PARTNUM>
|
||||||
|
# ============================================================
|
||||||
|
set -u
|
||||||
|
ISO="${1:-}"; ESP="${2:-}"; WIN_DISK="${3:-}"; ESP_PN="${4:-1}"
|
||||||
|
log(){ printf '\e[36m[bcdfix]\e[0m %s\n' "$*"; }
|
||||||
|
die(){ printf '\e[31m[bcdfix] ERREUR : %s\e[0m\n' "$*" >&2; exit 1; }
|
||||||
|
[ -d "$ISO" ] && [ -d "$ESP" ] && [ -b "$WIN_DISK" ] || die "args invalides"
|
||||||
|
command -v wimlib-imagex >/dev/null 2>&1 || die "wimlib absent"
|
||||||
|
|
||||||
|
# 1) Structure de boot WinPE depuis l'ISO (bootmgr + BCD WinPE prêts).
|
||||||
|
log "Staging de la WinPE de l'ISO sur l'ESP…"
|
||||||
|
mkdir -p "$ESP/EFI/Microsoft/Boot" "$ESP/sources"
|
||||||
|
cp -rf "$ISO"/efi/microsoft/boot/. "$ESP/EFI/Microsoft/Boot/" 2>/dev/null || true
|
||||||
|
[ -f "$ESP/EFI/Microsoft/Boot/bootmgfw.efi" ] \
|
||||||
|
|| cp -f "$ISO/efi/boot/bootx64.efi" "$ESP/EFI/Microsoft/Boot/bootmgfw.efi" 2>/dev/null \
|
||||||
|
|| die "bootmgfw.efi WinPE introuvable dans l'ISO"
|
||||||
|
|
||||||
|
# 2) Injecter l'automation dans l'image AMORÇABLE de boot.wim.
|
||||||
|
TMP="$(mktemp -d)"
|
||||||
|
cp -f "$ISO/sources/boot.wim" "$TMP/boot.wim" || die "boot.wim introuvable dans l'ISO"
|
||||||
|
cat > "$TMP/winpeshl.ini" <<'INI'
|
||||||
|
[LaunchApps]
|
||||||
|
"cmd.exe", "/c X:\fwspe.cmd"
|
||||||
|
INI
|
||||||
|
# ⚠ NON VALIDÉ. bcdboot dans WinPE : trouver le lecteur Windows par présence de
|
||||||
|
# winload.efi (NTFS auto-monté), et l'ESP par son label WINESP via diskpart.
|
||||||
|
cat > "$TMP/fwspe.cmd" <<'CMD'
|
||||||
|
@echo off
|
||||||
|
set WIN=
|
||||||
|
for %%D in (C D E F G H I J K L M N O P) do if exist %%D:\Windows\System32\winload.efi set WIN=%%D:
|
||||||
|
echo list volume > X:\dp.txt
|
||||||
|
diskpart /s X:\dp.txt > X:\vol.txt
|
||||||
|
for /f "tokens=2" %%V in ('findstr /i "WINESP" X:\vol.txt') do (
|
||||||
|
echo select volume %%V > X:\dp2.txt
|
||||||
|
echo assign letter=S >> X:\dp2.txt
|
||||||
|
diskpart /s X:\dp2.txt
|
||||||
|
)
|
||||||
|
if not defined WIN goto reboot
|
||||||
|
if exist S:\ ( bcdboot %WIN%\Windows /s S: /f UEFI ) else ( bcdboot %WIN%\Windows /f UEFI )
|
||||||
|
:reboot
|
||||||
|
wpeutil reboot
|
||||||
|
CMD
|
||||||
|
# Image amorcée = « Boot Index » (typiquement 2) ; on injecte aussi l'index 1 en ceinture.
|
||||||
|
BOOTIDX="$(wimlib-imagex info "$TMP/boot.wim" 2>/dev/null | sed -n 's/^Boot Index:[[:space:]]*//p' | head -1)"
|
||||||
|
[ -n "$BOOTIDX" ] || BOOTIDX=2
|
||||||
|
INJECTED=0
|
||||||
|
for i in $BOOTIDX 1; do
|
||||||
|
wimlib-imagex update "$TMP/boot.wim" "$i" \
|
||||||
|
--command="add '$TMP/winpeshl.ini' /Windows/System32/winpeshl.ini" 2>/dev/null \
|
||||||
|
&& wimlib-imagex update "$TMP/boot.wim" "$i" \
|
||||||
|
--command="add '$TMP/fwspe.cmd' /fwspe.cmd" 2>/dev/null \
|
||||||
|
&& INJECTED=1
|
||||||
|
done
|
||||||
|
[ "$INJECTED" = 1 ] || die "injection winpeshl/fwspe dans boot.wim échouée"
|
||||||
|
cp -f "$TMP/boot.wim" "$ESP/sources/boot.wim" || die "copie boot.wim → ESP échouée"
|
||||||
|
rm -rf "$TMP"
|
||||||
|
|
||||||
|
# 3) Entrée UEFI one-shot vers la WinPE stagée.
|
||||||
|
log "Création de l'entrée UEFI WinPE (one-shot BootNext)…"
|
||||||
|
efibootmgr -c -d "$WIN_DISK" -p "$ESP_PN" -L 'FWS WinPE (bcdboot)' \
|
||||||
|
-l '\EFI\Microsoft\Boot\bootmgfw.efi' >/dev/null 2>&1 \
|
||||||
|
|| die "création de l'entrée UEFI WinPE échouée"
|
||||||
|
PE_BN="$(efibootmgr 2>/dev/null | sed -n "s/^Boot\([0-9A-Fa-f]\{4\}\)\*\? *FWS WinPE.*/\1/p" | head -1)"
|
||||||
|
[ -n "$PE_BN" ] || die "numéro de boot WinPE introuvable"
|
||||||
|
efibootmgr -n "$PE_BN" >/dev/null || die "BootNext WinPE non armé"
|
||||||
|
log "WinPE armée en BootNext (Boot$PE_BN). Au 1er reboot : bcdboot puis retour FWS."
|
||||||
|
log "⚠ NON VALIDÉ sur matériel — à tester (assignation lettres WinPE, index boot.wim)."
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user