UAC.nsh 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. =======================
  3. UAC helper include file
  4. .......................
  5. Macros starting with UAC.I should only be called from the installer and vice versa for UAC.U macros.
  6. */
  7. !ifndef UAC_HDR__INC
  8. !define UAC_HDR__INC
  9. !include LogicLib.nsh
  10. !define UAC.RunElevatedAndProcessMessages 'UAC::RunElevated '
  11. !define UAC.Unload 'UAC::Unload '
  12. !define UAC.StackPush 'UAC::StackPush '
  13. /*!macro _UAC.BuildOnInitElevationFunc _funcprefix
  14. Function ${_funcprefix}onInit
  15. !ifmacrodef
  16. FunctionEnd
  17. !macroend*/
  18. !macro _UAC.GenerateSimpleFunction _funcprefix _funcName _funcCode
  19. Function ${_funcprefix}${_funcName}
  20. ${_funcCode}
  21. #messagebox mb_ok "${_funcprefix}${_funcName}"
  22. FunctionEnd
  23. !macroend
  24. !macro _UAC.TryDef _d _v
  25. !ifndef ${_d}
  26. !define ${_d} "${_v}"
  27. !endif
  28. !macroend
  29. !macro _UAC.InitStrings _modeprefix
  30. !insertmacro _UAC.TryDef UACSTR.UnDataFile "UAC.dat"
  31. !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvWinErr "Unable to elevate , error $0"
  32. !ifNdef __UNINSTALL__
  33. !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvAbortReqAdmin "This installer requires admin access, aborting!"
  34. !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvMustTryAgain "This installer requires admin access, try again"
  35. !else
  36. !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvAbortReqAdmin "This uninstaller requires admin access, aborting!"
  37. !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvMustTryAgain "This uninstaller requires admin access, try again"
  38. !endif
  39. !macroend
  40. !ifmacroNdef _UAC.GenerateUninstallerTango
  41. !macro _UAC.GenerateUninstallerTango UninstallerFileName
  42. !ifdef __GLOBAL__
  43. !error "UAC: Needs to be called inside a function"
  44. !endif
  45. !ifNdef __UNINSTALL__
  46. !error "UAC: _UAC.GenerateUninstallerTango should only be called by uninstaller, see http://forums.winamp.com/showthread.php?threadid=280330"
  47. !endif
  48. !ifNdef UAC_UNINSTALLERTANGOFORALLPLATFORMS
  49. !include WinVer.nsh
  50. !endif
  51. !insertmacro _UAC.InitStrings 'U.'
  52. ReadIniStr $0 "$ExeDir\${UACSTR.UnDataFile}" UAC "Un.Ready"
  53. ${IF} $0 != 1
  54. !ifNdef UAC_UNINSTALLERTANGOFORALLPLATFORMS
  55. ${AndIf} ${AtLeastWinVista}
  56. !endif
  57. InitPluginsDir
  58. WriteIniStr "$PluginsDir\${UACSTR.UnDataFile}" UAC "Un.Ready" 1
  59. CopyFiles /SILENT "$EXEPATH" "$PluginsDir\${UninstallerFileName}"
  60. StrCpy $0 ""
  61. ${IfThen} ${Silent} ${|} StrCpy $0 "/S " ${|}
  62. ExecWait '"$PluginsDir\${UninstallerFileName}" $0/NCRC _?=$INSTDIR' $0
  63. SetErrorLevel $0
  64. Quit
  65. ${EndIf}
  66. !macroend
  67. !endif
  68. !ifmacroNdef _UAC.GenerateOnInitElevationCode
  69. !macro _UAC.GenerateOnInitElevationCode _modeprefix
  70. !ifndef __FUNCTION__
  71. !error "UAC: Needs to be called inside a function"
  72. !endif
  73. !insertmacro _UAC.InitStrings ${_modeprefix}
  74. !define _UAC.GOIECUniq L${__LINE__}
  75. UAC_Elevate_${_UAC.GOIECUniq}:
  76. UAC::RunElevated
  77. StrCmp 1223 $0 UAC_ElevationAborted_${_UAC.GOIECUniq} ; UAC dialog aborted by user?
  78. StrCmp 0 $0 0 UAC_Err_${_UAC.GOIECUniq} ; Error?
  79. StrCmp 1 $1 0 UAC_Success_${_UAC.GOIECUniq} ;Are we the real deal or just the wrapper?
  80. Quit
  81. UAC_Err_${_UAC.GOIECUniq}:
  82. MessageBox mb_iconstop "${UACSTR.${_modeprefix}ElvWinErr}"
  83. Abort
  84. UAC_ElevationAborted_${_UAC.GOIECUniq}:
  85. MessageBox mb_iconstop "${UACSTR.${_modeprefix}ElvAbortReqAdmin}"
  86. Abort
  87. UAC_Success_${_UAC.GOIECUniq}:
  88. # if $0==0 && $3==1, we are a member of the admin group (Any OS)
  89. # if $0==0 && $1==0, UAC not supported (Probably <NT6), run as normal?
  90. # if $0==0 && $1==3, we can try to elevate again
  91. StrCmp 1 $3 /*+4*/ UAC_Done_${_UAC.GOIECUniq} ;Admin?
  92. StrCmp 3 $1 0 UAC_ElevationAborted_${_UAC.GOIECUniq} ;Try again or abort?
  93. MessageBox mb_iconexclamation "${UACSTR.${_modeprefix}ElvMustTryAgain}" ;Inform user...
  94. goto UAC_Elevate_${_UAC.GOIECUniq} ;...lets try again
  95. UAC_Done_${_UAC.GOIECUniq}:
  96. !undef _UAC.GOIECUniq
  97. !macroend
  98. !endif
  99. !define UAC.I.Elevate.AdminOnly '!insertmacro UAC.I.Elevate.AdminOnly '
  100. !macro UAC.I.Elevate.AdminOnly
  101. !insertmacro _UAC.GenerateOnInitElevationCode 'I.'
  102. !macroend
  103. !define UAC.U.Elevate.AdminOnly '!insertmacro UAC.U.Elevate.AdminOnly '
  104. !macro UAC.U.Elevate.AdminOnly _UninstallerName
  105. !ifNdef UAC_DISABLEUNINSTALLERTANGO
  106. !insertmacro _UAC.GenerateUninstallerTango "${_UninstallerName}"
  107. !endif
  108. !insertmacro _UAC.GenerateOnInitElevationCode 'U.'
  109. !macroend
  110. !define UAC.AutoCodeUnload '!insertmacro UAC.AutoCodeUnload '
  111. !macro UAC.AutoCodeUnload _HasUninstaller
  112. !insertmacro _UAC.GenerateSimpleFunction "" .OnInstFailed '${UAC.Unload}'
  113. !insertmacro _UAC.GenerateSimpleFunction "" .OnInstSuccess '${UAC.Unload}'
  114. !ifNdef MUI_INCLUDED
  115. !insertmacro _UAC.GenerateSimpleFunction "" .onUserAbort '${UAC.Unload}'
  116. !else
  117. !ifNdef MUI_CUSTOMFUNCTION_ABORT
  118. !error "UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_ABORT!"
  119. !endif
  120. !endif
  121. !if "${_HasUninstaller}" != ""
  122. !insertmacro _UAC.GenerateSimpleFunction "un" .onUninstFailed '${UAC.Unload}'
  123. !insertmacro _UAC.GenerateSimpleFunction "un" .onUninstSuccess '${UAC.Unload}'
  124. !ifNdef MUI_INCLUDED
  125. !insertmacro _UAC.GenerateSimpleFunction "un" .onUserAbort '${UAC.Unload}'
  126. !else
  127. !ifNdef MUI_CUSTOMFUNCTION_ABORT
  128. !error "UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_(UN)ABORT!"
  129. !endif
  130. !endif
  131. !endif
  132. !macroend
  133. !define UAC.FastCallFunctionAsUser '!insertmacro UAC.FastCallFunctionAsUser '
  134. !macro UAC.FastCallFunctionAsUser _func _var
  135. GetFunctionAddress ${_var} ${_func}
  136. UAC::ExecCodeSegment ${_var}
  137. !macroend
  138. !define UAC.CallFunctionAsUser '!insertmacro UAC.CallFunctionAsUser '
  139. !macro UAC.CallFunctionAsUser _func
  140. push $R9
  141. !insertmacro UAC.FastCallFunctionAsUser ${_func} $R9
  142. pop $R9
  143. !macroend
  144. !define UAC.FastCallGetOuterInstanceHwndParent UAC::GetOuterHwnd
  145. !define UAC.GetOuterInstanceHwndParent '!insertmacro UAC.GetOuterInstanceHwndParent '
  146. !macro UAC.GetOuterInstanceHwndParent _var
  147. push $0
  148. ${UAC.FastCallGetOuterInstanceHwndParent}
  149. Exch $0
  150. Pop ${_var}
  151. !macroend
  152. !macro _UAC.DumpEx _disp _f _fp _v
  153. ${_f} ${_fp}
  154. DetailPrint "${_disp}=${_v}"
  155. !macroend
  156. !macro _UAC.Dump _f _fp _v
  157. !insertmacro _UAC.DumpEx `${_f}` `${_f}` `${_fp}` `${_v}`
  158. !macroend
  159. !macro _UAC.DbgDetailPrint
  160. push $0
  161. push $1
  162. System::Call /NoUnload "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})"
  163. System::Call "Kernel32::GetComputerName(t.r1,*i${NSIS_MAX_STRLEN})"
  164. DetailPrint "$1\$0"
  165. ;!insertmacro _UAC.DumpEx "User" System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})" $0
  166. !insertmacro _UAC.DumpEx "CmdLine" "" "" "$CmdLine"
  167. !insertmacro _UAC.Dump UAC::IsAdmin "" $0
  168. !insertmacro _UAC.Dump UAC::SupportsUAC "" $0
  169. !insertmacro _UAC.Dump UAC::GetElevationType "" $0
  170. pop $1
  171. pop $0
  172. !macroend
  173. !endif /* ifndef UAC_HDR__INC */