sp_cfg.cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613
  1. #include "precompile.h"
  2. #include "sp_cfg.h"
  3. #include "sp_def.h"
  4. //#include "sp_sal.h"
  5. #include "sp_dir.h"
  6. #include "sp_dbg_export.h"
  7. #include "sp_env.h"
  8. #include "iniutil.h"
  9. #include "strutil.h"
  10. #include "memutil.h"
  11. #include "shm_mem.h"
  12. #include "fileutil.h"
  13. #include "SpBase.h"
  14. #include "CodeSignVerify.h"
  15. #include <fstream>
  16. #include <ostream>
  17. #include <string>
  18. #include <vector>
  19. #include <stdio.h>
  20. #include <winpr/ini.h>
  21. #include <winpr/string.h>
  22. #define MAX_ENTITY_LEN 33
  23. #ifdef _WIN32
  24. #define MOD_LIB_SUFFIX ".dll"
  25. #else
  26. #define MOD_LIB_SUFFIX ".so"
  27. #endif //_WIN32
  28. #define T_MALLOC_T(type, shm) \
  29. shm ? (type*)shm_malloc(sizeof(type)) : (type*)malloc(sizeof(type))
  30. #define T_MALLOC(size, shm) \
  31. shm ? shm_malloc(size) : malloc(size)
  32. #define T_FREE(p, shm) \
  33. shm ? shm_free(p) : free(p)
  34. #define T_STRDUP(s, shm) \
  35. shm ? shm_strdup(s) : _strdup(s)
  36. #define T_ARRAY_MAKE(n, size, shm) \
  37. shm ? shm_array_make(n, size) : array_make(n, size)
  38. std::vector<std::string> g_arrKill;
  39. std::vector<std::string> g_arrStart;
  40. std::vector<std::string> getKillArr() {
  41. return g_arrKill;
  42. }
  43. std::vector<std::string> getStartArr() {
  44. return g_arrStart;
  45. }
  46. static int verify_entity_name(const char *name)
  47. {
  48. const char *p = name;
  49. int len = 0;
  50. while (*p) {
  51. if (!isalnum(*p)) {
  52. return FALSE;
  53. }
  54. len++;
  55. if (len > MAX_ENTITY_LEN)
  56. return FALSE;
  57. p++;
  58. }
  59. return TRUE;
  60. }
  61. static int parse_install_state(const char *str)
  62. {
  63. const struct {
  64. int ch;
  65. int val;
  66. } tbl[] = {
  67. {'A', Install_Active},
  68. {'I', Install_Pending},
  69. {'S', Install_SetToStart},
  70. {'F', Install_FailRun},
  71. {'R', Install_RollBack},
  72. {'U', Install_Upgraded},
  73. {'C',Install_Cancelled},
  74. {'W',Install_WaitConfirm},
  75. {'D', Install_Installed},
  76. };
  77. int i;
  78. for (i = 0; i < array_size(tbl); ++i) {
  79. if (tbl[i].ch == str[0]) {
  80. return tbl[i].val;
  81. }
  82. }
  83. return -1; // error
  84. }
  85. int read_ini_install_state(const char *file, const char *section, const char *key)
  86. {
  87. char *p = inifile_read_str(file, section, key, "");
  88. int ret = parse_install_state(p);
  89. toolkit_free(p);
  90. return ret;
  91. }
  92. static __inline int file_write(FILE *fp, const void *buf, int n)
  93. {
  94. size_t t = fwrite(buf, n, 1, fp);
  95. return t == n ? 0 : Error_IO;
  96. }
  97. static __inline int file_read(FILE *fp, void *buf, int n)
  98. {
  99. size_t t = fread(buf, n, 1, fp);
  100. return t == n ? 0 : Error_IO;
  101. }
  102. static void destroy_entity(sp_cfg_shell_entity_t *entity)
  103. {
  104. if (entity) {
  105. if (entity->name)
  106. shm_free(entity->name);
  107. if (entity->argv)
  108. shm_free((void*)entity->argv);
  109. if (entity->cmdline)
  110. shm_free(entity->cmdline);
  111. shm_free(entity);
  112. }
  113. }
  114. static void destroy_module(sp_cfg_shell_module_t* mod)
  115. {
  116. if (mod) {
  117. if (mod->name)
  118. shm_free(mod->name);
  119. if (mod->author)
  120. shm_free(mod->author);
  121. if (mod->company)
  122. shm_free(mod->company);
  123. shm_free(mod);
  124. }
  125. }
  126. static void destroy_sysevent(sp_cfg_shell_sysevent_t *sysevent)
  127. {
  128. if (sysevent) {
  129. if (sysevent->name)
  130. shm_free(sysevent->name);
  131. if (sysevent->arr_owner_entity)
  132. shm_array_free(sysevent->arr_owner_entity);
  133. shm_free(sysevent);
  134. }
  135. }
  136. static sp_cfg_path_t *find_path(sp_cfg_t *cfg, const char *path_prefix)
  137. {
  138. int i;
  139. for (i = 0; i < cfg->root_ini->arr_path->nelts; ++i) {
  140. sp_cfg_path_t *tpath = ARRAY_IDX(cfg->root_ini->arr_path, i, sp_cfg_path_t*);
  141. if (strcmp(tpath->name, path_prefix) == 0) {
  142. return tpath;
  143. }
  144. }
  145. return NULL;
  146. }
  147. static sp_cfg_shell_module_t* find_module(sp_cfg_shell_ini_t *shell, const char *mod_name)
  148. {
  149. int i;
  150. sp_cfg_shell_module_t* mod;
  151. const int len = (strstr(mod_name, "lib") == mod_name) ? 3 : 0; //linux .so name
  152. ARRAY_FOR_EACH_ENTRY(mod, i, shell->arr_module, sp_cfg_shell_module_t*) {
  153. if (_stricmp(mod->name, mod_name + len) == 0)
  154. return mod;
  155. }
  156. return NULL;
  157. }
  158. static sp_cfg_shell_entity_t *find_entity(sp_cfg_shell_ini_t *shell, const char *entity_name)
  159. {
  160. int i;
  161. sp_cfg_shell_entity_t *entity;
  162. ARRAY_FOR_EACH_ENTRY(entity, i, shell->arr_entity, sp_cfg_shell_entity_t*) {
  163. if (_stricmp(entity->name, entity_name) == 0)
  164. return entity;
  165. }
  166. return NULL;
  167. }
  168. static int read_ini_version(const char *file, const char *section, const char *key, int *major, int *minor, int *revision, int *build)
  169. {
  170. int n;
  171. int ret = -1;
  172. char *str = inifile_read_str(file, section, key, "");
  173. if (str) {
  174. if (strlen(str) == 0) {
  175. if (major)
  176. *major = 0;
  177. if (minor)
  178. *minor = 0;
  179. if (revision)
  180. *revision = 0;
  181. if (build)
  182. *build = 0;
  183. return 0;
  184. }
  185. toolkit_free(str);
  186. }
  187. if (build) {
  188. n = inifile_format_read(file, section, key, "%d.%d.%d.%d", major, minor, revision, build);
  189. if (n == 4)
  190. ret = 0;
  191. } else if (revision) {
  192. n = inifile_format_read(file, section, key, "%d.%d.%d", major, minor, revision);
  193. if (n == 3)
  194. ret = 0;
  195. } else {
  196. n = inifile_format_read(file, section, key, "%d.%d", major, minor);
  197. if (n == 2)
  198. ret = 0;
  199. }
  200. return ret;
  201. }
  202. static int read_ini_str(const char *file, const char *section, const char *key, char **pstr, int shm)
  203. {
  204. int rc = Error_Param;
  205. char *str = inifile_read_str(file, section, key, "");
  206. if (str){
  207. if (shm) {
  208. *pstr = shm_strdup(str);
  209. rc = 0;
  210. toolkit_free(str);
  211. } else {
  212. *pstr = str;
  213. rc = 0;
  214. }
  215. }
  216. return rc;
  217. }
  218. static int read_ini_date(const char *file, const char *section, const char *key,
  219. int *year, int *month, int *day, int *hour, int *minute, int *second, int shm)
  220. {
  221. int ret;
  222. if (second)
  223. *second = 0;
  224. ret = inifile_format_read(file, section, key, "%d-%d-%d %d:%d", year, month, day, hour, minute);
  225. return ret == 5 ? 0 : Error_Param;
  226. }
  227. static int read_ini_position(const char *file, const char *section, const char *key, float *x, float *y, int shm)
  228. {
  229. int ret;
  230. ret = inifile_format_read(file, section, key, "%f,%f", x, y);
  231. return ret == 2 ? 0 : Error_Param;
  232. }
  233. static int read_ini_path(const char *file, const char *section, const char *key, char **path, int shm)
  234. {
  235. int rc = read_ini_str(file, section, key, path, shm);
  236. if (rc == 0) {
  237. char *s = *path;
  238. int slen = strlen(s);
  239. if (s[slen - 1] == SPLIT_SLASH)
  240. s[slen - 1] = 0;
  241. }
  242. return rc;
  243. }
  244. static int read_terminal(const char *file, sp_cfg_root_ini_t *root, int shm)
  245. {
  246. int rc;
  247. rc = read_ini_str(file, "Terminal", "TerminalNo", &root->terminal_no, shm);
  248. if (rc != 0)
  249. return rc;
  250. rc = read_ini_str(file, "Terminal", "MachineType", &root->machine_type, shm);
  251. if (rc != 0)
  252. return rc;
  253. rc = read_ini_str(file, "Terminal", "MachineModel", &root->machine_model, shm);
  254. rc = read_ini_version(file, "Terminal", "MachineVersion",
  255. &root->machine_version.major, &root->machine_version.minor, NULL, NULL);
  256. if (rc != 0)
  257. return rc;
  258. rc = read_ini_str(file, "Terminal", "Site", &root->site, shm);
  259. if (rc != 0)
  260. return rc;
  261. root->screen = inifile_read_int(file, "Terminal", "Screen", -1);
  262. if (root->screen == -1) {
  263. rc = -1;
  264. return rc;
  265. }
  266. rc = read_ini_position(file, "Terminal", "EnrolGPS", &root->enroll_gps_x, &root->enroll_gps_y, shm);
  267. if (rc != 0)
  268. return rc;
  269. rc = read_ini_str(file, "Terminal", "EnrolAddr", &root->enroll_address, shm);
  270. if (rc != 0)
  271. return rc;
  272. return rc;
  273. }
  274. static int read_path(const char *file, sp_cfg_root_ini_t *root, int shm)
  275. {
  276. int rc = 0;
  277. array_header_t *arr_kvp = NULL;
  278. char *pos;
  279. int i;
  280. arr_kvp = inifile_read_section_key_all(file, "Path");
  281. if (!arr_kvp)
  282. return Error_NotExist;
  283. root->arr_path = T_ARRAY_MAKE(arr_kvp->nelts, sizeof(sp_cfg_path_t*), shm);
  284. ARRAY_FOR_EACH_ENTRY(pos, i, arr_kvp, char*) {
  285. sp_cfg_path_t *path = T_MALLOC_T(sp_cfg_path_t, shm);
  286. path->name = T_STRDUP(pos, shm);
  287. rc = read_ini_path(file, "Path", pos, &path->path, shm);
  288. if (rc != 0)
  289. return rc;
  290. if (shm) {
  291. SHM_ARRAY_PUSH(root->arr_path, sp_cfg_path_t*) = path;
  292. } else {
  293. ARRAY_PUSH(root->arr_path, sp_cfg_path_t*) = path;
  294. }
  295. if (strcmp(path->name, "SysRoot") == 0) {
  296. root->ref_sysroot_path = path->path;
  297. } else if (strcmp(path->name, "ADData") == 0) {
  298. root->ref_addata_path = path->path;
  299. } else if (strcmp(path->name, "SysLog") == 0) {
  300. root->ref_syslog_path = path->path;
  301. } else if (strcmp(path->name, "InterLog") == 0) {
  302. root->ref_intlog_path = path->path;
  303. } else if (strcmp(path->name, "UploadVideo") == 0) {
  304. root->ref_uploadvideo_path = path->path;
  305. } else if (strcmp(path->name, "UploadPhoto") == 0) {
  306. root->ref_uploadphoto_path = path->path;
  307. } else if (strcmp(path->name, "LocalVideo") == 0) {
  308. root->ref_localvideo_path = path->path;
  309. } else if (strcmp(path->name, "Downloads") == 0) {
  310. root->ref_downloads_path = path->path;
  311. } else if (strcmp(path->name, "Upgraded") == 0) {
  312. root->ref_upgraded_path = path->path;
  313. } else if (strcmp(path->name, "Temp") == 0) {
  314. root->ref_tmp_path = path->path;
  315. } else if (strcmp(path->name, "CenterSetting") == 0) {
  316. root->ref_centersetting_path = path->path;
  317. }
  318. }
  319. toolkit_array_free2(arr_kvp);
  320. return rc;
  321. }
  322. static sp_cfg_pack_info_t *read_pack_info(const char *file, const char *pack, int shm)
  323. {
  324. sp_cfg_pack_info_t *pack_info = T_MALLOC_T(sp_cfg_pack_info_t, shm);
  325. memset(pack_info, 0, sizeof(sp_cfg_pack_info_t));
  326. pack_info->name = T_STRDUP(pack, shm);
  327. pack_info->install_time = inifile_read_int(file, pack, "InstalledDate", 0);
  328. pack_info->state = read_ini_install_state(file, pack, "PackState");
  329. return pack_info;
  330. }
  331. static array_header_t *parse_packs(const char *file, const char *str, int shm)
  332. {
  333. array_header_t *arr = T_ARRAY_MAKE(-1, sizeof(sp_cfg_pack_info_t*), shm);
  334. char *packs = _strdup(str);
  335. if (packs) {
  336. char *token;
  337. const char *seps = " \t,";
  338. token = strtok(packs, seps);
  339. while (token != NULL) {
  340. sp_cfg_pack_info_t *pack_info = read_pack_info(file, token, shm);
  341. if (pack_info) {
  342. if (shm) {
  343. SHM_ARRAY_PUSH(arr, sp_cfg_pack_info_t*) = pack_info;
  344. } else {
  345. ARRAY_PUSH(arr, sp_cfg_pack_info_t*) = pack_info;
  346. }
  347. }
  348. token = strtok(NULL, seps);
  349. }
  350. free(packs);
  351. }
  352. return arr;
  353. }
  354. static int load_root_ini(sp_dir_t *dir, sp_cfg_root_ini_t *root, const char *file, int shm)
  355. {
  356. int rc;
  357. rc = read_terminal(file, root, shm);
  358. if (rc != 0)
  359. return rc;
  360. rc = read_path(file, root, shm);
  361. return rc;
  362. }
  363. static int unload_root_ini(sp_cfg_root_ini_t *root, int shm)
  364. {
  365. int i;
  366. if (shm) {
  367. shm_free(root->terminal_no);
  368. shm_free(root->machine_type);
  369. shm_free(root->enroll_address);
  370. for (i = 0; i < root->arr_path->nelts; ++i) {
  371. sp_cfg_path_t *path = ARRAY_IDX(root->arr_path, i, sp_cfg_path_t*);
  372. shm_free(path->name);
  373. shm_free(path->path);
  374. shm_free(path);
  375. }
  376. shm_array_free(root->arr_path);
  377. } else {
  378. free(root->terminal_no);
  379. free(root->machine_type);
  380. free(root->enroll_address);
  381. for (i = 0; i < root->arr_path->nelts; ++i) {
  382. sp_cfg_path_t *path = ARRAY_IDX(root->arr_path, i, sp_cfg_path_t*);
  383. free(path->name);
  384. free(path->path);
  385. free(path);
  386. }
  387. array_free(root->arr_path);
  388. }
  389. memset(root, 0, sizeof(sp_cfg_root_ini_t));
  390. return 0;
  391. }
  392. static inline int shell_ini__load_debug_level(const char* shell_ini_path, const char* entity_name)
  393. {
  394. int level = inifile_read_int(shell_ini_path, "Debug", entity_name, 0);
  395. /*to see: DebugLevelEnum*/
  396. if (level > 2 || level < 0)
  397. level = 0;
  398. return level;
  399. }
  400. /*add intrinsic spshell module*/
  401. static inline void shell_ini__load_init_shell(sp_cfg_shell_ini_t* shell, const char* shell_ini_path, const CVersionInfo* shell_ver)
  402. {
  403. sp_cfg_shell_entity_t* ent = NULL;
  404. sp_cfg_shell_module_t* mod = NULL;
  405. mod = (sp_cfg_shell_module_t*)shm_malloc(sizeof(sp_cfg_shell_module_t));
  406. memset(mod, 0, sizeof(sp_cfg_shell_module_t));
  407. sp_version_copy(&mod->version, &shell->software_version);
  408. mod->author = shm_strdup(shell_ver->strAuthorName);
  409. mod->company = shm_strdup(shell_ver->strCompanyName);
  410. mod->name = shm_strdup("SpShell");
  411. mod->mem_trace = inifile_read_int(shell_ini_path, "MemTrace", mod->name, 0);
  412. mod->idx = shell->arr_module->nelts; //the first mod id is spshell
  413. /*increment netls at the same time*/
  414. SHM_ARRAY_PUSH(shell->arr_module, sp_cfg_shell_module_t*) = mod;
  415. ent = (sp_cfg_shell_entity_t*)shm_malloc(sizeof(sp_cfg_shell_entity_t));
  416. memset(ent, 0, sizeof(sp_cfg_shell_entity_t));
  417. ent->mod = mod;
  418. ent->name = shm_strdup("SpShell");
  419. ent->idx = shell->arr_entity->nelts;
  420. ent->privilege = 1;
  421. ent->debug_level = shell_ini__load_debug_level(shell_ini_path, ent->name);
  422. SHM_ARRAY_PUSH(shell->arr_entity, sp_cfg_shell_entity_t*) = ent;
  423. }
  424. static inline void shell_ini__get_mod_version(sp_cfg_shell_module_t* mod, const char* mod_path)
  425. {
  426. #ifdef _WIN32
  427. CCodeSignVerify ver;
  428. CVersionInfo verInfo;
  429. if (!ver.GetVersionInfo(mod_path, verInfo))
  430. sp_dbg_warn("read file %s version info fail, %s", mod_path, (const char*)ver.GetErrorMsg());
  431. mod->author = shm_strdup(verInfo.strAuthorName);
  432. mod->company = shm_strdup(verInfo.strCompanyName);
  433. mod->version.major = verInfo.FileVersion.GetMajor();
  434. mod->version.minor = verInfo.FileVersion.GetMajor();
  435. mod->version.revision = verInfo.FileVersion.GetRevision();
  436. mod->version.build = verInfo.FileVersion.GetBuild();
  437. #endif
  438. }
  439. static inline int shell_ini__veritify_core_file_legality(sp_dir_t* dir, sp_cfg_shell_ini_t* shell)
  440. {
  441. #ifdef _WIN32
  442. // SpBase.dll、SpShell.exe、SpHost.exe代码签名校验
  443. char sal_tmp[MAX_PATH] = { 0 };
  444. const char* sal_files[] = { "SpBase.dll", "SpHost.exe", "SpShell.exe" };
  445. int i;
  446. CCodeSignVerify ver;
  447. for (i = 0; i < sizeof(sal_files) / sizeof(sal_files[0]); i++) {
  448. sprintf(sal_tmp, "%s" SPLIT_SLASH_STR "%s", dir->bin_path, sal_files[i]);
  449. CSignInfo signInfo;
  450. if (!ver.VerifySignature(sal_tmp, signInfo)) {
  451. sp_dbg_error("file %s sign verify fail, %s", sal_files[i], (const char*)ver.GetErrorMsg());
  452. return Error_FailVerify;
  453. }
  454. sp_dbg_info("file %s sign verify pass, signer: %s, sign time: %s, cert hash: %s", sal_files[i],
  455. (const char*)signInfo.strSignCertSubject, (const char*)signInfo.dtSignTime.ToTimeString(), (const char*)signInfo.strSignCertHash);
  456. if (shell->spbase_sign_cert_hash == NULL) {
  457. shell->spbase_sign_cert_hash = shm_strdup(signInfo.strSignCertHash);
  458. }
  459. else if (stricmp(shell->spbase_sign_cert_hash, signInfo.strSignCertHash) != 0) {
  460. sp_dbg_error("sign cert hash not equal, last : [%s], current: [%s]", shell->spbase_sign_cert_hash, (const char*)signInfo.strSignCertHash);
  461. return Error_FailVerify;
  462. }
  463. }
  464. #endif
  465. return 0;
  466. }
  467. static inline int shell_ini__vertify_mod_legality(sp_cfg_shell_ini_t* shell, const char* lib_file_path, const char* mod_name)
  468. {
  469. int rc = 0;
  470. #ifdef _WIN32
  471. CCodeSignVerify ver;
  472. CSignInfo signInfo;
  473. if (!ver.VerifySignature(lib_file_path, signInfo)) {
  474. sp_dbg_error("file %s sign verify fail, %s", mod_name, (const char*)ver.GetErrorMsg());
  475. rc = Error_FailVerify;
  476. }
  477. sp_dbg_info("file %s sign verify pass, signer: %s, sign time: %s, cert hash: %s", mod_name,
  478. (const char*)signInfo.strSignCertSubject, (const char*)signInfo.dtSignTime.ToTimeString(), (const char*)signInfo.strSignCertHash);
  479. if (stricmp(shell->spbase_sign_cert_hash, signInfo.strSignCertHash) != 0) {
  480. sp_dbg_error("entity %s sign cert hash [%s] not equal to spbase sign cert hash [%s]",
  481. mod_name, (const char*)signInfo.strSignCertHash, shell->spbase_sign_cert_hash);
  482. rc = Error_FailVerify;
  483. }
  484. #endif
  485. return rc;
  486. }
  487. static int shell_ini__load_entities_list(sp_dir_t* dir, sp_cfg_shell_ini_t* shell, const char* shell_ini_path, bool vertify_or_not)
  488. {
  489. //read Main:EntityGroupNum
  490. int entityGroupNum = inifile_read_int(shell_ini_path, "Main", "EntityGroupNum", 0);
  491. int curGroup = 0;
  492. int rc = 0;
  493. int i;
  494. array_header_t* arr;
  495. do {
  496. char sectionName[MAX_PATH] = "";
  497. if (0 == curGroup)
  498. sprintf_s(sectionName, MAX_PATH, "Entity");
  499. else
  500. sprintf_s(sectionName, MAX_PATH, "Group%d", curGroup);
  501. arr = inifile_read_section_key_all(shell_ini_path, sectionName);
  502. for (i = 0; i < arr->nelts; ++i) {
  503. char tmp[MAX_PATH];
  504. int ret;
  505. sp_cfg_shell_entity_t* entity = (sp_cfg_shell_entity_t*)shm_malloc(sizeof(sp_cfg_shell_entity_t));
  506. memset(entity, 0, sizeof(sp_cfg_shell_entity_t));
  507. entity->name = shm_strdup(ARRAY_IDX(arr, i, char*));
  508. if (!verify_entity_name(entity->name)) {
  509. rc = Error_Unexpect;
  510. sp_dbg_warn("verify entity %s name failed!", entity->name);
  511. break;
  512. }
  513. entity->debug_level = shell_ini__load_debug_level(shell_ini_path, entity->name);
  514. ret = inifile_format_read(shell_ini_path, sectionName, entity->name, "%d,%[^,],%x", &entity->privilege, tmp, &entity->devel_id);
  515. if (ret == 3) {
  516. sp_cfg_shell_module_t* mod;
  517. if (str_has_suffix(tmp, MOD_LIB_SUFFIX)) {
  518. const int len = strlen(tmp);
  519. tmp[len - strlen(MOD_LIB_SUFFIX)] = 0;
  520. }
  521. mod = find_module(shell, tmp);
  522. if (!mod) {
  523. char mod_lib_path[MAX_PATH];
  524. const int len = (strstr(tmp, "lib") == tmp) ? 3 : 0;
  525. mod = (sp_cfg_shell_module_t*)shm_malloc(sizeof(sp_cfg_shell_module_t));
  526. memset(mod, 0, sizeof(sp_cfg_shell_module_t));
  527. mod->name = shm_strdup(tmp + len);
  528. tmp[strlen(tmp)] = '.';
  529. sprintf(mod_lib_path, "%s" SPLIT_SLASH_STR "%s", dir->mod_path, tmp);
  530. mod->group = curGroup;
  531. if (vertify_or_not) {
  532. rc = shell_ini__vertify_mod_legality(shell, mod_lib_path, mod->name);
  533. }
  534. if (rc == 0) {
  535. shell_ini__get_mod_version(mod, mod_lib_path);
  536. mod->mem_trace = inifile_read_int(shell_ini_path, "MemTrace", mod->name, 0);
  537. mod->idx = shell->arr_module->nelts;
  538. SHM_ARRAY_PUSH(shell->arr_module, sp_cfg_shell_module_t*) = mod;
  539. }
  540. else {
  541. sp_dbg_warn("sal verify file %s failed!", mod_lib_path);
  542. destroy_module(mod);
  543. destroy_entity(entity);
  544. break;
  545. }
  546. }
  547. entity->mod = mod;
  548. entity->idx = shell->arr_entity->nelts;
  549. SHM_ARRAY_PUSH(shell->arr_entity, sp_cfg_shell_entity_t*) = entity;
  550. sp_dbg_info("entity: %s, id: %d", entity->name, entity->idx);
  551. }
  552. else {
  553. sp_dbg_warn("read entity line failed! bad format!");
  554. rc = Error_Param;
  555. destroy_entity(entity);
  556. break;
  557. }
  558. }
  559. if (rc != 0)
  560. break;
  561. toolkit_array_free2(arr);
  562. } while (curGroup++ < entityGroupNum);
  563. return rc;
  564. }
  565. static int shell_ini__load_mod_entity(sp_dir_t* dir, sp_cfg_shell_ini_t* shell, const char* shell_ini_path, const sp_cfg_start_args_t* args, const CVersionInfo* ver)
  566. {
  567. shell->arr_entity = shm_array_make(0, sizeof(sp_cfg_shell_entity_t*));
  568. // BugFix: replace char* with sp_cfg_shell_module_t* [Gifur@2020422]
  569. shell->arr_module = shm_array_make(0, sizeof(sp_cfg_shell_module_t*));
  570. shell_ini__load_init_shell(shell, shell_ini_path, ver);
  571. return shell_ini__load_entities_list(dir, shell, shell_ini_path, args->sign_verifity);
  572. }
  573. static int shell_ini__load_sysevent(sp_cfg_shell_ini_t* shell, const char* shell_ini_path, const char* shell_var_path)
  574. {
  575. int rc = 0;
  576. int i;
  577. array_header_t* arr;
  578. shell->arr_sysevent = shm_array_make(0, sizeof(sp_cfg_shell_sysevent_t*));
  579. arr = inifile_read_section_key_all(shell_ini_path, "SysEvent");
  580. for (i = 0; i < arr->nelts; ++i) {
  581. char tmp[1024], tmp2[1024];
  582. char initVar[SP_CFG_MAX_SYSEVT_BUF];
  583. int ret;
  584. sp_cfg_shell_sysevent_t* sysevent = (sp_cfg_shell_sysevent_t*)shm_malloc(sizeof(sp_cfg_shell_sysevent_t));
  585. memset(sysevent, 0, sizeof(sp_cfg_shell_sysevent_t));
  586. sysevent->name = shm_strdup(ARRAY_IDX(arr, i, char*));
  587. sysevent->arr_owner_entity = shm_array_make(0, sizeof(sp_cfg_shell_entity_t*));
  588. ret = inifile_format_read(shell_ini_path, "SysEvent", sysevent->name, "%[^,], \"%[^\"]", tmp, sysevent->init_value);
  589. auto varRet = inifile_format_read(shell_var_path, "SysEvent", sysevent->name, "%[^,], \"%[^\"]", tmp2, initVar);
  590. if (varRet > 0) {
  591. memcpy(tmp, tmp2, sizeof(tmp));
  592. memcpy(sysevent->init_value, initVar, sizeof(sysevent->init_value)); //如果在shellvar.ini中也能找到该数据,则替换该数值
  593. //情况1:shell.ini添加一个长期有效变量,则在write时在shellvar.ini中生成一个相应的副本。下次读取时从shellvar.ini中读取
  594. //情况2:shell.ini中删除一个长期有效变量,shellvar.ini中并不会相应删除.优先从shell.ini中读取相应变量
  595. }
  596. // 为安全起见,准入实体状态强制设为初始状态I
  597. if (stricmp(sysevent->name, "EntryPermit") == 0)
  598. strcpy(sysevent->init_value, "I");
  599. if (ret > 0) {
  600. const char* seps = ";\t ";
  601. char* tok = strtok(tmp, seps);
  602. while (tok) {
  603. sp_cfg_shell_entity_t* owner_entity = find_entity(shell, tok);
  604. if (owner_entity) {
  605. SHM_ARRAY_PUSH(sysevent->arr_owner_entity, sp_cfg_shell_entity_t*) = owner_entity;
  606. }
  607. else {
  608. sp_dbg_error("cannot find entity: %s", tok);
  609. rc = Error_NotExist;
  610. destroy_sysevent(sysevent);
  611. break;
  612. }
  613. tok = strtok(NULL, seps);
  614. }
  615. if(rc != 0)
  616. break;
  617. sysevent->idx = shell->arr_sysevent->nelts;
  618. SHM_ARRAY_PUSH(shell->arr_sysevent, sp_cfg_shell_sysevent_t*) = sysevent;
  619. }
  620. else {
  621. sp_dbg_warn("read SysEvent failed! bad format!");
  622. rc = Error_Param;
  623. destroy_sysevent(sysevent);
  624. break;
  625. }
  626. }
  627. toolkit_array_free2(arr);
  628. return rc;
  629. }
  630. static int shell_ini__load_entity_list(sp_cfg_shell_ini_t* shell, array_header_t** arr, const char* shell_ini_path, int test_mode)
  631. {
  632. int i;
  633. int rc = 0;
  634. char section_name[128] = { "Startup" };
  635. if (test_mode) {
  636. sp_dbg_debug("test mode: override startup list");
  637. strcpy(section_name, "Test");
  638. }
  639. assert(arr);
  640. assert(*arr == NULL);
  641. i = inifile_read_int(shell_ini_path, section_name, "Number", 0);
  642. if (i >= 0) {
  643. int n = i;
  644. *arr = shm_array_make(i, sizeof(char*));
  645. assert(*arr);
  646. for (i = 1; i <= n; ++i) {
  647. char key[512];
  648. char* s;
  649. _itoa(i, key, 10);
  650. s = inifile_read_str(shell_ini_path, section_name, key, "");
  651. if (s) {
  652. if (strlen(s)) {
  653. int numargs, numchars;
  654. char** argv = NULL;
  655. char* p;
  656. sp_cfg_shell_entity_t* ent;
  657. char* cmdline = strchr(s, ' ');
  658. if (cmdline) {
  659. *cmdline = 0;
  660. cmdline++;
  661. str_parse_cmdline(cmdline, NULL, NULL, &numargs, &numchars);
  662. p = (char*)shm_malloc(numargs * sizeof(char*) + numchars);
  663. argv = (char**)p;
  664. str_parse_cmdline(cmdline, (char**)p, p + numargs * sizeof(char*), &numargs, &numchars);
  665. }
  666. ent = find_entity(shell, s);
  667. if (ent) {
  668. if (cmdline) {
  669. //TODO: detect only use entity::cmdline, never seem use of argc and argv [Gifur@2020426]
  670. ent->argc = numargs;
  671. ent->argv = argv;
  672. if (numargs) {
  673. ent->cmdline = shm_strdup(cmdline);
  674. }
  675. }
  676. SHM_ARRAY_PUSH(*arr, sp_cfg_shell_entity_t*) = ent;
  677. }
  678. else {
  679. sp_dbg_warn("read %s failed! find startup list [%s] defined entity [%s] fail!", section_name, key, s);
  680. rc = Error_Param;
  681. }
  682. }
  683. else {
  684. sp_dbg_warn("read %s failed! startup list [%s] define invalid!", section_name, key);
  685. rc = Error_Param;
  686. }
  687. toolkit_free(s);
  688. }
  689. else {
  690. sp_dbg_warn("read %s failed! startup list [%s] define invalid!", section_name, key);
  691. rc = Error_Param;
  692. }
  693. if (rc != 0)
  694. break;
  695. }
  696. }
  697. else {
  698. sp_dbg_warn("read %s failed! startup number invalid!", section_name);
  699. rc = Error_Param;
  700. }
  701. return rc;
  702. }
  703. /*
  704. static int shell_ini__load_bootup_entities(sp_cfg_shell_ini_t* shell, const char* shell_ini_path, int test_mode)
  705. {
  706. int i;
  707. int rc = 0;
  708. char section_name[128] = { "Startup" };
  709. if (test_mode) {
  710. sp_dbg_debug("test mode: override startup list");
  711. strcpy(section_name, "Test");
  712. }
  713. i = inifile_read_int(shell_ini_path, section_name, "Number", 0);
  714. if (i >= 0) {
  715. int n = i;
  716. shell->arr_startlist = shm_array_make(i, sizeof(char*));
  717. for (i = 1; i <= n; ++i) {
  718. char key[512];
  719. char* s;
  720. _itoa(i, key, 10);
  721. s = inifile_read_str(shell_ini_path, section_name, key, "");
  722. if (s) {
  723. if (strlen(s)) {
  724. int numargs, numchars;
  725. char** argv = NULL;
  726. char* p;
  727. sp_cfg_shell_entity_t* ent;
  728. char* cmdline = strchr(s, ' ');
  729. if (cmdline) {
  730. *cmdline = 0;
  731. cmdline++;
  732. str_parse_cmdline(cmdline, NULL, NULL, &numargs, &numchars);
  733. p = (char*)shm_malloc(numargs * sizeof(char*) + numchars);
  734. argv = (char**)p;
  735. str_parse_cmdline(cmdline, (char**)p, p + numargs * sizeof(char*), &numargs, &numchars);
  736. }
  737. ent = find_entity(shell, s);
  738. if (ent) {
  739. if (cmdline) {
  740. //TODO: detect only use entity::cmdline, never seem use of argc and argv [Gifur@2020426]
  741. ent->argc = numargs;
  742. ent->argv = argv;
  743. if (numargs) {
  744. ent->cmdline = shm_strdup(cmdline);
  745. }
  746. }
  747. SHM_ARRAY_PUSH(shell->arr_startlist, sp_cfg_shell_entity_t*) = ent;
  748. }
  749. else {
  750. sp_dbg_warn("read %s failed! find startup list [%s] defined entity [%s] fail!", section_name, key, s);
  751. rc = Error_Param;
  752. }
  753. }
  754. else {
  755. sp_dbg_warn("read %s failed! startup list [%s] define invalid!", section_name, key);
  756. rc = Error_Param;
  757. }
  758. toolkit_free(s);
  759. }
  760. else {
  761. sp_dbg_warn("read %s failed! startup list [%s] define invalid!", section_name, key);
  762. rc = Error_Param;
  763. }
  764. if (rc != 0)
  765. break;
  766. }
  767. }
  768. else {
  769. sp_dbg_warn("read %s failed! startup number invalid!", section_name);
  770. rc = Error_Param;
  771. }
  772. return rc;
  773. }
  774. */
  775. static int shell_init__load_startup_list(sp_cfg_shell_ini_t* shell, const char* shell_ini_path)
  776. {
  777. return shell_ini__load_entity_list(shell, &shell->arr_startlist, shell_ini_path, 0);
  778. }
  779. static inline int shell_ini__load_software_version(sp_cfg_shell_ini_t* shell, const char* shell_ini_path, const char* shell_runinfo_file)
  780. {
  781. int rc = 0;
  782. shell->software_version.build = 0;
  783. if (NULL != shell_runinfo_file)
  784. rc = read_ini_version(shell_runinfo_file, "Main", "SoftwareVersion",
  785. &shell->software_version.major, &shell->software_version.minor, &shell->software_version.revision, NULL);
  786. if (rc != 0)
  787. rc = read_ini_version(shell_ini_path, "Main", "SoftwareVersion",
  788. &shell->software_version.major, &shell->software_version.minor, &shell->software_version.revision, NULL);
  789. if (rc != 0) {
  790. sp_dbg_warn("read Main::SoftwareVersion failed!");
  791. }
  792. return rc;
  793. }
  794. static int sp_cfg_get_vertify_sign(sp_dir_t* dir, sp_cfg_root_ini_t* root)
  795. {
  796. CSimpleStringA strCenterSettingFullPath;
  797. strCenterSettingFullPath = dir->cfg_path;
  798. if ((stricmp(root->site, "CMB.LIB") == 0) // 行内大堂
  799. || (stricmp(root->site, "CMB.SSB") == 0))// 自助网点
  800. {
  801. strCenterSettingFullPath += SPLIT_SLASH_STR "CenterSetting.LAN.ini";
  802. }
  803. else if ((stricmp(root->site, "CMB.LSS") == 0) // 生活销售机
  804. || (stricmp(root->site, "CMB.FLB") == 0) // 离行机器
  805. || (stricmp(root->site, "CMB.OSB") == 0) // 外拓PAD
  806. || (stricmp(root->site, "CMB.SMM") == 0)) // 商户终端
  807. {
  808. strCenterSettingFullPath += SPLIT_SLASH_STR "CenterSetting.DMZ.ini";
  809. }
  810. else {
  811. strCenterSettingFullPath += SPLIT_SLASH_STR "CenterSetting.DMZ.ini";
  812. }
  813. //add (const char*) for fixing string print bug. Gifur
  814. sp_dbg_info("strCenterSettingFullPath=%s!", (const char*)strCenterSettingFullPath);
  815. //add by zl 20170717,从集中配置读取代码签名开关[VerifyCodeSign]
  816. int nVerifyCodeSign = inifile_read_int(strCenterSettingFullPath.GetData(), "SpBase", "VerifyCodeSign", 0);
  817. sp_dbg_info("get VerifyCodeSign=%d from [%s] ini", nVerifyCodeSign, strCenterSettingFullPath.GetData());
  818. return nVerifyCodeSign > 0 ? 1 : 0;
  819. }
  820. static int load_shell_ini(sp_dir_t *dir, sp_cfg_shell_ini_t *shell, const sp_cfg_start_args_t* args, const char *shell_ini_path, const char *fileVar)
  821. {
  822. int rc = -1;
  823. int i;
  824. array_header_t *arr;
  825. if((rc = shell_ini__load_software_version(shell, shell_ini_path, fileVar)) != 0)
  826. return rc;
  827. if (args->sign_verifity && (rc = shell_ini__veritify_core_file_legality(dir, shell)) != 0)
  828. return rc;
  829. CCodeSignVerify signVerify;
  830. CVersionInfo shellVerInfo;
  831. char spshell_path[MAX_PATH] = { 0 };
  832. sprintf(spshell_path, "%s" SPLIT_SLASH_STR "%s", dir->bin_path, "SpShell.exe");
  833. if (!signVerify.GetVersionInfo(spshell_path, shellVerInfo)) {
  834. sp_dbg_warn("read file %s version info fail, %s", spshell_path, (const char*)signVerify.GetErrorMsg());
  835. }
  836. if ((rc = shell_ini__load_mod_entity(dir, shell, shell_ini_path, args, &shellVerInfo)) != 0)
  837. return rc;
  838. if ((rc = shell_ini__load_sysevent(shell, shell_ini_path, fileVar)) != 0) {
  839. return rc;
  840. }
  841. if (args->debug_mode && shell->arr_entity) {
  842. sp_dbg_debug("override entities' debug level!");
  843. for (i = 0; i < shell->arr_entity->nelts; ++i) {
  844. sp_cfg_shell_entity_t* entity = ARRAY_IDX(shell->arr_entity, i, sp_cfg_shell_entity_t*);
  845. entity->debug_level = 2; /*Debug_High*/
  846. }
  847. }
  848. if (args->start_entities != NULL) {
  849. char* value;
  850. char* name;
  851. char* context = NULL;
  852. array_header_t* t = NULL;
  853. sp_dbg_debug("override start entity list!");
  854. value = _strdup(args->start_entities);
  855. if (!value) {
  856. sp_dbg_error("_strdup start_entities failed!");
  857. return -1;
  858. }
  859. shell->arr_startlist = shm_array_make(1, sizeof(char*));
  860. name = strtok_s(value, ";", &context);
  861. while (name != NULL) {
  862. sp_cfg_shell_entity_t* ent = find_entity(shell, name);
  863. if (ent) {
  864. SHM_ARRAY_PUSH(shell->arr_startlist, sp_cfg_shell_entity_t*) = ent;
  865. } else {
  866. sp_dbg_error("cannot find entity name %s defined at cmdline!", name);
  867. rc = Error_Param;
  868. }
  869. name = strtok_s(NULL, ";", &context);
  870. }
  871. free(value);
  872. if (rc != 0)
  873. return rc;
  874. }
  875. else {
  876. if ((rc = shell_init__load_startup_list(shell, shell_ini_path)) != 0) {
  877. return rc;
  878. }
  879. if (args->test_mode) {
  880. array_header_t* arr = NULL;
  881. if ((rc = shell_ini__load_entity_list(shell, &arr, shell_ini_path, 1)) != 0)
  882. return rc;
  883. if (arr && arr->nelts > 0) {
  884. sp_dbg_info("append additional test entity: %d", arr->nelts);
  885. shm_array_cat(shell->arr_startlist, arr);
  886. }
  887. shm_array_free(arr);
  888. }
  889. }
  890. shell->shell_debug_level = args->debug_mode ? 2 : shell_ini__load_debug_level(shell_ini_path, "SpShell");
  891. shell->nConsolePort = inifile_read_int(shell_ini_path, "Main", "ConsolePort", 0);
  892. auto killNum = inifile_read_int(shell_ini_path, "killProcess", "Number", 0);
  893. g_arrKill.clear();
  894. for (int i = 1; i <= killNum; i++)
  895. {
  896. char key[512];
  897. char* s;
  898. _itoa(i, key, 10);
  899. s = inifile_read_str(shell_ini_path, "killProcess", key, "");
  900. if (s && strlen(s) > 0) {
  901. g_arrKill.push_back(s);
  902. toolkit_free(s);
  903. }
  904. else
  905. {
  906. sp_dbg_warn("read kill failed! killProcess list [%s] define invalid!", key);
  907. rc = Error_Param;
  908. break;
  909. }
  910. }
  911. auto startNum = inifile_read_int(shell_ini_path, "RunScript", "Number", 0);
  912. g_arrStart.clear();
  913. for (int i = 1; i <= startNum; i++)
  914. {
  915. char key[512];
  916. char* s;
  917. _itoa(i, key, 10);
  918. s = inifile_read_str(shell_ini_path, "RunScript", key, "");
  919. if (s && strlen(s) > 0) {
  920. std::string fullPath = std::string(dir->bin_path) + SPLIT_SLASH_STR "spScript" SPLIT_SLASH_STR + s;
  921. g_arrStart.push_back(fullPath);
  922. toolkit_free(s);
  923. }
  924. else
  925. {
  926. sp_dbg_warn("read start failed! RunScript list [%s] define invalid!", key);
  927. rc = Error_Param;
  928. break;
  929. }
  930. }
  931. shell->shell_state = (rc == 0) ? 1 /*booting*/: 3 /*breakdown*/;
  932. return rc;
  933. }
  934. static int unload_shell_ini(sp_cfg_shell_ini_t *shell)
  935. {
  936. int i;
  937. if (shell->arr_entity) {
  938. for (i = 0; i< shell->arr_entity->nelts; ++i) {
  939. sp_cfg_shell_entity_t *entity = ARRAY_IDX(shell->arr_entity, i, sp_cfg_shell_entity_t*);
  940. destroy_entity(entity);
  941. }
  942. shm_array_free(shell->arr_entity);
  943. }
  944. if (shell->arr_module) {
  945. for (i = 0; i < shell->arr_module->nelts; ++i) {
  946. sp_cfg_shell_module_t *mod = ARRAY_IDX(shell->arr_module, i, sp_cfg_shell_module_t*);
  947. destroy_module(mod);
  948. }
  949. shm_array_free(shell->arr_module);
  950. }
  951. if (shell->arr_sysevent) {
  952. for (i = 0; i < shell->arr_sysevent->nelts; ++i) {
  953. sp_cfg_shell_sysevent_t *sysevent = ARRAY_IDX(shell->arr_sysevent, i, sp_cfg_shell_sysevent_t*);
  954. destroy_sysevent(sysevent);
  955. }
  956. shm_array_free(shell->arr_sysevent);
  957. }
  958. if (shell->arr_startlist) {
  959. shm_array_free(shell->arr_startlist);
  960. }
  961. return 0;
  962. }
  963. static int load_install_ini(sp_dir_t *dir, sp_cfg_install_ini_t *inst, const char *file, int shm)
  964. {
  965. int rc = 0;
  966. array_header_t *arr_section = NULL;
  967. int nLastStartTime =0;
  968. sp_version_t active_version = { 0 };
  969. rc = read_ini_version(file, "Main", "InstallVersion",
  970. &inst->install_version.major,
  971. &inst->install_version.minor,
  972. &inst->install_version.revision,
  973. &inst->install_version.build);
  974. if (rc != 0) {
  975. sp_dbg_warn("read ini file failed, %s Main::InstallVersion failed!", file);
  976. return rc;
  977. }
  978. // 校验版本目录名与软件版本是否一致
  979. sscanf(strrchr(dir->base_path, SPLIT_SLASH) + 1, "%d.%d.%d.%d",
  980. &active_version.major, &active_version.minor, &active_version.revision, &active_version.build);
  981. if (sp_version_cmp(&active_version, &inst->install_version) != 0)
  982. {
  983. sp_dbg_warn("version dir %d.%d.%d.%d not equals install version %d.%d.%d.%d",
  984. active_version.major, active_version.minor, active_version.revision, active_version.build,
  985. inst->install_version.major, inst->install_version.minor, inst->install_version.revision, inst->install_version.build);
  986. return -1;
  987. }
  988. inst->install_time = inifile_read_int(file, "Main", "CreateDate", 0);
  989. if (inst->install_time == 0) {
  990. sp_dbg_warn("read ini file failed, %s Main::CreateDate failed", file);
  991. return -1;
  992. }
  993. rc = read_ini_version(file, "Main", "LatterInstallVersion",
  994. &inst->latter_install_version.major,
  995. &inst->latter_install_version.minor,
  996. &inst->latter_install_version.revision,
  997. &inst->latter_install_version.build);
  998. if (rc != 0) {
  999. sp_dbg_warn("read ini file failed, %s Main::LatterInstallVersion failed!", file);
  1000. return rc;
  1001. }
  1002. rc = read_ini_str(file, "Main", "LightPack", &inst->light_packs, shm);
  1003. if (rc != 0 || inst->light_packs == NULL) {
  1004. sp_dbg_warn("read ini file failed, %s Main::LightPack", file);
  1005. return rc;
  1006. }
  1007. inst->arr_light_pack = parse_packs(file, inst->light_packs, shm);
  1008. nLastStartTime = inifile_read_int(file, "Main", "CurrentTime", 0);
  1009. inst->current_startup_time = y2k_time_now();
  1010. {
  1011. char tmp[32];
  1012. sprintf(tmp, "0x%08X", inst->current_startup_time);
  1013. inifile_write_str(file, "Main", "CurrentTime", tmp);
  1014. }
  1015. inst->today_run_count = inifile_read_int(file, "Main", "TodayRunCount", 0);
  1016. if (inst->today_run_count >=0)
  1017. {
  1018. if (y2k_time_is_today(nLastStartTime))
  1019. inst->today_run_count++;
  1020. else
  1021. inst->today_run_count = 1;
  1022. inifile_write_int(file, "Main", "TodayRunCount", inst->today_run_count);
  1023. }
  1024. inst->total_run_count = inifile_read_int(file, "Main", "TotalRunCount", 0);
  1025. if (inst->total_run_count >=0)
  1026. {
  1027. inst->total_run_count++;
  1028. inifile_write_int(file, "Main", "TotalRunCount", inst->total_run_count);
  1029. }
  1030. // read all history version
  1031. arr_section = inifile_read_section_all(file);
  1032. if (arr_section) {
  1033. int i;
  1034. inst->arr_version = T_ARRAY_MAKE(0, sizeof(sp_cfg_version_info_t*), shm);
  1035. for (i = 0; i < arr_section->nelts; ++i) {
  1036. char *sec = ARRAY_IDX(arr_section, i, char*);
  1037. if (_stricmp(sec, "Main") != 0) {
  1038. if (isdigit(sec[0]) && ('.' == sec[1] || '.' == sec[2])) //
  1039. { // skip light pack
  1040. sp_cfg_version_info_t *ver_info = T_MALLOC_T(sp_cfg_version_info_t, shm);
  1041. memset(ver_info, 0, sizeof(sp_cfg_version_info_t));
  1042. sscanf(sec, "%d.%d.%d.%d", &ver_info->version.major, &ver_info->version.minor,
  1043. &ver_info->version.revision, &ver_info->version.build);
  1044. rc = read_ini_version(file, sec, "PreviousInstallVersion",
  1045. &ver_info->previous_version.major, &ver_info->previous_version.minor,
  1046. &ver_info->previous_version.revision, &ver_info->previous_version.build);
  1047. if (rc != 0)
  1048. break;
  1049. rc = read_ini_str(file, sec, "InstallPack", &ver_info->install_pack, shm);
  1050. if (rc != 0)
  1051. break;
  1052. // 轻量安装包没有安装历史
  1053. //ver_info->arr_pack = parse_packs(file, ver_info->packs, shm);
  1054. ver_info->switch_time = inifile_read_int(file, sec, "SwitchOverDate", 0);
  1055. ver_info->install_state = read_ini_install_state(file, sec, "InstallState");
  1056. if (ver_info->install_state == -1)
  1057. break;
  1058. if (shm) {
  1059. SHM_ARRAY_PUSH(inst->arr_version, sp_cfg_version_info_t*) = ver_info;
  1060. } else {
  1061. ARRAY_PUSH(inst->arr_version, sp_cfg_version_info_t*) = ver_info;
  1062. }
  1063. }
  1064. }
  1065. }
  1066. toolkit_array_free2(arr_section);
  1067. } else {
  1068. sp_dbg_warn("read ini file failed, %s, section all failed", file);
  1069. return -1;
  1070. }
  1071. //////////////////////////////
  1072. return rc;
  1073. }
  1074. static void unload_install_ini(sp_cfg_install_ini_t *inst, int shm)
  1075. {
  1076. //...
  1077. }
  1078. // c:\run\version\0.0.0.1\bin
  1079. static int is_valid_version_dir(const char *path)
  1080. {
  1081. const char* p = strrchr(path, SPLIT_SLASH) + 1;
  1082. //sp_version_t ver;
  1083. if (p) {
  1084. while (isdigit(*p))
  1085. p++;
  1086. if (*p++ != '.')
  1087. return FALSE;
  1088. while (isdigit(*p))
  1089. p++;
  1090. if (*p++ != '.')
  1091. return FALSE;
  1092. while (isdigit(*p))
  1093. p++;
  1094. if (*p++ != '.')
  1095. return FALSE;
  1096. while (isdigit(*p))
  1097. p++;
  1098. if (*p == '\0')
  1099. return TRUE;
  1100. }
  1101. return FALSE;
  1102. }
  1103. static int generate_install_ini(sp_dir_t *dir)
  1104. {
  1105. char szIniPath[MAX_PATH] = {0};
  1106. sp_version_t active_version = {0};
  1107. int rc;
  1108. sp_version_t last_verion = {0};
  1109. int l = -1;
  1110. char *packs = NULL;
  1111. rc = sp_dir_get_path(dir, SP_DIR_INSTALL_INI, NULL, szIniPath, MAX_PATH);
  1112. assert(rc == 0);
  1113. sscanf(strrchr(dir->base_path, SPLIT_SLASH) + 1, "%d.%d.%d.%d",
  1114. &active_version.major, &active_version.minor, &active_version.revision, &active_version.build);
  1115. //// copy install.ini
  1116. //{
  1117. // array_header_t *arr = fileutil_get_sub_dirs_a(dir->root_ver_path);
  1118. // array_header_t *arr1 = array_make(0, sizeof(const char*));
  1119. //
  1120. // if (arr) {
  1121. // int i;
  1122. // for (i = 0; i < arr->nelts; ++i)
  1123. // {
  1124. // const char *tmp = (const char*)ARRAY_IDX(arr, i, const char*);
  1125. // if (_stricmp(tmp, dir->base_path) != 0) {
  1126. // if (is_valid_version_dir(tmp)) {
  1127. // ARRAY_PUSH(arr1, const char*) = tmp;
  1128. // } else {
  1129. // sp_dbg_warn("caution: %s is not a version dir", tmp);
  1130. // }
  1131. // }
  1132. // }
  1133. // for (i = 0; i < arr1->nelts; ++i)
  1134. // {
  1135. // const char *tmp1 = (const char*)ARRAY_IDX(arr, i, const char*);
  1136. // sp_version_t ver1;
  1137. // sscanf(strrchr(tmp1, '\\')+1, "%d.%d.%d.%d", &ver1.major, &ver1.minor, &ver1.revision, &ver1.build);
  1138. // if (sp_version_cmp(&ver1, &last_verion) > 0) {
  1139. // l = i;
  1140. // sp_version_copy(&last_verion, &ver1);
  1141. // }
  1142. // }
  1143. // toolkit_array_free2(arr);
  1144. // array_free(arr1);
  1145. // }
  1146. // // 找到除当前版本外最大的版本,拷贝对应版本Install.ini
  1147. // if (l != -1) {
  1148. // char tmp[MAX_PATH];
  1149. // char *install_version = NULL;
  1150. // rc = sp_dir_get_path_version(dir, last_verion.major, last_verion.minor, last_verion.revision, last_verion.build, SP_DIR_INSTALL_INI, NULL, tmp, MAX_PATH);
  1151. // if (rc != 0) {
  1152. // sp_dbg_warn("get path version failed!");
  1153. // return rc;
  1154. // }
  1155. // CopyFileA(tmp, szIniPath, TRUE);
  1156. // // 设置前一版本安装链
  1157. // install_version = inifile_read_str(tmp, "Main", "InstallVersion", "");
  1158. // inifile_write_str(tmp, "Main", "LatterInstallVersion", strrchr(dir->base_path, '\\')+1);
  1159. // inifile_write_str(tmp, install_version, "InstallState", "U");
  1160. // toolkit_free(install_version);
  1161. // }
  1162. //}
  1163. // write install.ini main section
  1164. {
  1165. char szVer[128];
  1166. char szNow[128];
  1167. y2k_time_t now;
  1168. sprintf(szVer, "%d.%d.%d.%d", active_version.major, active_version.minor, active_version.revision, active_version.build);
  1169. inifile_write_str(szIniPath, "Main", "InstallVersion", szVer);
  1170. now = y2k_time_now();
  1171. sprintf(szNow, "0x%08X", now);
  1172. inifile_write_str(szIniPath, "Main", "CreateDate", szNow);
  1173. inifile_write_str(szIniPath, "Main", "LatterInstallVersion", "");
  1174. packs = inifile_read_str(szIniPath, "Main", "LightPack", "");
  1175. inifile_write_str(szIniPath, "Main", "LightPack", "");
  1176. inifile_write_str(szIniPath, "Main", "TotalRunCount", "0");
  1177. inifile_write_str(szIniPath, "Main", "TodayRunCount", "0");
  1178. inifile_write_str(szIniPath, "Main", "CurrentTime", szNow);
  1179. if (l != -1)
  1180. {
  1181. char szPreVer[128];
  1182. sprintf(szPreVer, "%d.%d.%d.%d", last_verion.major, last_verion.minor, last_verion.revision, last_verion.build);
  1183. inifile_write_str(szIniPath, szVer, "PreviousInstallVersion", szPreVer);
  1184. }
  1185. inifile_write_str(szIniPath, szVer, "SwitchOverDate", szNow);
  1186. inifile_write_str(szIniPath, szVer, "InstallPack", "");
  1187. inifile_write_str(szIniPath, szVer, "InstallState", "A");
  1188. }
  1189. // 去掉所有历史版本中轻量安装记录
  1190. if (packs)
  1191. {
  1192. if (strlen(packs) >0)
  1193. {
  1194. char *p = NULL;
  1195. while((p = strrchr(packs, ',')) != NULL)
  1196. {
  1197. *p = 0;
  1198. WritePrivateProfileSectionA(p+1, NULL, szIniPath);
  1199. }
  1200. WritePrivateProfileSectionA(packs, NULL, szIniPath);
  1201. }
  1202. toolkit_free(packs);
  1203. }
  1204. return 0;
  1205. }
  1206. int sp_cfg_create(sp_dir_t *dir, const sp_cfg_start_args_t* args, sp_cfg_t **p_cfg)
  1207. {
  1208. sp_cfg_t *cfg;
  1209. int rc = Error_Unexpect;
  1210. char tmp[MAX_PATH], shell_var_path[MAX_PATH];
  1211. char *shellvarPath = NULL;
  1212. cfg = (sp_cfg_t *)shm_malloc(sizeof(sp_cfg_t));
  1213. memset(cfg, 0, sizeof(sp_cfg_t));
  1214. cfg->root_ini = (sp_cfg_root_ini_t *)shm_malloc(sizeof(sp_cfg_root_ini_t));
  1215. memset(cfg->root_ini, 0, sizeof(sp_cfg_root_ini_t));
  1216. cfg->shell_ini = (sp_cfg_shell_ini_t *)shm_malloc(sizeof(sp_cfg_shell_ini_t));
  1217. memset(cfg->shell_ini, 0, sizeof(sp_cfg_shell_ini_t));
  1218. cfg->install_ini = (sp_cfg_install_ini_t*)shm_malloc(sizeof(sp_cfg_install_ini_t));
  1219. memset(cfg->install_ini, 0, sizeof(sp_cfg_install_ini_t));
  1220. cfg->run_info = (sp_cfg_run_info_t*)shm_malloc(sizeof(sp_cfg_run_info_t));
  1221. memset(cfg->run_info, 0, sizeof(sp_cfg_run_info_t));
  1222. {
  1223. cfg->args = (sp_cfg_start_args_t*)shm_malloc(sizeof(sp_cfg_start_args_t));
  1224. memset(cfg->args, 0, sizeof(sp_cfg_start_args_t));
  1225. cfg->args->start_entities = shm_strdup(args->start_entities);
  1226. cfg->args->test_mode = args->test_mode;
  1227. cfg->args->debug_mode = args->debug_mode;
  1228. cfg->args->guardian_mode = args->guardian_mode;
  1229. cfg->args->sign_verifity = args->sign_verifity;
  1230. cfg->args->ipc_type = args->ipc_type;
  1231. }
  1232. cfg->run_info->startup_time = y2k_time_now();
  1233. rc = sp_dir_get_path(dir, SP_DIR_ROOT_INI, NULL, tmp, MAX_PATH);
  1234. if (rc != 0) {
  1235. sp_dbg_warn("get root ini path failed!");
  1236. return rc;
  1237. }
  1238. rc = load_root_ini(dir, cfg->root_ini, tmp, 1);
  1239. if (rc != 0) {
  1240. sp_dbg_warn("load root.ini failed!");
  1241. return rc;
  1242. }
  1243. cfg->root_ini_path = shm_strdup(tmp);
  1244. rc = sp_dir_get_path(dir, SP_DIR_SHELL_INI, NULL, tmp, MAX_PATH);
  1245. if (rc != 0) {
  1246. sp_dbg_warn("get shell.ini path failed!");
  1247. return rc;
  1248. }
  1249. rc = sp_dir_get_path(dir, SP_DIR_SHELLVAR_INI, NULL, shell_var_path, MAX_PATH);
  1250. if (rc != 0) {
  1251. sp_dbg_warn("get shellvar.ini path failed!");
  1252. return rc;
  1253. }
  1254. std::fstream shellVarFile;
  1255. shellVarFile.open(shell_var_path, std::ios::in);
  1256. if (!shellVarFile) {
  1257. /*cannot found shellVar.ini, then create one.*/
  1258. std::ofstream file(shell_var_path, std::fstream::out);
  1259. }
  1260. shellvarPath = shell_var_path;
  1261. /*override*/
  1262. cfg->args->sign_verifity = sp_cfg_get_vertify_sign(dir, cfg->root_ini);
  1263. if (cfg->args->sign_verifity)
  1264. sp_dbg_info("verify code sign required.");
  1265. rc = load_shell_ini(dir, cfg->shell_ini, cfg->args, tmp, shellvarPath);
  1266. if (rc != 0) {
  1267. sp_dbg_warn("load shell.ini failed!");
  1268. return rc;
  1269. }
  1270. cfg->shell_ini_path = shm_strdup(tmp);
  1271. cfg->shellvar_ini_path = shm_strdup(shell_var_path);
  1272. rc = sp_dir_get_path(dir, SP_DIR_INSTALL_INI, NULL, tmp, MAX_PATH);
  1273. if (rc != 0) {
  1274. sp_dbg_warn("get install.ini path failed!");
  1275. return rc;
  1276. }
  1277. cfg->install_ini_path = shm_strdup(tmp);
  1278. if (!ExistsFileA(tmp)) {
  1279. rc = generate_install_ini(dir);
  1280. if (rc != 0) {
  1281. sp_dbg_warn("generate install.ini failed!");
  1282. return rc;
  1283. }
  1284. }
  1285. rc = load_install_ini(dir, cfg->install_ini, tmp, 1);
  1286. if (rc != 0) {
  1287. sp_dbg_warn("load install.ini failed!");
  1288. return rc;
  1289. }
  1290. spinlock_init(&cfg->lock);
  1291. *p_cfg = cfg;
  1292. sp_dbg_info("create cfg object ok! %08x, lock = %d", cfg, cfg->lock);
  1293. rc = 0;
  1294. return rc;
  1295. }
  1296. void sp_cfg_destroy(sp_cfg_t *cfg)
  1297. {
  1298. unload_root_ini(cfg->root_ini, 1);
  1299. unload_shell_ini(cfg->shell_ini);
  1300. unload_install_ini(cfg->install_ini, 1);
  1301. shm_free(cfg->root_ini);
  1302. shm_free(cfg->root_ini_path);
  1303. shm_free(cfg->shell_ini);
  1304. shm_free(cfg->shell_ini_path);
  1305. shm_free(cfg->install_ini);
  1306. shm_free(cfg->args->start_entities);
  1307. shm_free(cfg->args);
  1308. shm_free(cfg);
  1309. }
  1310. void sp_cfg_lock(sp_cfg_t *cfg)
  1311. {
  1312. spinlock_enter(&cfg->lock, 0);
  1313. }
  1314. void sp_cfg_unlock(sp_cfg_t *cfg)
  1315. {
  1316. spinlock_leave(&cfg->lock);
  1317. }
  1318. sp_cfg_shell_entity_t *sp_cfg_get_entity_by_name(sp_cfg_t *cfg, const char *name)
  1319. {
  1320. return find_entity(cfg->shell_ini, name);
  1321. }
  1322. sp_cfg_shell_entity_t *sp_cfg_get_entity_by_idx(sp_cfg_t *cfg, int idx)
  1323. {
  1324. if (idx >= 0 && idx < cfg->shell_ini->arr_entity->nelts) {
  1325. return ARRAY_IDX(cfg->shell_ini->arr_entity, idx, sp_cfg_shell_entity_t*);
  1326. } else {
  1327. return NULL;
  1328. }
  1329. }
  1330. sp_cfg_shell_entity_t *sp_cfg_get_entity_shell(sp_cfg_t *cfg)
  1331. {
  1332. return ARRAY_IDX(cfg->shell_ini->arr_entity, 0, sp_cfg_shell_entity_t*);
  1333. }
  1334. sp_cfg_shell_module_t *sp_cfg_get_module_by_name(sp_cfg_t *cfg, const char *name)
  1335. {
  1336. return find_module(cfg->shell_ini, name);
  1337. }
  1338. sp_cfg_shell_module_t *sp_cfg_get_module_by_idx(sp_cfg_t *cfg, int idx)
  1339. {
  1340. if (idx >= 0 && idx < cfg->shell_ini->arr_module->nelts) {
  1341. return ARRAY_IDX(cfg->shell_ini->arr_module, idx, sp_cfg_shell_module_t*);
  1342. } else {
  1343. return NULL;
  1344. }
  1345. }
  1346. sp_cfg_shell_module_t *sp_cfg_get_module_shell(sp_cfg_t *cfg)
  1347. {
  1348. return ARRAY_IDX(cfg->shell_ini->arr_module, 0, sp_cfg_shell_module_t*);
  1349. }
  1350. sp_cfg_shell_sysevent_t*sp_cfg_get_sysevent(sp_cfg_t *cfg, const char *name)
  1351. {
  1352. array_header_t *arr_sysevent = cfg->shell_ini->arr_sysevent;
  1353. int i;
  1354. for (i = 0; i < arr_sysevent->nelts; ++i) {
  1355. sp_cfg_shell_sysevent_t *tmp = ARRAY_IDX(arr_sysevent, i, sp_cfg_shell_sysevent_t *);
  1356. if (_stricmp(tmp->name, name) == 0)
  1357. return tmp;
  1358. }
  1359. return NULL;
  1360. }
  1361. char *sp_cfg_get_path(sp_cfg_t *cfg, const char *path_prefix)
  1362. {
  1363. sp_cfg_path_t *path = find_path(cfg, path_prefix);
  1364. if (path) {
  1365. return path->path;
  1366. }
  1367. return NULL;
  1368. }
  1369. int sp_cfg_refresh_debug_level(sp_cfg_t *cfg, sp_cfg_shell_entity_t *cfg_ent)
  1370. {
  1371. //TODO: shell.ini cannot be written!!
  1372. char tmp[32];
  1373. _itoa(cfg_ent->debug_level, tmp, 10);
  1374. return WritePrivateProfileStringA("Debug", cfg_ent->name, tmp, cfg->shell_ini_path) ? 0 : Error_IO;
  1375. }
  1376. int sp_cfg_util_read_root_ini_version(sp_cfg_root_ini_t *ini, int major, int minor, int revision, int build)
  1377. {
  1378. char tmp[MAX_PATH];
  1379. sp_env_t *env = sp_get_env();
  1380. sp_dir_get_path_version(env->dir, major, minor, revision, build, SP_DIR_ROOT_INI, NULL, tmp, MAX_PATH);
  1381. return load_root_ini(env->dir, ini, tmp, 0);
  1382. }
  1383. int sp_cfg_util_free_root_ini(sp_cfg_root_ini_t *ini)
  1384. {
  1385. unload_root_ini(ini, 0);
  1386. return 0;
  1387. }
  1388. int sp_cfg_get_devel_id(sp_cfg_t *cfg, int idx)
  1389. {
  1390. sp_env_t *env = sp_get_env();
  1391. sp_cfg_shell_entity_t *cfg_ent = sp_cfg_get_entity_by_idx(env->cfg, idx);
  1392. return cfg_ent->devel_id;
  1393. }
  1394. sp_cfg_version_info_t* sp_cfg_find_previous_version_info(sp_cfg_t *cfg, const sp_version_t *version)
  1395. {
  1396. sp_cfg_version_info_t* ver_info = sp_cfg_find_version_info(cfg, version);
  1397. if (ver_info) {
  1398. sp_version_t *previous_version = &ver_info->previous_version;
  1399. return sp_cfg_find_version_info(cfg, previous_version);
  1400. }
  1401. return NULL;
  1402. }
  1403. sp_cfg_version_info_t* sp_cfg_find_version_info(sp_cfg_t *cfg, const sp_version_t *version)
  1404. {
  1405. int i;
  1406. for (i = 0; i < cfg->install_ini->arr_version->nelts; ++i) {
  1407. sp_cfg_version_info_t *ver_info = ARRAY_IDX(cfg->install_ini->arr_version, i, sp_cfg_version_info_t*);
  1408. //if (sp_version_equal_3(&ver_info->version, version))
  1409. if (sp_version_equal(&ver_info->version, version))
  1410. return ver_info;
  1411. }
  1412. return NULL;
  1413. }
  1414. int sp_cfg_is_pack_installed(sp_cfg_t *cfg, const char*pack)
  1415. {
  1416. // 先查找轻量表历史
  1417. int i;
  1418. for(i =0; i<cfg->install_ini->arr_light_pack->nelts; i++)
  1419. {
  1420. sp_cfg_pack_info_t *pack_info = ARRAY_IDX(cfg->install_ini->arr_light_pack, i, sp_cfg_pack_info_t *);
  1421. if (stricmp(pack_info->name, pack) == 0)
  1422. return 0;
  1423. }
  1424. // 再查找版本安装包
  1425. for (i = 0; i < cfg->install_ini->arr_version->nelts; ++i)
  1426. {
  1427. sp_cfg_version_info_t *ver_info = ARRAY_IDX(cfg->install_ini->arr_version, i, sp_cfg_version_info_t*);
  1428. if (stricmp(ver_info->install_pack, pack) ==0)
  1429. return 0;
  1430. }
  1431. return 1;
  1432. }