dllcall in compiled script failing

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
jrtolle
Posts: 7
Joined: 21 Oct 2015, 08:54

dllcall in compiled script failing

29 Sep 2016, 23:05

When the script this function is a part of is compiled, the DllCall for CreateProcessWithLogonW fails with 0xc0000005 access violation error. Runs fine as a script. I have tried various permutations of parameter types for pointers, but not sure why it is failing when compiled. I have looked through these boards, the old boards, and with Google, and cannot figure out what I am missing. I feel like it is something simple, but I just started messing around with DllCall this week and I am a scripter by trade, not a programmer, so diving in the MSDN pages has been enlightening...

Code: Select all

RunAsNetOnly(lpUsername,lpDomain,lpPassword,lpCommandLine,lpCurrentDirectory="%windir%",wShowWindow=0)
{
	;DO NOT DEFINE INVALID DIRECTORY NAME OR ENVIRONMENT VARIABLE FOR lpCurrentDirectory
	;WILL CAUSE failure and A_LastError to be non-zero (likely 123 or 267)
	IfInString, lpUsername, \
	{
		unArray := StrSplit(lpUsername,"\")
		lpUsername := unArray[2]
		lpDomain := unArray[1]
	}
	RegexMatch(lpCurrentDirectory,"O)(%.*?%)",Match)
	Needle := Match.Value(1)
	If (Needle <> "")
	{
		StringReplace, EnvVar, Needle, `%,, All ;%;end variable color in npp
		EnvGet, EnvVar2, %EnvVar%
		StringReplace, lpCurrentDirectory, lpCurrentDirectory, %Needle%, %EnvVar2%
	}
	;ahk tutorial on structures - http://maul-esel.github.io/ahkbook/en/Structures.html
	;stdOutToVar modified from from https://autohotkey.com/board/topic/96903-simplified-versions-of-seans-stdouttovar/
	;4 (bytes) used for DWORD arguments, A_PtrSize used for all other ptr arguments
	;https://msdn.microsoft.com/en-us/library/windows/desktop/aa365152(v=vs.85).aspx
	DllCall("CreatePipe", "UIntP", hPipeRead, "UIntP", hPipeWrite, "UInt", 0, "UInt", 0)
	;https://msdn.microsoft.com/en-us/library/windows/desktop/ms724935(v=vs.85).aspx
	DllCall("SetHandleInformation", "UIntP", hPipeWrite, "UInt", 1, "UInt", 1)
	;Process_Information STRUCT - https://msdn.microsoft.com/en-us/library/ms684873(v=vs.85).aspx
	piSize := 4+4+(2*A_PtrSize)
	VarSetCapacity(lpProcessInfo,piSize)
	;StartupInfo STRUCT - https://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx
	siSize := (9*4)+(9*A_PtrSize)
	VarSetCapacity(lpStartupInfo,siSize)
	NumPut(siSize,lpStartupInfo,0,"UInt")
	dwFlagsOffset := (9*4)+(3*A_PtrSize)
	;to set the next flag active and activate std handles
	NumPut(0x00000101,lpStartupInfo,dwFlagsOffset,"UInt")
	wShowWindowOffset := dwFlagsOffset + 4
	;1=normal window, 0=hide window - https://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx
	NumPut(wShowWindow,lpStartupInfo,wShowWindowOffset,"UInt")
	hStdOutputOffset := wShowWindowOffset + (3*A_PtrSize)
	NumPut(hPipeWrite,lpStartupInfo,hStdOutputOffset)
	hStdErrorOffset := hStdOutputOffset + A_PtrSize
	NumPut(hPipeWrite,lpStartupInfo,hStdErrorOffset)
	;https://msdn.microsoft.com/en-us/library/windows/desktop/ms682431(v=vs.85).aspx
	Result := DllCall("advapi32\CreateProcessWithLogonW"
		,"Str", lpUsername
		,"Str", lpDomain
		,"Str", lpPassword
		,"UInt", 2 ;dwLogonFlags
		,"Ptr", 0 ;lpApplicationName
		,"Str", lpCommandLine
		,"UInt", 0 ;dwCreationFlags
		,"Ptr", 0 ;lpEnvironment
		,"Str", lpCurrentDirectory
		,"UPtr", &lpStartupInfo
		,"UPtr", &lpProcessInfo
	,"UInt")
	createProcessErrorLevel := ErrorLevel
	hProcess := NumGet(lpProcessInfo,0,"UInt")
	hThreadOffset := 0+A_PtrSize
	hThread := NumGet(lpProcessInfo,hThreadOffset,"UInt")
	dwProcessIdOffset := hThreadOffset+A_PtrSize
	dwProcessId := NumGet(lpProcessInfo,dwProcessIdOffset,"UInt")
	dwThreadIdOffset := dwProcessId+4
	dwThreadId := NumGet(lpProcessInfo,dwThreadIdOffset,"UInt")
	If (dwProcessId = 0)
	{
		If (A_LastError = 2)
			msgReturn := "System Error Code: 2`nFile Does Not Exist"
		Else If (A_LastError = 123)
			msgReturn := "System Error Code: 123`nThe filename, directory name, or volume label syntax is incorrect."
		Else If (A_LastError = 267)
			msgReturn := "System Error Code: 267`nPath Does Not Exist"
		Else If (A_LastError = -1073741819)
			msgReturn := "Error Number: 0xc0000005`nAccess Violation"
		Else
			msgReturn := "System Error Code:" . A_LastError
	}
	Else
	{
		Process, WaitClose, dwProcessId, 10
		DllCall("CloseHandle","Ptr",hPipeWrite)
		If (createProcessErrorLevel = 0)
		{
			;grab stdOut
			;stdOutToVar modified from from https://autohotkey.com/board/topic/96903-simplified-versions-of-seans-stdouttovar/
			stdOutput := "", bytesRead := 0
			AIC := (SubStr(A_AhkVersion,1,3) = "1.0")
			VarSetCapacity(Buffer,4096,0)
			While DllCall("ReadFile", "UInt", hPipeRead, "Ptr", &Buffer, "UInt", 4094, "UIntP", bytesRead, "Ptr", 0, "UInt")
				stdOutput .= (AIC && NumPut(0,Buffer,bytesRead,"UChar") && VarSetCapacity(Buffer,-1)) ? Buffer : StrGet(&Buffer,bytesRead,"CP850") ;maybe ? change CP850 to UTF-8 or UTF-16
		}
		Else
		{
			;end process that was started
			Process, Exist, %dwProcessId%
			ProcessEL := ErrorLevel
			If (ProcessEL <> 0)
				RunWait, %comspec% /c taskkill.exe /f /pid %dwProcessId%,, Hide, UseErrorLevel
			}
		}
	}
	;clean-up
	DllCall("CloseHandle","Ptr",hProcess)
	DllCall("CloseHandle","Ptr",hThread)
	DllCall("CloseHandle","Ptr",hPipeRead)
	VarSetCapacity(lpProcessInfo,0)
	VarSetCapacity(lpStartupInfo,0)
	returnObj := {}
	returnObj.msgReturn := msgReturn
	returnObj.stdOutput := stdOutput
	Return returnObj
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], haomingchen1998, mcd, Peiya, ShatterCoder and 93 guests