#include "stdafx.h" #include "SpBase.h" #include "SpTimer.h" #include "SpMisc.h" #include "SpEntity.h" #include "SpModule.h" #include "SpEntityPrivilege.h" #include "SpAsyncWait.h" #include "sp_iom.h" #include "sp_svc.h" #include "sp_log.h" #include "sp_var.h" #include "sp_def.h" #include "sp_cfg.h" #include "sp_env.h" #include "memutil.h" #include "strutil.h" #include "fileutil.h" #include "shm_array.h" #include "shm_mem.h" #include "iobuffer.h" #include "iniutil.h" #include "def.h" #include "dbgutil.h" #include #include "sp_httpDefine.h" #ifdef RVC_OS_WIN #include "CodeSignVerify.h" #include #include "log_producer_config.h" #else #include "sp_dbg_export.h" #include #include #include #include #endif //RVC_OS_WIN static ErrorCodeEnum ControlEntity( SpEntity *pEntity, const char *pszEntityName, int call_type, const char *cmd_line, //don't change this type bcz: 1. ipc would not convey pointer-type, and receiver may receive as 4bytes type. [4/2/2020 11:13 Gifur] int param1, int param2, CSmartPointer &pAsynWaitSp) { if (!pszEntityName) { return Error_Null; } else if (strlen(pszEntityName) == 0) { return Error_Param; } sp_env_t *env = sp_get_env(); sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszEntityName); if (!ent) return Error_NotExist; iobuffer_t *req_pkt = iobuffer_create(-1, -1); int v = ent->cfg->idx; bool fetch_user_code = false; iobuffer_write(req_pkt, IOBUF_T_I4, &v, 0); if (call_type == SHELL_CMD_REQ_ENTITY_START) iobuffer_write(req_pkt, IOBUF_T_STR, cmd_line, -1); else if (call_type == SHELL_CMD_REQ_ENTITY_TEST) { /** prohibit user from sending test call in the absence of test mode [5/20/2020 Gifur] */ if (param1 == 1/*Test_Examine*/ && !is_own_test_mode( env->cfg->args->test_mode)) { iobuffer_destroy(req_pkt); return Error_NoPrivilege; } fetch_user_code = true; iobuffer_write(req_pkt, IOBUF_T_I4, ¶m1, 0); } SpAsyncWaitRPC *pAsyncWait = new SpAsyncWaitRPC(pEntity, &req_pkt, call_type, fetch_user_code); ErrorCodeEnum Error = pAsyncWait->Begin(); if (Error == Error_Succeed) { pAsynWaitSp.Attach(pAsyncWait, pAsyncWait->GetRefCountPtr()); } pAsyncWait->DecrementRef(); // xkm@20150115 if (req_pkt) iobuffer_dec_ref(req_pkt); return Error; } SpEntityPrivilege::SpEntityPrivilege(SpModule *pModule, sp_entity_t *ent, sp_cfg_shell_entity_t *cfg_ent, CEntityBase *pEntityBase) : SpEntity(pModule, ent, cfg_ent, pEntityBase), m_pEntityLifeListener(NULL) { spinlock_init(&m_maplock); m_pEntityStateListenerMap = stringmap_create(0); } SpEntityPrivilege::~SpEntityPrivilege() { UnregistEntityStateEvent(NULL); stringmap_destroy(m_pEntityStateListenerMap); } ErrorCodeEnum SpEntityPrivilege::Init() { ErrorCodeEnum Error = SpEntity::Init(); return Error; } void SpEntityPrivilege::Term() { //.... SpEntity::Term(); UnregistEntityStateEvent(NULL); // unregister all } CSmartPointer SpEntityPrivilege::GetPrivilegeFunction() { IEntityFunctionPrivilege *pPrivilege = dynamic_cast(this); return pPrivilege; } ErrorCodeEnum SpEntityPrivilege::StartEntity(const char *pszEntityName, const char *pszCmdLine,CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_START, pszCmdLine, 0, 0, pAsynWaitSp); } /*To Close*/ ErrorCodeEnum SpEntityPrivilege::StopEntity(const char *pszEntityName,CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_STOP, NULL, 0, 0, pAsynWaitSp); } /*To Close*/ ErrorCodeEnum SpEntityPrivilege::CloseEntity(const char *pszEntityName,CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_STOP, NULL, 0, 0, pAsynWaitSp); } /*To kill*/ ErrorCodeEnum SpEntityPrivilege::TerminateEntity(const char *pszEntityName,CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_TERMINATE, NULL, 0, 0, pAsynWaitSp); } ErrorCodeEnum SpEntityPrivilege::PauseEntity(const char *pszEntityName,CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_PAUSE, NULL, 0, 0, pAsynWaitSp); } ErrorCodeEnum SpEntityPrivilege::ContinueEntity(const char *pszEntityName,CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_CONTINUE, NULL, 0, 0, pAsynWaitSp); } ErrorCodeEnum SpEntityPrivilege::TestEntity(const char *pszEntityName,EntityTestEnum eTestType, CSmartPointer &pAsynWaitSp) { return ControlEntity(this, pszEntityName, SHELL_CMD_REQ_ENTITY_TEST, NULL, (int)eTestType, 0, pAsynWaitSp); } ErrorCodeEnum SpEntityPrivilege::RegistEntityLifeEvent(IEntityLifeListener *pListener) { if (!m_pEntityLifeListener) { sp_mod_entity_life_cb cb; cb.on_entity_close = &SpEntityPrivilege::__on_entity_close; cb.on_entity_create = &SpEntityPrivilege::__on_entity_create; cb.on_entity_exception = &SpEntityPrivilege::__on_entity_exception; cb.user_data = this; int rc = sp_mod_entity_life_listener_create(&cb, m_svc, pListener, &m_pEntityLifeListener); return SpTranslateError(rc); } else { return Error_Duplication; } } ErrorCodeEnum SpEntityPrivilege::UnregistLiftEvent() { if (!m_pEntityLifeListener) { return Error_NotInit; } else { sp_mod_entity_life_listener_destroy(m_pEntityLifeListener); m_pEntityLifeListener = NULL; return Error_Succeed; } } ErrorCodeEnum SpEntityPrivilege::RegistEntityStateEvent(const char *pszEntityName,IEntityStateListener *pListener) { sp_env_t *env = sp_get_env(); int target_ent_id; if (!pListener) return Error_Null; if (pszEntityName) { sp_entity_t *ent; ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszEntityName); if (!ent) return Error_NotExist; target_ent_id = ent->cfg->idx; } else { LOG_TRACE("registered state event for all entities!"); target_ent_id = -1; // regist for all entities pszEntityName = "*"; } ErrorCodeEnum Error = Error_Succeed; spinlock_enter(&m_maplock, -1); if (stringmap_find(m_pEntityStateListenerMap, pszEntityName) ){ Error = Error_AlreadyExist; } else { int rc; sp_mod_entity_state_listener_t *listener; sp_mod_entity_event_cb cb; cb.on_close_connection = &SpEntityPrivilege::__on_close_connection; cb.on_create_connection = &SpEntityPrivilege::__on_create_connection; cb.on_user_state = &SpEntityPrivilege::__on_user_state;; cb.on_entity_state = &SpEntityPrivilege::__on_entity_state; cb.user_data = this; rc = sp_mod_entity_listener_create(target_ent_id, &cb, m_svc, pListener, &listener); if (rc == 0) { stringmap_add(m_pEntityStateListenerMap, pszEntityName ? pszEntityName : "*", listener); } else { Error = SpTranslateError(rc); } } spinlock_leave(&m_maplock); return Error; } ErrorCodeEnum SpEntityPrivilege::UnregistEntityStateEvent(const char *pszEntityName) { ErrorCodeEnum Error = Error_Succeed; if (pszEntityName == NULL) { pszEntityName = "*"; } spinlock_enter(&m_maplock, -1); if (pszEntityName) { stringmap_kv_pair *kvp; kvp = stringmap_find(m_pEntityStateListenerMap, pszEntityName); if (kvp) { sp_mod_entity_state_listener_t *listener; listener = (sp_mod_entity_state_listener_t *)stringmap_kv_pair_get_value(kvp); stringmap_remove(m_pEntityStateListenerMap, pszEntityName); sp_mod_entity_listener_destroy(listener); } else { Error = Error_NotExist; } } else { // unregist all stringmap_iterator *it = stringmap_iterator_create(m_pEntityStateListenerMap); while (stringmap_iterator_next(it) == 0) { const char *ent_name = (const char*)stringmap_iterator_get_key(it); sp_mod_entity_state_listener_t *listener = (sp_mod_entity_state_listener_t *)stringmap_iterator_get_value(it); stringmap_remove(m_pEntityStateListenerMap, ent_name); sp_mod_entity_listener_destroy(listener); } stringmap_iterator_destroy(it); } spinlock_leave(&m_maplock); return Error; } ErrorCodeEnum SpEntityPrivilege::GetSpecifiedEntityState(const char* pszEntityName, EntityStateEnum& eEntityState, DWORD& dwUserState) { if (pszEntityName == NULL) { return Error_Param; } sp_env_t* env = sp_get_env(); sp_entity_t* ent; if (strlen(pszEntityName) == 0) { ent = m_ent; } else { ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszEntityName); } if (!ent) { return Error_NotExist; } eEntityState = (EntityStateEnum)ent->state; dwUserState = ent->user_state; return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::DisplayBlueScreen(const char *pszTitle) { ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); iobuffer_write(pkt, IOBUF_T_STR, pszTitle, -1); //int nBlueScreen = 1; //iobuffer_write(pkt, IOBUF_T_I4, &nBlueScreen, 0); Error = PostInfoShell(SHELL_CMD_INFO_BLUESCREEN_DISPLAY, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntityPrivilege::UndisplayBlueScreen() { ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); Error = PostInfoShell(SHELL_CMD_INFO_BLUESCREEN_UNDISPLAY, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntityPrivilege::Reboot(RebootTriggerEnum eTriggerReason,RebootWayEnum eWay) { ErrorCodeEnum Error; int v; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("call SpEntityPrivilege::Reboot, reason:%d, way:%d", eTriggerReason, eWay); iobuffer_t *pkt = iobuffer_create(-1, -1); v = eTriggerReason; iobuffer_write(pkt, IOBUF_T_I4, &v, 0); v = eWay; iobuffer_write(pkt, IOBUF_T_I4, &v, 0); Error = PostInfoShell(SHELL_CMD_INFO_MACHINE_REBOOT, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } bool SpEntityPrivilege::WriteInstallLog(const char *pszPackName, const char *pszLogText) { auto env = sp_get_env(); // 创建安装包日志文件 CSimpleStringA strInstallLogDir = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "InstallLog", env->dir->root_runinfo_path); if (!ExistsDirA(strInstallLogDir)) CreateDirA(strInstallLogDir, TRUE); // 写安装包日志 CSimpleStringA strInstallLog = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s.log", (const char*)strInstallLogDir, pszPackName); FILE *pInstallLog = fopen(strInstallLog, "a+"); if (pInstallLog == NULL) { LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("open install log file [%s] to write fail", pszPackName)); return false; } fprintf_s(pInstallLog, "[%s] %s\r\n", (const char*)CSmallDateTime::GetNow().ToTimeString(), pszLogText); fflush(pInstallLog); fclose(pInstallLog); return true; } bool SpEntityPrivilege::RecursiveCopyDir(const char *pszSourceDir, const char *pszDestDir, CSimpleStringA& strErrInfo) { array_header_t *arr; if (!ExistsDirA(pszSourceDir)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("source dir [%s] not exists", pszSourceDir); return false; } if (!ExistsDirA(pszDestDir)) { if (!CreateDirRecursiveA(pszDestDir)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create dir [%s] fail: %d", pszDestDir, GetLastError()); return false; } DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create dir [%s] succ", pszDestDir); } arr = fileutil_get_sub_files_a(pszSourceDir); if (arr) { int i; for (i = 0; i < arr->nelts; ++i) { char szDestFile[256] = { 0 }; char *file = ARRAY_IDX(arr, i, char*); strcpy(szDestFile, pszDestDir); if (szDestFile[strlen(szDestFile) - 1] != SPLIT_SLASH) strcat(szDestFile, SPLIT_SLASH_STR); strcat(szDestFile, strrchr(file, SPLIT_SLASH) + 1); if (!CopyFileA(file, szDestFile, FALSE)) { strErrInfo = CSimpleStringA::Format("copy file [%s] fail: %d", file, GetLastError()); DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy file [%s] fail: %d", file, GetLastError()); toolkit_array_free2(arr); return false; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy file [%s] succ", file); } toolkit_array_free2(arr); } arr = fileutil_get_sub_dirs_a(pszSourceDir); if (arr) { int i; for (i = 0; i < arr->nelts; ++i) { char szDestSubDir[256] = { 0 }; char *dir = ARRAY_IDX(arr, i, char*); strcpy(szDestSubDir, pszDestDir); if (szDestSubDir[strlen(szDestSubDir) - 1] != SPLIT_SLASH) strcat(szDestSubDir, SPLIT_SLASH_STR); strcat(szDestSubDir, strrchr(dir, SPLIT_SLASH) + 1); if (!RecursiveCopyDir(dir, szDestSubDir, strErrInfo)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy dir [%s] fail: %d", dir, GetLastError()); toolkit_array_free2(arr); return false; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy dir [%s] succ", dir); } toolkit_array_free2(arr); } return true; } // 创建新版本目录,拷贝当前版本bin、cfg、dep、mod、install.ini,并修改Shell.ini及install.ini中相关配置 ErrorCodeEnum SpEntityPrivilege::CreateInstallNewVersion(CVersion NewSoftwareVersion,const char *pszPackageName, CSimpleStringA& strErrInfo) { auto env = sp_get_env(); auto cfg = env->cfg; // 创建安装包日志文件 WriteInstallLog(pszPackageName, CSimpleStringA::Format("Create new version: [%s], pack: [%s]", (const char*)NewSoftwareVersion.ToString(), (const char*)pszPackageName)); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Create new version: [%s], pack: [%s]", (const char*)NewSoftwareVersion.ToString(), (const char*)pszPackageName); CSimpleStringA strCurVerPath = env->dir->base_path; CSimpleStringA strNewVerPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_ver_path, (const char*)NewSoftwareVersion.ToString()); auto &v = cfg->install_ini->install_version; CVersion curVersion(v.major, v.minor, v.revision, v.build); TOOLKIT_ASSERT(curVersion != NewSoftwareVersion); if (curVersion == NewSoftwareVersion) { LogError(Severity_Low, Error_Bug, 0, CSimpleStringA::Format("new ver [%s] equals current ver [%s]", (const char*)NewSoftwareVersion.ToString(), (const char*)curVersion.ToString())); strErrInfo = CSimpleStringA::Format("new ver [%s] equals current ver [%s]", (const char*)NewSoftwareVersion.ToString(), (const char*)curVersion.ToString()); return Error_Bug; } if (ExistsDirA(strNewVerPath)) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("new version dir [%s] already exist, delete it %s", (const char*)strNewVerPath, RemoveDirRecursiveA(strNewVerPath) ? "success" : "fail"); RemoveDirRecursiveA(strNewVerPath); } if (!CreateDirA(strNewVerPath, TRUE)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create new version dir fail: %d", GetLastError()); strErrInfo = CSimpleStringA::Format("create new version dir fail: %d", GetLastError()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create new version dir succ"); //增加错误信息字段,回传给上层应用 CSimpleStringA strErrMsg = ""; CSimpleStringA strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "bin", (const char*)strCurVerPath); CSimpleStringA strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "bin", (const char*)strNewVerPath); if (!RecursiveCopyDir(strSource, strDest, strErrMsg)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy bin dir fail"); strErrInfo = CSimpleStringA::Format("copy bin dir fail: %s", strErrMsg.GetData()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy bin dir succ"); strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "cfg", (const char*)strCurVerPath); strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "cfg", (const char*)strNewVerPath); if (!RecursiveCopyDir(strSource, strDest, strErrMsg)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy cfg dir fail"); strErrInfo = CSimpleStringA::Format("copy cfg dir fail: %s", strErrMsg.GetData()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy cfg dir succ"); strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "dep", (const char*)strCurVerPath); strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "dep", (const char*)strNewVerPath); if (!RecursiveCopyDir(strSource, strDest, strErrMsg)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy dep dir fail"); strErrInfo = CSimpleStringA::Format("copy dep dir fail: %s", strErrMsg.GetData()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy dep dir succ"); strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "mod", (const char*)strCurVerPath); strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "mod", (const char*)strNewVerPath); if (!RecursiveCopyDir(strSource, strDest, strErrMsg)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy mod dir fail"); strErrInfo = CSimpleStringA::Format("copy mod dir fail: %s", strErrMsg.GetData()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy mod dir succ"); strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "res", (const char*)strCurVerPath); strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "res", (const char*)strNewVerPath); // 检测res目录是否存在 if (ExistsDirA(strSource)) { if (!RecursiveCopyDir(strSource, strDest, strErrMsg)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy res dir fail"); strErrInfo = CSimpleStringA::Format("copy res dir fail: %s", strErrMsg.GetData()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy res dir succ"); } else { if (!CreateDirA(strDest, TRUE)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create res dir fail"); strErrInfo = "create res dir fail"; return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create res dir succ"); } strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "imdep", (const char*)strCurVerPath); strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "imdep", (const char*)strNewVerPath); // 检测imdep目录是否存在 if (ExistsDirA(strSource)) { if (!RecursiveCopyDir(strSource, strDest,strErrMsg)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy imdep dir fail"); strErrInfo = CSimpleStringA::Format("copy imdep dir fail: %s", strErrMsg.GetData()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy imdep dir succ"); } else { if (!CreateDirA(strDest, TRUE)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create imdep dir fail"); strErrInfo = "create imdep dir fail"; return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create imdep dir succ"); } strSource = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "install.ini", (const char*)strCurVerPath); strDest = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "install.ini", (const char*)strNewVerPath); if (!CopyFileA(strSource, strDest, FALSE)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy install.ini fail: %d", GetLastError()); strErrInfo = CSimpleStringA::Format("copy install.ini fail: %d", GetLastError()); return Error_Unexpect; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy install.ini succ"); // 修改新Shell.ini CSimpleStringA strShellVarIni = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "shellVar.ini", (const char*)env->dir->root_runinfo_path); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("update SoftwareVersion to %s", strShellVarIni); int nRet = inifile_format_write((const char*)strShellVarIni, "Main", "SoftwareVersion", "%d.%d.%d", NewSoftwareVersion.GetMajor(), NewSoftwareVersion.GetMinor(), NewSoftwareVersion.GetRevision()); //// 修改当前install.ini inifile_write_str(cfg->install_ini_path, "Main", "LatterInstallVersion", NewSoftwareVersion.ToString()); inifile_write_str(cfg->install_ini_path, "Main", "LatterInstallPack", pszPackageName); //inifile_write_str(cfg->install_ini_path, CurVersion.ToString(), "InstallState", "U"); // 修改新版本install.ini auto strNewInstallIni = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "install.ini", (const char*)strNewVerPath); TOOLKIT_ASSERT(ExistsFileA(strNewInstallIni)); char szNow[16] = {}; sprintf(szNow, "0x%08X", y2k_time_now()); // 缓存前版本轻量包记录 char *packs = inifile_read_str(strNewInstallIni, "Main", "LightPack", ""); nRet |= inifile_write_str(strNewInstallIni, "Main", "InstallVersion", NewSoftwareVersion.ToString()); nRet |= inifile_write_str(strNewInstallIni, "Main", "CreateDate", szNow); nRet |= inifile_write_str(strNewInstallIni, "Main", "LatterInstallVersion", ""); nRet |= inifile_write_str(strNewInstallIni, "Main", "LightPack", ""); nRet |= inifile_write_str(strNewInstallIni, "Main", "TotalRunCount", "1"); nRet |= inifile_write_str(strNewInstallIni, "Main", "TodayRunCount", "1"); nRet |= inifile_write_str(strNewInstallIni, "Main", "CurrentTime", szNow); nRet |= inifile_write_str(strNewInstallIni, NewSoftwareVersion.ToString(), "PreviousInstallVersion", curVersion.ToString()); nRet |= inifile_write_str(strNewInstallIni, NewSoftwareVersion.ToString(), "InstallPack", pszPackageName); nRet |= inifile_write_str(strNewInstallIni, NewSoftwareVersion.ToString(), "InstallState", "I"); // 正在安装 // 去掉所有历史版本中轻量安装记录 if (packs) { if (strlen(packs) >0) { char *p = NULL; while((p = strrchr(packs, ',')) != NULL) { *p = 0; WritePrivateProfileSectionA(p+1, NULL, strNewInstallIni); } WritePrivateProfileSectionA(packs, NULL, strNewInstallIni); } FREE(packs); } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("write version into install.ini done"); // 修改内存配置项 auto ver_info = (sp_cfg_version_info_t*)shm_malloc(sizeof(sp_cfg_version_info_t)); memset(ver_info, 0, sizeof(sp_cfg_version_info_t)); ver_info->version.major = NewSoftwareVersion.GetMajor(); ver_info->version.minor = NewSoftwareVersion.GetMinor(); ver_info->version.revision = NewSoftwareVersion.GetRevision(); ver_info->version.build = NewSoftwareVersion.GetBuild(); ver_info->previous_version.major = curVersion.GetMajor(); ver_info->previous_version.minor = curVersion.GetMinor(); ver_info->previous_version.revision = curVersion.GetRevision(); ver_info->previous_version.build = curVersion.GetBuild(); ver_info->install_pack = shm_strdup(pszPackageName); ver_info->install_state = Install_Pending; SHM_ARRAY_PUSH(cfg->install_ini->arr_version, sp_cfg_version_info_t*) = ver_info; cfg->install_ini->latter_install_version.major = NewSoftwareVersion.GetMajor(); cfg->install_ini->latter_install_version.minor = NewSoftwareVersion.GetMinor(); cfg->install_ini->latter_install_version.revision = NewSoftwareVersion.GetRevision(); cfg->install_ini->latter_install_version.build = NewSoftwareVersion.GetBuild(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("write version into share mem done"); return nRet == 0 ? Error_Succeed : Error_Unexpect; } ErrorCodeEnum SpEntityPrivilege::GenerateNewInstallCfg() { auto env = sp_get_env(); auto cfg = env->cfg; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Generate new install.ini to %s", cfg->install_ini_path); if (ExistsFile(cfg->install_ini_path)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("file exist, do not create, %s", cfg->install_ini_path); return Error_AlreadyExist; } char szVer[128]; char szNow[128]; y2k_time_t now; auto active_version = cfg->install_ini->install_version; auto szIniPath = cfg->install_ini_path; sprintf(szVer, "%d.%d.%d.%d", active_version.major, active_version.minor, active_version.revision, active_version.build); inifile_write_str(szIniPath, "Main", "InstallVersion", szVer); sprintf(szNow, "0x%08X", cfg->install_ini->install_time); inifile_write_str(szIniPath, "Main", "CreateDate", szNow); inifile_write_str(szIniPath, "Main", "LatterInstallVersion", ""); inifile_write_str(szIniPath, "Main", "LightPack", ""); inifile_write_str(szIniPath, "Main", "TotalRunCount", "0"); inifile_write_str(szIniPath, "Main", "TodayRunCount", "0"); inifile_write_str(szIniPath, "Main", "CurrentTime", szNow); inifile_write_str(szIniPath, szVer, "SwitchOverDate", szNow); inifile_write_str(szIniPath, szVer, "InstallPack", ""); inifile_write_str(szIniPath, szVer, "InstallState", "A"); return Error_Succeed; } ErrorCodeEnum CopyFolder(CSimpleStringA strSourcePath, CSimpleStringA strDestPath) { if (strSourcePath.IsNullOrEmpty() || strDestPath.IsNullOrEmpty()) { return Error_Null; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Start to copy dir %s to dir %s", (const char*)strSourcePath,(const char*)strDestPath); #ifdef _WIN32 _finddata_t FileInfo; CSimpleStringA strfind = strSourcePath + "\\*"; long Handle = _findfirst(strfind, &FileInfo); if (-1L == Handle) { _findclose(Handle); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("%s文件夹为空", strSourcePath); return Error_Succeed; } CSimpleStringA newPath; do{ if (FileInfo.attrib & _A_SUBDIR) { if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)) { newPath = strSourcePath + "\\" + FileInfo.name; CSimpleStringA newDestPath = strDestPath + "\\" + FileInfo.name; /*if (strcmp(FileInfo.name, "") == 0) { continue; }*/ if (!ExistsDirA(newDestPath)) { CreateDirA(newDestPath, TRUE); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Create Dir %s success", (const char*)newDestPath); } CopyFolder(newPath, newDestPath); } } else { CSimpleStringA strFindName = FileInfo.name; { CSimpleStringA strSourceFile = strSourcePath + "\\" + strFindName; CSimpleStringA strDestFile = strDestPath + "\\" + strFindName; if (ExistsFileA(strSourceFile)) { // 先去除目标文件只读属性 if (ExistsFileA(strDestFile)) RemoveFileReadOnlyAttributeA(strDestFile); LOG_TRACE("copy file from [%s] to [%s]", (const char*)strSourceFile, (const char*)strDestFile); BOOL bRet = CopyFileA(strSourceFile, strDestFile, FALSE); // 去除只读属性 if (bRet) RemoveFileReadOnlyAttributeA(strDestFile); else { // 覆盖失败,则生成.new副本 DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy file [%s] to [%s] fail, now save as .new file", (const char*) strSourcePath, (const char*) strDestFile); strDestFile += ".new"; bRet = CopyFileA(strSourceFile, strDestFile, FALSE); if (bRet) { RemoveFileReadOnlyAttributeA(strDestPath); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy [%s] as [%s] succeed", (const char*)strSourceFile, (const char*) strDestFile); } else { LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("copy file [%s] as [%s] fail", (const char*) strSourceFile, (const char*) strDestFile)); return Error_Block; } } } else { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("file [%s] to copy not exists", (const char*)strSourceFile)); return Error_NotExist; } } } } while (_findnext(Handle, &FileInfo) == 0); _findclose(Handle); return Error_Succeed; #else if (CopyDirA(strSourcePath, strDestPath)) { return Error_Succeed; } return Error_Unexpect; #endif //_WIN32 } CSimpleStringA GetFileDirectory(const char *pszFullPath) { int i=strlen(pszFullPath)-1; for( ; i>0 && pszFullPath[i]!=SPLIT_SLASH; i--)NULL; return CSimpleStringA(pszFullPath, i); } ErrorCodeEnum SpEntityPrivilege::BeginLightInstall(const char *pszPackageName) { // 创建安装包日志文件 WriteInstallLog(pszPackageName, CSimpleStringA::Format("Begin install light pack: [%s]", pszPackageName)); CSimpleStringA strAdPath; auto rc = GetPath("Ad", strAdPath); TOOLKIT_ASSERT(rc == Error_Succeed); CSimpleStringA strDownloadsPath; rc = GetPath("Downloads", strDownloadsPath); TOOLKIT_ASSERT(rc == Error_Succeed); CSimpleStringA strUnzipPath = CSimpleStringA::Format( "%s" SPLIT_SLASH_STR "%s", (const char*)strDownloadsPath, (const char*)pszPackageName); if (strUnzipPath.IsEndWith(".zip") || strUnzipPath.IsEndWith(".cab")) strUnzipPath = strUnzipPath.SubString(0, strUnzipPath.GetLength()-4); auto strConfigPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "Run.ini", (const char*)strUnzipPath); // 检查文件是否存在 DWORD attr = GetFileAttributesA(strConfigPath); TOOLKIT_ASSERT((attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY)); char *p = inifile_read_str(strConfigPath, "Action", "ToCopy", ""); CSimpleStringA strToCopy = p; FREE(p); //TOOLKIT_ASSERT(!strToCopy.IsNullOrEmpty()); if (strToCopy.IsNullOrEmpty()) { LogError(Severity_Low, Error_Null, 0, "file to copy not define"); return Error_Null; } #if defined(RVC_OS_LINUX) std::string strCopy = strToCopy.GetData(); std::replace(strCopy.begin(), strCopy.end(), '\\', SPLIT_SLASH); strToCopy = strCopy.c_str(); #endif //RVC_OS_LINUX auto list = strToCopy.Split(','); for(int i=0; i0) { CSimpleStringA strSourcePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strUnzipPath, (const char*)GetFileDirectory(file)); CSimpleStringA StrDirToCopy = GetFileDirectory(file).SubString(5, file.GetLength()-5); CSimpleStringA strDestPath = ""; if (StrDirToCopy.IsNullOrEmpty()) { strDestPath = strAdPath; } else { strDestPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strAdPath, (const char*)GetFileDirectory(file).SubString(5, file.GetLength()-5)); } rc = CopyFolder(strSourcePath, strDestPath); if (Error_Succeed != rc) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("copy dir [%s] to dir [%s] fail", (const char*)strSourcePath, (const char*)strDestPath)); } } else { CSimpleStringA strSourcePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strUnzipPath, (const char*)file); CSimpleStringA strDestPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strAdPath, (const char*)file.SubString(5, file.GetLength()-5)); if (ExistsFileA(strSourcePath)) { // 先去除目标文件只读属性 if (ExistsFileA(strDestPath)) RemoveFileReadOnlyAttributeA(strDestPath); LOG_TRACE("copy file from [%s] to [%s]", (const char*)strSourcePath, (const char*)strDestPath); BOOL bRet = CopyFileA(strSourcePath, strDestPath, FALSE); // 去除只读属性 if (bRet) RemoveFileReadOnlyAttributeA(strDestPath); else { // 覆盖失败,则生成.new副本 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy file [%s] to [%s] fail, now save as .new file", (const char*) strSourcePath, (const char*) strDestPath); strDestPath += ".new"; bRet = CopyFileA(strSourcePath, strDestPath, FALSE); if (bRet) { RemoveFileReadOnlyAttributeA(strDestPath); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("copy [%s] as [%s] succeed", (const char*)strSourcePath, (const char*) strDestPath); } else { LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("copy file [%s] as [%s] fail", (const char*) strSourcePath, (const char*) strDestPath)); return Error_Block; } } } else { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("file [%s] to copy not exists", (const char*)strSourcePath)); return Error_NotExist; } } } else { LogError(Severity_Low, Error_NoPrivilege, 0, CSimpleStringA::Format("light pack [%s] has invalid copy item: [%s]", (const char*)pszPackageName, (const char*)file)); return Error_NoPrivilege; } } // 登录到安装记录文件中 sp_env_t *env = sp_get_env(); auto cfg = env->cfg; CSimpleStringA strPackName = pszPackageName; CSimpleStringA strLightPacks = cfg->install_ini->light_packs; if (!strLightPacks.IsNullOrEmpty()) strLightPacks += ","; strLightPacks += strPackName; inifile_write_str(cfg->install_ini_path, "Main", "LightPack", strLightPacks); shm_free(cfg->install_ini->light_packs); cfg->install_ini->light_packs = shm_strdup(strLightPacks); // 修改内存配置项 sp_cfg_pack_info_t *pack_info = (sp_cfg_pack_info_t*)shm_malloc(sizeof(sp_cfg_pack_info_t)); memset(pack_info, 0, sizeof(sp_cfg_pack_info_t)); pack_info->name = shm_strdup(strPackName); pack_info->install_time = y2k_time_now(); pack_info->state = Install_Installed; SHM_ARRAY_PUSH(cfg->install_ini->arr_light_pack, sp_cfg_pack_info_t*) = pack_info; inifile_format_write(cfg->install_ini_path, strPackName, "InstalledDate", "0x%08X", y2k_time_now()); inifile_write_str(cfg->install_ini_path, strPackName, "PackState", "U"); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("install light pack [%s] succeed", (const char*)strPackName); return Error_Succeed; } #ifdef _WIN32 bool SpEntityPrivilege::IsWow64Process() { typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process"); BOOL bIsWow64 = FALSE; if (NULL != fnIsWow64Process) { if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("call IsWow64Process error: %d", GetLastError()); return false; } return bIsWow64 == TRUE; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get IsWow64Process error: %d", GetLastError()); return false; } } #endif //_WIN32 // result=0&msg=install ok bool SpEntityPrivilege::GetSysUpgradeResult(const char *pszResultLog, ErrorCodeEnum &eErrorCode, CSimpleStringA &strErrMsg) { // 设置初始值 eErrorCode = Error_Succeed; strErrMsg = ""; if (!ExistsFileA(pszResultLog)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)(CSimpleStringA::Format("result log [%s] not exist", pszResultLog)); strErrMsg = "result.log not exist"; return false; } FILE *pResultLog = fopen(pszResultLog, "r"); if (pResultLog == NULL) { LogError(Severity_Low, Error_Unexpect, 0, CSimpleStringA::Format("open result log [%s] fail", pszResultLog)); strErrMsg = "open result.log fail"; return false; } char szTmp[4096] = {}; int nRead = fread_s(szTmp, sizeof(szTmp), 1, sizeof(szTmp), pResultLog); CSimpleStringA strResult = szTmp; fclose(pResultLog); pResultLog = NULL; auto arr = strResult.Split('&'); for (int i = 0; i < arr.GetCount(); i++) { auto arr2 = arr[i].Split('='); if (arr2.GetCount() == 2) { if (stricmp(arr2[0], "result") == 0) eErrorCode = (ErrorCodeEnum)(DWORD)atoi(arr2[1]); else if (stricmp(arr2[0], "msg") == 0) strErrMsg = arr2[1]; } } return true; } // 执行系统外升级 ErrorCodeEnum SpEntityPrivilege::BeginSysPackInstall(const char *pszPackageName, CSimpleStringA &strErrMsg) { // 创建安装包日志文件 strErrMsg = ""; WriteInstallLog(pszPackageName, CSimpleStringA::Format("begin install os pack: [%s]", pszPackageName)); CSimpleStringA strDownloadsPath; auto rc = GetPath("Downloads", strDownloadsPath); TOOLKIT_ASSERT(rc == Error_Succeed); CSimpleStringA strUnzipPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strDownloadsPath, (const char*)pszPackageName); if (strUnzipPath.IsEndWith(".zip") || strUnzipPath.IsEndWith(".cab")) strUnzipPath = strUnzipPath.SubString(0, strUnzipPath.GetLength() - 4); auto strConfigPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "Run.ini", (const char*)strUnzipPath); // 检查文件是否存在 DWORD attr = GetFileAttributesA(strConfigPath); TOOLKIT_ASSERT((attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY)); // ToRun=install.bat char *p = inifile_read_str(strConfigPath, "Action", "ToRun", ""); CSimpleStringA strToRun = p; FREE(p); //TOOLKIT_ASSERT(!strToCopy.IsNullOrEmpty()); if (strToRun.IsNullOrEmpty()) { strErrMsg = "未定义执行文件[ToRun]"; LogError(Severity_Low, Error_Null, 0, "file to run not define"); return Error_Null; } ErrorCodeEnum eErrorCode = Error_Succeed; auto list = strToRun.Split(','); for (int i = 0; i < list.GetCount(); i++) { auto &file = list[i]; CSimpleStringA strSourcePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strUnzipPath, (const char*)file); if (ExistsFileA(strSourcePath)) { #ifdef _WIN32 // 如果是Wow64模式,需屏蔽System32重定向 PVOID pRedirectOldValue(NULL); bool bIsWow64 = IsWow64Process(); if (bIsWow64) { if (!Wow64DisableWow64FsRedirection(&pRedirectOldValue)) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Wow64DisableWow64FsRedirection fail: %d", GetLastError()); else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Wow64DisableWow64FsRedirection succ"); } #endif //_WIN32 // xkm@20161114: 执行完成,从result.txt中读取安装结果 system(strSourcePath); CSimpleStringA strResultLog = strUnzipPath + SPLIT_SLASH_STR "result.log"; if (!GetSysUpgradeResult(strResultLog, eErrorCode, strErrMsg)) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get upgrade result from result.log fail, %s", (const char*)strErrMsg); /** ?? [Gifur@202268]*/ eErrorCode = Error_Succeed; strErrMsg = ""; } #ifdef _WIN32 // 如果是Wow64模式,恢复System32重定向 if (bIsWow64) { if (!Wow64RevertWow64FsRedirection(pRedirectOldValue)) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Wow64RevertWow64FsRedirection fail: %d", GetLastError()); else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Wow64RevertWow64FsRedirection succ"); } #endif //_WIN32 if (eErrorCode != Error_Succeed) { LogError(Severity_Low, Error_UpdateFailed, 0, CSimpleStringA::Format("run file [%s] error: %s(%d)", (const char*)file, (const char*)strErrMsg, eErrorCode)); WriteInstallLog(pszPackageName, CSimpleStringA::Format("run file [%s] error: %s(%d)", (const char*)file, (const char*)strErrMsg, eErrorCode)); return eErrorCode; } } else { strErrMsg = "指定执行文件不存在"; LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("file [%s] to run not exists", (const char*)strSourcePath)); WriteInstallLog(pszPackageName, CSimpleStringA::Format("file [%s] to run not exists", (const char*)strSourcePath)); return Error_NotExist; } } WriteInstallLog(pszPackageName, "install sys pack succ"); // 登录到安装记录文件中 sp_env_t *env = sp_get_env(); auto cfg = env->cfg; CSimpleStringA strPackName = pszPackageName; char *pszSysPacks = inifile_read_str(cfg->install_ini_path, "Main", "SysPack", ""); CSimpleStringA strSysPacks = pszSysPacks; FREE(pszSysPacks); if (!strSysPacks.IsNullOrEmpty()) strSysPacks += ","; strSysPacks += pszPackageName; inifile_write_str(cfg->install_ini_path, "Main", "SysPack", strSysPacks); inifile_format_write(cfg->install_ini_path, strPackName, "InstalledDate", "0x%08X", y2k_time_now()); inifile_write_str(cfg->install_ini_path, strPackName, "PackState", "U"); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("install sys pack [%s] succ", (const char*)strPackName); return Error_Succeed; } // 判断是否是已安装的系统外升级包 ErrorCodeEnum SpEntityPrivilege::IsInstalledSysPack(const char *pszPackageName) { // 登录到安装记录文件中 sp_env_t *env = sp_get_env(); auto cfg = env->cfg; CSimpleStringA strPackName = pszPackageName; // 查询系统外升级包 char *p = inifile_read_str(cfg->install_ini_path, "Main", "SysPack", ""); CSimpleStringA strSysPackList = p; FREE(p); if (!strSysPackList.IsNullOrEmpty() && (strSysPackList.IndexOf(strPackName)!= -1)) { return Error_Succeed; } return Error_Unexpect; } ErrorCodeEnum SpEntityPrivilege::CopyFileToNewVersion(const char *pszRelativeFile, int nCopyMode) { auto env = sp_get_env(); auto cfg = env->cfg; // 取到新版本安装包名称 char *p = inifile_read_str(cfg->install_ini_path, "Main", "LatterInstallVersion", ""); CSimpleStringA strNewVer = p; FREE(p); TOOLKIT_ASSERT(!strNewVer.IsNullOrEmpty()); CSimpleStringA strNewInstallIni = CSimpleStringA::Format( #ifdef _WIN32 "%s\\%s\\install.ini", #else "%s/%s/install.ini", #endif //_WIN32 env->dir->root_ver_path, (const char*)strNewVer); TOOLKIT_ASSERT(ExistsFileA(strNewInstallIni)); p = inifile_read_str(strNewInstallIni, strNewVer, "InstallPack", ""); CSimpleStringA strPackName = p; FREE(p); TOOLKIT_ASSERT(!strPackName.IsNullOrEmpty()); // 取得临时解压目录 CSimpleStringA strDownloadsPath; auto rc = GetPath("Downloads", strDownloadsPath); TOOLKIT_ASSERT(rc == Error_Succeed); CSimpleStringA strUnzipPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strDownloadsPath, (const char*)strPackName); if (strUnzipPath.IsEndWith(".zip") || strUnzipPath.IsEndWith(".cab")) strUnzipPath = strUnzipPath.SubString(0, strUnzipPath.GetLength()-4); CSimpleStringA strCopyPath = pszRelativeFile; CSimpleStringA strSourceFile; CSimpleStringA strDestFile; if (strCopyPath.IsStartWith("Data" SPLIT_SLASH_STR)) { CSimpleStringA strAdPath; rc = GetPath("Ad", strAdPath); TOOLKIT_ASSERT(rc == Error_Succeed); strSourceFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strUnzipPath, (const char*)strCopyPath); strDestFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strAdPath, (const char*)strCopyPath.SubString(5, strCopyPath.GetLength()-5)); } else if (strCopyPath.IsStartWith("Run" SPLIT_SLASH_STR)) { strSourceFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strUnzipPath, (const char*)strCopyPath); CSimpleStringA strNewVerPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_ver_path, (const char*)strNewVer); strDestFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s",(const char*) strNewVerPath, (const char*)strCopyPath.SubString(4, strCopyPath.GetLength()-4)); } else { WriteInstallLog(strPackName, CSimpleStringA::Format("Copy file: [%s], result: [0x%X]", pszRelativeFile, Error_NoPrivilege)); LogError(Severity_Low, Error_NoPrivilege, 0, CSimpleStringA::Format("invalid copy item: [%s], must start with \"Data\" or \"Run\"", (const char*)pszRelativeFile)); return Error_NoPrivilege; } //TOOLKIT_ASSERT(ExistsFileA(strSourceFile)); if (!ExistsFileA(strSourceFile)) { WriteInstallLog(strPackName, CSimpleStringA::Format("Copy file: [%s], result: [0x%X]", pszRelativeFile, Error_NotExist)); LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("file [%s] to copy not exist", (const char*)strSourceFile)); return Error_NotExist; } //#ifdef _DEBUG // bool bVerifySign = false; //#else // bool bVerifySign = true; //#endif // // if (bVerifySign && (strSourceFile.IsEndWith(".dll", true) || strSourceFile.IsEndWith(".exe", true))) // { // CSimpleStringA strErrMsg; // if (VerifySignature(strSourceFile, strErrMsg) != Error_Succeed) // { // WriteInstallLog(strPackName, CSimpleStringA::Format("file [%s] sign verify not pass: %s", pszRelativeFile, (const char*)strErrMsg)); // LogError(Severity_Low, Error_FailVerify, 0, CSimpleStringA::Format("file [%s] sign verify not pass: %s", (const char*)strSourceFile, (const char*)strErrMsg)); // return Error_FailVerify; // } // } // check dest dir if exists auto strDestDir = GetFileDirectory(strDestFile); if (!ExistsDirA(strDestDir)) CreateDirA(strDestDir, TRUE); BOOL bDestFileExists = ExistsFileA(strDestFile); if (bDestFileExists) RemoveFileReadOnlyAttributeA(strDestFile); BOOL bRet = TRUE; // 1(copy only exisit); 2(copy only not exist); 3(copy always); 4(no copy if exist) switch (nCopyMode) { case 1: { if (bDestFileExists) bRet= CopyFileA(strSourceFile, strDestFile, FALSE); else LOG_TRACE("ignore file [%s] copy for dest file not exists", pszRelativeFile); } break; case 2: { if (!bDestFileExists) bRet= CopyFileA(strSourceFile, strDestFile, TRUE); else LOG_TRACE("ignore file [%s] copy for dest file exists", pszRelativeFile); } break; case 3: bRet= CopyFileA(strSourceFile, strDestFile, FALSE); break; case 4: { // 不发生拷贝,只进行判断 if(bDestFileExists) LOG_TRACE("file [%s] exist", pszRelativeFile); else LOG_TRACE("file [%s] not exist", pszRelativeFile); } break; } if (bRet) RemoveFileReadOnlyAttributeA(strDestFile); rc = bRet ? Error_Succeed : Error_Unexpect; WriteInstallLog(strPackName, CSimpleStringA::Format("Copy file: [%s], result: [0x%X]", pszRelativeFile, rc)); return rc; } // File*A.* bool SpEntityPrivilege::IsFileMatch(const char *pszFilter, const char *pszFileName) { if (stricmp(pszFilter, "*") == 0 || stricmp(pszFilter, "*.*") == 0) return true; const char *p1 = pszFilter; const char *p2 = pszFileName; if (p1 == NULL) return true; if (p2 == NULL) return false; if (*p1 ==NULL && *p2 ==NULL) return true; else if (*p1 == NULL) return false; else if (*p2 == NULL) { // 查找*p1是否全是* while(*p1 == '*') p1++; if (*p1 == NULL) return true; else return false; } if (*p1 != '*') { if (tolower(*p1) != tolower(*p2)) return false; else return IsFileMatch(p1+1, p2+1); } else { while(*++p1 == '*'); if (*p1 == NULL) return true; while (*p2) { while(tolower(*p1) != tolower(*p2) && *++p2); if (*p2 == NULL) return false; if(IsFileMatch(p1+1, p2+1)) return true; p2++; } return false; } } CSimpleStringA SpEntityPrivilege::GetFileDirectory(const char *pszFullPath) { int i=strlen(pszFullPath); for( ; i>0 && pszFullPath[i-1]!=SPLIT_SLASH; i--)NULL; return CSimpleStringA(pszFullPath, i); } ErrorCodeEnum SpEntityPrivilege::DeleteFileInNewVersion(const char *pszRelativeFile) { auto env = sp_get_env(); auto cfg = env->cfg; // 取到新版本安装包名称 char *p =inifile_read_str(cfg->install_ini_path, "Main", "LatterInstallVersion", ""); CSimpleStringA strNewVer = p; FREE(p); CSimpleStringA strNewInstallIni = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s" SPLIT_SLASH_STR "install.ini" , env->dir->root_ver_path, (const char*)strNewVer); TOOLKIT_ASSERT(ExistsFileA(strNewInstallIni)); p = inifile_read_str(strNewInstallIni, strNewVer, "InstallPack", ""); CSimpleStringA strPackName = p; FREE(p); TOOLKIT_ASSERT(!strPackName.IsNullOrEmpty()); CSimpleStringA strDelFile = pszRelativeFile; CSimpleStringA strDestFile; if (strDelFile.IsStartWith("Data" SPLIT_SLASH_STR)) { CSimpleStringA strAdPath; auto rc = GetPath("Ad", strAdPath); TOOLKIT_ASSERT(rc == Error_Succeed); strDestFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strAdPath, (const char*)strDelFile.SubString(5, strDelFile.GetLength()-5)); } else if (strDelFile.IsStartWith("Run" SPLIT_SLASH_STR)) { CSimpleStringA strNewVerPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_ver_path, (const char*)strNewVer); TOOLKIT_ASSERT(ExistsDirA(strNewVerPath)); strDestFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strNewVerPath, (const char*)strDelFile.SubString(4, strDelFile.GetLength()-4)); } else { WriteInstallLog(strPackName, CSimpleStringA::Format("Delete file: [%s], result: [%d]", pszRelativeFile, Error_NoPrivilege)); LogError(Severity_Low, Error_NoPrivilege, 0, CSimpleStringA::Format("invalid delete item: [%s], must start with \"Data\" or \"Run\"", (const char*)pszRelativeFile)); return Error_NoPrivilege; } // 解析文件通配符* BOOL bRet = TRUE; int nIndex = strDestFile.IndexOf("*"); if (nIndex > 0) { CSimpleStringA strFileFilter = _GetFileName(strDestFile); CSimpleStringA strDestDir = strDestFile.SubString(0, strDestFile.GetLength()-strFileFilter.GetLength()-1); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("delete wildchar file [%s] in dir [%s]", (const char*)strFileFilter, (const char*)strDestDir); // 删除所有匹配文件 auto arr = fileutil_get_sub_files(strDestDir); if (arr != NULL) { for (int i = 0; i < arr->nelts; ++i) { char *file = ARRAY_IDX(arr, i, char*); if (IsFileMatch(strFileFilter, _GetFileName(file))) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("delete match file: [%s]", file); bRet &= RemoveFileA(file); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ignore not match file: [%s]", file); } } toolkit_array_free2(arr); } // xkm@20170302: 删除所有匹配子目录 auto subdirs = fileutil_get_sub_dirs(strDestDir); if (subdirs != NULL) { for (int i = 0; i < subdirs->nelts; ++i) { const char *dir = ARRAY_IDX(subdirs, i, char*); if (IsFileMatch(strFileFilter, _GetFileName(dir))) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("delete match dir: [%s]", dir); bRet &= RemoveDirRecursive(dir); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("ignore not match dir: [%s]", dir); } } toolkit_array_free2(subdirs); } } else { if (ExistsFileA(strDestFile)) { bRet = DeleteFileA(strDestFile); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("delete file [%s] result: %d", strDestFile, bRet); } else if (ExistsDirA(strDestFile)) { bRet = RemoveDirRecursive(strDestFile); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("delete dir [%s] result: %d", strDestFile, bRet); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("delete file [%s] fail, not exists", pszRelativeFile); } } auto rc = bRet ? Error_Succeed : Error_Unexpect; WriteInstallLog(strPackName, CSimpleStringA::Format("Delete file: [%s], result: [%d]", pszRelativeFile, rc)); return rc; } ErrorCodeEnum SpEntityPrivilege::RollBackToPreviousVersion() { auto env = sp_get_env(); auto cfg = env->cfg; // 修改当前Install.ini配置 auto &v = cfg->install_ini->install_version; CVersion curVersion(v.major, v.minor, v.revision, v.build); CInstallInfo info = {}; auto rc = GetInstallInfo(curVersion, info); TOOLKIT_ASSERT(rc == Error_Succeed); if (!info.PreviousInstallVersion.IsValid()) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("current version [%s] has no previous version", (const char*)curVersion.ToString())); return Error_NotExist; } auto strPrevVersion = info.PreviousInstallVersion.ToString(); // 检查对应文件夹是否存在 CSimpleStringA strPreVerPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_ver_path, (const char*)strPrevVersion); if (!ExistsDirA(strPreVerPath)) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("previous version dir [%s] not exists", (const char*)strPreVerPath)); return Error_NotExist; } // 修改当前版本状态为倒回R int nRet = inifile_write_str(cfg->install_ini_path, curVersion.ToString(), "InstallState", "R"); // 更新回退次数 auto nTotalRollbackCount = inifile_read_int(cfg->install_ini_path, curVersion.ToString(), "TotalRollbackCount", 0); nTotalRollbackCount++; nRet = inifile_write_int(cfg->install_ini_path, curVersion.ToString(), "TotalRollbackCount", nTotalRollbackCount); if (-1 == nRet) { LogError(Severity_Low, Error_Unexpect, 0, "inifile_write_int TotalRollbackCount"); } LOG_TRACE("inifile_write_int, nTotalRollbackCount[%d]", nTotalRollbackCount); // 修改active.txt文件 CSimpleStringA strActiveFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "active.txt", env->dir->root_ver_path); HANDLE hFile = ::CreateFileA(strActiveFile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); BOOL bSetSucc = FALSE; if (hFile == INVALID_HANDLE_VALUE) { LogError(Severity_Low, Error_Unexpect, 0, "open active.txt fail"); return Error_Unexpect; } DWORD dwWrittenLen(0); bSetSucc = WriteFile(hFile, (const char*)strPrevVersion, strPrevVersion.GetLength(), &dwWrittenLen, NULL); FlushFileBuffers(hFile); SetEndOfFile(hFile); CloseHandle(hFile); LOG_TRACE("set rollback to previous version [%s] succeed", (const char*)strPrevVersion); //出现active文件为空的问题,此处增加写文件件后再读一次,确认是否写成功,以此来确认是否是写文件导致 if (1) { hFile = ::CreateFileA(strActiveFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { LogError(Severity_Low, Error_Unexpect, 0, "open active.txt fail"); return Error_Unexpect; } DWORD dwReadLen(0); char cVer[16] = { 0 }; if (ReadFile(hFile, cVer, 16, &dwReadLen, NULL)) { LOG_TRACE("read active.txt, version len[%d], version[%s]", dwReadLen, cVer); //如果为空,则重写 if (strlen(cVer) == 0) { if (WriteFile(hFile, (const char*)strPrevVersion, strPrevVersion.GetLength(), &dwWrittenLen, NULL)) { LOG_TRACE("rewrite active.txt success, strPrevVersion[%s]", strPrevVersion); } else { LogError(Severity_Low, Error_Unexpect, 0, "rewrite active.txt fail"); } } } else { LogError(Severity_Low, Error_Unexpect, 0, "Read active.txt fail"); } FlushFileBuffers(hFile); SetEndOfFile(hFile); CloseHandle(hFile); } return bSetSucc ? Error_Succeed : Error_Unexpect; } ErrorCodeEnum SpEntityPrivilege::RollBackToHistoryVersion(CVersion historyVersion) { auto env = sp_get_env(); auto cfg = env->cfg; // 判断目标版本是否小于当前版本 auto &v = cfg->install_ini->install_version; CVersion curVersion(v.major, v.minor, v.revision, v.build); if (curVersion <= historyVersion) { LogError(Severity_Low, Error_Param, 0, CSimpleStringA::Format("history version [%s] >= current version [%s]", (const char*)historyVersion.ToString(), (const char*)curVersion.ToString())); return Error_Param; } // 修改当前Install.ini配置 CInstallInfo info= {}; auto rc = GetInstallInfo(historyVersion, info); if (rc != Error_Succeed) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("history version [%s] to rollback not exist", (const char*)historyVersion.ToString())); return Error_NotExist; } // 检查对应文件夹是否存在 CSimpleStringA strHisVersion = historyVersion.ToString(); CSimpleStringA strHisVerPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_ver_path, (const char*)strHisVersion); if (!ExistsDirA(strHisVerPath)) { LogError(Severity_Low, Error_NotExist, 0, CSimpleStringA::Format("history version dir [%s] not exists", (const char*)strHisVerPath)); return Error_NotExist; } // 修改当前版本状态为倒回R int nRet = inifile_write_str(cfg->install_ini_path, curVersion.ToString(), "InstallState", "R"); // 更新回退次数 auto nTotalRollbackCount = inifile_read_int(cfg->install_ini_path, curVersion.ToString(), "TotalRollbackCount", 0); nTotalRollbackCount++; nRet = inifile_write_int(cfg->install_ini_path, curVersion.ToString(), "TotalRollbackCount", nTotalRollbackCount); if (-1 == nRet) { LogError(Severity_Low, Error_Unexpect, 0, "inifile_write_int TotalRollbackCount"); } LOG_TRACE("inifile_write_int, nTotalRollbackCount[%d]", nTotalRollbackCount); // 修改active.txt文件 CSimpleStringA strActiveFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "active.txt", env->dir->root_ver_path); HANDLE hFile = ::CreateFileA(strActiveFile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); BOOL bSetSucc = FALSE; if (hFile == INVALID_HANDLE_VALUE) { LogError(Severity_Low, Error_Unexpect, 0, "open active.txt fail"); return Error_Unexpect; } DWORD dwWrittenLen(0); bSetSucc = WriteFile(hFile, (const char*)strHisVersion, strHisVersion.GetLength(), &dwWrittenLen, NULL); FlushFileBuffers(hFile); SetEndOfFile(hFile); CloseHandle(hFile); //出现active文件为空的问题,此处增加写文件件后再读一次,确认是否写成功,以此来确认是否是写文件导致 if (1) { hFile = ::CreateFileA(strActiveFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { LogError(Severity_Low, Error_Unexpect, 0, "open active.txt fail"); return Error_Unexpect; } DWORD dwReadLen(0); char cVer[16] = {0}; if (ReadFile(hFile,cVer,16,&dwReadLen,NULL)) { LOG_TRACE("read active.txt, version len[%d], version[%s]", dwReadLen, cVer); } else { LogError(Severity_Low, Error_Unexpect, 0, "Read active.txt fail"); } CloseHandle(hFile); } LOG_TRACE("set rollback to history version [%s] succeed", (const char*)strHisVersion); return bSetSucc ? Error_Succeed : Error_Unexpect; } ErrorCodeEnum SpEntityPrivilege::UpgradeToNewVersion(bool bToSysInstall) { auto env = sp_get_env(); auto cfg = env->cfg; // 修改当前Install.ini配置 auto &v = cfg->install_ini->install_version; CVersion curVersion(v.major, v.minor, v.revision, v.build); int nRet = inifile_write_str(cfg->install_ini_path, curVersion.ToString(), "InstallState", "U"); // 已升级 // 取到新版本 char *p = inifile_read_str(cfg->install_ini_path, "Main", "LatterInstallVersion", ""); CSimpleStringA strNewVer = p; FREE(p); //TOOLKIT_ASSERT(!strNewVer.IsNullOrEmpty()); if (strNewVer.IsNullOrEmpty()) { LogError(Severity_Low, Error_Unexpect, 0, "install.ini Main LatterInstallVersion is null"); return Error_Unexpect; } CSimpleStringA strNewVerPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_ver_path, (const char*)strNewVer); // 修改新版本install.ini auto strNewInstallIni = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "install.ini", (const char*)strNewVerPath); TOOLKIT_ASSERT(ExistsFileA(strNewInstallIni)); // 取新版本安装包名称 p = inifile_read_str(strNewInstallIni, strNewVer, "InstallPack", ""); CSimpleStringA strPackName = p; FREE(p); TOOLKIT_ASSERT(!strPackName.IsNullOrEmpty()); WriteInstallLog(strPackName, "Upgrade to new version"); nRet &= inifile_write_str(strNewInstallIni, curVersion.ToString(), "InstallState", "U"); // 已升级 nRet &= inifile_write_str(strNewInstallIni, strNewVer, "InstallState", "S"); // 设置启动 // 修改active.txt配置 CSimpleStringA strActiveFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "active.txt", env->dir->root_ver_path); HANDLE hFile = ::CreateFileA(strActiveFile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); BOOL bSetSucc = (nRet == 0); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwWrittenLen(0); bSetSucc = bSetSucc && WriteFile(hFile, (const char*)strNewVer, strNewVer.GetLength(), &dwWrittenLen, NULL); FlushFileBuffers(hFile); SetEndOfFile(hFile); CloseHandle(hFile); LOG_TRACE("WriteFile [%s] to active.txt", (const char*)strNewVer); } else { bSetSucc = FALSE; LogError(Severity_Low, Error_Unexpect, 0, "open active.txt fail"); } //出现active文件为空的问题,此处增加写文件件后再读一次,确认是否写成功,以此来确认是否是写文件导致 if (1) { hFile = ::CreateFileA(strActiveFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { LogError(Severity_Low, Error_Unexpect, 0, "open active.txt fail"); return Error_Unexpect; } DWORD dwReadLen(0); char cVer[16] = {0}; if (ReadFile(hFile,cVer,16,&dwReadLen,NULL)) { LOG_TRACE("read active.txt, version len[%d], version[%s]", dwReadLen, cVer); } else { LogError(Severity_Low, Error_Unexpect, 0, "Read active.txt fail"); } CloseHandle(hFile); } // 修改内存配置 if (bSetSucc) { sp_version_t newVersion = {}; sscanf((const char*)strNewVer, "%d.%d.%d.%d", &newVersion.major, &newVersion.minor, &newVersion.revision, &newVersion.build); auto newVerInfo = sp_cfg_find_version_info(cfg, &newVersion); if (newVerInfo != NULL) newVerInfo->install_state = Install_SetToStart; LOG_TRACE("set new version [%s] active", (const char*)strNewVer); return Error_Succeed; } else { LogError(Severity_Low, Error_Unexpect, 0, "switch to new version fail"); } return Error_Unexpect; } ErrorCodeEnum SpEntityPrivilege::SetRunSucceed() { sp_env_t *env = sp_get_env(); auto cfg = env->cfg; // 修改内存状态 auto pVerInfo = sp_cfg_find_version_info(cfg, &cfg->install_ini->install_version); pVerInfo->install_state = Install_Active; // 安装成功 // 设置后一版本状态为倒回 if (sp_version_is_valid(&cfg->install_ini->latter_install_version)) { // 修改后一版本安装文件状态为倒回 auto &latterVer = cfg->install_ini->latter_install_version; char tmp[MAX_PATH]; auto rc = sp_dir_get_path_version(env->dir, latterVer.major, latterVer.minor, latterVer.revision, latterVer.build, SP_DIR_INSTALL_INI, NULL, tmp, MAX_PATH, detect_env_test_mode(env->cfg->args->test_mode)); if (rc != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get install.ini path failed!"); return (ErrorCodeEnum)rc; } if (ExistsFileA(tmp)) // 可能后续版本目录被删除 { // 倒回状态 CVersion lVer(latterVer.major, latterVer.minor, latterVer.revision, latterVer.build); inifile_write_str(tmp, (const char*)lVer.ToString(), "InstallState", "R"); // 修改内存状态 auto pLatterVerInfo = sp_cfg_find_version_info(cfg, &latterVer); if (pLatterVerInfo != NULL) pLatterVerInfo->install_state = Install_RollBack; // 修改对应安装包日志 auto p = inifile_read_str(tmp, (const char*)lVer.ToString(), "InstallPack", ""); CSimpleStringA strPackName = p; FREE(p); TOOLKIT_ASSERT(!strPackName.IsNullOrEmpty()); auto &curVer = cfg->install_ini->install_version; WriteInstallLog(strPackName, CSimpleStringA::Format("Rollback to version: [%d.%d.%d.%d]", curVer.major, curVer.minor, curVer.revision, curVer.build)); } } // 设置当前版本安装状态为活动 char *pCurVersion = inifile_read_str(cfg->install_ini_path, "Main", "InstallVersion", ""); inifile_write_str(cfg->install_ini_path, pCurVersion, "InstallState", "A"); inifile_format_write(cfg->install_ini_path, pCurVersion, "SwitchOverDate", "0x%08X", y2k_time_now()); auto pPackName = inifile_read_str(cfg->install_ini_path, pCurVersion, "InstallPack", ""); CSimpleStringA strPackName = pPackName; FREE(pCurVersion); FREE(pPackName); // 修改安装包历史 if (!strPackName.IsNullOrEmpty()) WriteInstallLog(strPackName, "Set version state active"); // 拷贝升级包到Upgraded目录 const char *pPackFile = pVerInfo->install_pack; CSimpleStringA strDownloadPath, strUpgradedPath; GetPath("Downloads", strDownloadPath); GetPath("Upgraded", strUpgradedPath); CSimpleStringA strSourcePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strDownloadPath, pPackFile); CSimpleStringA strDestPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strUpgradedPath, pPackFile); CopyFileA(strSourcePath, strDestPath, FALSE); return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::IsPackInstalled(const char *pszPackName, bool &bInstalled) { if (pszPackName == NULL) { bInstalled = false; return Error_Param; } // 先从内存查找 auto env = sp_get_env(); auto cfg = env->cfg; bInstalled = sp_cfg_is_pack_installed(cfg, pszPackName) == 0; if (bInstalled) return Error_Succeed; // 再从安装文件目录查找 CSimpleStringA strPath; GetPath("RunInfo", strPath); CSimpleStringA strInstallLog = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "InstallLog" SPLIT_SLASH_STR "%s.log", (const char*)strPath, pszPackName); bInstalled = ExistsFileA(strInstallLog) == TRUE; return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::GetSystemStaticInfoForVersion(CVersion verSoftware,CSystemStaticInfo &Info) { auto env = sp_get_env(); auto cfg = env->cfg; auto root_ini = cfg->root_ini; memset(&Info, 0, sizeof(Info)); Info.strTerminalID = CSimpleStringA(root_ini->terminal_no); Info.strMachineType = CSimpleStringA(root_ini->machine_type); Info.MachineVersion = CVersion(root_ini->machine_version.major, root_ini->machine_version.minor, root_ini->machine_version.revision, root_ini->machine_version.build); Info.eScreen = (ScreenEnum)root_ini->screen; Info.strSite = root_ini->site; Info.strEnrolAddr = root_ini->enroll_address; Info.EnrolGPS = CSphereVector(root_ini->enroll_gps_x, root_ini->enroll_gps_y); CSimpleStringA strInstallIni = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s" SPLIT_SLASH_STR "install.ini", env->dir->root_ver_path, (const char*)verSoftware.ToString()); if (ExistsFileA(strInstallIni)) { int n1(0), n2(0), n3(0), n4(0); auto p = inifile_read_str(strInstallIni, "Main", "LatterInstallVersion", ""); int n = sscanf(p, "%d.%d.%d.%d", &n1, &n2, &n3, &n4); toolkit_free(p); if (n == 4) Info.LatterInstallVersion = CVersion(n1, n2, n3, n4); else Info.LatterInstallVersion = CVersion(0, 0, 0, 0); //Info.LatterInstallPack = inifile_read_int(strInstallIni, "Main", "LatterInstallPack", 0); Info.nTotalRunCount = inifile_read_int(strInstallIni, "Main", "TotalRunCount", 0); Info.nTodayRunCount = inifile_read_int(strInstallIni, "Main", "TodayRunCount", 0); Info.tmCreateDate = CSmallDateTime(inifile_read_int(strInstallIni, "Main", "CreateDate", 0)); Info.tmCurrentTime = CSmallDateTime(inifile_read_int(strInstallIni, "Main", "CurrentTime", 0)); p = inifile_read_str(strInstallIni, "Main", "InstallVersion", ""); n = sscanf(p, "%d.%d.%d.%d", &n1, &n2, &n3, &n4); toolkit_free(p); if (n != 4) return Error_Unexpect; Info.InstallVersion = CVersion(n1, n2, n3, n4); auto strInstallVersion = Info.InstallVersion.ToString(); p = inifile_read_str(strInstallIni, strInstallVersion, "PreviousInstallVersion", ""); n = sscanf(p, "%d.%d.%d.%d", &n1, &n2, &n3, &n4); toolkit_free(p); if (n == 4) Info.PreviousInstallVersion = CVersion(n1, n2, n3, n4); else Info.PreviousInstallVersion = CVersion(0, 0, 0, 0); Info.tmSwithOverDate = CSmallDateTime(inifile_read_int(strInstallIni, strInstallVersion, "SwitchOverDate", 0)); p = inifile_read_str(strInstallIni, strInstallVersion, "InstallPack", ""); Info.InstallPack = p; toolkit_free(p); Info.InstallState = (InstallStateEnum)read_ini_install_state(strInstallIni, strInstallVersion, "InstallState"); // light pack p = inifile_read_str(strInstallIni, "Main", "LightPack", ""); CSimpleStringA strLightPacks = p; toolkit_free(p); if (!strLightPacks.IsNullOrEmpty()) { auto list = strLightPacks.Split(','); Info.LightPackInfos.Init(list.GetCount()); for (int i = 0; i < list.GetCount(); ++i) { auto& strPackName = list[i]; Info.LightPackInfos[i].strPackName = strPackName; Info.LightPackInfos[i].State = (InstallStateEnum)read_ini_install_state(strInstallIni, strPackName, "PackState"); Info.LightPackInfos[i].tmInstalledDate = CSmallDateTime(inifile_read_int(strInstallIni, strPackName, "InstalledDate", 0)); } } } else { auto latterVer = cfg->install_ini->latter_install_version; Info.LatterInstallVersion = CVersion(latterVer.major, latterVer.minor, latterVer.revision, latterVer.build); Info.nTotalRunCount = cfg->install_ini->total_run_count; Info.tmCreateDate = CSmallDateTime(cfg->install_ini->current_startup_time); Info.tmCurrentTime = CSmallDateTime(cfg->install_ini->install_time); auto installver = cfg->install_ini->install_version; Info.InstallVersion = CVersion(installver.major, installver.minor, installver.revision, installver.build); Info.PreviousInstallVersion = CVersion(0, 0, 0, 0); Info.tmSwithOverDate = CSmallDateTime(cfg->install_ini->install_time); Info.InstallPack = ""; Info.InstallState = Install_Active; Info.InstallPack = ""; Info.LightPackInfos.Clear(); } return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::SetSysDebugLevel(const char *pszEntityName,DebugLevelEnum eDebugLevel,bool bPersist) { sp_env_t *env = sp_get_env(); if (!pszEntityName) return Error_Null; if (stricmp(pszEntityName, "SpShell") == 0) env->cfg->shell_ini->shell_debug_level = (int)eDebugLevel; sp_cfg_shell_entity_t *cfg_ent = sp_cfg_get_entity_by_name(env->cfg, pszEntityName); if (cfg_ent) { int old = cfg_ent->debug_level; if (old != eDebugLevel) { cfg_ent->debug_level = (int)eDebugLevel; if (bPersist) { return SpTranslateError(sp_cfg_refresh_debug_level(env->cfg, cfg_ent)); } } } else { return Error_NotExist; } return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::RefreshFrameworkState(FrameworkStateEnum eState) { int rc = Error_Succeed; char n[12] = { '\0' }; sp_env_t* env = sp_get_env(); sp_cfg_t* cfg = env->cfg; const int old_state = cfg->shell_ini->shell_state; if (old_state != (int)eState) { cfg->shell_ini->shell_state = eState; _itoa(eState, n, 10); rc = sp_var_client_set((sp_var_client_t*)m_var_client, VAR_RSERVERD_KEY_TERM_STATE, n, 0); if (rc == Error_Succeed) { iobuffer_t* pkt = iobuffer_create(-1, -1); int v1 = (int)eState; int v2 = (int)old_state; iobuffer_write(pkt, IOBUF_T_I4, &v1, 0); iobuffer_write(pkt, IOBUF_T_I4, &v2, 0); rc = PostInfoShell(SHELL_CMD_INFO_TERMINALSTAGE_CHANGE, &pkt); if (pkt) { iobuffer_dec_ref(pkt); } } } return SpTranslateError(rc); } ErrorCodeEnum SpEntityPrivilege::ShowOuputConsole() { ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); Error = PostInfoShell(SHELL_CMD_INFO_OUTPUT_CONSOLE_ON, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntityPrivilege::CloseOuputConsole() { ErrorCodeEnum Error; iobuffer_t *pkt = iobuffer_create(-1, -1); Error = PostInfoShell(SHELL_CMD_INFO_OUTPUT_CONSOLE_OFF, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntityPrivilege::BeginLogSend(const char* endpoint, const char* topicSys, const char* topicUser, const char* topicBeidou , const char* bussSys, const char* bussUser, const char* vtmWeb) { ErrorCodeEnum Error; iobuffer_t* pkt = iobuffer_create(-1, -1); iobuffer_write(pkt, IOBUF_T_STR, endpoint, -1); iobuffer_write(pkt, IOBUF_T_STR, topicSys, -1); iobuffer_write(pkt, IOBUF_T_STR, topicUser, -1); iobuffer_write(pkt, IOBUF_T_STR, topicBeidou, -1); iobuffer_write(pkt, IOBUF_T_STR, bussSys, -1); iobuffer_write(pkt, IOBUF_T_STR, bussUser, -1); iobuffer_write(pkt, IOBUF_T_STR, vtmWeb, -1); Error = PostInfoShell(SHELL_CMD_INFO_START_UPLOAD_LOG, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntityPrivilege::SetHttpToken(const char* channelId, const char* token) { ErrorCodeEnum Error; iobuffer_t* pkt = iobuffer_create(-1, -1); iobuffer_write(pkt, IOBUF_T_STR, channelId, -1); iobuffer_write(pkt, IOBUF_T_STR, token, -1); Error = PostInfoShell(SHELL_CMD_INFO_UPDATE_TOKEN, &pkt); if (pkt) iobuffer_dec_ref(pkt); return Error; } ErrorCodeEnum SpEntityPrivilege::SetEntityPriority(const char* pszEntityName, EntityPriorityEnum nPriority) { if (!pszEntityName) return Error_Null; sp_env_t* env = sp_get_env(); sp_mod_mgr_t* mod_mgr = env->mod_mgr; sp_entity_t* ent = sp_mod_mgr_find_entity_by_name(mod_mgr, pszEntityName); if (!ent) { return Error_NotExist; } #ifndef _WIN32 auto func = [nPriority] { switch (nPriority) { case Priority_Low: return TOOLKIT_PRIORITY_LOW; case Priority_Below_Normal: return TOOLKIT_PRIORITY_BELOW_NORMAL; case Priority_Normal: return TOOLKIT_PRIORITY_NORMAL; case Priority_Above_Normal: return TOOLKIT_PRIORITY_ABOVE_NORMAL; case Priority_High: return TOOLKIT_PRIORITY_HIGH; case Priority_Highest: return TOOLKIT_PRIORITY_HIGHEST; default: return TOOLKIT_PRIORITY_NORMAL; } }; int res = toolkit_os_setpriority(ent->mod->process.pid, func()); #else int priviliegeValue = TOOLKIT_PRIORITY_NORMAL; switch (nPriority) { case Priority_Low: priviliegeValue = TOOLKIT_PRIORITY_LOW; break; case Priority_Below_Normal: priviliegeValue = TOOLKIT_PRIORITY_BELOW_NORMAL; break; case Priority_Normal: priviliegeValue = TOOLKIT_PRIORITY_NORMAL; break; case Priority_Above_Normal: priviliegeValue = TOOLKIT_PRIORITY_ABOVE_NORMAL; break; case Priority_High: priviliegeValue = TOOLKIT_PRIORITY_HIGH; break; case Priority_Highest: priviliegeValue = TOOLKIT_PRIORITY_HIGHEST; break; default: priviliegeValue = TOOLKIT_PRIORITY_NORMAL; break; } int res = toolkit_os_setpriority(ent->mod->process.pid, priviliegeValue); #endif //NOT _WIN32 if (res != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("toolkit_os_setpriority failed %s ", toolkit_strerror(res)); return Error_Unexpect; } return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::GetEntityPriority(const char* pszEntityName, EntityPriorityEnum& nPriority) { if (!pszEntityName) return Error_Null; sp_env_t* env = sp_get_env(); sp_mod_mgr_t* mod_mgr = env->mod_mgr; sp_entity_t* ent = sp_mod_mgr_find_entity_by_name(mod_mgr, pszEntityName); if (!ent) { return Error_NotExist; } int priority; int res = toolkit_os_getpriority(ent->mod->process.pid, &priority); if (res != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("toolkit_os_getpriority failed %s ", toolkit_strerror(res)); return Error_Unexpect; } #if defined(_MSC_VER) switch (priority) { case TOOLKIT_PRIORITY_LOW: nPriority = Priority_Low; break; case TOOLKIT_PRIORITY_BELOW_NORMAL: nPriority = Priority_Below_Normal; break; case TOOLKIT_PRIORITY_NORMAL: nPriority = Priority_Normal; break; case TOOLKIT_PRIORITY_ABOVE_NORMAL: nPriority = Priority_Above_Normal; break; case TOOLKIT_PRIORITY_HIGH: nPriority = Priority_High; break; case TOOLKIT_PRIORITY_HIGHEST: nPriority = Priority_Highest; break; default: nPriority = Priority_Unknown; break; } #else auto func = [](int value) { switch (value) { case TOOLKIT_PRIORITY_LOW: return Priority_Low; case TOOLKIT_PRIORITY_BELOW_NORMAL: return Priority_Below_Normal; case TOOLKIT_PRIORITY_NORMAL: return Priority_Normal; case TOOLKIT_PRIORITY_ABOVE_NORMAL: return Priority_Above_Normal; case TOOLKIT_PRIORITY_HIGH: return Priority_High; case TOOLKIT_PRIORITY_HIGHEST: return Priority_Highest; default: return Priority_Unknown; } }; nPriority = func(priority); #endif //_MSC_VER return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::GetToken(CSimpleString& curToken) { sp_env_t* env = sp_get_env(); if (env->cfg->shell_ini->token == NULL || strlen(env->cfg->shell_ini->token) == 0) return ErrorCodeEnum::Error_NotConfig; curToken = env->cfg->shell_ini->token; return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::GetVTMErrMsgArr(CAutoArray& strErrorCodeArr, CAutoArray& strDescriptionArr, CAutoArray& strRemarkArr) { sp_env_t* env = sp_get_env(); if(env->cfg->root_ini->vtm_err_msg_config == NULL || strlen(env->cfg->root_ini->vtm_err_msg_config) == 0) return ErrorCodeEnum::Error_NotConfig; return (ErrorCodeEnum)ConvertStrToVTMErrMsg(env->cfg->root_ini->vtm_err_msg_config, strErrorCodeArr, strDescriptionArr, strRemarkArr); } ErrorCodeEnum SpEntityPrivilege::TryUpdateToken(CSimpleString& oldToken, CSimpleString& newToken) { char t_oldToken[MAX_PATH] = "", t_newToken[MAX_PATH] = ""; auto ret = sp_TryUpdateToken(t_oldToken, t_newToken); if (ret == Error_Succeed) { oldToken = t_oldToken; newToken = t_newToken; } return (ErrorCodeEnum)ret; } ErrorCodeEnum SpEntityPrivilege::InitCfgUrl(VTMInitParam& info) { auto cfg = sp_get_env()->cfg; if (cfg == NULL || cfg->shell_ini == NULL || cfg->root_ini == NULL) return Error_Null; if (info.terminalNo.GetLength() > 0) { if (cfg->root_ini->terminal_no) shm_free(cfg->root_ini->terminal_no); cfg->root_ini->terminal_no = shm_strdup(info.terminalNo.GetData()); } if (info.channelId.GetLength() > 0) { if (cfg->shell_ini->channelId) shm_free(cfg->shell_ini->channelId); cfg->shell_ini->channelId = shm_strdup(info.channelId.GetData()); } if (info.tokenSecret.GetLength() > 0) { if (cfg->shell_ini->tokenSecret) shm_free(cfg->shell_ini->tokenSecret); cfg->shell_ini->tokenSecret = shm_strdup(info.tokenSecret.GetData()); } if (info.CommonLaunchUrl.GetLength() > 0) { if (cfg->shell_ini->CommonLaunchUrl) shm_free(cfg->shell_ini->CommonLaunchUrl); cfg->shell_ini->CommonLaunchUrl = shm_strdup(info.CommonLaunchUrl.GetData()); } if (info.CenterConfigTotal.GetLength() > 0) { if (cfg->shell_ini->CenterConfigTotal) shm_free(cfg->shell_ini->CenterConfigTotal); cfg->shell_ini->CenterConfigTotal = shm_strdup(info.CenterConfigTotal.GetData()); } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("TerminalNo:%s, CommonLaunchUrl:%s, CenterConfigTotal:%s" , cfg->root_ini->terminal_no == NULL ? "" : cfg->root_ini->terminal_no , cfg->shell_ini->CommonLaunchUrl == NULL ? "" : cfg->shell_ini->CommonLaunchUrl , cfg->shell_ini->CenterConfigTotal == NULL ? "" : cfg->shell_ini->CenterConfigTotal); return Error_Succeed; } ErrorCodeEnum SpEntityPrivilege::TryUpdateVTMERRMSG() { LOG_FUNCTION(); iobuffer_t* req_pkt = iobuffer_create(-1, -1); SpAsyncWaitRPC* pAsyncWait = new SpAsyncWaitRPC(this, &req_pkt, SHELL_CMD_REQ_TRY_UPDATE_VTMERRMSG); ErrorCodeEnum Error = pAsyncWait->Begin(); if (Error == Error_Succeed) { Error = pAsyncWait->WaitAnswer(30000);//WaitAnswer如果设定为INFINE,则最大10s,在http访问中会触发超时 if (Error == Error_Succeed) { CAutoBuffer AnsBuf; bool bEnd; Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd); if (Error == Error_Succeed) { iobuffer_t* pkt = iobuffer_create(-1, AnsBuf.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount()); } } } pAsyncWait->DecrementRef(); if (req_pkt) iobuffer_dec_ref(req_pkt); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("TryUpdateVTMERRMSG ret:%d", Error); return Error; } ErrorCodeEnum SpEntityPrivilege::TryUpdateCfg() { LOG_FUNCTION(); iobuffer_t* req_pkt = iobuffer_create(-1, -1); SpAsyncWaitRPC* pAsyncWait = new SpAsyncWaitRPC(this, &req_pkt, SHELL_CMD_REQ_TRY_UPDATE_CFG); ErrorCodeEnum Error = pAsyncWait->Begin(); if (Error == Error_Succeed) { Error = pAsyncWait->WaitAnswer(30000);//WaitAnswer如果设定为INFINE,则最大10s,在http访问中会触发超时 if (Error == Error_Succeed) { CAutoBuffer AnsBuf; bool bEnd; Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd); if (Error == Error_Succeed) { iobuffer_t* pkt = iobuffer_create(-1, AnsBuf.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount()); } } } pAsyncWait->DecrementRef(); if (req_pkt) iobuffer_dec_ref(req_pkt); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("TryUpdateCfg ret:%d", Error); return Error; } ErrorCodeEnum SpEntityPrivilege::ModifyMemCfgParam(MemCfgParam& info) { LOG_FUNCTION(); iobuffer_t* req_pkt = iobuffer_create(-1, -1); iobuffer_write(req_pkt, IOBUF_T_STR, info.configType, -1); iobuffer_write(req_pkt, IOBUF_T_STR, info.module.GetData(), -1); iobuffer_write(req_pkt, IOBUF_T_STR, info.name.GetData(), -1); iobuffer_write(req_pkt, IOBUF_T_STR, info.value.GetData(), -1); SpAsyncWaitRPC* pAsyncWait = new SpAsyncWaitRPC(this, &req_pkt, SHELL_CMD_REQ_MODIFY_MEM_CFG); ErrorCodeEnum Error = pAsyncWait->Begin(); if (Error == Error_Succeed) { Error = pAsyncWait->WaitAnswer(30000);//WaitAnswer如果设定为INFINE,则最大10s,在http访问中会触发超时 if (Error == Error_Succeed) { CAutoBuffer AnsBuf; bool bEnd; Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd); if (Error == Error_Succeed) { iobuffer_t* pkt = iobuffer_create(-1, AnsBuf.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount()); } } } pAsyncWait->DecrementRef(); if (req_pkt) iobuffer_dec_ref(req_pkt); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("ModifyMemCfgParam ret:%d", Error); return Error; } ErrorCodeEnum SpEntityPrivilege::WriteTerminalNoToRootIni(CSimpleString terminalNo) { LOG_FUNCTION(); iobuffer_t* req_pkt = iobuffer_create(-1, -1); iobuffer_write(req_pkt, IOBUF_T_STR, terminalNo.GetData(), -1); SpAsyncWaitRPC* pAsyncWait = new SpAsyncWaitRPC(this, &req_pkt, SHELL_CMD_REQ_WRITE_TERMINALNO); ErrorCodeEnum Error = pAsyncWait->Begin(); if (Error == Error_Succeed) { Error = pAsyncWait->WaitAnswer(30000);//WaitAnswer如果设定为INFINE,则最大10s,在http访问中会触发超时 if (Error == Error_Succeed) { CAutoBuffer AnsBuf; bool bEnd; Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd); if (Error == Error_Succeed) { iobuffer_t* pkt = iobuffer_create(-1, AnsBuf.GetCount()); iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount()); } } } pAsyncWait->DecrementRef(); if (req_pkt) iobuffer_dec_ref(req_pkt); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("WriteTerminalNoToRootIni ret:%d", Error); return Error; } ErrorCodeEnum SpEntityPrivilege::TryUpdateCenterCfg(bool& isUpdate, bool& isReset, CSimpleString& version) { char t_version[MAX_PATH] = ""; int t_isUpdate = 0, t_isReset = 0; auto ret = sp_TryUpdateCenterCfg(&t_isUpdate, &t_isReset, t_version); if (ret == Error_Succeed) { isUpdate = t_isUpdate; isReset = t_isReset; version = t_version; } return (ErrorCodeEnum)ret; } void SpEntityPrivilege::GetSendLogInfo(unsigned long* t_upload_TerminalSys_Suc, unsigned long* t_upload_TerminalUser_Suc, unsigned long* t_upload_BussinessSys_Suc, unsigned long* t_upload_BussinessUser_Suc, unsigned long* t_upload_beidou_Suc, unsigned long* t_upload_TerminalSys_Err, unsigned long* t_upload_TerminalUser_Err, unsigned long* t_upload_BussinessSys_Err, unsigned long* t_upload_BussinessUser_Err, unsigned long* t_upload_beidou_Err) { #if defined(_MSC_VER) log_producer_config_get_upload_info(t_upload_TerminalSys_Suc, t_upload_TerminalUser_Suc, t_upload_BussinessSys_Suc, t_upload_BussinessUser_Suc, t_upload_beidou_Suc, t_upload_TerminalSys_Err, t_upload_TerminalUser_Err, t_upload_BussinessSys_Err, t_upload_BussinessUser_Err, t_upload_beidou_Err); #else ///*TODO(80374374@3/9/2023): */ #endif //_MSC_VER } void SpEntityPrivilege::on_entity_create(int entity_id, int trigger_entity_id) { if (m_pEntityLifeListener) { sp_env_t *env = sp_get_env(); IEntityLifeListener *pCallback = (IEntityLifeListener *)sp_mod_entity_life_listener_get_tag(m_pEntityLifeListener); sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mod_mgr, entity_id); sp_entity_t *trigger_ent = sp_mod_mgr_find_entity_by_idx(mod_mgr, trigger_entity_id); pCallback->OnCreated(ent->cfg->name, Error_Succeed, trigger_ent->cfg->name); } } void SpEntityPrivilege::on_entity_close(int entity_id, int trigger_entity_id, int cause_code) { if (m_pEntityLifeListener) { sp_env_t *env = sp_get_env(); IEntityLifeListener *pCallback = (IEntityLifeListener *)sp_mod_entity_life_listener_get_tag(m_pEntityLifeListener); sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mod_mgr, entity_id); sp_entity_t *trigger_ent = sp_mod_mgr_find_entity_by_idx(mod_mgr, trigger_entity_id); pCallback->OnClosed(ent->cfg->name, (EntityCloseCauseEnum)cause_code, Error_Succeed, trigger_ent->cfg->name); } } void SpEntityPrivilege::on_entity_exception(int entity_id, int error, int entity_state) { if (m_pEntityLifeListener) { sp_env_t *env = sp_get_env(); IEntityLifeListener *pCallback = (IEntityLifeListener *)sp_mod_entity_life_listener_get_tag(m_pEntityLifeListener); sp_mod_mgr_t *mod_mgr = env->mod_mgr; sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(mod_mgr, entity_id); pCallback->OnException(ent->cfg->name, "", (EntityStateEnum)entity_state, (EntityStateEnum)entity_state, (ErrorCodeEnum)error); } } void SpEntityPrivilege::__on_entity_create(sp_mod_entity_life_listener_t *listener, int entity_id, int trigger_entity_id, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_entity_create(entity_id, trigger_entity_id); } void SpEntityPrivilege::__on_entity_close(sp_mod_entity_life_listener_t *listener, int entity_id, int trigger_entity_id, int cause_code, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_entity_close(entity_id, trigger_entity_id, cause_code); } void SpEntityPrivilege::__on_entity_exception(sp_mod_entity_life_listener_t *listener, int entity_id, int error, int entity_state, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_entity_exception(entity_id, error, entity_state); } void SpEntityPrivilege::on_user_state(sp_mod_entity_state_listener_t *listener, int entity_id, int last_state, int curr_state) { sp_env_t *env = sp_get_env(); IEntityStateListener *pListener = (IEntityStateListener *)sp_mod_entity_listener_get_tag(listener); sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, entity_id); pListener->OnUserStateHook(ent->cfg->name, (DWORD)curr_state, (DWORD)last_state); } void SpEntityPrivilege::on_entity_state(sp_mod_entity_state_listener_t *listener, int entity_id, int trigger_entity_id, int last_state, int curr_state) { sp_env_t *env = sp_get_env(); IEntityStateListener *pListener = (IEntityStateListener *)sp_mod_entity_listener_get_tag(listener); sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, entity_id); sp_entity_t *trigger_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, trigger_entity_id); pListener->OnEntityStateHook(ent->cfg->name, trigger_ent->cfg->name, (EntityStateEnum)curr_state, (EntityStateEnum)last_state); } void SpEntityPrivilege::on_create_connection(sp_mod_entity_state_listener_t *listener, int src_entity_id, int dst_entity_id) { sp_env_t *env = sp_get_env(); IEntityStateListener *pListener = (IEntityStateListener *)sp_mod_entity_listener_get_tag(listener); sp_entity_t *src_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, src_entity_id); sp_entity_t *dst_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, dst_entity_id); pListener->OnCeateConnection(src_ent->cfg->name, dst_ent->cfg->name); } void SpEntityPrivilege::on_close_connection(sp_mod_entity_state_listener_t *listener, int src_entity_id, int dst_entity_id) { sp_env_t *env = sp_get_env(); IEntityStateListener *pListener = (IEntityStateListener *)sp_mod_entity_listener_get_tag(listener); sp_entity_t *src_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, src_entity_id); sp_entity_t *dst_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, dst_entity_id); pListener->OnCloseConnection(src_ent->cfg->name, dst_ent->cfg->name); } void SpEntityPrivilege::__on_user_state(sp_mod_entity_state_listener_t *listener, int entity_id, int last_state, int curr_state, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_user_state(listener, entity_id, last_state, curr_state); } void SpEntityPrivilege::__on_entity_state(sp_mod_entity_state_listener_t *listener, int entity_id, int trigger_entity_id, int last_state, int curr_state, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_entity_state(listener, entity_id, trigger_entity_id, last_state, curr_state); } void SpEntityPrivilege::__on_create_connection(sp_mod_entity_state_listener_t *listener, int src_entity_id, int dst_entity_id, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_create_connection(listener, src_entity_id, dst_entity_id); } void SpEntityPrivilege::__on_close_connection(sp_mod_entity_state_listener_t *listener, int src_entity_id, int dst_entity_id, void *user_data) { SpEntityPrivilege *pThis = static_cast(user_data); pThis->on_close_connection(listener, src_entity_id, dst_entity_id); }