locked
LsaLogonUser + CreateProcessAsUser 0xc0000142 error RRS feed

  • Question

  • Hello!

    I'm running from an interactive session (session1) with local admin user. 

    I'm trying to create a process with the combination of LogonUser API and CreateProcessAsUser/CreateProcessWithTokenW. I want that the process will be with no GUI.

    However, when executing CreateProcessAsUser I get a message box: "The application was unable to start correctly (0xc0000142)".

    After reading the blog - https://support.microsoft.com/en-ca/help/165194/createprocessasuser-windowstations-and-desktops, I added the user token to the interactive desktop, and I don't get the message box - but I am still missing some points:

    1. Why do I need to add the user token to the interactive session if It's created in the same session,desktop and window station? Does it behave differently on Win8/10? I tested it only on Win7.

    2. I'm initializing lpDesktop to NULL, so as I understand - the new process inherits the desktop and window station of it's parent process, so the child process suppose to be created at my interactive session.

    I don't want the process to be visible, so I call the function CreateProcessAsUser with CREATE_NO_WINDOW, However, the process is created with a window. WHY?

    	status = LsaLogonUser(hLSA,
    		&originName,
    		Interactive,
    		authPackage,
    		authBuffer,
    		authBufferSize,
    		0,
    		&tokenSource,
    		&profileBuffer,
    		&profileBufferSize,
    		&loginId,
    		&token,
    		&quotaLimits,
    		&subStatus);
    
    	if (status != 0)
    	{
    		NTSTATUS winError = LsaNtStatusToWinError(status);
    		wprintf(L"Logon Failed with status %x", status);
    		return -1;
    	}
    
    	HANDLE hDuplicate;
    	DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hDuplicate);
    
    	add_token_to_interactive_sesion(token);
    
    	LPVOID pEnvironment = NULL;
    	STARTUPINFO StartupInfo;
    	StartupInfo.cb = sizeof(STARTUPINFO);
    	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
    	
    	StartupInfo.lpDesktop = NULL;
    	PROCESS_INFORMATION ProcessInformation;
    	ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
    
    	void* lpEnvironment = NULL;
    	BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, hDuplicate, TRUE);
    	if (resultEnv == 0)
    	{
    		long nError = GetLastError();
    		printf("CreateEnvironmentBlock failed - %d", GetLastError());
    	}
    
    	DWORD res = CreateProcessAsUser(hDuplicate, L"C:\\TestExe.exe", NULL, NULL, NULL, TRUE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT , lpEnvironment, NULL, &StartupInfo, &ProcessInformation);
    	if (res)
    	{
    		printf("Success!");
            }

    Thank you in advance,

    Tuesday, July 11, 2017 4:40 PM

All replies

  • I suggest you give CreateProcessWithLogonW a try.  It's a lot simpler than working with LsaLogonUser to get a token.  And, in my experience, it takes care of adding the necessary permissions to the inherited desktop and window station automatically.  The link above includes sample code.

    The docs for CreateProcessAsUser state "By default, CreateProcessAsUser creates the new process on a noninteractive window station with a desktop that is not visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default interactive window station and desktop, "winsta0\default", in the lpDesktop member of the STARTUPINFO structure. In addition, before calling CreateProcessAsUser, you must change the discretionary access control list (DACL) of both the default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the user or the logon session represented by the hToken parameter."

    As far as CREATE_NO_WINDOW is concerned, that flag is only for a console application.  Is TextExe.exe a console application?


    • Edited by RLWA32 Friday, July 14, 2017 2:34 PM
    Friday, July 14, 2017 2:32 PM