Launching an app under Vista with UAP enabled
- From: "Dan Updegraff" <daniel.updegraff@xxxxxxxxxxxxxxxx>
- Date: Tue, 2 May 2006 10:07:08 -0400
Is it possible to launch an application from a print component under Windows
Vista while UAP (User Account Protection) is enabled?
We are developing a printer driver, print processor, and language monitor
for XP and Vista. Each component launches an executable at some point (e.g.
the driver launches an app for manual duplexing animations, the print
processor launches and app for previewing the job, the language monitor
launches an app for showing job status.)
The following "execute" function is used to launch an app using the active
user account's security level. It works perfectly under XP, even when Fast
User Switched to a Guest account with limited permissions. However, it
won't work under Windows Vista as long as UAP is enabled.
FYI - Input Parameters:
inCmdLine = the full path name of the app to launch
inOptions.bHideWindow = false
inOptions.bImpersonateActiveUser = true
inOptions.bWaitForStart = true
inOptions.bWaitForFinish = false
inOptions.bShowWaitCursor = false
bool execute(LPCTSTR inCmdLine, ExecuteOptions inOptions)
{
BOOL bSuccess = FALSE;
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
SECURITY_ATTRIBUTES attribs;
SECURITY_DESCRIPTOR sd;
// Init.
memset(&startupInfo, 0, sizeof(startupInfo));
memset(&processInfo, 0, sizeof(processInfo));
memset(&attribs, 0, sizeof(attribs));
memset(&sd, 0, sizeof(sd));
startupInfo.cb = sizeof(startupInfo);
if (inOptions.bHideWindow)
{
startupInfo.dwFlags = STARTF_USESHOWWINDOW;
startupInfo.wShowWindow = SW_HIDE;
}
// Need a security descriptor with a NULL DACL to allow launching
// applications without running into security problems.
attribs.nLength = sizeof(SECURITY_ATTRIBUTES);
attribs.lpSecurityDescriptor = &sd;
attribs.bInheritHandle = FALSE;
if (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
// Add a NULL DACL to the security descriptor.
if (SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
{
// Execute the supplied command line either normally, or
// while impersonating the active user.
if (inOptions.bImpersonateActiveUser)
{
// Impersonate active user, then execute the command line.
SECURITY_IMPERSONATION_LEVEL impersonationLevel =
SecurityImpersonation;
HANDLE hThreadToken = 0;
HANDLE hToken = 0;
BOOL bTmp = ImpersonateSelf(impersonationLevel);
bSuccess = OpenThreadToken(
GetCurrentThread(), // ThreadHandle
TOKEN_ALL_ACCESS, // DesiredAccess
TRUE, // OpenAsSelf
&hThreadToken); // TokenHandle
bTmp = RevertToSelf();
if (bSuccess)
bSuccess = DuplicateTokenEx(
hThreadToken, // hExistingToken
MAXIMUM_ALLOWED, // dwDesiredAccess
&attribs, // lpTokenAttributes
impersonationLevel, //
ImpersonationLevel
TokenPrimary, // TokenType
&hToken); // phNewToken
if (hThreadToken)
CloseHandle(hThreadToken);
if (bSuccess)
bSuccess = CreateProcessAsUser(
hToken, // hToken
0, // lpApplicationName
(LPTSTR) inCmdLine, // lpCommandLine
&attribs, //
lpProcessAttributes
&attribs, //
lpThreadAttributes
FALSE, // bInheritHandles
DETACHED_PROCESS, // dwCreationFlags
0, // lpEnvironment
0, //
lpCurrentDirectory
&startupInfo, // lpStartupInfo
&processInfo); //
lpProcessInformation
if (hToken)
CloseHandle(hToken);
}
else
{
// Execute the command line without any impersonation.
bSuccess = CreateProcess(
0, // lpApplicationName
(LPTSTR) inCmdLine, // lpCommandLine
&attribs, //
lpProcessAttributes
&attribs, //
lpThreadAttributes
FALSE, // bInheritHandles
DETACHED_PROCESS, // dwCreationFlags
0, // lpEnvironment
0, //
lpCurrentDirectory
&startupInfo, // lpStartupInfo
&processInfo); //
lpProcessInformation
}
// If necessary, wait for the process to start/finish.
if (inOptions.bWaitForStart || inOptions.bWaitForFinish)
{
HCURSOR hWaitCursor = ::LoadCursor(NULL,
MAKEINTRESOURCE(IDC_WAIT));
HCURSOR hOldCursor = 0;
if (inOptions.bShowWaitCursor)
hOldCursor = SetCursor(hWaitCursor);
// Wait for the process to start running.
DWORD result = WaitForInputIdle(processInfo.hProcess,
30000);
if (result == WAIT_FAILED)
Sleep(100); // If WaitForInputIdle() fails, this sleep
gives the app a chance to launch.
else if (result == 0 && inOptions.bWaitForFinish)
{
// Wait for the process to terminate.
DWORD exitCode = 0;
MSG msg;
while (GetExitCodeThread(processInfo.hThread, &exitCode)
&& exitCode == STILL_ACTIVE)
{
if (inOptions.bShowWaitCursor)
SetCursor(hWaitCursor); // Restores the wait
cursor.
Sleep(500);
// Pump Window's messages while we wait.
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
if (inOptions.bShowWaitCursor)
SetCursor(hOldCursor);
}
}
}
// Clean up.
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
return (bSuccess ? true : false);
} // execute
Regards,
Dan
.
- Prev by Date: Re: access to port 0x2e
- Next by Date: FindWindow() problem under Windows Vista
- Previous by thread: Re: LTO3 support in XP PRO for using ntbackup?
- Next by thread: Re: Launching an app under Vista with UAP enabled
- Index(es):
Relevant Pages
|