Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
98 contributors

Users who have contributed to this file

@austin987 @kakurasan @bobwya @mihaitodor @ShannonVanWagner @gverm @eli-schwartz @zfigura @jre-wine @vszakats @AndreRH @hillwoodroc @qwertychouskie @mmmaisel @birdie-github @dhewg @slackner @lifanov @TotalCaesar659 @vanillajonathan @njlyf2011 @adrianbroher @davispuh @wdlkmpx @Lantizia @ukos-git
executable file 21675 lines (18646 sloc) 781 KB
#!/bin/sh
# shellcheck disable=SC2030,SC2031
# SC2030: Modification of WINE is local (to subshell caused by (..) group).
# SC2031: WINE was modified in a subshell. That change might be lost
# This has to be right after the shebang, see: https://github.com/koalaman/shellcheck/issues/779
# Name of this version of winetricks (YYYYMMDD)
# (This doesn't change often, use the sha256sum of the file when reporting problems)
WINETRICKS_VERSION=20190615-next
# This is a UTF-8 file
# You should see an o with two dots over it here [ö]
# You should see a micro (u with a tail) here [µ]
# You should see a trademark symbol here [™]
#--------------------------------------------------------------------
#
# Winetricks is a package manager for Win32 dlls and applications on POSIX.
# Features:
# - Consists of a single shell script - no installation required
# - Downloads packages automatically from original trusted sources
# - Points out and works around known wine bugs automatically
# - Both command-line and GUI operation
# - Can install many packages in silent (unattended) mode
# - Multiplatform; written for Linux, but supports OS X and Cygwin too
#
# Uses the following non-POSIX system tools:
# - wine is used to execute Win32 apps except on Cygwin.
# - ar, cabextract, unrar, unzip, and 7z are needed by some verbs.
# - aria2c, wget, curl, or fetch is needed for downloading.
# - fuseiso, archivemount (Linux), or hdiutil (macOS) is used to mount .iso images.
# - perl is used to munge steam config files.
# - pkexec, sudo, or kdesu (gksu/gksudo/kdesudo are deprecated upstream but also still supported)
# are used to mount .iso images if the user cached them with -k option.
# - sha256sum, sha256, or shasum (OSX 10.5 does not support these, 10.6+ is required)
# - torify is used with option "--torify" if sites are blocked in single countries.
# - xdg-open (if present) or open (for OS X) is used to open download pages
# for the user when downloads cannot be fully automated.
# - xz is used by some verbs to decompress tar archives.
# - zenity is needed by the GUI, though it can limp along somewhat with kdialog/xmessage.
#
# On Ubuntu, the following line can be used to install all the prerequisites:
# sudo apt install aria2 binutils cabextract fuseiso p7zip-full policykit-1 tor unrar unzip wine xdg-utils xz-utils zenity
#
# On Fedora, these commands can be used (RPM Fusion is used to install unrar):
# sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
# sudo dnf install binutils cabextract fuseiso p7zip-plugins polkit tor unrar unzip wget wine xdg-utils xz zenity
#
# See https://github.com/Winetricks/winetricks for documentation and tutorials,
# including how to contribute changes to winetricks.
#
#--------------------------------------------------------------------
#
# Copyright:
# Copyright (C) 2007-2014 Dan Kegel <dank!kegel.com>
# Copyright (C) 2008-2019 Austin English <austinenglish!gmail.com>
# Copyright (C) 2010-2011 Phil Blankenship <phillip.e.blankenship!gmail.com>
# Copyright (C) 2010-2015 Shannon VanWagner <shannon.vanwagner!gmail.com>
# Copyright (C) 2010 Belhorma Bendebiche <amro256!gmail.com>
# Copyright (C) 2010 Eleazar Galano <eg.galano!gmail.com>
# Copyright (C) 2010 Travis Athougies <iammisc!gmail.com>
# Copyright (C) 2010 Andrew Nguyen
# Copyright (C) 2010 Detlef Riekenberg
# Copyright (C) 2010 Maarten Lankhorst
# Copyright (C) 2010 Rico Schüller
# Copyright (C) 2011 Scott Jackson <sjackson2!gmx.com>
# Copyright (C) 2011 Trevor Johnson
# Copyright (C) 2011 Franco Junio
# Copyright (C) 2011 Craig Sanders
# Copyright (C) 2011 Matthew Bauer <mjbauer95>
# Copyright (C) 2011 Giuseppe Dia
# Copyright (C) 2011 Łukasz Wojniłowicz
# Copyright (C) 2011 Matthew Bozarth
# Copyright (C) 2013-2017 Andrey Gusev <andrey.goosev!gmail.com>
# Copyright (C) 2013-2017 Hillwood Yang <hillwood!opensuse.org>
# Copyright (C) 2013,2016 André Hentschel <nerv!dawncrow.de>
#
# License:
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
#--------------------------------------------------------------------
# Coding standards:
#
# Portability:
# - Portability matters, as this script is run on many operating systems
# - No bash, zsh, or csh extensions; only use features from
# the POSIX standard shell and utilities; see
# https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
# - 'checkbashisms -p -x winetricks' should show no warnings (per Debian policy)
# - Prefer classic sh idioms as described in e.g.
# "Portable Shell Programming" by Bruce Blinn, ISBN: 0-13-451494-7
# - If there is no universally available program for a needed function,
# support the two most frequently available programs.
# e.g. fall back to wget if curl is not available; likewise, support
# both sha256sum and sha256.
# - When using Unix commands like cp, put options before filenames so it will
# work on systems like OS X. e.g. "rm -f foo.dat", not "rm foo.dat -f"
#
# Formatting:
# - Your terminal and editor must be configured for UTF-8
# If you do not see an o with two dots over it here [ö], stop!
# - Do not use tabs in this file or any verbs.
# - Indent 4 spaces.
# - Try to keep line length below 80 (makes printing easier)
# - Open curly braces ('{'),
# then should go on the same line as 'if/elif'
# close curlies ('}') and 'fi' should line up with the matching { or if,
# cases indented 4 spaces from 'case' and 'esac'. For instance,
#
# if test "$FOO" = "bar"; then
# echo "FOO is bar"
# fi
#
# case "$FOO" in
# bar) echo "FOO is still bar" ;;
# esac
#
# Commenting:
# - Comments should explain intent in English
# - Keep functions short and well named to reduce need for comments
#
# Naming:
# Public things defined by this script, for use by verbs:
# - Variables have uppercase names starting with W_
# - Functions have lowercase names starting with w_
#
# Private things internal to this script, not for use by verbs:
# - Local variables have lowercase names starting with uppercase _W_
# (and should not use the local declaration, as it is not POSIX)
# - Global variables have uppercase names starting with WINETRICKS_
# - Functions have lowercase names starting with winetricks_
# FIXME: A few verbs still use winetricks-private functions or variables.
#
# Internationalization / localization:
# - Important or frequently used message should be internationalized
# so translations can be easily added. For example:
# case $LANG in
# de*) echo "Das ist die deutsche Meldung" ;;
# *) echo "This is the English message" ;;
# esac
#
# Support:
# - Winetricks is maintained by Austin English <austinenglish!$gmail.com>.
# - If winetricks has helped you out, then please consider donating to the FSF/EFF as a thank you:
# * EFF - https://supporters.eff.org/donate/button
# * FSF - https://my.fsf.org/donate
# - Donations towards electricity bill and developer beer fund can be sent via Bitcoin to 18euSAZztpZ9wcN6xZS3vtNnE1azf8niDk
# - I try to actively respond to bugs and pull requests on GitHub:
# - Bugs: https://github.com/Winetricks/winetricks/issues/new
# - Pull Requests: https://github.com/Winetricks/winetricks/pulls
#--------------------------------------------------------------------
# FIXME: XDG_CACHE_HOME is defined twice, clean this up
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
W_COUNTRY=""
W_PREFIXES_ROOT="${WINE_PREFIXES:-$XDG_DATA_HOME/wineprefixes}"
# For temp files before $WINEPREFIX is available:
if [ -x "$(command -v mktemp 2>/dev/null)" ] ; then
W_TMP_EARLY="$(mktemp -d "${TMPDIR:-/tmp}/winetricks.XXXXXXXX")"
elif [ -w "$TMPDIR" ] ; then
W_TMP_EARLY="$TMPDIR"
else
W_TMP_EARLY="/tmp"
fi
#---- Public Functions ----
# Ask permission to continue
w_askpermission()
{
echo "------------------------------------------------------"
echo "$@"
echo "------------------------------------------------------"
if test "$W_OPT_UNATTENDED"; then
_W_timeout="--timeout 5"
fi
case $WINETRICKS_GUI in
zenity) $WINETRICKS_GUI "$_W_timeout" --question --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')" --no-wrap;;
kdialog) $WINETRICKS_GUI --title winetricks --warningcontinuecancel "$@" ;;
none)
if [ -n "$_W_timeout" ]; then
# -t / TMOUT don't seem to be portable, so just assume yes in unattended mode
w_info "Unattended mode, not prompting for confirmation"
else
printf %s "Press Y or N, then Enter: "
read -r response
test "$response" = Y || test "$response" = y
fi
esac
if test $? -ne 0; then
case $LANG in
uk*) w_die "Операція скасована." ;;
pl*) w_die "Anulowano operację, opuszczanie." ;;
*) w_die "Operation cancelled, quitting." ;;
esac
exec false
fi
unset _W_timeout
}
# Display info message. Time out quickly if user doesn't click.
w_info()
{
# If $WINETRICKS_SUPER_QUIET is set, w_info is a no-op:
if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
echo "------------------------------------------------------"
echo "$@"
echo "------------------------------------------------------"
fi
_W_timeout="--timeout 3"
case $WINETRICKS_GUI in
zenity) $WINETRICKS_GUI "$_W_timeout" --info --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')" --no-wrap;;
kdialog) $WINETRICKS_GUI --title winetricks --msgbox "$@" ;;
none) ;;
esac
unset _W_timeout
}
# Display warning message to stderr (since it is called inside redirected code)
w_warn()
{
# If $WINETRICKS_SUPER_QUIET is set, w_info is a no-op:
if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
echo "------------------------------------------------------"
echo "$@"
echo "------------------------------------------------------"
fi
if test "$W_OPT_UNATTENDED"; then
_W_timeout="--timeout 5"
fi
case $WINETRICKS_GUI in
zenity) $WINETRICKS_GUI "$_W_timeout" --error --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')";;
kdialog) $WINETRICKS_GUI --title winetricks --error "$@" ;;
none) ;;
esac
unset _W_timeout
}
# Display warning message to stderr (since it is called inside redirected code)
# And give gui user option to cancel (for when used in a loop)
# If user cancels, exit status is 1
w_warn_cancel()
{
echo "------------------------------------------------------" >&2
echo "$@" >&2
echo "------------------------------------------------------" >&2
if test "$W_OPT_UNATTENDED"; then
_W_timeout="--timeout 5"
fi
# Zenity has no cancel button, but will set status to 1 if you click the go-away X
case $WINETRICKS_GUI in
zenity) $WINETRICKS_GUI "$_W_timeout" --error --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')";;
kdialog) $WINETRICKS_GUI --title winetricks --warningcontinuecancel "$@" ;;
none) ;;
esac
# can't unset, it clears status
}
# Display fatal error message and terminate script
w_die()
{
w_warn "$@"
exit 1
}
# Kill all instances of a process in a safe way (Solaris killall kills _everything_)
w_killall()
{
# shellcheck disable=SC2046,SC2086
kill -s KILL $(pgrep $1)
}
# Some packages don't support win32, die with an appropriate message
# Returns 64 (for tests/winetricks-test)
w_package_unsupported_win32()
{
if [ "$W_ARCH" = "win32" ] ; then
w_warn "This package ($W_PACKAGE) does not work on a 32-bit installation. You must use a prefix made with WINEARCH=win64."
exit 64
fi
}
# Warn user if package is broken. Optionally provide a link to the bug report.
w_package_broken_win64()
{
# Optional:
bug_link="$1"
if [ "$W_ARCH" = "win64" ] ; then
if [ -n "$1" ] ; then
w_die "This package ($W_PACKAGE) is broken on 64-bit Wine. Using a prefix made with WINEARCH=win32 to work around this. See: ${bug_link}"
else
w_die "This package ($W_PACKAGE) is broken on 64-bit Wine. Using a prefix made with WINEARCH=win32 to work around this."
fi
fi
}
# Some packages don't support win64, die with an appropriate message
# Note: this is for packages that natively don't support win64, not packages that are broken on wine64, for that, use w_package_broken_win64()
# Returns 32 (for tests/winetricks-test)
w_package_unsupported_win64()
{
if [ "$W_ARCH" = "win64" ] ; then
case $LANG in
pl*) w_warn "Ten pakiet ($W_PACKAGE) nie działa z 64-bitową instalacją. Musisz użyć prefiksu utworzonego z WINEARCH=win32." ;;
ru*) w_warn "Данный пакет не работает в 64-битном окружении. Используйте префикс, созданный с помощью WINEARCH=win32." ;;
*) w_warn "This package ($W_PACKAGE) does not work on a 64-bit installation. You must use a prefix made with WINEARCH=win32." ;;
esac
exit 32
fi
}
# For packages that are not well tested or have some known issues on win64, but aren't broken
w_package_warn_win64()
{
if [ "$W_ARCH" = "win64" ] ; then
case $LANG in
pl*) w_warn "Ten pakiet ($W_PACKAGE) może nie działać poprawnie z 64-bitową instalacją. Prefiks 32-bitowy może działąć lepiej." ;;
ru*) w_warn "Данный пакет может работать не полностью в 64-битном окружении. 32-битные префиксы могут работать лучше." ;;
*) w_warn "This package ($W_PACKAGE) may not fully work on a 64-bit installation. 32-bit prefixes may work better." ;;
esac
fi
}
### w_try and w_try wrappers ###
# Execute with error checking
# Put this in front of any command that might fail
w_try()
{
# "VAR=foo w_try cmd" fails to put VAR in the environment
# with some versions of bash if w_try is a shell function?!
# This is a problem when trying to pass environment variables to e.g. wine.
# Adding an explicit export here works around it, so add any we use.
export WINEDLLOVERRIDES
# If $WINETRICKS_SUPER_QUIET is set, make w_try quiet
if [ -z "$WINETRICKS_SUPER_QUIET" ]; then
printf '%s\n' "Executing $*"
fi
# On Vista, we need to jump through a few hoops to run commands in Cygwin.
# First, .exe's need to have the executable bit set.
# Second, only cmd can run setup programs (presumably for security).
# If $1 ends in .exe, we know we're running on real Windows, otherwise
# $1 would be 'wine'.
case "$1" in
*.exe)
chmod +x "$1" || true # don't care if it fails
cmd /c "$@"
;;
*)
"$@"
;;
esac
status=$?
if test $status -ne 0; then
case $LANG in
pl*) w_die "Informacja: poelcenie $* zwróciło status $status. Przerywam." ;;
ru*) w_die "Важно: команда $* вернула статус $status. Прерывание." ;;
*) w_die "Note: command $* returned status $status. Aborting." ;;
esac
fi
}
w_try_7z()
{
# $1 - directory to extract to
# $2 - file to extract
# $3 .. $n - files to extract from the archive
destdir="$1"
filename="$2"
shift 2
# Not always installed, use Windows 7-Zip as a fallback:
if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v 7z 2>/dev/null)" ] ; then
w_try 7z x "$filename" -o"$destdir" "$@"
else
w_warn "Cannot find 7z. Using Windows 7-Zip instead. (You can avoid this by installing 7z, e.g. 'sudo apt-get install p7zip-full' or 'sudo yum install p7zip-plugins')."
WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip
# errors out if there is a space between -o and path
w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" x "$(w_pathconv -w "$filename")" -o"$(w_pathconv -w "$destdir")" "$@"
fi
}
w_try_ar()
{
# $1 - ar file (.deb) to extract (keeping internal paths, in cwd)
# $2 - file to extract (optional)
# Not always installed, use Windows 7-zip as a fallback:
if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v ar 2>/dev/null)" ]; then
w_try ar x "$@"
else
w_warn "Cannot find ar. Using Windows 7-zip instead. (You can avoid this by installing binutils, e.g. 'sudo apt-get install binutils' or 'sudo yum install binutils')."
WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip
# -t* prevents 7-zip from decompressing .tar.xz to .tar, see
# https://sourceforge.net/p/sevenzip/discussion/45798/thread/8cd16946/?limit=25
w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" -t* x "$(w_pathconv -w "$1")"
fi
}
w_try_cabextract()
{
# Not always installed, but shouldn't be fatal unless it's being used
if test ! -x "$(command -v cabextract 2>/dev/null)"; then
w_die "Cannot find cabextract. Please install it (e.g. 'sudo apt-get install cabextract' or 'sudo yum install cabextract')."
fi
w_try cabextract -q "$@"
}
w_try_cd()
{
w_try cd "$@"
}
# Copy font files matching a glob pattern from source directory to destination directory.
# Also remove any file in the destination directory that has the same name as
# any of the files that we're trying to copy, but with different case letters.
# Note: it converts font file names to lower case to avoid inconsistencies due to paths
# being case-insensitive under Wine.
w_try_cp_font_files()
{
# $1 - source directory
# $2 - destination directory
# $3 - optional font file glob pattern (default: "*.ttf")
_W_src_dir="$1"
_W_dest_dir="$2"
_W_pattern="$3"
shift 2
if test ! -d "$_W_src_dir"; then
w_die "bug: missing source dir"
fi
if test ! -d "$_W_dest_dir"; then
w_die "bug: missing destination dir"
fi
if test -z "$_W_pattern"; then
_W_pattern="*.ttf"
fi
# POSIX sh doesn't have a good way to handle this, but putting into a separate script
# and running with sh avoids it.
#
# See https://github.com/Winetricks/winetricks/issues/995 for details
cat > "$WINETRICKS_WORKDIR/cp_font_files.sh" <<_EOF_
#!/bin/sh
_W_src_file="\$@"
# Extract the file name and lower case it
_W_file_name="\$(basename "\$_W_src_file" | tr "[:upper:]" "[:lower:]")"
# Remove any existing font files that might have the same name, but with different case characters
find "$_W_dest_dir" -maxdepth 1 -type f -iname "\$_W_file_name" -exec rm '{}' ';'
# FIXME: w_try() isn't available, need some better error handling:
cp -f "\$_W_src_file" "$_W_dest_dir/\$_W_file_name"
_EOF_
chmod +x "$WINETRICKS_WORKDIR/cp_font_files.sh"
find "$_W_src_dir" -maxdepth 1 -type f -iname "$_W_pattern" -exec "$WINETRICKS_WORKDIR/cp_font_files.sh" {} \;
# Wait for Wine to add the new font to the registry under HKCU\Software\Wine\Fonts\Cache
w_wineserver -w
unset _W_dest_dir
}
w_try_msiexec64()
{
if test "$W_ARCH" != "win64"; then
w_die "bug: 64-bit msiexec called from a $W_ARCH prefix."
fi
# shellcheck disable=SC2086
w_try "$WINE" start /wait "$W_SYSTEM64_DLLS_WIN32/msiexec.exe" $W_UNATTENDED_SLASH_Q "$@"
}
w_try_regedit()
{
# If on wow64, run under both wine and wine64 (otherwise they only go in the 32-bit registry afaict)
# shellcheck disable=SC2086
if [ "$W_ARCH" = "win32" ]; then
w_try_regedit32 "$@"
elif [ "$W_ARCH" = "win64" ]; then
w_try_regedit32 "$@"
w_try_regedit64 "$@"
fi
}
# fixme: cleanup. For wow64 registries, some/all entries need to be duplicated.
# Not sure of the best way yet, but thinking running wine/wine64 regedit for each?
w_try_regedit32()
{
# on windows, doesn't work without cmd /c
case "$W_PLATFORM" in
windows_cmd|wine_cmd) cmdc="cmd /c";;
*) unset cmdc ;;
esac
# shellcheck disable=SC2086
w_try "$WINE_MULTI" $cmdc regedit $W_UNATTENDED_SLASH_S "$@"
}
w_try_regedit64()
{
# on windows, doesn't work without cmd /c
case "$W_PLATFORM" in
windows_cmd|wine_cmd) cmdc="cmd /c";;
*) unset cmdc ;;
esac
# shellcheck disable=SC2086
w_try "$WINE64" $cmdc regedit $W_UNATTENDED_SLASH_S "$@"
}
w_try_regsvr()
{
# shellcheck disable=SC2086
w_try "$WINE" regsvr32 $W_UNATTENDED_SLASH_S "$@"
}
w_try_regsvr64()
{
# shellcheck disable=SC2086
w_try "$WINE64" regsvr32 $W_UNATTENDED_SLASH_S "$@"
}
w_try_unrar()
{
# $1 - zipfile to extract (keeping internal paths, in cwd)
# Not always installed, use Windows 7-Zip as a fallback:
if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v unrar 2>/dev/null)" ]; then
w_try unrar x "$@"
else
w_warn "Cannot find unrar. Using Windows 7-Zip instead. (You can avoid this by installing unrar, e.g. 'sudo apt-get install unrar' or 'sudo yum install unrar')."
WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip
w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" x "$(w_pathconv -w "$1")"
fi
}
w_try_unzip()
{
# $1 - directory to extract to
# $2 - zipfile to extract
# $3 .. $n - files to extract from the archive
destdir="$1"
zipfile="$2"
shift 2
# Not always installed, use Windows 7-Zip as a fallback:
if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v unzip 2>/dev/null)" ]; then
# FreeBSD ships unzip, but it doesn't support self-compressed executables
# If it fails, fall back to 7-Zip:
unzip -o -q -d"$destdir" "$zipfile" "$@"
ret=$?
case $ret in
0) return ;;
1|*) w_warn "Unzip failed, trying Windows 7-Zip instead." ;;
esac
else
w_warn "Cannot find unzip. Using Windows 7-Zip instead. (You can avoid this by installing unzip, e.g. 'sudo apt-get install unzip' or 'sudo yum install unzip')."
fi
WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip
# errors out if there is a space between -o and path
w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" x "$(w_pathconv -w "$zipfile")" -o"$(w_pathconv -w "$destdir")" "$@"
}
### End of w_try ###
w_read_key()
{
if test ! "$W_OPT_UNATTENDED"; then
W_KEY=dummy_to_make_autohotkey_happy
return 0
fi
mkdir -p "$W_CACHE/$W_PACKAGE"
# backwards compatible location
# Auth doesn't belong in cache, since restoring it requires user input
_W_keyfile="$W_CACHE/$W_PACKAGE/key.txt"
if ! test -f "$_W_keyfile"; then
_W_keyfile="$WINETRICKS_AUTH/$W_PACKAGE/key.txt"
fi
if ! test -f "$_W_keyfile"; then
# read key from user
case $LANG in
da*) _W_keymsg="Angiv venligst registrerings-nøglen for pakken '$W_PACKAGE'"
_W_nokeymsg="Ingen nøgle angivet"
;;
de*) _W_keymsg="Bitte einen Key für Paket '$W_PACKAGE' eingeben"
_W_nokeymsg="Keinen Key eingegeben?"
;;
pl*) _W_keymsg="Proszę podać klucz dla programu '$W_PACKAGE'"
_W_nokeymsg="Nie podano klucza"
;;
ru*) _W_keymsg="Пожалуйста, введите ключ для приложения '$W_PACKAGE'"
_W_nokeymsg="Ключ не введён"
;;
uk*) _W_keymsg="Будь ласка, введіть ключ для додатка '$W_PACKAGE'"
_W_nokeymsg="Ключ не надано"
;;
zh_CN*) _W_keymsg="按任意键为 '$W_PACKAGE'"
_W_nokeymsg="No key given"
;;
zh_TW*|zh_HK*) _W_keymsg="按任意鍵為 '$W_PACKAGE'"
_W_nokeymsg="No key given"
;;
*) _W_keymsg="Please enter the key for app '$W_PACKAGE'"
_W_nokeymsg="No key given"
;;
esac
case $WINETRICKS_GUI in
*zenity) W_KEY=$(zenity --entry --text "$_W_keymsg") ;;
*kdialog) W_KEY=$(kdialog --inputbox "$_W_keymsg") ;;
*xmessage) w_die "sorry, can't read key from GUI with xmessage" ;;
none) printf %s "$_W_keymsg": ; read -r W_KEY ;;
esac
if test "$W_KEY" = ""; then
w_die "$_W_nokeymsg"
fi
echo "$W_KEY" > "$_W_keyfile"
fi
W_RAW_KEY=$(cat "$_W_keyfile")
W_KEY=$(echo "$W_RAW_KEY" | tr -d '[:blank:][=-=]')
unset _W_keyfile _W_keymsg _W_nokeymsg
}
w_verify_cabextract_available()
{
# If verb_a requires verb_b, then verba will fail when the dependency for verb_b is installed
# This should be called by verb_a, to give a proper warning
w_try_cabextract -q -v
}
# Convert a Windows path to a Unix path quickly.
# $1 is an absolute Windows path starting with c:\ or C:/
# with no funny business, so we can use the simplest possible
# algorithm.
winetricks_wintounix()
{
_W_winp_="$1"
# Remove drive letter and colon
_W_winp="${_W_winp_#??}"
# Prepend the location of drive c
printf %s "$WINEPREFIX"/dosdevices/c:
# Change backslashes to slashes
echo "$_W_winp" | sed 's,\\,/,g'
}
# Convert between Unix path and Windows path
# Usage is lowest common denominator of cygpath/winepath
# so -u to convert to Unix, and -w to convert to Windows
w_pathconv()
{
case "$W_PLATFORM" in
windows_cmd)
# for some reason, cygpath turns some spaces into newlines?!
cygpath "$@" | tr '\012' '\040' | sed 's/ $//'
;;
*)
case "$@" in
-u?c:\\*|-u?C:\\*|-u?c:/*|-u?C:/*) winetricks_wintounix "$2" ;;
*) winetricks_early_wine winepath "$@" ;;
esac
;;
esac
}
# Expand an environment variable and print it to stdout
w_expand_env()
{
winetricks_early_wine cmd.exe /c echo "%$1%"
}
# Get the latest tagged release from github.com API
w_get_github_latest_release()
{
# $1 - github organization
# $2 - github repository
# FIXME: can we get releases that aren't on master branch?
WINETRICKS_SUPER_QUIET=1 w_download_to "${W_TMP_EARLY}" "https://api.github.com/repos/$1/$2/releases/latest" "" "release.json" >/dev/null 2>&1
# aria2c condenses the json (https://github.com/aria2/aria2/issues/1389)
# but curl/wget don't, so handle both cases:
json_length="$(wc -l "${W_TMP_EARLY}/release.json")"
case "$json_length" in
0*) latest_version="$(sed -e "s/\",\"/|/g" "${W_TMP_EARLY}/release.json" | tr '|' '\n' | grep tag_name | sed 's@.*"@@')";;
*) latest_version="$(grep -w tag_name "${W_TMP_EARLY}/release.json" | cut -d '"' -f 4)";;
esac
echo "$latest_version"
}
# get sha256sum string and set $_W_gotsha256sum to it
w_get_sha256sum()
{
_W_sha256_file="$1"
# See https://github.com/Winetricks/winetricks/issues/645
# User is running winetricks from /dev/stdin
if [ -f "$_W_sha256_file" ] || [ -h "$_W_sha256_file" ] ; then
_W_gotsha256sum=$($WINETRICKS_SHA256SUM < "$_W_sha256_file" | sed 's/(stdin)= //;s/ .*//')
else
w_warn "$_W_sha256_file is not a regular file, not checking sha256sum"
return
fi
}
w_get_shatype() {
_W_sum="$1"
# tr -d " " is for FreeBSD/OS X/Solaris return a leading space:
# See https://stackoverflow.com/questions/30927590/wc-on-osx-return-includes-spaces/30927885#30927885
_W_sum_length="$(echo "$_W_sum" | tr -d "\\n" | wc -c | tr -d " ")"
case "$_W_sum_length" in
0) _W_shatype="none" ;;
64) _W_shatype="sha256" ;;
# 128) sha512..
*) w_die "unsupported shasum..bug" ;;
esac
}
# verify a sha256sum
w_verify_sha256sum()
{
_W_vs_wantsum=$1
_W_vs_file=$2
w_get_sha256sum "$_W_vs_file"
if [ "$_W_gotsha256sum"x != "$_W_vs_wantsum"x ] ; then
case $LANG in
pl*) w_die "Niezgodność sumy sha256sum! Zmień nazwę $_W_vs_file i spróbuj ponownie." ;;
ru*) w_die "Контрольная сумма sha256sum не совпадает! Переименуйте файл $_W_vs_file и попробуйте еще раз." ;;
*) w_die "sha256sum mismatch! Rename $_W_vs_file and try again." ;;
esac
fi
unset _W_vs_wantsum _W_vs_file _W_gotsha256sum
}
# verify any kind of shasum (that winetricks supports ;) ):
w_verify_shasum()
{
_W_vs_wantsum="$1"
_W_vs_file="$2"
w_get_shatype "$_W_vs_wantsum"
case "$_W_shatype" in
none) w_warn "No checksum provided, not verifying" ;;
sha256) w_verify_sha256sum "$_W_sum" "$_W_vs_file" ;;
# 128) sha512..
*) w_die "unsupported shasum..bug" ;;
esac
}
# wget outputs progress messages that look like this:
# 0K .......... .......... .......... .......... .......... 0% 823K 40s
# This function replaces each such line with the pair of lines
# 0%
# # Downloading... 823K (40s)
# It uses minimal buffering, so each line is output immediately
# and the user can watch progress as it happens.
# wrapper around wineserver, to let users know that it will wait indefinitely/kill stuff
w_wineserver()
{
case "$@" in
*-k) w_warn "Running $WINESERVER -k. This will kill all running wine processes in prefix=$WINEPREFIX";;
*-w) w_warn "Running $WINESERVER -w. This will hang until all wine processes in prefix=$WINEPREFIX terminate";;
*) w_warn "Invoking wineserver with '$*'";;
esac
# shellcheck disable=SC2068
"$WINESERVER" $@
}
winetricks_parse_wget_progress()
{
# Parse a percentage, a size, and a time into $1, $2 and $3
# then use them to create the output line.
case $LANG in
pl*) perl -p -e \
'$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Pobieranie… \2 (\3)/' ;;
ru*) perl -p -e \
'$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Загрузка... \2 (\3)/' ;;
*) perl -p -e \
'$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Downloading... \2 (\3)/' ;;
esac
}
# Execute wget, and if in GUI mode, also show a graphical progress bar
winetricks_wget_progress()
{
case $WINETRICKS_GUI in
zenity)
# Use a subshell so if the user clicks 'Cancel',
# the --auto-kill kills the subshell, not the current shell
(
${torify} wget "$@" 2>&1 |
winetricks_parse_wget_progress | \
$WINETRICKS_GUI --progress --width 400 --title="$_W_file" --auto-kill --auto-close
)
err=$?
if test $err -gt 128; then
# 129 is 'killed by SIGHUP'
# Sadly, --auto-kill only applies to parent process,
# which was the subshell, not all the elements of the pipeline...
# have to go find and kill the wget.
# If we ran wget in the background, we could kill it more directly, perhaps...
if pid=$(pgrep -f ."$_W_file"); then
echo User aborted download, killing wget
# shellcheck disable=SC2086
kill $pid
fi
fi
return $err
;;
*) ${torify} wget "$@" ;;
esac
}
w_dotnet_verify()
{
case "$1" in
dotnet11) version="1.1" ;;
dotnet11sp1) version="1.1 SP1" ;;
dotnet20) version="2.0" ;;
dotnet20sp1) version="2.0 SP1" ;;
dotnet20sp2) version="2.0 SP2" ;;
dotnet30) version="3.0" ;;
dotnet30sp1) version="3.0 SP1" ;;
dotnet35) version="3.5" ;;
dotnet35sp1) version="3.5 SP1" ;;
dotnet40) version="4 Client" ;;
dotnet45) version="4.5" ;;
dotnet452) version="4.5.2" ;;
dotnet46) version="4.6" ;;
dotnet461) version="4.6.1" ;;
dotnet462) version="4.6.2" ;;
dotnet471) version="4.7.1" ;;
dotnet472) version="4.7.2" ;;
dotnet48) version="4.8" ;;
*) echo error ; exit 1 ;;
esac
w_call dotnet_verifier
# FIXME: The logfile may be useful somewhere (or at least print the location)
# for 'run, netfx_setupverifier.exe /q:a /c:"setupverifier2.exe"' line
# shellcheck disable=SC2140
w_ahk_do "
SetTitleMatchMode, 2
; FIXME; this only works the first time? Check if it's already verified somehow..
run, netfx_setupverifier.exe /q:a /c:"setupverifier2.exe"
winwait, Verification Utility
ControlClick, Button1
Control, ChooseString, NET Framework $version, ComboBox1
ControlClick, Button1 ; Verify
loop, 60
{
sleep 1000
process, exist, setupverifier2.exe
dn_pid=%ErrorLevel%
if dn_pid = 0
{
break
}
ifWinExist, Verification Utility, Product verification failed
{
process, close, setupverifier2.exe
exit 1
}
ifWinExist, Verification Utility, Product verification succeeded
{
process, close, setupverifier2.exe
break
}
}
"
dn_status="$?"
w_info ".Net Verifier returned $dn_status"
}
# Checks if the user can run the self-update/rollback commands
winetricks_check_update_availability()
{
# Prevents the development file overwrite:
if test -d "../.git"; then
w_warn "You're running in a dev environment. Please make a copy of the file before running this command."
exit
fi
# Checks read/write permissions on update directories
if ! { test -r "$0" && test -w "$0" && test -w "${0%/*}" && test -x "${0%/*}"; }; then
w_warn "You don't have the proper permissions to run this command. Try again with sudo or as root."
exit
fi
}
winetricks_selfupdate()
{
winetricks_check_update_availability
_W_filename="${0##*/}"
_W_rollback_file="${0}.bak"
_W_update_file="${0}.update"
_W_tmpdir=${TMPDIR:-/tmp}
_W_tmpdir="$(mktemp -d "$_W_tmpdir/$_W_filename.XXXXXXXX")"
w_download_to "$_W_tmpdir" https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
# 2016/10/26: now file is uncompressed? Handle both cases:
update_file_type="$(file "$_W_tmpdir/$_W_filename")"
case "$update_file_type" in
*"POSIX shell script"*)
#echo "already decompressed!"
w_try mv "$_W_tmpdir/$_W_filename" "${_W_update_file}"
;;
*"gzip compressed data"*)
w_try mv "$_W_tmpdir/$_W_filename" "${_W_update_file}.gz"
w_try gunzip "${_W_update_file}.gz"
;;
*)
echo "Unknown file type: $update_file_type"
exit 1
;;
esac
w_try rmdir "$_W_tmpdir"
w_try cp "$0" "$_W_rollback_file"
w_try chmod -x "$_W_rollback_file"
w_try mv "$_W_update_file" "$0"
w_try chmod +x "$0"
w_warn "Update finished! The current version is $($0 -V). Use 'winetricks --update-rollback' to return to the previous version."
exit
}
winetricks_selfupdate_rollback()
{
winetricks_check_update_availability
_W_rollback_file="${0}.bak"
if test -f "$_W_rollback_file"; then
w_try mv "$_W_rollback_file" "$0"
w_try chmod +x "$0"
w_warn "Rollback finished! The current version is $($0 -V)."
else
w_warn "Nothing to rollback."
fi
exit;
}
# Download a file
# Usage: w_download_to (packagename|path to download file) url [shasum [filename [cookie jar]]]
# Caches downloads in winetrickscache/$packagename
w_download_to()
{
winetricks_download_setup
_W_packagename="$1" # or path to download file to
_W_url="$2"
_W_sum="$3"
_W_file="$4"
_W_cookiejar="$5"
case $_W_packagename in
.) w_die "bug: please do not download packages to top of cache" ;;
esac
if echo "$_W_url" | grep ' ' ; then
w_die "bug: please use %20 instead of literal spaces in urls, curl rejects spaces, and they make life harder for linkcheck.sh"
fi
if [ "$_W_file"x = ""x ] ; then
_W_file=$(basename "$_W_url")
fi
w_get_shatype "$_W_sum"
if echo "${_W_packagename}" | grep -q -e '\/-' -e '^-'; then
w_die "Invalid path ${_W_packagename} given"
else
if ! echo "${_W_packagename}" | grep -q '^/' ; then
_W_cache="$W_CACHE/$_W_packagename"
else
_W_cache="$_W_packagename"
fi
fi
if test ! -d "$_W_cache" ; then
w_try mkdir -p "$_W_cache"
fi
# Try download twice
checksum_ok=""
tries=0
# Set olddir before entering the loop, otherwise second try will overwrite
_W_dl_olddir=$(pwd)
while test $tries -lt 2 ; do
# Warn on a second try
test "$tries" -eq 1 && winetricks_dl_warning
tries=$((tries + 1))
if test -s "$_W_cache/$_W_file" ; then
if test "$_W_sum" ; then
if test $tries = 1 ; then
# The cache was full. If the file is larger than 500 MB,
# don't checksum it, that just annoys the user.
# shellcheck disable=SC2046
if test $(du -k "$_W_cache/$_W_file" | cut -f1) -gt 500000 ; then
checksum_ok=1
break
fi
fi
# If checksum matches, declare success and exit loop
case "$_W_shatype" in
none)
w_warn "No checksum provided, not verifying"
;;
sha256)
w_get_sha256sum "$_W_cache/$_W_file"
if [ "$_W_gotsha256sum"x = "$_W_sum"x ] ; then
checksum_ok=1
break
fi
;;
esac
if test ! "$WINETRICKS_CONTINUE_DOWNLOAD" ; then
case $LANG in
pl*) w_warn "Niezgodność sum kontrolnych dla $_W_cache/$_W_file, pobieram ponownie" ;;
ru*) w_warn "Контрольная сумма файла $_W_cache/$_W_file не совпадает, попытка повторной загрузки" ;;
*) w_warn "Checksum for $_W_cache/$_W_file did not match, retrying download" ;;
esac
mv -f "$_W_cache/$_W_file" "$_W_cache/$_W_file".bak
fi
else
# file exists, no checksum known, declare success and exit loop
break
fi
elif test -f "$_W_cache/$_W_file" ; then
# zero-length file, just delete before retrying
rm "$_W_cache/$_W_file"
fi
w_try_cd "$_W_cache"
# Mac folks tend to have curl rather than wget
# On Mac, 'which' doesn't return good exit status
echo "Downloading $_W_url to $_W_cache"
# For sites that prefer Mozilla in the user-agent header, set W_BROWSERAGENT=1
case "$W_BROWSERAGENT" in
1) _W_agent="Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" ;;
*) _W_agent="" ;;
esac
if [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then
# Note: aria2c wants = for most options or silently fails
# (Slightly fancy) aria2c support
# See https://github.com/Winetricks/winetricks/issues/612
# --daemon=false --enable-rpc=false to ensure aria2c doesnt go into the background after starting
# and prevent any attempts to rebind on the RPC interface specified in someone's config.
# --input-file='' if the user config has a input-file specified then aria2 will read it and
# attempt to download everything in that input file again.
# --save-session='' if the user has specified save-session in their config, their session will be
# ovewritten by the new aria2 process
# shellcheck disable=SC2086
$torify aria2c \
$aria2c_torify_opts \
--connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \
--continue \
--daemon=false \
--dir="$_W_cache" \
--enable-rpc=false \
--input-file='' \
--max-connection-per-server=5 \
--max-tries="$WINETRICKS_DOWNLOADER_RETRIES" \
--out="$_W_file" \
--save-session='' \
--stream-piece-selector=geom \
"$_W_url"
elif [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then
# Use -nd to insulate ourselves from people who set -x in WGETRC
# [*] --retry-connrefused works around the broken sf.net mirroring
# system when downloading corefonts
# [*] --read-timeout is useful on the adobe server that doesn't
# close the connection unless you tell it to (control-C or closing
# the socket)
# shellcheck disable=SC2086
winetricks_wget_progress \
-O "$_W_file" \
-nd \
-c\
--read-timeout 300 \
--retry-connrefused \
--timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
--tries "$WINETRICKS_DOWNLOADER_RETRIES" \
${_W_cookiejar:+--load-cookies "$_W_cookiejar"} \
${_W_agent:+--user-agent="$_W_agent"} \
"$_W_url"
elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then
# Note: curl does not accept '=' when passing options
# curl doesn't get filename from the location given by the server!
# fortunately, we know it
# shellcheck disable=SC2086
$torify curl \
--connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
-L \
-o "$_W_file" \
-C - \
--retry "$WINETRICKS_DOWNLOADER_RETRIES" \
${_W_cookiejar:+--cookie "$_W_cookiejar"} \
${_W_agent:+--user-agent "$_W_agent"} \
"$_W_url"
elif [ "${WINETRICKS_DOWNLOADER}" = "fetch" ] ; then
# Note: fetch does not support configurable retry count
# shellcheck disable=SC2086
$torify fetch \
-T "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
-o "$_W_file" \
${_W_agent:+--user-agent="$_W_agent"} \
"$_W_url"
else
w_die "Here be dragons"
fi
if test $? = 0; then
# Need to decompress .exe's that are compressed, else Cygwin fails
# Also affects ttf files on github
# FIXME: gzip hack below may no longer be needed, but need to investigate before removing
_W_filetype=$(command -v file 2>/dev/null)
case $_W_filetype-$_W_file in
/*-*.exe|/*-*.ttf|/*-*.zip)
case $(file "$_W_file") in
*:*gzip*) mv "$_W_file" "$_W_file.gz"; gunzip < "$_W_file.gz" > "$_W_file";;
esac
esac
# On Cygwin, .exe's must be marked +x
case "$_W_file" in
*.exe) chmod +x "$_W_file" ;;
esac
w_try_cd "$_W_dl_olddir"
unset _W_dl_olddir
# downloaded successfully, exit from loop
break
elif test $tries = 2; then
test -f "$_W_file" && rm "$_W_file"
w_die "Downloading $_W_url failed"
fi
# Download from the Wayback Machine on second try
_W_url="https://web.archive.org/web/2000/$_W_url"
done
if test "$_W_sum" && test ! "$checksum_ok"; then
w_verify_shasum "$_W_sum" "$_W_cache/$_W_file"
fi
}
# Open a folder for the user in the specified directory
# Usage: w_open_folder directory
w_open_folder()
{
for _W_cmd in xdg-open open cygstart true ; do
_W_cmdpath=$(command -v $_W_cmd)
if test -n "$_W_cmdpath" ; then
break
fi
done
$_W_cmd "$1" &
unset _W_cmd _W_cmdpath
}
# Open a web browser for the user to the given page
# Usage: w_open_webpage url
w_open_webpage()
{
# See https://www.dwheeler.com/essays/open-files-urls.html
for _W_cmd in xdg-open sdtwebclient cygstart open firefox true ; do
_W_cmdpath=$(command -v $_W_cmd)
if test -n "$_W_cmdpath" ; then
break
fi
done
$_W_cmd "$1" &
unset _W_cmd _W_cmdpath
}
# Download a file
# Usage: w_download url [shasum [filename [cookie jar]]]
# Caches downloads in winetrickscache/$W_PACKAGE
w_download()
{
w_download_to "$W_PACKAGE" "$@"
}
# Download one or more files via BitTorrent
# Usage: w_download_torrent [foo.torrent]
# Caches downloads in $W_CACHE/$W_PACKAGE, torrent files are assumed to be there
# If no foo.torrent is given, will add ALL .torrent files in $W_CACHE/$W_PACKAGE
w_download_torrent()
{
# FIXME: figure out how to extract the filename from the .torrent file
# so callers don't need to check if the files are already downloaded.
w_call utorrent
UT_WINPATH="$W_CACHE_WIN\\$W_PACKAGE"
w_try_cd "$W_CACHE/$W_PACKAGE"
if [ "$2"x != ""x ] ; then # foo.torrent parameter supplied
w_try "$WINE" utorrent "/DIRECTORY" "$UT_WINPATH" "$UT_WINPATH\\$2" &
else # grab all torrents
for torrent in *.torrent ; do
w_try "$WINE" utorrent "/DIRECTORY" "$UT_WINPATH" "$UT_WINPATH\\$torrent" &
done
fi
# Start uTorrent, have it wait until all downloads are finished
w_ahk_do "
SetTitleMatchMode, 2
winwait, Torrent
Loop
{
sleep 6000
ifwinexist, Torrent, default
{
;should uTorrent be the default torrent app?
controlclick, Button1, Torrent, default ; yes
continue
}
ifwinexist, Torrent, already
{
;torrent already registered, fine
controlclick, Button1, Torrent, default ; yes
continue
}
ifwinexist, Torrent, Bandwidth
{
;Cancels bandwidth test on first run of uTorrent
controlclick, Button5, Torrent, Bandwidth
continue
}
ifwinexist, Torrent, version
{
;Decline upgrade to newer version
controlclick, Button3, Torrent, version
controlclick, Button2, Torrent, version
continue
}
break
}
;Sets parameter to close uTorrent once all downloads are complete
winactivate, Torrent 2.0
send !o
send a{Down}{Enter}
winwaitclose, Torrent 2.0
"
}
w_download_manual_to()
{
_W_packagename="$1"
_W_url="$2"
_W_file="$3"
_W_shasum="$4"
# shellcheck disable=SC2154
case "$media" in
"download") w_info "FAIL: bug: media type is download, but w_download_manual was called. Programmer, please change verb's media type to manual_download." ;;
esac
if ! test -f "$W_CACHE/$_W_packagename/$_W_file"; then
case $LANG in
da*) _W_dlmsg="Hent venligst filen $_W_file fra $_W_url og placér den i $W_CACHE/$_W_packagename, kør derefter dette skript.";;
de*) _W_dlmsg="Bitte laden Sie $_W_file von $_W_url runter, stellen Sie's in $W_CACHE/$_W_packagename, dann wiederholen Sie dieses Kommando.";;
pl*) _W_dlmsg="Proszę pobrać plik $_W_file z $_W_url, następnie umieścić go w $W_CACHE/$_W_packagename, a na końcu uruchomić ponownie ten skrypt.";;
ru*) _W_dlmsg="Пожалуйста, скачайте файл $_W_file по адресу $_W_url, и поместите его в $W_CACHE/$_W_packagename, а затем запустите winetricks заново.";;
uk*) _W_dlmsg="Будь ласка, звантажте $_W_file з $_W_url, розташуйте в $W_CACHE/$_W_packagename, потім запустіть скрипт знову.";;
zh_CN*) _W_dlmsg="请从 $_W_url 下载 $_W_file,并置放于 $W_CACHE/$_W_packagename, 然后重新运行 winetricks.";;
zh_TW*|zh_HK*) _W_dlmsg="請從 $_W_url 下載 $_W_file,并置放於 $W_CACHE/$_W_packagename, 然后重新執行 winetricks.";;
*) _W_dlmsg="Please download $_W_file from $_W_url, place it in $W_CACHE/$_W_packagename, then re-run this script.";;
esac
mkdir -p "$W_CACHE/$_W_packagename"
w_open_folder "$W_CACHE/$_W_packagename"
w_open_webpage "$_W_url"
sleep 3 # give some time for web browser to open
w_die "$_W_dlmsg"
# FIXME: wait in loop until file is finished?
fi
if test "$_W_shasum"; then
w_verify_shasum "$_W_shasum" "$W_CACHE/$_W_packagename/$_W_file"
fi
unset _W_dlmsg _W_file _W_sha256sum _W_url
}
w_download_manual()
{
w_download_manual_to "$W_PACKAGE" "$@"
}
# Turn off news, overlays, and friend interaction in Steam
# Run from inside C:\Program Files\Steam
w_steam_safemode()
{
cat > "$W_TMP/steamconfig.pl" <<"_EOF_"
#!/usr/bin/env perl
# Parse Steam's localconfig.vcf, add settings to it, and write it out again
# The file is a recursive dictionary
#
# FILE :== CONTAINER
#
# VALUE :== "name" "value" NEWLINE
#
# CONTAINER :== "name" NEWLINE "{" NEWLINE ( VALUE | CONTAINER ) * "}" NEWLINE
#
# We load it into a recursive hash.
use strict;
use warnings;
sub read_into_container{
my( $pcontainer ) = @_;
$_ = <FILE> || w_die "Can't read first line of container";
/{/ || w_die "First line of container was not {";
while (<FILE>) {
chomp;
if (/"([^"]*)"\s*"([^"]*)"$/) {
${$pcontainer}{$1} = $2;
} elsif (/"([^"]*)"$/) {
my( %newcon, $name );
$name = $1;
read_into_container(\%newcon);
${$pcontainer}{$name} = \%newcon;
} elsif (/}/) {
return;
} else {
w_die "huh?";
}
}
}
sub dump_container{
my( $pcontainer, $indent ) = @_;
foreach (sort(keys(%{$pcontainer}))) {
my( $val ) = ${$pcontainer}{$_};
if (ref $val eq 'HASH') {
print "${indent}\"$_\"\n";
print "${indent}{\n";
dump_container($val, "$indent\t");
print "${indent}}\n";
} else {
print "${indent}\"${_}\"\t\t\"$val\"\n";
}
}
}
# Disable anything unsafe or annoying
sub disable_notifications{
my( $pcontainer ) = @_;
${$pcontainer}{"friends"}{"PersonaStateDesired"} = "1";
${$pcontainer}{"friends"}{"Notifications_ShowIngame"} = "0";
${$pcontainer}{"friends"}{"Sounds_PlayIngame"} = "0";
${$pcontainer}{"friends"}{"Notifications_ShowOnline"} = "0";
${$pcontainer}{"friends"}{"Sounds_PlayOnline"} = "0";
${$pcontainer}{"friends"}{"Notifications_ShowMessage"} = "0";
${$pcontainer}{"friends"}{"Sounds_PlayMessage"} = "0";
${$pcontainer}{"friends"}{"AutoSignIntoFriends"} = "0";
${$pcontainer}{"News"}{"NotifyAvailableGames"} = "0";
${$pcontainer}{"system"}{"EnableGameOverlay"} = "0";
}
# Read the file
my(%top);
open FILE, $ARGV[0] || w_die "cannot open ".$ARGV[0];
my($line);
$line = <FILE> || w_die "Could not read first line from ".$ARGV[0];
$line =~ /"UserLocalConfigStore"/ || w_die "this is not a localconfig.vdf file";
read_into_container(\%top);
# Modify it
disable_notifications(\%top);
# Write modified file
print "\"UserLocalConfigStore\"\n";
print "{\n";
dump_container(\%top, "\t");
print "}\n";
_EOF_
for file in userdata/*/config/localconfig.vdf ; do
cp "$file" "$file.old"
perl "$W_TMP"/steamconfig.pl "$file.old" > "$file"
done
}
w_question()
{
case $WINETRICKS_GUI in
*zenity) $WINETRICKS_GUI --entry --text "$1" ;;
*kdialog) $WINETRICKS_GUI --inputbox "$1" ;;
*xmessage) w_die "sorry, can't ask question with xmessage" ;;
none)
# Using printf instead of echo because we don't want a newline
printf "%s" "$1" >&2 ;
read -r W_ANSWER ;
echo "$W_ANSWER";
unset W_ANSWER;;
esac
}
# Reads steam username and password from environment, cache, or user
# If had to ask user, cache answer.
w_steam_getid()
{
#TODO: Translate
_W_steamidmsg="Please enter your Steam login ID (not email)"
_W_steampasswordmsg="Please enter your Steam password"
if test ! "$W_STEAM_ID"; then
if test -f "$W_CACHE"/steam_userid.txt; then
W_STEAM_ID=$(cat "$W_CACHE"/steam_userid.txt)
else
W_STEAM_ID=$(w_question "$_W_steamidmsg")
echo "$W_STEAM_ID" > "$W_CACHE"/steam_userid.txt
chmod 600 "$W_CACHE"/steam_userid.txt
fi
fi
if test ! "$W_STEAM_PASSWORD"; then
if test -f "$W_CACHE"/steam_password.txt; then
W_STEAM_PASSWORD=$(cat "$W_CACHE"/steam_password.txt)
else
W_STEAM_PASSWORD=$(w_question "$_W_steampasswordmsg")
echo "$W_STEAM_PASSWORD" > "$W_CACHE"/steam_password.txt
chmod 600 "$W_CACHE"/steam_password.txt
fi
fi
}
# Usage:
# w_steam_install_game steamidnum windowtitle
w_steam_install_game()
{
_W_steamid=$1
_W_steamtitle="$2"
w_steam_getid
# Install the steam runtime
WINETRICKS_OPT_SHAREDPREFIX=1 w_call steam
# Steam puts up a bunch of windows. Here's the sequence:
# "Steam - Updating" - wait for it to close. May appear twice in a row.
# "Steam - Login" - wait for it to close (credentials already given on cmdline)
# "Steam" (small window) - connecting, wait for it to close
# "Steam" (large window) - the main window
# "Steam - Updates News" - close it forcefully
# "Install - $title" - send enter, click a couple checkboxes, send enter again
# "Updating $title" - small download progress dialog
# "Steam - Ready" game install done. (Only comes up if main window not up.)
w_try_cd "$W_PROGRAMS_X86_UNIX/Steam"
w_ahk_do "
SetTitleMatchMode 2
SetWinDelay 500
; Run steam once until it finishes its initial update.
; For me, this exits at 26%.
run steam.exe -applaunch $_W_steamid -login $W_STEAM_ID $W_STEAM_PASSWORD
Loop
{
ifWinExist, Steam - Updating
{
winwaitclose, Steam
process close, Steam.exe
sleep 1000
; Run a second time; let it finish updating, then kill it.
run steam.exe
winwait Steam - Updating
winwaitclose
process close, Steam.exe
; Run a third time, have it log in, wait until it has finished connecting
run steam.exe -applaunch $_W_steamid -login $W_STEAM_ID $W_STEAM_PASSWORD
}
ifWinExist, Steam Login
{
break
}
sleep 500
}
; wait for login window to close
winwaitclose
winwait Steam ; wait for small <<connecting>> window
winwaitclose
"
if [ "$STEAM_DVD" = "TRUE" ]
then
w_ahk_do "
; Run a fourth time, have it install the app.
run steam.exe -install ${W_ISO_MOUNT_LETTER}:\\
"
else
w_ahk_do "
; Run a fourth time, have it install the app.
run steam.exe -applaunch $_W_steamid
"
fi
w_ahk_do "
winwait Install - $_W_steamtitle
if ( w_opt_unattended > 0 ) {
send {enter} ; next (for 1st of 3 pages of install dialog)
sleep 1000
click 32, 91 ; uncheck create menu item?
click 32, 119 ; check create desktop icon?
send {enter} ; next (for 2nd of 3 pages of install dialog)
; dismiss any news dialogs, and click 'next' on third page of install dialog
loop
{
sleep 1000
ifwinexist Steam - Updates News
{
winclose
continue
}
ifwinexist Install - $_W_steamtitle
{
winactivate
send {enter} ; next (for 3rd of 3 pages of install dialog)
}
ifwinnotexist Install - $_W_steamtitle
{
sleep 1000
ifwinnotexist Install - $_W_steamtitle
break
}
}
}
"
if [ "$STEAM_DVD" = "TRUE" ]
then
# Wait for install to finish
while true
do
grep "SetHasAllLocalContent(true) called for $_W_steamid" "$W_PROGRAMS_X86_UNIX/Steam/logs/download_log.txt" && break
sleep 5
done
fi
w_ahk_do "
; For DVD's: theoretically, it should be installed now, but most games want to download updates. Do that now.
; For regular downloads: relaunch to coax steam into showing its nice small download progress dialog
process close, Steam.exe
run steam.exe -login $W_STEAM_ID $W_STEAM_PASSWORD -applaunch $_W_steamid
winwait Ready -
process close, Steam.exe
"
# Not all users need this disabled, but let's play it safe for now
if w_workaround_wine_bug 22053 "Disabling in-game notifications to prevent game crashes on some machines."; then
w_steam_safemode
fi
unset _W_steamid _W_steamtitle
}
#----------------------------------------------------------------
# Usage: w_mount "volume name" [filename-to-check [discnum]]
# Some games have two volumes with identical volume names.
# For these, please specify discnum 1 for first disc, discnum 2 for 2nd, etc.,
# else caching can't work.
# FIXME: should take mount option 'unhide' for poorly mastered discs
w_mount()
{
if test "$3"; then
WINETRICKS_IMG="$W_CACHE/$W_PACKAGE/$1-$3.iso"
else
WINETRICKS_IMG="$W_CACHE/$W_PACKAGE/$1.iso"
fi
mkdir -p "$W_CACHE/$W_PACKAGE"
if test -f "$WINETRICKS_IMG"; then
winetricks_mount_cached_iso
else
if test "$WINETRICKS_OPT_KEEPISOS" = 0 || test "$2"; then
while true
do
winetricks_mount_real_volume "$1"
if test "$2" = "" || test -f "$W_ISO_MOUNT_ROOT/$2"; then
break
else
w_warn "Wrong disc inserted, $2 not found."
fi
done
fi
case "$WINETRICKS_OPT_KEEPISOS" in
1)
winetricks_cache_iso "$1"
winetricks_mount_cached_iso
;;
esac
fi
}
w_umount()
{
if test "$WINE" = ""; then
# Windows
winetricks_load_vcdmount
w_try_cd "$VCD_DIR"
w_try vcdmount.exe /u
else
if test "$W_USE_USERMOUNT"; then
# FUSE-based tools or hdiutil
if test -d "$W_ISO_USER_MOUNT_ROOT"; then
"$WINE" eject "${W_ISO_MOUNT_LETTER}:"
cat > "$W_TMP"/unset_type_cdrom.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives]
"${W_ISO_MOUNT_LETTER}:"=-
_EOF_
w_try_regedit "$W_TMP"/unset_type_cdrom.reg
rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"
case "$WINETRICKS_ISO_MOUNT" in
hdiutil)
"$WINETRICKS_ISO_MOUNT" detach "$W_ISO_USER_MOUNT_ROOT"
;;
*)
# -uz lazy unmount in case executable still running
fusermount -uz "$W_ISO_USER_MOUNT_ROOT"
;;
esac
w_try rmdir "$W_ISO_USER_MOUNT_ROOT"
fi
W_ISO_MOUNT_ROOT=/mnt/winetricks
else
# sudo + umount
echo "Running $WINETRICKS_SUDO umount $W_ISO_MOUNT_ROOT"
case "$WINETRICKS_SUDO" in
gksu*|kdesudo)
# -l lazy unmount in case executable still running
"$WINETRICKS_SUDO" "umount -l $W_ISO_MOUNT_ROOT"
w_try "$WINETRICKS_SUDO" "rm -rf $W_ISO_MOUNT_ROOT"
;;
kdesu)
"$WINETRICKS_SUDO" -c "umount -l $W_ISO_MOUNT_ROOT"
w_try "$WINETRICKS_SUDO" -c "rm -rf $W_ISO_MOUNT_ROOT"
;;
*)
"$WINETRICKS_SUDO" umount -l "$W_ISO_MOUNT_ROOT"
w_try "$WINETRICKS_SUDO" rm -rf "$W_ISO_MOUNT_ROOT"
;;
esac
"$WINE" eject "${W_ISO_MOUNT_LETTER}:"
rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"
fi
fi
}
w_ahk_do()
{
if ! test -f "$W_CACHE/ahk/AutoHotkey.exe"; then
w_download_to ahk https://github.com/AutoHotkey/AutoHotkey/releases/download/v1.0.48.05/AutoHotkey104805_Install.exe 4311c3e7c29ed2d67f415138360210bc2f55ff78758b20b003b91d775ee207b9
w_try_7z "$W_CACHE/ahk" "$W_CACHE/ahk/AutoHotkey104805_Install.exe" AutoHotkey.exe AU3_Spy.exe
chmod +x "$W_CACHE/ahk/AutoHotkey.exe"
fi
# Previously this used printf + sed, but that was broken with BSD sed (FreeBSD/OS X):
# https://github.com/Winetricks/winetricks/issues/697
# So now using trying awk instead (next, perl):
cat <<_EOF_ | awk 'sub("$", "\r")' > "$W_TMP"/tmp.ahk
w_opt_unattended = ${W_OPT_UNATTENDED:-0}
$@
_EOF_
w_try "$WINE" "$W_CACHE_WIN\\ahk\\AutoHotkey.exe" "$W_TMP_WIN"\\tmp.ahk
}
# Function to protect Wine-specific sections of code.
# Outputs a message to console explaining what's being skipped.
# Usage:
# if w_skip_windows name-of-operation; then
# return
# fi
# ... do something that doesn't make sense on Windows ...
w_skip_windows()
{
case "$W_PLATFORM" in
windows_cmd)
echo "Skipping operation '$1' on Windows"
return 0
;;
esac
return 1
}
# for common code in w_override_dlls and w_override_app_dlls
w_common_override_dll()
{
_W_mode="$1"
module="$2"
# Remove wine's builtin manifest, if present. Use:
# wineboot ; find "$WINEPREFIX"/drive_c/windows/winsxs/ -iname \*deadbeef.manifest | sort
case "$W_PACKAGE" in
comctl32)
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest
;;
vcrun2005)
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
# These are 32-bit only?
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.mfcloc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.openmp_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest
;;
vcrun2008)
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc90.atl_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.atl_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
# These are 32-bit only?
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.mfc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.mfcloc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.openmp_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
;;
esac
if [ "$_W_mode" = default ] ; then
# To delete a registry key, give an unquoted dash as value
echo "\"*$module\"=-" >> "$W_TMP"/override-dll.reg
else
# Note: if you want to override even DLLs loaded with an absolute
# path, you need to add an asterisk:
echo "\"*$module\"=\"$_W_mode\"" >> "$W_TMP"/override-dll.reg
fi
}
w_override_dlls()
{
w_skip_windows w_override_dlls && return
_W_mode=$1
case $_W_mode in
*=*)
w_die "w_override_dlls: unknown mode $_W_mode.
Usage: 'w_override_dlls mode[,mode] dll ...'." ;;
disabled)
_W_mode="" ;;
esac
shift
echo "Using $_W_mode override for following DLLs: $*"
cat > "$W_TMP"/override-dll.reg <<_EOF_
REGEDIT4
[HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides]
_EOF_
while test "$1" != ""
do
w_common_override_dll "$_W_mode" "$1"
shift
done
w_try_regedit "$W_TMP_WIN"\\override-dll.reg
unset _W_mode
}
w_override_no_dlls()
{
w_skip_windows override && return
"$WINE" regedit /d 'HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides'
}
w_override_all_dlls()
{
# Disable all known native Microsoft DLLs in favor of Wine's built-in ones
# Generated with:
# find ./dlls -maxdepth 1 -type d ! -iname "*.dll16" ! -iname "*.drv*" ! -iname "*.ds" ! -iname "*.exe*" ! -iname "*.tlb" ! -iname "*.vxd" -print | sed \
# -e '/^.*\/adsiid$/ d' \
# -e '/^.*\/advapi32$/ d' \
# -e '/^.*\/capi2032$/ d' \
# -e '/^.*\/dbghelp$/ d' \
# -e '/^.*\/ddraw$/ d' \
# -e '/^.*\/dlls$/ d' \
# -e '/^.*\/dmoguids$/ d' \
# -e '/^.*\/dxerr8$/ d' \
# -e '/^.*\/dxerr9$/ d' \
# -e '/^.*\/dxguid$/ d' \
# -e '/^.*\/gdi32$/ d' \
# -e '/^.*\/glu32$/ d' \
# -e '/^.*\/icmp$/ d' \
# -e '/^.*\/iphlpapi$/ d' \
# -e '/^.*\/kernel32$/ d' \
# -e '/^.*\/l3codeca.acm$/ d' \
# -e '/^.*\/mfuuid$/ d' \
# -e '/^.*\/mountmgr.sys$/ d' \
# -e '/^.*\/mswsock$/ d' \
# -e '/^.*\/ntdll$/ d' \
# -e '/^.*\/opengl32$/ d' \
# -e '/^.*\/secur32$/ d' \
# -e '/^.*\/strmbase$/ d' \
# -e '/^.*\/strmiids$/ d' \
# -e '/^.*\/twain_32$/ d' \
# -e '/^.*\/unicows$/ d' \
# -e '/^.*\/user32$/ d' \
# -e '/^.*\/uuid$/ d' \
# -e '/^.*\/vdmdbg$/ d' \
# -e '/^.*\/w32skrnl$/ d' \
# -e '/^.*\/winecrt0$/ d' \
# -e '/^.*\/wined3d$/ d' \
# -e '/^.*\/winemp3.acm$/ d' \
# -e '/^.*\/wineqtdecoder$/ d' \
# -e '/^.*\/winmm$/ d' \
# -e '/^.*\/wintab32$/ d' \
# -e '/^.*\/wmcodecdspuuid$/ d' \
# -e '/^.*\/wnaspi32$/ d' \
# -e '/^.*\/wow32$/ d' \
# -e '/^.*\/ws2_32$/ d' \
# -e '/^.*\/wsock32$/ d' \
# -e 's,.*/, ,' | sort | fmt -63 | sed 's/$/ \\/'
#
# 2018-12-10: Last list update (wine-4.0-rc1)
w_override_dlls builtin \
acledit aclui activeds actxprxy adsldp adsldpc advpack \
amstream api-ms-win-appmodel-identity-l1-1-0 \
api-ms-win-appmodel-runtime-l1-1-1 \
api-ms-win-appmodel-runtime-l1-1-2 \
api-ms-win-core-apiquery-l1-1-0 \
api-ms-win-core-appcompat-l1-1-1 \
api-ms-win-core-appinit-l1-1-0 \
api-ms-win-core-atoms-l1-1-0 \
api-ms-win-core-bem-l1-1-0 api-ms-win-core-com-l1-1-0 \
api-ms-win-core-com-l1-1-1 api-ms-win-core-comm-l1-1-0 \
api-ms-win-core-com-private-l1-1-0 \
api-ms-win-core-console-l1-1-0 \
api-ms-win-core-console-l2-1-0 \
api-ms-win-core-crt-l1-1-0 api-ms-win-core-crt-l2-1-0 \
api-ms-win-core-datetime-l1-1-0 \
api-ms-win-core-datetime-l1-1-1 \
api-ms-win-core-debug-l1-1-0 \
api-ms-win-core-debug-l1-1-1 \
api-ms-win-core-delayload-l1-1-0 \
api-ms-win-core-delayload-l1-1-1 \
api-ms-win-core-errorhandling-l1-1-0 \
api-ms-win-core-errorhandling-l1-1-1 \
api-ms-win-core-errorhandling-l1-1-2 \
api-ms-win-core-errorhandling-l1-1-3 \
api-ms-win-core-fibers-l1-1-0 \
api-ms-win-core-fibers-l1-1-1 \
api-ms-win-core-file-l1-1-0 \
api-ms-win-core-file-l1-2-0 \
api-ms-win-core-file-l1-2-1 \
api-ms-win-core-file-l1-2-2 \
api-ms-win-core-file-l2-1-0 \
api-ms-win-core-file-l2-1-1 \
api-ms-win-core-file-l2-1-2 \
api-ms-win-core-handle-l1-1-0 \
api-ms-win-core-heap-l1-1-0 \
api-ms-win-core-heap-l1-2-0 \
api-ms-win-core-heap-l2-1-0 \
api-ms-win-core-heap-obsolete-l1-1-0 \
api-ms-win-core-interlocked-l1-1-0 \
api-ms-win-core-interlocked-l1-2-0 \
api-ms-win-core-io-l1-1-0 api-ms-win-core-io-l1-1-1 \
api-ms-win-core-job-l1-1-0 api-ms-win-core-job-l2-1-0 \
api-ms-win-core-kernel32-legacy-l1-1-0 \
api-ms-win-core-kernel32-legacy-l1-1-1 \
api-ms-win-core-kernel32-private-l1-1-1 \
api-ms-win-core-largeinteger-l1-1-0 \
api-ms-win-core-libraryloader-l1-1-0 \
api-ms-win-core-libraryloader-l1-1-1 \
api-ms-win-core-libraryloader-l1-2-0 \
api-ms-win-core-libraryloader-l1-2-1 \
api-ms-win-core-libraryloader-l1-2-2 \
api-ms-win-core-localization-l1-1-0 \
api-ms-win-core-localization-l1-2-0 \
api-ms-win-core-localization-l1-2-1 \
api-ms-win-core-localization-l2-1-0 \
api-ms-win-core-localization-obsolete-l1-1-0 \
api-ms-win-core-localization-obsolete-l1-2-0 \
api-ms-win-core-localization-obsolete-l1-3-0 \
api-ms-win-core-localization-private-l1-1-0 \
api-ms-win-core-localregistry-l1-1-0 \
api-ms-win-core-memory-l1-1-0 \
api-ms-win-core-memory-l1-1-1 \
api-ms-win-core-memory-l1-1-2 \
api-ms-win-core-misc-l1-1-0 \
api-ms-win-core-namedpipe-l1-1-0 \
api-ms-win-core-namedpipe-l1-2-0 \
api-ms-win-core-namespace-l1-1-0 \
api-ms-win-core-normalization-l1-1-0 \
api-ms-win-core-path-l1-1-0 \
api-ms-win-core-privateprofile-l1-1-1 \
api-ms-win-core-processenvironment-l1-1-0 \
api-ms-win-core-processenvironment-l1-2-0 \
api-ms-win-core-processthreads-l1-1-0 \
api-ms-win-core-processthreads-l1-1-1 \
api-ms-win-core-processthreads-l1-1-2 \
api-ms-win-core-processthreads-l1-1-3 \
api-ms-win-core-processtopology-obsolete-l1-1-0 \
api-ms-win-core-profile-l1-1-0 \
api-ms-win-core-psapi-ansi-l1-1-0 \
api-ms-win-core-psapi-l1-1-0 \
api-ms-win-core-psapi-obsolete-l1-1-0 \
api-ms-win-core-quirks-l1-1-0 \
api-ms-win-core-realtime-l1-1-0 \
api-ms-win-core-registry-l1-1-0 \
api-ms-win-core-registry-l2-1-0 \
api-ms-win-core-registryuserspecific-l1-1-0 \
api-ms-win-core-rtlsupport-l1-1-0 \
api-ms-win-core-rtlsupport-l1-2-0 \
api-ms-win-core-shlwapi-legacy-l1-1-0 \
api-ms-win-core-shlwapi-obsolete-l1-1-0 \
api-ms-win-core-shlwapi-obsolete-l1-2-0 \
api-ms-win-core-shutdown-l1-1-0 \
api-ms-win-core-sidebyside-l1-1-0 \
api-ms-win-core-stringansi-l1-1-0 \
api-ms-win-core-string-l1-1-0 \
api-ms-win-core-string-l2-1-0 \
api-ms-win-core-stringloader-l1-1-1 \
api-ms-win-core-string-obsolete-l1-1-0 \
api-ms-win-core-synch-ansi-l1-1-0 \
api-ms-win-core-synch-l1-1-0 \
api-ms-win-core-synch-l1-2-0 \
api-ms-win-core-synch-l1-2-1 \
api-ms-win-core-sysinfo-l1-1-0 \
api-ms-win-core-sysinfo-l1-2-0 \
api-ms-win-core-sysinfo-l1-2-1 \
api-ms-win-core-threadpool-l1-1-0 \
api-ms-win-core-threadpool-l1-2-0 \
api-ms-win-core-threadpool-legacy-l1-1-0 \
api-ms-win-core-threadpool-private-l1-1-0 \
api-ms-win-core-timezone-l1-1-0 \
api-ms-win-core-toolhelp-l1-1-0 \
api-ms-win-core-url-l1-1-0 api-ms-win-core-util-l1-1-0 \
api-ms-win-core-versionansi-l1-1-0 \
api-ms-win-core-version-l1-1-0 \
api-ms-win-core-version-l1-1-1 \
api-ms-win-core-version-private-l1-1-0 \
api-ms-win-core-windowserrorreporting-l1-1-0 \
api-ms-win-core-winrt-error-l1-1-0 \
api-ms-win-core-winrt-error-l1-1-1 \
api-ms-win-core-winrt-errorprivate-l1-1-1 \
api-ms-win-core-winrt-l1-1-0 \
api-ms-win-core-winrt-registration-l1-1-0 \
api-ms-win-core-winrt-roparameterizediid-l1-1-0 \
api-ms-win-core-winrt-string-l1-1-0 \
api-ms-win-core-winrt-string-l1-1-1 \
api-ms-win-core-wow64-l1-1-0 \
api-ms-win-core-wow64-l1-1-1 \
api-ms-win-core-xstate-l1-1-0 \
api-ms-win-core-xstate-l2-1-0 \
api-ms-win-crt-conio-l1-1-0 \
api-ms-win-crt-convert-l1-1-0 \
api-ms-win-crt-environment-l1-1-0 \
api-ms-win-crt-filesystem-l1-1-0 \
api-ms-win-crt-heap-l1-1-0 \
api-ms-win-crt-locale-l1-1-0 \
api-ms-win-crt-math-l1-1-0 \
api-ms-win-crt-multibyte-l1-1-0 \
api-ms-win-crt-private-l1-1-0 \
api-ms-win-crt-process-l1-1-0 \
api-ms-win-crt-runtime-l1-1-0 \
api-ms-win-crt-stdio-l1-1-0 \
api-ms-win-crt-string-l1-1-0 \
api-ms-win-crt-time-l1-1-0 \
api-ms-win-crt-utility-l1-1-0 \
api-ms-win-devices-config-l1-1-0 \
api-ms-win-devices-config-l1-1-1 \
api-ms-win-devices-query-l1-1-1 \
api-ms-win-downlevel-advapi32-l1-1-0 \
api-ms-win-downlevel-advapi32-l2-1-0 \
api-ms-win-downlevel-normaliz-l1-1-0 \
api-ms-win-downlevel-ole32-l1-1-0 \
api-ms-win-downlevel-shell32-l1-1-0 \
api-ms-win-downlevel-shlwapi-l1-1-0 \
api-ms-win-downlevel-shlwapi-l2-1-0 \
api-ms-win-downlevel-user32-l1-1-0 \
api-ms-win-downlevel-version-l1-1-0 \
api-ms-win-dx-d3dkmt-l1-1-0 \
api-ms-win-eventing-classicprovider-l1-1-0 \
api-ms-win-eventing-consumer-l1-1-0 \
api-ms-win-eventing-controller-l1-1-0 \
api-ms-win-eventing-legacy-l1-1-0 \
api-ms-win-eventing-provider-l1-1-0 \
api-ms-win-eventlog-legacy-l1-1-0 \
api-ms-win-gdi-dpiinfo-l1-1-0 \
api-ms-win-mm-joystick-l1-1-0 \
api-ms-win-mm-misc-l1-1-1 api-ms-win-mm-mme-l1-1-0 \
api-ms-win-mm-time-l1-1-0 \
api-ms-win-ntuser-dc-access-l1-1-0 \
api-ms-win-ntuser-rectangle-l1-1-0 \
api-ms-win-ntuser-sysparams-l1-1-0 \
api-ms-win-perf-legacy-l1-1-0 \
api-ms-win-power-base-l1-1-0 \
api-ms-win-power-setting-l1-1-0 \
api-ms-win-rtcore-ntuser-draw-l1-1-0 \
api-ms-win-rtcore-ntuser-private-l1-1-0 \
api-ms-win-rtcore-ntuser-private-l1-1-4 \
api-ms-win-rtcore-ntuser-window-l1-1-0 \
api-ms-win-rtcore-ntuser-winevent-l1-1-0 \
api-ms-win-rtcore-ntuser-wmpointer-l1-1-0 \
api-ms-win-rtcore-ntuser-wmpointer-l1-1-3 \
api-ms-win-security-activedirectoryclient-l1-1-0 \
api-ms-win-security-audit-l1-1-1 \
api-ms-win-security-base-l1-1-0 \
api-ms-win-security-base-l1-2-0 \
api-ms-win-security-base-private-l1-1-1 \
api-ms-win-security-credentials-l1-1-0 \
api-ms-win-security-cryptoapi-l1-1-0 \
api-ms-win-security-grouppolicy-l1-1-0 \
api-ms-win-security-lsalookup-l1-1-0 \
api-ms-win-security-lsalookup-l1-1-1 \
api-ms-win-security-lsalookup-l2-1-0 \
api-ms-win-security-lsalookup-l2-1-1 \
api-ms-win-security-lsapolicy-l1-1-0 \
api-ms-win-security-provider-l1-1-0 \
api-ms-win-security-sddl-l1-1-0 \
api-ms-win-security-systemfunctions-l1-1-0 \
api-ms-win-service-core-l1-1-0 \
api-ms-win-service-core-l1-1-1 \
api-ms-win-service-management-l1-1-0 \
api-ms-win-service-management-l2-1-0 \
api-ms-win-service-private-l1-1-1 \
api-ms-win-service-winsvc-l1-1-0 \
api-ms-win-service-winsvc-l1-2-0 \
api-ms-win-shcore-obsolete-l1-1-0 \
api-ms-win-shcore-scaling-l1-1-1 \
api-ms-win-shcore-stream-l1-1-0 \
api-ms-win-shcore-thread-l1-1-0 \
api-ms-win-shell-shellcom-l1-1-0 \
api-ms-win-shell-shellfolders-l1-1-0 apphelp \
appwiz.cpl atl atl100 atl110 atl80 atl90 atmlib \
authz avicap32 avifil32 avrt bcrypt bluetoothapis \
browseui bthprops.cpl cabinet cards cdosys cfgmgr32 \
clusapi combase comcat comctl32 comdlg32 compstui \
comsvcs concrt140 connect credui crtdll crypt32 \
cryptdlg cryptdll cryptext cryptnet cryptui ctapi32 \
ctl3d32 d2d1 d3d10 d3d10_1 d3d10core d3d11 d3d12 d3d8 \
d3d9 d3dcompiler_33 d3dcompiler_34 d3dcompiler_35 \
d3dcompiler_36 d3dcompiler_37 d3dcompiler_38 \
d3dcompiler_39 d3dcompiler_40 d3dcompiler_41 \
d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 \
d3dcompiler_47 d3dim d3drm d3dx10_33 d3dx10_34 \
d3dx10_35 d3dx10_36 d3dx10_37 d3dx10_38 d3dx10_39 \
d3dx10_40 d3dx10_41 d3dx10_42 d3dx10_43 d3dx11_42 \
d3dx11_43 d3dx9_24 d3dx9_25 d3dx9_26 d3dx9_27 \
d3dx9_28 d3dx9_29 d3dx9_30 d3dx9_31 d3dx9_32 d3dx9_33 \
d3dx9_34 d3dx9_35 d3dx9_36 d3dx9_37 d3dx9_38 d3dx9_39 \
d3dx9_40 d3dx9_41 d3dx9_42 d3dx9_43 d3dxof davclnt \
dbgeng dciman32 ddrawex devenum dhcpcsvc dhtmled.ocx \
difxapi dinput dinput8 dispex dmband dmcompos dmime \
dmloader dmscript dmstyle dmsynth dmusic dmusic32 \
dnsapi dplay dplayx dpnaddr dpnet dpnhpast dpnlobby \
dpvoice dpwsockx drmclien dsound dsquery dssenh \
dswave dwmapi dwrite dx8vb dxdiagn dxgi dxva2 esent \
evr explorerframe ext-ms-win-authz-context-l1-1-0 \
ext-ms-win-domainjoin-netjoin-l1-1-0 \
ext-ms-win-dwmapi-ext-l1-1-0 \
ext-ms-win-gdi-dc-create-l1-1-1 \
ext-ms-win-gdi-dc-l1-2-0 ext-ms-win-gdi-devcaps-l1-1-0 \
ext-ms-win-gdi-draw-l1-1-1 \
ext-ms-win-gdi-render-l1-1-0 \
ext-ms-win-kernel32-package-current-l1-1-0 \
ext-ms-win-kernel32-package-l1-1-1 \
ext-ms-win-ntuser-draw-l1-1-0 \
ext-ms-win-ntuser-gui-l1-3-0 \
ext-ms-win-ntuser-keyboard-l1-3-0 \
ext-ms-win-ntuser-message-l1-1-1 \
ext-ms-win-ntuser-misc-l1-2-0 \
ext-ms-win-ntuser-misc-l1-5-1 \
ext-ms-win-ntuser-mouse-l1-1-0 \
ext-ms-win-ntuser-private-l1-1-1 \
ext-ms-win-ntuser-private-l1-3-1 \
ext-ms-win-ntuser-rectangle-ext-l1-1-0 \
ext-ms-win-ntuser-uicontext-ext-l1-1-0 \
ext-ms-win-ntuser-windowclass-l1-1-1 \
ext-ms-win-ntuser-window-l1-1-1 \
ext-ms-win-ntuser-window-l1-1-4 \
ext-ms-win-oleacc-l1-1-0 \
ext-ms-win-ras-rasapi32-l1-1-0 \
ext-ms-win-rtcore-gdi-devcaps-l1-1-0 \
ext-ms-win-rtcore-gdi-object-l1-1-0 \
ext-ms-win-rtcore-gdi-rgn-l1-1-0 \
ext-ms-win-rtcore-ntuser-cursor-l1-1-0 \
ext-ms-win-rtcore-ntuser-dc-access-l1-1-0 \
ext-ms-win-rtcore-ntuser-dpi-l1-1-0 \
ext-ms-win-rtcore-ntuser-dpi-l1-2-0 \
ext-ms-win-rtcore-ntuser-rawinput-l1-1-0 \
ext-ms-win-rtcore-ntuser-syscolors-l1-1-0 \
ext-ms-win-rtcore-ntuser-sysparams-l1-1-0 \
ext-ms-win-security-credui-l1-1-0 \
ext-ms-win-security-cryptui-l1-1-0 \
ext-ms-win-uxtheme-themes-l1-1-0 faultrep feclient \
fltlib fltmgr.sys fntcache fontsub fusion fwpuclnt \
gameux gdiplus gpkcsp hal hhctrl.ocx hid hidclass.sys \
hlink hnetcfg httpapi iccvid ieframe ieproxy \
imaadp32.acm imagehlp imm32 inetcomm inetcpl.cpl \
inetmib1 infosoft initpki inkobj inseng iprop \
irprops.cpl itircl itss joy.cpl jscript jsproxy \
kerberos kernelbase ksuser ktmw32 loadperf localspl \
localui lz32 mapi32 mapistub mciavi32 mcicda mciqtz32 \
mciseq mciwave mf mf3216 mfplat mfreadwrite mgmtapi \
midimap mlang mmcndmgr mmdevapi mp3dmod mpr mprapi \
msacm32 msadp32.acm msasn1 mscat32 mscms mscoree \
msctf msctfp msdaps msdelta msdmo msdrm msftedit \
msg711.acm msgsm32.acm mshtml msi msident msimg32 \
msimsg msimtf msisip msisys.ocx msls31 msnet32 \
mspatcha msports msrle32 msscript.ocx mssign32 \
mssip32 mstask msvcirt msvcm80 msvcm90 msvcp100 \
msvcp110 msvcp120 msvcp120_app msvcp140 msvcp60 \
msvcp70 msvcp71 msvcp80 msvcp90 msvcr100 msvcr110 \
msvcr120 msvcr120_app msvcr70 msvcr71 msvcr80 \
msvcr90 msvcrt msvcrt20 msvcrt40 msvcrtd msvfw32 \
msvidc32 msxml msxml2 msxml3 msxml4 msxml6 mtxdm \
ncrypt nddeapi ndis.sys netapi32 netcfgx netprofm \
newdev ninput normaliz npmshtml npptools ntdsapi \
ntprint objsel odbc32 odbccp32 odbccu32 ole32 oleacc \
oleaut32 olecli32 oledb32 oledlg olepro32 olesvr32 \
olethk32 opcservices openal32 opencl packager pdh \
photometadatahandler pidgen powrprof printui prntvpt \
propsys psapi pstorec qcap qedit qmgr qmgrprxy \
quartz query qwave rasapi32 rasdlg regapi resutils \
riched20 riched32 rpcrt4 rsabase rsaenh rstrtmgr \
rtutils samlib sapi sas scarddlg sccbase schannel \
schedsvc scrobj scrrun scsiport.sys security sensapi \
serialui setupapi sfc sfc_os shcore shdoclc shdocvw \
shell32 shfolder shlwapi slbcsp slc snmpapi softpub \
spoolss srclient sspicli sti strmdll svrapi sxs \
t2embed tapi32 taskschd tdh tdi.sys traffic tzres \
ucrtbase uiautomationcore uiribbon updspapi url \
urlmon usbd.sys userenv usp10 uxtheme vbscript \
vcomp vcomp100 vcomp110 vcomp120 vcomp140 vcomp90 \
vcruntime140 version virtdisk vssapi vulkan-1 wbemdisp \
wbemprox wdscore webservices wer wevtapi wiaservc \
wimgapi windowscodecs windowscodecsext winebus.sys \
winegstreamer winehid.sys winemapi winevulkan wing32 \
winhttp wininet winnls32 winscard winsta wintrust \
winusb wlanapi wldap32 wmasf wmi wmiutils wmp wmphoto \
wmvcore wpc wpcap wsdapi wshom.ocx wsnmp32 wtsapi32 \
wuapi wuaueng x3daudio1_0 x3daudio1_1 x3daudio1_2 \
x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 \
x3daudio1_7 xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 \
xapofx1_5 xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 \
xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7 xaudio2_8 \
xaudio2_9 xinput1_1 xinput1_2 xinput1_3 xinput1_4 \
xinput9_1_0 xmllite xolehlp xpsprint xpssvcs \
# blank line so you don't have to remove the extra trailing \
}
w_override_app_dlls()
{
w_skip_windows w_override_app_dlls && return
_W_app=$1
shift
_W_mode=$1
shift
# Fixme: handle comma-separated list of modes
case $_W_mode in
b|builtin) _W_mode=builtin ;;
n|native) _W_mode=native ;;
default) _W_mode=default ;;
d|disabled) _W_mode="" ;;
*)
w_die "w_override_app_dlls: unknown mode $_W_mode. (want native, builtin, default, or disabled)
Usage: 'w_override_app_dlls app mode dll ...'." ;;
esac
echo "Using $_W_mode override for following DLLs when running $_W_app: $*"
(
echo REGEDIT4
echo ""
echo "[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\$_W_app\\DllOverrides]"
) > "$W_TMP"/override-dll.reg
while test "$1" != ""
do
w_common_override_dll "$_W_mode" "$1"
shift
done
w_try_regedit "$W_TMP_WIN"\\override-dll.reg
w_try rm "$W_TMP"/override-dll.reg
unset _W_app _W_mode
}
# Has to be set in a few places...
w_set_winver()
{
w_skip_windows w_set_winver && return
# FIXME: This should really be done with winecfg, but it has no CLI options.
# Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45616
# First, delete any lingering version info, otherwise it may conflict:
(
"$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion" /v SubVersionNumber /f || true
"$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion" /v VersionNumber /f || true
"$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CSDVersion /f || true
"$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentBuildNumber /f || true
"$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentVersion /f || true
"$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /f || true
"$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ServiceCurrent" /v OS /f || true
"$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\Windows" /v CSDVersion /f || true
"$WINE" reg delete "HKCU\\Software\\Wine" /v Version /f || true
"$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /f || true
) > /dev/null 2>&1
case "$1" in
win31)
echo "Setting Windows version to $1"
cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4
[HKEY_USERS\\S-1-5-4\\Software\\Wine]
"Version"="win31"
_EOF_
w_try_regedit "$W_TMP_WIN"\\set-winver.reg
return
;;
win95)
# This key is only used for Windows 95/98:
echo "Setting Windows version to $1"
cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion]
"ProductName"="Microsoft Windows 95"
"SubVersionNumber"=""
"VersionNumber"="4.0.950"
_EOF_
w_try_regedit "$W_TMP_WIN"\\set-winver.reg
return
;;
win98)
# This key is only used for Windows 95/98:
echo "Setting Windows version to $1"
cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion]
"ProductName"="Microsoft Windows 98"
"SubVersionNumber"=" A "
"VersionNumber"="4.10.2222"
_EOF_
w_try_regedit "$W_TMP_WIN"\\set-winver.reg
return
;;
nt40)
# Similar to modern version, but sets two extra keys:
echo "Setting Windows version to $1"
cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion]
"CSDVersion"="Service Pack 6a"
"CurrentBuildNumber"="1381"
"CurrentVersion"="4.0"
[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ProductOptions]
"ProductType"="WinNT"
[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ServiceCurrent]
"OS"="Windows_NT"
[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows]
"CSDVersion"=dword:00000600
_EOF_
w_try_regedit "$W_TMP_WIN"\\set-winver.reg
return
;;
win2k)
csdversion="Service Pack 4"
currentbuildnumber="2195"
currentversion="5.0"
csdversion_hex=dword:00000400
;;
winxp)
# Special case, afaik it's the only Windows version that has different version numbers for 32/64-bit
# So ensure we set the arch appropriate version:
if [ "$W_ARCH" = "win32" ]; then
csdversion="Service Pack 3"
currentbuildnumber="2600"
currentversion="5.1"
csdversion_hex=dword:00000300
elif [ "$W_ARCH" = "win64" ]; then
csdversion="Service Pack 2"
currentbuildnumber="3790"
currentversion="5.2"
csdversion_hex=dword:00000200
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
else
w_die "Invalid W_ARCH $W_ARCH"
fi
;;
win2k3)
csdversion="Service Pack 2"
currentbuildnumber="3790"
currentversion="5.2"
csdversion_hex=dword:00000200
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f
;;
vista)
csdversion="Service Pack 2"
currentbuildnumber="6002"
currentversion="6.0"
csdversion_hex=dword:00000200
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
;;
win7)
csdversion="Service Pack 1"
currentbuildnumber="7601"
currentversion="6.1"
csdversion_hex=dword:00000100
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
;;
win2k8)
csdversion="Service Pack 1"
currentbuildnumber="7601"
currentversion="6.1"
csdversion_hex=dword:00000100
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f
;;
win8)
csdversion=""
currentbuildnumber="9200"
currentversion="6.2"
csdversion_hex=dword:00000000
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
;;
win81)
csdversion=""
currentbuildnumber="9600"
currentversion="6.3"
csdversion_hex=dword:00000000
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
;;
win10)
csdversion=""
currentbuildnumber="10240"
currentversion="10.0"
csdversion_hex=dword:00000000
"$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
;;
*)
w_die "Invalid Windows version given."
;;
esac
echo "Setting Windows version to $1"
cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion]
"CSDVersion"="$csdversion"
"CurrentBuildNumber"="$currentbuildnumber"
"CurrentVersion"="$currentversion"
[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows]
"CSDVersion"=$csdversion_hex
_EOF_
w_try_regedit "$W_TMP_WIN"\\set-winver.reg
# Prevent a race when calling from another verb
w_wineserver -w
}
w_unset_winver()
{
w_set_winver winxp
}
# Present app $1 with the Windows personality $2
w_set_app_winver()
{
w_skip_windows w_set_app_winver && return
_W_app="$1"
_W_version="$2"
echo "Setting $_W_app to $_W_version mode"
(
echo REGEDIT4
echo ""
echo "[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\$_W_app]"
echo "\"Version\"=\"$_W_version\""
) > "$W_TMP"/set-winver.reg
w_try_regedit "$W_TMP_WIN"\\set-winver.reg
rm "$W_TMP"/set-winver.reg
unset _W_app
}
# Usage: w_compare_wine_version OP VALUE
# Note: currently only -ge and -le are supported,
# as well as the special case -bn (between)
# Example:
# if w_compare_wine_version -gt 2.5 ; then
# ...
# fi
w_compare_wine_version()
{
comparison="$1"
known_wine_val1="$2"
known_wine_val2="$3"
case "$comparison" in
# expected value if the comparison is true
-bn) _expected_pos_current_wine="2";;
-ge) _expected_pos_current_wine="2";;
-le) _expected_pos_current_wine="1";;
*) w_die "Unsupported comparison. Only -ge and -le are supported" ;;
esac
_pos_current_wine="$(printf "%s\\n%s\\n%s" "${known_wine_val1}" "${_wine_version_stripped}" "${known_wine_val2}" | sort -t. -k 1,1n -k 2,2n -k 3,3n | grep -n "^${_wine_version_stripped}\$" | cut -d : -f1)"
if [ "$_pos_current_wine" = "$_expected_pos_current_wine" ] ; then
#echo "true: known_wine_version=$2, comparison=$1, stripped wine=$_wine_version_stripped, expected_pos=$_expected_pos_known, pos_known=$_pos_known_wine"
#echo "Wine version comparison is true"
return 1
else
#echo "false: known_wine_version=$2, comparison=$1, stripped wine=$_wine_version_stripped, expected_pos=$_expected_pos_known, pos_known=$_pos_known_wine"
#echo "Wine version comparison is false"
return 0
fi
}
# Usage: w_wine_version_in range ...
# True if wine version in any of the given ranges
# 'range' can be
# val1, (for >= val1)
# ,val2 (for <= val2)
# val1,val2 (for >= val1 && <= val2)
w_wine_version_in()
{
for _W_range
do
_W_val1=$(echo "$_W_range" | sed 's/,.*//')
_W_val2=$(echo "$_W_range" | sed 's/.*,//')
# If in this range, return true
case $_W_range in
,*) w_compare_wine_version -le "$_W_val2" && unset _W_range _W_val1 _W_val2 && return 0;;
*,) w_compare_wine_version -ge "$_W_val1" && unset _W_range _W_val1 _W_val2 && return 0;;
*) w_compare_wine_version -bn "$_W_val1" "$_W_val2" && unset _W_range _W_val1 _W_val2 && return 0;;
esac
done
unset _W_range _W_val1 _W_val2
return 1
}
# Usage: workaround_wine_bug bugnumber [message] [good-wine-version-range ...]
# Returns true and outputs given msg if the workaround needs to be applied.
# For debugging: if you want to skip a bug's workaround, put the bug number in
# the environment variable WINETRICKS_BLACKLIST to disable it.
w_workaround_wine_bug()
{
if test "$WINE" = ""; then
echo "No need to work around wine bug $1 on Windows"
return 1
fi
case "$2" in
[0-9]*) w_die "bug: want message in w_workaround_wine_bug arg 2, got $2" ;;
"") _W_msg="";;
*) _W_msg="-- $2";;
esac
# shellcheck disable=SC2086
if test "$3" && w_wine_version_in $3 $4 $5 $6; then
echo "Current Wine does not have Wine bug $1, so not applying workaround"
return 1
fi
case "$1" in
"$WINETRICKS_BLACKLIST")
echo "Wine bug $1 workaround blacklisted, skipping"
return 1
;;
esac
case $LANG in
da*) w_warn "Arbejder uden om wine-fejl ${1} $_W_msg" ;;
de*) w_warn "Wine-Fehler ${1} wird umgegangen $_W_msg" ;;
pl*) w_warn "Obchodzenie błędu w wine ${1} $_W_msg" ;;
ru*) w_warn "Обход ошибки ${1} $_W_msg" ;;
uk*) w_warn "Обхід помилки ${1} $_W_msg" ;;
zh_CN*) w_warn "绕过 wine bug ${1} $_W_msg" ;;
zh_TW*|zh_HK*) w_warn "繞過 wine bug ${1} $_W_msg" ;;
*) w_warn "Working around wine bug ${1} $_W_msg" ;;
esac
winetricks_stats_log_command "w_workaround_wine_bug-$1"
return 0
}
# Function for verbs to register themselves so they show up in the menu.
# Example:
# w_metadata wog games \
# title="World of Goo Demo" \
# pub="2D Boy" \
# year="2008" \
# media="download" \
# file1="WorldOfGooDemo.1.0.exe"
w_metadata()
{
case $WINETRICKS_OPT_VERBOSE in
2) set -x ;;
*) set +x ;;
esac
# shellcheck disable=SC2154
if test "$installed_exe1" || test "$installed_file1" || test "$publisher" || test "$year"; then
w_die "bug: stray metadata tags set: somebody forgot a backslash in a w_metadata somewhere. Run with sh -x to see where."
fi
if winetricks_metadata_exists "$1"; then
w_die "bug: a verb named $1 already exists."
fi
_W_md_cmd="$1"
_W_category="$2"
file="$WINETRICKS_METADATA/$_W_category/$1.vars"
shift
shift
# Echo arguments to file, with double quotes around the values.
# Used to use Perl here, but that was too slow on Cygwin.
for arg
do
case "$arg" in
installed_exe1=/*) w_die "bug: w_metadata $_W_md_cmd has a unix path for installed_exe1, should be a windows path";;
installed_file1=/*) w_die "bug: w_metadata $_W_md_cmd has a unix path for installed_file1, should be a windows path";;
media=download_manual) w_die "bug: verb $_W_md_cmd has media=download_manual, should be manual_download" ;;
esac
# Use longest match when stripping value,
# and shortest match when stripping name,
# so descriptions can have embedded equals signs
# FIXME: backslashes get interpreted here. This screws up
# installed_file1 fairly often. Fortunately, we can use forward
# slashes in that variable instead of backslashes.
echo "${arg%%=*}"=\""${arg#*=}"\"
done > "$file"
echo category='"'"$_W_category"'"' >> "$file"
# If the problem described above happens, you'd see errors like this:
# /tmp/w.dank.4650/metadata/dlls/comctl32.vars: 6: Syntax error: Unterminated quoted string
# so check for lines that aren't properly quoted.
# Do sanity check unless running on Cygwin, where it's way too slow.
case "$W_PLATFORM" in
windows_cmd)
;;
*)
if grep '[^"]$' "$file"; then
w_die "bug: w_metadata $_W_md_cmd corrupt, might need forward slashes?"
fi
;;
esac
unset _W_md_cmd
# Restore verbosity:
case $WINETRICKS_OPT_VERBOSE in
1|2) set -x ;;
*) set +x ;;
esac
}
# Function for verbs to register their main executable [or, if name is given, other executables]
# Deprecated. No-op for backwards compatibility
w_declare_exe()
{
w_warn "w_declare_exe is deprecated, now a noop"
}
# Checks that a conflicting verb is not already installed in the prefix
# Usage: w_conflicts verb_to_install conflicting_verbs
w_conflicts()
{
verb="$1"
conflicting_verbs="$2"
for x in $conflicting_verbs
do
if grep -qw "$x" "$WINEPREFIX/winetricks.log" 2>/dev/null; then
w_die "error: $verb conflicts with $x, which is already installed. You can run \`$0 --force $verb\` to ignore this check and attempt installation."
fi
done
}
# Call a verb, don't let it affect environment
# Hope that subshell passes through exit status
# Usage: w_do_call foo [bar] (calls load_foo bar)
# Or: w_do_call foo=bar (also calls load_foo bar)
# Or: w_do_call foo (calls load_foo)
w_do_call()
{
(
# Hack..
if test "$cmd" = vd; then
load_vd "$arg"
_W_status=$?
test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
mkdir -p "$W_TMP"
return $_W_status
fi
case "$1" in
*=*) arg=$(echo "$1" | sed 's/.*=//'); cmd=$(echo "$1" | sed 's/=.*//');;
*) cmd=$1; arg=$2 ;;
esac
# Kludge: use Temp instead of temp to avoid \t expansion in w_try
# but use temp in Unix path because that's what Wine creates, and having both temp and Temp
# causes confusion (e.g. makes vc2005trial fail)
# FIXME: W_TMP is also set in winetricks_set_wineprefix, can we avoid the duplication?
W_TMP="$W_DRIVE_C/windows/temp/_$1"
W_TMP_WIN="C:\\windows\\Temp\\_$1"
test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
mkdir -p "$W_TMP"
# Unset all known used metadata values, in case this is a nested call
unset conflicts installed_file1 installed_exe1
if winetricks_metadata_exists "$1"; then
# shellcheck disable=SC1090
. "$WINETRICKS_METADATA"/*/"${1}.vars"
elif winetricks_metadata_exists "$cmd"; then
# shellcheck disable=SC1090
. "$WINETRICKS_METADATA"/*/"${cmd}.vars"
elif test "$cmd" = native || test "$cmd" = disabled || test "$cmd" = builtin || test "$cmd" = default; then
# ugly special case - can't have metadata for these verbs until we allow arbitrary parameters
w_override_dlls "$cmd" "$arg"
_W_status=$?
test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
mkdir -p "$W_TMP"
return $_W_status
else
w_die "No such verb $1"
fi
# If needed, set the app's wineprefix
case "$W_PLATFORM" in
windows_cmd|wine_cmd) ;;
*)
# shellcheck disable=SC2154
case "${category}-${WINETRICKS_OPT_SHAREDPREFIX}" in
apps-0|benchmarks-0|games-0)
winetricks_set_wineprefix "$cmd"
# If it's a new wineprefix, give it metadata
if test ! -f "$WINEPREFIX"/wrapper.cfg; then
echo ww_name=\""$title"\" > "$WINEPREFIX"/wrapper.cfg
fi
;;
esac
;;
esac
test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
mkdir -p "$W_TMP"
# Don't install if a conflicting verb is already installed:
# shellcheck disable=SC2154
if test "$WINETRICKS_FORCE" != 1 && test "$conflicts" && test -f "$WINEPREFIX/winetricks.log"; then
for x in $conflicts
do
w_conflicts "$1" "$x"
done
fi
# Don't install if already installed
if test "$WINETRICKS_FORCE" != 1 && winetricks_is_installed "$1"; then
echo "$1 already installed, skipping"
return 0
fi
# We'd like to get rid of W_PACKAGE, but for now, just set it as late as possible.
W_PACKAGE=$1
w_try "load_$cmd" "$arg"
winetricks_stats_log_command "$@"
# User-specific postinstall hook.
# Source it so the script can call w_download() if needed.
postfile="$WINETRICKS_POST/$1/$1-postinstall.sh"
if test -f "$postfile"; then
chmod +x "$postfile"
# shellcheck disable=SC1090
. "$postfile"
fi
# Verify install
if test "$installed_exe1" || test "$installed_file1"; then
if ! winetricks_is_installed "$1"; then
w_die "$1 install completed, but installed file $_W_file_unix not found"
fi
fi
# If the user specified --verify, also run GUI tests:
if test "$WINETRICKS_VERIFY" = 1; then
# command -v isn't POSIX :(
"verify_$cmd" 2>/dev/null
verify_status=$?
case $verify_status in
0) w_warn "verify_$cmd succeeded!" ;;
127) echo "verify_$cmd not found, not verifying $cmd" ;;
*) w_die "verify_$cmd failed!" ;;
esac
fi
# Clean up after this verb
test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
mkdir -p "$W_TMP"
# Reset whether use of user mount tool
unset W_USE_USERMOUNT
# Calling subshell must explicitly propagate error code with exit $?
) || exit $?
}
# If you want to check exit status yourself, use w_do_call
w_call()
{
w_try w_do_call "$@"
}
w_backup_reg_file()
{
W_reg_file=$1
w_get_sha256sum "$W_reg_file"
w_try cp "$W_reg_file" "$W_TMP_EARLY/_reg_$(echo "$_W_gotsha256sum" | cut -c1-8)"_$$.reg
unset W_reg_file _W_gotsha256sum
}
w_register_font()
{
W_file=$1
shift
W_font=$1
case $(echo "$W_file" | tr "[:upper:]" "[:lower:]") in
*.ttf|*.ttc) W_font="$W_font (TrueType)";;
esac
# Kludge: use _r to avoid \r expansion in w_try
cat > "$W_TMP"/_register-font.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts]
"$W_font"="$W_file"
_EOF_
# too verbose
w_try_regedit "$W_TMP_WIN"\\_register-font.reg
w_backup_reg_file "$W_TMP"/_register-font.reg
# Wine also updates the win9x fonts key, so let's do that, too
cat > "$W_TMP"/_register-font.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts]
"$W_font"="$W_file"
_EOF_
w_try_regedit "$W_TMP_WIN"\\_register-font.reg
w_backup_reg_file "$W_TMP"/_register-font.reg
unset W_file W_font
}
w_register_font_replacement()
{
_W_alias=$1
shift
_W_font=$1
# Kludge: use _r to avoid \r expansion in w_try
cat > "$W_TMP"/_register-font-replacements.reg <<_EOF_
REGEDIT4
[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\Replacements]
"$_W_alias"="$_W_font"
_EOF_
w_try_regedit "$W_TMP_WIN"\\_register-font-replacements.reg
w_backup_reg_file "$W_TMP"/_register-font-replacements.reg
unset _W_alias _W_font
}
w_append_path()
{
# Prepend $1 to the Windows path in the registry.
# Use printf %s to avoid interpreting backslashes.
# 2/4 backslashes, not 4/8, see https://github.com/Winetricks/winetricks/issues/932
_W_NEW_PATH="$(printf %s "$1" | sed 's,\\,\\\\,g')"
_W_WIN_PATH="$(w_expand_env PATH | sed 's,\\,\\\\,g')"
# FIXME: OS X? https://github.com/Winetricks/winetricks/issues/697
sed 's/$/\r/' > "$W_TMP"/path.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment]
"PATH"="$_W_NEW_PATH;$_W_WIN_PATH"
_EOF_
w_try_regedit "$W_TMP_WIN"\\path.reg
rm -f "$W_TMP"/path.reg
unset _W_NEW_PATH _W_WIN_PATH
}
#---- Private Functions ----
# Determines downloader to use, etc.
# I.e., things common to w_download_to(), winetricks_download_to_stdout(), and winetricks_stats_report())
winetricks_download_setup()
{
# shellcheck disable=SC2104
case "${WINETRICKS_DOWNLOADER}" in
aria2c|curl|wget|fetch) : ;;
"") if [ -x "$(command -v aria2c 2>/dev/null)" ] ; then
WINETRICKS_DOWNLOADER="aria2c"
elif [ -x "$(command -v wget 2>/dev/null)" ] ; then
WINETRICKS_DOWNLOADER="wget"
elif [ -x "$(command -v curl 2>/dev/null)" ] ; then
WINETRICKS_DOWNLOADER="curl"
elif [ -x "$(command -v fetch 2>/dev/null)" ] ; then
WINETRICKS_DOWNLOADER="fetch"
else
w_die "Please install wget or aria2c (or, if those aren't available, curl)"
fi
;;
*) w_die "Invalid value ${WINETRICKS_DOWNLOADER} given for WINETRICKS_DOWNLOADER. Possible values: aria2c, curl, wget, fetch"
esac
# Common values for aria2c/curl/fetch/wget
# Number of retry attempts (not supported by fetch):
WINETRICKS_DOWNLOADER_RETRIES=${WINETRICKS_DOWNLOADER_RETRIES:-3}
# Connection timeout time (in seconds):
WINETRICKS_DOWNLOADER_TIMEOUT=${WINETRICKS_DOWNLOADER_TIMEOUT:-15}
case "$WINETRICKS_OPT_TORIFY" in
1) torify=torify
# torify needs --async-dns=false, see https://github.com/tatsuhiro-t/aria2/issues/613
aria2c_torify_opts="--async-dns=false"
if [ ! -x "$(command -v torify 2>/dev/null)" ]; then
w_die "--torify was used, but torify is not installed, please install it." ; exit 1
fi ;;
*) torify=
aria2c_torify_opts="" ;;
esac
}
winetricks_dl_url_to_stdout()
{
winetricks_download_setup
# Not using w_try here as it adds extra output, breaking things.
# FIXME: add a w_try_quiet() wrapper around w_try() that doesn't print the
# Executing ... stuff, but still does error checking
if [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then
$torify wget -q -O - --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
--tries "$WINETRICKS_DOWNLOADER_RETRIES" "$1"
elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then
$torify curl -s --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
--retry "$WINETRICKS_DOWNLOADER_RETRIES" "$1"
elif [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then
# aria2c doesn't have support downloading to stdout:
# https://github.com/aria2/aria2/issues/190
# So instead, download to a temporary directory and cat the file:
stdout_tmpfile="${W_TMP_EARLY}/stdout.tmp"
if [ -e "${stdout_tmpfile}" ] ; then
rm "${stdout_tmpfile}"
fi
$torify aria2c \
$aria2c_torify_opts \
--continue \
--daemon=false \
--dir="${W_TMP_EARLY}" \
--enable-rpc=false \
--input-file='' \
--max-connection-per-server=5 \
--out="stdout.tmp" \
--save-session='' \
--stream-piece-selector=geom \
--connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \
--max-tries="$WINETRICKS_DOWNLOADER_RETRIES" \
"$1" > /dev/null
cat "${stdout_tmpfile}"
rm "${stdout_tmpfile}"
elif [ "${WINETRICKS_DOWNLOADER}" = "fetch" ] ; then
# fetch does not support retry count
$torify fetch -o - -T "${WINETRICKS_DOWNLOADER_TIMEOUT}" "$1" 2>/dev/null
else
w_die "Please install aria2c, curl, or wget"
fi
}
winetricks_dl_warning() {
case $LANG in
ru*) _W_countrymsg="Скрипт определил, что ваш IP-адрес принадлежит России. Если во время загрузки файлов вы увидите ошибки несоответствия сертификата, перезапустите скрипт с опцией '--torify' или скачайте файлы вручную, например, используя VPN." ;;
pl*) _W_countrymsg="Wykryto, że twój adres IP należy do Rosji. W wypadku problemów z pobieraniem, uruchom z parametrem '--torify' lub pobierz plik manualnie, np. z użyciem VPN." ;;
*) _W_countrymsg="Your IP address has been determined to belong to Russia. If you encounter a certificate error while downloading, please relaunch with the '--torify' option, or download files manually, for instance using VPN." ;;
esac
# Lookup own country via IP address only once (i.e. don't run this function for every download invocation)
if [ -z "$W_COUNTRY" ] ; then
W_COUNTRY="$(winetricks_dl_url_to_stdout "https://ipinfo.io/$(winetricks_dl_url_to_stdout "https://ipinfo.io/ip")" | awk -F '"' '/country/{print $4}')"
export W_COUNTRY
if [ -z "$W_COUNTRY" ] ; then
export W_COUNTRY="unknown"
fi
fi
# TODO: Resolve a full country name via https://github.com/umpirsky/country-list/tree/master/data
case "$W_COUNTRY" in
"RU") w_warn "$_W_countrymsg" ;;
*) : ;;
esac
}
winetricks_get_sha256sum_prog() {
# Linux/Solaris:
if [ -x "$(command -v sha256sum 2>/dev/null)" ] ; then
WINETRICKS_SHA256SUM="sha256sum"
# FreeBSD/NetBSD:
elif [ -x "$(command -v sha256 2>/dev/null)" ] ; then
WINETRICKS_SHA256SUM="sha256"
# OSX (10.6+), 10.5 doesn't support at all: https://stackoverflow.com/questions/7500691/rvm-sha256sum-nor-shasum-found
elif [ -x "$(command -v shasum 2>/dev/null)" ] ; then
WINETRICKS_SHA256SUM="shasum -a 256"
else
w_die "No sha256um utility available."
fi
}
winetricks_get_platform()
{
if [ "${OS}" = "Windows_NT" ]; then
if [ ! -v "${WINELOADERNOEXEC}" ]; then
export W_PLATFORM="windows_cmd"
else
export W_PLATFORM="wine_cmd"
fi
else
export W_PLATFORM="wine"
fi
}
winetricks_latest_version_check()
{
if [ "$WINETRICKS_LATEST_VERSION_CHECK" = 'disabled' ] || [ -f "${WINETRICKS_CONFIG}/disable-latest-version-check" ] ; then
w_info "winetricks latest version check update disabled"
return
# Used by ./src/release.sh, not for end users. Silently disables update check, without using $WINETRICKS_SUPER_QUIET
elif [ "$WINETRICKS_LATEST_VERSION_CHECK" = 'development' ] ; then
return
fi
latest_version="$(winetricks_dl_url_to_stdout https://raw.githubusercontent.com/Winetricks/winetricks/master/files/LATEST)"
# Check that $latest_version is an actual number in case github is down
if ! echo "${latest_version}" | grep -q -E "[0-9]{8}" || [ -z "${latest_version}" ] ; then
case $LANG in
pl*) w_warn "GitHub nie działa? Wersja '${latest_version}' nie wydaje się być prawdiłową wersją" ;;
ru*) w_warn "Отсутствует подключение к Github? версия '${latest_version}' может быть неактуальной" ;;
*) w_warn "Github down? version '${latest_version}' doesn't appear to be a valid version" ;;
esac
# If we can't get the latest version, no reason to go further:
return
fi
if [ ! "$WINETRICKS_VERSION" = "${latest_version}" ] && [ ! "$WINETRICKS_VERSION" = "${latest_version}-next" ]; then
if [ -f "${WINETRICKS_CONFIG}/enable-auto-update" ] ; then
w_info "You are running winetricks-${WINETRICKS_VERSION}."
w_info "New upstream release winetricks-${latest_version} is available."
w_info "auto-update enabled: running winetricks_selfupdate"
winetricks_selfupdate
else
case $LANG in
pl*)
w_warn "Korzystasz z winetricks-${WINETRICKS_VERSION}, a najnowszą wersją winetricks-${latest_version}!"
w_warn "Zalecana jest aktualizacja z użyciem menedżera pakietów Twojej dystrybucji, --self-update lub ręczna aktualizacja."
;;
ru*)
w_warn "Запущен winetricks-${WINETRICKS_VERSION}, последняя версия winetricks-${latest_version}!"
w_warn "Вы можете ее обновить с помощью менеджера пакетов, --self-update или вручную."
;;
*)
w_warn "You are running winetricks-${WINETRICKS_VERSION}, latest upstream is winetricks-${latest_version}!"
w_warn "You should update using your distribution's package manager, --self-update, or manually."
;;
esac
fi
fi
}
winetricks_print_version()
{
# Normally done by winetricks_init, but we don't want to set up the WINEPREFIX
# just to get the winetricks version:
winetricks_get_sha256sum_prog
w_get_sha256sum "$0"
echo "$WINETRICKS_VERSION - sha256sum: $_W_gotsha256sum"
}
# Run a small wine command for internal use
# Handy place to put small workarounds
winetricks_early_wine()
{
# The sed works around https://bugs.winehq.org/show_bug.cgi?id=25838
# which unfortunately got released in wine-1.3.12
# We would like to use DISPLAY= to prevent virtual desktops from
# popping up, but that causes AutoHotKey's tray icon to not show up.
# We used to use WINEDLLOVERRIDES=mshtml= here to suppress the Gecko
# autoinstall, but that yielded wineprefixes that *never* autoinstalled
# Gecko (winezeug bug 223).
# The tr removes carriage returns so expanded variables don't have crud on the end
# The grep works around using new wineprefixes with old wine
WINEDEBUG=-all "$WINE" "$@" 2> "$W_TMP_EARLY"/early_wine.err.txt | ( sed 's/.*1h.=//' | tr -d '\r' | grep -v -e "Module not found" -e "Could not load wine-gecko" || true)
}
winetricks_detect_gui()
{
if test -x "$(command -v zenity 2>/dev/null)"; then
WINETRICKS_GUI=zenity
WINETRICKS_GUI_VERSION="$(zenity --version)"
WINETRICKS_MENU_HEIGHT=500
WINETRICKS_MENU_WIDTH=1010
elif test -x "$(command -v kdialog 2>/dev/null)"; then
echo "Zenity not found! Using kdialog as poor substitute."
WINETRICKS_GUI=kdialog
WINETRICKS_GUI_VERSION="$(kdialog --version)"
else
echo "No arguments given, so tried to start GUI, but zenity not found."
echo "Please install zenity if you want a graphical interface, or "
echo "run with --help for more options."
exit 1
fi
# Print zenity/dialog version info for debugging:
if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
echo "winetricks GUI enabled, using $WINETRICKS_GUI $WINETRICKS_GUI_VERSION"
fi
}
# Detect which sudo to use
winetricks_detect_sudo()
{
WINETRICKS_SUDO=sudo
if test "$WINETRICKS_GUI" = "none"; then
return
fi
if test x"$DISPLAY" != x""; then
# This should be the default option because some of GUI sudo programs are unmaintained
# See https://github.com/Winetricks/winetricks/issues/912
if test -x "$(command -v pkexec 2>/dev/null)"; then
# Maintained and recommended, part of Polkit, desktop-independent
# Usage: pkexec command ...
WINETRICKS_SUDO=pkexec
# Austin said "gksu*/kdesu* should stay (at least for a while)" in Feb 2018
# See https://github.com/Winetricks/winetricks/pull/915#issuecomment-362984379
elif test -x "$(command -v gksudo 2>/dev/null)"; then
# Unmaintained [2009], part of gksu
# Usage: gksudo "command ..."
WINETRICKS_SUDO=gksudo
elif test -x "$(command -v kdesudo 2>/dev/null)"; then
# Unmaintained [2015] (latest is for KDE4, no KF5 version available)
# https://cgit.kde.org/kdesudo.git/
# Usage: kdesudo "command ..."
WINETRICKS_SUDO=kdesudo
# fall back to the su versions if sudo isn't available (Fedora, etc.):
elif test -x "$(command -v gksu 2>/dev/null)"; then
# Unmaintained [2009]
# Usage: gksu "command ..."
WINETRICKS_SUDO=gksu
elif test -x "$(command -v kdesu 2>/dev/null)"; then
# Maintained, KF5 version available
# https://cgit.kde.org/kdesu.git/
# Usage: kdesu -c "command ..."
WINETRICKS_SUDO=kdesu
fi
fi
}
# Detect which iso mount tool to use
winetricks_detect_iso_mount()
{
if test -x "$(command -v fuseiso 2>/dev/null)"; then
# File/dir names are converted to lowercase
WINETRICKS_ISO_MOUNT=fuseiso
elif test -x "$(command -v archivemount 2>/dev/null)"; then
# File/dir names may be uppercase and we may need
# case-insensitive operations
# e.g. w_try "$WINE" cmd /c "copy $W_ISO_MOUNT_LETTER:\\DOC.PDF C:\\doc.pdf"
# This tool had path issue in 0.8.8 or older versions
# e.g. office2013pro works in 0.8.9 or later but doesn't work in 0.8.8
WINETRICKS_ISO_MOUNT=archivemount
elif test -x "$(command -v hdiutil 2>/dev/null)"; then
# File/dir names may be uppercase (same as archivemount)
WINETRICKS_ISO_MOUNT=hdiutil
else
WINETRICKS_ISO_MOUNT=none
fi
# Notes about other tools:
# fuseiso9660: may append ";1" to filenames
# unar: the drive icon is not "optical drive + disc" in Wine Explorer
# and "wine eject" command fails
}
winetricks_get_prefix_var()
{
(
# shellcheck disable=SC1090
. "$W_PREFIXES_ROOT/$p/wrapper.cfg"
# The cryptic sed is there to turn ' into '\''
# shellcheck disable=SC1117
eval echo \$ww_"$1" | sed "s/'/'\\\''/"
)
}
# Display prefix menu, get which wineprefix the user wants to work with
winetricks_prefixmenu()
{
case $LANG in
ru*) _W_msg_title="Winetricks - выберите путь wine (wineprefix)"
_W_msg_body='Что вы хотите сделать?'
_W_msg_apps='Установить программу'
_W_msg_games='Установить игру'
_W_msg_benchmarks='Установить приложение для оценки производительности'
_W_msg_default="Выберите путь для wine по умолчанию"
_W_msg_mkprefix="Создать новый путь wine"
_W_msg_unattended0="Отключить автоматическую установку"
_W_msg_unattended1="Включить автоматическую установку"
_W_msg_help="Просмотр справки (в веб-браузере)"
;;
uk*) _W_msg_title="Winetricks - виберіть wineprefix"
_W_msg_body='Що Ви хочете зробити?'
_W_msg_apps='Встановити додаток'
_W_msg_games='Встановити гру'
_W_msg_benchmarks='Встановити benchmark'
_W_msg_default="Вибрати wineprefix за замовчуванням"
_W_msg_mkprefix="створити новий wineprefix"
_W_msg_unattended0="Вимкнути автоматичне встановлення"
_W_msg_unattended1="Увімкнути автоматичне встановлення"
_W_msg_help="Переглянути довідку"
;;
zh_CN*) _W_msg_title="Winetricks - 选择一个 Wine 容器"
_W_msg_body='您想要做什么?'
_W_msg_apps='安装一个 Windows 应用'
_W_msg_games='安装一个游戏'
_W_msg_benchmarks='安装一个基准测试软件'
_W_msg_default="选择默认的 Wine 容器"
_W_msg_mkprefix="创建新的 Wine 容器"
_W_msg_unattended0="禁用静默安装"
_W_msg_unattended1="启用静默安装"
_W_msg_help="查看帮助"
;;
zh_TW*|zh_HK*) _W_msg_title="Winetricks - 選取一個 Wine 容器"
_W_msg_body='您想要做什麼?'
_W_msg_apps='安裝一個 Windows 應用'
_W_msg_games='安裝一個遊戲'
_W_msg_benchmarks='安裝一個基准測試軟體'
_W_msg_default="選取預設的 Wine 容器"
_W_msg_mkprefix="建立新的 Wine 容器"
_W_msg_unattended0="禁用靜默安裝"
_W_msg_unattended1="啟用靜默安裝"
_W_msg_help="檢視輔助說明"
;;
de*) _W_msg_title="Winetricks - wineprefix auswählen"
_W_msg_body='Was möchten Sie tun?'
_W_msg_apps='Ein Programm installieren'
_W_msg_games='Ein Spiel installieren'
_W_msg_benchmarks='Einen Benchmark-Test installieren'
_W_msg_default="Standard wineprefix auswählen"
_W_msg_mkprefix="Neuen wineprefix erstellen"
_W_msg_unattended0="Automatische Installation deaktivieren"
_W_msg_unattended1="Automatische Installation aktivieren"
_W_msg_help="Hilfe anzeigen"
;;
pl*) _W_msg_title="Winetricks - wybierz prefiks Wine"
_W_msg_body='Co chcesz zrobić?'
_W_msg_apps='Zainstalować aplikację'
_W_msg_games='Zainstalować grę'
_W_msg_benchmarks='Zainstalować program sprawdzający wydajność komputera'
_W_msg_default="Wybrać domyślny prefiks Wine"
_W_msg_mkprefix="Stwórz nowy prefiks Wine"
_W_msg_unattended0="Wyłącz cichą instalację"
_W_msg_unattended1="Włącz cichą instalację"
_W_msg_help="Wyświetl pomoc"
;;
*) _W_msg_title="Winetricks - choose a wineprefix"
_W_msg_body='What do you want to do?'
_W_msg_apps='Install an application'
_W_msg_games='Install a game'
_W_msg_benchmarks='Install a benchmark'
_W_msg_default="Select the default wineprefix"
_W_msg_mkprefix="Create new wineprefix"
_W_msg_unattended0="Disable silent install"
_W_msg_unattended1="Enable silent install"
_W_msg_help="View help"
;;
esac
case "$W_OPT_UNATTENDED" in
1) _W_cmd_unattended=attended; _W_msg_unattended="$_W_msg_unattended0" ;;
*) _W_cmd_unattended=unattended; _W_msg_unattended="$_W_msg_unattended1" ;;
esac
case $WINETRICKS_GUI in
zenity)
printf %s "zenity \
--title '$_W_msg_title' \
--text '$_W_msg_body' \
--list \
--radiolist \
--column '' \
--column '' \
--column '' \
--height $WINETRICKS_MENU_HEIGHT \
--width $WINETRICKS_MENU_WIDTH \
--hide-column 2 \
FALSE help '$_W_msg_help' \
FALSE apps '$_W_msg_apps' \
FALSE benchmarks '$_W_msg_benchmarks' \
FALSE games '$_W_msg_games' \
TRUE main '$_W_msg_default' \
FALSE mkprefix '$_W_msg_mkprefix' \
" \
> "$WINETRICKS_WORKDIR"/zenity.sh
if ls -d "$W_PREFIXES_ROOT"/*/dosdevices > /dev/null 2>&1; then
for prefix in "$W_PREFIXES_ROOT"/*/dosdevices
do
q="${prefix%%/dosdevices}"
p="${q##*/}"
if test -f "$W_PREFIXES_ROOT/$p/wrapper.cfg"; then
_W_msg_name="$p ($(winetricks_get_prefix_var name))"
else
_W_msg_name="$p"
fi
case $LANG in
zh_CN*) printf %s " FALSE prefix='$p' '选择管理 $_W_msg_name' " ;;
zh_TW*|zh_HK*) printf %s " FALSE prefix='$p' '選擇管理 $_W_msg_name' " ;;
de*) printf %s " FALSE prefix='$p' '$_W_msg_name auswählen' " ;;
pl*) printf %s " FALSE prefix='$p' 'Wybierz $_W_msg_name' " ;;
*) printf %s " FALSE prefix='$p' 'Select $_W_msg_name' " ;;
esac
done >> "$WINETRICKS_WORKDIR"/zenity.sh
fi
printf %s " FALSE $_W_cmd_unattended '$_W_msg_unattended'" >> "$WINETRICKS_WORKDIR"/zenity.sh
sh "$WINETRICKS_WORKDIR"/zenity.sh | tr '|' ' '
;;
kdialog)
(
printf %s "kdialog \
--geometry 600x400+100+100 \
--title '$_W_msg_title' \
--separate-output \
--radiolist '$_W_msg_body' \
help '$_W_msg_help' off \
games '$_W_msg_games' off \
benchmarks '$_W_msg_benchmarks' off \
apps '$_W_msg_apps' off \
main '$_W_msg_default' on \
mkprefix '$_W_msg_mkprefix' off \
"
if ls -d "$W_PREFIXES_ROOT"/*/dosdevices > /dev/null 2>&1;