views:

353

answers:

2

I have this code:

#define _WIN32_WINNT 0x0500
#include <cstdlib>
#include <iostream>
#include <windows.h>

using namespace std;

int main(int argc, char *argv[])
{
    HDESK hOriginalThread;
    HDESK hOriginalInput;
    hOriginalThread = GetThreadDesktop(GetCurrentThreadId());
    hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP);


    HDESK hNewDesktop=CreateDesktop("BasicAppDesktopDesktop",NULL,NULL,0,DELETE|READ_CONTROL|WRITE_DAC|WRITE_OWNER|GENERIC_ALL,NULL);
    /*HDESK hNewDesktop=OpenDesktop("Winlogon", 0, FALSE,
                        DESKTOP_CREATEMENU |
                        DESKTOP_CREATEWINDOW |
                        DESKTOP_ENUMERATE    |
                        DESKTOP_HOOKCONTROL  |
                        DESKTOP_JOURNALPLAYBACK |
                        DESKTOP_JOURNALRECORD |
                        DESKTOP_READOBJECTS |
                        DESKTOP_SWITCHDESKTOP |
                        DESKTOP_WRITEOBJECTS);
                        */

    SetThreadDesktop(hNewDesktop);
    SwitchDesktop(hNewDesktop);
    //system("cmd");
    STARTUPINFOA si = {0};
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = "winsta0\\BasicAppDesktopDesktop";
    PROCESS_INFORMATION infos;
    CreateProcess(NULL,"explorer",NULL,NULL,false,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&infos);
    //WaitForSingleObject( infos.hProcess, INFINITE );
    while(!(GetAsyncKeyState(VK_F12) == -32767))Sleep(50);
    CloseHandle( infos.hProcess );
    CloseHandle( infos.hThread );

    SwitchDesktop(hOriginalInput);
    SetThreadDesktop(hOriginalThread);
    CloseDesktop(hNewDesktop);
    CloseDesktop(hOriginalInput);
    return 0;
}

When I press F12, desktop switch to original and program will close, but if I run in second desktop any program, then do not terminates, and when I run my program again, that any program will appears. Is there a way to delete desktops with programs, or automatic terminations of programs ran through second desktop on exit? Please help.

+3  A: 

If you want to force termination of a program that you started with CreateProcess (as in the code you posted), then you can just use TerminateProcess on the handle returned in your PROCESS_INFORMATION struct.

If you want to terminate all processes with threads attached to your new desktop, whether you started them or not, then its a bit (ok, a lot) more complicated. Your code would have to do the following:

  1. Enumerate all running processes (using CreateToolhelp32Snapshot)
  2. Enumerate threads for each process in turn (again using CreateToolhelp32Snapshot)
  3. Get desktop handle for each thread (using GetThreadDesktop)
  4. Get name of that desktop (using GetUserObjectInformation)
  5. Compare with name of your desktop
  6. If the names match, open a new handle to the parent process and terminate it (OpenProcess and TerminateProcess)

That's a lot of code to write, but it should work.

snowcrash09
Can you please post sample code here?I do not know programming in this area.
Matej
Have you considered reading the documentation?
jeffamaphone
@matej - if you the read the MSDN pages for each of the functions I've given you, the code will almost write itself ;-)
snowcrash09
+1  A: 

You can write a simle DLL that it will return GetStartupInfo using sockets. And you must inject your dll in all processes and execute your dll with CreateRemoteThread and de-inject after the StartupInfo data came.

Sorry for my bad English..