windows: 从 inf 获取驱动文件列表

This commit is contained in:
bin456789 2025-03-02 21:57:06 +08:00
parent 0be857bff9
commit a12718e49c
No known key found for this signature in database
GPG Key ID: EE301B386DE6C11B
6 changed files with 435 additions and 70 deletions

View File

@ -11,19 +11,18 @@
One-Click Script to Reinstall System [中文](README.md)
![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)
[![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)](https://github.com/sponsors/bin456789)
## Highlights
- One-click Linux installation: Supports 19 common distributions.
- One-click Windows installation: Uses the official ISO for installation instead of custom images. The script can automatically ~~retrieves the ISO link~~ and installs common drivers like `Virtio`.
- Supports installation in any direction, i.e., `Linux to Linux`, `Linux to Windows`, `Windows to Windows`, `Windows to Linux`
- No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC` and other special network configurations
- No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC`
- Specially optimized for low-spec servers, requires less memory than the official netboot
- Uses partition table ID to identify hard drives throughout the process, ensuring no wrong disk is written
- Supports BIOS and EFI boot, and ARM Server
- No homemades image included, all resources are obtained in real-time from mirror sites
- Includes many comments.
## System Requirements
@ -32,7 +31,7 @@ The original system can be any system listed in the table.
The system requirements for the target system are as follows:
| System | Version | Memory | Disk |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | -----------------|
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- |
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.18, 3.19, 3.20, 3.21 | 256 MB | 1 GB |
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12 | 256 MB | 1 ~ 1.5 GB ^ |
| <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | Rolling | 256 MB | 1 ~ 1.5 GB ^ |
@ -144,6 +143,7 @@ bash reinstall.sh anolis 7|8|23
kali
arch
gentoo
aosc
fnos
```
@ -329,6 +329,14 @@ bash reinstall.sh windows \
--iso "https://go.microsoft.com/fwlink/?linkid=2289029"
```
or Magnet Link
```bash
bash reinstall.sh windows \
--image-name "Windows 11 Enterprise LTSC 2024" \
--iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff"
```
<details>
<summary>The following website provides ISO links.</summary>
@ -336,6 +344,8 @@ bash reinstall.sh windows \
- General
- <https://msdl.gravesoft.dev>
- <https://massgrave.dev/genuine-installation-media>
- <https://next.itellyou.cn>
- <https://www.xitongku.com>
- <https://www.microsoft.com/software-download/windows10> (Need to open it with a non-Windows User-Agent)
- <https://www.microsoft.com/software-download/windows11>
- <https://www.microsoft.com/software-download/windows11arm64>
@ -349,8 +359,8 @@ bash reinstall.sh windows \
- <https://www.microsoft.com/evalcenter/download-windows-server-2022>
- <https://www.microsoft.com/evalcenter/download-windows-server-2025>
- Insider Preview
- <https://www.microsoft.com/software-download/windowsinsiderpreviewiso>
- <https://www.microsoft.com/software-download/windowsinsiderpreviewserver>
- <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewiso>
- <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver>
</details>
@ -361,10 +371,9 @@ bash reinstall.sh windows \
- `--rdp-port PORT` Change RDP port
- `--ssh-port PORT` Change SSH port (for log observation during installation)
- `--web-port PORT` Change Web port (for log observation during installation)
- `--add-driver-dir DIR` Adds additional driver, specifying the folder where the .inf file is located.
- `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file.
- The driver must be downloaded locally first.
- This parameter can be set multiple times to add different driver folders.
- The script will copy the entire folder, so no other files should be placed inside the folder.
- This parameter can be set multiple times to add different driver.
- `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`.
#### The following drivers will automatic download and install as needed, without the need for manual addition

View File

@ -11,19 +11,18 @@
一键重装脚本 [English](README.en.md)
![捐赠者](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)
[![Sponsors](https://raw.githubusercontent.com/bin456789/sponsors/refs/heads/master/sponsors.svg)](https://github.com/sponsors/bin456789)
## 亮点
- 一键安装 Linux支持 19 种常见发行版
- 一键安装 Windows使用官方 ISO 安装而非自制镜像,~~脚本会自动获取 ISO 链接~~、自动安装 Virtio 等常见驱动
- 支持任意方向重装,即 `Linux to Linux``Linux to Windows``Windows to Windows``Windows to Linux`
- 无需填写 IP 参数,自动识别动静态,支持 `/32``/128``网关不在子网范围内``纯 IPv6``双网卡` 等特殊网络
- 无需填写 IP 参数,自动识别动静态,支持 `/32``/128``网关不在子网范围内``纯 IPv6``双网卡`
- 专门适配低配小鸡,比官方 netboot 需要更少的内存
- 全程用分区表 ID 识别硬盘,确保不会写错硬盘
- 支持 BIOS、EFI 引导,支持 ARM 服务器
- 不含自制包,所有资源均实时从镜像源获得
- 有很多注释
## 系统要求
@ -47,7 +46,7 @@
| <img width="16" height="16" src="https://github.com/user-attachments/assets/99a542b6-6482-4086-addf-f192c06fef73" /> NixOS | 24.11 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 公测 | 512 MB | 12 GB |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | 任何 | 512 MB | 取决于镜像 |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
@ -330,6 +329,14 @@ bash reinstall.sh windows \
--iso "https://go.microsoft.com/fwlink/?linkid=2289029"
```
或者磁力链接
```bash
bash reinstall.sh windows \
--image-name "Windows 11 Enterprise LTSC 2024" \
--iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff"
```
<details>
<summary>以下网站可找到 ISO 链接</summary>
@ -337,6 +344,8 @@ bash reinstall.sh windows \
- 正式版
- <https://msdl.gravesoft.dev>
- <https://massgrave.dev/genuine-installation-media>
- <https://next.itellyou.cn>
- <https://www.xitongku.com>
- <https://www.microsoft.com/software-download/windows10> (需用非 Windows User-Agent 打开)
- <https://www.microsoft.com/software-download/windows11>
- <https://www.microsoft.com/software-download/windows11arm64>
@ -350,8 +359,8 @@ bash reinstall.sh windows \
- <https://www.microsoft.com/evalcenter/download-windows-server-2022>
- <https://www.microsoft.com/evalcenter/download-windows-server-2025>
- Insider 预览版
- <https://www.microsoft.com/software-download/windowsinsiderpreviewiso>
- <https://www.microsoft.com/software-download/windowsinsiderpreviewserver>
- <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewiso>
- <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver>
</details>
@ -362,10 +371,9 @@ bash reinstall.sh windows \
- `--rdp-port PORT` 更改 RDP 端口
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
- `--add-driver-dir DIR` 添加额外驱动,填写 .inf 所在的文件夹
- `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹
- 需先下载驱动到本地
- 可多次设置该参数以添加不同的驱动文件夹
- 脚本将复制整个文件夹,因此文件夹内不要放置其他文件
- 可多次设置该参数以添加不同的驱动
- `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os`
#### 以下驱动会自动按需下载安装,无需手动添加

View File

@ -81,8 +81,15 @@ EOF
}
info() {
upper=$(to_upper <<<"$@")
echo_color_text '\e[32m' "***** $upper *****" >&2
local msg
if [ "$1" = false ]; then
shift
msg=$*
else
msg=$(to_upper <<<"$@")
fi
echo_color_text '\e[32m' "***** $msg *****" >&2
}
warn() {
@ -91,7 +98,7 @@ warn() {
error() {
echo_color_text '\e[31m' "***** ERROR *****" >&2
echo_color_text '\e[31m' "Error: $*" >&2
echo_color_text '\e[31m' "$*" >&2
}
echo_color_text() {
@ -609,6 +616,12 @@ is_virt() {
$_is_virt
}
is_absolute_path() {
# 检查路径是否以/开头
# 注意语法和 ash 不同
[[ "$1" = /* ]]
}
assert_cpu_supports_x86_64_v3() {
# 用 ld.so/cpuid/coreinfo.exe 更准确
# centos 7 /usr/lib64/ld-linux-x86-64.so.2 没有 --help
@ -2150,7 +2163,13 @@ del_empty_lines() {
sed '/^[[:space:]]*$/d'
}
trim() {
# sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//'
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
prompt_password() {
info "prompt password"
while true; do
IFS= read -r -p "Password [$DEFAULT_PASSWORD]: " password
IFS= read -r -p "Retype password [$DEFAULT_PASSWORD]: " password_confirm
@ -3459,16 +3478,12 @@ This script is outdated, please download reinstall.sh again.
fi
# 添加自定义 windows 驱动
if [ "$distro" = windows ]; then
mkdir -p $initrd_dir/custom_drivers
i=0
while IFS= read -r dir; do
if [ -d "$dir" ]; then
((i += 1))
info "add custom driver: $dir"
cp -r "$dir" "$initrd_dir/custom_drivers/$i"
fi
done < <(echo "$custom_driver_dirs")
if [ "$distro" = windows ] && [ -n "$custom_infs" ]; then
# shellcheck disable=SC1090
. <(curl -L $confhome/windows-driver-utils.sh)
echo "$custom_infs" | while read -r inf; do
parse_inf_and_cp_driever "$inf" "$initrd_dir/custom_drivers" "$basearch_alt" true
done
fi
# alpine live 不精简 initrd
@ -3594,7 +3609,7 @@ fi
long_opts=
for o in ci installer debug minimal allow-ping force-cn \
add-driver-dir: \
add-driver: \
hold: sleep: \
iso: \
image-name: \
@ -3687,26 +3702,45 @@ while true; do
web_port=$2
shift 2
;;
--add-driver-dir)
# 指定 dir 而不是指定 inf
# 防止用户将 inf 放在 / 而复制整个 /
--add-driver)
# 路径转换
if is_in_windows; then
# 输入的路径是 / 开头也没问题
dir="$(cygpath -u "$2")"
inf_or_dir="$(cygpath -u "$2")"
else
dir=$2
inf_or_dir=$2
fi
# 防止重复添加
if ! grep -Fqx "$dir" <<<"$custom_driver_dirs"; then
# shellcheck disable=SC2010
{ [ -d "$dir" ] && ls "$dir" | grep -Eiq '\.inf$'; } || error_and_exit "Invalid Driver Directory: $2"
# 一行一个驱动文件夹
custom_driver_dirs+="$dir
"
# alpine busybox 不支持 readlink -m
# readlink -m /asfsafasfsaf/fasf
# 因此需要先判断路径是否存在
if ! [ -d "$inf_or_dir" ] &&
! { [ -f "$inf_or_dir" ] && [[ "$inf_or_dir" =~ \.[iI][nN][fF]$ ]]; }; then
error_and_exit "Not a inf or dir: $2"
fi
# 转为绝对路径
inf_or_dir=$(readlink -f "$inf_or_dir")
info "finding inf in $inf_or_dir"
# find /tmp -type f -iname '*.inf' 只要 /tmp 存在就会返回 0
if infs=$(find "$inf_or_dir" -type f -iname '*.inf' | grep .); then
while IFS= read -r inf; do
# 防止重复添加
if ! grep -Fqx "$inf" <<<"$custom_infs"; then
echo "inf found: $inf"
# 一行一个 inf
if [ -n "$custom_infs" ]; then
custom_infs+=$'\n'
fi
custom_infs+=$inf
fi
done <<<"$infs"
else
error_and_exit "Can't find inf files in $2"
fi
shift 2
;;
--force-old-windows-setup)

View File

@ -20,13 +20,28 @@ error() {
color='\e[31m'
plain='\e[0m'
echo -e "${color}***** ERROR *****${plain}" >&2
echo -e "${color}Error: $*${plain}" >&2
echo -e "${color}$*${plain}" >&2
}
info() {
color='\e[32m'
plain='\e[0m'
echo -e "${color}***** $(echo "$*" | to_upper) *****${plain}" >&2
local msg
if [ "$1" = false ]; then
shift
msg=$*
else
msg=$(echo "$*" | to_upper)
fi
echo -e "${color}***** $msg *****${plain}" >&2
}
warn() {
color='\e[33m'
plain='\e[0m'
echo -e "${color}Warning: $*${plain}" >&2
}
error_and_exit() {
@ -754,6 +769,10 @@ to_lower() {
tr '[:upper:]' '[:lower:]'
}
del_cr() {
sed 's/\r//g'
}
del_empty_lines() {
sed '/^[[:space:]]*$/d'
}
@ -4982,6 +5001,12 @@ get_filesize_mb() {
du -m "$1" | awk '{print $1}'
}
is_absolute_path() {
# 检查路径是否以/开头
# 注意语法和 bash 不同
[[ "$1" = "/*" ]]
}
install_windows() {
get_wim_prop() {
wim=$1
@ -5188,11 +5213,11 @@ install_windows() {
fi
# 变量名 使用场景
# arch_uname arch命令 / uname -m x86_64 aarch64
# arch_wim wiminfo x86 x86_64 ARM64
# arch virtio iso / unattend.xml x86 amd64 arm64
# arch_xdd virtio msi / xen驱动 x86 x64
# arch_dd 华为云驱动 32 64
# arch_uname arch命令 / uname -m x86_64 aarch64
# arch_wim wiminfo x86 x86_64 ARM64
# arch virtio iso / unattend.xml / .inf x86 amd64 arm64
# arch_xdd virtio msi / xen驱动 x86 x64
# arch_dd 华为云驱动 32 64
# 将 wim 的 arch 转为驱动和应答文件的 arch
case "$arch_wim" in
@ -5219,6 +5244,10 @@ install_windows() {
drv=/os/drivers
mkdir -p "$drv" # 驱动下载临时文件夹
# 下载脚本
# shellcheck disable=SC1090
. <(wget -O- $confhome/windows-driver-utils.sh)
# 这里有坑
# $(get_cloud_vendor) 调用了 cache_dmi_and_virt
# 但是 $(get_cloud_vendor) 运行在 subshell 里面
@ -5647,13 +5676,10 @@ install_windows() {
# 因此只能交给用户自己添加驱动
add_driver_custom() {
for dir in /custom_drivers/*; do
if [ -d "$dir" ]; then
info "Add custom drivers: $dir"
cp_drivers custom "$dir"
# 复制后不删除,因为脚本可能再次运行
fi
done
if [ -d /custom_drivers/ ]; then
cp_drivers custom /custom_drivers/
# 复制后不删除,因为脚本可能再次运行
fi
}
# 修改应答文件
@ -5718,21 +5744,20 @@ install_windows() {
cp_drivers() {
if [ "$1" = custom ]; then
shift
dst="/wim/custom_drivers/$(basename "$1")"
dst="/wim/custom_drivers"
else
dst=/wim/drivers
fi
mkdir -p "$dst"
src=$1
shift
find $src \
-type f \
-not -iname "*.pdb" \
-not -iname "dpinst.exe" \
"$@" \
-exec cp -rfv {} "$dst" \;
# -not -iname "*.pdb" \
# -not -iname "dpinst.exe" \
find $src -type f -iname "*.inf" "$@" | while read -r inf; do
parse_inf_and_cp_driever "$inf" "$dst" "$arch" false
done
}
# 添加驱动

278
windows-driver-utils.sh Normal file
View File

@ -0,0 +1,278 @@
#!/bin/ash
# shellcheck shell=dash
# shellcheck disable=SC3001,SC3010
# reinstall.sh / trans.sh 共用此文件
del_inf_comment() {
sed 's/;.*//'
}
simply_inf() {
del_cr | del_inf_comment | trim | del_empty_lines
}
simply_inf_word() {
# 1 删除引号 "
# 2 删除两边空格
# 3 \ 和 .\ 换成 /
# 4 连续的 / 替换成单个 /
# 5 删除最前面的 /
sed -E \
-e 's,",,g' \
-e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' \
-e 's,\.?\\,/,g' \
-e 's,/+,/,g' \
-e 's,^/,,'
}
# reinstall.sh 下无法判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 true
# trans.sh 下可以判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 false
list_files_from_inf() {
local inf=$1
local arch=$2 # x86 amd64 arm64
local mix_x86_x86_64=$3
# 所有字段不区分大小写
inf_txts=$(simply_inf <"$inf" | to_lower)
is_match_section() {
local section=$1
[ "$line" = "[$section]" ] || [ "$line" = "[$section.$arch]" ] ||
{ $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$line" = "[$section.amd64]" ]; } ||
{ $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$line" = "[$section.x86]" ]; }
}
is_match_catalogfile() {
local left
left=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word)
# catalogfile.nt 是指所有 nt ?
[ "$left" = "catalogfile" ] ||
[ "$left" = "catalogfile.nt" ] ||
[ "$left" = "catalogfile.nt$arch" ] ||
{ $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$left" = "catalogfile.ntamd64" ]; } ||
{ $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$left" = "catalogfile.ntx86" ]; }
}
is_match_manufacturer_arch() {
# x86 可写 NT / NTx86, 其它必须明确架构
# https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer-section
case "$arch" in
x86) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NT|NTx86' ;;
amd64) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NTamd64' ;;
arm64) regex='NTarm64' ;;
esac
# 注意 cut awk 结果不同
# 虽然在这里不会造成影响
# echo 1 | cut -d, -f2-
# 1
# echo 1 | awk -F, '{print $2}'
# 空白
echo "$line" | awk -F, '{for(i=2;i<=NF;i++) print $i}' | grep -Eiwq "$regex"
}
# 还需要从 [Strings] 读取字符串?
# 0. 检测 inf 是否适合当前架构
# 目前没有对比版本号
# 例子1
# [Manufacturer]
# %Amazon% = AWSNVME, NTamd64, NTARM64
# 例子2
# [Manufacturer]
# %MyName% = MyName,NTx86.6.0,NTx86.5.1,
# .
# [MyName.NTx86.6.0] ; Empty section, so this INF does not support
# . ; NT 6.0 and later.
# .
# [MyName.NTx86.5.1] ; Used for NT 5.1 and later
# . ; (but not NT 6.0 and later due to the NTx86.6.0 entry)
# %MyDev% = InstallB,hwid
# .
# [MyName] ; Empty section, so this INF does not support
# . ; Win2000
# .
# 例子3
# 系统自带的驱动,没有 [Manufacturer]
# 例子4
# C:\Windows\INF\wfcvsc.inf
# %StdMfg%=Standard,NTamd64...0x0000001,NTamd64...0x0000002,NTamd64...0x0000003
in_section=false
arch_matched=false
has_manufacturer=false
# 未添加 IFS= 时read 会删除行首行尾的空白字符
while read -r line; do
if [[ "$line" = "["* ]]; then
is_match_section manufacturer && has_manufacturer=true && in_section=true || in_section=false
continue
fi
if $in_section; then
if is_match_manufacturer_arch; then
arch_matched=true
break
fi
fi
done < <(echo "$inf_txts")
if $has_manufacturer && ! $arch_matched; then
return 10
fi
# 1. 输出 .inf 文件名
basename "$inf"
# 2. 输出 .cat 相对路径
# 例子
# [version]
# CatalogFile = "xxxxx.cat"
# CatalogFile.NTAMD64=Balloon.cat
in_section=false
# 未添加 IFS= 时read 会删除行首行尾的空白字符
while read -r line; do
if [[ "$line" = "["* ]]; then
is_match_section version && in_section=true || in_section=false
continue
fi
if $in_section && is_match_catalogfile; then
echo "$line" | awk -F= '{print $2}' | simply_inf_word
fi
done < <(echo "$inf_txts")
# 3. 获取 SourceDisksNames
# 例子
# [SourceDisksNames]
# 1 = "Windows NT CD-ROM",file.tag,, "\common"
SourceDisksNames=
in_section=false
# 未添加 IFS= 时read 会删除行首行尾的空白字符
while read -r line; do
if [[ "$line" = "["* ]]; then
is_match_section sourcedisksnames && in_section=true || in_section=false
continue
fi
# 注意可能有空格和引号
if $in_section; then
num=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word)
dir=$(echo "$line" | awk -F, '{print $4}' | simply_inf_word)
# 每行一条记录
if [ -n "$SourceDisksNames" ]; then
SourceDisksNames="$SourceDisksNames
"
fi
SourceDisksNames="$SourceDisksNames$num:$dir"
fi
done < <(echo "$inf_txts")
# 4. 打印 SourceDisksFiles 的绝对路径
# 例子
# [SourceDisksFiles]
# aha154x.sys = 1 , "\x86" ,,
in_section=false
# 未添加 IFS= 时read 会删除行首行尾的空白字符
while read -r line; do
if [[ "$line" = "["* ]]; then
is_match_section sourcedisksfiles && in_section=true || in_section=false
continue
fi
if $in_section; then
file=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word)
num=$(echo "$line" | awk -F'=|,' '{print $2}' | simply_inf_word)
sub_dir=$(echo "$line" | awk -F, '{print $2}' | simply_inf_word)
# 可能有多个
while IFS= read -r parent_dir; do
echo "$parent_dir/$sub_dir/$file" | simply_inf_word
done < <(echo "$SourceDisksNames" | awk -F: "\$1==\"$num\" {print \$2}")
fi
done < <(echo "$inf_txts")
}
find_file_ignore_case() {
# 同时支持参数和管道
local path
path=$({ if [ -n "$1" ]; then echo "$1"; else cat; fi; })
# 用 / 分割路径,提取成列表
# 例如: ///a///b/c.inf -> a b c.inf
# shellcheck disable=SC2046
set -- $(echo "$path" | grep -o '[^/]*')
(
# windows 安装驱动时,只会安装相同架构的驱动文件到系统,即使 inf 里有列出其它架构的驱动
# 因此导出驱动时,也就不会包含其它架构的驱动文件
# 因此这里只警告,不中断脚本
local output=
if is_absolute_path "$path"; then
cd /
output=/
fi
while [ $# -gt 0 ]; do
local part=$1
# shellcheck disable=SC2010
if part=$(ls -1 | grep -Fix "$part"); then
# 大于 1 表示当前 part 是目录
if [ $# -gt 1 ]; then
if cd "$part"; then
output="$output$part/"
else
warn "Can't cd $path"
return 1
fi
else
# 最后 part
output="$output$part"
fi
else
warn "Can't find $path" >&2
return 1
fi
shift
done
echo "$output"
)
}
parse_inf_and_cp_driever() {
local inf=$1
local dst=$2
local arch=$3
local mix_x86_x86_64=$4
info false "Add driver: $inf"
# 首先创建目录,否则无法通过 ls 文件数得到编号
mkdir -p "$dst"
# shellcheck disable=SC2012
inf_index=$(($(ls -1 "$dst" | wc -l) + 1))
inf_old_dir=$(dirname "$inf")
inf_new_dir=$dst/$inf_index
if driver_files=$(list_files_from_inf "$inf" "$arch" "$mix_x86_x86_64"); then
mkdir -p "$inf_new_dir"
(
cd "$inf_old_dir" || error_and_exit "Can't cd $inf_old_dir"
while read -r file; do
if file=$(find_file_ignore_case "$file"); then
cp -v --parents "$file" "$inf_new_dir"
fi
done < <(echo "$driver_files")
)
else
if [ $? -eq 10 ]; then
warn "$inf arch not match."
else
error_and_exit "Unknown error while parse $inf."
fi
fi
}

View File

@ -22,15 +22,26 @@ rem win8 pe 没有 powercfg
call powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 2>nul
rem 安装 SCSI 驱动
for %%F in ("X:\drivers\*.inf") do (
call :drvload_if_scsi "%%~F"
if exist X:\drivers\ (
for /f "delims=" %%F in ('dir /s /b "X:\drivers\*.inf" 2^>nul') do (
call :drvload_if_scsi "%%~F"
)
rem 官网写了可以安装但仅会加载关键驱动
rem Gcore 的 virtio-gpu 在安装时没有显示
rem 即使安装时加载了显卡驱动
rem 进入系统后才有显示
rem find /i "viogpudo" "%%~F" >nul
rem if not errorlevel 1 (
rem drvload "%%~F"
rem )
)
rem 安装自定义 SCSI 驱动
rem 可以用 forfiles /p X:\custom_drivers /m *.inf /c "cmd /c echo @path"
rem 不可以用 for %%F in ("X:\custom_drivers\*\*.inf")
if exist X:\custom_drivers\ (
for /f "delims=" %%F in ('dir /s /b "X:\custom_drivers\*.inf"') do (
for /f "delims=" %%F in ('dir /s /b "X:\custom_drivers\*.inf" 2^>nul') do (
call :drvload_if_scsi "%%~F"
)
)