|
| 1 | +:: |
| 2 | +:: PROJECT: ReactOS ISO Remastering Script |
| 3 | +:: LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) |
| 4 | +:: PURPOSE: Allows easy remastering of customized ReactOS ISO images. |
| 5 | +:: Based on the boot/boot_images.cmake script in the ReactOS |
| 6 | +:: source tree. Requires a MKISOFS-compatible utility. |
| 7 | +:: COPYRIGHT: Copyright 2023-2025 Hermès Bélusca-Maïto <[email protected]> |
| 8 | +:: |
| 9 | + |
| 10 | +@echo off |
| 11 | +:: title ReactOS ISO Remastering Script |
| 12 | + |
| 13 | +setlocal enabledelayedexpansion |
| 14 | + |
| 15 | +:: |
| 16 | +:: Customizable settings |
| 17 | +:: |
| 18 | +:: ISO image identifier names |
| 19 | +set ISO_MANUFACTURER="ReactOS Project"& :: For both the publisher and the preparer |
| 20 | +set ISO_VOLNAME="ReactOS"& :: For both the Volume ID and the Volume set ID |
| 21 | + |
| 22 | +:: Image names of the MKISOFS and ISOHYBRID tools |
| 23 | +set MKISOFS=MKISOFS.EXE |
| 24 | +set ISOHYBRID=ISOHYBRID.EXE |
| 25 | + |
| 26 | + |
| 27 | +:: |
| 28 | +:: Main script |
| 29 | +:: |
| 30 | +cls |
| 31 | +echo ******************************************************************************* |
| 32 | +echo * * |
| 33 | +echo * ReactOS ISO Remastering Script * |
| 34 | +echo * * |
| 35 | +echo ******************************************************************************* |
| 36 | +echo. |
| 37 | + |
| 38 | +:: Newline macro, see https://stackoverflow.com/a/6379940 |
| 39 | +(set \n=^ |
| 40 | +%=Don't remove this line=% |
| 41 | +) |
| 42 | + |
| 43 | + |
| 44 | +:: Verify that we have access to a temporary directory. |
| 45 | +:: See https://stackoverflow.com/a/21041546 for more details. |
| 46 | +if defined TEMP ( if exist "%TEMP%\" goto :TEMP0 ) |
| 47 | + if defined TMP ( if exist "%TMP%\" goto :TEMP1 ) |
| 48 | + echo No temporary directory exists on your system. |
| 49 | + echo Please create one and assign it to the TEMP environment variable. |
| 50 | + echo. |
| 51 | + goto :Quit |
| 52 | + :TEMP1 |
| 53 | + set "TEMP=%TMP%" |
| 54 | +:TEMP0 |
| 55 | + |
| 56 | + |
| 57 | +:: Try to auto-locate MKISOFS and if not, prompt the user for a directory. |
| 58 | +set TOOL_DIR= |
| 59 | +set TOOL_PATH= |
| 60 | +for /f "delims=" %%f in ('WHERE %MKISOFS% 2^>NUL') do ( |
| 61 | + set "TOOL_DIR=%%~dpf" & if "!TOOL_DIR:~-1!"=="\" set "TOOL_DIR=!TOOL_DIR:~0,-1!" |
| 62 | + set "TOOL_PATH=%%f" |
| 63 | + goto :mkisofs_found |
| 64 | +) |
| 65 | +if not defined TOOL_PATH ( |
| 66 | + set /p TOOL_DIR="Please enter the directory path where %MKISOFS% can be found:!\n!" |
| 67 | + echo. |
| 68 | + if "!TOOL_DIR:~-1!"=="\" set "TOOL_DIR=!TOOL_DIR:~0,-1!" |
| 69 | + set "TOOL_PATH=!TOOL_DIR!\%MKISOFS%" |
| 70 | +) |
| 71 | +:mkisofs_found |
| 72 | +set "MKISOFS=%TOOL_PATH%" |
| 73 | + |
| 74 | + |
| 75 | +set /p INPUT_DIR="Please enter the path of the directory tree to image into the ISO:!\n!" |
| 76 | +echo. |
| 77 | +set /p OUTPUT_ISO="Please enter the file path of the ISO image that will be created:!\n!" |
| 78 | +echo. |
| 79 | + |
| 80 | + |
| 81 | +:: Retrieve the full paths to the 'isombr', 'isoboot', 'isobtrt' and 'efisys' files |
| 82 | +set isombr_file=loader/isombr.bin |
| 83 | +set isoboot_file=loader/isoboot.bin |
| 84 | +set isobtrt_file=loader/isobtrt.bin |
| 85 | +set efisys_file=loader/efisys.bin |
| 86 | + |
| 87 | +set ISOBOOT_PATH=%isoboot_file% |
| 88 | +::CHOICE /c 12 /n /m "Please choose the ISO boot file: 1) isoboot.bin ; 2) isobtrt.bin!\n![default: 1]: " |
| 89 | +CHOICE /c YN /n /m "Do you want the ReactOS media to wait for a key-press before booting [Y,N]? " |
| 90 | +echo. |
| 91 | +if errorlevel 2 set ISOBOOT_PATH=%isobtrt_file% |
| 92 | + |
| 93 | +:: Enable (U)EFI boot support if possible: check the |
| 94 | +:: presence of %efisys_file% in the ISO directory tree. |
| 95 | +:: NOTE: Convert forward to backslashes. |
| 96 | +::ISO_EFI_BOOT_PARAMS |
| 97 | +set ISO_BOOT_EFI_OPTIONS= |
| 98 | +if exist "%INPUT_DIR%\%efisys_file:/=\%" ( |
| 99 | + set "ISO_BOOT_EFI_OPTIONS=-eltorito-alt-boot -eltorito-platform efi -eltorito-boot %efisys_file% -no-emul-boot" |
| 100 | +) |
| 101 | + |
| 102 | +:: Summary of the boot files. |
| 103 | +echo ISO boot file: '%ISOBOOT_PATH%' |
| 104 | +if defined ISO_BOOT_EFI_OPTIONS ( |
| 105 | + echo EFI boot file: '%efisys_file%' |
| 106 | +) |
| 107 | +echo. |
| 108 | + |
| 109 | + |
| 110 | +set DUPLICATES_ONCE= |
| 111 | +CHOICE /c YN /n /m "Do you want to store duplicated files only once (reduces the size!\n!of the ISO image) [Y,N]? " |
| 112 | +echo. |
| 113 | +if %ERRORLEVEL% equ 1 set DUPLICATES_ONCE=-duplicates-once |
| 114 | + |
| 115 | + |
| 116 | +echo Creating the ISO image... |
| 117 | +echo. |
| 118 | + |
| 119 | +:: Create a mkisofs sort file to specify an explicit ordering for the boot files |
| 120 | +:: to place them at the beginning of the image (makes ISO image analysis easier). |
| 121 | +:: See mkisofs/schilytools/mkisofs/README.sort and boot/boot_images.cmake script |
| 122 | +:: in the ReactOS source tree for more details. |
| 123 | +:: https://stackoverflow.com/a/29635767 |
| 124 | +( |
| 125 | + ::echo ${CMAKE_CURRENT_BINARY_DIR}/empty/boot.catalog 4 |
| 126 | + echo boot.catalog 4 |
| 127 | + :: NOTE: Convert forward to backslashes. |
| 128 | + echo %INPUT_DIR%\%isoboot_file:/=\% 3 |
| 129 | + echo %INPUT_DIR%\%isobtrt_file:/=\% 2 |
| 130 | + echo %INPUT_DIR%\%efisys_file:/=\% 1 |
| 131 | +) > "%TEMP%\bootfiles.sort" |
| 132 | + |
| 133 | +:: Finally, create the ISO image proper. |
| 134 | +"%MKISOFS%" ^ |
| 135 | + -o "%OUTPUT_ISO%" -iso-level 4 ^ |
| 136 | + -publisher %ISO_MANUFACTURER% -preparer %ISO_MANUFACTURER% ^ |
| 137 | + -volid %ISO_VOLNAME% -volset %ISO_VOLNAME% ^ |
| 138 | + -eltorito-boot %ISOBOOT_PATH% -no-emul-boot -boot-load-size 4 ^ |
| 139 | + %ISO_BOOT_EFI_OPTIONS% ^ |
| 140 | + -hide boot.catalog -sort "%TEMP%\bootfiles.sort" ^ |
| 141 | + %DUPLICATES_ONCE% -no-cache-inodes "%INPUT_DIR%" |
| 142 | +:: -graft-points -path-list "some/directory/iso_image.lst" |
| 143 | +echo. |
| 144 | + |
| 145 | +if errorlevel 1 ( |
| 146 | +del "%TEMP%\bootfiles.sort" |
| 147 | + echo An error %ERRORLEVEL% happened while creating the ISO image "%OUTPUT_ISO%". |
| 148 | + goto :Quit |
| 149 | +) else ( |
| 150 | +del "%TEMP%\bootfiles.sort" |
| 151 | + echo The ISO image "%OUTPUT_ISO%" has been successfully created. |
| 152 | +) |
| 153 | +echo. |
| 154 | + |
| 155 | + |
| 156 | +:: Check whether ISOHYBRID is also available and if so, propose to post-process |
| 157 | +:: the generated ISO image to allow hybrid booting as a CD-ROM or as a hard disk. |
| 158 | +set TOOL_PATH= |
| 159 | +for /f "delims=" %%f in ('WHERE "%TOOL_DIR%":%ISOHYBRID% 2^>NUL') do ( |
| 160 | + set "TOOL_PATH=%%f" & goto :isohybrid_found) |
| 161 | +if not defined TOOL_PATH ( |
| 162 | + for /f "delims=" %%f in ('WHERE %ISOHYBRID% 2^>NUL') do ( |
| 163 | + set "TOOL_PATH=%%f" |
| 164 | + goto :isohybrid_found |
| 165 | + ) |
| 166 | + if not defined TOOL_PATH ( |
| 167 | + echo %ISOHYBRID% patching skipped. |
| 168 | + goto :Success |
| 169 | + ) |
| 170 | +) |
| 171 | +:isohybrid_found |
| 172 | +set "ISOHYBRID=%TOOL_PATH%" |
| 173 | + |
| 174 | + |
| 175 | +CHOICE /c YN /n /m "Do you want to post-process the ISO image to allow hybrid booting!\n!as a CD-ROM or as a hard disk [Y,N]? " |
| 176 | +echo. |
| 177 | +if %ERRORLEVEL% neq 1 goto :Success |
| 178 | + |
| 179 | +echo Patching the ISO image... |
| 180 | + |
| 181 | +:: NOTE: Convert forward to backslashes. |
| 182 | +"%ISOHYBRID%" -b %INPUT_DIR%\%isombr_file:/=\% -t 0x96 "%OUTPUT_ISO%" |
| 183 | +echo. |
| 184 | + |
| 185 | +if errorlevel 1 ( |
| 186 | + echo An error %ERRORLEVEL% happened while patching the ISO image "%OUTPUT_ISO%". |
| 187 | + goto :Quit |
| 188 | +) |
| 189 | +:: else ( |
| 190 | +:: echo The ISO image "%OUTPUT_ISO%" has been successfully patched. |
| 191 | +:: ) |
| 192 | +:: echo. |
| 193 | + |
| 194 | + |
| 195 | +:Success |
| 196 | +echo Success^^! |
| 197 | +:Quit |
| 198 | +endlocal |
| 199 | +echo Press any key to quit... |
| 200 | +pause > NUL |
| 201 | +exit /b |
0 commit comments