"Fossies" - the Fresh Open Source Software Archive

Member "seafile-client-7.0.4/src/utils/process-win.cpp" (19 Nov 2019, 4979 Bytes) of package /linux/www/seafile-client-7.0.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "process-win.cpp" see the Fossies "Dox" file reference documentation.

    1 #ifndef _WIN32_WINNT
    2 #define _WIN32_WINNT 0x0501
    3 #endif
    4 #include <windows.h>
    5 #include <psapi.h>
    6 
    7 #include <assert.h>
    8 #include <errno.h>
    9 #include <dirent.h>
   10 #include <stdio.h>
   11 #include <stdlib.h>
   12 #include <string.h>
   13 #include <string>
   14 
   15 #include <QList>
   16 
   17 #include "process.h"
   18 
   19 namespace {
   20 
   21 /// always ignore current process
   22 HANDLE
   23 get_process_handle (const char *process_name_in)
   24 {
   25     char name[256];
   26     if (strstr(process_name_in, ".exe")) {
   27         snprintf (name, sizeof(name), "%s", process_name_in);
   28     } else {
   29         snprintf (name, sizeof(name), "%s.exe", process_name_in);
   30     }
   31 
   32     DWORD aProcesses[1024], cbNeeded, cProcesses;
   33 
   34     if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
   35         return NULL;
   36 
   37     /* Calculate how many process identifiers were returned. */
   38     cProcesses = cbNeeded / sizeof(DWORD);
   39 
   40     HANDLE hProcess;
   41     DWORD hCurrentProcessId = GetCurrentProcessId();
   42     unsigned int i;
   43     DWORD length;
   44 
   45     for (i = 0; i < cProcesses; i++) {
   46         if(aProcesses[i] == 0 || aProcesses[i] == hCurrentProcessId)
   47             continue;
   48         hProcess = OpenProcess (PROCESS_QUERY_INFORMATION |
   49                                 PROCESS_TERMINATE |
   50                                 PROCESS_VM_READ |
   51                                 SYNCHRONIZE , FALSE, aProcesses[i]);
   52         if (!hProcess)
   53             continue;
   54 
   55         char process_name[4096] = {0};
   56 
   57         // The GetProcessImageFileName function returns the path in device form, rather than drive letters
   58         // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683196%28v=vs.85%29.aspx
   59         // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217%28v=vs.85%29.aspx
   60         if (!(length = GetProcessImageFileName(hProcess, process_name, sizeof(process_name)))) {
   61             CloseHandle(hProcess);
   62             continue;
   63         }
   64         char *basename = strrchr(process_name, '\\');
   65         length -= (basename - process_name);
   66 
   67         // if basename doesn't start with `\` or not mached
   68         if (*basename != '\\' ||
   69             strncasecmp(name, ++basename, length) != 0) {
   70             CloseHandle(hProcess);
   71             continue;
   72         }
   73 
   74         return hProcess;
   75     }
   76     /* Not found */
   77     return NULL;
   78 }
   79 
   80 int
   81 win32_kill_process (const char *process_name)
   82 {
   83     HANDLE proc_handle = get_process_handle(process_name);
   84 
   85     if (proc_handle) {
   86         TerminateProcess(proc_handle, 0);
   87         CloseHandle(proc_handle);
   88         return 0;
   89     } else {
   90         return -1;
   91     }
   92 }
   93 
   94 
   95 } // namespace
   96 
   97 int
   98 process_is_running (const char *process_name)
   99 {
  100     HANDLE proc_handle = get_process_handle(process_name);
  101 
  102     if (proc_handle) {
  103         CloseHandle(proc_handle);
  104         return TRUE;
  105     } else {
  106         return FALSE;
  107     }
  108 }
  109 
  110 void shutdown_process (const char *name)
  111 {
  112     while (win32_kill_process(name) >= 0) ;
  113 }
  114 
  115 // Return the number of processes with the given executable name, and also
  116 // return the list of pids of them (except the current process, if it mathces)
  117 static int count_process_internal (const char *process_name_in, QList<uint64_t> *pids)
  118 {
  119     char name[MAX_PATH];
  120     DWORD aProcesses[1024], cbNeeded, cProcesses;
  121     HANDLE hProcess;
  122     DWORD length;
  123     int count = 0;
  124     DWORD i;
  125     DWORD hCurrentProcessId = GetCurrentProcessId();
  126 
  127     if (strstr(process_name_in, ".exe")) {
  128         snprintf (name, sizeof(name), "%s", process_name_in);
  129     } else {
  130         snprintf (name, sizeof(name), "%s.exe", process_name_in);
  131     }
  132 
  133     if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
  134         return 0;
  135     }
  136 
  137     /* Calculate how many process identifiers were returned. */
  138     cProcesses = cbNeeded / sizeof(DWORD);
  139 
  140     for (i = 0; i < cProcesses; i++) {
  141         if(aProcesses[i] == 0)
  142             continue;
  143         hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
  144         if (!hProcess) {
  145             continue;
  146         }
  147 
  148         char process_name[4096] = {0};
  149         if (!(length = GetProcessImageFileName(hProcess, process_name, sizeof(process_name)))) {
  150             CloseHandle(hProcess);
  151             continue;
  152         }
  153         char *basename = strrchr(process_name, '\\');
  154         length -= (basename - process_name);
  155 
  156         // if basename doesn't start with `\` or not mached
  157         if (*basename != '\\' ||
  158             strncasecmp(name, ++basename, length) != 0) {
  159             CloseHandle(hProcess);
  160             continue;
  161         }
  162 
  163         if (pids && aProcesses[i] != hCurrentProcessId) {
  164             pids->append(aProcesses[i]);
  165         }
  166         count++;
  167         CloseHandle(hProcess);
  168     }
  169 
  170     return count;
  171 }
  172 
  173 int count_process (const char *process_name_in) {
  174     return count_process_internal(process_name_in, nullptr);
  175 }
  176 
  177 int count_process(const char *name, uint64_t *pid)
  178 {
  179     QList<uint64_t> pids;
  180     int ret = count_process_internal(name, &pids);
  181     if (pid && !pids.isEmpty()) {
  182         *pid = pids[0];
  183     }
  184     return ret;
  185 }