The application was unable to start correctly 0xc0000142 CreateProcessWithLogonW

5

I have a block of of code

if(!CreateProcessWithLogonW(
    szUserName,
    NULL,
    szPassword,
    LOGON_WITH_PROFILE,
    L"C:\\Windows\\System32\\cmd.exe", // file to execute
    NULL,              
    NORMAL_PRIORITY_CLASS | CREATE_BREAKAWAY_FROM_JOB,   // creation flags
    NULL,              // pointer to new environment block 
    NULL,              // name of current directory 
    &si,               // pointer to STARTUPINFO structure
    &pi                // receives information about new process
    )){
        ReportError(L"Create Process");
    }

ReportError is not invoked, but csrss.exe pops up with Startup error

What am I doing wrong?!

The username and password ARE correct.

the whole file:

// cmd.cpp : Defines the entry point for the console application.
//

#include <Windows.h>
#include <Lmcons.h>
#include <iostream>
#include <ctype.h>
#include <string>
#include <stdio.h>

#define winstring LPWSTR
#define stcas(x) static_cast<x>
#define INFO_BUFFER_SIZE    260 

using namespace std;

void ReportError(LPCWSTR pszFunction, DWORD dwError = GetLastError()) 
{ 
    wprintf(L"%s failed w/err 0x%08lx\n", pszFunction, dwError); 
} 

int main()
{
    TCHAR un[UNLEN+1];
    DWORD size = UNLEN + 1;
    GetUserName(un, &size);

    string una(un);

    bool sys = !una.compare("SYSTEM");

    /*
    if(!sys) {
        system("cls");
        system("title Command Prompt");
        system("cmd");
        return 0;
    }
    */


    wchar_t szUserName[INFO_BUFFER_SIZE] = {}; 
    wchar_t szPassword[INFO_BUFFER_SIZE] = {}; 
    wchar_t *pc = NULL; 
    HANDLE hToken = NULL; 
    BOOL fSucceeded = FALSE; 
    BOOL logon = FALSE;


    printf("Enter the username: "); 
    fgetws(szUserName, ARRAYSIZE(szUserName), stdin); 
    pc = wcschr(szUserName, '\n'); 
    if (pc != NULL) *pc = '\0';  // Remove the trailing L'\n' 

    cout << endl;
    //string un(szUserName);

    printf("Enter the password: "); 
    fgetws(szPassword, ARRAYSIZE(szPassword), stdin); 
    pc = wcschr(szPassword, '\n'); 
    if (pc != NULL) *pc = '\0';  // Remove the trailing L'\n'



    if (!LogonUserW(szUserName, NULL, szPassword,  LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken)) 
    {
        ReportError(L"Logon");
        goto Cleanup; 
    } 
    else logon = true;

    HANDLE phToken = NULL;

    BOOL dup = FALSE;

    if(!DuplicateTokenEx(hToken, TOKEN_DUPLICATE|TOKEN_IMPERSONATE|TOKEN_QUERY, NULL, SecurityImpersonation, TokenPrimary, &phToken)){
        ReportError(L"DUPLICATE TOKEN");
    }

    else dup = TRUE;

    // Impersonate the logged on user. 
    if (!ImpersonateLoggedOnUser(phToken)) 
    { 

        ReportError(L"imp");
        goto Cleanup; 
    } 

    fSucceeded = true;

    Cleanup: 

    // Clean up the buffer containing sensitive password. 


    LPTSTR szCmdline[] = {"cmd"};
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;

    TCHAR uni[UNLEN+1];
    DWORD sizei = UNLEN + 1;
    GetUserName(uni, &sizei);

    string unai(uni);
    cout << unai << endl;

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);



    system("pause");

    // If the impersonation was successful, undo the impersonation. 
    if (fSucceeded && logon) 
    { 
        system("cls");
        system("title Command Prompt");
        //system("cmd");

        if(!CreateProcessWithLogonW(
        szUserName,
        NULL,
        szPassword,
        LOGON_WITH_PROFILE,
        L"cmd.exe", // file to exec
        NULL,              
        NORMAL_PRIORITY_CLASS | CREATE_BREAKAWAY_FROM_JOB,   // creation flags
        NULL,              // pointer to new environment block 
        NULL,              // name of current directory 
        &si,               // pointer to STARTUPINFO structure
        &pi                // receives information about new process
        )){
            ReportError(L"Create Process");
        }
        if (!RevertToSelf()) 
        {  
            ReportError(L"Undo Imp");
        } 

    }
    SecureZeroMemory(szPassword, sizeof(szPassword));
    system("pause");
}
c++
winapi
startup-error
asked on Stack Overflow Mar 23, 2014 by nimsson • edited Mar 25, 2014 by nimsson

1 Answer

4

The code you posted works for me if I skip the calls to LogonUser, DuplicateToken and ImpersonateLoggedOnUser. You don't want to impersonate another user in order to call CreateProcessWithLogon since it basically does that for you, so just remove all that logic to do the impersonation.

Impersonating a user could also cause your program to be unable to launch an application at all if the target application requires a higher level of privilege than the user has.

answered on Stack Overflow Mar 25, 2014 by Carey Gregory

User contributions licensed under CC BY-SA 3.0