osutil.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. #include "precompile.h"
  2. #include "osutil.h"
  3. #include "memutil.h"
  4. #include "strutil.h"
  5. #include "toolkit.h"
  6. #ifdef _WIN32
  7. #include <TlHelp32.h>
  8. TOOLKIT_API int osutil_detect_unique_app(char** pNames, int nNum, int* alive, alive_process_info* alive_process_arr)
  9. {
  10. HANDLE hSnapshot;
  11. int rc = TRUE;
  12. DWORD dwCurProcID = GetCurrentProcessId();
  13. int count = 0;
  14. if (alive) *alive = 0;
  15. hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  16. if (hSnapshot) {
  17. PROCESSENTRY32 pe;
  18. pe.dwSize = sizeof(pe);
  19. if (Process32First(hSnapshot, &pe)) {
  20. do {
  21. int i;
  22. for (i = 0; i < nNum; i++) {
  23. if (stricmp(&pe.szExeFile[0], pNames[i]) == 0 && pe.th32ProcessID != dwCurProcID) {
  24. rc = FALSE;
  25. count++;
  26. break;
  27. }
  28. }
  29. } while (Process32Next(hSnapshot, &pe));
  30. }
  31. CloseHandle(hSnapshot);
  32. }
  33. if (alive) *alive = count;
  34. return rc;
  35. }
  36. TOOLKIT_API int osutil_restart_system()
  37. {
  38. HANDLE hToken;
  39. TOKEN_PRIVILEGES tkp;
  40. BOOL fResult;
  41. // Get the current process token handle so we can get shutdown privilege.
  42. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  43. fprintf(stderr, "get proc token fail");
  44. return -1;
  45. }
  46. // Get the LUID for shutdown privilege.
  47. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  48. tkp.PrivilegeCount = 1; // one privilege to set
  49. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  50. // Get shutdown privilege for this process.
  51. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
  52. // Cannot test the return value of AdjustTokenPrivileges.
  53. if (GetLastError() != ERROR_SUCCESS) {
  54. fprintf(stderr, "adjust proc token privilege fail");
  55. return -1;
  56. }
  57. // Display the shutdown dialog box and start the countdown.
  58. fResult = InitiateSystemShutdown(
  59. NULL, // shut down local computer
  60. NULL, // message for user
  61. 0, // time-out period, in seconds
  62. FALSE, // ask user to close apps
  63. TRUE); // reboot after shutdown
  64. if (!fResult) {
  65. fprintf(stderr, "request windows reboot fail");
  66. return -1;
  67. }
  68. // Disable shutdown privilege.
  69. tkp.Privileges[0].Attributes = 0;
  70. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
  71. return 0;
  72. }
  73. TOOLKIT_API void osutil_terminate_related_process(char** process_array, const int array_size, int force)
  74. {
  75. const DWORD dwCurProcessID = GetCurrentProcessId();
  76. DWORD relateProcessIDs[256];
  77. DWORD dwIdx = 0;
  78. char szCmd[256];
  79. DWORD relateProcessNum = 0;
  80. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  81. memset(relateProcessIDs, 0, sizeof(relateProcessIDs));
  82. if (hSnapshot)
  83. {
  84. PROCESSENTRY32 pe;
  85. pe.dwSize = sizeof(pe);
  86. if (Process32First(hSnapshot, &pe)) {
  87. do {
  88. int i;
  89. for (i = 0; i < array_size; i++) {
  90. if (stricmp(&pe.szExeFile[0], process_array[i]) == 0 && pe.th32ProcessID != dwCurProcessID) {
  91. relateProcessIDs[relateProcessNum++] = pe.th32ProcessID;
  92. break;
  93. }
  94. }
  95. } while (Process32Next(hSnapshot, &pe));
  96. }
  97. CloseHandle(hSnapshot);
  98. }
  99. for (dwIdx = 0; dwIdx < relateProcessNum; ++dwIdx) {
  100. sprintf_s(szCmd, 256, "TASKKILL /PID %d /F", relateProcessIDs[dwIdx]);
  101. WinExec(szCmd, SW_HIDE);
  102. }
  103. }
  104. TOOLKIT_API int osutil_uname(tk_utsname_t* buffer)
  105. {
  106. return TOOLKIT_UNKNOWN;
  107. }
  108. TOOLKIT_API int osutil_is32r64_platform()
  109. {
  110. int isWow64 = -1;
  111. typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
  112. BOOL bIsWow64 = FALSE;
  113. LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
  114. if (NULL != fnIsWow64Process) {
  115. if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
  116. return -1;
  117. }
  118. else {
  119. isWow64 = bIsWow64 ? 1 : 0;
  120. }
  121. }
  122. return isWow64;
  123. }
  124. TOOLKIT_API ostuile_void_ptr osutil_sure_redirect_32sys_in_wow64()
  125. {
  126. ostuile_void_ptr value = NULL;
  127. if (osutil_is32r64_platform() == 1) {
  128. if (!Wow64DisableWow64FsRedirection(&value)) {
  129. value = NULL;
  130. }
  131. }
  132. return value;
  133. }
  134. TOOLKIT_API void osutil_reset_redirect_32sys_in_wow64(ostuile_void_ptr* value)
  135. {
  136. if (value != NULL && (*value) != NULL) {
  137. Wow64RevertWow64FsRedirection(*value);
  138. }
  139. return;
  140. }
  141. #else
  142. #include <unistd.h>
  143. #include <dirent.h>
  144. #include <sys/types.h> // for opendir(), readdir(), closedir()
  145. #include <sys/stat.h> // for stat()
  146. #include <strings.h>
  147. #include <signal.h>
  148. #include <winpr/wtypes.h>
  149. #include <sys/reboot.h>
  150. #include <sys/utsname.h>
  151. #define DEFAULT_PROCESS_CMDLINE_SIZE 56
  152. #define DEFAULT_PROCESS_PATH_SIZE 8192
  153. #define DEFAULT_PROCESS_NAME_SIZE 1024
  154. static inline int is_num(const char* chars)
  155. {
  156. for (; *chars; chars++)
  157. if (*chars < '0' || *chars > '9')
  158. return 0; // false
  159. return 1; // true
  160. }
  161. static int execute_cmd_return_result(const char* cmd, char* result)
  162. {
  163. char buf_ps[1024];
  164. char ps[1024] = { 0 };
  165. FILE* ptr;
  166. strcpy(ps, cmd);
  167. if ((ptr = popen(ps, "r")) != NULL) {
  168. while (fgets(buf_ps, 1024, ptr) != NULL) {
  169. strcat(result, buf_ps);
  170. if (strlen(result) > 1024)
  171. break;
  172. }
  173. int len = strlen(result);
  174. int i;
  175. for (i = len - 1; i >= 0 && result[i] == '\n'; --i) {
  176. result[i] = '\0';
  177. }
  178. pclose(ptr);
  179. return 0;
  180. } else {
  181. printf("popen %s error\n", ps);
  182. return -1;
  183. }
  184. }
  185. static int private_get_running_process_ids(int* alive, alive_process_info* alive_process_arr, const char* process_name)
  186. {
  187. int ret = 0, capacity, count, idx;
  188. char content[1025];
  189. char cmd[256];
  190. const int cur_pid = (int)getpid();
  191. memset(content, 0, sizeof(content));
  192. capacity = *alive;
  193. *alive = 0;
  194. idx = count = 0;
  195. sprintf(cmd, "pgrep -u root -d '|' %s", process_name);
  196. ret = execute_cmd_return_result(cmd, content);
  197. if (ret == 0 && strlen(content) > 0) {
  198. char** elems = strsplit(content, "|");
  199. if (elems != NULL) {
  200. char** p;
  201. for (p = elems; *p != NULL; ++p) {
  202. int pid;
  203. pid = atoi(*p);
  204. if(pid == cur_pid)
  205. continue;
  206. printf("%d: %s, %d\n", count, *p, pid);
  207. if (count < capacity) {
  208. alive_process_arr[count].pid = pid;
  209. strcpy(alive_process_arr[count].name, process_name);
  210. strcpy(alive_process_arr[count].path, process_name);
  211. idx++;
  212. }
  213. count++;
  214. }
  215. strfreev(elems);
  216. }
  217. }
  218. *alive = idx;
  219. return count;
  220. }
  221. #ifdef NEW_FEATURE
  222. TOOLKIT_API int osutil_detect_unique_app(char** pNames, int nNum, int* alive, alive_process_info* alive_process_arr)
  223. {
  224. int i = 0;
  225. int count = 0, capacity = 0;
  226. int real = 0;
  227. if (alive) {
  228. if (alive_process_arr) capacity = *alive;
  229. *alive = 0;
  230. }
  231. for (i = 0; i < nNum; ++i) {
  232. int cap = capacity - count;
  233. int result = private_get_running_process_ids(&cap, alive_process_arr + count, pNames[i]);
  234. count += cap;
  235. real += result;
  236. }
  237. if (alive) {
  238. *alive = real;
  239. }
  240. return (real > 0) ? FALSE : TRUE;
  241. }
  242. #else
  243. TOOLKIT_API int osutil_detect_unique_app(char** pNames, int nNum, int* alive, alive_process_info* alive_process_arr)
  244. {
  245. int rc = TRUE;
  246. DIR* dir_proc = NULL;
  247. struct dirent* dir_entity = NULL;
  248. int i = 0;
  249. int count = 0, capacity = 0;
  250. char cmdLinePath[DEFAULT_PROCESS_CMDLINE_SIZE] = { 0 };
  251. char processName[DEFAULT_PROCESS_NAME_SIZE] = { 0 };
  252. char processPath[DEFAULT_PROCESS_PATH_SIZE] = { 0 };
  253. pid_t pid = (pid_t)-1;
  254. const pid_t cur_pid = getpid();
  255. if (alive) {
  256. if (alive_process_arr) capacity = *alive;
  257. *alive = 0;
  258. }
  259. dir_proc = opendir("/proc/");
  260. if (dir_proc == NULL) {
  261. return FALSE;
  262. }
  263. while ((dir_entity = readdir(dir_proc))) {
  264. if (dir_entity->d_type == DT_DIR) {
  265. if (is_num(dir_entity->d_name)) {
  266. pid = (pid_t)atoi(dir_entity->d_name);
  267. if (pid == getpid()) {
  268. continue;
  269. }
  270. strcpy(cmdLinePath, "/proc/");
  271. strcat(cmdLinePath, dir_entity->d_name);
  272. strcat(cmdLinePath, "/cmdline");
  273. //printf("%s: open(%s)...\n", __FUNCTION__, cmdLinePath);
  274. FILE* fd_cmdline = fopen(cmdLinePath, "rt");
  275. if (fd_cmdline != NULL) {
  276. memset(processName, 0, DEFAULT_PROCESS_NAME_SIZE);
  277. memset(processPath, 0, DEFAULT_PROCESS_PATH_SIZE);
  278. ///**TODO(Gifur@1/10/2022): 读文件的所有内容并通过结束符0x00去拆分 */
  279. fscanf(fd_cmdline, "%s", processPath);
  280. //printf("%s: close(%p)...\n", __FUNCTION__, fd_cmdline);
  281. fclose(fd_cmdline);
  282. //printf("%s: close(%p) done!\n", __FUNCTION__, fd_cmdline);
  283. if (strrchr(processPath, '/')) {
  284. strcpy(processName, strrchr(processPath, '/') + 1);
  285. } else {
  286. strcpy(processName, processPath);
  287. }
  288. for (i = 0; i < nNum; i++) {
  289. if (strcasecmp(processName, pNames[i]) == 0) {
  290. printf("%s, %s, %d, %d\n", processPath, processName, pid, cur_pid);
  291. if (count < capacity) {
  292. if (strlen(processPath) > ALIVE_PROCESS_PATH_LEN - 1) {
  293. processPath[ALIVE_PROCESS_PATH_LEN - 1] = '\0';
  294. processPath[ALIVE_PROCESS_PATH_LEN - 2] = '.';
  295. processPath[ALIVE_PROCESS_PATH_LEN - 3] = '.';
  296. processPath[ALIVE_PROCESS_PATH_LEN - 4] = '.';
  297. }
  298. strcpy(alive_process_arr[count].path, processPath);
  299. alive_process_arr[count].pid = pid;
  300. strcpy(alive_process_arr[count].name, processName);
  301. }
  302. count++;
  303. rc = FALSE;
  304. break;
  305. }
  306. }
  307. } else {
  308. printf("%s: open(%s) failed %d!!\n", __FUNCTION__, cmdLinePath, errno);
  309. }
  310. }
  311. }
  312. if (!rc && !alive) {
  313. break;
  314. }
  315. }
  316. printf("%s: closedir(%p)...\n", __FUNCTION__, dir_proc);
  317. closedir(dir_proc);
  318. printf("%s: closedir(%p) done!\n", __FUNCTION__, dir_proc);
  319. if (alive) *alive = count;
  320. printf("%s: exit!\n", __FUNCTION__);
  321. return rc;
  322. }
  323. #endif
  324. TOOLKIT_API int osutil_restart_system()
  325. {
  326. int result = -1;
  327. sync();
  328. result = reboot(RB_AUTOBOOT);
  329. return result;
  330. }
  331. #ifdef NEW_FEATURE
  332. TOOLKIT_API void osutil_terminate_related_process(char** process_array, const int array_size, int force)
  333. {
  334. int i, j, k;
  335. const pid_t cur_pid = getpid();
  336. k = 0;
  337. for (i = 0; i < array_size; ++i) {
  338. int count = 50;
  339. alive_process_info processes[50];
  340. memset(processes, 0, sizeof(processes));
  341. int result = private_get_running_process_ids(&count, processes, process_array[i]);
  342. for (j = 0; j < count; ++j) {
  343. printf("kill %s, %s, %d, %d\n", processes[j].path, processes[j].name, processes[j].pid, cur_pid);
  344. int r = kill(processes[j].pid, SIGKILL);
  345. if (r != 0) {
  346. printf("kill of pid=%d failed:%d\n", processes[j].pid, errno);
  347. } else {
  348. k++;
  349. }
  350. }
  351. }
  352. printf("total kill process count: %d\n", k);
  353. }
  354. #else
  355. TOOLKIT_API void osutil_terminate_related_process(char** process_array, const int array_size, int force)
  356. {
  357. DIR* dir_proc = NULL;
  358. struct dirent* dir_entity = NULL;
  359. int i = 0;
  360. int count = 0;
  361. char cmdLinePath[DEFAULT_PROCESS_CMDLINE_SIZE] = { 0 };
  362. char processName[DEFAULT_PROCESS_NAME_SIZE] = { 0 };
  363. char processPath[DEFAULT_PROCESS_PATH_SIZE] = { 0 };
  364. const pid_t cur_pid = getpid();
  365. dir_proc = opendir("/proc/");
  366. if (dir_proc == NULL) {
  367. goto finished;
  368. }
  369. while ((dir_entity = readdir(dir_proc))) {
  370. if (dir_entity->d_type == DT_DIR) {
  371. if (is_num(dir_entity->d_name)) {
  372. pid_t pid = (pid_t)atoi(dir_entity->d_name);
  373. if (pid == getpid()) {
  374. continue;
  375. }
  376. strcpy(cmdLinePath, "/proc/");
  377. strcat(cmdLinePath, dir_entity->d_name);
  378. strcat(cmdLinePath, "/cmdline");
  379. FILE* fd_cmdline = fopen(cmdLinePath, "rt");
  380. if (fd_cmdline != NULL) {
  381. memset(processName, 0, DEFAULT_PROCESS_NAME_SIZE);
  382. memset(processPath, 0, DEFAULT_PROCESS_PATH_SIZE);
  383. fscanf(fd_cmdline, "%s", processPath);
  384. fclose(fd_cmdline);
  385. if (strrchr(processPath, '/')) {
  386. strcpy(processName, strrchr(processPath, '/') + 1);
  387. } else {
  388. strcpy(processName, processPath);
  389. }
  390. for (i = 0; i < array_size; i++) {
  391. if (strcasecmp(processName, process_array[i]) == 0) {
  392. printf("kill %s, %s, %d, %d, type: %s\n", processPath, processName, pid, cur_pid, !!force ? "SIGKILL" : "SIGTERM");
  393. int r = kill(pid, !!force ? SIGKILL : SIGTERM);
  394. if (r != 0) {
  395. printf("kill of pid=%d failed:%d\n", pid, errno);
  396. }
  397. else {
  398. Sleep(200);
  399. count++;
  400. }
  401. break;
  402. }
  403. }
  404. } else if(errno != 2) {
  405. printf("%s: open(%s) failed %d!!\n", __FUNCTION__, cmdLinePath, errno);
  406. }
  407. }
  408. }
  409. }
  410. closedir(dir_proc);
  411. finished:
  412. printf("total kill process count: %d\n", count);
  413. }
  414. #endif
  415. /*cat /ect/os-release*/
  416. TOOLKIT_API int osutil_uname(tk_utsname_t* buffer)
  417. {
  418. struct utsname buf;
  419. int r;
  420. if (buffer == NULL)
  421. return TOOLKIT_EINVAL;
  422. if (uname(&buf) == -1) {
  423. r = TOOLKIT__ERR(errno);
  424. goto error;
  425. }
  426. r = strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname));
  427. if (r == TOOLKIT_E2BIG)
  428. goto error;
  429. r = strscpy(buffer->release, buf.release, sizeof(buffer->release));
  430. if (r == TOOLKIT_E2BIG)
  431. goto error;
  432. r = strscpy(buffer->version, buf.version, sizeof(buffer->version));
  433. if (r == TOOLKIT_E2BIG)
  434. goto error;
  435. r = strscpy(buffer->machine, buf.machine, sizeof(buffer->machine));
  436. if (r == TOOLKIT_E2BIG)
  437. goto error;
  438. return 0;
  439. error:
  440. buffer->sysname[0] = '\0';
  441. buffer->release[0] = '\0';
  442. buffer->version[0] = '\0';
  443. buffer->machine[0] = '\0';
  444. return r;
  445. }
  446. TOOLKIT_API int osutil_is32r64_platform()
  447. {
  448. return 0;
  449. }
  450. TOOLKIT_API ostuile_void_ptr osutil_sure_redirect_32sys_in_wow64()
  451. {
  452. ostuile_void_ptr value = NULL;
  453. return value;
  454. }
  455. TOOLKIT_API void osutil_reset_redirect_32sys_in_wow64(ostuile_void_ptr* value)
  456. {
  457. return;
  458. }
  459. #endif
  460. TOOLKIT_API int osutil_shutdown_system()
  461. {
  462. //system("poweroff");
  463. system("shutdown -h now");
  464. return 0;
  465. }