Archive: UAC plugin CallFunctionAsUser GetTempPath returns empty?


UAC plugin CallFunctionAsUser GetTempPath returns empty?
  I want to make an installer with UAC plugin where I can detect some original user folders using the user level process, and then copying files to Program Files using the elevated admin user process.

I began by finding the TEMP folder, calling GetTempPath using System plugin, but calling it in the user level process returns emtpy string or "0" ("0" if I run it in a virtual XP from a non-admin user, and when the elevation dialog pops I enter an admin user credentials).

Can anybody tell me why it happens or how should I do it? Here's my complete script:


SetCompressor lzma


OutFile.TempDir.exe

Name "TempDir"
>VIProductVersion "1.0.0.0"
>VIAddVersionKey "FileVersion" "1.0.0.0"
>VIAddVersionKey "FileDescription" "TempDir"
>VIAddVersionKey "ProductName" "TempDir"
>VIAddVersionKey "CompanyName" "Temp dir Inc."
>VIAddVersionKey "LegalCopyright" "lalala (c) 2009"
>RequestExecutionLevel user

SilentInstall silent

>!include UAC.nsh
>!include LogicLib.nsh

>Function .OnInit
${UAC.I.Elevate.AdminOnly}
>FunctionEnd

>Function .OnInstFailed
${UAC.Unload}
>FunctionEnd

>Function .OnInstSuccess
${UAC.Unload}
>FunctionEnd

>!define GetTemp "!insertmacro GetTemp"
>!macro GetTemp Answer
Call GetTemp
Pop${Answer}
!macroend
>!define UserGetTemp "!insertmacro UserGetTemp"
>!macro UserGetTemp Answer
${UAC.CallFunctionAsUser} GetTemp
Pop${Answer}
!macroend
>Function GetTemp
Push $R1

Push $R0
System
::Call "*(&t${NSIS_MAX_STRLEN}) i .R0"
System::Call "kernel32.dll::GetTempPathA(i ${NSIS_MAX_STRLEN}, i R0)"
System::Call "*$R0(&t${NSIS_MAX_STRLEN} .R1)"
System::Free $R0
Pop $R0

Push $R2
StrCpy $R2 $R1"" -1
${If} $R2 == "\"
${OrIf} $R2 == "/"
StrCpy $R1 $R1 -1
${EndIf}
Pop $R2

Exch $R1
FunctionEnd

Section
${UserGetTemp} $0
${GetTemp} $1
MessageBox MB_OK "$$TEMP: $TEMP$nUser Temp: $0$nTemp: $1"
SectionEnd
>

you can't read the "user" stack in the admin process

you can use UAC::GetShellFolderPath (I can't remember if there is a CSIDL_TEMP)