// ManageClient.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" #include "ManageClient.h" #include #include // CNamedMutex #include #include // g_CExceptionReport #include #include #include #include #include #include #include #include #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { CNamedMutex Mutex("ManageClient", TRUE); if(GetLastError() == ERROR_ALREADY_EXISTS) { ERRLOG0(g_Log, "ManageClient already server operating now. please shutdown and restart"); return 0; } unsigned long dwExceptionFeatures = CExceptionReport::CATCH_EXCEPTION | CExceptionReport::USE_MINIDUMP | CExceptionReport::USE_REPORT; CExceptionReport::GetInstance().Enable(dwExceptionFeatures); CManageClient& ManageClient = CManageClient::GetInstance(); if(ManageClient.Initialize(hInstance, CServerSetup::GetInstance().GetManageClientWindowName(), lpCmdLine, IDI_MANAGECLIENT, IDC_MANAGECLIENT)) { ManageClient.ProcessMessage(); } return 0; } class CManageClientProcessThread : public CProcessThread { public: enum Const { PROCESS_TPP = 200, // 200ms(0.2ÃÊ) ¿¡ 1ƽ. CONNECT_CHECK = 10 * (1000 / PROCESS_TPP), // 10Ãʸ¶´Ù ¿¬°á üũ PRINT_CHECK = 2 * (1000 / PROCESS_TPP), // 2Ãʸ¶´Ù ÄÜ¼Ö Ãâ·Â PROCESS_CHECK = 3 * (1000 / PROCESS_TPP) // 5Ãʸ¶´Ù ó¸® °»½Å }; CManageClientProcessThread(CManageClient& ManageClient) : CProcessThread(ManageClient, PROCESS_TPP), m_ManageClient(ManageClient) { } private: virtual void Cleanup(CPulse& Pulse) { } virtual void InternalRun(CPulse& Pulse) { unsigned long dwCurrentPulse = Pulse.GetCurrentPulse(); if(0 == (dwCurrentPulse % CONNECT_CHECK)) { m_ManageClient.CheckConnectionAndReconnect(); } if(0 == (dwCurrentPulse % PRINT_CHECK)) { m_ManageClient.PrintConnectionStatus(); } if(0 == (dwCurrentPulse % PROCESS_CHECK)) { GET_SINGLE_DISPATCH(lpManageClientDispatch, CManageClientDispatch, CManageClientDispatch::GetDispatchTable()); if(0 != lpManageClientDispatch) { lpManageClientDispatch->CheckProcessStatus(); } } } CManageClient& m_ManageClient; }; CManageClient& CManageClient::GetInstance() { static CManageClient manageClient; return manageClient; } CManageClient::CManageClient() : m_lpClientSessionPolicy(SessionPolicy::CreateTCPPolicy()) { } CManageClient::~CManageClient() { if(0 != m_lpClientSessionPolicy) { m_lpClientSessionPolicy->Release(); m_lpClientSessionPolicy = 0; } } void CManageClient::CheckConnectionAndReconnect() { bool bReconnect = false; GET_SINGLE_DISPATCH(lpManageClientDispatch, CManageClientDispatch, CManageClientDispatch::GetDispatchTable()); if(0 == lpManageClientDispatch) { // ¿¬°áÀÌ ¾È µÇ¾î ÀÖÀ¸¸é ¿¬°áÀ» Å×½ºÆ®ÇÔ. CIOCPNet* lpIOCP = GetIOCPNet(); if(0 != lpIOCP) { ConnectToManageServer(); } } else if(lpManageClientDispatch->DoPatchNow()) { // ÆÐÄ¡¸¦ ÀüºÎ ¹Þ°í, ÆÐÄ¡Çϱâ Á÷ÀüÀÌ´Ù. ÆÐÄ¡ ÇÁ·Î¼¼½º¸¦ ½ÃÀÛÇÑ´Ù. DoSelfPatchProcess(*lpManageClientDispatch); } } void CManageClient::ConnectToManageServer() { CIOCPNet* lpIOCP = GetIOCPNet(); if(0 != lpIOCP && 0 != m_lpClientSessionPolicy) { INET_Addr& manageServerAddr = ManageSetup::ClientSetup::GetInstance().GetManageServerAddr(); if(!lpIOCP->Connect(m_lpClientSessionPolicy, manageServerAddr.get_addr_string(), manageServerAddr.get_port_in())) { DETLOG3(g_Log, "this:0x%p/IP:%15s/Port/%02d/ManageServer connect failed.", this, manageServerAddr.get_addr_string(), manageServerAddr.get_port_in()); } } } void CManageClient::DoSelfPatchProcess(CManageClientDispatch& ClientDispatch) { /* // temporary .bat file static const TCHAR szTempBatContent[] = _T(":Repeat\r\n") _T("del \"%s\"\r\n") // execute file name(full path) _T("if exist \"%s\" goto Repeat\r\n") // execute file name(full path) _T(":Repeat2\r\n") _T("rename %s %s\r\n") // first - temp file name(full path), second - execute file name only _T("if not exist \"%s\" goto Repeat\r\n") // execute file name(full path) _T("cd %s\r\n") // execute file path(full path) _T("%s\r\n"); // execute file name(full path) static const TCHAR szTempBatName[] = "_manageclient_selfpatch.bat" ; TCHAR szFullPathModuleName[MAX_PATH]; // absolute path of calling .exe file TCHAR szModulePath[MAX_PATH]; // Module path TCHAR szModuleFileName[MAX_PATH]; // fileName TCHAR szModuleExtension[NAX_PATH]; // extension TCHAR szTempBatPathName[MAX_PATH]; // absolute path of temporary .bat file memset(szFullPathModuleName, 0, sizeof(TCHAR) * MAX_PATH); memset(szModulePath, 0, sizeof(TCHAR) * MAX_PATH); memset(szTempBatPathName, 0, sizeof(TCHAR) * MAX_PATH); bool bFailedGetName = true; unsigned long dwPathLength = GetTempPath(MAX_PATH, szTempBatPathName); if(0 < dwPathLength) { if(0 < _sntprintf(szTempBatPathName + dwPathLength, MAX_PATH - dwPathLength - 1, "%s", szTempBatName)) { szTempBatPathName[MAX_PATH - 1] = 0; bFailedGetName = false; } } const TCHAR* szErrorMessage = 0; if(bFailedGetName) { szErrorMessage = _T("this:0x%p/Failed get tempbat file."); } else { dwPathLength = GetModuleFileName(NULL, szFullPathModuleName, MAX_PATH - 1); szFullPathModuleName[MAX_PATH - 1] = 0; _tsplitpath(szFullPathModuleName, 0, 0, szModuleFileName, szModuleExtension); _sntprintf(szModuleFileName, szModuleExtension szModuleFileName = _tcsrchr(szFullPathModuleName, _T('\\')); if(0 == szModuleFileName) { szModuleFileName = _tcsrchr(szFullPathModuleName, _T('/')); } if(0 == szModuleFileName || 0 == dwPathLength) { szErrorMessage = _T("this:0x%p/Failed get module name."); } else { memcpy(szModulePath, szFullPathModuleName, szModuleFileName - szFullPathModuleName); szModulePath[szModuleFileName - szFullPathModuleName] = _T('\0'); ++szModuleFileName; HANDLE hBatFile = CreateFile(szTempBatPathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ; if (INVALID_HANDLE_VALUE == hBatFile) { szErrorMessage = _T("this:0x%p/Temp bat file create failed."); } else { DWORD dwLength = 0; unsigned long dwTempBatContentLen = _tcslen(szTempBatContent); unsigned long dwFullPathModuleNameLen = _tcslen(szFullPathModuleName); unsigned long dwTempPathFileLen = _tcslen(ClientDispatch.GetTempPatchFileName()); unsigned long dwModuleFileNameLen = _tcslen(szModuleFileName); unsigned long dwModulePathLen = _tcslen(szModulePath); TCHAR* szBatBuffer = new TCHAR[dwTempBatContentLen + dwFullPathModuleNameLen * 4 + dwTempPathFileLen + dwModuleFileNameLen + dwModulePathLen + MAX_PATH]; int nLength = _sntprintf(szBatBuffer, MAX_PATH * 10 - 1, szTempBatContent, szFullPathModuleName, // Áö¿ï ÆÄÀÏ À̸§ szFullPathModuleName, // ÆÄÀÏ Á¸Àç ¿©ºÎ üũ ClientDispatch.GetTempPatchFileName(), // Àӽà ÆÄÀÏ À̸§ szModuleFileName, // ¹Ù²ð À̸§ szFullPathModuleName, // ¹Ù²ï À̸§ szModulePath, // °æ·Î À̵¿ szFullPathModuleName); // ½ÇÇà if(0 < nLength) { if(!WriteFile(hBatFile, szBatBuffer, _tcslen(szBatBuffer), &dwLength, NULL)) { szErrorMessage = _T("this:0x%p/Temp bat file write content failed."); } } else { szErrorMessage = _T("this:0x%p/Temp bat file make content failed."); } CloseHandle(hBatFile); delete [] szBatBuffer; ShellExecute(NULL, _T("open"), szTempBatContent, NULL, NULL, SW_HIDE); } } } if(0 != szErrorMessage) { ERRLOG1(g_Log, szErrorMessage, this); } else { // ÆÐÄ¡ ¼º°ø. Á¾·á. DETLOG1(g_Log, "this:0x%p/Patch success. restart now.", this); PostMessage(GetWnd(), WM_DESTROY, 0, 0); } */ } bool CManageClient::ApplicationSpecificInit(const TCHAR* szCmdLine) { const TCHAR* szErrorMessage = 0; if(!InitializeMsgProc()) { szErrorMessage = _T("this:0x%p/InitializeMsgProc failed"); } else if(!InitializeCommand()) { szErrorMessage = _T("this:0x%p/InitializeCommand failed"); } else if(!AddProcessThread(new CManageClientProcessThread(*this))) { szErrorMessage = "this:0x%p/AddProcessThread failed"; } if(0 != szErrorMessage) { ERRLOG1(g_Log, szErrorMessage, this); return false; } CheckConnectionAndReconnect(); return true; } void CManageClient::PrintConnectionStatus() { const int MAX_BUFFER = 4096; char szBuffer[MAX_BUFFER]; char szFileName[MAX_PATH]; char szExtension[MAX_PATH]; INET_Addr& manageServerAddr = ManageSetup::ClientSetup::GetInstance().GetManageServerAddr(); GET_SINGLE_DISPATCH(lpManageClientDispatch, CManageClientDispatch, CManageClientDispatch::GetDispatchTable()); int nLength = _snprintf(szBuffer, MAX_BUFFER - 1, "ManageClient Console\r\n\r\nManageServer IP:%s, Port:%d %s\r\n\r\n", manageServerAddr.get_addr_string(), manageServerAddr.get_port_in(), (0 != lpManageClientDispatch) ? "Connected" : "Disconnected"); int nTotalLength = 0; if(0 < nLength) { if(0 != lpManageClientDispatch) { nTotalLength += nLength; CManageClientDispatch::RunTable& runTable = lpManageClientDispatch->GetRunTable(); CManageClientDispatch::RunTable::iterator pos = runTable.begin(); CManageClientDispatch::RunTable::iterator end = runTable.end(); for(; pos != end; ++pos) { const ServerManage::RunInfo& runInfo = pos->second.m_RunInfo; _splitpath(runInfo.m_szPath, 0, 0, szFileName, szExtension); nLength = _snprintf(szBuffer + nTotalLength, MAX_BUFFER - nTotalLength, "RunID:%5d / %s%s %s\r\n", runInfo.m_dwRunID, szFileName, szExtension, runInfo.m_szOption); if(0 < nLength) { nTotalLength += nLength; } } } if(0 < nTotalLength && nTotalLength < MAX_BUFFER) { szBuffer[nTotalLength] = 0; PrintInfo(szBuffer); } } }