locked
CreateProcessAsUser yields no results even though no errors are returned. RRS feed

  • Question

  • Hi,

    My system service (running as LocalSystem, on Windows 2008, June 2007 CTP) is trying to launch a client app in a user's interactive session. I followed the guidelines from MSDN, but the process fails silently. None of the API calls I invoke returns any errors, and I get a valid process and thread handles, but I don't see the application, neither on the desktop nor in the list of processes in task manager, or SysInternals' Process Explorer. The new process exists, and yet it doesn't at the same time? Has anybody got this working?

    I attach my code below. Methods AddAceToWindowStation, AddAceToDesktop, GetLogonSID,  and FreeLogonSID have been copied from these MSDN articles:

    http://msdn2.microsoft.com/en-us/library/Aa379608.aspx
    http://msdn2.microsoft.com/en-us/library/aa446670.aspx

    My code (it's managed C++, but that I suppose doesn't matter):

        void Controller::Launch(String^ _user, String^ _password, int _session, String^ _application)
        {
            Debugger::Launch();

            wchar_t *user = NULL;
            wchar_t *password = NULL;
            wchar_t *application = NULL;
            DWORD sessionid = 0;      
            HANDLE token = INVALID_HANDLE_VALUE;
            HWINSTA winstasave = NULL;
            HWINSTA winsta = NULL;
            HDESK desktop = NULL;
            PSID psid = NULL;
            DWORD processid = 0;
            STARTUPINFO startupinfo;
            PROCESS_INFORMATION processinfo;

            try
            {
                user = (wchar_t *) Marshal:: StringToHGlobalUni(_user).ToPointer();
                password = (wchar_t *) Marshal:: StringToHGlobalUni(_password).ToPointer();      
                sessionid = (DWORD) _session;
                application = (wchar_t *) Marshal:: StringToHGlobalUni(_application).ToPointer();      

                if (!LogonUser(user, L".", password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &token))
                    throw gcnew Exception("LogonUser failed");

                if (!SetTokenInformation(token, TOKEN_INFORMATION_CLASS::TokenSessionId, (PVOID) &sessionid, sizeof(sessionid)))
                    throw gcnew Exception("SetTokenInformation failed");

                winstasave = GetProcessWindowStation();
                if (winstasave == NULL)
                    throw gcnew Exception("GetProcessWindowStation failed");

                try
                {
                    winsta = OpenWindowStation(L"WinSta0", FALSE, READ_CONTROL | WRITE_DAC);
                    if (winsta == NULL)
                        throw gcnew Exception("OpenWindowStation failed");

                    if (!SetProcessWindowStation(winsta))
                        throw gcnew Exception("SetProcessWindowStation failed");

                    desktop = OpenDesktop(L"default", 0, FALSE, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);
                    if (desktop == NULL)
                        throw gcnew Exception("OpenDesktop failed");
                }
                finally
                {
                    if (!SetProcessWindowStation(winstasave))
                        throw gcnew Exception("SetProcessWindowStation failed");
                }

                if (!GetLogonSID(token, &psid))
                    throw gcnew Exception("GetLogonSID failed");

                if (!AddAceToWindowStation(winsta, psid))
                    throw gcnew Exception("AddAceToWindowStation failed");
              
                if (!AddAceToDesktop(desktop, psid))
                    throw gcnew Exception("AddAceToDesktop failed");

                if (!ImpersonateLoggedOnUser(token))
                    throw gcnew Exception("ImpersonateLoggedOnUser failed");

                try
                {
                    ZeroMemory(&startupinfo, sizeof(STARTUPINFO));
                    startupinfo.cb = sizeof(startupinfo);
                    startupinfo.lpDesktop = L"WinSta0\\default";

                    if (!CreateProcessAsUser(token, application,
                        NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, NULL, NULL, &startupinfo, &processinfo))
                    {
                        throw gcnew Exception("CreateProcessAsUser failed");
                    }
                }
                finally
                {
                    RevertToSelf();
                }

                processid = processinfo.dwProcessId;
                Log("Created(process id = " + ((int) processid).ToString() + ")");

                if (processinfo.hProcess != INVALID_HANDLE_VALUE)
                {
                    WaitForSingleObject(processinfo.hProcess, INFINITE);
                    CloseHandle(processinfo.hProcess);
                }

                if (processinfo.hThread != INVALID_HANDLE_VALUE)
                    CloseHandle(processinfo.hThread);
            }
            catch (Exception^ exc)
            {
                int error = (int) GetLastError();
                Log(exc->ToString());
                Log("GetLastError returned " + error.ToString());
            }
            finally
            {
                if (psid != NULL)
                    FreeLogonSID(&psid);

                if (winsta != NULL)
                    CloseWindowStation(winsta);

                if (desktop != NULL)
                    CloseDesktop(desktop);

                if (token != INVALID_HANDLE_VALUE)
                    CloseHandle(token);

                if (user != NULL)
                    Marshal::FreeHGlobal(IntPtr(user));      

                if (password != NULL)
                    Marshal::FreeHGlobal(IntPtr(password));

                if (application != NULL)
                    Marshal::FreeHGlobal(IntPtr(application));
            }
        }

    Krzys
    http://www.cs.cornell.edu/~krzys/

    Tuesday, August 7, 2007 9:57 PM

All replies