example code: A service calls CreateProcessAsUser() I want the process to run in the user's session, not session 0

kevinwaite picture kevinwaite · Sep 2, 2011 · Viewed 23.9k times · Source

I am seeking example code:

For a service calls CreateProcessAsUser() I want the process to run in the user's session, not session 0

thus far the created process is only running like a service in session 0

Answer

Carey Gregory picture Carey Gregory · Sep 2, 2011

This was stripped from some old code that launched a console app from a service. It worked under NT4 but I haven't tested it with a modern version of Windows so can't guarantee it will work as it did on NT4.

EDIT: No, that's not going to work as-is. You need to add the code found here to create a desktop, set the SID, etc.

    if (!LogonUser(userId,
                   domain,
                   password,
                   LOGON32_LOGON_INTERACTIVE,
                   LOGON32_PROVIDER_DEFAULT,
                   &hUserToken))
    {
        return GetLastError();
    }

    if (!ImpersonateLoggedOnUser(hUserToken))
    {
        DWORD rc = GetLastError();
        CloseHandle(hUserToken);
        return rc;
    }

    STARTUPINFO             si;
    PROCESS_INFORMATION pi;

    memset(&si, 0, sizeof(si));
    memset(&pi, 0, sizeof(pi));

    si.cb = sizeof(si);

    rc = CreateProcessAsUser(hUserToken,                // user token
                           0,                           // app name
                           "foo.exe",                   // command line
                           0,                           // process attributes
                           0,                           // thread attributes
                           FALSE,                       // don't inherit handles
                           DETACHED_PROCESS,            // flags
                           0,                           // environment block
                           0,                           // current dir
                           &si,                         // startup info
                           &pi);                        // process info gets put here


    if (!rc)
    {
        DWORD rc = GetLastError();
        RevertToSelf();
        CloseHandle(hUserToken);
        return rc;
    }

    RevertToSelf();
    CloseHandle(hUserToken);

    return 0;