#include "stdafx.h" #if defined(_MSC_VER) #include #include #include #include #include #include #include #include #include "XUnzip.h" //解压文件 #include #include #include #include #else #include "SogouVersion.h" #include #include #include #include "XUnZipZilb.h" #include #endif //_MSC_VER #include "array.h" #include "fileutil.h" #include "iniutil.h" #include "toolkit.h" #include "osutil.h" #include "publicFunExport.h" #include #include "SpUtility.h" #include #include "HealthManager_client_g.h" #include "CommEntityUtil.hpp" #include "mod_ResourceWatcher.h" #include "ResourceWatcher_UserCode.h" #ifdef RVC_OS_WIN #pragma comment(lib, "shell32.lib") #pragma comment(lib, "Wintrust.lib") #pragma comment(lib, "crypt32.lib") #pragma comment(lib, "Gdi32.lib") #pragma comment(lib, "User32.lib") #endif // RVC_OS_WIN using namespace HealthManager; #define SafeDeleteArraySize(pData) { if(pData){delete []pData;pData=NULL;} } void ResourceWatcherServiceSession::Handle_GetDevInfo( SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->GetDevInfo(ctx); } void ResourceWatcherServiceSession::Handle_BizLinkDetect(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->BizLinkDetect(ctx); } void ResourceWatcherServiceSession::Handle_CheckNetType(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->CheckNetType(ctx); } void ResourceWatcherServiceSession::Handle_GetBizLinks(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->GetBizLinks(ctx); } void ResourceWatcherServiceSession::Handle_GetThirdPartyInstallState(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->GetThirdPartyInstallState(ctx); } void ResourceWatcherServiceSession::Handle_InstallThirdPartyProgram(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->InstallThirdPartyProgram(ctx); } void ResourceWatcherServiceSession::Handle_UninstallThirdPartyProgram(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->UninstallThirdPartyProgram(ctx); } void ResourceWatcherServiceSession::Handle_RestartThirdPartyProgram(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->RestartThirdPartyProgram(ctx); } void ResourceWatcherServiceSession::Handle_ProcessDetectThirdPartyProgram(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->ProcessDetectThirdPartyProgram(ctx); } void ResourceWatcherServiceSession::Handle_FilesClean(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->FilesClean(ctx); } void ResourceWatcherServiceSession::Handle_FetchSystemSnapshot(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->FetchSystemSnapshot(ctx); } void ResourceWatcherServiceSession::Handle_OperateFile (SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->OperateFile(ctx); } struct SogouRunVersionInfo { CSimpleStringA strInstallDir; CSimpleStringA strVersion; SogouRunVersionInfo() :strInstallDir(true), strVersion(true) {} CSimpleStringA ToString() const { CSimpleStringA result(true); if (!strInstallDir.IsNullOrEmpty()) { result += strInstallDir; result += "#"; } if (!strVersion.IsNullOrEmpty()) { result += strVersion; } return result; } CVersion ConvertVersion() { CVersion installVer; DWORD dwMajor(0), dwMinor(0), dwRevision(0), dwBuild(0); int n = sscanf(strVersion.GetData(), "%d.%d.%d.%d", &dwMajor, &dwMinor, &dwRevision, &dwBuild); if (n != 4) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Not sogou version.[%s]", strVersion.GetData()); } else { installVer = CVersion(dwMajor, dwMinor, dwRevision, dwBuild); } return installVer; } //true: 普通调用版本输入法,false: SDK版本输入法 bool IsTSFVersion() { #if defined(_MSC_VER) CVersion standardVer = CVersion(2, 6, 1, 1967); //对比版本为2.6.1.1967 #else CVersion standardVer = CVersion(2, 6, 4, 355); //对比版本为2.4.6.355 #endif //_MSC_VER return (ConvertVersion() >= standardVer); } }; struct SogouInstallStateInfo { DWORD dwInstalledStatus; CSimpleStringA strInstallDate; SogouInstallStateInfo() :dwInstalledStatus(-1), strInstallDate(true) {} CSimpleStringA ToString() const { CSimpleStringA result(true); if (!strInstallDate.IsNullOrEmpty()) { result += GetInstallTime().ToTimeString().GetData(); result += "#"; } result += CSimpleStringA::Format("%u", dwInstalledStatus); return result; } CSmallDateTime GetInstallTime() const { if (!strInstallDate.IsNullOrEmpty()) { DWORD dwSecsSince1970(0); sscanf_s(strInstallDate.GetData(), "%u", &dwSecsSince1970); dwSecsSince1970 -= 946656000; // 2000-1970 return CSmallDateTime(dwSecsSince1970); } return CSmallDateTime::BeginTime; } }; struct SogouInstallInfo { SogouInstallStateInfo state; SogouRunVersionInfo program; CSimpleStringA Stringfy() const { return (state.ToString() + "||" + program.ToString()); } bool IsInstalledSuccess() const { return (state.dwInstalledStatus == 0); } }; #if defined(RVC_OS_LINUX) std::string TryToGetSogouVersionEx() { std::string succStr, errStr; std::string runStr("cat /opt/sogouimebs/files/share/sogou-version"); if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) { if (succStr.empty()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cat sogou version return empty!"); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("cat sogou version returned: %s", succStr.c_str()); return succStr; } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("execute cmd failed: %s", errStr.c_str()); } return ""; } #else static inline bool Is64BitPlatform() { SYSTEM_INFO si; GetNativeSystemInfo(&si); return (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64); } static int Is32R64Platform() { static int isWow64 = -1; typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); if (isWow64 == -1) { BOOL bIsWow64 = FALSE; LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process"); if (NULL != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("detect is running with 64bit or not failed: %u", GetLastError()); return -1; } else { isWow64 = bIsWow64 ? 1 : 0; } } } return isWow64; } static bool GetRegistValue(HKEY hKey, LPCTSTR lpcszParam, DWORD* pDwValue, CHAR* pSzValue, const DWORD* pDwSizeOfSz) { if (pDwValue != NULL) { DWORD dwType = REG_DWORD; DWORD dwValue = 0; DWORD dwSize = sizeof(DWORD); LONG lResult = RegQueryValueExA(hKey, lpcszParam, NULL, &dwType, (LPBYTE)&dwValue, &dwSize); if (lResult == ERROR_SUCCESS) { *pDwValue = dwValue; return true; } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("RegQueryValueEx for \"%s\" error, result=%ld.", lpcszParam, lResult); return false; } } else if (pSzValue != NULL) { DWORD dwType = REG_SZ; DWORD dwSize = MAX_PATH * sizeof(CHAR); TCHAR szValue[MAX_PATH + 1] = { 0 }; LONG lResult = RegQueryValueEx(hKey, lpcszParam, NULL, &dwType, (LPBYTE)szValue, &dwSize); if (lResult == ERROR_SUCCESS) { strcpy_s(pSzValue, *pDwSizeOfSz, szValue); return true; } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("RegQueryValueEx for \"InstallTime\" error, result=%ld.", lResult); return false; } } return false; } static LONG GetSogouInstallState(SogouInstallStateInfo& info) { HKEY hKey; LONG lResult = -1; DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS; lResult = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\SogouPCIme", 0, dwFlag, &hKey); if (lResult == ERROR_SUCCESS) { DWORD dwValue = (DWORD)-1; const bool res1 = GetRegistValue(hKey, "InstallFlag", &dwValue, NULL, NULL); if (res1) { info.dwInstalledStatus = dwValue; } TCHAR szValue[MAX_PATH + 1] = { 0 }; DWORD dwLength = MAX_PATH; //1970 0x83AA7E80 const bool res2 = GetRegistValue(hKey, "InstallTime", NULL, szValue, &dwLength); if (res2) { info.strInstallDate = szValue; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("InstallTime: %s", info.GetInstallTime().ToTimeString().GetData()); } if (res1 && res2) { lResult = 0; } else { lResult = -1; } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("%s::RegOpenKeyEx error, Result=%ld.", __FUNCTION__, lResult); } RegCloseKey(hKey); return lResult; } static LONG GetSogouExecuteInfo(SogouRunVersionInfo& info, BOOL f32bit = TRUE) { HKEY hKey; LONG lResult = -1; PVOID oldValue = NULL; Wow64DisableWow64FsRedirection(&oldValue); DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS; lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, f32bit ? "SOFTWARE\\SogouPCIme" : "SOFTWARE\\WOW6432Node\\SogouPCIme", 0, dwFlag, &hKey); if (lResult == ERROR_SUCCESS) { TCHAR szVersion[MAX_PATH + 1] = { 0 }, szDefault[MAX_PATH + 1] = { 0 }; DWORD dwLength = MAX_PATH; const bool res1 = GetRegistValue(hKey, "Version", NULL, szVersion, &dwLength); if (res1) info.strVersion = szVersion; const bool res2 = GetRegistValue(hKey, "", NULL, szDefault, &dwLength); if (res2) info.strInstallDir = szDefault; if (res1 && res2) { lResult = 0; } else { lResult = -1; } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("%s::RegOpenKeyEx(32bit=%d) error, Result=%ld.", __FUNCTION__, f32bit, lResult); } RegCloseKey(hKey); Wow64RevertWow64FsRedirection(oldValue); return lResult; } #endif //RVC_OS_LINUX ErrorCodeEnum GetSogouInstallInfo(SogouInstallInfo& info) { #if defined(RVC_OS_LINUX) info.state.dwInstalledStatus = Sogou_GetInstallStatus(); info.state.strInstallDate = Sogou_GetInstallTime(); info.program.strInstallDir = Sogou_GetInstallPath(); info.program.strVersion = Sogou_GetVersion(); if (info.program.strVersion.IsNullOrEmpty()) { info.program.strVersion = TryToGetSogouVersionEx().c_str(); } const int maxTimes = 3; int curTimes = 0; while (info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) { Sleep(1000); info.program.strVersion = Sogou_GetVersion(); if (info.program.strVersion.IsNullOrEmpty()) { info.program.strVersion = TryToGetSogouVersionEx().c_str(); } curTimes++; } #else GetSogouInstallState(info.state); BOOL is32Bit = Is64BitPlatform() ? FALSE : TRUE; if (ERROR_FILE_NOT_FOUND == GetSogouExecuteInfo(info.program, is32Bit)) GetSogouExecuteInfo(info.program, !is32Bit); #endif //RVC_OS_LINUX DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d, %s, %s, %s" , info.state.dwInstalledStatus, info.state.strInstallDate.GetData() , info.program.strInstallDir.GetData(), info.program.strVersion.GetData()); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData()); return info.IsInstalledSuccess() ? Error_Succeed : Error_InvalidState; } ErrorCodeEnum SetFileExecutePriviledge(LPCTSTR lpcszDirOrFilePath) { #if defined(RVC_OS_WIN) ErrorCodeEnum result(Error_NotSupport); #else ErrorCodeEnum result(Error_Succeed); if (ExistsDirA(lpcszDirOrFilePath)) { do { array_header_t* subs; subs = fileutil_get_sub_dirs_a(lpcszDirOrFilePath); if (subs) { for (int i = 0; i < subs->nelts; ++i) { char* dir = ARRAY_IDX(subs, i, char*); const char* dirname = &dir[strlen(lpcszDirOrFilePath) + 1]; ErrorCodeEnum tmpResult = SetFileExecutePriviledge(dir); if (tmpResult != Error_Succeed) { toolkit_array_free2(subs); return tmpResult; } } } } while (false); do { array_header_t* subs; subs = fileutil_get_sub_files_a(lpcszDirOrFilePath); if (subs) { for (int i = 0; i < subs->nelts; ++i) { char* path = ARRAY_IDX(subs, i, char*); mode_t f_attrib = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH; if (chmod(path, f_attrib) != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("chmod file priviledge failed, %s, %d", path, errno); toolkit_array_free2(subs); return Error_Unexpect; } } toolkit_array_free2(subs); } } while (false); } else if (ExistsFileA(lpcszDirOrFilePath)) { mode_t f_attrib = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH; if (chmod(lpcszDirOrFilePath, f_attrib) != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("chmod file priviledge failed, %s, %d", lpcszDirOrFilePath, errno); return Error_Unexpect; } } else { result = Error_InvalidState; } #endif //RVC_OS_WIN return result; } void ResourceWatcherEntity::InstallThirdPartyProgram(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_USER)("ctx-req context: %d, %d, %d", ctx->Req.type, ctx->Req.reserved1, ctx->Req.reserved2); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_INSTALL_THIRDPARTY, CSimpleStringA::Format("InstallThirdPartyProgram: ctx-req context: %d, %d, %d", ctx->Req.type, ctx->Req.reserved1, ctx->Req.reserved2)); bool sogouInstalled = false; const bool doTryRestart = (ctx->Req.reserved1 != 1); if (ctx->Req.type == 1) { //安装搜狗输入法 CSmartPointer sogouInstall = new InstallSogouTask(this); sogouInstall->ctx = ctx; GetFunction()->PostThreadPoolTask(sogouInstall.GetRawPointer()); return; } else if (ctx->Req.type == 2) {//安装花了钱的字体 #if defined(RVC_OS_WIN) tmpResult = Error_NotSupport; #else CSimpleStringA strAdDataDirPath(true); tmpResult = GetFunction()->GetPath("Ad", strAdDataDirPath); if (strAdDataDirPath.IsNullOrEmpty()) { strAdDataDirPath = "/opt/rvc/adData"; } if (strAdDataDirPath.IsNullOrEmpty()) { tmpResult = Error_Unexpect; tmpMsg = "获取安装包路径Ad失败"; } else { CSimpleStringA strInstallPkgPath = strAdDataDirPath + SPLIT_SLASH_STR "HYQiHei"; if (!ExistsDirA(strInstallPkgPath)) { tmpMsg = CSimpleStringA::Format("%s 文件夹不存在", strInstallPkgPath.GetData()); tmpResult = Error_NotExist; } else { CSimpleStringA strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini"; if (ExistsFileA(strRunIniFilePath)) { char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", ""); CSimpleStringA strInstallScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + p); toolkit_free(p); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RunScript file: %s", strInstallScriptFile.GetData()); if (ExistsFileA(strInstallScriptFile)) { do { char app[MAX_PATH] = { '\0' }; tk_process_t* process = NULL; tk_process_option_t option; option.exit_cb = NULL; option.file = NULL; option.flags = 0; sprintf(app, "bash %s", strInstallScriptFile.GetData()); option.params = app; const int res = process_spawn(&option, &process); if (0 == res) { FREE(process); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("execute {%s} suc", strInstallScriptFile.GetData()); } else { tmpMsg = CSimpleStringA::Format("执行 %s 失败:%s", strInstallScriptFile.GetData(), toolkit_strerror(res)); tmpResult = Error_Process; } } while (false); } else { tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData()); tmpResult = Error_NotExist; } } else { tmpMsg = CSimpleStringA::Format("%s 文件不存在", strRunIniFilePath.GetData()); tmpResult = Error_NotExist; } } } if (tmpResult == Error_Succeed) { ///**TODO(Gifur@10/21/2021): 二次校验 */ } #endif //RVC_OS_WIN } else { result = Error_NotSupport; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM) ("用户桌面安装:%s. result:%d.", tmpMsg.GetData(), tmpResult); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_INSTALL_THIRDPARTY, CSimpleStringA::Format("用户桌面安装:%s. result:%d.", tmpMsg.GetData(), tmpResult)); ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(result); return; } void ResourceWatcherEntity::UninstallSogou(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("to uninstall sogou input..."); #if defined(RVC_OS_LINUX) CSimpleStringA strUninstallScriptFile(true); SogouInstallInfo info; do { ErrorCodeEnum ecGet = GetSogouInstallInfo(info); if (info.program.IsTSFVersion()) { CSimpleStringA shellScriptPath; GetFunction()->GetPath("Base", shellScriptPath); shellScriptPath += SPLIT_SLASH_STR; shellScriptPath += "res" SPLIT_SLASH_STR "RunScript" SPLIT_SLASH_STR; strUninstallScriptFile = shellScriptPath + "uninstall_tfs_sogouimebs.sh"; if (!ExistsFileA(strUninstallScriptFile)) { tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strUninstallScriptFile.GetData()); tmpResult = Error_InvalidState; break; } char app[MAX_PATH] = { '\0' }; sprintf(app, "bash %s", strUninstallScriptFile.GetData()); tmpResult = RunShellScript(app); if (tmpResult != 0) { tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app); } else { Sleep(300); } } else { CSimpleStringA strInstallPkgPath; tmpResult = GetSogouPkgDirPath(strInstallPkgPath); if (tmpResult == Error_Succeed) { tmpResult = SetFileExecutePriviledge(strInstallPkgPath); if (tmpResult != Error_Succeed) { tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData()); tmpResult = Error_NoPrivilege; break; } const CSimpleStringA strShutdownScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "shutdown_service.sh"; strUninstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "uninstall_sogouime.sh"; if (!ExistsFileA(strShutdownScriptFile)) { tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strShutdownScriptFile.GetData()); tmpResult = Error_InvalidState; break; } if (!ExistsFileA(strUninstallScriptFile)) { tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strUninstallScriptFile.GetData()); tmpResult = Error_InvalidState; break; } char app[MAX_PATH] = { '\0' }; sprintf(app, "bash %s", strShutdownScriptFile.GetData()); tmpResult = RunShellScript(app); if (tmpResult != 0) { tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app); } else { Sleep(300); sprintf(app, "bash %s", strUninstallScriptFile.GetData()); tmpResult = RunShellScript(app); if (tmpResult != 0) { tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app); } else { Sleep(100); } } } else { tmpMsg = CSimpleStringA::Format(" 指定位置 [Ad] 找不到输入法安装包"); tmpResult = Error_InvalidState; break; } } } while (false); #else SogouInstallInfo info; GetSogouInstallInfo(info); CSimpleStringA uninPath = info.program.strInstallDir + "\\" + info.program.strVersion + "\\Uninstall.exe"; int startFlag = WinExec(uninPath.GetData(), SW_SHOWNORMAL); if (startFlag > 31) { tmpMsg = CSimpleStringA::Format("已执行搜狗卸载程序!路径:%s。", uninPath.GetData()); } else { tmpMsg = CSimpleStringA::Format("执行搜狗卸载程序异常!路径:%s。", uninPath.GetData()); tmpResult = Error_Unexpect; } #endif //RVC_OS_LINUX ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(result); } void ResourceWatcherEntity::UninstallThirdPartyProgram(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_UNINSTALL_THIRDPARTYPROGRAM, CSimpleStringA::Format("UninstallThirdPartyProgram: ctx-req context: %d, %d, %d", ctx->Req.type, ctx->Req.reserved1, ctx->Req.reserved2)); if (ctx->Req.type == 1) { //卸载搜狗输入法 #if defined(RVC_OS_LINUX) UninstallSogouTask* sogouUninstall = new UninstallSogouTask(this); sogouUninstall->ctx = ctx; GetFunction()->PostThreadPoolTask(sogouUninstall); return; #else UninstallSogou(ctx); #endif //RVC_OS_LINUX } else { tmpMsg = CSimpleStringA::Format("接口调用参数错误"); result = Error_NotSupport; } ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(result); return; } void ResourceWatcherEntity::RestartThirdPartyProgram(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_RESTART_THIRDPARTYPROGRAM, CSimpleStringA::Format("RestartThirdPartyProgram: ctx-req context: %d, %d, %d", ctx->Req.type, ctx->Req.reserved1, ctx->Req.reserved2)); if (ctx->Req.type == 1) { SogouInstallInfo info; GetSogouInstallInfo(info); if (!info.program.IsTSFVersion()) { //重启搜狗输入法 #if defined(RVC_OS_WIN) CSimpleStringA csBinPath; ErrorCodeEnum eErrPath = GetFunction()->GetPath("Bin", csBinPath); CSimpleStringA startPath = csBinPath + "\\spScript\\SogouServStarter.bat"; if (eErrPath != Error_Succeed) { tmpResult = Error_NotExist; tmpMsg = "获取重启脚本路径失败。"; } else if (!ExistsFileA(startPath)) { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("搜狗重启脚本不存在。"); } else { CAutoArray pName(2); pName[0] = "SogouImeMon.exe"; pName[1] = "SogouImeWebSrv.exe"; if (!KillProcessFromName(pName[0]) || !KillProcessFromName(pName[1])) { tmpMsg = CSimpleStringA::Format("杀死当前搜狗进程失败。"); tmpResult = Error_Unexpect; } else { STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = TRUE; char* cmdline = const_cast(startPath.GetData()); BOOL bRet = ::CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); WaitForSingleObject(pi.hProcess, INFINITE); std::string res = DoCheckCertainProcessStatus(pName); if (res.size() > 0) { tmpMsg = CSimpleStringA::Format("已成功重启搜狗输入法进程!路径:%s。", startPath.GetData()); } else { tmpMsg = CSimpleStringA::Format("重启搜狗进程失败!路径:%s。", startPath.GetData()); tmpResult = Error_Unexpect; } } } #else static int old_process_id[2] = { -1, -1 }; char* relate_processes[2] = { "sogouImeWebSrv", "sogouImeService" }; int count = 3; alive_process_info processes[3]; memset(processes, 0, sizeof(processes)); osutil_detect_unique_app(relate_processes, array_size(relate_processes), &count, processes); CAutoArray msgs(array_size(relate_processes)); int cnt(0); for (int i = 0; i < array_size(relate_processes); ++i) { int k = -1; for (int j = 0; j < count; ++j) { if (strcmp(processes[j].name, relate_processes[i]) == 0) { k = j; break; } } if (k != -1) { cnt++; old_process_id[k] = processes[k].pid; std::string sucContent, failedContent; CSimpleStringA strCmd = CSimpleStringA::Format("kill -9 %d", old_process_id[k]); bool ret = SP::Module::Util::ShellExecute(strCmd.GetData(), sucContent, failedContent); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("{%s}:{%s}{%s}", strCmd.GetData(), sucContent.c_str(), failedContent.c_str()); } } int cnt2(0); if (cnt > 0) { ///**TODO(Gifur@7/5/2022): 待优化处理 */ Sleep(2000); int newCount = 3; int notSame = 0; vector tKillmsg; alive_process_info newProcesses[3]; memset(newProcesses, 0, sizeof(newProcesses)); osutil_detect_unique_app(relate_processes, array_size(relate_processes), &newCount, newProcesses); for (int i = 0; i < array_size(relate_processes); ++i) { int k = -1; for (int j = 0; j < count; ++j) { if (strcmp(newProcesses[j].name, relate_processes[i]) == 0 && newProcesses[j].pid > 0) { k = j; break; } } if (k != -1) { cnt2++; if (newProcesses[k].pid != old_process_id[k]) { notSame++; } else { tmpResult = Error_Unexpect; CSimpleStringA tmsg = CSimpleStringA::Format("{杀死当前搜狗进程[%s]失败,pid[%d]。}", newProcesses[k].name, newProcesses[k].pid); tKillmsg.push_back(tmsg); } } } if (cnt2 == 0) { tmpMsg = "已杀死搜狗进程。但重启搜狗进程失败,请确认守护进程正常运行。"; tmpResult = Error_Unexpect; } else { if (tKillmsg.size() != 0) { for (int i = 0; i < tKillmsg.size(); ++i) { tmpMsg += tKillmsg[i]; } } else { tmpMsg = "已成功重启搜狗输入法进程。"; } } } else { tmpMsg = "当前系统无搜狗进程,请确认已安装搜狗输入法,并重启计算机以尝试启动搜狗输入法!"; tmpResult = Error_Unexpect; } #endif //RVC_OS_WIN } else { tmpResult = Error_NotSupport; tmpMsg = CSimpleStringA::Format("新搜狗版本,不支持重启功能"); } } else { tmpResult = Error_Param; tmpMsg = CSimpleStringA::Format("接口调用参数错误。"); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM) ("用户桌面重启:%s. result:%d.", tmpMsg.GetData(), tmpResult); LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_RESTART_THIRDPARTYPROGRAM, CSimpleStringA::Format("用户桌面重启:%s. result:%d.", tmpMsg.GetData(), tmpResult)); ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(result); return; } void ResourceWatcherEntity::ProcessDetectThirdPartyProgram(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); std::string res(""); if (ctx->Req.type == 1) {//检测搜狗输入法进程 CAutoArray pName(2); #if defined(RVC_OS_WIN) pName[0] = "SogouImeMon.exe"; pName[1] = "SogouImeWebSrv.exe"; #else pName[0] = "sogouImeWebSrv"; pName[1] = "sogouImeService"; #endif //RVC_OS_WIN res = DoCheckCertainProcessStatus(pName); if (res.length() == 0) { tmpResult = Error_Failed; tmpMsg = "当前系统无搜狗进程"; } else { tmpMsg = CSimpleStringA::Format("%s", res.c_str()); } } ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(result); return; } ErrorCodeEnum ResourceWatcherEntity::ReportSogouInstallState() { CSmartPointer spFunction = GetFunction(); CSmartPointer spConfig; ErrorCodeEnum err = spFunction->OpenConfig(Config_Run, spConfig); BOOL fNeedAlarm = TRUE; SogouInstallInfo info; GetSogouInstallInfo(info); CSimpleStringA strLastRecord(true); err = spConfig->ReadConfigValue("SogouInput", "LastInstalledRecord", strLastRecord); if (strLastRecord.IsNullOrEmpty() || info.Stringfy().Compare(strLastRecord) != 0) { spConfig->WriteConfigValue("SogouInput", "LastInstalledRecord", info.Stringfy()); fNeedAlarm = TRUE; } else { //Report info per day. int nLastRecordTime = 0; err = spConfig->ReadConfigValueInt("SogouInput", "LastReportTime", nLastRecordTime); SYSTEMTIME stTaskTime = CSmallDateTime(nLastRecordTime).ToSystemTime(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Last Sogou install check time: %04d-%02d-%02d %02d:%02d:%02d", stTaskTime.wYear, stTaskTime.wMonth, stTaskTime.wDay, stTaskTime.wHour, stTaskTime.wMinute, stTaskTime.wSecond); SYSTEMTIME stNow = {}; GetLocalTime(&stNow); if (nLastRecordTime > 0 && stTaskTime.wYear == stNow.wYear && stTaskTime.wMonth == stNow.wMonth && stTaskTime.wDay == stNow.wDay) { //The Same Day fNeedAlarm = FALSE; } else { fNeedAlarm = TRUE; } } if (fNeedAlarm) { const DWORD dwUserCode = info.IsInstalledSuccess() ? LOG_ERR_SOGOU_INPUT_INSTALLED : LOG_ERR_SOGOU_INPUT_NOTINSTALLED; LogWarn(Severity_Low, Error_DataCheck, dwUserCode, info.Stringfy()); //json上送,方便业务组解析 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("SogouVerStatus")("{\"install\":%d,\"program\":\"%s\",\"version\":\"%s\",\"installTime\":\"%s\"}", info.state.dwInstalledStatus, info.program.strInstallDir.GetData(), info.program.strVersion.GetData(), info.state.GetInstallTime().ToTimeString().GetData()); spConfig->WriteConfigValue("SogouInput", "LastReportTime", CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); } return Error_Succeed; } #if defined(RVC_OS_LINUX) /** No use for now [Gifur@2023109]*/ std::vector ResourceWatcherEntity::GetUserNameList(bool bExcludeRoot) { std::vector results; array_header_t* arr; arr = fileutil_get_sub_dirs_a("/home"); if (arr) { int i; for (i = 0; i < arr->nelts; ++i) { char szDestSubDir[256] = { 0 }; char* dir = ARRAY_IDX(arr, i, char*); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("sub dir: %s", dir); strcpy(szDestSubDir, dir); strcat(szDestSubDir, SPLIT_SLASH_STR); strcat(szDestSubDir, ".config/kwinrc"); if (ExistsFileA(szDestSubDir)) { std::string strUserName((const char*)&dir[strlen("/home/")]); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("username:%s", strUserName.c_str()); if (strUserName.compare("root") != 0 || !bExcludeRoot) { results.push_back(strUserName); } } } toolkit_array_free2(arr); } return results; } #else void ResourceWatcherEntity::ReadFileContent() { vector msg; CSmartPointer spCtSettingConfig; GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); int fileCnt = 0; CSimpleStringA info(""); do { fileCnt++; CSimpleStringA getFilename = CSimpleStringA::Format("ReadFileContentPath%d", fileCnt); CSimpleStringA path(""), part(""), key(""); spCtSettingConfig->ReadConfigValue("ResourceWatcher", getFilename.GetData(), info); if (info.GetLength() == 0) { break; } CAutoArray arr = info.Split('|'); int len = arr.GetCount(); if (len != 3) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Wrong ReadFile path config."); break; } path = arr[0]; part = arr[1]; key = arr[2]; char szValue[MAX_PATH + 1] = _T(""); long vLength = GetPrivateProfileString(part.GetData(), key.GetData(), "", szValue, 1024, path.GetData()); CSimpleStringA tMsg = CSimpleStringA::Format("Read file [%s], Part = [%s], [%s] = [%s]", path.GetData(), part.GetData(), key.GetData(), szValue); msg.push_back(tMsg); } while (info.GetLength() != 0); if (msg.size() != 0) { CSimpleStringA fRes("|"); for (int i = 0; i < msg.size(); ++i) { fRes = fRes + msg[i] + "|"; } LogWarn(Severity_Low, Error_Debug, LOG_WARN_GET_FILE_CONTENT, fRes.GetData()); } } long long GetDirSize(string dirPath) { long long fileLen = 0; long hFile = 0; //文件信息 struct _finddata_t fileinfo; string p; if ((hFile = _findfirst(p.assign(dirPath).append("\\*").c_str(), &fileinfo)) != -1) { do { //如果是目录,迭代之 //如果不是,加入列表 if ((fileinfo.attrib & _A_SUBDIR)) { if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) fileLen += GetDirSize(p.assign(dirPath).append("\\").append(fileinfo.name)); } else { fileLen += fileinfo.size; } } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); } return fileLen; } void ResourceWatcherEntity::ReadFileInfo() { //读取文件大小 修改时间 vector msg; CSmartPointer spCtSettingConfig; GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); CSimpleStringA path(""); int fileCnt = 0; do { fileCnt++; CSimpleStringA getFilename = CSimpleStringA::Format("ReadFileInfoPath%d", fileCnt); spCtSettingConfig->ReadConfigValue("ResourceWatcher", getFilename.GetData(), path); if (path.GetLength() == 0) { break; } time_t lCreateTime, lModifyTime; long long lFileLen; struct _finddata_t fileinfo;//文件信息读取结构 long hFile = -1; hFile = _findfirst(path.GetData(), &fileinfo); if (hFile == -1) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Get path [%s] file info failed.", path.GetData()); continue; } _findclose(hFile); lCreateTime = fileinfo.time_create; lModifyTime = fileinfo.time_write; if ((fileinfo.attrib & _A_SUBDIR)) { lFileLen = GetDirSize(string(path.GetData())); } else { lFileLen = fileinfo.size; } CSimpleStringA resLen = CSimpleStringA::Format("%lld B", lFileLen); if (lFileLen >= 1024 && lFileLen < (1024 * 1024)) { DOUBLE len = (DOUBLE)lFileLen / 1024; resLen = CSimpleStringA::Format("%.2f KB", len); } else if (lFileLen >= (1024 * 1024) && lFileLen < (1024 * 1024 * 1024)) { DOUBLE len = (DOUBLE)lFileLen / (1024 * 1024); resLen = CSimpleStringA::Format("%.2f MB", len); } else if (lFileLen >= (1024 * 1024 * 1024)) { DOUBLE len = (DOUBLE)lFileLen / (1024 * 1024 * 1024); resLen = CSimpleStringA::Format("%.2f GB", len); } tm* localCreate, * localWrite; //本地时间 char bufCreate[128] = { 0 }; char bufWrite[128] = { 0 }; //所有的localtime返回的指针指向同一个static变量,非线程安全,后续的localtime结果会覆盖之前的 localCreate = localtime(&lCreateTime); //转为本地时间 strftime(bufCreate, 64, "%Y-%m-%d %H:%M:%S", localCreate); localWrite = localtime(&lModifyTime); strftime(bufWrite, 64, "%Y-%m-%d %H:%M:%S", localWrite); CSimpleStringA tMsg = CSimpleStringA::Format("文件[%s], 大小[%s], 创建时间 [%s], 最近修改时间[%s]", path.GetData(), resLen.GetData(), bufCreate, bufWrite); msg.push_back(tMsg); } while (path.GetLength() != 0); if (msg.size() > 0) { CSimpleStringA fRes("|"); for (int i = 0; i < msg.size(); i++) { fRes = fRes + msg[i] + "|"; } LogWarn(Severity_Low, Error_Debug, LOG_WARN_READ_FILE_INFO, fRes.GetData()); } return; } void ResourceWatcherEntity::ChcekDiskFileSpace() { CSimpleStringA path = "D:"; long long fileLen = 0; long hFile = 0; //文件信息 struct _finddata_t fileinfo; string p; if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1) { do { //如果是目录,迭代之 //如果不是,加入列表 if ((fileinfo.attrib & _A_SUBDIR)) { if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) fileLen = GetDirSize(p.assign(path).append("\\").append(fileinfo.name)); } else { fileLen = fileinfo.size; } CSimpleStringA resLen = CSimpleStringA::Format("%lld B", fileLen); if (fileLen >= 1024 && fileLen < (1024 * 1024)) { DOUBLE len = (DOUBLE)fileLen / 1024; resLen = CSimpleStringA::Format("%.2f KB", len); } else if (fileLen >= (1024 * 1024) && fileLen < (1024 * 1024 * 1024)) { DOUBLE len = (DOUBLE)fileLen / (1024 * 1024); resLen = CSimpleStringA::Format("%.2f MB", len); } else if (fileLen >= (1024 * 1024 * 1024)) { DOUBLE len = (DOUBLE)fileLen / (1024 * 1024 * 1024); resLen = CSimpleStringA::Format("%.2f GB", len); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("[%s] 大小为 [%s]", p.assign(path).append("\\").append(fileinfo.name).c_str(), resLen.GetData()); } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); } } BOOL ResourceWatcherEntity::KillProcessFromName(const CSimpleStringA& strProcessName) { #if defined(RVC_OS_WIN) //创建进程快照(TH32CS_SNAPPROCESS表示创建所有进程的快照) HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnapShot, &pe)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("获取进程快照失败。"); return FALSE; } while (Process32Next(hSnapShot, &pe)) { //pe.szExeFile获取当前进程的可执行文件名称 CSimpleStringA scTmp = pe.szExeFile; if (!scTmp.Compare(strProcessName)) { DWORD dwProcessID = pe.th32ProcessID; HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID); BOOL killed = ::TerminateProcess(hProcess, 0); CloseHandle(hProcess); if (killed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("SUCCESS! Kill process [%s], pid [%d].", strProcessName.GetData(), dwProcessID); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("FAILED! Kill process [%s], pid [%d].", strProcessName.GetData(), dwProcessID); } return killed; } } return TRUE; #else DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("It's not supported %s", __FUNCTION__); return FALSE; #endif //RVC_OS_WIN } #endif //RVC_OS_LINUX void ResourceWatcherEntity::DoCheckSogouProcessStatus() { #if defined(RVC_OS_WIN) if (lastUpgradeInstallTime != 0 && lastUpgradeSwitchTime != 0 && lastUpgradeInstallTime < lastUpgradeSwitchTime) //完整记录了上一次升级的时间 { if (sogouChangeTime.size() != 0) { for (int i = 0; i < sogouChangeWarn.size(); i++) { if (newestSogouInstall) //搜狗升级 { //正常不用告警 /* LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, (sogouChangeWarn[i] + "搜狗升级切换1").GetData()); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040250A01Z102")("搜狗升级切换1");*/ } else //非搜狗升级导致的退出 { LogWarn(Severity_Middle, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, (sogouChangeWarn[i] + "异常切换1").GetData()); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040250A01Z103").setResultCode("RTA5A08")("搜狗异常切换1"); } } sogouChangeTime.clear(); sogouChangeWarn.clear(); lastUpgradeInstallTime = 0; lastUpgradeSwitchTime = 0; newestSogouInstall = false; return; } } bool fCheck = false; CAutoArray pName(2); pName[0] = "SogouImeMon.exe"; pName[1] = "SogouImeWebSrv.exe"; int pSize = pName.GetCount(); static int old_process_id[2] = { -1, -1 }; static int firstCheck[2] = { -1, -1 }; CAutoArray msgs; for (int i = 0; i < pSize; ++i) { /*old_process_id.push_back(-1);*/ CSimpleStringA temp(""); msgs.Append(&temp, 0, 1); } int cnt(0); PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); //获得系统进程快照的句柄 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("CreateToolhelp32Snapshot error."); return; } for (int i = 0; i < pSize; ++i) { int position = -1; BOOL bProcess = Process32First(hProcessSnap, &pe32); while (bProcess) { if (strcmp(pe32.szExeFile, pName[i].GetData()) == 0) { position = 1; break; } bProcess = Process32Next(hProcessSnap, &pe32); } if (position != -1 && old_process_id[i] == -1) { if (firstCheck[i] == -1) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Sougou first check!"); msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"pid\":%d}" , pName[i].GetData(), pe32.th32ProcessID); firstCheck[i] = 1; fCheck = true; sogouProcessRun = 1; } old_process_id[i] = pe32.th32ProcessID; } else if (position != -1 && (pe32.th32ProcessID != old_process_id[i])) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , pName[i].GetData(), old_process_id[i], pe32.th32ProcessID); old_process_id[i] = pe32.th32ProcessID; } else if (position == -1 && old_process_id[i] > 0) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , pName[i].GetData(), old_process_id[i], 0); old_process_id[i] = 0; } } std::string uploadInfo(""); if (cnt > 0) { if (cnt > 1) { uploadInfo = "{"; } for (int i = 0; i < cnt; ++i) { if (i != 0) { uploadInfo += ","; } uploadInfo += msgs[i].GetData(); } if (cnt > 1) { uploadInfo += "}"; } if (fCheck) //首次检测 { LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_FIRSTCHECK, uploadInfo.c_str()); //第一次检测 lastUpgradeInstallTime = 0; lastUpgradeSwitchTime = 0; newestSogouInstall = false; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040250A01Z101")("搜狗首次检测"); } else if (newestSogouInstall) { //LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, (uploadInfo + "搜狗升级切换2").c_str()); //升级安装导致的进程切换视为正常退出 lastUpgradeInstallTime = 0; lastUpgradeSwitchTime = 0; newestSogouInstall = false; //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040250A01Z102")("搜狗升级切换2"); } else if (time(0) <= lastSogouChangeEndTime) //lastSogouChangeEndTime为状态'I'结束后的60秒 { //LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, (uploadInfo + "搜狗升级切换3").c_str()); //升级安装导致的进程切换视为正常退出 lastUpgradeInstallTime = 0; lastUpgradeSwitchTime = 0; newestSogouInstall = false; //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040250A01Z102")("搜狗升级切换3"); } else { if (lastUpgradeInstallTime == 0 && lastUpgradeSwitchTime == 0)//非升级时段 { LogWarn(Severity_Middle, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, (uploadInfo + "异常切换3").c_str()); //其他情况下的进程切换视为异常退出 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_USER).setLogCode("QLR040250A01Z103").setResultCode("RTA5A08")("搜狗异常切换3"); } else //升级时段,'I'安装中,但是还没有'S'切换时,出现了搜狗进程切换 { sogouChangeWarn.push_back(CSimpleStringA(uploadInfo.c_str())); sogouChangeTime.push_back(time(0)); } } } else { SogouInstallInfo info; GetSogouInstallInfo(info); if (!info.program.IsTSFVersion()) //如果是旧版本搜狗,则检测是否启动 { if (sogouProcessRun == 0)//进程未运行 { LogWarn(Severity_Middle, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, "搜狗进程未启动!"); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setLogCode("QLR040250A01Z101").setResultCode("RTA5A01")("搜狗未启动!"); sogouProcessRun = -1; //进程未启动告警一次即可 } } } CloseHandle(hProcessSnap); #else static int old_process_id[2] = { -1, -1 }; char* relate_processes[2] = { "sogouImeWebSrv", "sogouImeService" }; int count = 3; alive_process_info processes[3]; memset(processes, 0, sizeof(processes)); osutil_detect_unique_app(relate_processes, array_size(relate_processes), &count, processes); CAutoArray msgs(array_size(relate_processes)); int cnt(0); for (int i = 0; i < array_size(relate_processes); ++i) { int k = -1; for (int j = 0; j < count; ++j) { if (strcmp(processes[j].name, relate_processes[i]) == 0) { k = j; break; } } if (k != -1 && old_process_id[i] == -1) { old_process_id[i] = processes[k].pid; } else if (k != -1 && (processes[k].pid != old_process_id[i])) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , relate_processes[i], old_process_id[i], processes[k].pid); old_process_id[i] = processes[k].pid; } else if (k == -1 && old_process_id[i] != 0) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , relate_processes[i], old_process_id[i], 0); old_process_id[i] = 0; } } if (cnt > 0) { std::string uploadInfo(""); if (cnt > 1) { uploadInfo = "{"; } for (int i = 0; i < cnt; ++i) { if (i != 0) { uploadInfo += ","; } uploadInfo += msgs[i].GetData(); } if (cnt > 1) { uploadInfo += "}"; } LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHER_SOGOU_PROCESS_STATUS_CHANGE, uploadInfo.c_str()); } #endif //RVC_OS_WIN } #if defined(RVC_OS_LINUX) ErrorCodeEnum ResourceWatcherEntity::GetSogouPkgDirPath(CSimpleStringA& strPkgPath) { CSimpleStringA strAdDataDirPath(true); CSimpleStringA strInstallPkgPath(true); ErrorCodeEnum result = GetFunction()->GetPath("Ad", strAdDataDirPath); if (strAdDataDirPath.IsNullOrEmpty()) { strAdDataDirPath = "/opt/rvc/adData"; } if (strAdDataDirPath.IsNullOrEmpty()) { return Error_Unexpect; } array_header_t* subs; subs = fileutil_get_sub_dirs_a(strAdDataDirPath); if (subs) { for (int i = 0; i < subs->nelts; ++i) { char* dir = ARRAY_IDX(subs, i, char*); const char* dirname = &dir[strAdDataDirPath.GetLength() + 1]; if (CSimpleStringA(dirname).IsStartWith("sogou", true) || CSimpleStringA(dirname).IsStartWith("uos-sogou", true)) { if (strInstallPkgPath.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("found it: %s", dir); strInstallPkgPath = dir; } else if (strInstallPkgPath.Compare(dir) < 0) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("replace %s with %s", (LPCTSTR)strInstallPkgPath, dir); strInstallPkgPath = dir; } } } toolkit_array_free2(subs); } if (strInstallPkgPath.IsNullOrEmpty()) { return Error_NotExist; } strPkgPath = strInstallPkgPath; return Error_Succeed; } #endif //RVC_OS_LINUX ErrorCodeEnum ResourceWatcherEntity::RunShellScript(LPCTSTR cmdline) { #if defined(RVC_OS_WIN) return Error_NotSupport; #else char app[MAX_PATH] = { '\0' }; char szldPath[1024] = { '\0' }; size_t szldLen = 1023; tk_process_t* process = NULL; tk_process_option_t option; const int ldRet = toolkit_getenv("LD_LIBRARY_PATH", szldPath, &szldLen); if (ldRet == 0) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("get library path: %s", szldPath); toolkit_unsetenv("LD_LIBRARY_PATH"); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetEnv of LD_LIBRARY_PATH failed: %s", toolkit_strerror(ldRet)); } option.exit_cb = NULL; option.file = NULL; option.flags = 0; option.params = (char*)cmdline; const int res = process_spawn(&option, &process); if (ldRet == 0) { toolkit_setenv("LD_LIBRARY_PATH", szldPath); } if (0 == res) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("execute {%s}, pid: %d, and wait ...", cmdline, process->pid); int status; while (process->pid > 0 && waitpid(process->pid, &status, 0) < 0) { if (errno != EINTR) { status = -1; break; } } if (WIFEXITED(status)) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("normal terminal. exit status: %d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("abnormal terminal, signal: %d", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cihild stop, signal: %d", WSTOPSIG(status)); } FREE(process); return Error_Succeed; } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("execute {%s} failed: %d", cmdline, res); return Error_Unexpect; } #endif //RVC_OS_WIN } std::string ResourceWatcherEntity::DoCheckCertainProcessStatus(const CAutoArray& pName) { const int pSize = pName.GetCount(); vector old_process_id; CAutoArray msgs; #if defined(RVC_OS_WIN) for (int i = 0; i < pSize; ++i) { old_process_id.push_back(-1); CSimpleStringA temp(""); msgs.Append(&temp, 0, 1); } int cnt(0); PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("CreateToolhelp32Snapshot error."); return ""; } for (int i = 0; i < pSize; ++i) { int position = -1; BOOL bProcess = Process32First(hProcessSnap, &pe32); while (bProcess) { if (strcmp(pe32.szExeFile, pName[i].GetData()) == 0) { position = 1; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("pname: %s, pid: %d.", pe32.szExeFile, pe32.th32ProcessID); break; } bProcess = Process32Next(hProcessSnap, &pe32); } if (position != -1 && old_process_id[i] == -1) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"pid\":%d}" , pName[i].GetData(), pe32.th32ProcessID); old_process_id[i] = pe32.th32ProcessID; } else if (position != -1 && (pe32.th32ProcessID != old_process_id[i])) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , pName[i].GetData(), old_process_id[i], pe32.th32ProcessID); old_process_id[i] = pe32.th32ProcessID; } else if (position == -1 && old_process_id[i] > 0) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , pName[i].GetData(), old_process_id[i], 0); old_process_id[i] = 0; } } CloseHandle(hProcessSnap); #else alive_process_info* processes = new alive_process_info[pSize]; char** relate_processes = new char* [pSize]; int count = pSize; for (int i = 0; i < pSize; ++i) { old_process_id.push_back(-1); CSimpleStringA temp(""); msgs.Append(&temp, 0, 1); relate_processes[i] = const_cast(pName[i].GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("relate_process name: %s.", relate_processes[i]); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("COUNT = %d!", count); osutil_detect_unique_app(relate_processes, pSize, &count, processes); int cnt(0); for (int i = 0; i < pSize; ++i) { int k = -1; for (int j = 0; j < count; ++j) { if (strcmp(processes[j].name, relate_processes[i]) == 0) { k = j; break; } } if (k != -1 && old_process_id[i] == -1) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"pid\":%d}" , relate_processes[i], processes[k].pid); old_process_id[i] = processes[k].pid; } else if (k != -1 && (processes[k].pid != old_process_id[i])) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , relate_processes[i], old_process_id[i], processes[k].pid); old_process_id[i] = processes[k].pid; } else if (k == -1 && old_process_id[i] != 0) { msgs[cnt++] = CSimpleStringA::Format("{\"name\":\"%s\", \"prev\":%d, \"pid\":%d}" , relate_processes[i], old_process_id[i], 0); old_process_id[i] = 0; } } #endif //RVC_OS_WIN std::string uploadInfo(""); if (cnt > 0) { if (cnt > 1) { uploadInfo = "{"; } for (int i = 0; i < cnt; ++i) { if (i != 0) { uploadInfo += ","; } uploadInfo += msgs[i].GetData(); } if (cnt > 1) { uploadInfo += "}"; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", uploadInfo.c_str()); } return uploadInfo; } //检测安全软件进程:亚信、联软、锐眼 void ResourceWatcherEntity::SecProcCheck() { //默认检测windows, 若后续需要在UOS检测,则通过集中配置读取修改名称 CSimpleStringA yaXin = "NTRtScan.exe"; //亚信 CSimpleStringA lianRuan = "UniAccessAgent.exe"; //联软 CSimpleStringA ruiYan = "RuiYan.exe"; //锐眼 #ifdef RVC_OS_LINUX CSmartPointer spCtSettingConfig; GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); spCtSettingConfig->ReadConfigValue("ResourceWatcher", "YaXinProcUOS", yaXin); spCtSettingConfig->ReadConfigValue("ResourceWatcher", "LianRuanProcUOS", lianRuan); spCtSettingConfig->ReadConfigValue("ResourceWatcher", "RuiYanProcUOS", ruiYan); #endif // RVC_OS_WIN CAutoArray tArray(&yaXin, 1); //Dbg("Security check name:%s.Size = %d.", tArray[0].GetData(), tArray.GetCount()); if (yaXin.GetLength() != 0) { string yaXinRe = DoCheckCertainProcessStatus(tArray); if (!yaXinRe.empty()) { LogWarn(Severity_Low, Error_Debug, LOG_WARN_SUEPROCCHECK_YAXIN, yaXinRe.c_str()); } } if (lianRuan.GetLength() != 0) { tArray[0] = lianRuan; string lianRuanRe = DoCheckCertainProcessStatus(tArray); if (!lianRuanRe.empty()) { LogWarn(Severity_Low, Error_Debug, LOG_WARN_SUEPROCCHECK_LIANRUAN, lianRuanRe.c_str()); } } if (ruiYan.GetLength() != 0) { tArray[0] = ruiYan; string ruiYanRe = DoCheckCertainProcessStatus(tArray); if (!ruiYanRe.empty()) { LogWarn(Severity_Low, Error_Debug, LOG_WARN_SUEPROCCHECK_RUIYAN, ruiYanRe.c_str()); } } } bool ResourceWatcherEntity::is_str_utf8(const char* str) { unsigned int nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节 unsigned char chr = *str; bool bAllAscii = true; for (unsigned int i = 0; str[i] != '\0'; ++i) { chr = *(str + i); //判断是否ASCII编码,如果不是,说明有可能是UTF8,ASCII用7位编码,最高位标记为0,0xxxxxxx if (nBytes == 0 && (chr & 0x80) != 0) { bAllAscii = false; } if (nBytes == 0) { //如果不是ASCII码,应该是多字节符,计算字节数 if (chr >= 0x80) { if (chr >= 0xFC && chr <= 0xFD) { nBytes = 6; } else if (chr >= 0xF8) { nBytes = 5; } else if (chr >= 0xF0) { nBytes = 4; } else if (chr >= 0xE0) { nBytes = 3; } else if (chr >= 0xC0) { nBytes = 2; } else { return false; } nBytes--; } } else { if ((chr & 0xC0) != 0x80) { return false; } nBytes--; } } if (nBytes != 0) { return false; } if (bAllAscii) { //如果全部都是ASCII, 也是UTF8 return true; } return true; } ErrorCodeEnum ResourceWatcherEntity::UnzipPack(const char* unZipPackName) { CSimpleStringA strDownloadsPath; CSmartPointer spFunction = GetFunction(); ErrorCodeEnum rc = spFunction->GetPath("Downloads", strDownloadsPath); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("unzipPack is fail,get Downloads Path is fail"); return Error_Unexpect; } CSimpleStringA strTempPath; ErrorCodeEnum rc2 = GetFunction()->GetPath("Temp", strTempPath); assert(rc2 == Error_Succeed); CSimpleStringA strUnzipDir; strUnzipDir = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strTempPath.GetData(), unZipPackName); if (strUnzipDir.IsEndWith(".zip") || strUnzipDir.IsEndWith(".cab")) { strUnzipDir = strUnzipDir.SubString(0, strUnzipDir.GetLength() - 4); } // 如目标目录存在,则先删除 if (ExistsDirA(strUnzipDir)) { if (!RemoveDirRecursiveA(strUnzipDir)) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("remove old unzip dir [%s] fail", strUnzipDir.GetData())); return Error_NotExist; } } // 创建临时解压目录 CreateDirA(strUnzipDir.GetData(), true); if (!ExistsDirA(strUnzipDir)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("unzipPack is fail,create temp unzip dir [%s] fail,err=%d", strUnzipDir.GetData(), GetLastError()); return Error_Unexpect; } CSimpleStringA strZipFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strDownloadsPath.GetData(), unZipPackName); //升级包是否存在 if (!ExistsFileA(strZipFile)) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("pack [%s] not exists", unZipPackName).GetData()); return Error_NotExist; } #if defined(RVC_OS_LINUX) string zipFileStr = strZipFile.GetData(); string zipTempDir = strUnzipDir.GetData(); if (UnZipToDir(zipFileStr, zipTempDir) != 0) { LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("unzip pack [%s] fail", zipFileStr.c_str())); return Error_NotExist; } #else // 设定解压临时目录 char szOldPath[MAX_PATH] = {}; GetCurrentDirectoryA(MAX_PATH, szOldPath); //设置当前目录为主目录 if (!SetCurrentDirectoryA(strUnzipDir.GetData())) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("unzipPack is fail,SetCurrentDirectoryA dir [%s] fail,err=%d", strUnzipDir.GetData(), GetLastError()); return Error_Unexpect; } // 解压 HZIP hz = OpenZip((void*)(const char*)strZipFile, 0, ZIP_FILENAME); if (hz == 0) { SetCurrentDirectoryA(szOldPath); LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("open zip file [%s] fail", unZipPackName).GetData()); return Error_Unexpect; } ZIPENTRY ze; ZRESULT zrc = GetZipItemA(hz, -1, &ze); if (zrc == ZR_OK) { int numitems = ze.index; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("zip entry count is %d", ze.index); for (int i = 0; i < numitems; i++) { zrc = GetZipItemA(hz, i, &ze); if (zrc == ZR_OK) { //兼容压缩包里面中文名称是utf8编码 if (is_str_utf8(ze.name)) { char* pGBK = SP::Module::Util::ConvertUtf8ToGBK((const char*)ze.name); zrc = UnzipItem(hz, i, pGBK, 0, ZIP_FILENAME); if (zrc == ZR_OK) { delete[] pGBK; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("unzip [%s] UTF8 item fail,result=0x%X", pGBK, (int)zrc); delete[] pGBK; break; } } else { zrc = UnzipItem(hz, i, ze.name, 0, ZIP_FILENAME); if (zrc != ZR_OK) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("unzip [%s] GBK item fail,result=0x%X", ze.name, (int)zrc); break; } } } else { //出错,退出 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("UnzipPack")("unzip GetZipItemA [%d] item fail,fail=0x%X", i, (int)zrc); break; } } CloseZip(hz); } else { CloseZip(hz); } // 恢复当前目录 SetCurrentDirectoryA(szOldPath); if (zrc != ZR_OK) { return Error_Exception; } #endif //RVC_OS_LINUX return Error_Succeed; } ErrorCodeEnum ResourceWatcherEntity::DeleteUnzipDir() { CSimpleStringA strDownloadsPath; CSmartPointer spFunction = GetFunction(); ErrorCodeEnum rc = spFunction->GetPath("Downloads", strDownloadsPath); if (rc != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DeleteUnzipDir")("DeleteUnzipDir is fail,get Downloads Path is fail"); return Error_Unexpect; } CSimpleStringA sogouTest = "sogoutest"; CSimpleStringA strUnzipDir = CSimpleStringA::Format("%s\\%s", strDownloadsPath.GetData(), sogouTest.GetData()); //解压去除了.zip后缀 if (strUnzipDir.IsEndWith(".zip")) { strUnzipDir = strUnzipDir.SubString(0, strUnzipDir.GetLength() - 4); } // 解压目录是否存在,存在则删除 if (ExistsDirA(strUnzipDir.GetData())) { if (!RemoveDirRecursiveA(strUnzipDir.GetData())) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("DeleteUnzipDir")("DeleteUnzipDir fail , temp unzip dir [%s] fail,err=%d", strUnzipDir.GetData(), (int)GetLastError()); return Error_Unexpect; } else { return Error_Succeed; } } return Error_Succeed; } void ResourceWatcherEntity::GetThirdPartyInstallState(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); if (ctx->Req.mode == 1) {//查看搜狗输入法安装状态 SogouInstallInfo info; GetSogouInstallInfo(info); ctx->Ans.status = info.IsInstalledSuccess() ? 1 : 0; ctx->Ans.path = info.program.strInstallDir; ctx->Ans.version = info.program.strVersion; ctx->Ans.reserverd1 = info.state.GetInstallTime().ToTimeString(); ctx->Ans.reserverd2 = ""; ctx->Ans.reserverd3 = info.program.IsTSFVersion() ? 1 : 0; ctx->Ans.reserverd4 = 0; } else if (ctx->Req.mode == 2) { //检测字体的安装状态 #if defined(_MSC_VER) result = Error_NotImpl; #else CSimpleStringA strFontDir("/usr/share/fonts/truetype"); CSimpleStringA strRVCTTFsDir(strFontDir + SPLIT_SLASH_STR + "RVCTTFs"); if (!ExistsDirA(strRVCTTFsDir)) { ctx->Ans.status = 0; ctx->Ans.reserverd1 = CSimpleStringA::Format("%s 文件夹不存在", (LPCTSTR)strRVCTTFsDir); } else { CSimpleStringA ttf1 = strRVCTTFsDir + SPLIT_SLASH_STR + "HYQiHei-55S.ttf"; CSimpleStringA ttf2 = strRVCTTFsDir + SPLIT_SLASH_STR + "HYQiHei-65S.ttf"; CSimpleStringA ttfdir = strRVCTTFsDir + SPLIT_SLASH_STR + "fonts.dir"; CSimpleStringA ttfscale = strRVCTTFsDir + SPLIT_SLASH_STR + "fonts.scale"; CSimpleStringA ttfuuid = strRVCTTFsDir + SPLIT_SLASH_STR + ".uuid"; int existCheck = 0; if (!ExistsFileA(ttf1)) { existCheck |= 1; } if (!ExistsFileA(ttf2)) { existCheck |= 2; } if (!ExistsFileA(ttfdir)) { existCheck |= 4; } if (!ExistsFileA(ttfscale)) { existCheck |= 8; } if (!ExistsFileA(ttfuuid)) { existCheck |= 16; } if (existCheck != 0) { ctx->Ans.status = 0; ctx->Ans.reserverd1 = CSimpleStringA::Format("安装文件不存在:0x%X", existCheck); } else { ctx->Ans.status = 1; ctx->Ans.reserverd1 = ""; ctx->Ans.path = strRVCTTFsDir; ctx->Ans.version = ""; } } #endif //_MSC_VER } else if (ctx->Req.mode == 3) { //自定义安装 #if defined(RVC_OS_WIN) result = Error_NotSupport; #else if (ctx->Req.reserverd3.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("the req rerverd3 is empty."); result = Error_Param; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to check %s 's install status...", ctx->Req.reserverd3.GetData()); CSimpleStringA strSoftwareName(ctx->Req.reserverd3); CSimpleStringA strSoftwareVersion(ctx->Req.reserverd4); CSimpleStringA runItem = CSimpleStringA::Format("dpkg -l | grep %s | awk '{print $3}'", strSoftwareName.GetData()); std::string additional(""); std::string succStr, errStr; std::string runStr(runItem.GetData()); if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) { if (succStr.empty()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("%s is not installed", strSoftwareName.GetData()); ctx->Ans.status = 0; } else { succStr = SP::Utility::ToTrim(succStr); if (strSoftwareVersion.IsNullOrEmpty() || strSoftwareVersion.Compare(succStr.c_str()) == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s is installed, version: %s", strSoftwareName.GetData(), succStr.c_str()); ctx->Ans.status = 1; } else { ctx->Ans.status = 2; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s is installed, but the version<%s> is not the dream one<%s>" , strSoftwareName.GetData(), succStr.c_str(), strSoftwareVersion.GetData()); ctx->Ans.reserverd1 = succStr.c_str(); } } } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Execute <%s> failed.", runItem.GetData()); result = Error_Process; } } #endif //RVC_OS_WIN } else { result = Error_NotSupport; } ctx->Answer(result); return; } CSimpleStringA ResourceWatcherEntity::GetFilePathWithDir(CSimpleStringA dir, CSimpleStringA fileName) { CSimpleStringA tmpPath(""), filePath(""); #ifdef RVC_OS_LINUX struct stat st; if (stat(dir, &st) == -1) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("[%s] Failed to get file stats.", dir.GetData()); return ""; } if (!S_ISDIR(st.st_mode)) { return ""; } DIR* dp; struct dirent* dirp; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to open dir %s", dir.GetData()); if ((dp = opendir(dir.GetData())) != NULL) { while ((dirp = readdir(dp)) != NULL) { if ((!strcmp(dirp->d_name, ".")) || (!strcmp(dirp->d_name, ".."))) { continue; } CSimpleStringA tmpName(dirp->d_name); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("name:%s", tmpName.GetData()); if (tmpName == fileName) { filePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", dir.GetData(), tmpName.GetData()); break; } tmpPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", dir.GetData(), tmpName.GetData()); filePath = GetFilePathWithDir(tmpPath, fileName); if (!filePath.IsNullOrEmpty()) { break; } } closedir(dp); if (filePath.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Can't find file[%s] under path [%s].",fileName.GetData(), dir.GetData()); } return filePath; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Open dir [%s] failed.", dir.GetData()); return ""; } #else CSimpleStringA inPath = dir; inPath.Append("\\*"); // "D:aaa\bbb\ccc\* " 匹配目录下的所有文件和文件夹 int fileLength = inPath.GetLength(); WIN32_FIND_DATA wfd; HANDLE hFind; hFind = FindFirstFile(inPath.GetData(), &wfd); //单文件操作 if (hFind == INVALID_HANDLE_VALUE) // 非文件夹 (inPath "D:aaa\bbb\ccc\* "格式的情况下,如果前面是文件,会找不到匹配) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("[%s] is NOT dir.", dir.GetData()); return ""; } //文件夹操作 do { if ((!strcmp(wfd.cFileName, ".")) || (!strcmp(wfd.cFileName, ".."))) { continue; } CSimpleStringA tmpName(wfd.cFileName); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("name:%s", tmpName.GetData()); if (tmpName == fileName) { filePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", dir.GetData(), tmpName.GetData()); break; } tmpPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", dir.GetData(), tmpName.GetData()); filePath = GetFilePathWithDir(tmpPath, fileName); if (!filePath.IsNullOrEmpty()) { break; } } while (FindNextFileA(hFind, &wfd)); FindClose(hFind); if (filePath.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Can't find file[%s] under path [%s].", fileName.GetData(), dir.GetData()); } return filePath; #endif // RVC_OS_LINUX } void ResourceWatcherEntity::InstallSogou(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); CSimpleStringA tmpPath(true); DWORD warnCode = LOG_RESOURCEWATCHE_INSTALL_THIRDPARTY; //RTA映射 CSimpleStringA newSogouPath(true); CSimpleStringA strDownloadDirPath(true); GetFunction()->GetPath("Downloads", strDownloadDirPath); CSimpleStringA strTempDirPath(true); GetFunction()->GetPath("Temp", strTempDirPath); #if defined(RVC_OS_LINUX) bool sogouInstalled = false; const bool doTryRestart = (ctx->Req.reserved1 != 1); SogouInstallInfo info; //安装搜狗输入法 bool zipFind = false; time_t newestWrite = 0; if (strDownloadDirPath.IsNullOrEmpty()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("downloads path is invalid, maybe in config mode"); tmpResult = Error_Unexpect; tmpMsg = CSimpleStringA::Format("搜狗安装包目录[Downloads]不存在!"); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } else { DIR* dp; struct dirent* dirp; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to open dir %s", strDownloadDirPath.GetData()); if ((dp = opendir(strDownloadDirPath.GetData())) != NULL) { while ((dirp = readdir(dp)) != NULL) { CSimpleStringA tmpName(dirp->d_name); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("name:%s", tmpName.GetData()); if ((tmpName.IsStartWith("sogou", true) || tmpName.IsStartWith("uos-sogou", true)) && tmpName.IsEndWith(".zip", true)) { struct stat buf; memset(&buf, 0x00, sizeof(buf)); CSimpleStringA strFullPathName = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strDownloadDirPath.GetData(), dirp->d_name); const int ret = stat(strFullPathName.GetData(), &buf); if (ret != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("获取文件[%s]状态信息出错。", tmpName.GetData()); } else if (buf.st_mtim.tv_sec > newestWrite) { newestWrite = buf.st_mtim.tv_sec; newSogouPath = CSimpleStringA(tmpName.GetData()); zipFind = true; } } } closedir(dp); if (!zipFind) { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("在路径[%s]下未找到搜狗安装包!", strDownloadDirPath.GetData()); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } } else { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("打开[Downloads]目录失败!"); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } } CSimpleStringA strInstallPkgPath(true); if (zipFind) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to unzip pack %s", newSogouPath.GetData()); if (UnzipPack(newSogouPath) != Error_Succeed) { tmpResult = Error_Unexpect; tmpMsg = CSimpleStringA::Format("解压搜狗安装包失败!"); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { newSogouPath = newSogouPath.SubString(0, newSogouPath.GetLength() - 4); strInstallPkgPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strTempDirPath.GetData(), newSogouPath.GetData()); } } else { tmpResult = GetSogouPkgDirPath(strInstallPkgPath); if (tmpResult != Error_Succeed) { tmpMsg = CSimpleStringA::Format(" 指定位置 [Ad] 找不到输入法安装包"); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } } CSimpleStringA strInstallScriptFile; CSimpleStringA strRunIniFilePath; CSimpleStringA strResultLogFilePath; const bool doNotStartup(true); //安装后是否启动搜狗输入法服务,据搜狗反馈,不能通过root权限启动Sogou输入法 if (tmpResult == Error_Succeed) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to install sogou input... %s", strInstallPkgPath.GetData()); tmpResult = SetFileExecutePriviledge(strInstallPkgPath); if (tmpResult != Error_Succeed) { tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData()); tmpResult = Error_NotExist; warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { strRunIniFilePath = GetFilePathWithDir(strInstallPkgPath, "Run.ini"); if (ExistsFileA(strRunIniFilePath)) { char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", ""); strInstallScriptFile = GetFilePathWithDir(strInstallPkgPath, p); FREE(p); } else { strInstallScriptFile = GetFilePathWithDir(strInstallPkgPath, "install_sogouime.sh"); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("install script file: %s", strInstallScriptFile.GetData()); if (ExistsFileA(strInstallScriptFile)) { char app[MAX_PATH] = { '\0' }; sprintf(app, "bash %s", strInstallScriptFile.GetData()); tmpResult = RunShellScript(app); if (tmpResult != 0) { tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else if (!doNotStartup) { CSimpleStringA strStartupScriptFile = GetFilePathWithDir(strInstallPkgPath, "startup_service.sh"); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("startup script file: %s", strStartupScriptFile.GetData()); if (!ExistsFileA(strStartupScriptFile)) { tmpMsg = CSimpleStringA::Format("%s 启动脚本文件不存在,请重启设备再次验证", strStartupScriptFile.GetData()); tmpResult = Error_NotExist; warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { Sleep(1000); do { sprintf(app, "bash %s", strStartupScriptFile.GetData()); tmpResult = RunShellScript(app); if (tmpResult != 0) { tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app); tmpResult = Error_Process; warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } } while (false); } } } else { tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData()); tmpResult = Error_NotExist; warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } } } if (tmpResult == Error_Succeed) { Sleep(1500); strResultLogFilePath = GetFilePathWithDir(strInstallPkgPath, "result.log"); do { const int maxTimes = 5; int curTimes = 0; while (!ExistsFileA(strResultLogFilePath) && curTimes < maxTimes) { Sleep(1500); curTimes++; } } while (false); if (!ExistsFileA(strResultLogFilePath)) { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("安装成功标志文件不存在!"); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { FILE* pResultLog = fopen(strResultLogFilePath, "r"); if (pResultLog == NULL) { tmpResult = Error_IO; tmpMsg = CSimpleStringA::Format("打开安装成功标志文件失败!%s", strerror(errno)); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { char szTmp[1024] = { '\0' }; int nRead = fread(szTmp, 1, sizeof(szTmp), pResultLog); int installResult(-1); char installMsg[256] = { '\0' }; sscanf(szTmp, "result=%d&msg=%s", &installResult, installMsg); fclose(pResultLog); if (installResult != 0) { tmpResult = Error_Unexpect; tmpMsg = CSimpleStringA::Format("安装状态错误:%s", szTmp);; warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { GetSogouInstallInfo(info); if (!info.IsInstalledSuccess()) { tmpResult = Error_FailVerify; tmpMsg = CSimpleStringA::Format("搜狗检测安装状态失败!"); } else { ctx->Ans.path = info.program.strInstallDir; ctx->Ans.reserverd1 = info.program.strVersion; ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString(); //ctx->Ans.reserverd3 = info.program.IsTSFVersion() ? 1 : 0; //ctx->Ans.reserverd4 = 0; if (doTryRestart) { tmpMsg = CSimpleStringA::Format(" 从[%s]安装搜狗输入法成功。", strInstallPkgPath.GetData()); } sogouInstalled = true; } } } } } LogWarn(Severity_Low, Error_Debug, warnCode, CSimpleStringA::Format("用户桌面重装搜狗:%s. result:%d.", tmpMsg.GetData(), tmpResult)); ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(tmpResult, warnCode); #else //win-sogou 包名 bool zipFind = false; struct _finddata_t fileinfo;//文件信息读取结构 long hFile = -1; time_t newestWrite = 0; if (strDownloadDirPath.IsNullOrEmpty()) { tmpResult = Error_Unexpect; tmpMsg = CSimpleStringA::Format("搜狗安装包目录[Downloads]不存在!"); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } else { CSimpleStringA tmpDownloads(strDownloadDirPath.GetData()); hFile = _findfirst(tmpDownloads.Append("\\*").GetData(), &fileinfo); if (hFile != -1) { do { CSimpleStringA tmpName(fileinfo.name); if ((tmpName.IsStartWith("sogou", true) || tmpName.IsStartWith("win-sogou", true) || tmpName.IsStartWith("Sys-Win-sogou", true)) && tmpName.IsEndWith(".zip", true) && fileinfo.time_write > newestWrite) { newestWrite = fileinfo.time_write; newSogouPath = CSimpleStringA(tmpName.GetData()); zipFind = true; } } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); if (zipFind) { if (UnzipPack(newSogouPath.GetData()) != Error_Succeed) { tmpResult = Error_Unexpect; tmpMsg = CSimpleStringA::Format("解压搜狗安装包失败!"); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { newSogouPath = newSogouPath.SubString(0, newSogouPath.GetLength() - 4); CSimpleStringA tmpStrInstallDirPath = CSimpleStringA::Format("%s\\%s", strTempDirPath.GetData(), newSogouPath.GetData()); //D:RVC\temp\sogou.xxxxx CSimpleStringA strInstallDirPath(""); CSimpleStringA strResultLogFilePath(""); strInstallDirPath = GetFilePathWithDir(tmpStrInstallDirPath, "install_sogouime.bat") + " force"; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("开始安装"); STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = TRUE; char* cmdline = const_cast(strInstallDirPath.GetData()); BOOL bRet = ::CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); WaitForSingleObject(pi.hProcess, INFINITE); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("结束后台安装流程"); strResultLogFilePath = GetFilePathWithDir(tmpStrInstallDirPath, "result.log"); if (strResultLogFilePath.IsNullOrEmpty() || strInstallDirPath.IsNullOrEmpty()) { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("进入安装目录失败!路径为空!"); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else if (!ExistsFileA(strResultLogFilePath)) { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("安装成功标志文件不存在!路径[%s]", strResultLogFilePath.GetData()); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { FILE* pResultLog = fopen(strResultLogFilePath, "r"); if (pResultLog == NULL) { tmpResult = Error_IO; tmpMsg = CSimpleStringA::Format("打开安装成功标志文件失败!%s", strerror(errno)); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { char szTmp[1024] = { '\0' }; int nRead = fread(szTmp, 1, sizeof(szTmp), pResultLog); CSimpleStringA tInstallRe = szTmp; fclose(pResultLog); CSimpleStringA installResult = "-1"; CSimpleStringA installMsg; auto arr = tInstallRe.Split('&'); if (arr.GetCount() != 2) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetSysUpgradeResult")("GetSysUpgradeResult read result log format fail"); tmpMsg = "read result.log format fail,eg result=0&msg=install ok"; } for (int i = 0; i < arr.GetCount(); i++) { auto arr2 = arr[i].Split('='); if (arr2.GetCount() == 2) { if (stricmp(arr2[0], "result") == 0) installResult = arr2[1]; else if (stricmp(arr2[0], "msg") == 0) installMsg = arr2[1]; } } if (installResult != CSimpleStringA::Format("0")) { tmpResult = Error_Unexpect; tmpMsg = CSimpleStringA::Format("安装状态错误:%s", szTmp); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { SogouInstallInfo info; if (GetSogouInstallInfo(info) != Error_Succeed) { tmpResult = Error_FailVerify; tmpMsg = CSimpleStringA::Format("搜狗安装状态失败!"); warnCode = LOG_RESOURCEWATCHE_INSTALL_SOGOU_FAILED; } else { ctx->Ans.path = info.program.strInstallDir; ctx->Ans.reserverd1 = info.program.strVersion; ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString(); } } } } if (tmpResult == Error_Succeed) { tmpMsg = CSimpleStringA::Format("已成功安装搜狗输入法!"); } } } else { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("在路径[%s]下未找到搜狗安装包!", strDownloadDirPath.GetData()); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } } else { tmpResult = Error_NotExist; tmpMsg = CSimpleStringA::Format("搜狗打开[Downloads]目录失败!"); warnCode = LOG_RESOURCEWATCHE_SOGOU_FINDPKG_FAILED; } } LogWarn(Severity_Low, Error_Debug, warnCode, CSimpleStringA::Format("用户桌面重装搜狗:%s. result:%d.", tmpMsg.GetData(), tmpResult)); ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(tmpResult, warnCode); return; #endif //RVC_OS_LINUX } void ResourceWatcherEntity::CheckProcessStatus() { vector msg; CSmartPointer spCtSettingConfig; GetFunction()->OpenConfig(Config_CenterSetting, spCtSettingConfig); CSimpleStringA getProcess(""), tName(""); int procCnt = 0; #if defined(RVC_OS_LINUX) do { procCnt++; getProcess = CSimpleStringA::Format("ProcessNameUOS%d", procCnt); spCtSettingConfig->ReadConfigValue("ResourceWatcher", (LPCTSTR)getProcess, tName); if (!tName.IsNullOrEmpty()) { std::string succStr, errStr; std::string runStr("pgrep -d '|' "); runStr += tName.GetData(); CSimpleStringA tMsg(true); if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) { if (succStr.empty()) { tMsg = CSimpleStringA::Format("{ \"name\":\"%s\", \"pid\": 0}", tName.GetData()); } else { succStr = SP::Utility::ToTrim(succStr); if (succStr.find('|') != std::string::npos) { tMsg = CSimpleStringA::Format("{ \"name\":\"%s\", \"pid\": %s}", tName.GetData(), succStr.c_str()); } else { tMsg = CSimpleStringA::Format("{ \"name\":\"%s\", \"pid\": \"%s\"}", tName.GetData(), succStr.c_str()); } } } else { tMsg = CSimpleStringA::Format("{ \"name\":\"%s\", \"pid\": -1}", tName.GetData()); } msg.push_back(tMsg.GetData()); } } while (!tName.IsNullOrEmpty()); #else do { procCnt++; getProcess = CSimpleStringA::Format("ProcessName%d", procCnt); spCtSettingConfig->ReadConfigValue("ResourceWatcher", (LPCTSTR)getProcess, tName); if (tName.GetLength() != 0) { CAutoArray tArray; tArray.Append(&tName, 0, 1); string tMsg = DoCheckCertainProcessStatus(tArray); if (tMsg.size() == 0) { tMsg = CSimpleStringA::Format("{ \"name\":\"%s\", \"pid\": 0}", tName.GetData()); } msg.push_back(tMsg); } } while (tName.GetLength() != 0); #endif //RVC_OS_LINUX if (msg.size() != 0) { CSimpleStringA res(true); if (msg.size() == 1) { res = msg[0].c_str(); } else { res = "{"; for (int i = 0; i < msg.size(); ++i) { if (i != 0) { res += ","; } res = res + msg[i].c_str(); } res += "}"; } LogWarn(Severity_Low, Error_Debug, LOG_WARN_PROCESS_STATUS, res); } } void ResourceWatcherEntity::FilesClean(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum result(Error_Succeed); ErrorCodeEnum tmpResult(Error_Succeed); CSimpleStringA tmpMsg(true); if (ctx->Req.type == 1)//清理浏览器缓存 { BrowserCacheClean browserCacheClean; browserCacheClean.needClean = 1; SpSendBroadcast(GetFunction(), SP_MSG_OF(BrowserCacheClean), SP_MSG_SIG_OF(BrowserCacheClean), browserCacheClean); tmpMsg = "已发送重启命令"; } else { tmpResult = Error_NotExist; tmpMsg = "非法的调用参数"; } ctx->Ans.result = tmpResult; ctx->Ans.msg = tmpMsg; ctx->Answer(result); } void ResourceWatcherEntity::OnUpgradeStateEvent(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, UpgradeManager::UpgradeStateEvent& evt) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("OnUpgradeStateEvent, cInstallState:%c, strNewVersion:%s.", evt.cInstallState, evt.strNewVersion.GetData()); CSimpleStringA packName = evt.strPackName; if (evt.cInstallState == 'I') { lastUpgradeInstallTime = time(0); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("lastUpgradeInstallTime = %lld.", lastUpgradeInstallTime); } if (evt.cInstallState == 'S' || evt.cInstallState == 'C') { lastUpgradeSwitchTime = time(0); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("lastUpgradeSwitchTime = %lld.", lastUpgradeSwitchTime); if (evt.strNewVersion.GetLength() == 0) { newestSogouInstall = true; lastSogouChangeEndTime = lastUpgradeSwitchTime + 60; } DoCheckSogouProcessStatus(); } } void ResourceWatcherEntity::FetchSystemSnapshot( SpReqAnsContext::Pointer ctx) { CSimpleStringA info(true); if (ctx->Req.type == 1) { #if defined(RVC_OS_WIN) ctx->Answer(Error_NotSupport); #else const bool ret = m_fsm.GetMonitorInfo(info); if (ret) { ctx->Ans.result = 0; ctx->Ans.msg = info; LogWarn(Severity_Low, Error_Debug, LOG_INFO_MONITOR_SETTINGS_GET, info); } else { ctx->Ans.result = -1; ctx->Ans.msg = "调用 GetMonitorInfo 接口失败"; } ctx->Answer(Error_Succeed); #endif //RVC_OS_WIN } else if (ctx->Req.type == 2) { /** 有无安装新版浏览器 [Gifur@20221219]*/ #if defined(_MSC_VER) ctx->Answer(Error_NotSupport); #else const std::string execute_newbrowser_path = "/usr/share/browser/browser"; const std::string execute_oldbrowser_path = "/usr/share/uosbrowser/uosbrowser"; int result(0); std::string additional(""); std::string succStr, errStr; std::string runStr("dpkg -l | grep org.deepin.browser | awk '{print $3}'"); if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) { if (succStr.empty()) { if (ExistsFileA(execute_oldbrowser_path.c_str())) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s exists!", execute_oldbrowser_path.c_str()); result = 1; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("%s not exists!", execute_oldbrowser_path.c_str()); } } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("new browser version: %s", succStr.c_str()); additional = succStr; if (!ExistsFileA(execute_newbrowser_path.c_str())) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("%s not exists!", execute_newbrowser_path.c_str()); } result = 2; } ctx->Ans.result = result; ctx->Ans.msg = additional.c_str(); ctx->Answer(Error_Succeed); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("execute '%s' failed!", runStr.c_str()); ctx->Answer(Error_Process); } #endif //_MSC_VER } else { ctx->Answer(Error_NotSupport); } } #if defined(RVC_OS_WIN) SP_BEGIN_ENTITY_MAP() SP_ENTITY(ResourceWatcherEntity) SP_END_ENTITY_MAP() #else ResourceWatcherEntity cur; class SpEntityModuleStub : public ModuleBase { public: SpEntityModuleStub() { try { //ResourceWatcherEntity* cur = new ResourceWatcherEntity(); // 内存分配成功 m_pEntityArray[m_nEntityCount++] = dynamic_cast(&cur); } catch (const std::bad_alloc& e) { // 内存分配失败,捕获异常 Dbg("ResourceWatcher Error: Memory allocation failed for ResourceWatcherEntity. %s", e.what()); // 处理错误 } catch (...) { Dbg("ResourceWatcher Error: other for ResourceWatcherEntity"); } Dbg("ResourceWatcher SpEntityModuleStub end"); } }; SpEntityModuleStub g_ModuleInst; extern "C" void __attribute__((constructor)) SoMain() { g_ModuleInst.DllMain(NULL, DLL_PROCESS_ATTACH, NULL); } #endif