[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

App started in a new session via CreateProcessAsUser never shows u

krzys

8/7/2007 9:48:00 PM

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/Aa3...
http://msdn2.microsoft.com/en-us/library/aa4...

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));
}
}