"Fossies" - the Fresh Open Source Software Archive

Member "mumble-1.3.2/overlay/ancestor.cpp" (9 Jul 2020, 3108 Bytes) of package /linux/misc/mumble-1.3.2.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 "ancestor.cpp" see the Fossies "Dox" file reference documentation.

    1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license
    3 // that can be found in the LICENSE file at the root of the
    4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
    5 
    6 #include "lib.h"
    7 
    8 #include <tlhelp32.h>
    9 
   10 #include <string>
   11 #include <vector>
   12 
   13 /// Find the PROCESSENTRY32 entry for the parent of the process with the |childpid| PID.
   14 ///
   15 /// Returns true on success, and fills out |parent| with the correct PROCESSENTRY32.
   16 /// Returns false on failure, and does not touch |parent|.
   17 static bool findParentProcessForChild(DWORD childpid, PROCESSENTRY32 *parent) {
   18     DWORD parentpid = 0;
   19     HANDLE hSnap = NULL;
   20     bool done = false;
   21 
   22     PROCESSENTRY32 pe;
   23     pe.dwSize = sizeof(pe);
   24 
   25     MODULEENTRY32 me;
   26     me.dwSize = sizeof(me);
   27 
   28     // Find our parent's process ID.
   29     {
   30         BOOL ok = FALSE;
   31 
   32         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   33         if (hSnap == INVALID_HANDLE_VALUE) {
   34             return false;
   35         }
   36         ok = Process32First(hSnap, &pe);
   37         while (ok) {
   38             if (pe.th32ProcessID == childpid) {
   39                 parentpid = pe.th32ParentProcessID;
   40                 break;
   41             }
   42             ok = Process32Next(hSnap, &pe);
   43         }
   44         CloseHandle(hSnap);
   45     }
   46 
   47     if (parentpid == 0) {
   48         return false;
   49     }
   50 
   51     // Find our parent's name.
   52     {
   53         BOOL ok = FALSE;
   54 
   55         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   56         if (hSnap == INVALID_HANDLE_VALUE) {
   57             return false;
   58         }
   59         ok = Process32First(hSnap, &pe);
   60         while (ok) {
   61             if (pe.th32ProcessID == parentpid) {
   62                 memcpy(parent, &pe, sizeof(pe));
   63                 ok = FALSE;
   64                 done = true;
   65                 break;
   66             }
   67             ok = Process32Next(hSnap, &pe);
   68         }
   69         CloseHandle(hSnap);
   70     }
   71 
   72     return done;
   73 }
   74 
   75 /// Find the MODULEENTRY32 for the PROCESSENTRY32 |parent|.
   76 /// The MODULEENTRY32 allows us to access the absolute path of the parent executable.
   77 ///
   78 /// Returns true on success, and fills out |module| with the proper MODULEENTRY32 entry.
   79 /// Returns false on failure, and does not touch |module|.
   80 static bool getModuleForParent(PROCESSENTRY32 *parent, MODULEENTRY32 *module) {
   81     HANDLE hSnap = NULL;
   82     bool done = false;
   83 
   84     MODULEENTRY32 me;
   85     me.dwSize = sizeof(me);
   86 
   87     hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32 | TH32CS_SNAPMODULE, parent->th32ProcessID);
   88     if (hSnap == INVALID_HANDLE_VALUE) {
   89         goto out;
   90     }
   91 
   92     if (!Module32First(hSnap, &me)) {
   93         goto out;
   94     }
   95 
   96     memcpy(module, &me, sizeof(me));
   97     done = true;
   98 
   99 out:
  100     CloseHandle(hSnap);
  101     return done;
  102 }
  103 
  104 bool GetProcessAncestorChain(std::vector<std::string> &absAncestorExeNames, std::vector<std::string> &ancestorExeNames) {
  105     PROCESSENTRY32 parent;
  106     MODULEENTRY32 module;
  107 
  108     std::vector<std::string> abs;
  109     std::vector<std::string> rel;
  110 
  111     bool ok = true;
  112     DWORD childpid = GetCurrentProcessId();
  113     while (ok) {
  114         ok = findParentProcessForChild(childpid, &parent);
  115         if (ok) {
  116             ok = getModuleForParent(&parent, &module);
  117             if (ok) {
  118                 abs.push_back(std::string(module.szExePath));
  119                 rel.push_back(std::string(parent.szExeFile));
  120                 childpid = parent.th32ProcessID;
  121             }
  122         }
  123     }
  124 
  125     ok = abs.size() > 0;
  126     if (ok) {
  127         absAncestorExeNames = abs;
  128         ancestorExeNames = rel;
  129     }
  130 
  131     return ok;
  132 }