]> git.sesse.net Git - vlc/commitdiff
Win32: don't launch VLC as admin after installing
authorGeoffroy Couprie <geal@videolan.org>
Fri, 5 Mar 2010 18:48:17 +0000 (19:48 +0100)
committerGeoffroy Couprie <geal@videolan.org>
Fri, 5 Mar 2010 19:35:59 +0000 (20:35 +0100)
Fixes 3192

Makefile.am
extras/package/win32/UAC.dll [new file with mode: 0644]
extras/package/win32/UAC.nsh [new file with mode: 0644]
extras/package/win32/vlc.win32.nsi.in

index 08ac51d15478966bed4b4335e47969ff506029b0..d4ad59e62bb0e3bebce271968f2ed27edd379dcb 100644 (file)
@@ -48,6 +48,8 @@ EXTRA_DIST = \
        extras/package/rpm/vlc.altlinux.spec \
        extras/package/win32/vlc.win32.nsi.in \
        extras/package/win32/spad.nsi.in \
+       extras/package/win32/UAC.nsh \
+       extras/package/win32/UAC.dll \
        extras/package/win32/languages/declaration.nsh \
        extras/package/win32/languages/english.nsh \
        extras/package/win32/languages/french.nsh
@@ -772,6 +774,8 @@ package-win32-base-debug: package-win-common
 # Script installer
        cp "$(top_builddir)/extras/package/win32/vlc.win32.nsi" "$(win32_destdir)/"
        cp "$(top_builddir)/extras/package/win32/spad.nsi" "$(win32_destdir)/"
+       cp "$(srcdir)/extras/package/win32/UAC.nsh" "$(win32_destdir)/"
+       cp "$(srcdir)/extras/package/win32/UAC.dll" "$(win32_destdir)/"
        mkdir "$(win32_destdir)/languages"
        cp $(srcdir)/extras/package/win32/languages/*.nsh "$(win32_destdir)/languages/"
 
diff --git a/extras/package/win32/UAC.dll b/extras/package/win32/UAC.dll
new file mode 100644 (file)
index 0000000..edf2130
Binary files /dev/null and b/extras/package/win32/UAC.dll differ
diff --git a/extras/package/win32/UAC.nsh b/extras/package/win32/UAC.nsh
new file mode 100644 (file)
index 0000000..9df8cef
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+=======================
+UAC helper include file
+.......................
+
+Macros starting with UAC.I should only be called from the installer and vice versa for UAC.U macros.
+
+*/
+!ifndef UAC_HDR__INC
+!define UAC_HDR__INC
+!include LogicLib.nsh
+
+!define UAC.RunElevatedAndProcessMessages 'UAC::RunElevated '
+!define UAC.Unload 'UAC::Unload '
+!define UAC.StackPush 'UAC::StackPush '
+
+/*!macro _UAC.BuildOnInitElevationFunc _funcprefix
+Function ${_funcprefix}onInit
+!ifmacrodef
+FunctionEnd
+!macroend*/
+
+!macro _UAC.GenerateSimpleFunction _funcprefix _funcName _funcCode
+Function ${_funcprefix}${_funcName}
+${_funcCode}
+#messagebox mb_ok "${_funcprefix}${_funcName}"
+FunctionEnd
+!macroend
+
+!macro _UAC.TryDef _d _v
+!ifndef ${_d}
+!define ${_d} "${_v}"
+!endif
+!macroend
+
+!macro _UAC.InitStrings _modeprefix
+!insertmacro _UAC.TryDef UACSTR.UnDataFile "UAC.dat"
+!insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvWinErr "Unable to elevate , error $0"
+!ifNdef __UNINSTALL__
+       !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvAbortReqAdmin "This installer requires admin access, aborting!"
+       !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvMustTryAgain "This installer requires admin access, try again"
+       !else
+       !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvAbortReqAdmin "This uninstaller requires admin access, aborting!"
+       !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvMustTryAgain "This uninstaller requires admin access, try again"
+       !endif
+!macroend
+
+!ifmacroNdef _UAC.GenerateUninstallerTango
+!macro _UAC.GenerateUninstallerTango UninstallerFileName
+!ifdef __GLOBAL__
+       !error "UAC: Needs to be called inside a function"
+       !endif
+!ifNdef __UNINSTALL__
+       !error "UAC: _UAC.GenerateUninstallerTango should only be called by uninstaller, see http://forums.winamp.com/showthread.php?threadid=280330"
+       !endif
+!ifNdef UAC_UNINSTALLERTANGOFORALLPLATFORMS
+       !include WinVer.nsh
+       !endif
+!insertmacro _UAC.InitStrings 'U.'
+ReadIniStr $0 "$ExeDir\${UACSTR.UnDataFile}" UAC "Un.Ready"
+${IF} $0 != 1
+!ifNdef UAC_UNINSTALLERTANGOFORALLPLATFORMS
+${AndIf} ${AtLeastWinVista}
+!endif
+       InitPluginsDir
+       WriteIniStr "$PluginsDir\${UACSTR.UnDataFile}" UAC "Un.Ready" 1
+       CopyFiles /SILENT "$EXEPATH" "$PluginsDir\${UninstallerFileName}"
+       StrCpy $0 ""
+       ${IfThen} ${Silent} ${|} StrCpy $0 "/S " ${|}
+       ExecWait '"$PluginsDir\${UninstallerFileName}" $0/NCRC _?=$INSTDIR' $0
+       SetErrorLevel $0
+       Quit
+       ${EndIf}
+!macroend
+!endif
+
+!ifmacroNdef _UAC.GenerateOnInitElevationCode
+!macro _UAC.GenerateOnInitElevationCode _modeprefix
+!ifndef __FUNCTION__
+       !error "UAC: Needs to be called inside a function"
+       !endif
+!insertmacro _UAC.InitStrings ${_modeprefix}
+!define _UAC.GOIECUniq L${__LINE__}
+UAC_Elevate_${_UAC.GOIECUniq}:
+UAC::RunElevated 
+StrCmp 1223 $0 UAC_ElevationAborted_${_UAC.GOIECUniq} ; UAC dialog aborted by user?
+StrCmp 0 $0 0 UAC_Err_${_UAC.GOIECUniq} ; Error?
+StrCmp 1 $1 0 UAC_Success_${_UAC.GOIECUniq} ;Are we the real deal or just the wrapper?
+Quit
+UAC_Err_${_UAC.GOIECUniq}:
+MessageBox mb_iconstop "${UACSTR.${_modeprefix}ElvWinErr}"
+Abort
+UAC_ElevationAborted_${_UAC.GOIECUniq}:
+MessageBox mb_iconstop "${UACSTR.${_modeprefix}ElvAbortReqAdmin}"
+Abort
+UAC_Success_${_UAC.GOIECUniq}:
+# if $0==0 && $3==1, we are a member of the admin group (Any OS)
+# if $0==0 && $1==0, UAC not supported (Probably <NT6), run as normal?
+# if $0==0 && $1==3, we can try to elevate again
+StrCmp 1 $3 /*+4*/ UAC_Done_${_UAC.GOIECUniq} ;Admin?
+StrCmp 3 $1 0 UAC_ElevationAborted_${_UAC.GOIECUniq} ;Try again or abort?
+MessageBox mb_iconexclamation "${UACSTR.${_modeprefix}ElvMustTryAgain}" ;Inform user...
+goto UAC_Elevate_${_UAC.GOIECUniq} ;...lets try again
+UAC_Done_${_UAC.GOIECUniq}:
+!undef _UAC.GOIECUniq
+!macroend
+!endif
+
+!define UAC.I.Elevate.AdminOnly '!insertmacro UAC.I.Elevate.AdminOnly '
+!macro UAC.I.Elevate.AdminOnly
+!insertmacro _UAC.GenerateOnInitElevationCode 'I.'
+!macroend
+
+!define UAC.U.Elevate.AdminOnly '!insertmacro UAC.U.Elevate.AdminOnly '
+!macro UAC.U.Elevate.AdminOnly _UninstallerName
+!ifNdef UAC_DISABLEUNINSTALLERTANGO
+       !insertmacro _UAC.GenerateUninstallerTango "${_UninstallerName}"
+       !endif
+!insertmacro _UAC.GenerateOnInitElevationCode 'U.'
+!macroend
+
+!define UAC.AutoCodeUnload '!insertmacro UAC.AutoCodeUnload '
+!macro UAC.AutoCodeUnload _HasUninstaller
+!insertmacro _UAC.GenerateSimpleFunction "" .OnInstFailed '${UAC.Unload}'
+!insertmacro _UAC.GenerateSimpleFunction "" .OnInstSuccess '${UAC.Unload}'
+!ifNdef MUI_INCLUDED
+       !insertmacro _UAC.GenerateSimpleFunction "" .onUserAbort '${UAC.Unload}'
+       !else
+       !ifNdef MUI_CUSTOMFUNCTION_ABORT
+               !error "UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_ABORT!"
+               !endif
+       !endif
+!if "${_HasUninstaller}" != ""
+       !insertmacro _UAC.GenerateSimpleFunction "un" .onUninstFailed '${UAC.Unload}'
+       !insertmacro _UAC.GenerateSimpleFunction "un" .onUninstSuccess '${UAC.Unload}'
+       !ifNdef MUI_INCLUDED
+               !insertmacro _UAC.GenerateSimpleFunction "un" .onUserAbort '${UAC.Unload}'
+               !else
+               !ifNdef MUI_CUSTOMFUNCTION_ABORT
+                       !error "UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_(UN)ABORT!"
+                       !endif
+               !endif
+       !endif
+!macroend
+
+!define UAC.FastCallFunctionAsUser '!insertmacro UAC.FastCallFunctionAsUser '
+!macro UAC.FastCallFunctionAsUser _func _var
+GetFunctionAddress ${_var} ${_func}
+UAC::ExecCodeSegment ${_var}
+!macroend
+!define UAC.CallFunctionAsUser '!insertmacro UAC.CallFunctionAsUser '
+!macro UAC.CallFunctionAsUser _func
+push $R9
+!insertmacro UAC.FastCallFunctionAsUser ${_func} $R9
+pop $R9
+!macroend
+
+!define UAC.FastCallGetOuterInstanceHwndParent UAC::GetOuterHwnd
+!define UAC.GetOuterInstanceHwndParent '!insertmacro UAC.GetOuterInstanceHwndParent '
+!macro UAC.GetOuterInstanceHwndParent _var
+push $0
+${UAC.FastCallGetOuterInstanceHwndParent}
+Exch $0
+Pop ${_var}
+!macroend
+
+
+
+!macro _UAC.DumpEx _disp _f _fp _v
+${_f} ${_fp}
+DetailPrint "${_disp}=${_v}"
+!macroend
+!macro _UAC.Dump _f _fp _v
+!insertmacro _UAC.DumpEx `${_f}` `${_f}` `${_fp}` `${_v}`
+!macroend
+!macro _UAC.DbgDetailPrint
+push $0
+push $1
+System::Call /NoUnload "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})"
+System::Call "Kernel32::GetComputerName(t.r1,*i${NSIS_MAX_STRLEN})"
+DetailPrint "$1\$0"
+;!insertmacro _UAC.DumpEx "User" System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})" $0
+!insertmacro _UAC.DumpEx "CmdLine" "" "" "$CmdLine"
+!insertmacro _UAC.Dump UAC::IsAdmin "" $0
+!insertmacro _UAC.Dump UAC::SupportsUAC "" $0
+!insertmacro _UAC.Dump UAC::GetElevationType "" $0
+pop $1
+pop $0
+!macroend
+
+!endif /* ifndef UAC_HDR__INC */
\ No newline at end of file
index f7712f9fa541a3351e536c1b02bb9c80d51cac74..8c462a008e8e96f22ee2bb814a62e739982d57b7 100644 (file)
@@ -48,6 +48,11 @@ InstType $Name_InstTypeRecommended
 InstType $Name_InstTypeMinimum
 InstType $Name_InstTypeFull
 
+RequestExecutionLevel user
+!addincludedir .
+!addplugindir .
+!include UAC.nsh
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; NSIS Modern User Interface configuration ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -75,7 +80,17 @@ InstType $Name_InstTypeFull
   ; Instfiles page
     !insertmacro MUI_PAGE_INSTFILES
   ; Finish page
-    !define MUI_FINISHPAGE_RUN "$INSTDIR\vlc.exe"
+
+    Function ExecAppFile
+      Exec '$INSTDIR\vlc.exe'
+    FunctionEnd
+
+    Function AppRunAs
+      !insertmacro UAC.CallFunctionAsUser ExecAppFile
+    FunctionEnd
+
+    !define MUI_FINISHPAGE_RUN
+    !define MUI_FINISHPAGE_RUN_FUNCTION AppRunAs
     !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt"
     !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
     !define MUI_FINISHPAGE_LINK $Link_VisitWebsite
@@ -314,11 +329,15 @@ FunctionEnd
 ; 3. Delete prefs and cache ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+Function ExecCacheGen
+  ExecWait "$INSTDIR\vlc-cache-gen.exe $APPDATA\\VideoLAN\\VLC"
+FunctionEnd
+
 !macro gencache
   SetShellVarContext all
   CreateDirectory "$APPDATA\\VideoLAN"
   CreateDirectory "$APPDATA\\VideoLAN\\VLC"
-  ExecWait "$INSTDIR\vlc-cache-gen.exe $APPDATA\\VideoLAN\\VLC"
+  !insertmacro UAC.CallFunctionAsUser ExecCacheGen
   SetShellVarContext current
 !macroend
 
@@ -664,6 +683,27 @@ SectionEnd
 
 ;;; Start function
 Function .onInit
+
+UAC_Elevate:
+    UAC::RunElevated
+    StrCmp 1223 $0 UAC_ElevationAborted
+    StrCmp 0 $0 0 UAC_Err
+    StrCmp 1 $1 0 UAC_Success
+    Quit
+
+UAC_Err:
+    MessageBox mb_iconstop "Unable to elevate, error $0"
+    Abort
+
+UAC_ElevationAborted:
+    MessageBox mb_iconstop "This installer requires admin access, aborting!"
+    Abort
+
+UAC_Success:
+    StrCmp 1 $3 +4
+    StrCmp 3 $1 0 UAC_ElevationAborted
+    MessageBox mb_iconstop "This installer requires admin access, try again"
+    goto UAC_Elevate
   !insertmacro MUI_LANGDLL_DISPLAY
 
   !include "languages\english.nsh"
@@ -734,6 +774,13 @@ Function .onInit
 
 FunctionEnd
 
+Function .OnInstFailed
+    UAC::Unload
+FunctionEnd
+
+Function .OnInstSuccess
+    UAC::Unload
+FunctionEnd
 ;; End function
 Section -Post
   WriteUninstaller "$INSTDIR\uninstall.exe"
@@ -916,13 +963,38 @@ SectionEnd
   !insertmacro MUI_DESCRIPTION_TEXT ${SEC92} $Desc_Section92
 !insertmacro MUI_UNFUNCTION_DESCRIPTION_END
 
-;Function un.onUninstSuccess
-;  HideWindow
-;  MessageBox MB_ICONINFORMATION|MB_OK \
-;    "$(^Name) was successfully removed from your computer."
-;FunctionEnd
+Function un.OnUnInstFailed
+    UAC::Unload
+FunctionEnd
+
+Function un.OnUnInstSuccess
+    UAC::Unload
+    Delete "$INSTDIR\UAC.dll"
+FunctionEnd
 
 Function un.onInit
+
+UAC_Elevate:
+    UAC::RunElevated
+    StrCmp 1223 $0 UAC_ElevationAborted
+    StrCmp 0 $0 0 UAC_Err
+    StrCmp 1 $1 0 UAC_Success
+    Quit
+
+UAC_Err:
+    MessageBox mb_iconstop "Unable to elevate, error $0"
+    Abort
+
+UAC_ElevationAborted:
+    MessageBox mb_iconstop "This installer requires admin access, aborting!"
+    Abort
+
+UAC_Success:
+    StrCmp 1 $3 +4
+    StrCmp 3 $1 0 UAC_ElevationAborted
+    MessageBox mb_iconstop "This installer requires admin access, try again"
+    goto UAC_Elevate
+
   !insertmacro MUI_UNGETLANGUAGE
 
   !include "languages\english.nsh"