osutil.c 14 KB

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