Maiken Roskilde Maiken Roskilde - 6 months ago 74
Vb.net Question

Launching an elevated process using a windows service

I'm trying to run a software update from a Windows Service. My service runs under LocalSystem.

I think all works fine up to the

CreateProcessAsUser
line which fails with API error 3 (
ERR_FILE_NOT_FOUND
).

I'm unsure how to go on debugging my code. I used ProcMon to see if it really can't find the path, but it does, so I think I might have missed something else.

Does anybody see a possible mistake?

I am using
WTSEnumerateSessions
to get the active session. For some reason, its
MachineName
member is empty, but the
SessionID
is not 0, so I guess that is still ok.

Public Function StartAppInSessionAsAdmin(ByVal uSessionID As String, ByVal uWinstationNameStrPtr As Long, ByVal uAppName As String) As Integer

'get SessionID token
Dim hToken&
Dim bRet As Boolean
bRet = WTSQueryUserToken(uSessionID, hToken)
WriteLog "wtsqueryusertoken: " & bRet & ", htoken: " & hToken

'we need to get the TokenLinked Token
Dim TLT As TOKEN_LINKED_TOKEN
Dim TLTSize&
TLTSize = Len(TLT.LinkedToken)

Dim hLinkedToken&
Dim iRetSize&
bRet = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, hLinkedToken, TLTSize, iRetSize)
WriteLog "gettokeninformation: " & bRet & " linkedtoken: " & TOKEN_INFORMATION_CLASS.TokenLinkedToken & " linked2: " & hLinkedToken

'Use CreateEnvironment Block with the original token to create an environment for the new program with the USER Environment
Dim lpEB&
bRet = CreateEnvironmentBlock(lpEB, hToken, False)
WriteLog "Createenvblock: " & bRet

If bRet Then

Dim pi As PROCESS_INFORMATION
Dim si As STARTUPINFO
si.lpDesktop = uWinstationNameStrPtr ' '”Winsta0\default”
si.cb = Len(si)

Dim lRet&
lRet = CreateProcessAsUser( _
hLinkedToken, _
"", _
uAppName, _
0&, _
0&, _
0&, _
NORMAL_PRIORITY_CLASS, _
0&, _
0&, _
si, _
pi)

'Give user a feedback
If lRet <> 0 Then
WriteLog ":-) createprocessasuser succeeded!"
Else
WriteLog ":-( failed createprocessasuser! error: " & Err.LastDllError
End If
End If

WriteLog "pstartappinsessions}"

End Function

Answer

ERROR_FILE_NOT_FOUND strongly suggests that the executable cannot be found. In other words, the problem is with lpApplicationName or lpCommandLine. From the documentation:

The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin; otherwise, the file name is ambiguous. [...] If the file name does not contain an extension, .exe is appended.

If lpApplicationName is null, then lpCommandLine must start with the program you want to run. If the path to the program contains a space, then the path must be enclosed in quotes.

If lpApplicationName is null, then you can test whether lpCommandLine is valid by pasting its value into a command prompt.