Anteaus Posted May 26, 2010 Share Posted May 26, 2010 (edited) Trying to get CreateProcessAsUser to work with AutoIt. Have it working with C but can't seem to figure-out the right variable types to use in AutoIt. Presently the call doesn't throw any exceptions and @error=0, but it doesn't launch the process either. expandcollapse popup#include <StructureConstants.au3> (3.2.6.1) $lpApplicationName="" $lpCommandline=$thisProcess $lpProcessAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) $lpThreadAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) $bInheritHandles=FALSE $dwCreationFlags=0x0 $lpEnvironment="" $lpCurrentDirectory="" $si=dllstructcreate($tagSTARTUPINFO) $pi=dllstructcreate($tagPROCESS_INFORMATION) DLLStructSetData($lpThreadAttributes,"Descriptor","") $ta_size=dllstructgetsize($lpThreadAttributes) DLLStructSetData($lpThreadAttributes,"Length",$ta_size) DLLStructSetData($lpProcessAttributes,"Descriptor","") $pa_size=dllstructgetsize($lpProcessAttributes) DLLStructSetData($lpProcessAttributes,"Length",$pa_size) DLLStructSetData($si,"lpDesktop","winsta0\default") $pi_size=dllstructgetsize($pi) $si_size=dllstructgetsize($si) DLLStructSetData($pi,"Size",$pi_size) DLLStructSetData($si,"Size",$si_size) $a_PCall = DllCall("advapi32.dll", "int", "CreateProcessAsUser", _ "handle", $hToken, _ "str",$lpApplicationName, _ "str",$lpCommandline, _ "ptr",dllstructgetptr($lpProcessAttributes), _ "ptr",dllstructgetptr($lpThreadAttributes), _ "bool",$bInheritHandles, _ "dword",$dwCreationFlags, _ "int_ptr",$lpEnvironment, _ "str",$lpCurrentDirectory, _ "ptr", dllstructgetptr($si), _ "ptr", dllstructgetptr($pi)) If I test with all of the params set to be null pointers except for the token, commandline and $si/$pi, then it does work. Some C writeups suggest this approach is OK, however in my case I need to set certain parameters. Any advice welcome. Edited May 26, 2010 by Anteaus Link to comment Share on other sites More sharing options...
trancexx Posted May 26, 2010 Share Posted May 26, 2010 Post the code that works. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Anteaus Posted May 26, 2010 Author Share Posted May 26, 2010 Here's a self-contained function, makes it easier to test: Uses 3.3.6.1 compiler. expandcollapse popup#include <StructureConstants.au3> SaferLaunchProcess("cmd.exe") exit func SaferLaunchProcess($thisProcess) local $SAFER_LEVELID_NORMALUSER = 0x20000 local $SAFER_SCOPEID_USER = 2 local $SAFER_LEVEL_OPEN = 1 ;Open handle $a_iCall = DllCall("advapi32.dll", "int", "SaferCreateLevel", _ "dword", $SAFER_SCOPEID_USER, _ "dword", $SAFER_LEVELID_NORMALUSER, _ "dword", $SAFER_LEVEL_OPEN, _ "hwnd*", 0, _ "ptr", 0) If @error Or Not $a_iCall[0] Then msgbox(0,"Error","Failure opening handle occured!") EndIf $hHandle = $a_iCall[4] $a_LCall = DllCall("advapi32.dll", "int", "SaferComputeTokenFromLevel", _ "dword", $hHandle, _ "ptr",0, _ "hwnd*",0, _ "ptr",0, _ "ptr",0) If @error Or Not $a_iCall[0] Then msgbox(0,"Error","Failure computing Token occured") return 0 EndIf $hToken=$a_LCall[3] $si=dllstructcreate($tagSTARTUPINFO) $pi=dllstructcreate($tagPROCESS_INFORMATION) $pi_size=dllstructgetsize($pi) $si_size=dllstructgetsize($si) $si_lpDesktop="" DLLStructSetData($pi,"Size",$pi_size) DLLStructSetData($si,"Size",$si_size) $console="0x3" $a_PCall = DllCall("advapi32.dll", "int", "CreateProcessAsUser", _ "dword", $hToken, _ "ptr",0, _ "str",$thisProcess, _ "ptr","", _ "ptr","", _ "ptr",0, _ "str*",$console, _ "ptr","", _ "ptr","", _ "ptr", dllstructgetptr($si), _ "ptr", dllstructgetptr($pi)) $dllerr=@error if $a_Pcall[0]>0 then $pHandle=$a_Pcall[1] else $pHandle=0 endif ;Close handle $a_iCall = DllCall("advapi32.dll", "int", "SaferCloseLevel", _ "hwnd", $hHandle) $pi="" $si="" return $pHandle endfunc Section in-question is: $a_PCall = DllCall("advapi32.dll", "int", "CreateProcessAsUser", _ "dword", $hToken, _ "ptr",0, _ "str",$thisProcess, _ "ptr","", _ "ptr","", _ "ptr",0, _ "str*",$console, _ "ptr","", _ "ptr","", _ "ptr", dllstructgetptr($si), _ "ptr", dllstructgetptr($pi)) ..and basically this is wrong in many respects but for some reason it works, whereas the attempt at correct coding does not. Link to comment Share on other sites More sharing options...
Sundance Posted May 26, 2010 Share Posted May 26, 2010 (edited) When using the DLLCALL 'CreateProcessAsUserW' the call should look like this: $aResult = DllCall("advapi32.dll", "int", "CreateProcessAsUserW", "ptr", $hToken, "ptr", $pAppName, "wstr", $sCommand, "ptr", $pSecurity, "ptr", $pThread, _ "int", $fInherit, "dword", $iFlags, "ptr", $pEnviron, "wstr", $sDir, "ptr", $pStartupInfo, "ptr", $pProcess) hope this helps Sundance Edited May 26, 2010 by Sundance Link to comment Share on other sites More sharing options...
trancexx Posted May 26, 2010 Share Posted May 26, 2010 (edited) Call like this: DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better "handle", $hToken, _ "ptr", 0, _ ; you don't need this "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW "ptr", DllStructGetPtr($lpProcessAttributes), _ "ptr", DllStructGetPtr($lpThreadAttributes), _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", 0, _ ; you don't need this "ptr", 0, _ ; you don't need this "ptr", DllStructGetPtr($si), _ "ptr", DllStructGetPtr($pi)) Btw, you should close thread an process handles from PROCESS_INFORMATION before returning from the function. edit: and if "ptr" as type is used then it's more correct to use 0 for NULL (as opposed to ""). You should also check structures you use. Seems you are overdoing on some. As a matter of fact don't set any data to STARTUPINFO nor PROCESS_INFORMATION. They are meant to be filled by CreateProcessAsUser function. Edited May 26, 2010 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Anteaus Posted May 26, 2010 Author Share Posted May 26, 2010 (edited) $aResult = DllCall("advapi32.dll", "int", "CreateProcessAsUserW", "ptr", $hToken, "ptr", $pAppName, "wstr", $sCommand, "ptr", $pSecurity, "ptr", $pThread, _ "int", $fInherit, "dword", $iFlags, "ptr", $pEnviron, "wstr", $sDir, "ptr", $pStartupInfo, "ptr", $pProcess) Done some testing, and it seems that if you use the CreateProcessAsUserW version, then you use wstr strings. Fair enough. Other than that, the unicode version also won't work unless all parameters between $sCommand and $pStartupInfo are replaced with null ptr's. At least, I can't get it to work with the variable types listed here. Am I missing something? Probably, but question is.. what? Edited May 26, 2010 by Anteaus Link to comment Share on other sites More sharing options...
Anteaus Posted May 26, 2010 Author Share Posted May 26, 2010 Call like this: DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better "handle", $hToken, _ "ptr", 0, _ ; you don't need this "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW "ptr", DllStructGetPtr($lpProcessAttributes), _ "ptr", DllStructGetPtr($lpThreadAttributes), _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", 0, _ ; you don't need this "ptr", 0, _ ; you don't need this "ptr", DllStructGetPtr($si), _ "ptr", DllStructGetPtr($pi)) Thanks, that's much more like it. It now works with the specified data types. The final hurdle is getting it to recognise the $dwCreationFlags values, which it seems to be ignoring. About time I packed-up for the night anyway, will continue tomorrow. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now