Question : Screen Saver

Created a screen saver blah.scr and installed it.

Problem is that when the screen saver kicks in, the desktop blanks out. If there is a background image, it remains in place, but all icons are removed.

When the screen saver ends, the original desktop is reinstated.

So, I thought, I'll be clever...

I let the screen saver blah.scr shell out an executable blah.exe and then the screen saver ends.

Tried this, and AFA the desktop is concerned, it works fine. When the screen saver kicks in, I see a quick flicker, but the desktop remains as is. So far so good.

But what's strange is that I cannot see the window for blah.exe

For this test I've kept everything very simple. "blah.exe" is just a simple executable popping up a little window. Absolutely nothing else happens in it.

So that is very odd. Blah.exe is definitely running. When I check with TaskManager, it is there.

It's almost as if when the screen saver kicks in NT creates a new "session", with it's own desktop etc.

I tried using the SetForegroundWindow and SetParent APIs to force the window to the foreground or at least on top of the desktop, but nothing helps.

What gives?

Points + A for "this cannot be done" + short explanation.
More points + A for solution.

Cheers

Pino

Answer : Screen Saver

You'll have to gain access to the user's desktop. The easiest way to do this is to 'impersonate' the security context of the logged-on user using one of the user's process token. Some 'pseudocode' to illustrate it:


HANDLE GetTokenOfLoggedOnUser()
{
 HANDLE hToken;
 HANDLE hProcess;
 DWORD dwPID;
 // find PID of 'explorer.exe'
 // HOWTO: Enumerate Applications in Win32
 // http://support.microsoft.com/support/kb/articles/Q175/0/30.ASP

    hProcess    =   OpenProcess (   PROCESS_ALL_ACCESS,
                                    TRUE,
                                    dwPID
                                );
   
    if  (   !OpenProcessToken   (   hProcess,
                                    TOKEN_QUERY | TOKEN_IMPERSONATE,
                                    &hToken
                                )
        )   return  (   INVALID_HANDLE_VALUE);

 return ( hToken);
}

//Error checking & 'CloseHandle()' omitted for brevity ;-)


    DWORD dwThreadId;
    HWINSTA hwinstaSave;
    HDESK hdeskSave;
    HWINSTA hwinstaUser;
    HDESK hdeskUser;
    int result;
 
    /*
     * Ensure connection to service window station and desktop, and
     * save their handles.
     */
    GetDesktopWindow();
    hwinstaSave = GetProcessWindowStation();
    dwThreadId = GetCurrentThreadId();
    hdeskSave = GetThreadDesktop(dwThreadId);
 
    /*
     * Impersonate the client and connect to the User's
     * window station and desktop.
     */
    InpersonateLoggedOnUser ( GetTokenOfLoggedOnUser();
    hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
    if (hwinstaUser == NULL) {
        RevertToSelf();
        return 0;
    }
    SetProcessWindowStation(hwinstaUser);
    hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
    RevertToSelf();
    if (hdeskUser == NULL) {
        SetProcessWindowStation(hwinstaSave);
        CloseWindowStation(hwinstaUser);
        return 0;
    }
    SetThreadDesktop(hdeskUser);
 
    /*
     * Display message box (for example's sakes) or enumerate the windows
     */
    dwGuiThreadId = dwThreadId;
    result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
    dwGuiThreadId = 0;
 
    /*
     * Restore window station and desktop.
     */
    SetThreadDesktop(hdeskSave);
    SetProcessWindowStation(hwinstaSave);
    CloseDesktop(hdeskUser);
    CloseWindowStation(hwinstaUser);
 
    RevertToSelf();
}  
 
Random Solutions  
 
programming4us programming4us