rbtree: add rb_search_exact()
[nasm.git] / nsis / NASMMultiUser.nsh
bloba5dc3a4aa4f2eea5c03e3fac4e44f72b2e869c82
1 /*
3 MultiUser.nsh
5 Installer configuration for multi-user Windows environments
7 Copyright 2008-2009 Joost Verburg
8 Updated 2016 by H. Peter Anvin to handle 64-bit Windows
12 !ifndef MULTIUSER_INCLUDED
13 !define MULTIUSER_INCLUDED
14 !verbose push
15 !verbose 3
17 ;Standard NSIS header files
19 !ifdef MULTIUSER_MUI
20   !include MUI2.nsh
21 !endif
22 !include nsDialogs.nsh
23 !include LogicLib.nsh
24 !include WinVer.nsh
25 !include FileFunc.nsh
27 ;Variables
29 Var MultiUser.Privileges
30 Var MultiUser.InstallMode
32 ;Command line installation mode setting
34 !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
35   !include StrFunc.nsh
36   !ifndef StrStr_INCLUDED
37     ${StrStr}
38   !endif
39   !ifndef MULTIUSER_NOUNINSTALL
40     !ifndef UnStrStr_INCLUDED
41       ${UnStrStr}
42     !endif
43   !endif
45   Var MultiUser.Parameters
46   Var MultiUser.Result
47 !endif
49 ;Installation folder stored in registry
51 !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
52   Var MultiUser.InstDir
53 !endif
55 !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
56   Var MultiUser.DefaultKeyValue
57 !endif
59 ;Windows Vista UAC setting
61 !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
62   RequestExecutionLevel admin
63   !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
64 !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
65   RequestExecutionLevel admin
66   !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
67 !else if "${MULTIUSER_EXECUTIONLEVEL}" == Highest
68   RequestExecutionLevel highest
69   !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
70 !else
71   RequestExecutionLevel user
72 !endif
76 Install modes
80 !macro MULTIUSER_INSTALLMODE_ALLUSERS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
82   ;Install mode initialization - per-machine
84   ${ifnot} ${IsNT}
85     ${orif} $MultiUser.Privileges == "Admin"
86     ${orif} $MultiUser.Privileges == "Power"
88     StrCpy $MultiUser.InstallMode AllUsers
90     SetShellVarContext all
92     !if "${UNINSTALLER_PREFIX}" != UN
93       ;Set default installation location for installer
94       !ifdef MULTIUSER_INSTALLMODE_INSTDIR
95         StrCpy $INSTDIR "${GLOBALINSTDIR}\${MULTIUSER_INSTALLMODE_INSTDIR}"
96       !endif
97     !endif
99     !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
101       ReadRegStr $MultiUser.InstDir HKLM "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
103       ${if} $MultiUser.InstDir != ""
104         StrCpy $INSTDIR $MultiUser.InstDir
105       ${endif}
107     !endif
109     !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
110       Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
111     !endif
113   ${endif}
115 !macroend
117 !macro MULTIUSER_INSTALLMODE_CURRENTUSER UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
119   ;Install mode initialization - per-user
121   ${if} ${IsNT}
123     StrCpy $MultiUser.InstallMode CurrentUser
125     SetShellVarContext current
127     !if "${UNINSTALLER_PREFIX}" != UN
128       ;Set default installation location for installer
129       !ifdef MULTIUSER_INSTALLMODE_INSTDIR
130         ${if} ${AtLeastWin2000}
131           StrCpy $INSTDIR "$LOCALAPPDATA\bin\${MULTIUSER_INSTALLMODE_INSTDIR}"
132         ${else}
133           StrCpy $INSTDIR "${GLOBALINSTDIR}\${MULTIUSER_INSTALLMODE_INSTDIR}"
134         ${endif}
135       !endif
136     !endif
138     !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
140       ReadRegStr $MultiUser.InstDir HKCU "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
142       ${if} $MultiUser.InstDir != ""
143         StrCpy $INSTDIR $MultiUser.InstDir
144       ${endif}
146     !endif
148     !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
149       Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
150     !endif
152   ${endif}
154 !macroend
156 Function MultiUser.InstallMode.AllUsers
157   !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS "" ""
158 FunctionEnd
160 Function MultiUser.InstallMode.CurrentUser
161   !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER "" ""
162 FunctionEnd
164 !ifndef MULTIUSER_NOUNINSTALL
166 Function un.MultiUser.InstallMode.AllUsers
167   !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS UN .un
168 FunctionEnd
170 Function un.MultiUser.InstallMode.CurrentUser
171   !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER UN .un
172 FunctionEnd
174 !endif
178 Installer/uninstaller initialization
182 !macro MULTIUSER_INIT_QUIT UNINSTALLER_FUNCPREFIX
184   !ifdef MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUNCTIONQUIT
185     Call "${MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUCTIONQUIT}
186   !else
187     Quit
188   !endif
190 !macroend
192 !macro MULTIUSER_INIT_TEXTS
194   !ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED
195     !define MULTIUSER_INIT_TEXT_ADMINREQUIRED "$(^Caption) requires Administrator priviledges."
196   !endif
198   !ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED
199     !define MULTIUSER_INIT_TEXT_POWERREQUIRED "$(^Caption) requires at least Power User priviledges."
200   !endif
202   !ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE
203     !define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this compuetr."
204   !endif
206 !macroend
208 !macro MULTIUSER_INIT_CHECKS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
210   ;Installer initialization - check privileges and set install mode
212   !insertmacro MULTIUSER_INIT_TEXTS
214   UserInfo::GetAccountType
215   Pop $MultiUser.Privileges
217   ${if} ${IsNT}
219     ;Check privileges
221     !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
223       ${if} $MultiUser.Privileges != "Admin"
224         MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
225         !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
226       ${endif}
228     !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
230       ${if} $MultiUser.Privileges != "Power"
231         ${andif} $MultiUser.Privileges != "Admin"
232         ${if} ${AtMostWinXP}
233            MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_POWERREQUIRED}"
234         ${else}
235            MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
236         ${endif}
237         !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
238       ${endif}
240     !endif
242     !ifdef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
244       ;Default to per-machine installation if possible
246       ${if} $MultiUser.Privileges == "Admin"
247         ${orif} $MultiUser.Privileges == "Power"
248         !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
249           Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
250         !else
251           Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
252         !endif
254         !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
256           ;Set installation mode to setting from a previous installation
258           !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
259             ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
260             ${if} $MultiUser.DefaultKeyValue == ""
261               ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
262               ${if} $MultiUser.DefaultKeyValue != ""
263                 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
264               ${endif}
265             ${endif}
266           !else
267             ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
268             ${if} $MultiUser.DefaultKeyValue == ""
269               ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
270               ${if} $MultiUser.DefaultKeyValue != ""
271                 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
272               ${endif}
273             ${endif}
274           !endif
276         !endif
278       ${else}
279         Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
280       ${endif}
282     !else
284       Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
286     !endif
288     !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
290       ;Check for install mode setting on command line
292       ${${UNINSTALLER_FUNCPREFIX}GetParameters} $MultiUser.Parameters
294       ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/CurrentUser"
296       ${if} $MultiUser.Result != ""
297         Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
298       ${endif}
300       ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/AllUsers"
302       ${if} $MultiUser.Result != ""
303         ${if} $MultiUser.Privileges == "Admin"
304           ${orif} $MultiUser.Privileges == "Power"
305           Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
306         ${else}
307           MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE}"
308         ${endif}
309       ${endif}
311     !endif
313   ${else}
315     ;Not running Windows NT, per-user installation not supported
317     Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
319   ${endif}
321 !macroend
323 !macro MULTIUSER_INIT
324   !verbose push
325   !verbose 3
327   !insertmacro MULTIUSER_INIT_CHECKS "" ""
329   !verbose pop
330 !macroend
332 !ifndef MULTIUSER_NOUNINSTALL
334 !macro MULTIUSER_UNINIT
335   !verbose push
336   !verbose 3
338   !insertmacro MULTIUSER_INIT_CHECKS Un un.
340   !verbose pop
341 !macroend
343 !endif
347 Modern UI 2 page
351 !ifdef MULTIUSER_MUI
353 !macro MULTIUSER_INSTALLMODEPAGE_INTERFACE
355   !ifndef MULTIUSER_INSTALLMODEPAGE_INTERFACE
356     !define MULTIUSER_INSTALLMODEPAGE_INTERFACE
357     Var MultiUser.InstallModePage
359     Var MultiUser.InstallModePage.Text
361     Var MultiUser.InstallModePage.AllUsers
362     Var MultiUser.InstallModePage.CurrentUser
364     Var MultiUser.InstallModePage.ReturnValue
365   !endif
367 !macroend
369 !macro MULTIUSER_PAGEDECLARATION_INSTALLMODE
371   !insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""
372   !insertmacro MULTIUSER_INSTALLMODEPAGE_INTERFACE
374   !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_TOP "$(MULTIUSER_INNERTEXT_INSTALLMODE_TOP)"
375   !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS "$(MULTIUSER_INNERTEXT_INSTALLMODE_ALLUSERS)"
376   !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER "$(MULTIUSER_INNERTEXT_INSTALLMODE_CURRENTUSER)"
378   PageEx custom
380     PageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
382     Caption " "
384   PageExEnd
386   !insertmacro MULTIUSER_FUNCTION_INSTALLMODEPAGE MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
388   !undef MULTIUSER_INSTALLMODEPAGE_TEXT_TOP
389   !undef MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS
390   !undef MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER
392 !macroend
394 !macro MULTIUSER_PAGE_INSTALLMODE
396   ;Modern UI page for install mode
398   !verbose push
399   !verbose 3
401   !ifndef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
402     !error "A mixed-mode installation requires MULTIUSER_EXECUTIONLEVEL to be set to Admin, Power or Highest."
403   !endif
405   !insertmacro MUI_PAGE_INIT
406   !insertmacro MULTIUSER_PAGEDECLARATION_INSTALLMODE
408   !verbose pop
410 !macroend
412 !macro MULTIUSER_FUNCTION_INSTALLMODEPAGE PRE LEAVE
414   !ifndef MULTIUSER_TEXT_NOTADMIN
415     !define MULTIUSER_TEXT_NOTADMIN "The installer is currently running as an unprivileged user.  It will not be possible to install this software for all users on the system.  Cancel and re-run the installer as Administrator to install system-wide."
416   !endif
418   ;Page functions of Modern UI page
420   Function "${PRE}"
422     ${ifnot} ${IsNT}
423       Abort
424     ${endif}
426     ${if} $MultiUser.Privileges != "Power"
427       ${andif} $MultiUser.Privileges != "Admin"
428         MessageBox MB_OKCANCEL "${MULTIUSER_TEXT_NOTADMIN}" /SD IDOK IDABORT nofun
429         Abort
431     nofun:
432         Quit
433     ${endif}
435     !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
436     !insertmacro MUI_HEADER_TEXT_PAGE $(MULTIUSER_TEXT_INSTALLMODE_TITLE) $(MULTIUSER_TEXT_INSTALLMODE_SUBTITLE)
438     nsDialogs::Create 1018
439     Pop $MultiUser.InstallModePage
441     ${NSD_CreateLabel} 0u 0u 300u 20u "${MULTIUSER_INSTALLMODEPAGE_TEXT_TOP}"
442     Pop $MultiUser.InstallModePage.Text
444     ${NSD_CreateRadioButton} 20u 50u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS}"
445     Pop $MultiUser.InstallModePage.AllUsers
447     ${NSD_CreateRadioButton} 20u 70u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER}"
448     Pop $MultiUser.InstallModePage.CurrentUser
450     ${if} $MultiUser.InstallMode == "AllUsers"
451       SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0
452     ${else}
453       SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0
454     ${endif}
456     !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
457     nsDialogs::Show
459   FunctionEnd
461   Function "${LEAVE}"
462      SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue
464      ${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}
465         Call MultiUser.InstallMode.AllUsers
466      ${else}
467         Call MultiUser.InstallMode.CurrentUser
468      ${endif}
470     !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE
471   FunctionEnd
473 !macroend
475 !endif
477 !verbose pop
478 !endif