-
Notifications
You must be signed in to change notification settings - Fork 0
/
dowine
executable file
·337 lines (309 loc) · 10.9 KB
/
dowine
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
#!/bin/sh
case "$1" in
--help|-h*) cat <<EOF
Usage:
$0 [<opts>] <exec>
<exec> is either winetricks, some Wine exec (e.g. winecfg), or some .exe
Forces WINEARCH for the program if detected in registry; otherwise
respects WINEARCH, if set (i.e., use WINEARCH=win64 for 64-bit)
opts:
-c Use wineconsole instead of wine
-w Use wine-wait instead of wine (for programs that run in background)
-nc Keep current directory with more recent wine
-n Allow built-in mono (.net) install/usage
-g Allow built-in gecko install/usage
-b install/uninstall built-in mono/gecko based on current flags
-k Kill wine
-m Mount windows overlay
-M Dismount windows overlay
-d use wine-vanilla (latest development)
-S use wine-staging (latest staging) [may be older than -d]
-s use wine (current stable) (default)
-s2 use wine-2 (stable - 2.0.x)
-s3 use wine-3 (stable - 3.0.x)
-s4 use wine-4 (stable - 4.0.x)
-s5 use wine-5 (stable - 5.0.x)
-s6 use wine-6 (stable - 6.0.x)
-s7 use wine (stable 7.0.x)
-D use winedbg/gdb
-V <exe> use <exe> as wine; may not work right
EOF
exit 0 ;;
esac
# My wine prefixes operate as follows:
# - main prefix is some subdir of a dir named wine
# - reference prefix for current wine version is ~/.wine-ver or ~/.wine64-ver
# - reference prefix's windows is overlayed onto main prefix's windows
# writable version is .windows
# assumes following patches to wine:
# - use real dirs instead of soft links for user dirs
# - don't create z: link to /
# TODO: fix .msi files for gecko/mono intalls (but nothing I run now uses
# them anyway, so who cares?)
# if gecko/mono updated, uninstall before update and then reinstall
# add option to mount/unumount .windows dir
# figure out how to override users/<yname> and mount that as well
# Add option to pick wine version (d3d9/any/vanilla; specific version)
# Prevent Wine from adding menu entries and desktop links.
export WINEDLLOVERRIDES="${WINEDLLOVERRIDES}${WINEDLLOVERRIDES:+;}winemenubuilder.exe=d"
# quiet all but final run of wine
wdb="$WINEDEBUG"
export WINEDEBUG=fixme-all
test win64 = "$WINEARCH" || export WINEARCH=win32
prg=wine
wp=wine
dis_mono=y
dis_gecko=y
builtin_inst=
kill_wine=
mnt_wine=
no_cd=
while :; do
case "$1" in
-S) wp=wine-staging ;;
-d) wp=wine-vanilla ;;
-s2) wp=wine-2 ;;
-s3) wp=wine-3 ;;
-s4) wp=wine-4 ;;
-s5) wp=wine-5 ;;
-s6) wp=wine-6 ;;
-s|-s7) wp=wine ;;
-V) wp="$2" ; shift ;;
-m) mnt_wine=y ;;
-M) mnt_wine=d ;;
-c) prg=wineconsole ;;
-nc) no_cd=y ;;
-w)
prg=wine-wait ;;
-D)
prg=winedbg\ --gdb ;;
-n)
dis_mono= ;;
-g)
dis_gecko= ;;
-b)
builtin_inst=y ;;
-k)
kill_wine=y ;;
*) break ;;
esac
shift
done
winever="`$wp --version`"
winever="${winever%% *}"
winever="${winever#wine-}"
wpver="${wp%-[0-9]*}" # strip off explicit ver from -V
wpver="${wpver#wine}"
test -n "$wpver" || type wineserver"$wpver"-"$winever" >/dev/null 2>&1 || wpver=-vanilla
wpver="$wpver-$winever"
prefix_setup() {
(
# just verify wine installation in current dir
# do an init/update
cd "${WINEPREFIX%/windows}"
# I suppose there is a "better" more official way to do this, but I'm
# not going to dive into the code and "documentation" to find it.
$wp regedit /\? >/dev/null 2>&1
wineserver$wpver -w
# exit if update rather than init
test -d windows/drive_c || return
# my prefix has config in windows subdir and drive_c in main dir
# so move things around after init
mv windows .windows
# The use of .[^.]* is supposed to move the drive serial #, but that
# doesn't seem to be created any more. 2>/dev/null suppresses the error.
mv .windows/drive_c/{.[^.],}* . 2>/dev/null
rmdir .windows/drive_c
mv .windows/{.[^.],}* windows 2>/dev/null
rmdir .windows
rm windows/dosdevices/c:
ln -s ../.. windows/dosdevices/c:
# don't do the other stuff for reference prefixes
# especially replacing the library stubs below
test -n "$1" && return
# enable wine-9 (will autodetect backend, so no need to set in registry)
# using standalone configurator program creates z: and other crap, so don't
# enable dxvk (FIXME: supposedly d3d10 overrides no longer needed)
# set default GOG installer options
# enable opengl 4.6 (probably not needed any more and maybe counterproductive)
# attempt to set USERPROFILE dir (doesn't work)
cat <<"EOF" > $$.reg
REGEDIT4
[HKEY_CURRENT_USER\Software\Wine\DllOverrides]
"d3d9"="n"
"d3d11"="n,b"
"dxgi"="n,b"
"d3d10"="n,b"
"d3d10_1"="n,b"
"d3d10core"="n,b"
[HKEY_LOCAL_MACHINE\Software\GOG.com]
"DefaultPackPath"="C:\\"
"DesktopIcon"="OFF"
[HKEY_LOCAL_MACHINE\Software\Wow6432Node\GOG.com]
"DefaultPackPath"="C:\\"
"DesktopIcon"="OFF"
[HKEY_CURRENT_USER\Software\Wine\Direct3D]
"csmt"=dword:00000001
"MaxVersionGL"=dword:00040006
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment]
"USERPROFILE"="C:\\users\\user"
EOF
$wp regedit $$.reg
rm $$.reg
# wine-nine files
# dxvk files
if [ -d ../../win/dxvk ]; then
windir="../../../../win"
else
windir="$HOME/games/win"
fi
mkdir -p windows/system32
if [ win64 = "$WINEARCH" ]; then
# I guess syswow64 is actually the 32-bit stuff, and system32 is 64-bit
(cd windows/system32 && ln -sf "$windir"/dxvk/x64/* .)
# as of dxvk-1.5, d9vk is included. For now, I choose d3d9-nine.
ln -sf /usr/lib64/d3d9-nine.dll.so windows/system32/d3d9.dll
mkdir -p windows/syswow64
(cd windows/syswow64 && ln -sf "$windir"/dxvk/x32/* .)
# as of dxvk-1.5, d9vk is included. For now, I choose d3d9-nine.
ln -sf /usr/lib32/d3d9-nine.dll.so windows/syswow64/d3d9.dll
else
(cd windows/system32 && ln -sf "$windir"/dxvk/x32/* .)
# as of dxvk-1.5, d9vk is included. For now, I choose d3d9-nine.
ln -sf /usr/lib32/d3d9-nine.dll.so windows/system32/d3d9.dll
fi
)
}
# figure out wine prefix from dir program runs from
# assumes parent dir is wine (e.g. wine/prefix1 wine/prefix2 ...)
case "$1" in
*/winetricks) d="$PWD" ;;
/*) d="${1%/*}" ;;
*/*) d="$PWD/${1%/*}" ;;
*) d="$PWD" ;;
esac
while :; do
case "$d" in
*/wine/*/*) d="${d%/*}" ;;
*/wine/*) break ;;
*) echo "Wine path unknown."; exit 1 ;;
esac
done
export WINEPREFIX="$d/windows"
# force WINEARCH based on user.reg, if present
# even if set in env, it may be wrong, so ignore
#if [ -z "$WINEARCH" ]; then
a=`head -n 5 "${WINEPREFIX%windows}".windows/user.reg 2>/dev/null | grep '^#arch=' | cut -d= -f2`
test -n "$a" && export WINEARCH="$a"
#fi
# not sure why I set LIBGL_DRIVERS_PATH explicitly, but I used to do
# it in a separate wrapper around wine, and now I've moved that here
if [ win64 = "$WINEARCH" ]; then
wp=wine64${wp#wine}
export LIBGL_DRIVERS_PATH=/usr/lib64/dri
else
export LIBGL_DRIVERS_PATH=/usr/lib32/dri
fi
# some games seem to use both, so I'll override the above
export LIBGL_DRIVERS_PATH=/usr/lib32/dri:/usr/lib64/dri
test wine = "$prg" && prg=$wp
if [ -n "$kill_wine" ]; then
wineserver$wpver -k
exit $?
fi
# set up reference dir
refdir="$HOME/.${wp%-[0-9]*}-${winever}"
test -d "$refdir" || mkdir "$refdir"
(WINEPREFIX="$refdir/windows" prefix_setup n)
# Prevent Wine from auto-installing gecko & mono
test -n "$dis_mono" && WINEDLLOVERRIDES="${WINEDLLOVERRIDES};mscoree.dll=n"
test -n "$dis_gecko" && WINEDLLOVERRIDES="${WINEDLLOVERRIDES};mshtml.dll=n"
# piece of shit gentoo claims to only support /proc/mounts link now, but
# yet somehow it keeps reverting to a file
# having as a file ignores fusermounts
test -h /etc/mtab || sudo ln -sf /proc/mounts /etc/mtab
# automatically generate/update prefix before starting app
# note that "fusermount -u" won't work if /etc/mtab isn't /proc/mounts
fusermount -u "$WINEPREFIX" 2>/dev/null
test d = "$mnt_wine" && exit 0
wdir="${WINEPREFIX%/windows}"/.windows
if [ ! -d "$wdir" ]; then
prefix_setup
wineserver$wpver -k
mv "$WINEPREFIX" "$wdir"
mkdir "$WINEPREFIX"
else
test -f "$WINEPREFIX"/system.reg || unionfs -o cow,nonempty,uid=$(id -u) "$wdir=RW:$refdir/windows=RO" "$WINEPREFIX" || exit 1
prefix_setup
wineserver$wpver -k
fusermount -u "$WINEPREFIX" 2>/dev/null # don't want to mess in wdir while mounted
fi
# always recheck wdir - maybe too slow for comfort
# then again, running prefix_setup twice is the real slowdown
find "$wdir" -type f | while read -r x; do
cmp "$x" "$refdir/windows/${x#$wdir}" >/dev/null 2>&1 && rm "$x"
done
rm -f "$wdir"/dosdevices/c:
find "$wdir" -depth -type d | while read -r x; do
test -d "$refdir/windows/${x#$wdir}" && rmdir "$x" 2>/dev/null
done
test -f "$WINEPREFIX"/system.reg || unionfs -o cow,nonempty,uid=$(id -u) "$wdir=RW:$refdir/windows=RO" "$WINEPREFIX" || exit 1
test y = "$mnt_wine" && exit 0
if [ -n "$builtin_inst" ]; then
# This automatically installs gecko/mono if requested and not already done
test -z "$dis_mono" -a ! -d "$d/.windows/mono" && rm -f "$d/windows/.update-timestamp"
test -z "$dis_gecko" -a ! -d "$d"/.windows/system32/gecko/*/wine_gecko && rm -f "$d/windows/.update-timestamp"
# And this ensures that gecko/mono is *not* installed if not requested
case "$1" in
*.[eE][xX][eE])
if [ -n "$dis_mono" -a -d "$d/windows/mono" ]; then
echo "Mono installed, but not explicitly enabled with -m"
wine uninstaller >/dev/null 2>&1
test -d "$d/windows/mono" && exit 1
fi
if [ -n "$dis_gecko" -a -d "$d"/windows/system32/gecko/*/wine_gecko ]; then
echo "Gecko installed, but not explicitly enabled with -g"
wine uninstaller >/dev/null 2>&1
test -d "$d"/windows/system32/gecko/*/wine_gecko && exit 1
fi
;;
esac
fi
case "$1" in
"") : ;;
winetricks|*/winetricks) env WINE="$wp" WINESERVER="wineserver$wpver" "$@"; ret=$? ;;
*) rm -f reg.[0-9]*.diff # ignore old diffs; probably not worth reading
$wp regedit -E c:\\reg.$$
if [ -f wine-keys.exe ]; then
echo Running wine-keys
nonet $wp wine-keys.exe & pidk=$!
else
pidk=
fi
test wine-wait = "$prg" && set -- -e "$wpver" "$@"
test wineconsole = "$prg" && prg="${prg}${wpver}"
# recent wine no longer changes to program dir by default
# this can be good, but it breaks some of my old scripts
if [ -z "$no_cd" ]; then
case "$1" in
*[/\\]*) pn="${1##*[/\\]}"; pp="${1%[/\\]*}"; shift; set -- "$pn" "$@"
pp="${pp//\\//}"; cd "$pp" ;;
*) pp= ;;
esac
fi
nonet env LD_PRELOAD="$LD_PRELOAD" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" WINEDEBUG="$wdb" $prg "$@" & pid=$!
if [ -z "$no_cd" -a -n "$pp" ]; then
pp="${pp//[^\/]}"
cd "${pp//\//../}"
fi
trap "kill $pid $pidk; wineserver$wpver -k" TERM
wait $pid; ret=$?
test -n "$pidk" && kill $pidk
$wp regedit -E c:\\reg.$$.new
diff -au "$d/reg.$$" "$d/reg.$$.new" >"$d/reg.$$.diff"
rm "$d/reg.$$" "$d/reg.$$.new"
test -s "$d/reg.$$.diff" || rm "$d/reg.$$.diff" ;;
esac
wineserver$wpver -k
fusermount -u "$WINEPREFIX"
exit $ret