Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
835 lines
25 KiB
C++
835 lines
25 KiB
C++
#include "stdafx.h"
|
||
|
||
#include "ManageClientDispatch.h"
|
||
|
||
#include <Network/Session/Session.h>
|
||
#include <Network/Packet/ManagePacketCmd.h>
|
||
#include <Setup/SetupClient.h>
|
||
|
||
#include <Network/Dispatch/SingleDispatchStorage.h>
|
||
#include <Network/Dispatch/SendManagePacket.h>
|
||
#include <Log/ServerLog.h>
|
||
|
||
#include <tlhelp32.h>
|
||
#include <mmsystem.h>
|
||
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
#pragma comment(lib, "winmm.lib")
|
||
|
||
/*
|
||
// forward decl
|
||
HANDLE GetProcessHandle(const char* szProcessFullPathName, unsigned long* lpdwPID);
|
||
*/
|
||
|
||
enum ManageClientConst
|
||
{
|
||
MANAGE_CLIENT_DEFAULT_DISPATCH_NUM = 10
|
||
};
|
||
|
||
|
||
CManageClientDispatch::RunExtraInfo::RunExtraInfo(const ServerManage::RunInfo& runInfo,
|
||
HANDLE hProcess, unsigned long dwProcessID)
|
||
: m_RunInfo(runInfo), m_hProcess(hProcess), m_dwProcessID(dwProcessID),
|
||
m_hWnd(0), m_dwCustomStatus(0), m_dwLastSetWindowHandleTime(0)
|
||
{
|
||
char szCommand[MAX_PATH];
|
||
|
||
_snprintf(szCommand, MAX_PATH - 1, "%s", m_RunInfo.m_szOption);
|
||
szCommand[MAX_PATH - 1] = 0;
|
||
|
||
char* szData = strtok(szCommand, " \t\r\n");
|
||
while(0 != szData)
|
||
{
|
||
m_CommandSet.insert(szData);
|
||
szData = strtok(0, " \t\r\n");
|
||
}
|
||
}
|
||
|
||
|
||
CSingleDispatch& CManageClientDispatch::GetDispatchTable()
|
||
{
|
||
static CSingleDispatch singleDispatch;
|
||
return singleDispatch;
|
||
}
|
||
|
||
|
||
CManageClientDispatch::CManageClientDispatch(CSession& Session)
|
||
: CRylServerDispatch(Session, MANAGE_CLIENT_DEFAULT_DISPATCH_NUM),
|
||
m_hPatchFile(INVALID_HANDLE_VALUE),
|
||
m_bDoPatchNow(false)
|
||
{
|
||
TCHAR* szTempFileName = _T("./mytmp_patch.tmp");
|
||
|
||
memset(m_szTempPatchFileName, 0, sizeof(TCHAR) * MAX_PATH);
|
||
_tcscpy(m_szTempPatchFileName, szTempFileName);
|
||
|
||
TCHAR szFullPathModuleName[MAX_PATH];
|
||
|
||
GetModuleFileName(NULL, szFullPathModuleName, MAX_PATH - 1);
|
||
szFullPathModuleName[MAX_PATH - 1] = 0;
|
||
|
||
TCHAR szDrive[MAX_PATH];
|
||
TCHAR szPath[MAX_PATH];
|
||
TCHAR szName[MAX_PATH];
|
||
TCHAR szExtension[MAX_PATH];
|
||
|
||
_tsplitpath(szFullPathModuleName, szDrive, szPath, szName, szExtension);
|
||
|
||
_sntprintf(m_szTempPatchFileName, MAX_PATH - 1,
|
||
_T("%s\\%s\\%s"), szDrive, szPath, szTempFileName);
|
||
m_szTempPatchFileName[MAX_PATH - 1] = 0;
|
||
|
||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Created", this);
|
||
}
|
||
|
||
|
||
CManageClientDispatch::~CManageClientDispatch()
|
||
{
|
||
if(INVALID_HANDLE_VALUE != m_hPatchFile)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD>. <20>ݴ´<DDB4>.
|
||
ERRLOG2(g_Log, "this:0x%0p/HANDLE:0x%p/PatchFile is not closed. close now", this, m_hPatchFile);
|
||
CloseHandle(m_hPatchFile);
|
||
}
|
||
|
||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Destroyed", this);
|
||
}
|
||
|
||
|
||
void CManageClientDispatch::Connected()
|
||
{
|
||
GetDispatchTable().SetDispatch(this);
|
||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Connected", this);
|
||
}
|
||
|
||
|
||
void CManageClientDispatch::Disconnected()
|
||
{
|
||
GetDispatchTable().RemoveDispatch(this);
|
||
DETLOG1(g_Log, "this:0x%p/CManageClientDispatch Disconnected", this);
|
||
}
|
||
|
||
|
||
bool CManageClientDispatch::DispatchPacket(PktBase* lpPktBase)
|
||
{
|
||
PktBase::LengthType nPacketLen = lpPktBase->GetLen();
|
||
|
||
if(nPacketLen < sizeof(ServerManage::ManageCommand))
|
||
{
|
||
ERRLOG3(g_Log, "IP:%15s/PacketLen:%d/Cmd:0x%02x/Invalid packet length or command",
|
||
GetSession().GetRemoteAddr().get_addr_string(), lpPktBase->GetLen(), lpPktBase->GetCmd());
|
||
}
|
||
else
|
||
{
|
||
ServerManage::ManageCommand* lpManageCommand =
|
||
reinterpret_cast<ServerManage::ManageCommand*>(lpPktBase);
|
||
|
||
if(nPacketLen != sizeof(ServerManage::ManageCommand) + lpManageCommand->usDataLen)
|
||
{
|
||
ERRLOG3(g_Log, "IP:%15s/PacketLen:%d/Cmd:0x%02x/Invalid packet length",
|
||
GetSession().GetRemoteAddr().get_addr_string(), lpPktBase->GetLen(), lpPktBase->GetCmd());
|
||
}
|
||
else
|
||
{
|
||
TCHAR* szWindowName = 0;
|
||
|
||
char* lpData = (0 != lpManageCommand->usDataLen) ?
|
||
reinterpret_cast<char*>(lpManageCommand + 1) : 0;
|
||
|
||
const TCHAR* szErrorMessage = 0;
|
||
|
||
switch(lpManageCommand->GetCmd())
|
||
{
|
||
case ServerManage::CMD::UpdateRunList: // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> (ManageServer -> ManageClient, ManageTool), Ack<63><6B><EFBFBD><EFBFBD>.
|
||
ProcessUpdateRunList(lpData, lpManageCommand->usDataLen, lpManageCommand->usFlags);
|
||
break;
|
||
|
||
case ServerManage::CMD::RunProcess: // <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. (ManageTool -> ManageServer -> ManageClient), Ack<63><6B> <20>ݴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ProcessRunServer(lpManageCommand->dwRunID);
|
||
break;
|
||
|
||
case ServerManage::CMD::QuitProcess: // <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. (ManageTool -> ManageServer -> ManageClient), Ack<63><6B> <20>ݴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ProcessQuitServer(lpManageCommand->dwRunID);
|
||
break;
|
||
|
||
case ServerManage::CMD::ForceTerminate: // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. (ManageTool -> ManageServer -> ManageClient), Ack<63><6B> <20>ݴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ProcessTerminateServer(lpManageCommand->dwRunID);
|
||
break;
|
||
|
||
case ServerManage::CMD::RelayCommand: // <20><>Ŷ Ŀ<>ǵ带 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> <20>Ἥ <20>߰<EFBFBD><DFB0>ؼ<EFBFBD> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
|
||
|
||
/*
|
||
if(!ProcessRelayCommand(lpManageCommand->nMessage,
|
||
lpManageCommand->wParam, lpManageCommand->lParam,
|
||
szWindowName, lpData, lpManageCommand->usDataLen, lpManageCommand->cFlag))
|
||
{
|
||
szErrorMessage = _T("RelayCommand : RelayCommand Failed");
|
||
}
|
||
*/
|
||
break;
|
||
|
||
case ServerManage::CMD::AutoPatch: // <20>ڱ<EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><>ġ<EFBFBD>Ѵ<EFBFBD>
|
||
|
||
if(!ProcessAutoPatch(lpData, lpManageCommand->usDataLen, lpManageCommand->usFlags))
|
||
{
|
||
szErrorMessage = _T("AutoPatch : AutoPatch packet process failed");
|
||
}
|
||
break;
|
||
|
||
case ServerManage::CMD::ChangeSetup: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲٰ<D9B2> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
|
||
if(!ManageSetup::ClientSetup::GetInstance().SerializeIn(lpData, lpManageCommand->usDataLen))
|
||
{
|
||
szErrorMessage = _T("ChangeSetup : Change setup failed");
|
||
}
|
||
else
|
||
{
|
||
ManageSetup::ClientSetup::GetInstance().Save();
|
||
}
|
||
break;
|
||
|
||
case ServerManage::CMD::ReloadSetup: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
|
||
|
||
ManageSetup::ClientSetup::GetInstance().Load();
|
||
break;
|
||
|
||
|
||
case ServerManage::CMD::ExecuteCommand:
|
||
ProcessExecuteConsoleCommand(lpManageCommand);
|
||
break;
|
||
|
||
default:
|
||
|
||
szErrorMessage = _T("Unknown message : Process failed");
|
||
break;
|
||
}
|
||
|
||
if(0 != szErrorMessage)
|
||
{
|
||
ERRLOG4(g_Log, "IP:%15s/DetailCmd:0x%02x/Error:%d/%s",
|
||
GetSession().GetRemoteAddr().get_addr_string(),
|
||
lpPktBase->GetCmd(), GetLastError(), szErrorMessage);
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
|
||
bool CManageClientDispatch::ProcessRelayCommand(unsigned int nMessage, WPARAM wParam, LPARAM lParam,
|
||
const char* szWindowName, const char* lpData,
|
||
unsigned short usDataLen, unsigned char cFlag)
|
||
{
|
||
if(0 != szWindowName)
|
||
{
|
||
HWND hWnd = FindWindow(0, szWindowName);
|
||
if(0 != hWnd)
|
||
{
|
||
if(0 != lpData && WM_COPYDATA == nMessage)
|
||
{
|
||
COPYDATASTRUCT copyDataStruct;
|
||
|
||
copyDataStruct.dwData = 0;
|
||
copyDataStruct.cbData = usDataLen;
|
||
copyDataStruct.lpData = (void*)lpData;
|
||
|
||
// <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
SendMessage(hWnd, nMessage, wParam,
|
||
reinterpret_cast<LPARAM>(©DataStruct));
|
||
}
|
||
else
|
||
{
|
||
SendMessage(hWnd, nMessage, wParam, lParam);
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
bool CManageClientDispatch::ProcessAutoPatch(const char* lpData, unsigned short usDataLen, unsigned short usFlag)
|
||
{
|
||
switch(usFlag)
|
||
{
|
||
case ServerManage::ManageCommand::AUTOPATCH_OPENFILE:
|
||
|
||
if(INVALID_HANDLE_VALUE != m_hPatchFile)
|
||
{
|
||
// <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>ݴ´<DDB4>.
|
||
ERRLOG2(g_Log, "this:0x%0p/HANDLE:0x%p/PatchFile is not closed. close now for create new one",
|
||
this, m_hPatchFile);
|
||
|
||
CloseHandle(m_hPatchFile);
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
m_hPatchFile = CreateFile(m_szTempPatchFileName, GENERIC_WRITE, 0, 0,
|
||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||
|
||
if(INVALID_HANDLE_VALUE == m_hPatchFile)
|
||
{
|
||
ERRLOG2(g_Log, "this:0x%p/Error:%d/Patch tempfile create failed",
|
||
this, GetLastError());
|
||
}
|
||
break;
|
||
|
||
case ServerManage::ManageCommand::AUTOPATCH_DATA:
|
||
|
||
if(INVALID_HANDLE_VALUE != m_hPatchFile)
|
||
{
|
||
unsigned long dwWritten = 0;
|
||
unsigned long dwTotalWritten = 0;
|
||
|
||
while(usDataLen != dwTotalWritten)
|
||
{
|
||
if(!WriteFile(m_hPatchFile, lpData, usDataLen, &dwWritten, 0))
|
||
{
|
||
ERRLOG3(g_Log, "this:0x%p/HANDLE:0x%p/Error:%d/Patchfile write failed.",
|
||
this, m_hPatchFile, GetLastError());
|
||
|
||
CloseHandle(m_hPatchFile);
|
||
m_hPatchFile = INVALID_HANDLE_VALUE;
|
||
|
||
DeleteFile(m_szTempPatchFileName);
|
||
break;
|
||
}
|
||
|
||
dwTotalWritten += dwWritten;
|
||
}
|
||
|
||
if(0 == usDataLen && INVALID_HANDLE_VALUE != m_hPatchFile)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ҵ<DEBE>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
m_bDoPatchNow = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERRLOG1(g_Log, "this:0x%p/Patchfile is invalid", this);
|
||
}
|
||
break;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
bool CManageClientDispatch::ProcessUpdateRunList(const char* szData, unsigned short usDataLen,
|
||
unsigned short usFlags)
|
||
{
|
||
if(ServerManage::SEND_RUNINFO_START == usFlags)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Process<73>鿡 <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD> <20>ݴ´<DDB4>.
|
||
RunTable::iterator pos = m_RunTable.begin();
|
||
RunTable::iterator end = m_RunTable.end();
|
||
|
||
for(; pos != end; ++pos)
|
||
{
|
||
RunExtraInfo& runExtraInfo = pos->second;
|
||
|
||
if(0 != runExtraInfo.m_hProcess)
|
||
{
|
||
CloseHandle(runExtraInfo.m_hProcess);
|
||
}
|
||
}
|
||
|
||
m_RunTable.clear();
|
||
}
|
||
else if(ServerManage::SEND_RUNINFO_NOW == usFlags)
|
||
{
|
||
// RunTable<6C><65> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
const ServerManage::RunInfo* lpRunInfo = reinterpret_cast<const ServerManage::RunInfo*>(szData);
|
||
const ServerManage::RunInfo* lpEndRunInfo = lpRunInfo + (usDataLen / sizeof(ServerManage::RunInfo));
|
||
|
||
for(; lpRunInfo != lpEndRunInfo; ++lpRunInfo)
|
||
{
|
||
m_RunTable.insert(RunTable::value_type(lpRunInfo->m_dwRunID,
|
||
RunExtraInfo(*lpRunInfo, 0, 0)));
|
||
}
|
||
}
|
||
else if(ServerManage::SEND_RUNINFO_FINISH == usFlags)
|
||
{
|
||
// <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
CheckProcessStatus();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CManageClientDispatch::ProcessRunServer(unsigned long dwRunID)
|
||
{
|
||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||
|
||
if(pos != m_RunTable.end())
|
||
{
|
||
RunExtraInfo& runExInfo = pos->second;
|
||
|
||
TCHAR szDrive[MAX_PATH];
|
||
TCHAR szPath[MAX_PATH];
|
||
|
||
TCHAR szDefaultPath[MAX_PATH];
|
||
|
||
_splitpath(runExInfo.m_RunInfo.m_szPath, szDrive, szPath, 0, 0);
|
||
|
||
_snprintf(szDefaultPath, MAX_PATH - 1, "%s%s", szDrive, szPath);
|
||
szDefaultPath[MAX_PATH - 1] = 0;
|
||
|
||
STARTUPINFO si;
|
||
PROCESS_INFORMATION pi;
|
||
|
||
ZeroMemory(&si, sizeof(si));
|
||
si.cb = sizeof(si);
|
||
|
||
ZeroMemory(&pi, sizeof(pi));
|
||
|
||
// Start the child process.
|
||
|
||
|
||
/*
|
||
if(CreateProcess(runExInfo.m_RunInfo.m_szPath, runExInfo.m_RunInfo.m_szOption, 0, 0,
|
||
FALSE, 0, 0, szDefaultPath, &si, &pi))
|
||
*/
|
||
char szExecutePath[MAX_PATH * 2];
|
||
_snprintf(szExecutePath, MAX_PATH * 2 - 1, "\"%s\" %s",
|
||
runExInfo.m_RunInfo.m_szPath, runExInfo.m_RunInfo.m_szOption);
|
||
|
||
szExecutePath[MAX_PATH * 2 - 1] = 0;
|
||
|
||
if(CreateProcess(0, szExecutePath, 0, 0,
|
||
FALSE, 0, 0, szDefaultPath, &si, &pi))
|
||
|
||
{
|
||
runExInfo.m_hProcess = pi.hProcess;
|
||
runExInfo.m_dwProcessID = pi.dwProcessId;
|
||
|
||
DETLOG4(g_Log, "Execute file success, RunID(%u), Path(%s), Option(%s), DefaultPath(%s)",
|
||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||
runExInfo.m_RunInfo.m_szOption, szDefaultPath);
|
||
}
|
||
else
|
||
{
|
||
ERRLOG5(g_Log, "Cannot execute file : CreateProcess failed(%d), RunID(%u), "
|
||
"Path(%s), Option(%s), DefaultPath(%s)",
|
||
WSAGetLastError(), runExInfo.m_RunInfo.m_dwRunID,
|
||
runExInfo.m_RunInfo.m_szPath, runExInfo.m_RunInfo.m_szOption, szDefaultPath);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ERRLOG1(g_Log, "Cannot execute file : Unknown RunID(%d)", dwRunID);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CManageClientDispatch::ProcessQuitServer(unsigned long dwRunID)
|
||
{
|
||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||
|
||
if(pos != m_RunTable.end())
|
||
{
|
||
RunExtraInfo& runExInfo = pos->second;
|
||
|
||
if(0 != runExInfo.m_hWnd)
|
||
{
|
||
TCHAR szWindowName[MAX_PATH];
|
||
GetWindowText(runExInfo.m_hWnd, szWindowName, MAX_PATH - 1);
|
||
szWindowName[MAX_PATH - 1] = 0;
|
||
|
||
SendMessage(runExInfo.m_hWnd, WM_DESTROY, 0, 0);
|
||
|
||
DETLOG6(g_Log, "Send quit message : HANDLE(0x%p), PID(0x%08x), WindowName(%s), "
|
||
"RunID(%u), Path(%s), Option(%s)",
|
||
runExInfo.m_hProcess, runExInfo.m_dwProcessID, szWindowName,
|
||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||
runExInfo.m_RunInfo.m_szOption);
|
||
}
|
||
else
|
||
{
|
||
ERRLOG5(g_Log, "Cannot send quit message (Get window failed) : "
|
||
"HANDLE(0x%p), PID(0x%08x), RunID(%u), Path(%s), Option(%s)",
|
||
runExInfo.m_hProcess, runExInfo.m_dwProcessID,
|
||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||
runExInfo.m_RunInfo.m_szOption);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CManageClientDispatch::ProcessTerminateServer(unsigned long dwRunID)
|
||
{
|
||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||
|
||
if(pos != m_RunTable.end())
|
||
{
|
||
RunExtraInfo& runExInfo = pos->second;
|
||
|
||
if(0 != runExInfo.m_hProcess)
|
||
{
|
||
if(TerminateProcess(runExInfo.m_hProcess, -1))
|
||
{
|
||
DETLOG5(g_Log, "Terminate process. HANDLE(0x%p), PID(0x%08x), "
|
||
"RunID(%u), Path(%s), Option(%s)",
|
||
runExInfo.m_hProcess, runExInfo.m_dwProcessID,
|
||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||
runExInfo.m_RunInfo.m_szOption);
|
||
}
|
||
else
|
||
{
|
||
ERRLOG6(g_Log, "Cannot terminate process. Err(%d), HANDLE(0x%p), PID(0x%08x), "
|
||
"RunID(%u), Path(%s), Option(%s)",
|
||
GetLastError(), runExInfo.m_hProcess, runExInfo.m_dwProcessID,
|
||
runExInfo.m_RunInfo.m_dwRunID, runExInfo.m_RunInfo.m_szPath,
|
||
runExInfo.m_RunInfo.m_szOption);
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
bool CManageClientDispatch::ProcessExecuteConsoleCommand(ServerManage::ManageCommand* lpManageCmd)
|
||
{
|
||
RunTable::iterator pos = m_RunTable.find(lpManageCmd->dwRunID);
|
||
|
||
if(pos != m_RunTable.end())
|
||
{
|
||
RunExtraInfo& runExInfo = pos->second;
|
||
|
||
if(0 != runExInfo.m_hWnd)
|
||
{
|
||
COPYDATASTRUCT copyDataStruct;
|
||
|
||
copyDataStruct.dwData = 0;
|
||
copyDataStruct.cbData = lpManageCmd->GetLen();
|
||
copyDataStruct.lpData = lpManageCmd;
|
||
|
||
SendMessage(runExInfo.m_hWnd, WM_COPYDATA, 0, (LPARAM)©DataStruct);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
void CManageClientDispatch::CheckProcessStatus()
|
||
{
|
||
const int MAX_PROCESS_STATUS_SEND_ONCE =
|
||
(PktMaxLen - sizeof(ServerManage::ManageCommand)) / sizeof(ServerManage::ProcessStatus);
|
||
|
||
ServerManage::ProcessStatus procesStatus[MAX_PROCESS_STATUS_SEND_ONCE];
|
||
|
||
RunTable::iterator pos = m_RunTable.begin();
|
||
RunTable::iterator end = m_RunTable.end();
|
||
|
||
for(; pos != end; ++pos)
|
||
{
|
||
RunExtraInfo& runExtraInfo = pos->second;
|
||
|
||
// üũ<C3BC>ϰ<EFBFBD>, PID<49><44> <20>ִµ<D6B4> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD>, <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
if(0 != runExtraInfo.m_dwProcessID && 0 != runExtraInfo.m_hWnd
|
||
&& 0 == runExtraInfo.m_hProcess)
|
||
{
|
||
runExtraInfo.m_hProcess = OpenProcess(PROCESS_ALL_ACCESS,
|
||
FALSE, runExtraInfo.m_dwProcessID);
|
||
}
|
||
}
|
||
|
||
unsigned long dwExitCode = 0;
|
||
unsigned long dwErrorCode = 0;
|
||
unsigned short usSendProcessStatus = 0;
|
||
|
||
pos = m_RunTable.begin();
|
||
end = m_RunTable.end();
|
||
|
||
for(; pos != end; ++pos)
|
||
{
|
||
RunExtraInfo& runExtraInfo = pos->second;
|
||
|
||
// Default - Deactivated Process.
|
||
ServerManage::ProcessStatus* lpCurrentProcessStatus = procesStatus + usSendProcessStatus;
|
||
memset(lpCurrentProcessStatus, 0, sizeof(ServerManage::ProcessStatus));
|
||
|
||
lpCurrentProcessStatus->m_dwRunID = runExtraInfo.m_RunInfo.m_dwRunID;
|
||
lpCurrentProcessStatus->m_dwStatusFlags = 0;
|
||
lpCurrentProcessStatus->m_dwCurrentTime = timeGetTime();
|
||
lpCurrentProcessStatus->m_dwCustomStatus = runExtraInfo.m_dwCustomStatus;
|
||
lpCurrentProcessStatus->m_dwLastSetWindowHandleTime = runExtraInfo.m_dwLastSetWindowHandleTime;
|
||
|
||
if(0 != runExtraInfo.m_hProcess)
|
||
{
|
||
GetProcessTimes(runExtraInfo.m_hProcess,
|
||
&lpCurrentProcessStatus->m_CreationTIme,
|
||
&lpCurrentProcessStatus->m_ExitTime,
|
||
&lpCurrentProcessStatus->m_KernelTime,
|
||
&lpCurrentProcessStatus->m_UserTime);
|
||
|
||
GetProcessMemoryInfo(runExtraInfo.m_hProcess,
|
||
&lpCurrentProcessStatus->m_ProcessMemoryCounters,
|
||
sizeof(PROCESS_MEMORY_COUNTERS));
|
||
|
||
if(!GetExitCodeProcess(runExtraInfo.m_hProcess, &dwExitCode))
|
||
{
|
||
ERRLOG3(g_Log, "GetExitCodeProcess failed(%d) : RunID(%u), Path(%s)",
|
||
dwErrorCode, runExtraInfo.m_RunInfo.m_dwRunID,
|
||
runExtraInfo.m_RunInfo.m_szPath);
|
||
}
|
||
else if(dwExitCode != STILL_ACTIVE)
|
||
{
|
||
DETLOG4(g_Log, "Close process handle : HANDLE(0x%p), PID(0x%08x), RunID(%u), Path(%s)",
|
||
runExtraInfo.m_hProcess, runExtraInfo.m_dwProcessID,
|
||
runExtraInfo.m_RunInfo.m_dwRunID, runExtraInfo.m_RunInfo.m_szPath);
|
||
|
||
CloseHandle(runExtraInfo.m_hProcess);
|
||
runExtraInfo.m_hProcess = 0;
|
||
runExtraInfo.m_dwProcessID = 0;
|
||
runExtraInfo.m_hWnd = 0;
|
||
runExtraInfo.m_dwLastSetWindowHandleTime = 0;
|
||
}
|
||
else
|
||
{
|
||
lpCurrentProcessStatus->m_dwStatusFlags =
|
||
ServerManage::PROCESS_RUNNING;
|
||
}
|
||
}
|
||
|
||
++usSendProcessStatus;
|
||
|
||
if(usSendProcessStatus == MAX_PROCESS_STATUS_SEND_ONCE)
|
||
{
|
||
ServerManage::SendManagePacket(GetSession(), ServerManage::CMD::ProcessStatus,
|
||
0, 0, 0, 0, sizeof(ServerManage::ProcessStatus) * usSendProcessStatus, 0, procesStatus, 0);
|
||
|
||
usSendProcessStatus = 0;
|
||
}
|
||
}
|
||
|
||
if(0 < usSendProcessStatus)
|
||
{
|
||
ServerManage::SendManagePacket(GetSession(), ServerManage::CMD::ProcessStatus,
|
||
0, 0, 0, 0, sizeof(ServerManage::ProcessStatus) * usSendProcessStatus, 0, procesStatus, 0);
|
||
|
||
usSendProcessStatus = 0;
|
||
}
|
||
}
|
||
|
||
bool CManageClientDispatch::SetAppData(unsigned long dwRunID, HWND hWnd,
|
||
unsigned long dwPID, unsigned long dwCustomStatus)
|
||
{
|
||
RunTable::iterator pos = m_RunTable.find(dwRunID);
|
||
RunTable::iterator end = m_RunTable.end();
|
||
|
||
if(pos != end)
|
||
{
|
||
RunExtraInfo& runExtraInfo = pos->second;
|
||
|
||
runExtraInfo.m_dwProcessID = dwPID;
|
||
runExtraInfo.m_hWnd = hWnd;
|
||
runExtraInfo.m_dwCustomStatus = dwCustomStatus;
|
||
runExtraInfo.m_dwLastSetWindowHandleTime = timeGetTime();
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
bool CManageClientDispatch::GetRunIDFromString(const char* szAppName, const char* szCommandLine,
|
||
unsigned long& dwRunID_Out)
|
||
{
|
||
char szProcessName[MAX_PATH];
|
||
char szProcessSnapName[MAX_PATH];
|
||
|
||
_snprintf(szProcessSnapName, MAX_PATH - 1, "%s", szAppName);
|
||
szProcessSnapName[MAX_PATH - 1] = 0;
|
||
_strupr(szProcessSnapName);
|
||
|
||
char szCommandLineData[MAX_PATH * 2];
|
||
_snprintf(szCommandLineData, MAX_PATH * 2 - 1, "%s", szCommandLine);
|
||
szCommandLineData[MAX_PATH * 2 - 1] = 0;
|
||
|
||
RunExtraInfo::CommandSet commandSet;
|
||
|
||
char* szData = 0;
|
||
|
||
if('\"' == szCommandLineData[0])
|
||
{
|
||
szData = strtok(szCommandLineData, "\"");
|
||
szData = strtok(0, "\"");
|
||
|
||
if(0 != szData)
|
||
{
|
||
// <20><><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD> <20>и<EFBFBD><D0B8><EFBFBD> Argument<6E><74> <20>Ƽ<DEBE> ó<><C3B3>..
|
||
char szRealCommandLine[MAX_PATH];
|
||
_snprintf(szRealCommandLine, MAX_PATH - 1, "%s", szData);
|
||
szRealCommandLine[MAX_PATH - 1] = 0;
|
||
|
||
szData = strtok(szRealCommandLine, " \t\r\n");
|
||
while(0 != szData)
|
||
{
|
||
commandSet.insert(szData);
|
||
szData = strtok(0, " \t\r\n");
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
szData = strtok(szCommandLineData, " \t\r\n");
|
||
|
||
// ù<><C3B9>° Argument<6E><74> <20><><EFBFBD>ϸ<EFBFBD><CFB8>̹Ƿ<CCB9> <20><><EFBFBD><EFBFBD>.
|
||
szData = strtok(0, " \t\r\n");
|
||
while(0 != szData)
|
||
{
|
||
commandSet.insert(szData);
|
||
szData = strtok(0, " \t\r\n");
|
||
}
|
||
}
|
||
|
||
RunTable::iterator pos = m_RunTable.begin();
|
||
RunTable::iterator end = m_RunTable.end();
|
||
|
||
for(; pos != end; ++pos)
|
||
{
|
||
RunExtraInfo& runExtraInfo = pos->second;
|
||
|
||
_snprintf(szProcessName, MAX_PATH - 1, "%s", runExtraInfo.m_RunInfo.m_szPath);
|
||
szProcessName[MAX_PATH - 1] = 0;
|
||
_strupr(szProcessName);
|
||
|
||
if(0 == strncmp(szProcessName, szProcessSnapName, MAX_PATH))
|
||
{
|
||
if((runExtraInfo.m_CommandSet.size() == commandSet.size()
|
||
&& std::equal(runExtraInfo.m_CommandSet.begin(),
|
||
runExtraInfo.m_CommandSet.end(), commandSet.begin())))
|
||
{
|
||
dwRunID_Out = runExtraInfo.m_RunInfo.m_dwRunID;
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
dwRunID_Out = 0;
|
||
return false;
|
||
}
|
||
|
||
|
||
bool CManageClientDispatch::GetRunIDFromPID(unsigned long dwPID, unsigned long& dwRunID_Out)
|
||
{
|
||
RunTable::iterator pos = m_RunTable.begin();
|
||
RunTable::iterator end = m_RunTable.end();
|
||
|
||
for(; pos != end; ++pos)
|
||
{
|
||
RunExtraInfo& runExtraInfo = pos->second;
|
||
|
||
if(runExtraInfo.m_dwProcessID == dwPID)
|
||
{
|
||
dwRunID_Out = runExtraInfo.m_RunInfo.m_dwRunID;
|
||
return true;
|
||
}
|
||
}
|
||
|
||
dwRunID_Out = 0;
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
|
||
/*
|
||
HANDLE GetProcessHandle(const char* szProcessFullPathName, unsigned long* lpdwPID)
|
||
{
|
||
HANDLE hProcess = INVALID_HANDLE_VALUE;
|
||
|
||
if(0 == lpdwPID)
|
||
{
|
||
return hProcess;
|
||
}
|
||
|
||
// Take a snapshot of all processes in the system.
|
||
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||
|
||
if (hProcessSnap == INVALID_HANDLE_VALUE)
|
||
{
|
||
return hProcess;
|
||
}
|
||
|
||
// Fill in the size of the structure before using it.
|
||
PROCESSENTRY32 pe32 = {0};
|
||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||
|
||
// Walk the snapshot of the processes, and for each process,
|
||
// display information.
|
||
|
||
char szProcessName[MAX_PATH];
|
||
char szProcessSnapName[MAX_PATH];
|
||
|
||
_snprintf(szProcessName, MAX_PATH - 1, "%s", szProcessFullPathName);
|
||
szProcessName[MAX_PATH - 1] = 0;
|
||
|
||
_strupr(szProcessName);
|
||
|
||
bool bFound = false;
|
||
|
||
if (Process32First(hProcessSnap, &pe32))
|
||
{
|
||
do
|
||
{
|
||
MODULEENTRY32 me32 = {0};
|
||
|
||
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe32.th32ProcessID);
|
||
if (hModuleSnap != INVALID_HANDLE_VALUE)
|
||
{
|
||
me32.dwSize = sizeof(MODULEENTRY32);
|
||
|
||
if (Module32First(hModuleSnap, &me32))
|
||
{
|
||
do
|
||
{
|
||
_snprintf(szProcessSnapName, MAX_PATH - 1, "%s", me32.szExePath);
|
||
szProcessSnapName[MAX_PATH - 1] = 0;
|
||
|
||
_strupr(szProcessSnapName);
|
||
|
||
if(0 == strcmp(szProcessName, szProcessSnapName))
|
||
{
|
||
// Get the actual priority class.
|
||
hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
|
||
if(INVALID_HANDLE_VALUE == hProcess)
|
||
{
|
||
ERRLOG2(g_Log, "Process open failed(%d) : %s",
|
||
GetLastError(), me32.szExePath);
|
||
}
|
||
|
||
*lpdwPID = pe32.th32ProcessID;
|
||
bFound = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
while (!bFound && Module32Next(hModuleSnap, &me32));
|
||
}
|
||
|
||
CloseHandle (hModuleSnap);
|
||
}
|
||
}
|
||
|
||
while (!bFound && Process32Next(hProcessSnap, &pe32));
|
||
}
|
||
|
||
CloseHandle(hProcessSnap);
|
||
return hProcess;
|
||
}
|
||
|
||
*/ |