Search code examples
c++cwinapiwin32-process

CreateProcessAsUser from c++ service creates process but no console


I am developing C++ service which uses CreateProcessAsUser function. I have tested this on Windows 7 and it was working excellent. But i am testing now my code for windows 10 and it doesnt want to work but process is created and visible in task manager, just no windows/console created. I am trying now code snippet with cmd only without any parameters I will really appreciate any kind of help

I can see this with task manager, so my process is created. task manager

    PROCESS_INFORMATION pi;
   STARTUPINFO si;
   BOOL bResult = FALSE;
   DWORD dwSessionId;
   HANDLE hUserToken;
    // Log the client on to the local computer.
   dwSessionId = WTSGetActiveConsoleSessionId();    
   WTSQueryUserToken(dwSessionId,&hUserToken);
   ZeroMemory(&si, sizeof(STARTUPINFO));
   si.cb= sizeof(STARTUPINFO);
   si.lpDesktop = L"winsta0\\default";
   ZeroMemory(&pi, sizeof(pi));    
   LPVOID pEnv =NULL;    
   if(CreateEnvironmentBlock(&pEnv,hUserToken,TRUE)){
   }
   else
      pEnv=NULL;    
   bResult = CreateProcessAsUser(
      hUserToken,                     // client's access token
      L"C:\\Windows\\System32\\cmd.exe",    // file to execute
      L"",                 // command line
      NULL,            // pointer to process SECURITY_ATTRIBUTES
      NULL,               // pointer to thread SECURITY_ATTRIBUTES
      FALSE,              // handles are not inheritable
      CREATE_UNICODE_ENVIRONMENT|HIGH_PRIORITY_CLASS,     // creation flags
      pEnv,               // pointer to new environment block
      NULL,               // name of current directory
      &si,               // pointer to STARTUPINFO structure
      &pi                // receives information about new process
   );    
   //Perform All the Close Handles tasks  
   DestroyEnvironmentBlock(pEnv);
   CloseHandle(pi.hThread);
   CloseHandle(pi.hProcess);
   CloseHandle(hUserToken);

Solution

  • #define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT}
    
    #define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{
    #define END_PRIVILEGES }};
    
    ULONG adjustPrivileges()
    {
        HANDLE hToken;
    
        ULONG err;
        if (OpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
        {
            BEGIN_PRIVILEGES(tp, 2)
                LAA(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE),
                LAA(SE_INCREASE_QUOTA_PRIVILEGE),
            END_PRIVILEGES  
    
            AdjustTokenPrivileges(hToken, FALSE, (::PTOKEN_PRIVILEGES)&tp, 0, 0, 0);
    
            err = GetLastError();
    
            CloseHandle(hToken);
        }
        else
        {
            err = GetLastError();
        }
    
        return err;
    }
    
    ULONG cup()
    {
        HANDLE hUserToken;
    
        DWORD dwSessionId = WTSGetActiveConsoleSessionId();
    
        if (dwSessionId == MAXDWORD)
        {
            return ERROR_GEN_FAILURE;
        }
    
        ULONG err = adjustPrivileges();
    
        if (err)
        {
            return err;
        }
    
        if (WTSQueryUserToken(dwSessionId,&hUserToken))
        {
            PVOID pEnv;
    
            if (CreateEnvironmentBlock(&pEnv,hUserToken,TRUE))
            {
                PROCESS_INFORMATION pi;
                STARTUPINFO si = { sizeof(STARTUPINFO) };
                si.lpDesktop = L"winsta0\\default";
    
                if (CreateProcessAsUser(
                    hUserToken,                     // client's access token
                    L"C:\\Windows\\System32\\cmd.exe",    // file to execute
                    NULL,                 // command line
                    NULL,            // pointer to process SECURITY_ATTRIBUTES
                    NULL,               // pointer to thread SECURITY_ATTRIBUTES
                    FALSE,              // handles are not inheritable
                    CREATE_UNICODE_ENVIRONMENT|HIGH_PRIORITY_CLASS,  // creation flags
                    pEnv,               // pointer to new environment block
                    NULL,               // name of current directory
                    &si,               // pointer to STARTUPINFO structure
                    &pi                // receives information about new process
                    ))
                {
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);
                }
                else
                {
                    err = GetLastError();
                }
    
                DestroyEnvironmentBlock(pEnv);
    
            }
            else
            {
                err = GetLastError();
            }
            CloseHandle(hUserToken);
        }
        else
        {
            err = GetLastError();
        }
        return err;
    }