advapi32/tests: Fix memory leaks (found by Smatch).
[wine] / programs / winelauncher.in
1 #!/bin/sh
2 #------------------------------------------------------------------------------
3 #   Winelauncher
4 #       This shell script attempts to intelligently manage the process
5 #   of launching a program with Wine.  It adds some level of
6 #   visual feedback to an end user.
7 #
8 #   Usage:
9 #       winelauncher [options]  "<windows program> [program arguments]"
10 #
11 #       This script is meant to be installed to /usr/bin/wine, and
12 #   to be used to invoke a Windows executable.
13 #       The options are passed through directly to Wine, and are
14 #   documented in the Wine man page.
15 #
16 #   Copyright (c) 2000 by Jeremy White for CodeWeavers
17 #
18 # This library is free software; you can redistribute it and/or
19 # modify it under the terms of the GNU Lesser General Public
20 # License as published by the Free Software Foundation; either
21 # version 2.1 of the License, or (at your option) any later version.
22 #
23 # This library is distributed in the hope that it will be useful,
24 # but WITHOUT ANY WARRANTY; without even the implied warranty of
25 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26 # Lesser General Public License for more details.
27 #
28 # You should have received a copy of the GNU Lesser General Public
29 # License along with this library; if not, write to the Free Software
30 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #------------------------------------------------------------------------------
32
33 #------------------------------------------------------------------------------
34 #  Primary configuration area - change this if you installed Wine to
35 #    a different location
36 #------------------------------------------------------------------------------
37 WINEBIN=@bindir@
38 WINELIB=@libdir@
39 WINESERVER=
40 WINEDLLPATH=@dlldir@
41
42 #------------------------------------------------------------------------------
43 #  Establish Color Scheme
44 #------------------------------------------------------------------------------
45 COLOR=' -xrm *.Command.background:darkgrey
46 -xrm *.Command.foreground:black
47 -xrm *.Text.background:black
48 -xrm *.Text.foreground:green
49 -xrm *.Form.background:grey
50 -xrm *.Form.foreground:green
51 -xrm *.foreground:green
52 -xrm *.background:black'
53
54
55 #------------------------------------------------------------------------------
56 #  Locate either xmessage or gmessage, if we can.
57 #------------------------------------------------------------------------------
58 type xmessage >/dev/null 2>/dev/null
59 if [ $? -ne 0 ] ; then
60     # xmessage not found; make sure the user notices this error
61     # (GUI users wouldn't even notice if we printed the text on console !)
62     MSGFILE=`mktemp "/tmp/wine.xmessage.XXXXXX"`
63     cat > $MSGFILE <<EOF
64 Warning:
65     The Wine launcher is unable to find the xmessage program,
66     which it needs to properly notify you of Wine execution status
67     or problems.
68
69     This launcher script relies heavily on finding this tool,
70     and without it, it will behave very poorly.
71
72     We strongly recommend that you use your distribution's
73     software methods to locate xmessage, or alternatively
74     use your favourite internet search engine to find out
75     how you are supposed to install xmessage on your system.
76 EOF
77
78     # try to display message file with tons of different X11 editors
79     # until we find one that's installed and working
80     for EDITPRG in nedit gedit kedit gvim xemacs; do
81       type $EDITPRG >/dev/null 2>/dev/null
82       if [ $? -eq 0 ] ; then
83         # execute editor and exit if successful
84         $EDITPRG $MSGFILE && exit
85       fi
86     done
87
88     # ok, we really give up now, this system is hosed ;-)
89     cat $MSGFILE
90     rm $MSGFILE
91 else
92     XMESSAGE="xmessage $COLOR"
93 fi
94
95 #------------------------------------------------------------------------------
96 #  We're going to do a lot of fancy footwork below.
97 #    Before we get started, it would be nice to know the argv0
98 #    of the actual script we're running (and lets remove at least
99 #    one level of symlinking).
100 #------------------------------------------------------------------------------
101 argv0_path=`which $0`
102 if [ -z $argv0_path ] ; then
103     argv0_path=$0
104 fi
105
106 real_name=`find $argv0_path -type l -printf "%l\n"`
107 if [ ! $real_name ]; then
108     real_name=$argv0_path
109 elif [ ! -x $real_name ]; then
110     real_name=`find $argv0_path -printf "%h\n"`/$real_name
111 fi
112
113 argv0_dir=`find $real_name -printf "%h\n"`
114
115 if [ -z $argv0_dir ] ; then
116     argv0_dir=.
117 fi
118
119 #------------------------------------------------------------------------------
120 #  Okay, now all that junk above was established at configure time.
121 #   However, if this is an RPM install, they may have chosen
122 #   to relocate this installation.  If so, that stuff above
123 #   is all broken and we should rejigger it.
124 #------------------------------------------------------------------------------
125 WINE_BIN_NAME=wine.bin
126 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
127     WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
128 fi
129
130 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
131     WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
132 fi
133
134 if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
135     WINE_BIN_NAME=wine
136     if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
137         WINEBIN=`find $argv0_dir -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
138     fi
139
140     if [ ! -x $WINEBIN/$WINE_BIN_NAME ] ; then
141         WINEBIN=`find $argv0_dir/../ -maxdepth 1 -perm +0111 -type f -name "$WINE_BIN_NAME" -printf "%h\n" | head -n 1`
142     fi
143 fi
144
145 if [ ! -r $WINELIB/libwine.so ] ; then
146     WINELIB=`find $argv0_dir -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -n 1`
147 fi
148
149 if [ ! -r $WINELIB/libwine.so ] ; then
150     WINELIB=`find $argv0_dir/../ -maxdepth 2 -name 'libwine.so' -printf "%h\n" | head -n 1`
151 fi
152
153 if [ -x $WINEBIN/wineserver ] ; then
154     WINESERVER=$WINEBIN/wineserver
155 fi
156
157 #------------------------------------------------------------------------------
158 #  Hey, if we built Wine from source, let's add a little extra fun to
159 #   mix it up a bit
160 #------------------------------------------------------------------------------
161 if [ -x $WINEBIN/server/wineserver ] ; then
162     WINESERVER=$WINEBIN/server/wineserver
163 fi
164
165 if [ -r $WINELIB/dlls/ntdll.dll.so ] ; then
166     WINEDLLPATH=$WINELIB/dlls
167 fi
168
169
170 #------------------------------------------------------------------------------
171 #  Okay, set the paths and move on.
172 #------------------------------------------------------------------------------
173 if [ -n "$LD_LIBRARY_PATH" ]; then
174         export LD_LIBRARY_PATH=$WINELIB:$LD_LIBRARY_PATH
175 else
176         export LD_LIBRARY_PATH=$WINELIB
177 fi
178 export PATH=$WINEBIN:$PATH
179 export WINELOADER=$WINEBIN/$WINE_BIN_NAME
180 export WINEDLLPATH
181 export WINESERVER
182
183 info_flag=~/.wine/.no_prelaunch_window_flag
184 debug_flag=~/.wine/.no_debug_window_flag
185 debug_options="warn+all"
186
187 if [ -f $info_flag ] ; then
188     use_info_message=0
189 else
190     use_info_message=1
191 fi
192
193 if [ -f $debug_flag ] ; then
194     use_debug_message=0
195 else
196     use_debug_message=1
197 fi
198
199
200 #------------------------------------------------------------------------------
201 #  Handle winelib apps going through here
202 #------------------------------------------------------------------------------
203 winelib=0
204 if [ -f $argv0_path.so ] ; then
205     winelib=1
206     export WINEPRELOAD=$argv0_path.so
207 fi
208
209
210 #------------------------------------------------------------------------------
211 #  No arguments?  Help 'em out
212 #------------------------------------------------------------------------------
213 always_see_output=0
214 no_args=0
215 if [ $# -eq 0 ] ; then
216     no_args=1
217 fi
218
219 if [ $# -eq 1 -a "$1" = "" ] ; then
220     no_args=1
221 fi
222
223 if [ $winelib -eq 1 ] ; then
224     no_args=0
225 fi
226
227 if [ $no_args -eq 1 ] ; then
228     echo "Wine called with no arguments."
229     echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
230     $XMESSAGE -buttons "    Okay    ":0," See the Wine Usage Statement ":1,"  Configure Wine  ":2 \
231         -title "Welcome to Wine" \
232         "
233
234         You have started Wine without specifying any arguments.
235
236         Wine requires at least one argument - the name of the Windows
237         application you would like to run.
238
239         If you have launched this through the KDE menu system
240         and your KDE installation is specially configured for Wine,
241         then you can use the KDE file browser to select a Windows
242         executable and then click on it to launch Wine with
243         that application.
244
245         You can similarly use the GNOME file manager to
246         select a Windows executable and double click on it.
247
248         If you would like to see the command line arguments
249         for Wine, select the second option, below.
250
251         "
252     welcome_rc=$?
253     if [ $welcome_rc -eq 0 ] ; then
254         exit
255     fi
256
257     if [ $welcome_rc -eq 2 ] ; then
258         winecfg
259         exit
260     fi
261
262     use_info_message=0
263     always_see_output=1
264 fi
265
266 #------------------------------------------------------------------------------
267 #  Optionally Warn the user we're going to be launching Wine...
268 #------------------------------------------------------------------------------
269 if [ $use_info_message -ne 0 ] ; then
270     echo "Invoking $WINEBIN/$WINE_BIN_NAME $@ ..."
271     $XMESSAGE -timeout 30 -buttons "    Dismiss    ":0," Never display this message again ":3 \
272         -title "Wine Launch Window" \
273         "Invoking $WINEBIN/$WINE_BIN_NAME $@ ...
274
275         This dialog box is a temporary status dialog to let you know
276         that Wine is attempting to launch your application.
277
278         Since Wine is still very much in a development stage,
279         many applications will fail silently.
280         This dialog box is your indication
281         that we're *trying* to run your application.
282
283         This dialog box will automatically disappear after 30 seconds,
284         or after your application finishes.
285
286         You can permanently disable this dialog by selecting
287         the option below.
288         " &
289     info_message_pid=$!
290 fi
291
292 #------------------------------------------------------------------------------
293 #  Here's a little function to clean up after that dialog...
294 #------------------------------------------------------------------------------
295 clean_up_info_message ()
296 {
297     if [ $use_info_message -ne 0 ] ; then
298
299         #------------------------------------------------------------------------------
300         #  Okay, make sure that the notice window is dead (and kill it if it ain't)
301         #------------------------------------------------------------------------------
302         ps $info_message_pid >/dev/null 2>&1
303         if [ $? -ne 0 ] ; then
304             wait $info_message_pid
305             info_return=$?
306         else
307             info_return=0
308             kill $info_message_pid
309         fi
310
311         #------------------------------------------------------------------------------
312         #  If they didn't like the warning window, turn it off
313         #------------------------------------------------------------------------------
314         if [ $info_return -eq 3 ] ; then
315             $XMESSAGE -title "Wine Prelaunch Control" \
316             "Wine will now disable the prelaunch window you just saw.
317             You will no longer be notified when Wine is attempting
318             to start a Windows application.
319
320             Please take note that you can reenable this window
321             by removing the $info_flag file." -buttons "  Okay  ":0," Cancel ":1
322             if [ $? -eq 0 ] ; then
323                 touch $info_flag
324             fi
325         fi
326     fi
327
328     use_info_message=0
329 }
330 #------------------------------------------------------------------------------
331 #  Generate a temporary log file name
332 #------------------------------------------------------------------------------
333 if [ -n "$TMP" ] ; then
334   log_dir="$TMP"
335 else
336   log_dir="/tmp"
337 fi
338 use_log_name=0
339 log_name=`mktemp "$log_dir/wine.log.XXXXXX"`
340 if [ $? -eq 0 ] ; then
341     use_log_name=1
342 fi
343 use_status_name=0
344 status_name=`mktemp "$log_dir/wine.status.XXXXXX"`
345 if [ $? -eq 0 ] ; then
346     use_status_name=1
347 fi
348
349 #------------------------------------------------------------------------------
350 #  Okay, really launch Wine...
351 #------------------------------------------------------------------------------
352 if [ $use_log_name -ne 0 -a $use_status_name -ne 0 ] ; then
353     ( $WINEBIN/$WINE_BIN_NAME "$@"; echo $? >$status_name ) 2>&1 | tee "$log_name"
354     wine_return=`cat $status_name`
355 else
356     $WINEBIN/$WINE_BIN_NAME "$@"
357     wine_return=$?
358 fi
359 if [ $use_status_name -ne 0 ] ; then
360     rm -f $status_name
361 fi
362
363 #------------------------------------------------------------------------------
364 #  Test the return code, and see if it fails
365 #------------------------------------------------------------------------------
366 if [ $always_see_output -eq 0 -a $wine_return -eq 0 ] ; then
367     echo "Wine exited with a successful status"
368     if [ $use_log_name -ne 0 ] ; then
369         rm -f "$log_name"
370     fi
371 else
372     if [ $always_see_output -eq 0 ] ; then
373         echo "Wine failed with return code $wine_return"
374     fi
375
376     #------------------------------------------------------------------------------
377     #  Gracefully display a debug message if they like...
378     #------------------------------------------------------------------------------
379     while [ $use_debug_message -gt 0 ] ; do
380
381         #------------------------------------------------------------------------------
382         #  Build up the menu of choices they can make...
383         #------------------------------------------------------------------------------
384         BUTTONS='    Okay    :0'
385         if [ $use_log_name -ne 0 ] ; then
386             BUTTONS="$BUTTONS"', View Log :1'
387         fi
388
389         BUTTONS="$BUTTONS"',  Debug  :2'
390         BUTTONS="$BUTTONS"',  Configure :4'
391         BUTTONS="$BUTTONS"',  Disable :3'
392
393         #------------------------------------------------------------------------------
394         #  Build an error message
395         #------------------------------------------------------------------------------
396         MESSAGE="
397 Wine has exited with a failure status of $wine_return.
398
399 Wine is still development software, so there can be many
400 explanations for this problem.
401
402 You can choose to run Wine again with a higher level
403 of debug messages (the debug option, below).
404
405 You can attempt to reconfigure Wine to make it work better.
406 The Wine Configuration program can assist you in making
407 those changes (select Configure, below, for more).
408
409 You can disable this message entirely by selecting the
410 Disable option below."
411
412         if [ $always_see_output -ne 0 -a $wine_return -eq 0 ] ; then
413             MESSAGE="
414 Wine has exited with a failure status of $wine_return.
415
416 You can disable this message entirely by selecting the
417 Disable option below."
418
419         fi
420
421         if [ $use_log_name -ne 0 ] ; then
422             MESSAGE="$MESSAGE
423
424 Wine has captured a log of the Wine output in the file $log_name.
425 You may view this file by selecting View Log, below."
426         fi
427
428         #------------------------------------------------------------------------------
429         #  Display the message
430         #------------------------------------------------------------------------------
431         $XMESSAGE -title "Wine Finished With Error" -buttons "$BUTTONS" "$MESSAGE"
432         debug_return=$?
433
434         #------------------------------------------------------------------------------
435         #  Dismiss the other window...
436         #------------------------------------------------------------------------------
437         clean_up_info_message
438
439         #------------------------------------------------------------------------------
440         #  Process a configure instruction
441         #------------------------------------------------------------------------------
442         if [ $debug_return -eq 4 ] ; then
443             winecfg
444             continue;
445         fi
446
447         #------------------------------------------------------------------------------
448         #  Process a view instruction
449         #------------------------------------------------------------------------------
450         if [ $debug_return -eq 1 ] ; then
451             $XMESSAGE -title "View Wine Log" -file "$log_name" -buttons "  Okay  ":0,"Delete $log_name":1
452             if [ $? -eq 1 ] ; then
453                 echo "Deleting $log_name"
454                 rm -f "$log_name"
455                 use_log_name=0
456             fi
457         else
458             use_debug_message=0
459         fi
460
461         #------------------------------------------------------------------------------
462         #  If they didn't like the warning window, turn it off
463         #------------------------------------------------------------------------------
464         if [ $debug_return -eq 3 ] ; then
465             $XMESSAGE -title "Wine Debug Log Control" \
466             "Wine will now disable the Wine debug output control window you just saw.
467             You will no longer be notified when Wine fails to start a
468             Windows application.
469
470             Please take note that you can reenable this window
471             by removing the $debug_flag file." -buttons "  Okay  ":0," Cancel ":1
472
473             if [ $? -eq 0 ] ; then
474                 touch $debug_flag
475             fi
476
477         fi
478
479         #------------------------------------------------------------------------------
480         #  If they want to retry with debug, let 'em.
481         #------------------------------------------------------------------------------
482         if [ $debug_return -eq 2 ] ; then
483             echo "Rerunning WINEDEBUG=$debug_options $0 $@"
484             WINEDEBUG=$debug_options exec $0 "$@"
485         fi
486     done
487 fi
488
489
490 clean_up_info_message
491
492 # killed by signal?
493 if [ $wine_return -ge 128 ]; then
494         # try to kill myself with the same signal
495         kill -$[wine_return - 128] $$
496         # if we get here the kill didn't work
497         exit 1
498 fi