#include "precompile.h" #include "sp_groupProcess.h" #include #include #ifdef _WIN32 #include //CreateToolhelp32Snapshot #include #endif //_WIN32 #include "toolkit.h" #include #include #include #define TAG SPBASE_TAG("sp_groupProcess") using namespace std; #define DEFAULT_WAITTIME 5000 #define OPERATE_SUCCESS "success" #define OPERATE_FAIL "fail" #define GUID_LEN 64 typedef enum { PIPE_PROCESS_START, PIPE_ENTITY_KILL, PIPE_PROCESS_QUERY, PIPE_PROCESS_KILL }PIPE_PROCESS_DO; map mapProcess; class groupLock { public: groupLock() { static bool isInit = false; if (!isInit) { InitializeCriticalSection(&cs_); isInit = true; } EnterCriticalSection(&cs_); } ~groupLock() { LeaveCriticalSection(&cs_); } private: groupLock(const groupLock&); groupLock& operator =(const groupLock&); private: static CRITICAL_SECTION cs_; }; CRITICAL_SECTION groupLock::cs_; int paramSplit(char* srcStr, char dstParam[10][MAX_PATH]) { char *split = " ", *p = NULL; int i = 0; if (NULL == srcStr || NULL == dstParam) return -1; p = strtok(srcStr, split); for (i = 0; p != NULL; i++) { strcpy(&(dstParam[i][0]), p); p = strtok(NULL,split); } return i; } int getNewGuid(char *guidBuffer) { GUID guid; if (CoCreateGuid(&guid)) return -1; _snprintf(guidBuffer, GUID_LEN, "%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); return 0; } /**return str with "group0_{mod_name}" or "group{group_id} if group is not zero or entityName is null"**/ string makeGroupMapName(int group, const char *entityName) { char tempGroupName[50] = ""; if (0 == group && NULL != entityName) sprintf_s(tempGroupName, sizeof(tempGroupName), "group%d_%s", group, entityName); else sprintf_s(tempGroupName, sizeof(tempGroupName), "group%d", group); return string(tempGroupName); } sp_process_t* findGroupProcessInfo(int group, const char *entityName) { groupLock curLock; map::iterator iter; iter = mapProcess.find(makeGroupMapName(group, entityName)); if (iter != mapProcess.end()) return iter->second; else return NULL; } int checkGroupProcesInfo(int group, const char *entityName) { sp_process_t* curProcess = findGroupProcessInfo(group, entityName); if (NULL == curProcess) return -1; if (process_exist_or_not(curProcess->pid)) { char szCmd[256]; sprintf_s(szCmd, 256, "TASKKILL /PID %d /F", curProcess->pid); WinExec(szCmd, SW_HIDE); RemoveGroupProcessInfo(group, entityName); return 0; } else { RemoveGroupProcessInfo(group, entityName); return -1; } } int AddGroupProcessInfo(int group, sp_process_t* curProcess, const char *entityName) { if (findGroupProcessInfo(group, entityName)) return -1; groupLock curLock; mapProcess.insert(map::value_type(makeGroupMapName(group, entityName), curProcess)); return 0; } int RemoveGroupProcessInfo(int group, const char *entityName) { sp_process_t *curProcess = findGroupProcessInfo(group, entityName); groupLock curLock; if (!curProcess) return -1; if (curProcess->read_pipe) CloseHandle(curProcess->read_pipe); if (curProcess->process_Handle) CloseHandle(curProcess->process_Handle); mapProcess.erase(makeGroupMapName(group, entityName)); free(curProcess); return 0; } int writePipe(const sp_process_t* curProcess, PIPE_PROCESS_DO code, const char *paramStr) { if (NULL == curProcess || NULL == curProcess->read_pipe || NULL == curProcess->write_pipe ) return -1; char writeBuf[1024] = ""; DWORD byteWrite = 0; switch(code) { case PIPE_PROCESS_START: sprintf_s(writeBuf, 1024, "start %s", paramStr); break; case PIPE_ENTITY_KILL: sprintf_s(writeBuf, 1024, "kill %s", paramStr); break; case PIPE_PROCESS_QUERY: sprintf_s(writeBuf, 1024, "query %s", paramStr); break; case PIPE_PROCESS_KILL: sprintf_s(writeBuf, 1024, "kill process"); break; default: return -1; } OVERLAPPED overlap = { 0 }; overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (!WriteFile(curProcess->write_pipe, (LPCVOID)writeBuf, strlen(writeBuf) + 1, &byteWrite, &overlap) || byteWrite != strlen(writeBuf) + 1) return -1; if (WAIT_OBJECT_0 == WaitForSingleObject(overlap.hEvent, 5000)) { CloseHandle(overlap.hEvent); return 0; } else return -1; return 0; } int readPipe(const sp_process_t *curProcess, char *dstStr, DWORD waitTime) { if (NULL == dstStr || NULL == curProcess) return -1; DWORD byteRead = 0; OVERLAPPED overlap = { 0 }; overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); UCHAR buffer[100] = { 0 }; DWORD dwRead = 0; ReadFile(curProcess->read_pipe, dstStr, MAX_PATH, &byteRead, &overlap); if (WAIT_OBJECT_0 == WaitForSingleObject(overlap.hEvent, waitTime)) { CloseHandle(overlap.hEvent); return 0; } return -1; } int startModByPipe(const sp_process_t* curProcess, char *paramStr) {//do writePipe and readPipe if (NULL == curProcess || NULL == paramStr) return -1; char dstStr[MAX_PATH] = ""; int result = 0; do { result = writePipe(curProcess, PIPE_PROCESS_START, paramStr); if (0 != result) { WLog_ERR(TAG, "writePipe failed! %d", result); break; } result = readPipe(curProcess, dstStr, DEFAULT_WAITTIME); if (0 != result) { WLog_ERR(TAG, "readPipe failed! %d", result); break; } if (!!strcmp(dstStr, OPERATE_SUCCESS)) { WLog_ERR(TAG, "readPipe returned: %s", dstStr); result = -1; break; } } while (false); return result; } #define PROCESS_WAITTIME 5000 int killModByPipe(const sp_process_t *curProcess, char *paramStr) { if (NULL == curProcess || NULL == paramStr) return -1; groupLock curLock; char dstStr[MAX_PATH] = ""; if (0 < curProcess->group) { if (0 == writePipe(curProcess, PIPE_ENTITY_KILL, paramStr) && 0 == readPipe(curProcess, dstStr, DEFAULT_WAITTIME) && !strcmp(dstStr, OPERATE_SUCCESS)) return 0; } else if (0 == curProcess->group) { if (0 == writePipe(curProcess, PIPE_PROCESS_KILL, paramStr) && WAIT_TIMEOUT != WaitForSingleObject(curProcess->process_Handle, PROCESS_WAITTIME)) { RemoveGroupProcessInfo(curProcess->group, paramStr); return 0; } } return -1; } int queryModByPipe(const sp_process_t* curProcess, const char *paramStr, char dstParam[10][MAX_PATH]) { if (NULL == curProcess || NULL == paramStr) return -1; char dstStr[MAX_PATH] = ""; if (0 == writePipe(curProcess, PIPE_PROCESS_QUERY, paramStr) && 0 == readPipe(curProcess, dstStr, DEFAULT_WAITTIME)) { int paramNum = paramSplit(dstStr, dstParam); if (-1 != paramNum && !strcmp(dstParam[0], OPERATE_SUCCESS)) return paramNum; } return -1; } void ClearGroupProcessInfo() { auto it = mapProcess.begin(); while (it != mapProcess.end()) { sp_process_t* t = it->second; if (t != NULL) { free(t); it->second = NULL; } mapProcess.erase(it); it = mapProcess.begin(); } }