/
winetricks
executable file
·20127 lines (17356 loc) · 720 KB
/
winetricks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/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=20180603-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.
# - sha256sum, sha256, or shasum (OSX 10.5 does not support these, 10.6+ is required):
# note: some legacy verbs may still use sha1sum, sha1, or shasum, but this is
# deprecated and will be removed in a future release.
# - zenity is needed by the GUI, though it can limp along somewhat with kdialog/xmessage.
# - xdg-open (if present) or open (for OS X) is used to open download pages
# for the user when downloads cannot be fully automated.
# - 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.
# - fuseiso, archivemount (Linux), or hdiutil (macOS) is used to mount .iso images.
# - perl is used to munge steam config files.
# - torify is used with option "--torify" if sites are blocked in single countries.
# On Ubuntu, the following lines can be used to install all the prerequisites:
# sudo add-apt-repository ppa:ubuntu-wine/ppa
# sudo apt-get update
# sudo apt-get install binutils cabextract p7zip-full unrar unzip wget wine 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 p7zip-plugins unrar unzip wget wine zenity
#
# See http://winetricks.org for documentation and tutorials, including
# how to contribute changes to winetricks.
#
#--------------------------------------------------------------------
#
# Copyright:
# Copyright (C) 2007-2014 Dan Kegel <dank!kegel.com>
# Copyright (C) 2008-2017 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
# http://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 "$(which 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 [ ! "$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 [ ! "$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)
}
# 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_die "Ten pakiet ($W_PACKAGE) nie działa z 64-bitową instalacją. Musisz użyć prefiksu utworzonego z WINEARCH=win32." ;;
ru*) w_die "Данный пакет не работает в 64-битном окружении. Используйте префикс, созданный с помощью WINEARCH=win32." ;;
*) w_die "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
printf '%s\n' "Executing $*"
# 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 test -x "$(which 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 test -x "$(which 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 "$(which 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
_W_src_files=$(find "$_W_src_dir" -maxdepth 1 -type f -iname "$_W_pattern")
for _W_src_file in $_W_src_files; do
# 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 '{}' ';'
w_try cp -f "$_W_src_file" "$_W_dest_dir/$_W_file_name"
done
# Wait for Wine to add the new font to the registry under HKCU\Software\Wine\Fonts\Cache
w_wineserver -w
unset _W_src_files _W_dest_dir _W_src_file _W_file_name
}
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_unrar()
{
# $1 - zipfile to extract (keeping internal paths, in cwd)
# Not always installed, use Windows 7-Zip as a fallback:
if test -x "$(which 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 test -x "$(which 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 sha1sum string and set $_W_gotsha1um to it
w_get_sha1sum()
{
_W_sha1_file="$1"
# See https://github.com/Winetricks/winetricks/issues/645
# User is running winetricks from /dev/stdin
if [ -f "$_W_sha1_file" ] || [ -h "$_W_sha1_file" ] ; then
_W_gotsha1sum=$($WINETRICKS_SHA1SUM < "$_W_sha1_file" | sed 's/(stdin)= //;s/ .*//')
w_get_sha256sum "$_W_sha1_file"
else
w_warn "$_W_sha1_file is not a regular file, not checking sha1sum"
return
fi
w_warn "sha1sum is considered deprecated and should no longer be used. This package (${W_PACKAGE}) still uses it. This is a bug."
w_warn "See https://github.com/Winetricks/winetricks/issues/737 and https://shattered.io/"
w_warn "Please report the following to https://github.com/Winetricks/winetricks/: file:${_W_sha1_file} sha1: ${_W_gotsha1sum} sha256:${_W_gotsha256sum}"
}
# 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" ;;
40) _W_shatype="sha1" ;;
64) _W_shatype="sha256" ;;
# 128) sha512..
*) w_die "unsupported shasum..bug" ;;
esac
}
# FIXME: remove 2018/04/01 (or 03/31 or 4/2, to avoid April Fools comments), along with any remaining unfixed verbs
# verify a sha1sum
w_verify_sha1sum()
{
_W_vs_wantsum=$1
_W_vs_file=$2
w_get_sha1sum "$_W_vs_file"
if [ "$_W_gotsha1sum"x != "$_W_vs_wantsum"x ] ; then
case $LANG in
pl*) w_die "Niezgodność sumy sha1sum! Zmień nazwę $_W_vs_file i spróbuj ponownie." ;;
ru*) w_die "Контрольная сумма sha1sum не совпадает! Переименуйте файл $_W_vs_file и попробуйте еще раз." ;;
*) w_die "sha1sum mismatch! Rename $_W_vs_file and try again." ;;
esac
fi
unset _W_vs_wantsum _W_vs_file _W_gotsha1sum
}
# 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" ;;
sha1) w_verify_sha1sum "$_W_sum" "$_W_vs_file" ;;
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" ;;
*) 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