CommEntityUtil.hpp 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. #ifndef RVC_MOD_COMM_ENTITY_UTIL_HPP_
  2. #define RVC_MOD_COMM_ENTITY_UTIL_HPP_
  3. #if defined(_MSC_VER)
  4. #include <Windows.h>
  5. #include <TlHelp32.h>
  6. #include <iphlpapi.h>
  7. #include <ws2tcpip.h>
  8. #include <Winsock2.h>
  9. #include <IPTypes.h>
  10. #include <WinInet.h>
  11. #include <ShlObj.h>
  12. #include <Pdh.h>
  13. #pragma comment(lib, "IPHLPAPI.lib")
  14. #pragma comment(lib, "Wininet.lib")
  15. #pragma comment(lib, "pdh.lib")
  16. #define streq stricmp
  17. #else
  18. #include <net/if.h>
  19. #include <sys/ioctl.h>
  20. #include <unistd.h>
  21. #include <thread>
  22. #include <chrono>
  23. #define streq strcasecmp
  24. #endif //_MSC_VER
  25. #include "path.h"
  26. #include "toolkit.h"
  27. #include <string>
  28. #include <iostream>
  29. #include <sstream>
  30. #include <map>
  31. #include "SpBase.h"
  32. #include "publicFunExport.h"
  33. #define MACSESION 6
  34. #define DIV (1024 * 1024)
  35. #define DAY_DIV (24 * 60 * 60)
  36. #define HOURS_DIV (60 * 60)
  37. #define MINUS_DIV (60)
  38. typedef unsigned long long ULLINT;
  39. typedef CAutoArray<CSimpleStringA> NetworkAddressesList;
  40. #define SLEEP(interval) std::this_thread::sleep_for(std::chrono::milliseconds(interval))
  41. namespace SP
  42. {
  43. namespace Module
  44. {
  45. namespace System
  46. {
  47. static BOOL GetSystemBootTime(CSmallDateTime& systemBootTime)
  48. {
  49. #if defined(_MSC_VER)
  50. PDH_STATUS Status;
  51. HQUERY Query = NULL;
  52. HCOUNTER hcElapsedTimeCount;
  53. BOOL fSuc = FALSE;
  54. Status = PdhOpenQuery(NULL, NULL, &Query);
  55. PDH_FMT_COUNTERVALUE counterValue;
  56. if (Status != ERROR_SUCCESS) {
  57. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("PdhOpenQuery failed with status 0x%x.", Status);
  58. goto Cleanup;
  59. }
  60. Status = PdhAddCounter(Query, "\\System\\System Up Time", NULL, &hcElapsedTimeCount);
  61. if (Status != ERROR_SUCCESS) {
  62. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("PdhAddCounter for SystemElapsedQuery failed with status 0x%x.", Status);
  63. goto Cleanup;
  64. }
  65. // 查询性能监视器数据
  66. Status = PdhCollectQueryData(Query);
  67. if (Status != ERROR_SUCCESS) {
  68. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("PdhCollectQueryData failed with 0x%x.", Status);
  69. goto Cleanup;
  70. }
  71. Status = PdhGetFormattedCounterValue(hcElapsedTimeCount, PDH_FMT_LARGE, NULL, &counterValue);
  72. if (Status == ERROR_SUCCESS) {
  73. ULONGLONG ulSinceSeconds = counterValue.largeValue;
  74. ULONG days = 0, hours = 0, minutes = 0, seconds = 0;
  75. days = ULONG(ulSinceSeconds / DAY_DIV);
  76. ulSinceSeconds %= DAY_DIV;
  77. hours = ULONG(ulSinceSeconds / HOURS_DIV);
  78. ulSinceSeconds %= HOURS_DIV;
  79. minutes = ULONG(ulSinceSeconds / MINUS_DIV);
  80. ulSinceSeconds %= MINUS_DIV;
  81. seconds = ULONG(ulSinceSeconds);
  82. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SystemElapseTime: %u:%02u:%02u:%02u", days, hours, minutes, seconds);
  83. FILETIME ftCurTime, ftStartTime;
  84. GetSystemTimeAsFileTime(&ftCurTime);
  85. ULARGE_INTEGER uliCurTime;
  86. uliCurTime.HighPart = ftCurTime.dwHighDateTime;
  87. uliCurTime.LowPart = ftCurTime.dwLowDateTime;
  88. uliCurTime.QuadPart -= counterValue.largeValue * 1e7;
  89. ftStartTime.dwHighDateTime = uliCurTime.HighPart;
  90. ftStartTime.dwLowDateTime = uliCurTime.LowPart;
  91. SYSTEMTIME stUTC, stLocal;
  92. FileTimeToSystemTime(&ftStartTime, &stUTC);
  93. char temp[22];
  94. SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
  95. sprintf_s(temp, 22, "%d-%02d-%02d %02d:%02d:%02d",
  96. stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond);
  97. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OSStartTime: %s", temp);
  98. systemBootTime.FromSystemTime(stLocal);
  99. fSuc = TRUE;
  100. }
  101. Cleanup:
  102. Status = PdhRemoveCounter(hcElapsedTimeCount);
  103. if (Query) {
  104. PdhCloseQuery(Query);
  105. }
  106. return fSuc;
  107. #else
  108. ///*TODO(80374374@3/7/2023): */
  109. return FALSE;
  110. #endif //_MSC_VER
  111. }
  112. }//system
  113. namespace Comm
  114. {
  115. /** Rely on ${OTHER_LIB_BASE_DIR}/libpublicFun and library target libpublicFun*/
  116. struct LogNotiyMessageStruct
  117. {
  118. std::string Reason;
  119. std::string ErrMsg;
  120. std::string RebootTime;
  121. LogNotiyMessageStruct(const CSimpleStringA& reason, const CSimpleStringA& errmsg, const CSimpleStringA& rebootTime)
  122. :Reason(reason.GetData()), ErrMsg(reason.GetData()), RebootTime(reason.GetData())
  123. {
  124. }
  125. LogNotiyMessageStruct(const std::string& reason, const std::string& errmsg, const std::string& rebootTime)
  126. :Reason(reason), ErrMsg(errmsg), RebootTime(rebootTime)
  127. {
  128. }
  129. LogNotiyMessageStruct(const char* reason, const char* errmsg, char* rebootTime)
  130. :Reason(reason), ErrMsg(errmsg), RebootTime(rebootTime)
  131. {
  132. }
  133. LogNotiyMessageStruct(const char* errmsg)
  134. :Reason(""), ErrMsg(errmsg), RebootTime("")
  135. {
  136. }
  137. std::string ToJsonString() const {
  138. std::map<std::string, std::string> srcData;
  139. srcData.insert(std::make_pair("reason", Reason));
  140. srcData.insert(std::make_pair("errmsg", ErrMsg));
  141. srcData.insert(std::make_pair("rebootTime", RebootTime));
  142. auto ret = generateJsonStr(srcData);
  143. if (ret.first) {
  144. return ret.second;
  145. } else {
  146. return ErrMsg;
  147. }
  148. }
  149. };
  150. struct LogCommNotiyStruct
  151. {
  152. NotifyLevelEnum eLevel;
  153. ErrorCodeEnum eSysCode;
  154. DWORD dwUserCode;
  155. LogCommNotiyStruct() :eLevel(Notify_None), eSysCode(Error_Unexpect), dwUserCode(0) {}
  156. LogCommNotiyStruct(NotifyLevelEnum level, ErrorCodeEnum errorCode, DWORD dwUserCode)
  157. :eLevel(level), eSysCode(errorCode), dwUserCode(dwUserCode) {}
  158. LogCommNotiyStruct(NotifyLevelEnum level, ErrorCodeEnum errorCode)
  159. :eLevel(level), eSysCode(errorCode), dwUserCode(0)
  160. { }
  161. virtual ~LogCommNotiyStruct() {}
  162. virtual void Notify(const LogNotiyMessageStruct& notifyMessage)
  163. {
  164. LogNotify(eLevel, eSysCode, dwUserCode, notifyMessage.ToJsonString().c_str());
  165. }
  166. };
  167. struct LogInfoNotiyStruct : public LogCommNotiyStruct
  168. {
  169. LogInfoNotiyStruct(ErrorCodeEnum errorCode, DWORD dwUserCode)
  170. :LogCommNotiyStruct(Notify_Info, errorCode, dwUserCode){}
  171. ~LogInfoNotiyStruct() {}
  172. };
  173. struct LogWarnNotiyStruct : public LogCommNotiyStruct
  174. {
  175. LogWarnNotiyStruct(ErrorCodeEnum errorCode, DWORD dwUserCode)
  176. :LogCommNotiyStruct(Notify_Warn, errorCode, dwUserCode)
  177. {
  178. }
  179. ~LogWarnNotiyStruct() {}
  180. };
  181. struct LogErrorNotiyStruct : public LogCommNotiyStruct
  182. {
  183. LogErrorNotiyStruct(ErrorCodeEnum errorCode, DWORD dwUserCode)
  184. :LogCommNotiyStruct(Notify_Error, errorCode, dwUserCode)
  185. {
  186. }
  187. ~LogErrorNotiyStruct() {}
  188. };
  189. static BOOL IsFirsRunAppAfterSystemBoot(CEntityBase* pEntity)
  190. {
  191. BOOL result(FALSE);
  192. CSystemRunInfo runInfo = { 0 };
  193. ErrorCodeEnum ec = pEntity->GetFunction()->GetSystemRunInfo(runInfo);
  194. if (ec == Error_Succeed) {
  195. CBootInfo bootInfo = { 0 };
  196. CSmallDateTime dateTime;
  197. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("systemRunInfo time: %s", (LPCTSTR)runInfo.tmStart.ToTimeString());
  198. ec = pEntity->GetFunction()->GetRebootInfo(/*runInfo.tmStart*/dateTime, bootInfo);
  199. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("bootInfor time: %s", (LPCTSTR)bootInfo.tmStart.ToTimeString());
  200. CSmallDateTime systemBootTime;
  201. const BOOL bRet = System::GetSystemBootTime(systemBootTime);
  202. if (bRet && systemBootTime > bootInfo.tmStart) {
  203. result = TRUE;
  204. }
  205. }
  206. return result;
  207. }
  208. inline
  209. CSimpleStringA GetCurrMachineType(CEntityBase* pEntity)
  210. {
  211. CSystemStaticInfo sysInfo;
  212. pEntity->GetFunction()->GetSystemStaticInfo(sysInfo);
  213. return sysInfo.strMachineType;
  214. }
  215. inline
  216. CSimpleStringA GetCurrEntityConfigPath(CEntityBase* pEntity)
  217. {
  218. CSimpleStringA strConfigDir(true);
  219. pEntity->GetFunction()->GetPath("cfg", strConfigDir);
  220. CSimpleStringA result(strConfigDir + SPLIT_SLASH_STR + pEntity->GetEntityName() + ".ini");
  221. Dbg("config path: %s", result.GetData());
  222. return result;
  223. }
  224. enum Site
  225. {
  226. CMB_UNKNOWN,
  227. CMB_LIB, /** 行内大堂*/
  228. CMB_FLB, /** 离行机器*/
  229. };
  230. #define SITE_ENUM_TYPE(MACRO) \
  231. MACRO(LIB)\
  232. MACRO(FLB)
  233. #define ENUM_MAP_CONVERT(elem) \
  234. if (streq(lpcszSiteName, "CMB."#elem) == 0) return CMB_##elem;
  235. /*!
  236. * convert cmb site name to enum type.
  237. */
  238. static Site Str2Site(LPCSTR lpcszSiteName)
  239. {
  240. if (lpcszSiteName == NULL || strlen(lpcszSiteName) == 0)
  241. return CMB_UNKNOWN;
  242. SITE_ENUM_TYPE(ENUM_MAP_CONVERT)
  243. return CMB_UNKNOWN;
  244. }
  245. #undef ENUM_MAP_CONVERT
  246. #define ENUM_MAP_CONVERT(elem) case CMB_##elem: return "CMB."#elem;
  247. static LPCSTR Site2Str(Site site)
  248. {
  249. switch (site) {
  250. SITE_ENUM_TYPE(ENUM_MAP_CONVERT)
  251. default:
  252. break;
  253. }
  254. return "Unkown";
  255. }
  256. enum What
  257. {
  258. RVC_UNKNOWN,
  259. RVC_Stand2S, /** 落地式大机*/
  260. RVC_PAD, /** PAD*/
  261. RVC_Desk2S, /** 低柜双屏*/
  262. RVC_IL, /** 简版*/
  263. RVC_Desk1S, /** 低柜一体机*/
  264. RVC_CardStore, /** 卡库*/
  265. RPM_Stand1S, /** 扩展柜*/
  266. RVC_CardPrinter /** 制卡机*/
  267. };
  268. #define MACHINE_ENUM_TYPE(MACRO) \
  269. MACRO(Stand2S)\
  270. MACRO(PAD)\
  271. MACRO(Desk2S)\
  272. MACRO(IL)\
  273. MACRO(Desk1S)\
  274. MACRO(CardStore)
  275. #undef ENUM_MAP_CONVERT
  276. #define ENUM_MAP_CONVERT(elem) \
  277. if (streq(lpcszTypeName, "RVC."#elem) == 0) return RVC_##elem;
  278. /*!
  279. * convert cmb site name to enum type.
  280. */
  281. static What Str2Type(LPCSTR lpcszTypeName)
  282. {
  283. if (lpcszTypeName == NULL || strlen(lpcszTypeName) == 0)
  284. return RVC_UNKNOWN;
  285. MACHINE_ENUM_TYPE(ENUM_MAP_CONVERT)
  286. if (streq(lpcszTypeName, "RPM.Stand1S") == 0)
  287. return RPM_Stand1S;
  288. return RVC_UNKNOWN;
  289. }
  290. #undef ENUM_MAP_CONVERT
  291. #define ENUM_MAP_CONVERT(elem) case RVC_##elem: return "RVC."#elem;
  292. static LPCSTR Type2Str(What what)
  293. {
  294. switch (what) {
  295. MACHINE_ENUM_TYPE(ENUM_MAP_CONVERT)
  296. default:
  297. break;
  298. }
  299. if (what == RPM_Stand1S)
  300. return "RPM.Stand1S";
  301. return "Unkown";
  302. }
  303. struct TerminalMachineInfo
  304. {
  305. Site site;
  306. What type;
  307. struct {
  308. WORD minor;
  309. WORD major;
  310. } gen;
  311. };
  312. inline
  313. TerminalMachineInfo GetTerminalMachineInfo(CEntityBase* pEntity)
  314. {
  315. CSystemStaticInfo sysInfo;
  316. TerminalMachineInfo termInfo;
  317. pEntity->GetFunction()->GetSystemStaticInfo(sysInfo);
  318. termInfo.site = Str2Site(sysInfo.strSite);
  319. termInfo.type = Str2Type(sysInfo.strMachineType);
  320. termInfo.gen.major = sysInfo.MachineVersion.GetMajor();
  321. termInfo.gen.minor = sysInfo.MachineVersion.GetMinor();
  322. return termInfo;
  323. }
  324. inline ULLINT RVCGetTickCount()
  325. {
  326. #ifdef RVC_OS_WIN
  327. return GetTickCount64();
  328. #else
  329. struct timespec ts;
  330. clock_gettime(CLOCK_MONOTONIC, &ts);
  331. return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
  332. #endif // RVC_OS_WIN
  333. }
  334. } // comm
  335. namespace Util
  336. {
  337. static int StrBuf2HexBuf(char* strBuf, PBYTE* hexBuf)
  338. {
  339. int len = strlen(strBuf);
  340. if (len == 0 || len % 2 != 0)
  341. return 0;
  342. BYTE* buf = new BYTE[len / 2];
  343. if (buf == NULL)
  344. return 0;
  345. int j = 0;
  346. for (int i = 0; i < len;) {
  347. int tmpVal;
  348. sscanf(strBuf + i, "%2X", &tmpVal);
  349. buf[j] = tmpVal;
  350. i += 2;
  351. j++;
  352. }
  353. *hexBuf = buf;
  354. return j;
  355. }
  356. static int HexBuf2StrBuf(PBYTE hexBuf, char** strBuf, DWORD len)
  357. {
  358. char* tmpStr = *strBuf;
  359. DWORD count = 0;
  360. for (DWORD i = 0; i < len; ++i) {
  361. sprintf(tmpStr + count, "%0.2X", hexBuf[i]);
  362. count += 2;
  363. }
  364. return 0;
  365. }
  366. static DWORD GetDuration(const SYSTEMTIME& time1, const SYSTEMTIME& time2)
  367. {
  368. #if defined(RVC_OS_WIN)
  369. ULARGE_INTEGER fTime1;/*FILETIME*/
  370. ULARGE_INTEGER fTime2;/*FILETIME*/
  371. SystemTimeToFileTime(&time1, (FILETIME*)&fTime1);
  372. SystemTimeToFileTime(&time2, (FILETIME*)&fTime2);
  373. unsigned __int64 dft = fTime2.QuadPart - fTime1.QuadPart;
  374. return DWORD(dft / 10000);
  375. #else
  376. ///**TODO(Gifur@9/3/2021): Bug 不能这样简单的实现,考虑凌晨,切换月份甚至是年份 */
  377. DWORD s1, s2;
  378. s1 = (time1.wMinute * 60 + time1.wSecond) * 1000 + time1.wMilliseconds;
  379. s2 = (time2.wMinute * 60 + time2.wSecond) * 1000 + time2.wMilliseconds;
  380. return s2 - s1;
  381. #endif //RVC_OS_WIN
  382. }
  383. static std::string formatTime(const SYSTEMTIME& time)
  384. {
  385. char tBuf[1024] = "";
  386. sprintf(tBuf, "%04u-%02u-%02u %02u:%02u:%02u:%03u", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
  387. return tBuf;
  388. }
  389. static bool ShellExecute(const std::string& cmd, std::string& succResult, std::string& errResult)
  390. {
  391. #if defined(_MSC_VER)
  392. ///*TODO(80374374@3/7/2023): */
  393. return false;
  394. #else
  395. char buf_ps[1024];
  396. char ps[1024] = { 0 };
  397. char result[2049] = { 0 };
  398. FILE* ptr;
  399. strcpy(ps, cmd.c_str());
  400. succResult = errResult = "";
  401. if ((ptr = popen(ps, "r")) != NULL) {
  402. while (fgets(buf_ps, 1024, ptr) != NULL) {
  403. if (strlen(result) + strlen(buf_ps) > 2048)
  404. break;
  405. strcat(result, buf_ps);
  406. }
  407. pclose(ptr);
  408. const int len = strlen(result);
  409. for (int i = len - 1; i >= 0 && (result[i] == '\r' || result[i] == '\n'); --i) {
  410. result[i] = '\0';
  411. }
  412. succResult = result;
  413. return true;
  414. } else {
  415. sprintf(result, "popen %s error: %d", ps, errno);
  416. errResult = result;
  417. return false;
  418. }
  419. #endif //_MSC_VER
  420. }
  421. static CSimpleString generateConsumeTimeJson(CSimpleString entityName, CSimpleString startTime, int cost)
  422. {
  423. return CSimpleString::Format("[{\"name\":\"%s\",\"time\":\"%s\",\"cost\":%d}]", entityName.GetData(), startTime.GetData(), cost);
  424. }
  425. #if defined(_MSC_VER)
  426. static char* ConvertUtf8ToGBK(const char* strUtf8)
  427. {
  428. int len = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0);
  429. WCHAR* wszGBK = new WCHAR[len + 1];
  430. memset(wszGBK, 0, len * 2 + 2);
  431. MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, wszGBK, len);
  432. len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
  433. char* szGBK = new char[len + 1];
  434. memset(szGBK, 0, len + 1);
  435. WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
  436. delete[] wszGBK;
  437. return szGBK;
  438. }
  439. static void ConvertUtf8ToGBK(std::string& str)
  440. {
  441. char* dst = ConvertUtf8ToGBK(str.c_str());
  442. str = dst;
  443. delete[] dst;
  444. }
  445. static char* ConvertGBKToUtf8(const char* gbk, int* n)
  446. {
  447. int len = MultiByteToWideChar(CP_ACP, 0, gbk, -1, NULL, 0);
  448. WCHAR* wszGBK = new WCHAR[len + 1];
  449. memset(wszGBK, 0, len * 2 + 2);
  450. MultiByteToWideChar(CP_ACP, 0, gbk, -1, wszGBK, len);
  451. len = WideCharToMultiByte(CP_UTF8, 0, wszGBK, -1, NULL, 0, NULL, NULL);
  452. char* szUtf8 = new char[len + 1];
  453. memset(szUtf8, 0, len + 1);
  454. WideCharToMultiByte(CP_UTF8, 0, wszGBK, -1, szUtf8, len, NULL, NULL);
  455. delete[] wszGBK;
  456. *n = len - 1;
  457. return szUtf8;
  458. }
  459. static void ConvertGBKToUtf8(std::string& str)
  460. {
  461. int len = 0;
  462. char* dst = ConvertGBKToUtf8(str.c_str(), &len);
  463. str = dst;
  464. delete[] dst;
  465. }
  466. #endif //_MSC_VER
  467. static std::string W2S(const std::wstring wstr)
  468. {
  469. #if defined(_MSC_VER)
  470. char* str = NULL;
  471. int n = ::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
  472. if (n > 0) {
  473. str = new char[n + 1];
  474. if (str == NULL) {
  475. return std::string();
  476. }
  477. std::memset(str, 0, sizeof(char) * (n + 1));
  478. ::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], n, NULL, NULL);
  479. std::string strr(str);
  480. delete str;
  481. return strr;
  482. }
  483. #else
  484. ///*TODO(80374374@3/7/2023): */
  485. #endif //_MSC_VER
  486. return std::string();
  487. }
  488. static std::wstring S2W(const std::string str)
  489. {
  490. #if defined(_MSC_VER)
  491. wchar_t* wstr = NULL;
  492. int n = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
  493. if (n > 0) {
  494. wstr = new wchar_t[n + 1];
  495. if (wstr == NULL) {
  496. return std::wstring();
  497. }
  498. std::memset(wstr, 0, (n + 1) * sizeof(wchar_t));
  499. ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &wstr[0], n);
  500. std::wstring strr(wstr);
  501. delete wstr;
  502. return strr;
  503. }
  504. #else
  505. ///*TODO(80374374@3/7/2023): */
  506. #endif //_MSC_VER
  507. return std::wstring();
  508. }
  509. } //namespace Util
  510. namespace Net{
  511. struct NetworkAdapterItem
  512. {
  513. int idx;
  514. std::string friend_name;
  515. std::string adapter_name;
  516. std::string description;
  517. std::string ip;
  518. std::string mask;
  519. std::string mac;
  520. std::string gateway;
  521. std::string dhcp;
  522. bool is_physical;
  523. DWORD type;
  524. int operStatus;
  525. bool isLocal;
  526. NetworkAdapterItem() :idx(0), friend_name(""), adapter_name(""), description(""), ip(""), mask(""),
  527. mac(""), gateway(""), dhcp(""), is_physical(true), type(0), operStatus(0), isLocal(false)
  528. {
  529. }
  530. };
  531. static bool IsLocalAdapter(const std::string& name)
  532. {
  533. #if defined(_MSC_VER)
  534. if (name.length() <= 0) {
  535. return false;
  536. }
  537. std::string key("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
  538. HKEY h_sub_key = NULL;
  539. LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_READ, &h_sub_key);
  540. if (ret != 0) {
  541. return false;
  542. }
  543. std::ostringstream str;
  544. str << name << "\\Connection";
  545. HKEY h_local_key = NULL;
  546. ret = RegOpenKeyEx(h_sub_key, str.str().c_str(), 0, KEY_READ, &h_local_key);
  547. if (0 != ret) {
  548. RegCloseKey(h_sub_key);
  549. return false;
  550. }
  551. DWORD type = REG_SZ;
  552. TCHAR buf[250];
  553. DWORD buf_size = 250;
  554. ret = RegQueryValueEx(h_local_key, "PnPInstanceId", 0, &type, (BYTE*)(buf), &buf_size);
  555. RegCloseKey(h_sub_key);
  556. RegCloseKey(h_local_key);
  557. if (0 != ret) {
  558. return false;
  559. }
  560. if (0 == strnicmp(buf, "PCI", strlen("PCI")) || 0 == strnicmp(buf, "USB", strlen("USB"))) {
  561. return true;
  562. }
  563. return false;
  564. #else
  565. ///*TODO(80374374@3/7/2023): */
  566. return true;
  567. #endif //_MSC_VER
  568. }
  569. static ErrorCodeEnum GetINETMacAddresses(NetworkAddressesList& macList, NetworkAddressesList& ipList)
  570. {
  571. #if defined(RVC_OS_WIN)
  572. PIP_ADAPTER_ADDRESSES pAddresses = NULL;
  573. ULONG family = AF_INET;
  574. ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
  575. ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
  576. // Make an initial call to GetAdaptersAddresses to get the
  577. // size needed into the outBufLen variable
  578. if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
  579. pAddresses = static_cast<PIP_ADAPTER_ADDRESSES>(HeapAlloc(GetProcessHeap(), 0, outBufLen));
  580. }
  581. if (NULL == pAddresses) {
  582. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("pAddresses = NULL");
  583. return Error_Unexpect;
  584. }
  585. DWORD dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
  586. /* MACAddresses vAddress;*/
  587. if (dwRetVal != ERROR_SUCCESS) {
  588. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("dwRetVal = %d", dwRetVal);
  589. return Error_Unexpect;
  590. }
  591. PIP_ADAPTER_ADDRESSES pFirst = pAddresses;
  592. while (pAddresses) {
  593. if (pAddresses->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET &&
  594. pAddresses->OperStatus == IfOperStatusUp &&
  595. pAddresses->IfType != IF_TYPE_SOFTWARE_LOOPBACK) {
  596. BYTE* pa = pAddresses->PhysicalAddress;
  597. if (!pa) {
  598. pAddresses = pAddresses->Next ? pAddresses->Next : NULL;
  599. continue;
  600. }
  601. CSimpleStringA strFriendlyName(true);
  602. CSimpleStringA strDescription(true);
  603. DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, pAddresses->FriendlyName, -1, NULL, 0, NULL, FALSE);
  604. char* psText = new char[dwNum];
  605. if (psText != NULL) {
  606. WideCharToMultiByte(CP_OEMCP, NULL, pAddresses->FriendlyName, -1, psText, dwNum, NULL, FALSE);
  607. strFriendlyName = psText;
  608. delete[] psText;
  609. }
  610. dwNum = WideCharToMultiByte(CP_OEMCP, NULL, pAddresses->Description, -1, NULL, 0, NULL, FALSE);
  611. psText = new char[dwNum];
  612. if (psText != NULL) {
  613. WideCharToMultiByte(CP_OEMCP, NULL, pAddresses->Description, -1, psText, dwNum, NULL, FALSE);
  614. strDescription = psText;
  615. delete[] psText;
  616. }
  617. char bAddressBytes[MACSESION];
  618. int bAddressInt[MACSESION];
  619. memset(bAddressBytes, 0, MACSESION);
  620. size_t nAddressSize = pAddresses->PhysicalAddressLength;
  621. memcpy(bAddressBytes, pa, (nAddressSize < MACSESION ? nAddressSize : MACSESION));
  622. for (int i = 0; i < MACSESION; ++i) {
  623. bAddressInt[i] = bAddressBytes[i];
  624. bAddressInt[i] &= 0x000000ff; // avoid "ff" leading bytes when "char" is lager then 0x7f
  625. }
  626. CSimpleStringA tmpmac = CSimpleStringA::Format("%02x:%02x:%02x:%02x:%02x:%02x",
  627. bAddressInt[0],
  628. bAddressInt[1],
  629. bAddressInt[2],
  630. bAddressInt[3],
  631. bAddressInt[4],
  632. bAddressInt[5]);
  633. macList.Append(&tmpmac, 0, 1);
  634. sockaddr_in* sa_in = (sockaddr_in*)pAddresses->FirstUnicastAddress->Address.lpSockaddr;
  635. char buf_addr[100] = { 0 };
  636. CSimpleStringA tmpip = CSimpleStringA(inet_ntop(AF_INET, &(sa_in->sin_addr), buf_addr, 100));
  637. ipList.Append(&tmpip, 0, 1);
  638. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s, %s: OperStatus: %d, IfType = %d, ip=%s, mac=%s"
  639. , strFriendlyName.GetData(), strDescription.GetData()
  640. , pAddresses->OperStatus, pAddresses->IfType, tmpip.GetData(), tmpmac.GetData());
  641. }
  642. pAddresses = pAddresses->Next ? pAddresses->Next : NULL;
  643. }
  644. HeapFree(GetProcessHeap(), 0, pFirst);
  645. return Error_Succeed;
  646. #else
  647. std::map<std::string, std::string> inteIPs;
  648. std::map<std::string, std::string> inteMacs;
  649. char buf[512];
  650. toolkit_interface_address_t* info;
  651. int count, i;
  652. toolkit_interface_addresses(&info, &count);
  653. i = count;
  654. Dbg("Number of interfaces: %d", count);
  655. while (i--) {
  656. toolkit_interface_address_t interface = info[i];
  657. Dbg("Name: %s", interface.name);
  658. Dbg("Internal? %s", interface.is_internal ? "Yes" : "No");
  659. if (interface.address.address4.sin_family == AF_INET) {
  660. toolkit_ip4_name(&interface.address.address4, buf, sizeof(buf));
  661. Dbg("IPv4 address: %s", buf);
  662. inteIPs[interface.name] = buf;
  663. } else if (interface.address.address4.sin_family == AF_INET6) {
  664. toolkit_ip6_name(&interface.address.address6, buf, sizeof(buf));
  665. Dbg("IPv6 address: %s", buf);
  666. //inteIPs[interface.name] = buf;
  667. }
  668. }
  669. toolkit_free_interface_addresses(info, count);
  670. {
  671. int fd, interface;
  672. struct ifreq buf[16];
  673. struct ifconf ifc;
  674. char mac[32] = { 0 };
  675. if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
  676. int i = 0;
  677. ifc.ifc_len = sizeof(buf);
  678. ifc.ifc_buf = (caddr_t)buf;
  679. if (!ioctl(fd, SIOCGIFCONF, (char*)&ifc)) {
  680. interface = ifc.ifc_len / sizeof(struct ifreq);
  681. Dbg("interface num is %d", interface);
  682. while (i < interface) {
  683. Dbg("Name: %s", buf[i].ifr_name);
  684. if (!(ioctl(fd, SIOCGIFHWADDR, (char*)&buf[i]))) {
  685. sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",
  686. (unsigned char)buf[i].ifr_hwaddr.sa_data[0],
  687. (unsigned char)buf[i].ifr_hwaddr.sa_data[1],
  688. (unsigned char)buf[i].ifr_hwaddr.sa_data[2],
  689. (unsigned char)buf[i].ifr_hwaddr.sa_data[3],
  690. (unsigned char)buf[i].ifr_hwaddr.sa_data[4],
  691. (unsigned char)buf[i].ifr_hwaddr.sa_data[5]);
  692. Dbg("HWaddr %s", mac);
  693. inteMacs[buf[i].ifr_name] = mac;
  694. }
  695. i++;
  696. }
  697. }
  698. close(fd);
  699. }
  700. }
  701. std::map<std::string, std::string>::const_iterator map_it = inteIPs.begin();
  702. while (map_it != inteIPs.end()) {
  703. CSimpleStringA tmpip(map_it->second.c_str());
  704. CSimpleStringA tmpmac(true);
  705. auto it = inteMacs.find(std::string(map_it->first));
  706. if (it != inteMacs.end()) {
  707. tmpmac = it->second.c_str();
  708. }
  709. if (tmpip.Compare("127.0.0.1") == 0 && tmpmac.Compare("00:00:00:00:00:00") == 0) {
  710. //skip
  711. } else {
  712. ipList.Append(&tmpip, 0, 1);
  713. macList.Append(&tmpmac, 0, 1);
  714. }
  715. ++map_it;
  716. }
  717. return Error_Succeed;
  718. #endif //RVC_OS_WIN
  719. }
  720. static std::vector<NetworkAdapterItem> GetNetAdapterItems()
  721. {
  722. std::vector<NetworkAdapterItem> results;
  723. #if defined(_MSC_VER)
  724. ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS;
  725. ULONG family = AF_UNSPEC;
  726. PIP_ADAPTER_ADDRESSES address_ptr = nullptr;
  727. ULONG out_buf_len = 15000;
  728. DWORD ret_val = 0;
  729. PIP_ADAPTER_ADDRESSES cur_addr_ptr = nullptr;
  730. PIP_ADAPTER_UNICAST_ADDRESS unicast_ptr = nullptr;
  731. PIP_ADAPTER_ANYCAST_ADDRESS anycast_ptr = nullptr;
  732. PIP_ADAPTER_MULTICAST_ADDRESS multicast_ptr = nullptr;
  733. PIP_ADAPTER_DNS_SERVER_ADDRESS dns_server_ptr = nullptr;
  734. IP_ADAPTER_PREFIX* prefix_ptr = nullptr;
  735. do {
  736. address_ptr = (PIP_ADAPTER_ADDRESSES)malloc(out_buf_len);
  737. if (address_ptr == nullptr) {
  738. return results;
  739. }
  740. ret_val = GetAdaptersAddresses(family, flags, NULL, address_ptr, &out_buf_len);
  741. if (ERROR_BUFFER_OVERFLOW == ret_val) {
  742. free(address_ptr);
  743. }
  744. } while (ret_val == ERROR_BUFFER_OVERFLOW);
  745. if (NO_ERROR == ret_val) {
  746. cur_addr_ptr = address_ptr;
  747. while (cur_addr_ptr) {
  748. std::string description = Util::W2S(cur_addr_ptr->Description);
  749. bool is_local = IsLocalAdapter(cur_addr_ptr->AdapterName);
  750. std::string friend_name = Util::W2S(cur_addr_ptr->FriendlyName);
  751. NetworkAdapterItem item;
  752. item.idx = cur_addr_ptr->IfIndex;
  753. item.adapter_name = cur_addr_ptr->AdapterName;
  754. item.description = description;
  755. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(">>>>>>>>>>>>>>> friendly name: %s", friend_name.c_str());
  756. item.friend_name = friend_name;
  757. if (is_local) {
  758. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Adapter Desc: %s", description.c_str());
  759. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Adapter Name: %s", cur_addr_ptr->AdapterName);
  760. item.isLocal = true;
  761. }
  762. if (cur_addr_ptr->PhysicalAddressLength != 0) {
  763. char sz_addr[32] = { 0 };
  764. std::stringstream str;
  765. for (int i = 0; i < (int)cur_addr_ptr->PhysicalAddressLength; i++) {
  766. if (i == ((int)cur_addr_ptr->PhysicalAddressLength - 1))
  767. sprintf_s(sz_addr, "%.2X", (int)cur_addr_ptr->PhysicalAddress[i]);
  768. else
  769. sprintf_s(sz_addr, "%.2X:", (int)cur_addr_ptr->PhysicalAddress[i]);
  770. str << sz_addr;
  771. }
  772. item.mac = str.str();
  773. }
  774. item.type = cur_addr_ptr->IfType;
  775. item.operStatus = cur_addr_ptr->OperStatus;
  776. switch (cur_addr_ptr->IfType) {
  777. case MIB_IF_TYPE_OTHER:
  778. break;
  779. case MIB_IF_TYPE_ETHERNET:
  780. break;
  781. case MIB_IF_TYPE_TOKENRING:
  782. break;
  783. case MIB_IF_TYPE_FDDI:
  784. break;
  785. case MIB_IF_TYPE_PPP:
  786. break;
  787. case MIB_IF_TYPE_LOOPBACK:
  788. break;
  789. case MIB_IF_TYPE_SLIP:
  790. break;
  791. case IF_TYPE_IEEE80211:
  792. break;
  793. case IF_TYPE_WWANPP:
  794. case IF_TYPE_WWANPP2:
  795. //WWAN devices
  796. break;
  797. default:
  798. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Unknown type %d", cur_addr_ptr->IfType);
  799. break;
  800. }
  801. unicast_ptr = cur_addr_ptr->FirstUnicastAddress;
  802. while (unicast_ptr) {
  803. char ip[120] = { 0 };
  804. if (AF_INET == unicast_ptr->Address.lpSockaddr->sa_family) {
  805. inet_ntop(PF_INET, &((sockaddr_in*)unicast_ptr->Address.lpSockaddr)->sin_addr, ip, sizeof(ip));
  806. } else if (AF_INET6 == unicast_ptr->Address.lpSockaddr->sa_family) {
  807. inet_ntop(PF_INET6, &((sockaddr_in*)unicast_ptr->Address.lpSockaddr)->sin_addr, ip, sizeof(ip));
  808. }
  809. unicast_ptr = unicast_ptr->Next;
  810. }
  811. if (cur_addr_ptr->Dhcpv4Server.lpSockaddr) {
  812. char ip[120] = { 0 };
  813. if (AF_INET == cur_addr_ptr->Dhcpv4Server.lpSockaddr->sa_family) {
  814. inet_ntop(PF_INET, &((sockaddr_in*)cur_addr_ptr->Dhcpv4Server.lpSockaddr)->sin_addr, ip, sizeof(ip));
  815. } else if (AF_INET6 == cur_addr_ptr->Dhcpv4Server.lpSockaddr->sa_family) {
  816. inet_ntop(PF_INET6, &((sockaddr_in*)cur_addr_ptr->Dhcpv4Server.lpSockaddr)->sin_addr, ip, sizeof(ip));
  817. }
  818. item.dhcp = ip;
  819. }
  820. dns_server_ptr = cur_addr_ptr->FirstDnsServerAddress;
  821. while (dns_server_ptr) {
  822. char ip[120] = { 0 };
  823. if (AF_INET == dns_server_ptr->Address.lpSockaddr->sa_family) {
  824. inet_ntop(PF_INET, &((sockaddr_in*)dns_server_ptr->Address.lpSockaddr)->sin_addr, ip, sizeof(ip));
  825. } else if (AF_INET6 == dns_server_ptr->Address.lpSockaddr->sa_family) {
  826. inet_ntop(PF_INET6, &((sockaddr_in*)dns_server_ptr->Address.lpSockaddr)->sin_addr, ip, sizeof(ip));
  827. }
  828. dns_server_ptr = dns_server_ptr->Next;
  829. }
  830. auto gateway_ptr = cur_addr_ptr->FirstGatewayAddress;
  831. while (gateway_ptr) {
  832. char ip[120] = { 0 };
  833. if (AF_INET == gateway_ptr->Address.lpSockaddr->sa_family) {
  834. inet_ntop(PF_INET, &((sockaddr_in*)gateway_ptr->Address.lpSockaddr)->sin_addr, ip, sizeof(ip));
  835. } else if (AF_INET6 == gateway_ptr->Address.lpSockaddr->sa_family) {
  836. inet_ntop(PF_INET6, &((sockaddr_in*)gateway_ptr->Address.lpSockaddr)->sin_addr, ip, sizeof(ip));
  837. }
  838. gateway_ptr = gateway_ptr->Next;
  839. }
  840. results.push_back(item);
  841. cur_addr_ptr = cur_addr_ptr->Next;
  842. }
  843. } else {
  844. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetAdaptersAddresses failed with error: %d", ret_val);
  845. }
  846. free(address_ptr);
  847. #else
  848. ///*TODO(80374374@3/7/2023): */
  849. #endif //_MSC_VER
  850. return results;
  851. }
  852. static BOOL CheckLANConnectStatus()
  853. {
  854. #if defined(_MSC_VER)
  855. DWORD dwFlag(0);
  856. BOOL bRet = InternetGetConnectedState(&dwFlag, 0);
  857. if ((dwFlag & INTERNET_CONNECTION_CONFIGURED) == INTERNET_CONNECTION_CONFIGURED) {
  858. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Local system has a valid connection to the Internet, but it might or might not be currently connected.");
  859. }
  860. if ((dwFlag & INTERNET_CONNECTION_LAN) == INTERNET_CONNECTION_LAN) {
  861. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Local system uses a local area network to connect to the Internet.");
  862. }
  863. if ((dwFlag & INTERNET_CONNECTION_MODEM) == INTERNET_CONNECTION_MODEM) {
  864. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Local system uses a modem to connect to the Internet.");
  865. }
  866. if ((dwFlag & INTERNET_CONNECTION_MODEM_BUSY) == INTERNET_CONNECTION_MODEM_BUSY) {
  867. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("No longer used: INTERNET_CONNECTION_MODEM_BUSY");
  868. }
  869. if ((dwFlag & INTERNET_CONNECTION_OFFLINE) == INTERNET_CONNECTION_OFFLINE) {
  870. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Local system is in offline mode.");
  871. }
  872. if ((dwFlag & INTERNET_CONNECTION_PROXY) == INTERNET_CONNECTION_PROXY) {
  873. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Local system uses a proxy server to connect to the Internet.");
  874. }
  875. if ((dwFlag & INTERNET_RAS_INSTALLED) == INTERNET_RAS_INSTALLED) {
  876. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Local system has RAS installed.");
  877. }
  878. if (bRet) {
  879. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InternetGetConnectedState Succeed: 0x%08X", dwFlag);
  880. } else {
  881. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("InternetGetConnectedState failed: 0x%08X, GLE=%u", dwFlag, GetLastError());
  882. }
  883. return bRet;
  884. #else
  885. return FALSE;
  886. #endif //_MSC_VER
  887. }
  888. static std::string GetWWWInfoThroughDig(const std::string& wwwUrl)
  889. {
  890. std::string succStr, errStr;
  891. std::string runStr("dig ");
  892. runStr += wwwUrl;
  893. if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) {
  894. return succStr;
  895. } else {
  896. return std::string("ShellExecute(") + wwwUrl + ") failed";
  897. }
  898. }
  899. }//Net
  900. } // mod
  901. } // sp
  902. #endif //RVC_MOD_COMM_ENTITY_UTIL_HPP_