SpBase.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpTimer.h"
  4. #include "SpEntity.h"
  5. #include "SpModule.h"
  6. #ifdef WIN32
  7. #include "SpBaseRoutine.h"
  8. #endif
  9. #include "SpMisc.h"
  10. #include "SpClientSessionFunction.h"
  11. #include "sockutil.h"
  12. #include "fileutil.h"
  13. #include "sp_shm.h"
  14. #include "sp_dbg_export.h"
  15. #include "sp_def.h"
  16. #include "sp_env.h"
  17. #include "DumpException.h"
  18. #ifdef _WIN32
  19. #include "sp_checkEntity.h"
  20. #include <DbgHelp.h>
  21. #else
  22. #include <exception>
  23. #endif // _WIN32
  24. #include<winpr//library.h>
  25. #include <winpr/locale.h>
  26. #include <winpr/exception.h>
  27. #ifndef _WIN32
  28. static SpModule* g_module = NULL;
  29. #endif //NOT _WIN32
  30. SpModule *GetSpModule()
  31. {
  32. #ifdef _WIN32
  33. SpModule *curModule = NULL;
  34. if (findThreadModule(GetCurrentThreadId(), (void **)&curModule))
  35. return curModule;
  36. else
  37. {
  38. CSimpleStringA mod_name = TraceStack();
  39. if (CSimpleStringA("") == mod_name) {
  40. return NULL;
  41. }
  42. SetthreadGroup(GetCurrentThreadId(), mod_name);
  43. if (findThreadModule(GetCurrentThreadId(), (void**)&curModule))
  44. return curModule;
  45. }
  46. return NULL;
  47. #else
  48. return g_module;
  49. #endif //_WIN32
  50. }
  51. #ifdef _WIN32
  52. static LONG WINAPI SuppressError(struct _EXCEPTION_POINTERS* ExceptionInfo)
  53. {
  54. char tmp[MAX_PATH] = { '\0' };
  55. char drivePath[_MAX_DRIVE] = {'\0'};
  56. sp_dir_get_cur_drive(drivePath);
  57. wsprintfA(tmp, "%s\\rvc\\dmp\\expt.%s.%d.%d.log", drivePath, GetSpModule() ? GetSpModule()->get_mod()->cfg->name : "", GetCurrentThreadId(), GetCurrentProcessId());
  58. HANDLE hLogFile = ::CreateFileA(tmp, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  59. if (hLogFile != INVALID_HANDLE_VALUE) {
  60. DumpExceptionInfo(ExceptionInfo, hLogFile);
  61. FlushFileBuffers(hLogFile);
  62. SetEndOfFile(hLogFile);
  63. CloseHandle(hLogFile);
  64. }
  65. wsprintfA(tmp, "%s\\rvc\\dmp\\expt.%s.%d.%d.dmp", drivePath, GetSpModule() ? GetSpModule()->get_mod()->cfg->name : "", GetCurrentThreadId(), GetCurrentProcessId());
  66. HANDLE hDumpFile = CreateFileA( tmp, GENERIC_READ | GENERIC_WRITE,
  67. 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  68. if( ( hDumpFile != NULL ) && ( hDumpFile != INVALID_HANDLE_VALUE ) )
  69. {
  70. MINIDUMP_EXCEPTION_INFORMATION mdei;
  71. mdei.ThreadId = GetCurrentThreadId();
  72. mdei.ExceptionPointers = ExceptionInfo;
  73. mdei.ClientPointers = FALSE;
  74. MINIDUMP_TYPE mdt = MiniDumpWithIndirectlyReferencedMemory;
  75. BOOL rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
  76. hDumpFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
  77. CloseHandle( hDumpFile );
  78. }
  79. Dbg("exit entity exception!");
  80. ExitProcess(Error_Exception); // exit process to suppress reporting exception
  81. return EXCEPTION_EXECUTE_HANDLER;
  82. }
  83. static void DisableSetUnhandledExceptionFilter()
  84. {
  85. void* addr = (void*)GetProcAddress(LoadLibrary("kernel32.dll"), "SetUnhandledExceptionFilter");
  86. if (addr) {
  87. DWORD dwOldFlag, dwTempFlag;
  88. unsigned char code[] = {0x33, 0xC0, 0xC2, 0x04, 0x00}; // xor eax,eax; ret 4;
  89. VirtualProtect(addr, sizeof(code), PAGE_READWRITE, &dwOldFlag);
  90. WriteProcessMemory(GetCurrentProcess(), addr, code, sizeof(code), NULL);
  91. VirtualProtect(addr, sizeof(code), dwOldFlag, &dwTempFlag);
  92. }
  93. }
  94. #endif //_WIN32
  95. SPBASE_API void LogEvent(const SeverityLevelEnum eLevel,DWORD dwUserEventCode,const char *pszMessage)
  96. {//MAX string len < 1024
  97. SpModule *pModule = GetSpModule();
  98. if (pModule) {
  99. pModule->LogMessage(Log_Event, eLevel, 0, dwUserEventCode, pszMessage);
  100. }
  101. // write a copy in dbg log
  102. sp_dbg_info("Event: {%s}(uc=0x%X)", pszMessage, dwUserEventCode);
  103. }
  104. SPBASE_API void LogError(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode,DWORD dwUserErrorCode,const char *pszMessage)
  105. {
  106. SpModule *pModule = GetSpModule();
  107. if (pModule) {
  108. pModule->LogMessage(Log_Error, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage);
  109. }
  110. else
  111. sp_dbg_info("LogError failed!can not find the module");
  112. // write a copy in dbg log
  113. sp_dbg_error("Error: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  114. }
  115. SPBASE_API void LogWarn(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode,DWORD dwUserErrorCode, const char *pszMessage)
  116. {
  117. SpModule *pModule = GetSpModule();
  118. if (pModule) {
  119. pModule->LogMessage(Log_Warning, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage);
  120. }
  121. // write a copy in dbg log
  122. sp_dbg_warn("Warn: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  123. }
  124. SPBASE_API void LogAssert(const char *pszMessage,const char *pszFile,const int nLine)
  125. {
  126. SpModule *pModule = GetSpModule();
  127. if (pModule) {
  128. pModule->LogMessage(Log_Debug, Severity_Middle, 0, 0,
  129. CSimpleStringA::Format("assert fail: {%s}, file: {%s}, line: {%d}, stack: {%s}",
  130. pszMessage, _GetFileName(pszFile), nLine,
  131. #ifdef _WIN32
  132. (const char*)DumpStack(2)
  133. #else
  134. "not implement, TODO:"
  135. #endif //_WIN32
  136. ));
  137. }
  138. // write a copy in dbg log
  139. sp_dbg_debug("Assert fail: {%s}, file: {%s}, line: {%d}, stack: {%s}",
  140. pszMessage, _GetFileName(pszFile), nLine,
  141. #ifdef _WIN32
  142. (const char*)DumpStack(2)
  143. #else
  144. "not implement, TODO:"
  145. #endif //_WIN32
  146. );
  147. }
  148. SPBASE_API void LogTrace(const char *pszMessage,const char *pszFile,const int nLine)
  149. {
  150. SpModule *pModule = GetSpModule();
  151. if (pModule) {
  152. pModule->LogMessage(Log_Debug, Severity_None, 0, 0, pszMessage);
  153. }
  154. // write a copy in dbg log
  155. sp_dbg_debug("Trace: {%s}, file: {%s}, line: {%d}", pszMessage, _GetFileName(pszFile), nLine);
  156. }
  157. #include "log.h"
  158. #include <malloc.h>
  159. extern "C" SPBASE_API void Dbg(const char *str, ...)
  160. {
  161. va_list arg;
  162. va_start(arg, str);
  163. vDbg(str, arg);
  164. va_end(arg);
  165. }
  166. extern "C" SPBASE_API void vDbg(const char *str, va_list list)
  167. {
  168. int n = _vscprintf(str, list);
  169. if (n > 1024)
  170. n = 1024;
  171. char *buf = (char*)_alloca(n+1);
  172. memset(buf, 0, n+1);
  173. /*write at most n bytes(including the terminating null byte '\0') to buf*/
  174. vsnprintf(buf, n+1, str, list); // plus 1 to n, never changed code but the log lost one char [4/1/2020 16:25 Gifur]
  175. sp_dbg_debug("Debug: {%s}", buf); //打印到文件
  176. //修改,不发出Log_Debug类消息
  177. //SpModule* pModule = GetSpModule();
  178. // if (pModule)
  179. // {
  180. // __try
  181. // {
  182. // SpEntity *pEntity = (SpEntity*)(getEntityResource()->m_Entity);
  183. //
  184. // if (pEntity != NULL)
  185. // {
  186. // auto pEntCfg = pEntity->get_cfg_ent();
  187. // if (pEntCfg != NULL && pEntCfg->debug_level > 0)
  188. // {
  189. // pEntity->LogMessage(Log_Debug, Severity_None, -1, -1, buf);
  190. // }
  191. // }
  192. // }
  193. // __finally
  194. // {
  195. //
  196. // }
  197. // }
  198. }
  199. static bool RegistMain(HMODULE hModule,EntryRoutine Main, EntryRoutine Exit)
  200. {
  201. SpModule::SetEntryRoutine(Main, Exit);
  202. return true;
  203. }
  204. static HMODULE LoadModuleLibrary(sp_mod_t *mod)
  205. {
  206. sp_env_t *env = sp_get_env();
  207. char tmp[MAX_PATH];
  208. sp_dir_get_path(env->dir, SP_DIR_MODULE_BIN, mod->cfg->name, tmp, sizeof(tmp));
  209. return LoadLibraryA(tmp);
  210. }
  211. /*It seems never been used anywhere.*/
  212. SPBASE_API HINSTANCE SpLoadLibrary(const char *file)
  213. {
  214. sp_env_t *env = sp_get_env();
  215. if (env) {
  216. char tmp[MAX_PATH];
  217. sprintf(tmp, "%s" SPLIT_SLASH_STR "%s", env->dir->dep_path, file);
  218. return LoadLibraryA(tmp);
  219. } else {
  220. return NULL;
  221. }
  222. }
  223. /*only sphost would invoke it.*/
  224. extern "C" SPBASE_API int __stdcall SpExit(const char* mod_name)
  225. {
  226. #ifdef _WIN32
  227. Dbg("Do SpExit!");
  228. SetthreadGroup(GetCurrentThreadId(), mod_name);
  229. CleanModuleThread(mod_name);
  230. sp_iom_stop(GetSpModule()->get_iom());
  231. GetSpModule()->Term();
  232. sp_shm_term();
  233. sp_dbg_term();
  234. sp_iom_destroy(GetSpModule()->get_iom());
  235. delete GetSpModule();
  236. //winsock_term();
  237. FreeLibrary(getEntityResource()->m_Module);
  238. DestoryModuleInfo(mod_name);
  239. #else
  240. if (sp_shm_is_newalloc())
  241. return 0; /*spshell*/
  242. if (g_module) {
  243. delete g_module;
  244. g_module = nullptr;
  245. }
  246. #endif //_WIN32
  247. return 0;
  248. }
  249. //static void SpExit(void) __attribute__((destructor));
  250. extern "C" SPBASE_API int __stdcall SpRun(const char *mod_name, int epid, int range, int group)
  251. {
  252. ErrorCodeEnum Error = Error_Unexpect;
  253. if (!mod_name) { return Error_Bug; }
  254. if (epid == SP_INVALID_MOD_ID) { return Error_Bug; }
  255. #ifdef _WIN32
  256. if (findModuleByName(mod_name)) //检测实体是否已创建
  257. SpExit(mod_name);
  258. bool result = group == 0 ? CreateModuleInfo(ENTITY_SINGLE_GROUPNAME) : CreateModuleInfo(mod_name);
  259. //the SetthreadGroup routine would never return false, so the group variable must be not-zero
  260. if (!result || !SetthreadGroup(GetCurrentThreadId(), mod_name))
  261. return Error_Duplication;
  262. #else
  263. if (g_module) {
  264. return Error_Duplication;
  265. }
  266. #endif //_WIN32
  267. /*the log is separeted by {mod_name},so if there are gt one entity defined at one module,
  268. *the log about each brother entity also store in same log file.
  269. */
  270. sp_dbg_init(mod_name);
  271. if (winsock_init() != 0) {
  272. return Error_NetBroken;
  273. }
  274. sp_dbg_info("==============SpRun(%s) start==============", mod_name);
  275. sp_dbg_info("process id: %d", GetCurrentProcessId());
  276. void *hint_addr = sp_shm_init(range, FALSE);
  277. if (!hint_addr) {
  278. sp_dbg_warn("shm init failed! hint_addr: 0x%08x", hint_addr);
  279. return Error_Unexpect;
  280. }
  281. sp_dbg_info("shm init ok! hint_addr: 0x%08x", hint_addr);
  282. sp_env_t *env = sp_get_env();
  283. if (!env) {
  284. sp_dbg_warn("module env object init failed!");
  285. return Error_Unexpect;
  286. }
  287. sp_dbg_info("retrieve env object ok!");
  288. sp_mod_t *mod = sp_mod_mgr_find_module_by_idx(env->mod_mgr, epid);
  289. if (!mod) {
  290. sp_dbg_warn("find shm module object failed!");
  291. return Error_NotExist;
  292. }
  293. sp_dbg_info("find module %s id %d ok!", mod->cfg->name, mod->cfg->idx);
  294. sp_dbg_info("module %s file version: %d.%d.%d.%d", mod->cfg->name,
  295. mod->cfg->version.major,
  296. mod->cfg->version.minor,
  297. mod->cfg->version.revision,
  298. mod->cfg->version.build);
  299. SpInitUUID((WORD)mod->cfg->idx);
  300. sp_cfg_shell_module_t *cfg_mod = sp_cfg_get_module_by_idx(env->cfg, epid);
  301. if (!cfg_mod) {
  302. sp_dbg_warn("get module %s cfg object failed!", mod->cfg->name);
  303. return Error_Bug;
  304. }
  305. sp_dbg_info("find cfg module object %s id %d ok!", cfg_mod->name, cfg_mod->idx);
  306. #ifdef _WIN32
  307. SetUnhandledExceptionFilter(&SuppressError);
  308. //DisableSetUnhandledExceptionFilter();
  309. #endif //_WIN32
  310. #ifdef _WIN32
  311. SpModule* curModule = new SpModule(mod, cfg_mod);
  312. getEntityResource()->m_Module = LoadModuleLibrary(mod);
  313. if (!getEntityResource()->m_Module) {
  314. sp_dbg_warn("load module library %s failed! GetLastError = %d", mod->cfg->name, GetLastError());
  315. goto on_error;
  316. }
  317. curModule->getEntryRoutine(&(getEntityResource()->m_pfMain), &(getEntityResource()->m_pfExit));
  318. Error = curModule->Init(env->url);
  319. if (Error) {
  320. delete curModule;
  321. curModule = NULL;
  322. goto on_error;
  323. }
  324. #else
  325. g_module = new SpModule(mod, cfg_mod);
  326. HMODULE hModule = LoadModuleLibrary(mod);
  327. if (!hModule) {
  328. sp_dbg_warn("load module library %s failed! GetLastError = %d", mod->cfg->name, GetLastError());
  329. goto on_error;
  330. }
  331. Error = g_module->Init(env->url);
  332. if (Error) {
  333. goto on_error;
  334. }
  335. #endif //_WIN32
  336. sp_dbg_debug("before set thread priority");
  337. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
  338. sp_dbg_debug("after set thread priority");
  339. #ifdef _WIN32
  340. if (!SetSpModule(mod_name, curModule))
  341. goto on_error;
  342. Error = curModule->Run();
  343. curModule->Term();
  344. FreeLibrary(getEntityResource()->m_Module);
  345. delete curModule;
  346. curModule = NULL;
  347. #else
  348. Error = g_module->Run();
  349. g_module->Term();
  350. #endif //_WIN32
  351. sp_shm_term();
  352. on_error:
  353. #ifndef _WIN32
  354. if (hModule) {
  355. FreeLibrary(hModule);
  356. hModule = NULL;
  357. }
  358. if (g_module) {
  359. delete g_module;
  360. g_module = nullptr;
  361. }
  362. #endif //NOT _WIN32
  363. return Error;
  364. }
  365. #define SPBASE_ERRNO_MAP(MAP) \
  366. MAP(Error_Succeed, "Error_Succeed") \
  367. MAP(Error_DataCheck, "Error_DataCheck") \
  368. MAP(Error_Null, "Error_Null") \
  369. MAP(Error_Param, "Error_Param") \
  370. MAP(Error_Overflow, "Error_Overflow") \
  371. MAP(Error_TooSmallBuffer, "Error_TooSmallBuffer") \
  372. MAP(Error_NotIntegrated, "Error_NotIntegrated") \
  373. MAP(Error_CheckSum, "Error_CheckSum") \
  374. MAP(Error_TargetBeing, "Error_TargetBeing") \
  375. MAP(Error_NoTarget, "Error_NoTarget") \
  376. MAP(Error_NoDefine, "Error_NoDefine") \
  377. MAP(Error_NotImpl, "Error_NotImpl") \
  378. MAP(Error_NotExist, "Error_NotExist") \
  379. MAP(Error_Duplication, "Error_Duplication") \
  380. MAP(Error_Unregisted, "Error_Unregisted") \
  381. MAP(Error_AlreadyExist, "Error_AlreadyExist") \
  382. MAP(Error_MethodNotFound, "Error_MethodNotFound") \
  383. MAP(Error_Redirect, "Error_Redirect") \
  384. MAP(Error_BridgeNotBind, "Error_BridgeNotBind") \
  385. MAP(Error_BridgeNotOK, "Error_BridgeNotOK") \
  386. MAP(Error_NotSupport, "Error_NotSupport") \
  387. MAP(Error_InvalidState, "Error_InvalidState") \
  388. MAP(Error_NotInit, "Error_NotInit") \
  389. MAP(Error_Paused, "Error_Paused") \
  390. MAP(Error_Stoped, "Error_Stoped") \
  391. MAP(Error_Losted, "Error_Losted") \
  392. MAP(Error_Closed, "Error_Closed") \
  393. MAP(Error_Accept, "Error_Accept") \
  394. MAP(Error_Failed, "Error_Failed") \
  395. MAP(Error_Busy, "Error_Busy") \
  396. MAP(Error_TaskControl, "Error_TaskControl") \
  397. MAP(Error_Pending, "Error_Pending") \
  398. MAP(Error_Cancel, "Error_Cancel") \
  399. MAP(Error_Break, "Error_Break") \
  400. MAP(Error_NotMeetCondition, "Error_NotMeetCondition") \
  401. MAP(Error_NoPrivilege, "Error_NoPrivilege") \
  402. MAP(Error_MethodSignatureFailed, "Error_MethodSignatureFailed") \
  403. MAP(Error_PeerAction, "Error_PeerAction") \
  404. MAP(Error_PeerClose, "Error_PeerClose") \
  405. MAP(Error_PeerIgnore, "Error_PeerIgnore") \
  406. MAP(Error_PeerReject, "Error_PeerReject") \
  407. MAP(Error_PeerDelay, "Error_PeerDelay") \
  408. MAP(Error_Process, "Error_Process") \
  409. MAP(Error_NetBroken, "Error_NetBroken") \
  410. MAP(Error_UpdateFailed, "Error_UpdateFailed") \
  411. MAP(Error_RegistryFailed, "Error_RegistryFailed") \
  412. MAP(Error_IO, "Error_IO") \
  413. MAP(Error_Readonly, "Error_Readonly") \
  414. MAP(Error_TimeOut, "Error_TimeOut") \
  415. MAP(Error_BlockTimeOut, "Error_BlockTimeOut") \
  416. MAP(Error_ThreadTimeOut, "Error_ThreadTimeOut") \
  417. MAP(Error_QueueTimeOut, "Error_QueueTimeOut") \
  418. MAP(Error_ReplyTimeOut, "Error_ReplyTimeOut") \
  419. MAP(Error_Hardware, "Error_Hardware") \
  420. MAP(Error_DevLoadFileFailed, "Error_DevLoadFileFailed") \
  421. MAP(Error_DevNotAvailable, "Error_DevNotAvailable") \
  422. MAP(Error_DevAlreadyConnected, "Error_DevAlreadyConnected") \
  423. MAP(Error_DevConnFailed, "Error_DevConnFailed") \
  424. MAP(Error_DevCommFailed, "Error_DevCommFailed") \
  425. MAP(Error_DevMedia, "Error_DevMedia") \
  426. MAP(Error_EnvCamera, "Error_EnvCamera") \
  427. MAP(Error_OptCamera, "Error_OptCamera") \
  428. MAP(Error_AllCamera, "Error_AllCamera") \
  429. MAP(Error_AudioIN, "Error_AudioIN") \
  430. MAP(Error_AudioOut, "Error_AudioOut") \
  431. MAP(Error_Debug, "Error_Debug") \
  432. MAP(Error_Assert, "Error_Assert") \
  433. MAP(Error_Trace, "Error_Trace") \
  434. MAP(Error_Bug, "Error_Bug") \
  435. MAP(Error_Unrecover, "Error_Unrecover") \
  436. MAP(Error_Resource, "Error_Resource") \
  437. MAP(Error_NewProcess, "Error_NewProcess") \
  438. MAP(Error_FailVerify, "Error_FailVerify") \
  439. MAP(Error_Block, "Error_Block") \
  440. MAP(Error_Exception, "Error_Exception") \
  441. MAP(Error_Unexpect, "Error_Unexpect") \
  442. MAP(Error_IgnoreAll, "Error_IgnoreAll")
  443. #define SPBASE_ERRNO_IMPL_MAP(nErrCode, szErrMsg) \
  444. case nErrCode : return szErrMsg; break;
  445. extern "C" SPBASE_API const char* SpStrError(ErrorCodeEnum errorCode)
  446. {
  447. static char szErrInfo[64];
  448. switch (errorCode) {
  449. SPBASE_ERRNO_MAP(SPBASE_ERRNO_IMPL_MAP)
  450. default:
  451. break;
  452. }
  453. // multi-unsafe!!!! [Gifur@2020422]
  454. sprintf(szErrInfo, "Unkown ErrorCode(0x%08X)", errorCode);
  455. return szErrInfo;
  456. }
  457. #undef SPBASE_ERRNO_IMPL_MAP
  458. SPBASE_API CSimpleStringA GetSysErrMsg(int nErrCode)
  459. {
  460. char szBuf[2048] = {};
  461. DWORD dwRet = FormatMessageA(
  462. FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  463. NULL,
  464. nErrCode,
  465. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  466. szBuf,
  467. sizeof(szBuf)-1,
  468. NULL);
  469. char *p = strrchr(szBuf, '\r');
  470. if (p != NULL)
  471. *p = ' ';
  472. p = strrchr(szBuf, '\n');
  473. if (p != NULL)
  474. *p = ' ';
  475. return dwRet > 0 ? szBuf : CSimpleStringA::Format("get error message fail: %d", GetLastError());
  476. }
  477. SPBASE_API const char *_GetFileName(const char *pszFilePath)
  478. {
  479. int i=strlen(pszFilePath);
  480. for( ; i>0 && pszFilePath[i-1]!=SPLIT_SLASH; i--)NULL;
  481. return pszFilePath+i;
  482. }
  483. #ifdef _WIN32
  484. extern "C" BOOL APIENTRY DllMain(HMODULE hModule,
  485. DWORD ul_reason_for_call,
  486. LPVOID lpReserved)
  487. {
  488. switch (ul_reason_for_call) {
  489. case DLL_PROCESS_ATTACH:
  490. {
  491. DisableThreadLibraryCalls(hModule);
  492. break;
  493. }
  494. case DLL_THREAD_ATTACH:
  495. break;
  496. case DLL_THREAD_DETACH:
  497. break;
  498. case DLL_PROCESS_DETACH:
  499. break;
  500. }
  501. return TRUE;
  502. }
  503. #endif //_WIN32
  504. ModuleBase::~ModuleBase()
  505. {
  506. #ifdef _WIN32
  507. getEntityResource()->m_moduleBase = NULL;
  508. #else
  509. ModuleBase::s_pModuleInst = NULL;
  510. #endif //_WIN32
  511. for (int i = 0; i < m_nEntityCount; ++i)
  512. {
  513. if (m_pEntityArray[i])
  514. {
  515. #ifdef _WIN32
  516. __try {
  517. delete m_pEntityArray[i];
  518. }
  519. __finally {
  520. m_pEntityArray[i] = NULL;
  521. }
  522. #else
  523. delete m_pEntityArray[i];
  524. m_pEntityArray[i] = NULL;
  525. #endif //_WIN32
  526. }
  527. }
  528. m_nEntityCount = 0;
  529. }
  530. static ErrorCodeEnum __Init()
  531. {
  532. #ifdef _WIN32
  533. ModuleBase* pThis = (ModuleBase*)(getEntityResource()->m_moduleBase);
  534. #else
  535. ModuleBase* pThis = ModuleBase::s_pModuleInst;
  536. #endif //_WIN32
  537. _ASSERT(pThis);
  538. return pThis->Init();
  539. }
  540. static ErrorCodeEnum __Exit()
  541. {
  542. #ifdef _WIN32
  543. ModuleBase* pThis = (ModuleBase*)(getEntityResource()->m_moduleBase);
  544. #else
  545. ModuleBase* pThis = ModuleBase::s_pModuleInst;
  546. #endif //_WIN32
  547. _ASSERT(pThis);
  548. return pThis->Exit();
  549. }
  550. ErrorCodeEnum ModuleBase::Init()
  551. {
  552. ErrorCodeEnum Error = Error_Succeed;
  553. for (int i = 0; i < m_nEntityCount; ++i)
  554. {
  555. Error = RegistEntity(m_pEntityArray[i]);
  556. if (Error)
  557. break;
  558. }
  559. return Error;
  560. }
  561. ErrorCodeEnum ModuleBase::Exit()
  562. {
  563. ErrorCodeEnum Error = Error_Succeed;
  564. for (int i = 0; i < m_nEntityCount; ++i)
  565. {
  566. Error = UnregistEntity(m_pEntityArray[i]);
  567. if (Error)
  568. break;
  569. }
  570. return Error;
  571. }
  572. BOOL ModuleBase::DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  573. {
  574. if (dwReason == DLL_PROCESS_ATTACH) {
  575. bool ret = RegistMain(hInstance, &__Init, &__Exit);
  576. if (!ret)
  577. return FALSE;
  578. DisableThreadLibraryCalls(hInstance);
  579. m_hInstance = hInstance;
  580. }
  581. return TRUE;
  582. }
  583. ErrorCodeEnum ModuleBase::RegistEntity(CEntityBase *pEntity)
  584. {
  585. SpModule *pModule = GetSpModule();
  586. if (!pModule)
  587. return Error_Null;
  588. return pModule->AddEntityBase(pEntity);
  589. }
  590. ErrorCodeEnum ModuleBase::UnregistEntity(CEntityBase *pEntity)
  591. {
  592. SpModule *pModule = GetSpModule();
  593. return pModule->RemoveEntityBase(pEntity);
  594. }
  595. ErrorCodeEnum ModuleBase::GetRegistEntity(const char *pszEntityName,CSmartPointer<CEntityBase> &pEntity)
  596. {
  597. SpModule *pModule = GetSpModule();
  598. return pModule->GetEntityBase(pszEntityName, pEntity);
  599. }
  600. #ifndef _WIN32
  601. ModuleBase* ModuleBase::s_pModuleInst = NULL;
  602. #endif //NOT _WIN32
  603. ModuleBase* ModuleBase::GetModuleBase()
  604. {
  605. #ifdef _WIN32
  606. return (ModuleBase*)(getEntityResource()->m_moduleBase);
  607. #else
  608. return ModuleBase::s_pModuleInst;
  609. #endif //_WIN32
  610. }
  611. ModuleBase::ModuleBase()
  612. :m_hInstance(NULL), m_nEntityCount(0)
  613. {
  614. #ifdef _WIN32
  615. getEntityResource()->m_moduleBase = this;
  616. #else
  617. ModuleBase::s_pModuleInst = this;
  618. #endif //_WIN32
  619. }
  620. CClientSessionBase::~CClientSessionBase()
  621. {
  622. if (m_pSessionFunction) {
  623. SpClientSessionFunction *pFunction = dynamic_cast<SpClientSessionFunction *>(m_pSessionFunction);
  624. m_pSessionFunction = NULL;
  625. pFunction->DecrementRef();
  626. }
  627. }