views:

529

answers:

1

I'm using CreateDesktop() to create a temporary desktop where an application will run, perform a cleanup action (while remaining out of the way) and terminate. I'm closing that desktop once the application is gone. Everything is fine when using Windows XP and even Vista. The problem arises when you enable the (annoying) UAC.

Everything is OK when you create a desktop, but when you call CreateProcess() to open a program on that desktop it causes the opened application to crash with an exception on User32.dll.

I've been reading a lot about the different desktops and layers on Windows and the restrictions of memory. However, most of the programs I open (as test scenarios) are OK, but a few (like IE, Notepad, Calc and my own application) cause the crash.

Anyone has any idea why this happen on Vista with UAC, or more specifically for those specific programs? and how to fix this?

Anyone has a good solid example on how to create a desktop and open an application there without switching to it under Vista with UAC on?

Code is appreciated.

Thanks

EDIT: Here's the code I am using.

//Security
SECURITY_ATTRIBUTES sa;

HDESK dOld;
HDESK dNew;

BOOL switchdesk, switchdesk2, closedesk;
int AppPid;

sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);

//Get handle to current desktop
dOld = OpenDesktopA("default", 0, TRUE, DESKTOP_SWITCHDESKTOP| 
         DESKTOP_WRITEOBJECTS|
         DESKTOP_READOBJECTS|
         DESKTOP_ENUMERATE|
         DESKTOP_CREATEWINDOW|
         DESKTOP_CREATEMENU);
if(!dOld)
{
    printf("Failed to get current desktop handle !!\n\n");
    return 0;
}

//Make a new desktop
dNew = CreateDesktopA("kaka", 0, 0, 0, DESKTOP_SWITCHDESKTOP|
           DESKTOP_WRITEOBJECTS|
           DESKTOP_READOBJECTS|
           DESKTOP_ENUMERATE|
           DESKTOP_CREATEWINDOW|
           DESKTOP_CREATEMENU, &sa);

if(!dNew)
{
    printf("Failed to create new desktop !!\n\n");
    return 0;
}

AppPid = PerformOpenApp(SomeAppPath);
if(AppPid == 0)
{
    printf("failed to open app, err = %d\n", GetLastError());
}
else
{
    printf("App pid = %d\n", AppPid);
}


closedesk = CloseDesktop(dNew);

if(!closedesk)
{
    printf("Failed to close new desktop !!\n\n");
    return 0;
}


return 0;

EDIT for Bounty The current answer propesed DOES NOT COUNT as an answer, please do not set this as the answer to the bounty if the time for the bounty expires.

I pressed the "accept" by mistake. I asked the question again in http://stackoverflow.com/questions/1395351/createdesktop-with-vista-and-uac-on-c-windows

+1  A: 

Interesting problem... I wouldn't expect a difference bewteen the UAC/non-UAC scenario unless the launched program required administrator privilege (and I doubt that either notepad or calc does). Anyway, have you tried setting the thread's desktop before calling CreateProcess()?

HDESK hOld = GetThreadDesktop( GetCurrentThreadId() );
HDESK hNew = OpenDesktop( "name", 0, FALSE, GENERIC_ALL );
SetThreadDesktop( hNew );
CreateProcess( ... );
SetThreadDesktop( hOld );
CloseDesktop( hNew );
Peter Ruderman
no, but i'm trying now. Question, why are you using OpenDesktop() and not CreateDesktop()? unless you are creating it and then opening it?
wonderer
nope. It is still crashing...
wonderer
I may have misunderstood your question. Are you launching the application from the same thread you use to create the desktop? I suspect that setting the thread desktop may still be the problem. SetThreadDesktop() will fail if the calling thread owns any windows on the current desktop. It's safe to assume that CreateDesktop will fail to set the thread's desktop for the same reason, even if it successfully creates the new desktop.
Peter Ruderman
Yes, I create a desktop and then call createprocess. all from the same program. If I understood correctly, this won't work?
wonderer
It should work but evidentally doesn't. If you're creating the desktop from your main UI thread, chances are it will fail to set the thread's desktop. Maybe this is what's tripping UAC up.
Peter Ruderman
weird behavior. I tried opening firefox and ms word and none of them caused the crash. So it's not something consistent. I mean, if it's problem with memory allocation or space then I would assume that ms word would crash is it consumes everything there is, but nope. Why word is ok and IE not? or notepad?
wonderer
It's a good question. It sounds like a genuine Windows bug to me.
Peter Ruderman
:( no answer then? anyone? please...?
wonderer
well. the accept was pressed by mistake. I asked the question again in http://stackoverflow.com/questions/1395351/createdesktop-with-vista-and-uac-on-c-windows
wonderer
CreateProcess does not use the desktop from SetThreadDesktop because the call is sent by RPC to a service. Instead use the member desktop of the startupinfo structure.
ChristianWimmer