Initial commit

This commit is contained in:
ValdikSS 2018-04-30 22:40:11 +03:00
parent f992411b15
commit e56ae29ad6
2 changed files with 262 additions and 0 deletions

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# Windows2usb
**Burn Windows ISO to USB Flash Drive on Linux**
## What is this?
Windows2usb is a bash script which writes Microsoft Windows 7/8/8.1/10 installation DVD images to USB Flash Drive or external HDD on Linux. It was designed with compatibility in mind, and should work in all cases, contrary to other popular Linux tools.
Features:
* Fully automatic, no preparations required
* Supports BIOS and UEFI, FAT32 and NTFS
* Supports custom Windows ISOs with install.wim > 4GiB
* Uses stock Windows bootloaders where possible
* Does not break UEFI Secure Boot chain
## How to use?
Download latest [portable AppImage version](https://github.com/ValdikSS/windows2usb/releases) from the **Releases** page, set *execution bit* (`chmod +x windows2usb-*.AppImage`) and run it from the terminal.
`windows2usb <device> <windows iso> <mbr/gpt/gptntfs>`
The program prints removable storage list if no arguments supplied.
### BIOS Boot
BIOS Boot (Legacy Boot/UEFI-CSM) uses stock Windows 7 MBR and NTFS bootloader, courtesy of [ms-sys](http://ms-sys.sourceforge.net/) project.
Use this mode if you have old computer without UEFI support or want maximum compatibility of installation media.
To burn ISO in this mode, run:
`windows2usb <device> <windows iso> mbr`
### UEFI Boot
UEFI Boot (`gpt` mode) creates FAT32 partition with stock Windows UEFI bootloader.
This mode will not work on old computers. Use this mode for new computers with UEFI support.
This mode supports UEFI Secure Boot.
To burn ISO in this mode, run:
`windows2usb <device> <windows iso> gpt`
### UEFI Boot with NTFS Partition
UEFI Boot with NTFS partition uses [uefi-ntfs](https://github.com/pbatard/uefi-ntfs) bootloader from Rufus project.
This mode is made for custom installation disks with install.wim file greater than 4 GiB, which could be found on various torrent trackers. **Windows2usb** creates 2 partitions in this mode, small 1 MiB FAT32 partition with **uefi-ntfs** and huge NTFS partition with ISO data.
This mode does not support Secure Boot (uefi-ntfs bootloader is not signed by Microsoft or other trusted party).
To burn ISO in this mode, run:
`windows2usb <device> <windows iso> gptntfs`
If your ISO contains install.wim greater than 4 GiB, `gpt` mode will automatically detect that and terminate the writing process.
## Alternatives
[WoeUSB](https://github.com/slacka/WoeUSB)—does not support NTFS partitioning and install.wim > 4GiB; uses GRUB for BIOS Boot.
## Credits
This script uses:
* **lsblk** and **sfdisk** from [util-linux](https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/)
* [**ms-sys**](http://ms-sys.sourceforge.net/) for native Windows 7 MBR and NTFS bootloaders
* [**p7zip**](https://www.7-zip.org/) for ISO extraction

192
windows2usb Executable file
View File

@ -0,0 +1,192 @@
#!/bin/bash
set -e # errexit
set -f # noglob
set +o braceexpand # disable braceexpand
shopt -s nocasematch # for "if labeltype"
export LANG=C
bold="$(tput bold)"
normal="$(tput sgr0)"
scriptpath="$(readlink -f -- "$0")"
dirpath="$(dirname "$scriptpath")"
function check_requirements() {
local reqs=(awk lsblk 7z mkfs.vfat mkfs.ntfs sfdisk ms-sys mktemp)
for req in ${reqs[*]}; do
if ! command -v "$req" > /dev/null;
then
echo "${bold} == ERROR: $req is required but not found ==${normal}"
exit 104
fi
done
}
function list_removable_drives() {
lsblk -d -I 8 -o RM,NAME,SIZE,MODEL | \
awk '($1 == 1) {print "/dev/" substr($0, index($0, $2))}'
}
function format_drive() {
if [[ "$1" == "dos" ]] || [[ "$1" == "gpt" ]];
then
echo "label: $1" | sfdisk "$2"
else
echo "${bold} == format_drive: INTERNAL ERROR ==${normal}"
exit 101
fi
}
function check_installwim_gt4gib() {
7z l "$1" | awk '($6 ~ /install.wim/) {if ($4 > 429496296) {exit 1}; exit}'
}
function create_partitions() {
local mbrscript="- - 7 *"
local gptscript="- - U *"
local gptntfsscript="- 1MiB U *\n- - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 *"
if [[ "$1" == "dos" ]] || [[ "$1" == "gpt" ]] || [[ "$1" == "gptntfs" ]];
then
if [[ "$1" == "dos" ]];
then
echo -e "$mbrscript" | sfdisk "$2"
elif [[ "$1" == "gpt" ]];
then
echo -e "$gptscript" | sfdisk "$2"
elif [[ "$1" == "gptntfs" ]];
then
echo -e "$gptntfsscript" | sfdisk "$2"
fi
else
echo "${bold} == create_partitions: INTERNAL ERROR ==${normal}"
exit 102
fi
}
function write_uefintfs() {
cat "$dirpath/uefi-ntfs.img" > "$1"
}
function extract_iso() {
# $1 - isopath
# $2 - destdir
7z x "$1" -o"$2"
}
function umount_rm_path() {
umount "$1" || true
rm -r "$1"
}
function sigint_handler() {
umount_rm_path "$partpath"
}
if [[ ! "$3" ]];
then
echo "Windows 7/8/8.1/10 ISO to Flash Drive burning utility"
echo "$(basename "$0")" "<device> <windows iso> <mbr/gpt/gptntfs>"
echo
echo "Use MBR mode for old computers with BIOS (without UEFI), or for UEFI legacy mode (CSM)."
echo "Use GPT mode for new UEFI computers."
echo "Use 'gptntfs' mode for custom ISO images with install.wim file greater than 4 GiB."
echo "NOTE: gptntfs does not support Secure Boot!"
echo
echo "${bold} == Removable storage list ==${normal}"
list_removable_drives
exit
fi
if [[ "$EUID" == "0" ]];
then
dev="$1"
isopath="$2"
labeltype="$3"
partpath="$(mktemp -d /run/winiso-write.XXXXXXXXXX)"
check_requirements
trap sigint_handler INT
# MBR
if [[ "$labeltype" == "mbr" ]];
then
echo "${bold} == Creating new MBR-formatted partition table ==${normal}"
format_drive "dos" "$dev"
echo "${bold} == Creating NTFS partition ==${normal}"
create_partitions "dos" "$dev"
mkfs.ntfs -f "${dev}1"
echo "${bold} == Writing bootloader ==${normal}"
ms-sys -7 "${dev}"
ms-sys -n "${dev}1"
echo "${bold} == Mounting data partition ==${normal}"
mount "${dev}1" "$partpath"
# GPT
elif [[ "$labeltype" == "gpt" ]];
then
if check_installwim_gt4gib "$isopath";
then
echo "${bold} == ERROR: install.wim is greater than 4 GiB ==${normal}"
echo "${bold} == ERROR: Please use gptntfs mode ==${normal}"
umount_rm_path "$partpath"
exit 103
fi
echo "${bold} == Creating new GPT-formatted partition table ==${normal}"
format_drive "gpt" "$dev"
echo "${bold} == Creating UEFI FAT partition ==${normal}"
create_partitions "gpt" "$dev"
mkfs.vfat "${dev}1"
echo "${bold} == Mounting data partition ==${normal}"
mount "${dev}1" "$partpath"
# GPT FAT32 + NTFS
elif [[ "$labeltype" == "gptntfs" ]];
then
echo "${bold} == Creating new GPT-formatted partition table ==${normal}"
format_drive "gpt" "$dev"
echo "${bold} == Creating UEFI FAT and Microsoft NTFS partitions ==${normal}"
create_partitions "gptntfs" "$dev"
write_uefintfs "${dev}1"
mkfs.ntfs -f "${dev}2"
echo "${bold} == Mounting data partition ==${normal}"
mount "${dev}2" "$partpath"
fi
echo "${bold} == Extracting files from ISO to the partition ==${normal}"
extract_iso "$isopath" "$partpath"
echo "${bold} == Unmounting partition ==${normal}"
umount_rm_path "$partpath"
echo "${bold} == All done! ==${normal}"
else
if [[ "$APPIMAGE" ]];
then
scriptpath="$APPIMAGE"
fi;
privescs=(pkexec sudo)
for privesc in ${privescs[*]}; do
if command -v "$privesc" > /dev/null; then
"$privesc" "$scriptpath" "$@"
exit
fi
done
echo "${bold} == ERROR: no pkexec or sudo found. ==${normal}"
echo "${bold} == ERROR: please run this script as root manually. ==${normal}"
fi