Mayaqua.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231
  1. // SoftEther VPN Source Code - Stable Edition Repository
  2. // Mayaqua Kernel
  3. //
  4. // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
  5. //
  6. // Copyright (c) Daiyuu Nobori.
  7. // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
  8. // Copyright (c) SoftEther Corporation.
  9. // Copyright (c) all contributors on SoftEther VPN project in GitHub.
  10. //
  11. // All Rights Reserved.
  12. //
  13. // http://www.softether.org/
  14. //
  15. // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
  16. // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
  17. //
  18. // License: The Apache License, Version 2.0
  19. // https://www.apache.org/licenses/LICENSE-2.0
  20. //
  21. // DISCLAIMER
  22. // ==========
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. // SOFTWARE.
  31. //
  32. // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
  33. // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
  34. // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
  35. // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
  36. // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
  37. // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
  38. // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
  39. // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
  40. // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
  41. // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
  42. // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
  43. // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
  44. // LAW OR COURT RULE.
  45. //
  46. // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
  47. // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
  48. // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
  49. // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
  50. // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
  51. // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
  52. // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
  53. // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
  54. // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
  55. // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
  56. // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
  57. // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
  58. // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
  59. // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
  60. // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
  61. // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
  62. // STATEMENT FOR WARNING AND DISCLAIMER.
  63. //
  64. // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
  65. // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
  66. // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
  67. //
  68. //
  69. // SOURCE CODE CONTRIBUTION
  70. // ------------------------
  71. //
  72. // Your contribution to SoftEther VPN Project is much appreciated.
  73. // Please send patches to us through GitHub.
  74. // Read the SoftEther VPN Patch Acceptance Policy in advance:
  75. // http://www.softether.org/5-download/src/9.patch
  76. //
  77. //
  78. // DEAR SECURITY EXPERTS
  79. // ---------------------
  80. //
  81. // If you find a bug or a security vulnerability please kindly inform us
  82. // about the problem immediately so that we can fix the security problem
  83. // to protect a lot of users around the world as soon as possible.
  84. //
  85. // Our e-mail address for security reports is:
  86. // softether-vpn-security [at] softether.org
  87. //
  88. // Please note that the above e-mail address is not a technical support
  89. // inquiry address. If you need technical assistance, please visit
  90. // http://www.softether.org/ and ask your question on the users forum.
  91. //
  92. // Thank you for your cooperation.
  93. //
  94. //
  95. // NO MEMORY OR RESOURCE LEAKS
  96. // ---------------------------
  97. //
  98. // The memory-leaks and resource-leaks verification under the stress
  99. // test has been passed before release this source code.
  100. // Mayaqua.c
  101. // Mayaqua Kernel program
  102. #include <GlobalConst.h>
  103. #include <stdio.h>
  104. #include <stdlib.h>
  105. #include <string.h>
  106. #include <wchar.h>
  107. #include <stdarg.h>
  108. #include <locale.h>
  109. #include <time.h>
  110. #include <errno.h>
  111. #include <Mayaqua/Mayaqua.h>
  112. // Global variable
  113. bool g_memcheck; // Enable memory check
  114. bool g_debug; // Debug mode
  115. UINT64 kernel_status[NUM_KERNEL_STATUS]; // Kernel state
  116. UINT64 kernel_status_max[NUM_KERNEL_STATUS]; // Kernel state (maximum value)
  117. LOCK *kernel_status_lock[NUM_KERNEL_STATUS]; // Kernel state lock
  118. BOOL kernel_status_inited = false; // Kernel state initialization flag
  119. bool g_little_endian = true;
  120. char *cmdline = NULL; // Command line
  121. wchar_t *uni_cmdline = NULL; // Unicode command line
  122. // Static variable
  123. static char *exename = NULL; // EXE file name (ANSI)
  124. static wchar_t *exename_w = NULL; // EXE file name (Unicode)
  125. static TOKEN_LIST *cmdline_token = NULL; // Command line token
  126. static UNI_TOKEN_LIST *cmdline_uni_token = NULL; // Command line token (Unicode)
  127. static OS_INFO *os_info = NULL; // OS information
  128. static bool dot_net_mode = false;
  129. static bool minimal_mode = false;
  130. static UINT last_time_check = 0;
  131. static UINT first_time_check = 0;
  132. static bool is_nt = false;
  133. static bool is_ham_mode = false;
  134. static UINT init_mayaqua_counter = 0;
  135. static bool use_probe = false;
  136. static BUF *probe_buf = NULL;
  137. static LOCK *probe_lock = NULL;
  138. static UINT64 probe_start = 0;
  139. static UINT64 probe_last = 0;
  140. static bool probe_enabled = false;
  141. // The function which should be called once as soon as possible after the process is started
  142. static bool init_proc_once_flag = false;
  143. void InitProcessCallOnce()
  144. {
  145. InitProcessCallOnceEx(false);
  146. }
  147. void InitProcessCallOnceEx(int restricted_mode)
  148. {
  149. if (init_proc_once_flag == false)
  150. {
  151. init_proc_once_flag = true;
  152. InitCanaryRand();
  153. #ifdef OS_WIN32
  154. MsInitProcessCallOnce(restricted_mode);
  155. #endif // OS_WIN32
  156. }
  157. }
  158. // Calculate the checksum
  159. USHORT CalcChecksum16(void *buf, UINT size)
  160. {
  161. int sum = 0;
  162. USHORT *addr = (USHORT *)buf;
  163. int len = (int)size;
  164. USHORT *w = addr;
  165. int nleft = len;
  166. USHORT answer = 0;
  167. while (nleft > 1)
  168. {
  169. USHORT ww = 0;
  170. Copy(&ww, w++, sizeof(USHORT));
  171. sum += ww;
  172. nleft -= 2;
  173. }
  174. if (nleft == 1)
  175. {
  176. *(UCHAR *)(&answer) = *(UCHAR *)w;
  177. sum += answer;
  178. }
  179. sum = (sum >> 16) + (sum & 0xffff);
  180. sum += (sum >> 16);
  181. answer = ~sum;
  182. return answer;
  183. }
  184. // Writing a probe with the data
  185. void WriteProbeData(char *filename, UINT line, char *str, void *data, UINT size)
  186. {
  187. char tmp[MAX_SIZE];
  188. USHORT cs;
  189. if (IsProbeEnabled() == false)
  190. {
  191. return;
  192. }
  193. // Take a checksum of the data
  194. if (size != 0)
  195. {
  196. cs = CalcChecksum16(data, size);
  197. }
  198. else
  199. {
  200. cs = 0;
  201. }
  202. // Generating a String
  203. snprintf(tmp, sizeof(tmp), "\"%s\" (Size=%5u, Crc=0x%04X)", str, size, cs);
  204. WriteProbe(filename, line, tmp);
  205. }
  206. // Writing Probe
  207. void WriteProbe(char *filename, UINT line, char *str)
  208. {
  209. #ifdef OS_WIN32
  210. char *s;
  211. char tmp[MAX_SIZE];
  212. char tmp2[MAX_SIZE];
  213. UINT64 now = 0;
  214. UINT64 time;
  215. if (IsProbeEnabled() == false)
  216. {
  217. return;
  218. }
  219. now = MsGetHiResCounter();
  220. Lock(probe_lock);
  221. {
  222. UINT64 diff;
  223. time = MsGetHiResTimeSpanUSec(now - probe_start);
  224. diff = time - probe_last;
  225. if (time < probe_last)
  226. {
  227. diff = 0;
  228. }
  229. probe_last = time;
  230. ToStr64(tmp, time);
  231. MakeCharArray2(tmp2, ' ', (UINT)(MIN(12, (int)12 - (int)StrLen(tmp))));
  232. WriteBuf(probe_buf, tmp2, StrLen(tmp2));
  233. WriteBuf(probe_buf, tmp, StrLen(tmp));
  234. s = " [+";
  235. WriteBuf(probe_buf, s, StrLen(s));
  236. ToStr64(tmp, diff);
  237. MakeCharArray2(tmp2, ' ', (UINT)(MIN(12, (int)12 - (int)StrLen(tmp))));
  238. WriteBuf(probe_buf, tmp2, StrLen(tmp2));
  239. WriteBuf(probe_buf, tmp, StrLen(tmp));
  240. s = "] - ";
  241. WriteBuf(probe_buf, s, StrLen(s));
  242. WriteBuf(probe_buf, filename, StrLen(filename));
  243. s = "(";
  244. WriteBuf(probe_buf, s, StrLen(s));
  245. ToStr64(tmp, (UINT64)line);
  246. WriteBuf(probe_buf, tmp, StrLen(tmp));
  247. s = "): ";
  248. WriteBuf(probe_buf, s, StrLen(s));
  249. WriteBuf(probe_buf, str, StrLen(str));
  250. s = "\r\n";
  251. WriteBuf(probe_buf, s, StrLen(s));
  252. }
  253. Unlock(probe_lock);
  254. #endif // OS_WIN32
  255. }
  256. // Initialization of Probe
  257. void InitProbe()
  258. {
  259. probe_buf = NewBuf();
  260. probe_lock = NewLock();
  261. probe_enabled = false;
  262. probe_start = 0;
  263. #ifdef OS_WIN32
  264. probe_start = MsGetHiResCounter();
  265. #endif // OS_WIN32
  266. }
  267. // Release of Probe
  268. void FreeProbe()
  269. {
  270. if (probe_buf->Size >= 1)
  271. {
  272. SYSTEMTIME st;
  273. char filename[MAX_SIZE];
  274. // Write all to the file
  275. MakeDirEx("@probe_log");
  276. LocalTime(&st);
  277. snprintf(filename, sizeof(filename), "@probe_log/%04u%02u%02u_%02u%02u%02u.log",
  278. st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
  279. DumpBuf(probe_buf, filename);
  280. }
  281. FreeBuf(probe_buf);
  282. DeleteLock(probe_lock);
  283. }
  284. // Set enable / disable the Probe
  285. void EnableProbe(bool enable)
  286. {
  287. probe_enabled = enable;
  288. }
  289. // Get whether the Probe is enabled?
  290. bool IsProbeEnabled()
  291. {
  292. #ifndef USE_PROBE
  293. return false;
  294. #else // USE_PROBE
  295. return probe_enabled;
  296. #endif // USE_PROBE
  297. }
  298. // Set the Ham mode
  299. void SetHamMode()
  300. {
  301. is_ham_mode = true;
  302. }
  303. // Get whether in Ham mode
  304. bool IsHamMode()
  305. {
  306. return is_ham_mode;
  307. }
  308. // Display the time from the previous call to now
  309. void TimeCheck()
  310. {
  311. #ifdef OS_WIN32
  312. UINT now, ret, total;
  313. now = Win32GetTick();
  314. if (last_time_check == 0)
  315. {
  316. ret = 0;
  317. }
  318. else
  319. {
  320. ret = now - last_time_check;
  321. }
  322. last_time_check = now;
  323. if (first_time_check == 0)
  324. {
  325. first_time_check = now;
  326. }
  327. total = now - first_time_check;
  328. printf(" -- %3.3f / %3.3f\n", (double)ret / 1000.0f, (double)total / 1000.0f);
  329. #endif // OS_WIN32
  330. }
  331. // Whether this system is IA64
  332. bool IsIA64()
  333. {
  334. if (Is64() == false)
  335. {
  336. return false;
  337. }
  338. #ifndef MAYAQUA_IA_64
  339. return false;
  340. #else // MAYAQUA_IA_64
  341. return true;
  342. #endif // MAYAQUA_IA_64
  343. }
  344. // Whether in x64
  345. bool IsX64()
  346. {
  347. if (Is64() == false)
  348. {
  349. return false;
  350. }
  351. #ifndef MAYAQUA_IA_64
  352. return true;
  353. #else // MAYAQUA_IA_64
  354. return false;
  355. #endif // MAYAQUA_IA_64
  356. }
  357. // Whether 64bit
  358. bool Is64()
  359. {
  360. #ifdef CPU_64
  361. return true;
  362. #else // CPU_64
  363. return false;
  364. #endif // CPU_64
  365. }
  366. // Whether 32bit
  367. bool Is32()
  368. {
  369. return Is64() ? false : true;
  370. }
  371. // .NET mode
  372. void MayaquaDotNetMode()
  373. {
  374. dot_net_mode = true;
  375. }
  376. // Acquisition whether in .NET mode
  377. bool MayaquaIsDotNetMode()
  378. {
  379. return dot_net_mode;
  380. }
  381. // Check the endian
  382. void CheckEndian()
  383. {
  384. unsigned short test;
  385. UCHAR *buf;
  386. test = 0x1234;
  387. buf = (UCHAR *)&test;
  388. if (buf[0] == 0x12)
  389. {
  390. g_little_endian = false;
  391. }
  392. else
  393. {
  394. g_little_endian = true;
  395. }
  396. }
  397. // Minimize mode
  398. void MayaquaMinimalMode()
  399. {
  400. minimal_mode = true;
  401. }
  402. bool MayaquaIsMinimalMode()
  403. {
  404. return minimal_mode;
  405. }
  406. // Whether in NT
  407. bool IsNt()
  408. {
  409. return is_nt;
  410. }
  411. // Whether the Unicode is supported
  412. bool IsUnicode()
  413. {
  414. #ifdef OS_WIN32
  415. // Windows
  416. return IsNt();
  417. #else // OS_WIN32
  418. // UNIX
  419. return true;
  420. #endif // OS_WIN32
  421. }
  422. // Initialization of Mayaqua library
  423. void InitMayaqua(bool memcheck, bool debug, int argc, char **argv)
  424. {
  425. wchar_t tmp[MAX_PATH];
  426. UCHAR hash[SHA1_SIZE];
  427. if ((init_mayaqua_counter++) > 0)
  428. {
  429. return;
  430. }
  431. InitProcessCallOnce();
  432. g_memcheck = memcheck;
  433. g_debug = debug;
  434. cmdline = NULL;
  435. if (dot_net_mode == false)
  436. {
  437. // Fail this for some reason when this is called this in .NET mode
  438. setbuf(stdout, NULL);
  439. }
  440. // Acquisition whether NT
  441. #ifdef OS_WIN32
  442. is_nt = Win32IsNt();
  443. #endif // OS_WIN32
  444. // Check endian
  445. CheckEndian();
  446. #ifdef OS_WIN32
  447. _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
  448. #endif // OS_WIN32
  449. // Set the locale information of the CRT to the Japanese
  450. setlocale(LC_ALL, "");
  451. // Initialization of OS
  452. OSInit();
  453. // Initialize the random number
  454. srand((UINT)SystemTime64());
  455. tick_manual_lock = NewLock();
  456. // Initialization of CRC32
  457. InitCrc32();
  458. // Initialization of the FIFO system
  459. InitFifo();
  460. // Initialize the Kernel status
  461. InitKernelStatus();
  462. // Initialize the tracking
  463. InitTracking();
  464. // Initialization of thread pool
  465. InitThreading();
  466. // Initialize the string library
  467. InitStringLibrary();
  468. // Initialization of the locale information
  469. SetLocale(NULL);
  470. // Initialization of the crypt library
  471. InitCryptLibrary();
  472. // Initialization of the real-time clock
  473. InitTick64();
  474. // Initialize the network communication module
  475. InitNetwork();
  476. // Initialization of the aquisition of the EXE file name
  477. InitGetExeName(argc >= 1 ? argv[0] : NULL);
  478. // Initialization of the command line string
  479. InitCommandLineStr(argc, argv);
  480. // Initialization of OS information
  481. InitOsInfo();
  482. // Initialization of the operating system-specific module
  483. #ifdef OS_WIN32
  484. MsInit(); // Microsoft Win32
  485. #endif // OS_WIN32
  486. // Initialization of the security token module
  487. InitSecure();
  488. if (OSIsSupportedOs() == false)
  489. {
  490. // Abort
  491. exit(0);
  492. }
  493. // Initialization of HamCore file system
  494. InitHamcore();
  495. // Initialization of string table routine
  496. InitTable();
  497. if (exename == NULL)
  498. {
  499. // Executable file name
  500. exename = CopyStr("unknown");
  501. }
  502. // Check whether the executable file name of themselves is found
  503. // (If not found, quit because this is started in strange path)
  504. GetExeNameW(tmp, sizeof(tmp));
  505. if (IsFileExistsW(tmp) == false)
  506. {
  507. wchar_t tmp2[MAX_SIZE];
  508. UniFormat(tmp2, sizeof(tmp2),
  509. L"Error: Executable binary file \"%s\" not found.\r\n\r\n"
  510. L"Please execute program with full path.\r\n",
  511. tmp);
  512. AlertW(tmp2, NULL);
  513. _exit(0);
  514. }
  515. CheckUnixTempDir();
  516. // Initialization of Probe
  517. InitProbe();
  518. // Initialization of Machine Hash
  519. GetCurrentMachineIpProcessHash(hash);
  520. // Reading Private IP file
  521. LoadPrivateIPFile();
  522. }
  523. // Release of Mayaqua library
  524. void FreeMayaqua()
  525. {
  526. if ((--init_mayaqua_counter) > 0)
  527. {
  528. return;
  529. }
  530. // Release of Private IP File
  531. FreePrivateIPFile();
  532. // Release of Probe
  533. FreeProbe();
  534. // Delete the table
  535. FreeTable();
  536. // Release of security token module
  537. FreeSecure();
  538. // Release of the operating system specific module
  539. #ifdef OS_WIN32
  540. MsFree();
  541. #endif // OS_WIN32
  542. // Release of OS information
  543. FreeOsInfo();
  544. // Release of HamCore file system
  545. FreeHamcore();
  546. // Release of the command line string
  547. FreeCommandLineStr();
  548. // Release of the command line token
  549. FreeCommandLineTokens();
  550. // Release of network communication module
  551. FreeNetwork();
  552. // Release of real-time clock
  553. FreeTick64();
  554. // Release of crypt library
  555. FreeCryptLibrary();
  556. // Release of the string library
  557. FreeStringLibrary();
  558. // Release of thread pool
  559. FreeThreading();
  560. #ifndef VPN_SPEED
  561. // Show the kernel status
  562. if (g_debug)
  563. {
  564. PrintKernelStatus();
  565. }
  566. // Display the debug information
  567. if (g_memcheck)
  568. {
  569. PrintDebugInformation();
  570. }
  571. #endif // VPN_SPEED
  572. // Release the tracking
  573. FreeTracking();
  574. // Release of the kernel status
  575. FreeKernelStatus();
  576. DeleteLock(tick_manual_lock);
  577. tick_manual_lock = NULL;
  578. // Release of OS
  579. OSFree();
  580. }
  581. // Check whether /tmp is available in the UNIX
  582. void CheckUnixTempDir()
  583. {
  584. if (OS_IS_UNIX(GetOsInfo()->OsType))
  585. {
  586. char tmp[128], tmp2[64];
  587. UINT64 now = SystemTime64();
  588. IO *o;
  589. MakeDir("/tmp");
  590. Format(tmp2, sizeof(tmp2), "%I64u", now);
  591. Format(tmp, sizeof(tmp), "/tmp/.%s", tmp2);
  592. o = FileCreate(tmp);
  593. if (o == NULL)
  594. {
  595. o = FileOpen(tmp, false);
  596. if (o == NULL)
  597. {
  598. Print("Unable to use /tmp.\n\n");
  599. exit(0);
  600. return;
  601. }
  602. }
  603. FileClose(o);
  604. FileDelete(tmp);
  605. }
  606. }
  607. // Show an alert
  608. void Alert(char *msg, char *caption)
  609. {
  610. OSAlert(msg, caption);
  611. }
  612. void AlertW(wchar_t *msg, wchar_t *caption)
  613. {
  614. OSAlertW(msg, caption);
  615. }
  616. // Display of OS information
  617. void PrintOsInfo(OS_INFO *info)
  618. {
  619. // Validate arguments
  620. if (info == NULL)
  621. {
  622. return;
  623. }
  624. Print(
  625. "OS Type : %u\n"
  626. "OS Service Pack : %u\n"
  627. "os_is_windows : %s\n"
  628. "os_is_windows_nt : %s\n"
  629. "OS System Name : %s\n"
  630. "OS Product Name : %s\n"
  631. "OS Vendor Name : %s\n"
  632. "OS Version : %s\n"
  633. "Kernel Name : %s\n"
  634. "Kernel Version : %s\n",
  635. info->OsType,
  636. info->OsServicePack,
  637. OS_IS_WINDOWS(info->OsType) ? "true" : "false",
  638. OS_IS_WINDOWS_NT(info->OsType) ? "true" : "false",
  639. info->OsSystemName,
  640. info->OsProductName,
  641. info->OsVendorName,
  642. info->OsVersion,
  643. info->KernelName,
  644. info->KernelVersion);
  645. #ifdef OS_WIN32
  646. {
  647. char *exe, *dir;
  648. exe = MsGetExeFileName();
  649. dir = MsGetExeDirName();
  650. Print(
  651. "EXE File Path : %s\n"
  652. "EXE Dir Path : %s\n"
  653. "Process Id : %u\n"
  654. "Process Handle : 0x%X\n",
  655. exe, dir, MsGetCurrentProcessId(), MsGetCurrentProcess());
  656. }
  657. #endif // OS_WIN32
  658. }
  659. // Get the OS type
  660. UINT GetOsType()
  661. {
  662. OS_INFO *i = GetOsInfo();
  663. if (i == NULL)
  664. {
  665. return 0;
  666. }
  667. return i->OsType;
  668. }
  669. // Getting OS information
  670. OS_INFO *GetOsInfo()
  671. {
  672. return os_info;
  673. }
  674. // Initialization of OS information
  675. void InitOsInfo()
  676. {
  677. if (os_info != NULL)
  678. {
  679. return;
  680. }
  681. os_info = ZeroMalloc(sizeof(OS_INFO));
  682. OSGetOsInfo(os_info);
  683. }
  684. // Release of OS information
  685. void FreeOsInfo()
  686. {
  687. if (os_info == NULL)
  688. {
  689. return;
  690. }
  691. Free(os_info->OsSystemName);
  692. Free(os_info->OsProductName);
  693. Free(os_info->OsVendorName);
  694. Free(os_info->OsVersion);
  695. Free(os_info->KernelName);
  696. Free(os_info->KernelVersion);
  697. Free(os_info);
  698. os_info = NULL;
  699. }
  700. // Get the Unicode command line tokens
  701. UNI_TOKEN_LIST *GetCommandLineUniToken()
  702. {
  703. if (cmdline_uni_token == NULL)
  704. {
  705. return UniNullToken();
  706. }
  707. else
  708. {
  709. return UniCopyToken(cmdline_uni_token);
  710. }
  711. }
  712. // Getting the command line tokens
  713. TOKEN_LIST *GetCommandLineToken()
  714. {
  715. if (cmdline_token == NULL)
  716. {
  717. return NullToken();
  718. }
  719. else
  720. {
  721. return CopyToken(cmdline_token);
  722. }
  723. }
  724. // Convert the command line string into tokens
  725. void ParseCommandLineTokens()
  726. {
  727. if (cmdline_token != NULL)
  728. {
  729. FreeToken(cmdline_token);
  730. }
  731. cmdline_token = ParseCmdLine(cmdline);
  732. if (cmdline_uni_token != NULL)
  733. {
  734. UniFreeToken(cmdline_uni_token);
  735. }
  736. cmdline_uni_token = UniParseCmdLine(uni_cmdline);
  737. }
  738. // Release command line tokens
  739. void FreeCommandLineTokens()
  740. {
  741. if (cmdline_token != NULL)
  742. {
  743. FreeToken(cmdline_token);
  744. }
  745. cmdline_token = NULL;
  746. if (cmdline_uni_token != NULL)
  747. {
  748. UniFreeToken(cmdline_uni_token);
  749. }
  750. cmdline_uni_token = NULL;
  751. }
  752. // Initialization of the command line string
  753. void InitCommandLineStr(int argc, char **argv)
  754. {
  755. if (argc >= 1)
  756. {
  757. #ifdef OS_UNIX
  758. exename_w = CopyUtfToUni(argv[0]);
  759. exename = CopyUniToStr(exename_w);
  760. #else // OS_UNIX
  761. exename = CopyStr(argv[0]);
  762. exename_w = CopyStrToUni(exename);
  763. #endif // OS_UNIX
  764. }
  765. if (argc < 2 || argv == NULL)
  766. {
  767. // No command-line string
  768. SetCommandLineStr(NULL);
  769. }
  770. else
  771. {
  772. // There are command-line string
  773. int i, total_len = 1;
  774. char *tmp;
  775. for (i = 1;i < argc;i++)
  776. {
  777. total_len += StrLen(argv[i]) * 2 + 32;
  778. }
  779. tmp = ZeroMalloc(total_len);
  780. for (i = 1;i < argc;i++)
  781. {
  782. UINT s_size = StrLen(argv[i]) * 2;
  783. char *s = ZeroMalloc(s_size);
  784. bool dq = (SearchStrEx(argv[i], " ", 0, true) != INFINITE);
  785. ReplaceStrEx(s, s_size, argv[i], "\"", "\"\"", true);
  786. if (dq)
  787. {
  788. StrCat(tmp, total_len, "\"");
  789. }
  790. StrCat(tmp, total_len, s);
  791. if (dq)
  792. {
  793. StrCat(tmp, total_len, "\"");
  794. }
  795. StrCat(tmp, total_len, " ");
  796. Free(s);
  797. }
  798. Trim(tmp);
  799. SetCommandLineStr(tmp);
  800. Free(tmp);
  801. }
  802. }
  803. // Release of the command line string
  804. void FreeCommandLineStr()
  805. {
  806. SetCommandLineStr(NULL);
  807. if (exename != NULL)
  808. {
  809. Free(exename);
  810. exename = NULL;
  811. }
  812. if (exename_w != NULL)
  813. {
  814. Free(exename_w);
  815. exename_w = NULL;
  816. }
  817. }
  818. // Get the Unicode command line string
  819. wchar_t *GetCommandLineUniStr()
  820. {
  821. if (uni_cmdline == NULL)
  822. {
  823. return UniCopyStr(L"");
  824. }
  825. else
  826. {
  827. return UniCopyStr(uni_cmdline);
  828. }
  829. }
  830. // Get the command line string
  831. char *GetCommandLineStr()
  832. {
  833. if (cmdline == NULL)
  834. {
  835. return CopyStr("");
  836. }
  837. else
  838. {
  839. return CopyStr(cmdline);
  840. }
  841. }
  842. // Set the Unicode command line string
  843. void SetCommandLineUniStr(wchar_t *str)
  844. {
  845. if (uni_cmdline != NULL)
  846. {
  847. Free(uni_cmdline);
  848. }
  849. if (str == NULL)
  850. {
  851. uni_cmdline = NULL;
  852. }
  853. else
  854. {
  855. uni_cmdline = CopyUniStr(str);
  856. }
  857. ParseCommandLineTokens();
  858. }
  859. // Set the command-line string
  860. void SetCommandLineStr(char *str)
  861. {
  862. // Validate arguments
  863. if (str == NULL)
  864. {
  865. if (cmdline != NULL)
  866. {
  867. Free(cmdline);
  868. }
  869. cmdline = NULL;
  870. }
  871. else
  872. {
  873. if (cmdline != NULL)
  874. {
  875. Free(cmdline);
  876. }
  877. cmdline = CopyStr(str);
  878. }
  879. if (cmdline == NULL)
  880. {
  881. if (uni_cmdline != NULL)
  882. {
  883. Free(uni_cmdline);
  884. uni_cmdline = NULL;
  885. }
  886. }
  887. else
  888. {
  889. if (uni_cmdline != NULL)
  890. {
  891. Free(uni_cmdline);
  892. }
  893. uni_cmdline = CopyStrToUni(cmdline);
  894. }
  895. ParseCommandLineTokens();
  896. }
  897. // Display the kernel status
  898. void PrintKernelStatus()
  899. {
  900. bool leaked = false;
  901. Print("\n");
  902. Print(
  903. " --------- Mayaqua Kernel Status ---------\n"
  904. " Malloc Count ............... %u\n"
  905. " ReAlloc Count .............. %u\n"
  906. " Free Count ................. %u\n"
  907. " Total Memory Size .......... %I64u bytes\n"
  908. " * Current Memory Blocks ...... %u Blocks (Peek: %u)\n"
  909. " Total Memory Blocks ........ %u Blocks\n"
  910. " * Current MemPool Blocks ..... %u Blocks (Peek: %u)\n"
  911. " Total MemPool Mallocs ...... %u Mallocs\n"
  912. " Total MemPool ReAllocs ..... %u ReAllocs\n"
  913. " NewLock Count .............. %u\n"
  914. " DeleteLock Count ........... %u\n"
  915. " * Current Lock Objects ....... %u Objects\n"
  916. " * Current Locked Objects ..... %u Objects\n"
  917. " NewRef Count ............... %u\n"
  918. " FreeRef Count .............. %u\n"
  919. " * Current Ref Objects ........ %u Objects\n"
  920. " * Current Ref Count .......... %u Refs\n"
  921. " GetTime Count .............. %u\n"
  922. " GetTick Count .............. %u\n"
  923. " NewThread Count ............ %u\n"
  924. " FreeThread Count ........... %u\n"
  925. " * Current Threads ............ %u Threads\n"
  926. " Wait For Event Count ....... %u\n\n",
  927. KS_GET(KS_MALLOC_COUNT),
  928. KS_GET(KS_REALLOC_COUNT),
  929. KS_GET(KS_FREE_COUNT),
  930. KS_GET64(KS_TOTAL_MEM_SIZE),
  931. KS_GET(KS_CURRENT_MEM_COUNT),
  932. KS_GETMAX(KS_CURRENT_MEM_COUNT),
  933. KS_GET(KS_TOTAL_MEM_COUNT),
  934. KS_GET(KS_MEMPOOL_CURRENT_NUM),
  935. KS_GETMAX(KS_MEMPOOL_CURRENT_NUM),
  936. KS_GET(KS_MEMPOOL_MALLOC_COUNT),
  937. KS_GET(KS_MEMPOOL_REALLOC_COUNT),
  938. KS_GET(KS_NEWLOCK_COUNT),
  939. KS_GET(KS_DELETELOCK_COUNT),
  940. KS_GET(KS_CURRENT_LOCK_COUNT),
  941. KS_GET(KS_CURRENT_LOCKED_COUNT),
  942. KS_GET(KS_NEWREF_COUNT),
  943. KS_GET(KS_FREEREF_COUNT),
  944. KS_GET(KS_CURRENT_REF_COUNT),
  945. KS_GET(KS_CURRENT_REFED_COUNT),
  946. KS_GET(KS_GETTIME_COUNT),
  947. KS_GET(KS_GETTICK_COUNT),
  948. KS_GET(KS_NEWTHREAD_COUNT),
  949. KS_GET(KS_FREETHREAD_COUNT),
  950. KS_GET(KS_NEWTHREAD_COUNT) - KS_GET(KS_FREETHREAD_COUNT),
  951. KS_GET(KS_WAIT_COUNT)
  952. );
  953. if (KS_GET(KS_CURRENT_MEM_COUNT) != 0 || KS_GET(KS_CURRENT_LOCK_COUNT) != 0 ||
  954. KS_GET(KS_MEMPOOL_CURRENT_NUM) != 0 ||
  955. KS_GET(KS_CURRENT_LOCKED_COUNT) != 0 || KS_GET(KS_CURRENT_REF_COUNT) != 0)
  956. {
  957. leaked = true;
  958. }
  959. if (leaked)
  960. {
  961. Print(" !!! MEMORY LEAKS DETECTED !!!\n\n");
  962. if (g_memcheck == false)
  963. {
  964. GetLine(NULL, 0);
  965. }
  966. }
  967. else
  968. {
  969. Print(" @@@ NO MEMORY LEAKS @@@\n\n");
  970. }
  971. }
  972. // Initialize Kernel status
  973. void InitKernelStatus()
  974. {
  975. UINT i;
  976. // Memory initialization
  977. Zero(kernel_status, sizeof(kernel_status));
  978. Zero(kernel_status_max, sizeof(kernel_status_max));
  979. // Lock initialization
  980. for (i = 0;i < NUM_KERNEL_STATUS;i++)
  981. {
  982. kernel_status_lock[i] = OSNewLock();
  983. }
  984. kernel_status_inited = true;
  985. }
  986. // Release of the kernel status
  987. void FreeKernelStatus()
  988. {
  989. UINT i;
  990. kernel_status_inited = false;
  991. // Lock release
  992. for (i = 0;i < NUM_KERNEL_STATUS;i++)
  993. {
  994. OSDeleteLock(kernel_status_lock[i]);
  995. }
  996. }
  997. // Lock the kernel status
  998. void LockKernelStatus(UINT id)
  999. {
  1000. // Validate arguments
  1001. if (id >= NUM_KERNEL_STATUS)
  1002. {
  1003. return;
  1004. }
  1005. OSLock(kernel_status_lock[id]);
  1006. }
  1007. // Unlock the kernel status
  1008. void UnlockKernelStatus(UINT id)
  1009. {
  1010. // Validate arguments
  1011. if (id >= NUM_KERNEL_STATUS)
  1012. {
  1013. return;
  1014. }
  1015. OSUnlock(kernel_status_lock[id]);
  1016. }
  1017. // Display the debug information
  1018. void PrintDebugInformation()
  1019. {
  1020. MEMORY_STATUS memory_status;
  1021. GetMemoryStatus(&memory_status);
  1022. // Header
  1023. Print("====== " CEDAR_PRODUCT_STR " VPN System Debug Information ======\n");
  1024. // Memory information
  1025. Print(" <Memory Status>\n"
  1026. " Number of Allocated Memory Blocks: %u\n"
  1027. " Total Size of Allocated Memory Blocks: %u bytes\n",
  1028. memory_status.MemoryBlocksNum, memory_status.MemorySize);
  1029. // Footer
  1030. Print("====================================================\n");
  1031. if (KS_GET(KS_CURRENT_MEM_COUNT) != 0 || KS_GET(KS_CURRENT_LOCK_COUNT) != 0 ||
  1032. KS_GET(KS_CURRENT_LOCKED_COUNT) != 0 || KS_GET(KS_CURRENT_REF_COUNT) != 0)
  1033. {
  1034. // Show a debug menu because memory leaks suspected
  1035. MemoryDebugMenu();
  1036. }
  1037. }