Maiken Roskilde
Maiken Roskilde

Reputation: 467

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

Upvotes: 2

Views: 248

Answers (1)

theB
theB

Reputation: 6738

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.

Upvotes: 4

Related Questions