mirror of
https://github.com/dockur/windows.git
synced 2026-07-28 21:53:34 +07:00
Update iso-prototype.py
This commit is contained in:
@@ -477,6 +477,78 @@ def sync_tree(iso, tree: Path, logical_root: PurePosixPath) -> None:
|
||||
add_file_all_namespaces(iso, root_path / name, logical)
|
||||
|
||||
|
||||
def rebuild_windows_eltorito(iso, tree: Path) -> None:
|
||||
"""Replace imported hidden boot entries with complete extracted images.
|
||||
|
||||
Microsoft installation media commonly stores the El Torito boot images as
|
||||
hidden extents. When PyCdlib opens such an ISO, the catalog's 512-byte load
|
||||
count is not enough to recover the real size of the hidden UEFI FAT image.
|
||||
Writing the imported entry back can therefore truncate it to one sector.
|
||||
|
||||
Rebuild the catalog from the files extracted by the normal Windows image
|
||||
preparation flow instead. Short root-level ISO9660 names are intentional:
|
||||
the boot images only need stable Directory Records for PyCdlib and do not
|
||||
need to be exposed through the UDF namespace used by Windows Setup.
|
||||
"""
|
||||
bios_source = tree / "boot/etfsboot.com"
|
||||
uefi_source = tree / "efi/microsoft/boot/efisys_noprompt.bin"
|
||||
|
||||
missing = [str(path) for path in (bios_source, uefi_source) if not path.is_file()]
|
||||
if missing:
|
||||
raise PrototypeError(
|
||||
"Cannot rebuild Windows El Torito catalog; missing boot image(s): "
|
||||
+ ", ".join(missing)
|
||||
)
|
||||
|
||||
bios_iso_path = "/PYBIOS.BIN;1"
|
||||
uefi_iso_path = "/PYUEFI.BIN;1"
|
||||
|
||||
print("Rebuilding El Torito catalog from extracted boot images:")
|
||||
print(f" BIOS: {bios_source} ({bios_source.stat().st_size} bytes)")
|
||||
print(f" UEFI: {uefi_source} ({uefi_source.stat().st_size} bytes)")
|
||||
|
||||
# Remove the imported catalog before touching any inode referenced by it.
|
||||
# This also releases PyCdlib's incomplete hidden boot-image records.
|
||||
if getattr(iso, "eltorito_boot_catalog", None) is not None:
|
||||
iso.rm_eltorito()
|
||||
|
||||
# These private root-level records avoid depending on the source ISO's very
|
||||
# small ISO9660 tree. The original Microsoft files remain available via UDF.
|
||||
for iso_path in (bios_iso_path, uefi_iso_path):
|
||||
try:
|
||||
iso.get_record(iso_path=iso_path)
|
||||
except Exception:
|
||||
continue
|
||||
iso.rm_file(iso_path=iso_path)
|
||||
|
||||
iso.add_file(str(bios_source), iso_path=bios_iso_path)
|
||||
iso.add_file(str(uefi_source), iso_path=uefi_iso_path)
|
||||
|
||||
# Match the production genisoimage settings: no-emulation BIOS boot, eight
|
||||
# 512-byte sectors loaded, and a boot info table patched into etfsboot.com.
|
||||
iso.add_eltorito(
|
||||
bios_iso_path,
|
||||
boot_load_size=8,
|
||||
platform_id=0x00,
|
||||
boot_info_table=True,
|
||||
media_name="noemul",
|
||||
bootable=True,
|
||||
boot_load_seg=0,
|
||||
)
|
||||
|
||||
# A second add_eltorito() call creates an alternate catalog section. Leaving
|
||||
# boot_load_size unset makes PyCdlib use the complete EFI FAT image rather
|
||||
# than the misleading one-sector count imported from Microsoft media.
|
||||
iso.add_eltorito(
|
||||
uefi_iso_path,
|
||||
platform_id=0xEF,
|
||||
efi=True,
|
||||
media_name="noemul",
|
||||
bootable=True,
|
||||
boot_load_seg=0,
|
||||
)
|
||||
|
||||
|
||||
def build_pycdlib(args: argparse.Namespace) -> None:
|
||||
try:
|
||||
import pycdlib # type: ignore
|
||||
@@ -503,6 +575,7 @@ def build_pycdlib(args: argparse.Namespace) -> None:
|
||||
logical = PurePosixPath("/") / value.lstrip("/")
|
||||
print(f"Synchronizing tree: {logical}")
|
||||
sync_tree(iso, tree, logical)
|
||||
rebuild_windows_eltorito(iso, tree)
|
||||
print("Checking PyCdlib consistency...")
|
||||
iso.force_consistency()
|
||||
print(f"Writing output ISO: {output}")
|
||||
|
||||
Reference in New Issue
Block a user