mirror of
https://github.com/dockur/windows.git
synced 2025-06-23 16:07:47 +00:00
Compare commits
8 Commits
b1ca283ba8
...
654f7ebaa8
Author | SHA1 | Date | |
---|---|---|---|
|
654f7ebaa8 | ||
|
1f67633120 | ||
|
07de844831 | ||
|
a571ab69cd | ||
|
cea531cf3a | ||
|
5d7f4c9b6e | ||
|
c2012a9e32 | ||
|
2ace98f46d |
@ -11,6 +11,7 @@ RUN set -eu && \
|
|||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get --no-install-recommends -y install \
|
apt-get --no-install-recommends -y install \
|
||||||
bc \
|
bc \
|
||||||
|
jq \
|
||||||
curl \
|
curl \
|
||||||
7zip \
|
7zip \
|
||||||
wsdd \
|
wsdd \
|
||||||
|
@ -102,8 +102,6 @@ kubectl apply -f https://raw.githubusercontent.com/dockur/windows/refs/heads/mas
|
|||||||
| `10` | Windows 10 Pro | 5.7 GB |
|
| `10` | Windows 10 Pro | 5.7 GB |
|
||||||
| `10l` | Windows 10 LTSC | 4.6 GB |
|
| `10l` | Windows 10 LTSC | 4.6 GB |
|
||||||
| `10e` | Windows 10 Enterprise | 5.2 GB |
|
| `10e` | Windows 10 Enterprise | 5.2 GB |
|
||||||
||||
|
|
||||||
| `8` | Windows 8.1 Pro | 4.0 GB |
|
|
||||||
| `8e` | Windows 8.1 Enterprise | 3.7 GB |
|
| `8e` | Windows 8.1 Enterprise | 3.7 GB |
|
||||||
| `7e` | Windows 7 Enterprise | 3.0 GB |
|
| `7e` | Windows 7 Enterprise | 3.0 GB |
|
||||||
| `ve` | Windows Vista Enterprise | 3.0 GB |
|
| `ve` | Windows Vista Enterprise | 3.0 GB |
|
||||||
|
@ -164,7 +164,7 @@ getLanguage() {
|
|||||||
desc="English"
|
desc="English"
|
||||||
culture="en-GB" ;;
|
culture="en-GB" ;;
|
||||||
"en" | "en-"* )
|
"en" | "en-"* )
|
||||||
lang="English (United States)"
|
lang="English"
|
||||||
desc="English"
|
desc="English"
|
||||||
culture="en-US" ;;
|
culture="en-US" ;;
|
||||||
"mx" | "es-mx" )
|
"mx" | "es-mx" )
|
||||||
@ -280,15 +280,15 @@ getLanguage() {
|
|||||||
desc="$lang"
|
desc="$lang"
|
||||||
culture="uk-UA" ;;
|
culture="uk-UA" ;;
|
||||||
"hk" | "zh-hk" | "cn-hk" )
|
"hk" | "zh-hk" | "cn-hk" )
|
||||||
lang="Chinese Traditional"
|
lang="Chinese (Traditional)"
|
||||||
desc="Chinese HK"
|
desc="Chinese HK"
|
||||||
culture="zh-TW" ;;
|
culture="zh-TW" ;;
|
||||||
"tw" | "zh-tw" | "cn-tw" )
|
"tw" | "zh-tw" | "cn-tw" )
|
||||||
lang="Chinese Traditional"
|
lang="Chinese (Traditional)"
|
||||||
desc="Chinese TW"
|
desc="Chinese TW"
|
||||||
culture="zh-TW" ;;
|
culture="zh-TW" ;;
|
||||||
"zh" | "zh-"* | "cn" | "cn-"* )
|
"zh" | "zh-"* | "cn" | "cn-"* )
|
||||||
lang="Chinese Simplified"
|
lang="Chinese (Simplified)"
|
||||||
desc="Chinese"
|
desc="Chinese"
|
||||||
culture="zh-CN" ;;
|
culture="zh-CN" ;;
|
||||||
esac
|
esac
|
||||||
@ -671,10 +671,6 @@ getMido() {
|
|||||||
size=4898582528
|
size=4898582528
|
||||||
sum="e4ab2e3535be5748252a8d5d57539a6e59be8d6726345ee10e7afd2cb89fefb5"
|
sum="e4ab2e3535be5748252a8d5d57539a6e59be8d6726345ee10e7afd2cb89fefb5"
|
||||||
;;
|
;;
|
||||||
"win81x64" )
|
|
||||||
size=4320526336
|
|
||||||
sum="d8333cf427eb3318ff6ab755eb1dd9d433f0e2ae43745312c1cd23e83ca1ce51"
|
|
||||||
;;
|
|
||||||
"win81x64-enterprise-eval" )
|
"win81x64-enterprise-eval" )
|
||||||
size=3961473024
|
size=3961473024
|
||||||
sum="2dedd44c45646c74efc5a028f65336027e14a56f76686a4631cf94ffe37c72f2"
|
sum="2dedd44c45646c74efc5a028f65336027e14a56f76686a4631cf94ffe37c72f2"
|
||||||
@ -766,6 +762,11 @@ getLink1() {
|
|||||||
sum="d8333cf427eb3318ff6ab755eb1dd9d433f0e2ae43745312c1cd23e83ca1ce51"
|
sum="d8333cf427eb3318ff6ab755eb1dd9d433f0e2ae43745312c1cd23e83ca1ce51"
|
||||||
url="8.x/8.1/en_windows_8.1_with_update_x64_dvd_6051480.iso"
|
url="8.x/8.1/en_windows_8.1_with_update_x64_dvd_6051480.iso"
|
||||||
;;
|
;;
|
||||||
|
"win81x64-enterprise" | "win81x64-enterprise-eval" )
|
||||||
|
size=4139163648
|
||||||
|
sum="c3c604c03677504e8905090a8ce5bb1dde76b6fd58e10f32e3a25bef21b2abe1"
|
||||||
|
url="8.x/8.1/en_windows_8.1_enterprise_with_update_x64_dvd_6054382.iso"
|
||||||
|
;;
|
||||||
"win2025" | "win2025-eval" )
|
"win2025" | "win2025-eval" )
|
||||||
size=5307176960
|
size=5307176960
|
||||||
sum="2293897341febdcea599f5412300b470b5288c6fd2b89666a7b27d283e8d3cf3"
|
sum="2293897341febdcea599f5412300b470b5288c6fd2b89666a7b27d283e8d3cf3"
|
||||||
|
88
src/mido.sh
88
src/mido.sh
@ -63,31 +63,33 @@ download_windows() {
|
|||||||
local lang="$2"
|
local lang="$2"
|
||||||
local desc="$3"
|
local desc="$3"
|
||||||
local sku_id=""
|
local sku_id=""
|
||||||
|
local sku_url=""
|
||||||
|
local iso_url=""
|
||||||
|
local iso_json=""
|
||||||
local language=""
|
local language=""
|
||||||
local session_id=""
|
local session_id=""
|
||||||
local user_agent=""
|
local user_agent=""
|
||||||
|
local download_type=""
|
||||||
local windows_version=""
|
local windows_version=""
|
||||||
local iso_download_link=""
|
local iso_download_link=""
|
||||||
|
local download_page_html=""
|
||||||
local product_edition_id=""
|
local product_edition_id=""
|
||||||
local iso_download_link_html=""
|
local language_skuid_json=""
|
||||||
local iso_download_page_html=""
|
local profile="606624d44113"
|
||||||
local language_skuid_table_html=""
|
|
||||||
|
|
||||||
case "${id,,}" in
|
|
||||||
"win11x64" ) windows_version="11" ;;
|
|
||||||
"win10x64" ) windows_version="10" ;;
|
|
||||||
"win81x64" ) windows_version="8" ;;
|
|
||||||
* ) error "Invalid VERSION specified, value \"$id\" is not recognized!" && return 1 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
user_agent=$(get_agent)
|
user_agent=$(get_agent)
|
||||||
language=$(getLanguage "$lang" "name")
|
language=$(getLanguage "$lang" "name")
|
||||||
|
|
||||||
local url="https://www.microsoft.com/en-us/software-download/windows$windows_version"
|
case "${id,,}" in
|
||||||
case "$windows_version" in
|
"win11x64" ) windows_version="11" && download_type="1" ;;
|
||||||
8 | 10) url+="ISO";;
|
"win10x64" ) windows_version="10" && download_type="1" ;;
|
||||||
|
"win11arm64" ) windows_version="11arm64" && download_type="2" ;;
|
||||||
|
* ) error "Invalid VERSION specified, value \"$id\" is not recognized!" && return 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
local url="https://www.microsoft.com/en-us/software-download/windows$windows_version"
|
||||||
|
[[ "${id,,}" == "win10"* ]] && url+="ISO"
|
||||||
|
|
||||||
# uuidgen: For MacOS (installed by default) and other systems (e.g. with no /proc) that don't have a kernel interface for generating random UUIDs
|
# uuidgen: For MacOS (installed by default) and other systems (e.g. with no /proc) that don't have a kernel interface for generating random UUIDs
|
||||||
session_id=$(cat /proc/sys/kernel/random/uuid 2> /dev/null || uuidgen --random)
|
session_id=$(cat /proc/sys/kernel/random/uuid 2> /dev/null || uuidgen --random)
|
||||||
|
|
||||||
@ -96,44 +98,40 @@ download_windows() {
|
|||||||
# This is the *only* request we make that Fido doesn't. Fido manually maintains a list of all the Windows release/edition product edition IDs in its script (see: $WindowsVersions array). This is helpful for downloading older releases (e.g. Windows 10 1909, 21H1, etc.) but we always want to get the newest release which is why we get this value dynamically
|
# This is the *only* request we make that Fido doesn't. Fido manually maintains a list of all the Windows release/edition product edition IDs in its script (see: $WindowsVersions array). This is helpful for downloading older releases (e.g. Windows 10 1909, 21H1, etc.) but we always want to get the newest release which is why we get this value dynamically
|
||||||
# Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden
|
# Also, keeping a "$WindowsVersions" array like Fido does would be way too much of a maintenance burden
|
||||||
# Remove "Accept" header that curl sends by default
|
# Remove "Accept" header that curl sends by default
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo " - Parsing download page: ${url}"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Parsing download page: ${url}"
|
||||||
iso_download_page_html=$(curl --silent --max-time 30 --user-agent "$user_agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
|
download_page_html=$(curl --silent --max-time 30 --user-agent "$user_agent" --header "Accept:" --max-filesize 1M --fail --proto =https --tlsv1.2 --http1.1 -- "$url") || {
|
||||||
handle_curl_error $?
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting Product edition ID: "
|
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting Product edition ID: "
|
||||||
# tr: Filter for only numerics to prevent HTTP parameter injection
|
product_edition_id=$(echo "$download_page_html" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16)
|
||||||
# head -c was recently added to POSIX: https://austingroupbugs.net/view.php?id=407
|
|
||||||
product_edition_id=$(echo "$iso_download_page_html" | grep -Eo '<option value="[0-9]+">Windows' | cut -d '"' -f 2 | head -n 1 | tr -cd '0-9' | head -c 16)
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "$product_edition_id"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "$product_edition_id"
|
||||||
|
|
||||||
|
if [ -z "$product_edition_id" ]; then
|
||||||
|
error "Product edition ID not found!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Permit Session ID: $session_id"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Permit Session ID: $session_id"
|
||||||
# Permit Session ID
|
# Permit Session ID
|
||||||
# "org_id" is always the same value
|
|
||||||
curl --silent --max-time 30 --output /dev/null --user-agent "$user_agent" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://vlscppe.microsoft.com/tags?org_id=y6jn8c31&session_id=$session_id" || {
|
curl --silent --max-time 30 --output /dev/null --user-agent "$user_agent" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://vlscppe.microsoft.com/tags?org_id=y6jn8c31&session_id=$session_id" || {
|
||||||
# This should only happen if there's been some change to how this API works
|
# This should only happen if there's been some change to how this API works
|
||||||
handle_curl_error $?
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# Extract everything after the last slash
|
|
||||||
local url_segment_parameter="${url##*/}"
|
|
||||||
|
|
||||||
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting language SKU ID: "
|
[[ "$DEBUG" == [Yy1]* ]] && echo -n "Getting language SKU ID: "
|
||||||
# Get language -> skuID association table
|
sku_url="https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=$profile&ProductEditionId=$product_edition_id&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=$session_id"
|
||||||
# SKU ID: This specifies the language of the ISO. We always use "English (United States)", however, the SKU for this changes with each Windows release
|
language_skuid_json=$(curl --silent --max-time 30 --request GET --user-agent "$user_agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$sku_url") || {
|
||||||
# We must make this request so our next one will be allowed
|
|
||||||
# --data "" is required otherwise no "Content-Length" header will be sent causing HTTP response "411 Length Required"
|
|
||||||
language_skuid_table_html=$(curl --silent --max-time 30 --request POST --user-agent "$user_agent" --data "" --header "Accept:" --max-filesize 10K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/en-US/api/controls/contentinclude/html?pageId=a8f8f489-4c7f-463a-9ca6-5cff94d8d041&host=www.microsoft.com&segments=software-download,$url_segment_parameter&query=&action=getskuinformationbyproductedition&sessionId=$session_id&productEditionId=$product_edition_id&sdVersion=2") || {
|
|
||||||
handle_curl_error $?
|
handle_curl_error $?
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# tr: Filter for only alphanumerics or "-" to prevent HTTP parameter injection
|
{ sku_id=$(echo "$language_skuid_json" | jq --arg LANG "$language" -r '.Skus[] | select(.Language==$LANG).Id') 2>/dev/null; rc=$?; } || :
|
||||||
sku_id=$(echo "$language_skuid_table_html" | grep -m 1 ">${language}<" | sed 's/"//g' | cut -d ',' -f 1 | cut -d ':' -f 2 | tr -cd '[:alnum:]-' | head -c 16)
|
|
||||||
|
|
||||||
if [ -z "$sku_id" ]; then
|
if [ -z "$sku_id" ] || [[ "${sku_id,,}" == "null" ]] || (( rc != 0 )); then
|
||||||
language=$(getLanguage "$lang" "desc")
|
language=$(getLanguage "$lang" "desc")
|
||||||
error "No download in the $language language available for $desc!"
|
error "No download in the $language language available for $desc!"
|
||||||
return 1
|
return 1
|
||||||
@ -144,28 +142,31 @@ download_windows() {
|
|||||||
|
|
||||||
# Get ISO download link
|
# Get ISO download link
|
||||||
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
|
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
|
||||||
# --referer: Required by Microsoft servers to allow request
|
|
||||||
iso_download_link_html=$(curl --silent --max-time 30 --request POST --user-agent "$user_agent" --data "" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/en-US/api/controls/contentinclude/html?pageId=6e2a1789-ef16-4f27-a296-74ef7ef5d96b&host=www.microsoft.com&segments=software-download,$url_segment_parameter&query=&action=GetProductDownloadLinksBySku&sessionId=$session_id&skuId=$sku_id&language=English&sdVersion=2")
|
|
||||||
|
|
||||||
if ! [ "$iso_download_link_html" ]; then
|
iso_url="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$sku_id&friendlyFileName=undefined&Locale=en-US&sessionID=$session_id"
|
||||||
|
iso_json=$(curl --silent --max-time 30 --request GET --user-agent "$user_agent" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_url")
|
||||||
|
|
||||||
|
if ! [ "$iso_json" ]; then
|
||||||
# This should only happen if there's been some change to how this API works
|
# This should only happen if there's been some change to how this API works
|
||||||
error "Microsoft servers gave us an empty response to our request for an automated download."
|
error "Microsoft servers gave us an empty response to our request for an automated download."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo "$iso_download_link_html" | grep -q "We are unable to complete your request at this time."; then
|
if echo "$iso_json" | grep -q "Sentinel marked this request as rejected."; then
|
||||||
error "Microsoft blocked the automated download request based on your IP address."
|
error "Microsoft blocked the automated download request based on your IP address."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Filter for 64-bit ISO download URL
|
if echo "$iso_json" | grep -q "We are unable to complete your request at this time."; then
|
||||||
# sed: HTML decode "&" character
|
error "Microsoft blocked the automated download request based on your IP address."
|
||||||
# tr: Filter for only alphanumerics or punctuation
|
return 1
|
||||||
iso_download_link=$(echo "$iso_download_link_html" | grep -o "https://software.download.prss.microsoft.com.*IsoX64" | cut -d '"' -f 1 | sed 's/&/\&/g' | tr -cd '[:alnum:][:punct:]')
|
fi
|
||||||
|
|
||||||
if ! [ "$iso_download_link" ]; then
|
{ iso_download_link=$(echo "$iso_json" | jq --argjson TYPE "$download_type" -r '.ProductDownloadOptions[] | select(.DownloadType==$TYPE).Uri') 2>/dev/null; rc=$?; } || :
|
||||||
# This should only happen if there's been some change to the download endpoint web address
|
|
||||||
|
if [ -z "$iso_download_link" ] || [[ "${iso_download_link,,}" == "null" ]] || (( rc != 0 )); then
|
||||||
error "Microsoft servers gave us no download link to our request for an automated download!"
|
error "Microsoft servers gave us no download link to our request for an automated download!"
|
||||||
|
info "Response: $iso_json"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -283,8 +284,8 @@ download_windows_eval() {
|
|||||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Found download link: $iso_download_link"
|
[[ "$DEBUG" == [Yy1]* ]] && echo "Found download link: $iso_download_link"
|
||||||
|
|
||||||
# Follow redirect so proceeding log message is useful
|
# Follow redirect so proceeding log message is useful
|
||||||
# This is a request we make this Fido doesn't
|
# This is a request we make that Fido doesn't
|
||||||
# We don't need to set "--max-filesize" here because this is a HEAD request and the output is to /dev/null anyway
|
|
||||||
iso_download_link=$(curl --silent --max-time 30 --user-agent "$user_agent" --location --output /dev/null --silent --write-out "%{url_effective}" --head --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_download_link") || {
|
iso_download_link=$(curl --silent --max-time 30 --user-agent "$user_agent" --location --output /dev/null --silent --write-out "%{url_effective}" --head --fail --proto =https --tlsv1.2 --http1.1 -- "$iso_download_link") || {
|
||||||
# This should only happen if the Microsoft servers are down
|
# This should only happen if the Microsoft servers are down
|
||||||
handle_curl_error $?
|
handle_curl_error $?
|
||||||
@ -317,6 +318,7 @@ getWindows() {
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
case "${version,,}" in
|
case "${version,,}" in
|
||||||
|
"win11${PLATFORM,,}" ) ;;
|
||||||
"win11${PLATFORM,,}-enterprise-iot"* ) ;;
|
"win11${PLATFORM,,}-enterprise-iot"* ) ;;
|
||||||
"win11${PLATFORM,,}-enterprise-ltsc"* ) ;;
|
"win11${PLATFORM,,}-enterprise-ltsc"* ) ;;
|
||||||
* )
|
* )
|
||||||
@ -327,7 +329,7 @@ getWindows() {
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
case "${version,,}" in
|
case "${version,,}" in
|
||||||
"win81${PLATFORM,,}" | "win10${PLATFORM,,}" | "win11${PLATFORM,,}" )
|
"win10${PLATFORM,,}" | "win11${PLATFORM,,}" )
|
||||||
download_windows "$version" "$lang" "$edition" && return 0
|
download_windows "$version" "$lang" "$edition" && return 0
|
||||||
;;
|
;;
|
||||||
"win11${PLATFORM,,}-enterprise"* | "win10${PLATFORM,,}-enterprise"* )
|
"win11${PLATFORM,,}-enterprise"* | "win10${PLATFORM,,}-enterprise"* )
|
||||||
|
Loading…
Reference in New Issue
Block a user