Проблема с параметрами в CreateProcessAsUser - PullRequest
0 голосов
/ 24 марта 2011

Мне было поручено создать службу Windows, способную запускать процесс для текущего интерактивного пользователя, используя VB.NET 2005.

После некоторых исследований я создал следующий код:

Dim hToken As IntPtr = IntPtr.Zero
Dim LastW32Error As Integer

If WTSQueryUserToken(WTSGetActiveConsoleSessionId(), hToken) Then
        Dim hTokenDup As IntPtr = IntPtr.Zero
        If DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, Nothing, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, hTokenDup) Then
            Dim hEnv As IntPtr = IntPtr.Zero
            If CreateEnvironmentBlock(hEnv, hTokenDup, False) Then
                Dim strCommandLine As String = "c:\\windows\\system32\\NotePad.exe"
                Dim saProcessAttributes As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES
                Dim saThreadAttributes As SECURITY_ATTRIBUTES = New SECURITY_ATTRIBUTES
                Dim pi As New PROCESS_INFORMATION
                Dim si As New STARTUPINFO

                saProcessAttributes.nLength = Convert.ToUInt32(Marshal.SizeOf(saProcessAttributes))
                saThreadAttributes.nLength = Convert.ToUInt32(Marshal.SizeOf(saThreadAttributes))
                si.cb = Convert.ToUInt32(Marshal.SizeOf(si))

                If Not CreateProcessAsUser(hTokenDup, Nothing, strCommandLine, saProcessAttributes, saThreadAttributes, False, 0, hEnv, Nothing, si, pi) Then
                    LastW32Error = Marshal.GetLastWin32Error()
                    EvtLog.WriteEntry("CreateProcessAsUser: " + CStr(LastW32Error))
                End If
            Else
                LastW32Error = Marshal.GetLastWin32Error()
                EvtLog.WriteEntry("CreateEnvironmentBlock: " + CStr(LastW32Error))
            End If
            DestroyEnvironmentBlock(hEnv)
        Else
            LastW32Error = Marshal.GetLastWin32Error()
            EvtLog.WriteEntry("DuplicateTokenEx: " + CStr(LastW32Error))
        End If
        CloseHandle(hTokenDup)
Else
    LastW32Error = Marshal.GetLastWin32Error()
    EvtLog.WriteEntry("WTSQueryUserToken: " + CStr(LastW32Error))
End If

CloseHandle(hToken)

Но я получаю ошибку 87 (ERROR_INVALID_PARAMETER) при вызове CreateProcessAsUser.Кто-нибудь может указать мне, что я делаю неправильно?

Код реализован в виде службы Windows, которая работает под учетной записью LocalSystem.

1 Ответ

3 голосов
/ 10 апреля 2012
  • WTSQueryUserToken может вызываться только в LocalSystem
  • WTSQueryUserToken возвращает PrimaryToken. Не нужно дублировать его.
  • Этот токен уже имеет правильный sessionID и среду (он получен из текущего вошедшего в систему пользователя), поэтому нет необходимости создавать блок среды
...