Error 87 with CreateProcessWithLogonW in Windows Vista (VB6)

I have a function that starts a process as another user using the API function CreateProcessWithLogonW, as I saw in http://support.microsoft.com/kb/285879.

- This function works in Windows 2000 and XP.
- It fails with the error 87 when I run it in Windows Vista.

The user that calls the CreateProcessWithLogonW functions is a local administrator and the user that will run the process is a domain administrator. I tried also to run it as local administrator and failed with the same error (87).

Any idea?

(Visual Basic 6)
Private Const CREATE_DEFAULT_ERROR_MODE     As Long = 4000000
 
Private Const NORMAL_PRIORITY_CLASS         As Long = &H20&
Private Const INFINITE                      As Long = -1&
 
Private Const LOGON_WITH_PROFILE            As Long = 1
Private Const LOGON_NETCREDENTIALS_ONLY     As Long = 2
 
Private Const LOGON32_LOGON_INTERACTIVE     As Long = 2
Private Const LOGON32_PROVIDER_DEFAULT      As Long = 0
 
 
Private Type STARTUPINFO
  cb                            As Long
  lpReserved                    As Long     ' !!! must be Long for Unicode string
  lpDesktop                     As Long     ' !!! must be Long for Unicode string
  lpTitle                       As Long     ' !!! must be Long for Unicode string
  dwX                           As Long
  dwY                           As Long
  dwXSize                       As Long
  dwYSize                       As Long
  dwXCountChars                 As Long
  dwYCountChars                 As Long
  dwFillAttribute               As Long
  dwFlags                       As Long
  wShowWindow                   As Integer
  cbReserved2                   As Integer
  lpReserved2                   As Long
  hStdInput                     As Long
  hStdOutput                    As Long
  hStdError                     As Long
End Type
Private Type PROCESS_INFORMATION
  hProcess                      As Long
  hThread                       As Long
  dwProcessID                   As Long
  dwThreadID                    As Long
End Type
 
 
' CreateProcessWithLogonW API is available only on Windows 2000 and later.
Private Declare Function CreateProcessWithLogonW Lib "advapi32.dll" _
                         ( _
                          ByVal lpUsername As String, _
                          ByVal lpDomain As String, _
                          ByVal lpPassword As String, _
                          ByVal dwLogonFlags As Long, _
                          ByVal lpApplicationName As Long, _
                          ByVal lpCommandLine As String, _
                          ByVal dwCreationFlags As Long, _
                          ByVal lpEnvironment As Long, _
                          ByVal lpCurrentDirectory As String, _
                          ByRef lpStartupInfo As STARTUPINFO, _
                          ByRef lpProcessInformation As PROCESS_INFORMATION _
                         ) As Long
Private Declare Function CloseHandle Lib "kernel32" _
                         ( _
                          ByVal hObject As Long _
                         ) As Long
 
 
 
Private Sub Test()
  Dim strUserName             As String
  Dim strPassword             As String
  Dim strDomainName           As String
  Dim strCommandLine          As String
  Dim strCurrentDirectory     As String
 
  Dim lngReturn               As Long
  Dim start                   As STARTUPINFO
  Dim proc                    As PROCESS_INFORMATION
  Dim strUnicodeUser          As String
  Dim strUnicodeDomain        As String
  Dim strUnicodePassword      As String
  Dim strUnicodeCommandLine   As String
  Dim strUnicodeCurrentDir    As String
 
  strUserName = "Administrator"
  strDomainName = "MYDOMAIN"
  strPassword = "password"
  strCommandLine = "c:\test2.exe"
  strCurrentDirectory = "c:\"
 
  start.cb = Len(start)
 
  strUnicodeUser = StrConv(strUserName + Chr$(0), vbUnicode)
  strUnicodeDomain = StrConv(strDomainName + Chr$(0), vbUnicode)
  strUnicodePassword = StrConv(strPassword + Chr$(0), vbUnicode)
  strUnicodeCommandLine = StrConv(strCommandLine + Chr$(0), vbUnicode)
  strUnicodeCurrentDir = StrConv(strCurrentDirectory + Chr$(0), vbUnicode)
 
  lngReturn = CreateProcessWithLogonW(strUnicodeUser, strUnicodeDomain, strUnicodePassword, _
                                      LOGON_WITH_PROFILE, 0&, strUnicodeCommandLine, _
                                      CREATE_DEFAULT_ERROR_MODE, 0&, strUnicodeCurrentDir, start, proc)
 
  If lngReturn <> 0 Then
    CloseHandle proc.hThread
    CloseHandle proc.hProcess
  Else
    lngReturn = Err.LastDllError
    MsgBox "ERROR " & CStr(lngReturn) & ": CreateProcessWithLogonW"
  End If
End Sub

Open in new window

LVL 1
gllanderasAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

danaseamanCommented:
Declare CreateProcessWithLogonW as is would work in in TLB. Since it is declared local you should change All String Params to Long and use StrPtr(sMyString) when calling.

Missing Const CREATE_UNICODE_ENVIRONMENT

Revised code returns error 1326 (Logon failure: unknown user name or bad password. )
You will need to try this on your system with correct Username and Password.


Option Explicit
 
Private Const LOGON_WITH_PROFILE = &H1&
Private Const LOGON_NETCREDENTIALS_ONLY = &H2&
Private Const CREATE_DEFAULT_ERROR_MODE = &H4000000
Private Const CREATE_NEW_CONSOLE = &H10&
Private Const CREATE_NEW_PROCESS_GROUP = &H200&
Private Const CREATE_SEPARATE_WOW_VDM = &H800&
Private Const CREATE_SUSPENDED = &H4&
Private Const CREATE_UNICODE_ENVIRONMENT = &H400&
 
Private Const ABOVE_NORMAL_PRIORITY_CLASS = &H8000&
Private Const BELOW_NORMAL_PRIORITY_CLASS = &H4000&
Private Const HIGH_PRIORITY_CLASS = &H80&
Private Const IDLE_PRIORITY_CLASS = &H40&
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const REALTIME_PRIORITY_CLASS = &H100&
 
Private Const INFINITE                      As Long = -1&
 
Private Const LOGON32_LOGON_INTERACTIVE     As Long = 2
Private Const LOGON32_PROVIDER_DEFAULT      As Long = 0
 
 
Private Type STARTUPINFO
  cb                            As Long
  lpReserved                    As Long     ' !!! must be Long for Unicode string
  lpDesktop                     As Long     ' !!! must be Long for Unicode string
  lpTitle                       As Long     ' !!! must be Long for Unicode string
  dwX                           As Long
  dwY                           As Long
  dwXSize                       As Long
  dwYSize                       As Long
  dwXCountChars                 As Long
  dwYCountChars                 As Long
  dwFillAttribute               As Long
  dwFlags                       As Long
  wShowWindow                   As Integer
  cbReserved2                   As Integer
  lpReserved2                   As Long
  hStdInput                     As Long
  hStdOutput                    As Long
  hStdError                     As Long
End Type
Private Type PROCESS_INFORMATION
  hProcess                      As Long
  hThread                       As Long
  dwProcessID                   As Long
  dwThreadID                    As Long
End Type
 
 
' CreateProcessWithLogonW API is available only on Windows 2000 and later.
Private Declare Function CreateProcessWithLogonW Lib "Advapi32" (ByVal lpUsername As Long, ByVal lpDomain As Long, ByVal lpPassword As Long, ByVal dwLogonFlags As Long, ByVal lpApplicationName As Long, ByVal lpCommandLine As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, lpProcessInfo As PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
 
 
 
Private Sub Test()
  Dim strUserName             As String
  Dim strPassword             As String
  Dim strDomainName           As String
  Dim strCommandLine          As String
  Dim strCurrentDirectory     As String
 
  Dim lngReturn               As Long
  Dim start                   As STARTUPINFO
  Dim proc                    As PROCESS_INFORMATION
  'Dim strUnicodeUser          As String
  'Dim strUnicodeDomain        As String
  'Dim strUnicodePassword      As String
  'Dim strUnicodeCommandLine   As String
  'Dim strUnicodeCurrentDir    As String
 
  strUserName = "Administrator"
  strDomainName = "MYDOMAIN"
  strPassword = "password"
  strCommandLine = "c:\test2.exe"
  strCurrentDirectory = "c:\"
 
  start.cb = LenB(start)
 
  'strUnicodeUser = StrConv(strUserName + Chr$(0), vbUnicode)
  'strUnicodeDomain = StrConv(strDomainName + Chr$(0), vbUnicode)
  'strUnicodePassword = StrConv(strPassword + Chr$(0), vbUnicode)
  'strUnicodeCommandLine = StrConv(strCommandLine + Chr$(0), vbUnicode)
  'strUnicodeCurrentDir = StrConv(strCurrentDirectory + Chr$(0), vbUnicode)
 
  'lngReturn = CreateProcessWithLogonW(StrPtr(strUserName), StrPtr(strDomainName), StrPtr(strPassword), _
                                      LOGON_WITH_PROFILE, 0&, StrPtr(strCommandLine), _
                                      CREATE_DEFAULT_ERROR_MODE, 0&, StrPtr(strCurrentDirectory), start, proc)
 
lngReturn = CreateProcessWithLogonW(StrPtr(strUserName), StrPtr(strDomainName), StrPtr(strPassword), LOGON_WITH_PROFILE, StrPtr(strCommandLine), StrPtr(strCommandLine), CREATE_UNICODE_ENVIRONMENT & CREATE_NEW_CONSOLE Or CREATE_NEW_PROCESS_GROUP, ByVal 0&, StrPtr(strCurrentDirectory), start, proc)
 
  If lngReturn <> 0 Then
    CloseHandle proc.hThread
    CloseHandle proc.hProcess
  Else
    Debug.Print "Error " & Err.Number & vbCrLf & Err.Description
    lngReturn = Err.LastDllError
    MsgBox "ERROR " & CStr(lngReturn) & ": CreateProcessWithLogonW"
  End If
End Sub
 
Private Sub Command1_Click()
   Call Test
End Sub

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
danaseamanCommented:
BTW. Revised code was run on Vista Ultimate.
0
gllanderasAuthor Commented:
Yes, the code that you posted works perfectly.
Thank you very much. :-)
0
gllanderasAuthor Commented:
Perfect.
It runs on a Vista Business and on a Windows Server 2003.
Thanks, danaseaman.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.