Add update handling to installer and uninstaller
[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 # Copyright (C) 2017 Intevation GmbH
4 #
5 # This file is part of GPG4Win.
6 #
7 # GPG4Win is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # GPG4Win is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20
21 # No servicable parts beyond this line.  Stay clear :)
22
23 !ifdef REQUIRE_W32_NSIS
24 !ifdef PACKAGE_LIBRARY
25 !include "Library.nsh"
26 !endif
27 !else
28 !macro InstallLib libtype shared install localfile destfile tempbasedir
29   File "${localfile}"
30 !macroend
31 !endif
32
33 !include "FileFunc.nsh"
34 !include "WinMessages.nsh"
35 !include "WinVer.nsh"
36
37 # We use the modern UI 2.
38 !include "MUI2.nsh"
39 !ifdef DEBUG
40 !undef DEBUG
41 !endif
42
43 # Set the package name.  Note that this name should not be sufficed
44 #  with the version because this would get displayed in the start menu.
45 Name "${PRETTY_PACKAGE}"
46 OutFile "${PACKAGE}-${VERSION}.exe"
47 BrandingText "${PRETTY_PACKAGE}-${VERSION}"
48
49 # Details button conflicts with splashscreen
50 ShowInstDetails nevershow
51
52 # Set the installation directory.
53 !ifndef INSTALL_DIR
54 !define INSTALL_DIR "${PACKAGE}"
55 !endif
56 InstallDir "$PROGRAMFILES\${INSTALL_DIR}"
57
58 # Add version information to the file properties.
59 VIProductVersion "${PROD_VERSION}"
60 VIAddVersionKey "ProductName" "${PRETTY_PACKAGE_SHORT} (${VERSION})"
61 !ifdef LICENSE_GPL
62 VIAddVersionKey "Comments" \
63    "${PRETTY_PACKAGE_SHORT} is Free Software; you can redistribute it  \
64     and/or modify it under the terms of the GNU General Public License.  \
65     You should have received a copy of the GNU General Public License  \
66     along with this software; if not, write to the Free Software  \
67     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  \
68     MA 02110-1301, USA"
69 !else
70 VIAddVersionKey "Comments" \
71    "${PRETTY_PACKAGE_SHORT} is Free Software; you can redistribute it  \
72     and/or modify it under the terms of the GNU Lesser General Public  \
73     License. You should have received a copy of the GNU Lesser General  \
74     Public License along with this software; if not, write to the Free  \
75     Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  \
76     MA 02110-1301, USA"
77 !endif
78 VIAddVersionKey "CompanyName" "${COMPANY}"
79 VIAddVersionKey "LegalTrademarks" ""
80 VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
81 VIAddVersionKey "FileDescription" "${DESCRIPTION}"
82 VIAddVersionKey "FileVersion" "${PROD_VERSION}"
83
84 # Set to the name of another GnuPG installation if one has been detected
85 Var OtherGnuPGDetected
86
87 # Interface Settings
88
89 # !define MUI_ABORTWARNING
90 !define MUI_FINISHPAGE_NOAUTOCLOSE
91 !define MUI_UNFINISHPAGE_NOAUTOCLOSE
92
93 !define MUI_HEADERIMAGE
94 !define MUI_HEADERIMAGE_BITMAP \
95                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-header-install-150x57.bmp"
96 !define MUI_HEADERIMAGE_UNBITMAP \
97                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-header-uninstall-150x57.bmp"
98 !define MUI_WELCOMEFINISHPAGE_BITMAP \
99                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-wizard-install-164x314.bmp"
100 !define MUI_UNWELCOMEFINISHPAGE_BITMAP \
101                "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-wizard-uninstall-164x314.bmp"
102 !define MUI_ICON "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-install.ico"
103 !define MUI_UNICON "${TOP_SRCDIR}/doc/logo/gpg4win-nsis-uninstall.ico"
104
105 # Remember the installer language
106
107 !define MUI_LANGDLL_REGISTRY_ROOT "SHCTX"
108 !define MUI_LANGDLL_REGISTRY_KEY "Software\${PRETTY_PACKAGE_SHORT}"
109 !define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
110
111 # No Umlaute, please!
112 !define MUI_LANGDLL_INFO "Please choose a language for the setup.$\r$\n\
113 Bitte die Sprache des Installations-Vorgangs angeben."
114
115 # The list of wizard pages.
116
117 !define MUI_WELCOMEPAGE_TITLE "${WELCOME_TITLE_STR}"
118 !define MUI_WELCOMEPAGE_TEXT "${ABOUT_STR}"
119
120 !insertmacro MUI_PAGE_WELCOME
121
122 #!define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)"
123 #!define MUI_PAGE_HEADER_SUBTEXT "$(T_GPLHeader)"
124 #!insertmacro MUI_PAGE_LICENSE "license.blurb"
125
126 !define MUI_PAGE_CUSTOMFUNCTION_SHOW PrintNonAdminWarning
127 !insertmacro MUI_PAGE_COMPONENTS
128
129 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE CheckExistingVersion
130 !insertmacro MUI_PAGE_DIRECTORY
131
132 !define MUI_PAGE_CUSTOMFUNCTION_PRE BeforeInstallHooks
133 !insertmacro MUI_PAGE_INSTFILES
134 # Finish page
135 !ifndef SOURCES
136 !define MUI_PAGE_CUSTOMFUNCTION_PRE ShowFinalWarnings
137
138 !define MUI_PAGE_CUSTOMFUNCTION_SHOW FinishFunction
139 !define MUI_FINISHPAGE_RUN
140 !define MUI_FINISHPAGE_RUN_FUNCTION RunAsUser
141 !define MUI_FINISHPAGE_SHOWREADME "share\gpg4win\README.$(T_LangCode).txt"
142 !define MUI_FINISHPAGE_SHOWREADME_TEXT "$(T_ShowReadme)"
143 !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
144 !define MUI_FINISHPAGE_LINK "$(T_MoreInfo)"
145 !define MUI_FINISHPAGE_LINK_LOCATION "$(T_MoreInfoURL)"
146 !insertmacro MUI_PAGE_FINISH
147
148 Function FinishFunction
149   IfSilent leave
150   !insertmacro SectionFlagIsSet ${SEC_kleopatra} \
151         ${SF_SELECTED} have_kleo check_gpa
152 check_gpa:
153   !insertmacro SectionFlagIsSet ${SEC_gpa} \
154         ${SF_SELECTED} have_gpa have_nothing
155 have_nothing:
156   ShowWindow $mui.FinishPage.Run ${SW_HIDE}
157   goto leave
158 have_kleo:
159   SendMessage $mui.FinishPage.Run.Text ${WM_SETTEXT} 0 "STR:$(T_RunKleopatra)"
160   goto leave
161 have_gpa:
162   SendMessage $mui.FinishPage.Run.Text ${WM_SETTEXT} 0 "STR:$(T_RunGPA)"
163 leave:
164 FunctionEnd
165
166 Function RunAsUser
167   !insertmacro SectionFlagIsSet ${SEC_kleopatra} \
168         ${SF_SELECTED} do_kleo skip_kleo
169 do_kleo:
170   g4wihelp::DesktopShellRun "$INSTDIR\bin\kleopatra.exe"
171   goto leave
172 skip_kleo:
173   !insertmacro SectionFlagIsSet ${SEC_gpa} \
174         ${SF_SELECTED} do_gpa leave
175 do_gpa:
176   g4wihelp::DesktopShellRun "$INSTDIR\bin\gpa.exe"
177 leave:
178 FunctionEnd
179
180 LangString T_RunKleopatra ${LANG_ENGLISH} \
181    "Run Kleopatra"
182
183 LangString T_RunGPA ${LANG_ENGLISH} \
184    "Run GPA"
185
186 # /SOURCES
187 !endif
188
189 # Uninstaller pages.
190
191 !insertmacro MUI_UNPAGE_WELCOME
192 !insertmacro MUI_UNPAGE_CONFIRM
193 !ifndef SOURCES
194 !define MUI_PAGE_CUSTOMFUNCTION_PRE un.CloseApps
195 !endif
196 !insertmacro MUI_UNPAGE_INSTFILES
197 #!insertmacro MUI_UNPAGE_FINISH
198
199 #Page license
200 #Page components
201 #Page directory
202 #Page instfiles
203 #UninstPage uninstConfirm
204 #UninstPage instfiles
205
206
207 # Language support.  This has to be done after defining the pages, but
208 # before defining the translation strings.  Confusing.
209
210 # Enable this to not filter languages for the current code page.  Note
211 # that languages which are then not filtered out may not be displayed
212 # correctly in the Windows version the user is using.  Not recommended,
213 # but can be useful for testing.
214 !ifdef DEBUG
215 !define MUI_LANGDLL_ALLLANGUAGES
216 !endif
217
218 !insertmacro MUI_LANGUAGE "English"
219 !define PO_HEADER
220 !include "../po/catalogs.nsi"
221 !undef PO_HEADER
222
223 !insertmacro MUI_RESERVEFILE_LANGDLL
224 ReserveFile "${BUILD_DIR}\g4wihelp.dll"
225 !ifdef SOURCES
226 ReserveFile "${TOP_SRCDIR}\doc\logo\gpg4win-logo-400px.bmp"
227 ReserveFile "${TOP_SRCDIR}\src\gpg4win-splash.wav"
228 !endif
229 ReserveFile "${TOP_SRCDIR}\COPYING"
230 ReserveFile "${TOP_SRCDIR}\doc\logo\gpg4win-logo-164x314.bmp"
231
232 # Language support
233
234 LangString T_LangCode ${LANG_ENGLISH} "en"
235
236 # Startup page
237 LangString T_GPLHeader ${LANG_ENGLISH} \
238   "This software is licensed under the terms of the GNU General Public \
239    License (GNU GPL)."
240
241 LangString T_GPLShort ${LANG_ENGLISH} \
242   "In short: You are allowed to run this software for any purpose. \
243    You may distribute it as long as you give the recipients the same \
244    rights you have received."
245
246 LangString T_MoreInfo ${LANG_ENGLISH} \
247    "Go to Gpg4win's webpage"
248 LangString T_MoreInfoURL ${LANG_ENGLISH} "https://www.gpg4win.org"
249
250 LangString T_ShowReadme ${LANG_ENGLISH} \
251    "Show the README file"
252
253 LangString T_NoKeyManager ${LANG_ENGLISH} \
254    "No key manager has been installed, thus we can't run one now."
255
256 # Used as subdirectory name in Start Menu.
257
258 LangString DESC_Menu_manuals ${LANG_ENGLISH} \
259    "Documentation"
260
261 LangString DESC_Menu_uninstall ${LANG_ENGLISH} \
262    "Uninstall"
263
264 # Used as subdirectory name on Desktop.
265 LangString DESC_Desktop_manuals ${LANG_ENGLISH} \
266    "Gpg4win Documentation"
267
268
269 # Functions
270
271 # Custom functions and macros for gpg4win.
272 !include "g4wihelp.nsi"
273
274 # Display a warning if this is a Beta version.
275 #Function PrintBetaWarning
276 #   MessageBox MB_OK "$(T_BetaWarning)"
277 #FunctionEnd
278
279
280 # Display a warning if GnuPP has been detected and allow the user to abort
281 # the installation.
282 Function PrintGnuPPWarning
283    MessageBox MB_YESNO "$(T_FoundOldGnuPP)" IDYES cont
284      Abort
285  cont:
286    StrCpy $OtherGnuPGDetected "GnuPP"
287 FunctionEnd
288
289 # Display a warning if GnuPT has been detected and allow the user to abort
290 # the installation.
291 Function PrintGnuPTWarning
292    MessageBox MB_YESNO "$(T_FoundOldGnuPT)" IDYES cont
293      Abort
294  cont:
295    StrCpy $OtherGnuPGDetected "GnuPT"
296 FunctionEnd
297
298 # Display a warning if the Sourceforge WinPT has been detected and
299 # allow the user to abort the installation.
300 Function PrintWinPTSFWarning
301    MessageBox MB_YESNO "$(T_FoundOldWinPTSF)" IDYES cont
302      Abort
303  cont:
304    StrCpy $OtherGnuPGDetected "WinPT-SF"
305 FunctionEnd
306
307 # Display a warning if GnuPG Pack has been detected and abort the
308 # the installation.  This one clobbers our own Registry space.
309 Function PrintGnuPackWarning
310    MessageBox MB_OK "$(T_FoundOldGnuPack)"
311    Abort
312 FunctionEnd
313
314
315 # Check whether one of the other GnuPG systems has already been
316 # installed.  We do this by looking at the registry.
317 !ifndef SOURCES
318 Function CheckOtherGnuPGApps
319   StrCpy $OtherGnuPGDetected ""
320   ClearErrors
321   ReadRegStr $0 SHCTX "Software\GNU\GnuPP\Settings" "Path"
322   IfErrors +2 0
323     Call PrintGnuPPWarning
324
325   EnumRegKey $0 HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Start Menu\Programs\GnuPT" 0
326   StrCmp $0 "" +2
327     Call PrintGnuPTWarning
328
329   ClearErrors
330   ReadRegStr $0 SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\Windows Privacy Tools" "DisplayVersion"
331   IfErrors +2 0
332     Call PrintWinPTSFWarning
333
334   ReadRegStr $0 SHCTX "Software\GNU\GnuPG" "Install Directory"
335   Push $0
336   Push "GnuPG-Pack"
337   Call StrStr
338   Pop $0
339   StrCmp $0 "" +2
340     Call PrintGnuPackWarning
341
342
343 FunctionEnd
344 !endif
345
346 # Check whether gpg4win has already been installed.  This is called as
347 # a leave function from the directory page.  A call to abort will get
348 # back to the directory selection.
349 Function CheckExistingVersion
350   ClearErrors
351   FileOpen $0 "$INSTDIR\VERSION" r
352   IfErrors leave
353   FileRead $0 $R0
354   FileRead $0 $R1
355   FileClose $0
356
357   Push $R1
358   Call TrimNewLines
359   Pop $R1
360
361   # Extract major version.
362   StrCpy $0 $R1 2
363   StrCmp $0 "1." 0 leave
364     MessageBox MB_YESNO "$(T_FoundExistingOldVersion)" IDYES leave
365     Abort
366
367  leave:
368 FunctionEnd
369
370
371
372 # PrintNonAdminWarning
373
374 # Check whether the current user is in the Administrator group or an
375 # OS version without the need for an Administrator is in use.  Print a
376 # diagnostic if this is not the case and abort installation.
377 Function PrintNonAdminWarning
378
379   #Call PrintBetaWarning
380
381   ClearErrors
382   UserInfo::GetName
383   IfErrors leave
384   Pop $0
385   UserInfo::GetAccountType
386   Pop $1
387   StrCmp $1 "Admin" leave +1
388   MessageBox MB_YESNO "$(T_AdminWanted)" IDNO exit
389   goto leave
390 exit:
391   Quit
392  leave:
393 FunctionEnd
394
395
396 # Check for claws mail installation which was shipped in Gpg4win
397 # versions < 2.2.6
398 Function CheckClawsUninstall
399     IfFileExists $INSTDIR\claws-mail.exe 0 leave
400     MessageBox MB_YESNO "$(T_FoundOldClaws)" IDYES uninstall IDNO leave
401    uninstall:
402     !insertmacro SelectSection ${SecUninstClawsMail}
403    leave:
404 FunctionEnd
405
406 # Check whether this is a reinstall and popup a message box to explain
407 # that it is better to close other apps before continuing
408 Function PrintCloseOtherApps
409    g4wihelp::KillProc "kleopatra.exe"
410    g4wihelp::KillProc "gpa.exe"
411 goto leave
412 # TODO check for running outlook and offer to kill it.
413    print_warning:
414     MessageBox MB_OK|MB_ICONEXCLAMATION "$(T_CloseOtherApps)"
415 leave:
416 FunctionEnd
417
418 Function un.CloseApps
419    g4wihelp::KillProc "kleopatra.exe"
420    g4wihelp::KillProc "gpa.exe"
421 FunctionEnd
422
423 # Called right before installation
424 Function BeforeInstallHooks
425     Call PrintCloseOtherApps
426     Call CheckClawsUninstall
427 FunctionEnd
428
429 # Called right before the final page to show more warnings.
430 Function ShowFinalWarnings
431    StrCmp $OtherGnupgDetected "" +2
432      MessageBox MB_OK "$(T_FoundOldSeeManual)"
433    leave:
434 FunctionEnd
435
436 #-----------------------------------------------
437 # Strings pertaining to the install options page
438 #-----------------------------------------------
439
440 # Installation options title
441 LangString T_InstallOptions ${LANG_ENGLISH} "Install Options"
442
443 # Installation options subtitle 1
444 LangString T_InstallOptLinks ${LANG_ENGLISH} "Start links"
445
446 LangString T_InstOptLabelA  ${LANG_ENGLISH} \
447      "Please select where Gpg4win shall install links:"
448
449 LangString T_InstOptLabelB  ${LANG_ENGLISH} \
450      "(Only programs will be linked into the quick launch bar.)"
451
452 LangString T_InstOptFieldA  ${LANG_ENGLISH} \
453      "Start Menu"
454
455 LangString T_InstOptFieldB  ${LANG_ENGLISH} \
456      "Desktop"
457
458 LangString T_InstOptFieldC  ${LANG_ENGLISH} \
459      "Quick Launch Bar"
460
461 #------------------------------------------------
462 # String pertaining to the existing version check
463 #------------------------------------------------
464 LangString T_FoundExistingVersion ${LANG_ENGLISH} \
465      "Version $R1 has already been installed.  $\r$\n\
466       Do you want to overwrite it with version ${VERSION}?"
467 LangString T_FoundExistingOldVersion ${LANG_ENGLISH} \
468      "An old version $R1 has already been installed.  It is \
469       strongly recommended to deinstall previous versions on \
470       major upgrades. $\r$\n\
471       Do you want to continue installing Gpg4win ${VERSION} anyway?"
472 LangString T_UninstallingOldVersion ${LANG_ENGLISH} \
473      "Uninstalling Gpg4win-"
474
475
476 #---------------------------------------------
477 # From the old installation checking functions
478 #---------------------------------------------
479 LangString T_FoundOldSeeManual ${LANG_ENGLISH} \
480      "Please see the Gpg4win user manual to learn how to migrate existing \
481       keys from other GnuPG based installations to Gpg4win."
482
483 #---------
484 LangString T_FoundOldGnuPP ${LANG_ENGLISH} \
485      "An old installation of GnuPP (GNU Privacy Project) has been been \
486       detected.  That software is not maintained anymore and thus should \
487       be removed. $\r$\n\
488           $\r$\n\
489       Do you want to continue installing Gpg4win and take care of the old \
490       installation later?"
491
492 #---------
493 LangString T_FoundOldGnuPT ${LANG_ENGLISH} \
494      "An installation of GnuPT has been been detected.  This may cause \
495       problems when used along with Gpg4win. $\r$\n\
496           $\r$\n\
497       Do you want to continue installing Gpg4win?"
498
499 #---------
500 LangString T_FoundOldWinPTSF ${LANG_ENGLISH} \
501      "An old installation of the Sourceforge hosted WinPT has been been \
502       detected.  That software is not maintained anymore and should \
503       be removed. $\r$\n\
504           $\r$\n\
505       Do you want to continue installing Gpg4win and take care of the old \
506       installation later?"
507
508
509 #--------
510 LangString T_FoundOldGnuPack ${LANG_ENGLISH} \
511      "An installation of GnuPG-Pack has been been detected. You need to \
512       uninstall it before you can continue with Gpg4win installation. $\r$\n\
513         $\r$\n\
514       The installation will be aborted now!"
515
516
517
518 # From Function PrintBetaWarning
519 LangString T_BetaWarning ${LANG_ENGLISH} \
520    "Note: This is a BETA version of Gpg4win. $\r$\n\
521      $\r$\n\
522     Beta versions are only intended for testing and \
523     shall not be used in a production environment."
524
525 # From Function PrintNonAdminWarning
526 LangString T_AdminWanted ${LANG_ENGLISH} \
527     "Warning: It is recommended to install Gpg4win system-wide with \
528         administrator rights. \
529           $\r$\n\
530           $\r$\n\
531     Do you want to continue installing Gpg4win without administrator rights?"
532
533 # From Function PrintCloseOtherApps
534 LangString T_CloseOtherApps ${LANG_ENGLISH} \
535    "Please make sure that other applications are not running. \
536     In particular you should close Outlook and all Explorer \
537     windows.  Gpg4win will try to install anyway but a reboot \
538     will be required then."
539 LangString T_ShuttingDownWinPT ${LANG_ENGLISH} \
540    "Trying to shutdown a possible running instance of WinPT."
541
542 # From Function CheckClawsUninstall
543 LangString T_FoundOldClaws ${LANG_ENGLISH} \
544    "An old version of Claws Mail was found in your Installation directory. \
545     $\r$\nPlease note that Claws Mail is no longer bundled with Gpg4win \
546     and is now available as a standalone package.$\r$\n\
547     You should uninstall Claws Mail now, and if you wish to \
548     continue to use it, install an up-to-date version from:$\r$\n\
549     http://www.claws-mail.org/win32 $\r$\n$\r$\n\
550     Uninstall Claws Mail from Gpg4win now?"
551
552 # From Function CheckClawsUninstall
553 LangString T_WinisDeprecated ${LANG_ENGLISH} \
554    "Windows Versions before Windows 7 are no longer maintained by Gpg4win. \
555     $\r$\nSupport for them may be removed in a future version.\
556     $\r$\n$\r$\nKleopatra is disabled."
557
558 # FIXME: The GetAfterChar function comes from the NSIS wiki.
559 Function un.GetAfterChar
560   Exch $0 ; chop char
561   Exch
562   Exch $1 ; input string
563   Push $2
564   Push $3
565   StrCpy $2 0
566   loop:
567     IntOp $2 $2 - 1
568     StrCpy $3 $1 1 $2
569     StrCmp $3 "" 0 +3
570       StrCpy $0 ""
571       Goto exit2
572     StrCmp $3 $0 exit1
573     Goto loop
574   exit1:
575     IntOp $2 $2 + 1
576     StrCpy $0 $1 "" $2
577   exit2:
578     Pop $3
579     Pop $2
580     Pop $1
581     Exch $0 ; output
582 FunctionEnd
583
584
585 Function un.SourceDelete
586   Push "/"
587   Call un.GetAfterChar
588   Pop $R0
589   Delete "$INSTDIR\$R0"
590 FunctionEnd
591
592
593 # StrStr  - taken from the NSIS reference
594 # input, top of stack = string to search for
595 #        top of stack-1 = string to search in
596 # output, top of stack (replaces with the portion of the string remaining)
597 # modifies no other variables.
598 #
599 # Usage:
600 #   Push "this is a long ass string"
601 #   Push "ass"
602 #   Call StrStr
603 #   Pop $R0
604 #  ($R0 at this point is "ass string")
605 #
606 !macro StrStr un
607 Function ${un}StrStr
608    Exch $R1 # st=haystack,old$R1, $R1=needle
609    Exch     # st=old$R1,haystack
610    Exch $R2 # st=old$R1,old$R2, $R2=haystack
611    Push $R3
612    Push $R4
613    Push $R5
614    StrLen $R3 $R1
615    StrCpy $R4 0
616    # $R1=needle
617    # $R2=haystack
618    # $R3=len(needle)
619    # $R4=cnt
620    # $R5=tmp
621    loop:
622      StrCpy $R5 $R2 $R3 $R4
623      StrCmp $R5 $R1 done
624      StrCmp $R5 "" done
625      IntOp $R4 $R4 + 1
626      Goto loop
627  done:
628    StrCpy $R1 $R2 "" $R4
629    Pop $R5
630    Pop $R4
631    Pop $R3
632    Pop $R2
633    Exch $R1
634 FunctionEnd
635 !macroend
636
637
638 # TrimNewlines  - taken from the NSIS reference
639 # input, top of stack  (e.g. whatever$\r$\n)
640 # output, top of stack (replaces, with e.g. whatever)
641 # modifies no other variables.
642 Function TrimNewlines
643    Exch $R0
644    Push $R1
645    Push $R2
646    StrCpy $R1 0
647
648  loop:
649    IntOp $R1 $R1 - 1
650    StrCpy $R2 $R0 1 $R1
651    StrCmp $R2 "$\r" loop
652    StrCmp $R2 "$\n" loop
653    IntOp $R1 $R1 + 1
654    IntCmp $R1 0 no_trim_needed
655    StrCpy $R0 $R0 $R1
656
657  no_trim_needed:
658    Pop $R2
659    Pop $R1
660    Exch $R0
661 FunctionEnd
662
663
664 Function .onInit
665   Call G4wRunOnce
666
667   SetOutPath $TEMP
668 !ifdef SOURCES
669   File /oname=gpgspltmp.bmp "${TOP_SRCDIR}/doc/logo/gpg4win-logo-400px.bmp"
670   # We play the tune only for the source installer
671   File /oname=gpgspltmp.wav "${TOP_SRCDIR}/src/gpg4win-splash.wav"
672   g4wihelp::playsound $TEMP\gpgspltmp.wav
673   g4wihelp::showsplash 2500 $TEMP\gpgspltmp.bmp
674
675   Delete $TEMP\gpgspltmp.bmp
676   # Note that we delete gpgspltmp.wav in .onInst{Failed,Success}
677 !else
678   ${GetParameters} $R0
679   ClearErrors
680   ${GetOptions} $R0 /MINIMAL= $is_minimal
681
682   Var /GLOBAL changed_dir
683   # Check if the install directory was modified on the command line
684   StrCmp "$INSTDIR" "$PROGRAMFILES\${INSTALL_DIR}" unmodified 0
685   # It is modified. Save that value.
686   StrCpy $changed_dir "$INSTDIR"
687
688   # MULITUSER_INIT overwrites directory setting from command line
689   !insertmacro MULTIUSER_INIT
690   StrCpy $INSTDIR "$changed_dir"
691   goto initDone
692 unmodified:
693   !insertmacro MULTIUSER_INIT
694 !endif
695 initDone:
696   # Enable this to force a language selection dialog on every run (the
697   # preferred language is the default).  Otherwise, the preferred
698   # language is stored in the registry, and the installer does not ask
699   # on upgrades.
700 !ifdef DEBUG
701 !define MUI_LANGDLL_ALWAYSSHOW
702 !endif
703   !insertmacro MUI_LANGDLL_DISPLAY
704
705 ${IfNot} ${AtLeastWin7}
706     MessageBox MB_OK "$(T_WinisDeprecated)"
707 ${Endif}
708
709   ${MementoSectionRestore}
710   Call CalcDefaults
711   Call CalcDepends
712 !ifndef SOURCES
713   Call CheckOtherGnuPGApps
714 !endif
715 FunctionEnd
716
717
718 Function un.onInit
719 !ifndef SOURCES
720   !insertmacro MULTIUSER_UNINIT
721 !endif
722   # Remove the language preference.
723   !insertmacro MUI_UNGETLANGUAGE
724   StrCpy $is_update "0"
725   ${un.GetParameters} $R0
726   ClearErrors
727   ${un.GetOptions} $R0 /UPDATE= $R1
728   IfErrors +2
729   StrCpy $is_update "1"
730 FunctionEnd
731
732 # This must be in a central place.  Urgs.
733
734 !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
735 !ifdef HAVE_PKG_GNUPG_W32
736   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_gnupg_w32} $(DESC_SEC_gnupg_w32)
737 !endif
738 !ifdef HAVE_PKG_GPGOL
739   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_gpgol} $(DESC_SEC_gpgol)
740 !endif
741 !ifdef HAVE_PKG_GPGEX
742   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_gpgex} $(DESC_SEC_gpgex)
743 !endif
744 !ifdef HAVE_PKG_PAPERKEY
745   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_paperkey} $(DESC_SEC_paperkey)
746 !endif
747 !ifdef HAVE_PKG_GPA
748   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_gpa} $(DESC_SEC_gpa)
749 !endif
750 !ifdef HAVE_PKG_KLEOPATRA
751   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_kleopatra} $(DESC_SEC_kleopatra)
752 !endif
753 !ifdef HAVE_PKG_MAN_NOVICE_EN
754   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_man_novice_en} $(DESC_SEC_man_novice_en)
755 !endif
756 !ifdef HAVE_PKG_MAN_ADVANCED_EN
757   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_man_advanced_en} $(DESC_SEC_man_advanced_en)
758 !endif
759 !ifdef HAVE_PKG_COMPENDIUM
760   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_compendium} $(DESC_SEC_compendium)
761 !endif
762 !ifdef HAVE_PKG_MAN_NOVICE_DE
763   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_man_novice_de} $(DESC_SEC_man_novice_de)
764 !endif
765 !ifdef HAVE_PKG_MAN_ADVANCED_DE
766   !insertmacro MUI_DESCRIPTION_TEXT ${SEC_man_advanced_de} $(DESC_SEC_man_advanced_de)
767 !endif
768 !insertmacro MUI_FUNCTION_DESCRIPTION_END
769