4723ad5a1065df51cac33c67e4189b803a8f9843
[gpg4win.git] / src / installer.nsi
1 # installer.nsi - Installer for GnuPG 4 Windows.    -*- coding: latin-1; -*-
2 # Copyright (C) 2005, 2007 g10 Code GmbH
3
4 # This file is part of GPG4Win.
5
6 # GPG4Win is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # GPG4Win is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19
20 # No servicable parts beyond this line.  Stay clear :)
21
22 !ifdef REQUIRE_W32_NSIS
23 !ifdef PACKAGE_LIBRARY
24 !include "Library.nsh"
25 !endif
26 !else
27 !macro InstallLib libtype shared install localfile destfile tempbasedir
28   File "${localfile}"
29 !macroend
30 !endif
31
32 !include "WinMessages.nsh"
33
34 # Define for the registry key to change the environment.  The
35 # commented one may be used if the setting should affect only the
36 # current user.
37 !define Regkey_for_Env \
38     'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
39 # !define Regkey_for_Env 'HKCU "Environment"'
40
41
42 # We use Memento to remember past installation choices.
43 !include Memento.nsh
44 !define MEMENTO_REGISTRY_ROOT HKLM
45 !define MEMENTO_REGISTRY_KEY \
46   Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRETTY_PACKAGE_SHORT}
47
48
49 # We use the modern UI.
50 !include "MUI.nsh"
51
52 # Set the package name.  Note that this name should not be sufficed
53 #  with the version because this would get displayed in the start menu.
54 Name "${PRETTY_PACKAGE}"
55
56
57 # Set the output filename.
58 !ifdef GPG4WIN_LIGHT
59 OutFile "${PACKAGE}-light-${VERSION}.exe"
60 !else
61 OutFile "${PACKAGE}-${VERSION}.exe"
62 !endif
63
64
65 # Set the installation directory.
66 !ifndef INSTALL_DIR
67 !define INSTALL_DIR "${PACKAGE}"
68 !endif
69 InstallDir "$PROGRAMFILES\GNU\${INSTALL_DIR}" 
70
71
72 InstallDirRegKey HKLM "Software\GNU\${PRETTY_PACKAGE_SHORT}" \
73         "Install Directory"
74
75
76 # Add version information to the file properties.
77 VIProductVersion "${PROD_VERSION}"
78 VIAddVersionKey "ProductName" "${PRETTY_PACKAGE_SHORT} (${VERSION})"
79 !ifdef LICENSE_GPL
80 VIAddVersionKey "Comments" \
81    "${PRETTY_PACKAGE_SHORT} is Free Software; you can redistribute it  \
82     and/or modify it under the terms of the GNU General Public License.  \
83     You should have received a copy of the GNU General Public License  \
84     along with this software; if not, write to the Free Software  \
85     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  \
86     MA 02110-1301, USA"
87 !else
88 VIAddVersionKey "Comments" \
89    "${PRETTY_PACKAGE_SHORT} is Free Software; you can redistribute it  \
90     and/or modify it under the terms of the GNU Lesser General Public  \
91     License. You should have received a copy of the GNU Lesser General  \
92     Public License along with this software; if not, write to the Free  \
93     Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  \
94     MA 02110-1301, USA"
95 !endif
96 VIAddVersionKey "CompanyName" "${COMPANY}"
97 VIAddVersionKey "LegalTrademarks" ""
98 VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
99 VIAddVersionKey "FileDescription" "${DESCRIPTION}"
100 VIAddVersionKey "FileVersion" "${PROD_VERSION}"
101
102 # Set to the name of another GnuPG installation if one has been detected
103 Var OtherGnuPGDetected
104
105 # Interface Settings
106
107 # !define MUI_ABORTWARNING
108 !define MUI_FINISHPAGE_NOAUTOCLOSE
109 !define MUI_UNFINISHPAGE_NOAUTOCLOSE
110
111 !define MUI_HEADERIMAGE
112 !define MUI_HEADERIMAGE_BITMAP \
113                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-header-install-150x57.bmp"
114 !define MUI_HEADERIMAGE_UNBITMAP \
115                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-header-uninstall-150x57.bmp"
116 !define MUI_WELCOMEFINISHPAGE_BITMAP \
117                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-wizard-install-164x314.bmp"
118 !define MUI_UNWELCOMEFINISHPAGE_BITMAP \
119                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-wizard-uninstall-164x314.bmp"
120 !define MUI_ICON "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-install.ico"
121 !define MUI_UNICON "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-uninstall.ico"
122
123 # Remember the installer language
124
125 !define MUI_LANGDLL_REGISTRY_ROOT "HKLM"
126 !define MUI_LANGDLL_REGISTRY_KEY "Software\GNU\${PRETTY_PACKAGE_SHORT}" 
127 !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
128
129 # No Umlaute, please!
130 !define MUI_LANGDLL_INFO "Please choose a language for the setup.$\r$\n\
131 Bitte die Sprache des Installations-Vorgangs angeben."
132
133 # The list of wizard pages.
134
135 !define MUI_WELCOMEPAGE_TITLE "${WELCOME_TITLE_STR}"
136 !define MUI_WELCOMEPAGE_TEXT "${ABOUT_STR}"
137
138 !insertmacro MUI_PAGE_WELCOME
139
140 !define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
141 !define MUI_PAGE_HEADER_SUBTEXT "$(T_GPLHeader)"
142 !define MUI_LICENSEPAGE_TEXT_BOTTOM "$(T_GPLShort)"
143 !insertmacro MUI_PAGE_LICENSE "${TOP_SRCDIR}/COPYING"
144
145 !define MUI_PAGE_CUSTOMFUNCTION_SHOW PrintNonAdminWarning
146 !insertmacro MUI_PAGE_COMPONENTS
147
148 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE CheckExistingVersion
149 !insertmacro MUI_PAGE_DIRECTORY
150
151 !ifdef HAVE_STARTMENU
152
153 Page custom CustomPageOptions
154
155 Var STARTMENU_FOLDER
156
157 !define MUI_PAGE_CUSTOMFUNCTION_PRE CheckIfStartMenuWanted
158 !define MUI_STARTMENUPAGE_NODISABLE
159 !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
160 !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\GNU\${PRETTY_PACKAGE_SHORT}"
161 !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
162
163 !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
164
165 !endif
166
167 !define MUI_PAGE_CUSTOMFUNCTION_PRE PrintCloseOtherApps
168 !insertmacro MUI_PAGE_INSTFILES
169
170 !define MUI_PAGE_CUSTOMFUNCTION_PRE ShowFinalWarnings
171 !define MUI_FINISHPAGE_SHOWREADME "share\gpg4win\README.$(T_LangCode).txt"
172 !define MUI_FINISHPAGE_SHOWREADME_TEXT "$(T_ShowReadme)"
173 #!define MUI_FINISHPAGE_RUN
174 #!define MUI_FINISHPAGE_RUN_FUNCTION RunOnFinish
175 #!define MUI_FINISHPAGE_RUN_TEXT "$(T_RunKeyManager)"
176 #!define MUI_FINISHPAGE_RUN_NOTCHECKED
177 !define MUI_FINISHPAGE_LINK "$(T_MoreInfo)"
178 !define MUI_FINISHPAGE_LINK_LOCATION "$(T_MoreInfoURL)"
179 !insertmacro MUI_PAGE_FINISH
180
181
182 # Uninstaller pages.
183
184 !insertmacro MUI_UNPAGE_WELCOME
185 !insertmacro MUI_UNPAGE_CONFIRM
186 !insertmacro MUI_UNPAGE_INSTFILES
187 !insertmacro MUI_UNPAGE_FINISH
188
189 #Page license
190 #Page components
191 #Page directory
192 #Page instfiles
193 #UninstPage uninstConfirm
194 #UninstPage instfiles
195
196
197 # Language support.  This has to be done after defining the pages, but
198 # before defining the translation strings.  Confusing.
199
200 # Enable this to not filter languages for the current code page.  Note
201 # that languages which are then not filtered out may not be displayed
202 # correctly in the Windows version the user is using.  Not recommended,
203 # but can be useful for testing.
204 !ifdef DEBUG
205 !define MUI_LANGDLL_ALLLANGUAGES
206 !endif
207
208 !insertmacro MUI_LANGUAGE "English"
209 !define PO_HEADER
210 !include "../po/catalogs.nsi"
211 !undef PO_HEADER
212
213 !insertmacro MUI_RESERVEFILE_LANGDLL
214 !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
215 ReserveFile "${BUILD_DIR}\g4wihelp.dll"
216 !ifdef SOURCES
217 ReserveFile "${TOP_SRCDIR}\doc\logo\gpg4win-logo-400px.bmp"
218 ReserveFile "${TOP_SRCDIR}\src\gpg4win-splash.wav"
219 !endif
220 ReserveFile "${TOP_SRCDIR}\COPYING"
221 ReserveFile "installer-options.ini"
222 ReserveFile "${TOP_SRCDIR}\doc\logo\gpg4win-logo-164x314.bmp"
223
224 # Language support
225
226 LangString T_LangCode ${LANG_ENGLISH} "en"
227
228 # Startup page
229 LangString T_GPLHeader ${LANG_ENGLISH} \
230   "This software is licensed under the terms of the GNU General Public \
231    License (GPL)."
232
233 LangString T_GPLShort ${LANG_ENGLISH} \
234   "In short: You are allowed to run this software for any purpose. \
235    You may distribute it as long as you give the recipients the same \
236    rights you have received."
237
238 LangString T_RunKeyManager ${LANG_ENGLISH} \
239    "Run the key manager"
240
241 LangString T_MoreInfo ${LANG_ENGLISH} \
242    "Click here for the project's homepage"
243 LangString T_MoreInfoURL ${LANG_ENGLISH} "http://www.gpg4win.org"
244
245 LangString T_ShowReadme ${LANG_ENGLISH} \
246    "Show the README file"
247
248 LangString T_NoKeyManager ${LANG_ENGLISH} \
249    "No key manager has been installed, thus we can't run one now."
250
251 # Used as subdirectory name in Start Menu.
252
253 LangString DESC_Menu_manuals ${LANG_ENGLISH} \
254    "Documentation"
255
256 LangString DESC_Menu_uninstall ${LANG_ENGLISH} \
257    "Uninstall"
258
259 # Used as subdirectory name on Desktop.
260 LangString DESC_Desktop_manuals ${LANG_ENGLISH} \
261    "Gpg4win Documentation"
262
263
264 # Functions
265
266 # Custom functions and macros for gpg4win. 
267 !include "g4wihelp.nsi"
268
269 #
270 # Control function for the Custom page to select special
271 # install options.
272 #
273 Function CustomPageOptions
274   !insertmacro MUI_HEADER_TEXT "$(T_InstallOptions)" "$(T_InstallOptLinks)"
275
276   # Note that the default selection is done in the ini file.
277   !insertmacro MUI_INSTALLOPTIONS_WRITE "installer-options.ini" \
278         "Field 1" "Text"  "$(T_InstOptLabelA)"
279   !insertmacro MUI_INSTALLOPTIONS_WRITE "installer-options.ini" \
280         "Field 2" "Text"  "$(T_InstOptFieldA)"
281   !insertmacro MUI_INSTALLOPTIONS_WRITE "installer-options.ini" \
282         "Field 3" "Text"  "$(T_InstOptFieldB)"
283   !insertmacro MUI_INSTALLOPTIONS_WRITE "installer-options.ini" \
284         "Field 4" "Text"  "$(T_InstOptFieldC)"
285   !insertmacro MUI_INSTALLOPTIONS_WRITE "installer-options.ini" \
286         "Field 5" "Text"  "$(T_InstOptLabelB)"
287
288   !insertmacro MUI_INSTALLOPTIONS_DISPLAY "installer-options.ini"
289 FunctionEnd
290
291 # Display a warning if this is a Beta version.
292 #Function PrintBetaWarning
293 #   MessageBox MB_OK "$(T_BetaWarning)"
294 #FunctionEnd
295
296
297 # Display a warning if GnuPP has been detected and allow the user to abort
298 # the installation.
299 Function PrintGnuPPWarning
300    MessageBox MB_YESNO "$(T_FoundOldGnuPP)" IDYES cont
301      Abort
302  cont:
303    StrCpy $OtherGnuPGDetected "GnuPP"
304 FunctionEnd
305
306 # Display a warning if GnuPT has been detected and allow the user to abort
307 # the installation.
308 Function PrintGnuPTWarning
309    MessageBox MB_YESNO "$(T_FoundOldGnuPT)" IDYES cont
310      Abort
311  cont:
312    StrCpy $OtherGnuPGDetected "GnuPT"
313 FunctionEnd
314
315 # Display a warning if the Sourceforge WinPT has been detected and
316 # allow the user to abort the installation.
317 Function PrintWinPTSFWarning
318    MessageBox MB_YESNO "$(T_FoundOldWinPTSF)" IDYES cont
319      Abort
320  cont:
321    StrCpy $OtherGnuPGDetected "WinPT-SF"
322 FunctionEnd
323
324 # Display a warning if GnuPG Pack has been detected and abort the
325 # the installation.  This one clobbers our own Registry space.
326 Function PrintGnuPackWarning
327    MessageBox MB_OK "$(T_FoundOldGnuPack)"
328    Abort
329 FunctionEnd
330
331
332 # Check whether one of the other GnuPG systems has already been
333 # installed.  We do this by looking at the registry.
334 Function CheckOtherGnuPGApps
335   StrCpy $OtherGnuPGDetected ""
336   ClearErrors
337   ReadRegStr $0 HKLM "Software\GNU\GnuPP\Settings" "Path"
338   IfErrors +2 0
339     Call PrintGnuPPWarning
340
341   EnumRegKey $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Start Menu\Programs\GnuPT" 0
342   StrCmp $0 "" +2
343     Call PrintGnuPTWarning
344
345   ClearErrors
346   ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Windows Privacy Tools" "DisplayVersion"
347   IfErrors +2 0
348     Call PrintWinPTSFWarning
349
350   ReadRegStr $0 HKLM "Software\GNU\GnuPG" "Install Directory"
351   Push $0
352   Push "GnuPG-Pack"
353   Call StrStr
354   Pop $0
355   StrCmp $0 "" +2
356     Call PrintGnuPackWarning
357
358
359 FunctionEnd
360
361 # Check whether gpg4win has already been installed.  This is called as
362 # a leave function from the directory page.  A call to abort will get
363 # back to the directory selection.
364 Function CheckExistingVersion
365   ClearErrors
366   FileOpen $0 "$INSTDIR\VERSION" r
367   IfErrors nexttest
368   FileRead $0 $R0
369   FileRead $0 $R1
370   FileClose $0
371
372   Push $R1
373   Call TrimNewLines
374   Pop $R1
375
376   # Extract major version.
377   StrCpy $0 $R1 2
378   StrCmp $0 "1." 0 secondtest
379     MessageBox MB_YESNO "$(T_FoundExistingOldVersion)" IDYES leave
380     Abort
381
382  secondtest:
383   MessageBox MB_YESNO "$(T_FoundExistingVersion)" IDYES leave
384   Abort
385
386  nexttest:
387   ClearErrors
388   ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GPG4Win" "DisplayVersion"
389   IfErrors leave 0
390      MessageBox MB_YESNO "$(T_FoundExistingVersionB)" IDYES leave
391      Abort
392      
393  leave:
394 FunctionEnd
395
396
397
398 # PrintNonAdminWarning
399
400 # Check whether the current user is in the Administrator group or an
401 # OS version without the need for an Administrator is in use.  Print a
402 # diagnostic if this is not the case and abort installation.
403 Function PrintNonAdminWarning
404
405   #Call PrintBetaWarning
406
407   ClearErrors
408   UserInfo::GetName
409   IfErrors leave
410   Pop $0
411   UserInfo::GetAccountType
412   Pop $1
413   StrCmp $1 "Admin" leave +1
414   MessageBox MB_OK "$(T_AdminNeeded)"
415   Quit
416
417  leave:
418 FunctionEnd
419
420
421 # Check whether the start menu is actually wanted.
422
423 Function CheckIfStartMenuWanted
424   !insertmacro MUI_INSTALLOPTIONS_READ $R0 "installer-options.ini" \
425         "Field 2" "State"
426   IntCmp $R0 1 +2
427     Abort
428 FunctionEnd
429
430
431 # Check whether this is a reinstall and popup a message box to explain
432 # that it is better to close other apps before continuing
433 Function PrintCloseOtherApps
434     IfFileExists $INSTDIR\gnupg.exe print_warning
435     IfFileExists $INSTDIR\winpt.exe print_warning
436     IfFileExists $INSTDIR\gpa.exe   print_warning
437     IfFileExists $INSTDIR\gpgol.dll print_warning
438     IfFileExists $INSTDIR\gpgee.dll print_warning
439     IfFileExists $INSTDIR\dirmngr.exe print_warning
440     Return
441    print_warning:
442     MessageBox MB_OK|MB_ICONEXCLAMATION "$(T_CloseOtherApps)"
443     IfFileExists $INSTDIR\winpt.exe 0 +3
444       MessageBox MB_OK "$(T_ShuttingDownWinPT)"
445       ExecWait '"$INSTDIR\winpt.exe" --stop'
446     IfFileExists $INSTDIR\dirmngr.exe 0 +3
447       MessageBox MB_OK "$(T_ShuttingDownDirMngr)"
448       g4wihelp::service_stop "DirMngr"
449    leave:
450 FunctionEnd
451
452 # Called right before the final page to show more warnings.
453 Function ShowFinalWarnings
454    StrCmp $OtherGnupgDetected "" +2
455      MessageBox MB_OK "$(T_FoundOldSeeManual)"
456    leave:
457 FunctionEnd
458
459 #-----------------------------------------------
460 # Strings pertaining to the install options page
461 #-----------------------------------------------
462
463 # Installation options title
464 LangString T_InstallOptions ${LANG_ENGLISH} "Install Options"
465
466 # Installation options subtitle 1
467 LangString T_InstallOptLinks ${LANG_ENGLISH} "Start links"
468
469 LangString T_InstOptLabelA  ${LANG_ENGLISH} \
470      "Please select where Gpg4win shall install links:"
471
472 LangString T_InstOptLabelB  ${LANG_ENGLISH} \
473      "(Only programs will be linked into the quick launch bar.)"
474
475 LangString T_InstOptFieldA  ${LANG_ENGLISH} \
476      "Start Menu"
477
478 LangString T_InstOptFieldB  ${LANG_ENGLISH} \
479      "Desktop"
480
481 LangString T_InstOptFieldC  ${LANG_ENGLISH} \
482      "Quick Launch Bar"
483
484 #------------------------------------------------
485 # String pertaining to the existing version check
486 #------------------------------------------------
487 LangString T_FoundExistingVersion ${LANG_ENGLISH} \
488      "Version $R1 has already been installed.  $\r$\n\
489       Do you want to overwrite it with version ${VERSION}?"
490 LangString T_FoundExistingOldVersion ${LANG_ENGLISH} \
491      "An old version $R1 has already been installed.  It is \
492       strongly recommended to deinstall previous versions on \
493       major upgrades. $\r$\n\
494       Do you want to continue installing Gpg4win ${VERSION} anyway?"
495 LangString T_FoundExistingVersionB ${LANG_ENGLISH} \
496      "A version of Gpg4Win has already been installed on the system. \
497       There will be no problem installing and thus overwriting this \
498       Version. $\r$\n\
499        $\r$\n\
500       Do you want to continue installing Gpg4win?"
501
502
503 #---------------------------------------------
504 # From the old installation checking functions
505 #---------------------------------------------
506 LangString T_FoundOldSeeManual ${LANG_ENGLISH} \
507      "Please see the Gpg4win user manual to learn how to migrate existing \
508       keys from other GnuPG based installations to Gpg4win."
509
510 #---------
511 LangString T_FoundOldGnuPP ${LANG_ENGLISH} \
512      "An old installation of GnuPP (GNU Privacy Project) has been been \
513       detected.  That software is not maintained anymore and thus should \
514       be removed. $\r$\n\
515           $\r$\n\
516       Do you want to continue installing Gpg4win and take care of the old \
517       installation later?"
518
519 #---------
520 LangString T_FoundOldGnuPT ${LANG_ENGLISH} \
521      "An installation of GnuPT has been been detected.  This may cause \
522       problems when used along with Gpg4win. $\r$\n\
523           $\r$\n\
524       Do you want to continue installing Gpg4win?"
525
526 #---------
527 LangString T_FoundOldWinPTSF ${LANG_ENGLISH} \
528      "An old installation of the Sourceforge hosted WinPT has been been \
529       detected.  That software is not maintained anymore and should \
530       be removed. $\r$\n\
531           $\r$\n\
532       Do you want to continue installing Gpg4win and take care of the old \
533       installation later?"
534
535
536 #--------
537 LangString T_FoundOldGnuPack ${LANG_ENGLISH} \
538      "An installation of GnuPG-Pack has been been detected. You need to \
539       uninstall it before you can continue with Gpg4win installation. $\r$\n\
540         $\r$\n\
541       The installation will be aborted now!"
542
543
544
545 # From Function PrintBetaWarning
546 LangString T_BetaWarning ${LANG_ENGLISH} \
547    "Note: This is a BETA version of Gpg4win. $\r$\n\
548      $\r$\n\
549     Beta versions are only intended for testing and \
550     shall not be used in a production environment."
551
552 # From Function PrintNonAdminWarning
553 LangString T_AdminNeeded ${LANG_ENGLISH} \
554    "Warning: Administrator permissions required for a successful installation"
555
556 # From Function PrintCloseOtherApps
557 LangString T_CloseOtherApps ${LANG_ENGLISH} \
558    "Please make sure that other applications are not running. \
559     In particular you should close Outlook and all Explorer \
560     windows.  Gpg4win will try to install anyway but a reboot \
561     will be required then."
562 LangString T_ShuttingDownWinPT ${LANG_ENGLISH} \
563    "Trying to shutdown a possible running instance of WinPT."
564 LangString T_ShuttingDownDirMngr ${LANG_ENGLISH} \
565    "Trying to shutdown a possible running instance of DirMngr."
566
567
568 # FIXME: The GetAfterChar function comes from the NSIS wiki.
569 Function un.GetAfterChar
570   Exch $0 ; chop char
571   Exch
572   Exch $1 ; input string
573   Push $2
574   Push $3
575   StrCpy $2 0
576   loop:
577     IntOp $2 $2 - 1
578     StrCpy $3 $1 1 $2
579     StrCmp $3 "" 0 +3
580       StrCpy $0 ""
581       Goto exit2
582     StrCmp $3 $0 exit1
583     Goto loop
584   exit1:
585     IntOp $2 $2 + 1
586     StrCpy $0 $1 "" $2
587   exit2:
588     Pop $3
589     Pop $2
590     Pop $1
591     Exch $0 ; output
592 FunctionEnd
593
594
595 Function un.SourceDelete
596   Push "/"
597   Call un.GetAfterChar
598   Pop $R0
599   Delete "$INSTDIR\$R0"
600 FunctionEnd
601
602
603 # StrStr  - taken from the NSIS reference
604 # input, top of stack = string to search for
605 #        top of stack-1 = string to search in
606 # output, top of stack (replaces with the portion of the string remaining)
607 # modifies no other variables.
608 #
609 # Usage:
610 #   Push "this is a long ass string"
611 #   Push "ass"
612 #   Call StrStr
613 #   Pop $R0
614 #  ($R0 at this point is "ass string")
615 #
616 !macro StrStr un
617 Function ${un}StrStr
618    Exch $R1 # st=haystack,old$R1, $R1=needle
619    Exch     # st=old$R1,haystack
620    Exch $R2 # st=old$R1,old$R2, $R2=haystack
621    Push $R3
622    Push $R4
623    Push $R5
624    StrLen $R3 $R1
625    StrCpy $R4 0
626    # $R1=needle
627    # $R2=haystack
628    # $R3=len(needle)
629    # $R4=cnt
630    # $R5=tmp
631    loop:
632      StrCpy $R5 $R2 $R3 $R4
633      StrCmp $R5 $R1 done
634      StrCmp $R5 "" done
635      IntOp $R4 $R4 + 1
636      Goto loop
637  done:
638    StrCpy $R1 $R2 "" $R4
639    Pop $R5
640    Pop $R4
641    Pop $R3
642    Pop $R2
643    Exch $R1
644 FunctionEnd
645 !macroend
646 !insertmacro StrStr ""
647 !insertmacro StrStr "un."
648
649
650 # TrimNewlines  - taken from the NSIS reference
651 # input, top of stack  (e.g. whatever$\r$\n)
652 # output, top of stack (replaces, with e.g. whatever)
653 # modifies no other variables.
654 Function TrimNewlines
655    Exch $R0
656    Push $R1
657    Push $R2
658    StrCpy $R1 0
659  
660  loop:
661    IntOp $R1 $R1 - 1
662    StrCpy $R2 $R0 1 $R1
663    StrCmp $R2 "$\r" loop
664    StrCmp $R2 "$\n" loop
665    IntOp $R1 $R1 + 1
666    IntCmp $R1 0 no_trim_needed
667    StrCpy $R0 $R0 $R1
668  
669  no_trim_needed:
670    Pop $R2
671    Pop $R1
672    Exch $R0
673 FunctionEnd
674
675
676 # AddToPath - Adds the given dir to the search path.
677 #        Input - head of the stack
678 Function AddToPath
679   Exch $0
680   g4wihelp::path_add "$0"
681   StrCmp $R5 "0" add_to_path_done
682   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
683   add_to_path_done:
684   Pop $0
685 FunctionEnd
686  
687 # RemoveFromPath - Remove a given dir from the path
688 #     Input: head of the stack
689 Function un.RemoveFromPath
690   Exch $0
691   g4wihelp::path_remove "$0"
692   StrCmp $R5 "0" remove_from_path_done
693   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
694   remove_from_path_done:
695   Pop $0
696 FunctionEnd
697  
698