Getting parent process id from child process

I am creating a child process using the CreateProcess API. From the child process, I need to get the parent process id.

If there is a child and a large child in my process tree. I also need to get the id of the top parent process from the big child.

+1


source to share


4 answers


You have to use Native API and GetProcAddress

to find the address NtQueryInformationProcess

.

typedef struct _PROCESS_BASIC_INFORMATION
{
    NTSTATUS ExitStatus;
    PPEB PebBaseAddress;
    ULONG_PTR AffinityMask;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
    HANDLE InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryInformationProcess(
    __in HANDLE ProcessHandle,
    __in PROCESS_INFORMATION_CLASS ProcessInformationClass,
    __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
    __in ULONG ProcessInformationLength,
    __out_opt PULONG ReturnLength
    );

PROCESS_BASIC_INFORMATION basicInfo;

NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &basicInfo, sizeof(basicInfo), NULL);
// My parent PID (*) is in basicInfo.InheritedFromUniqueProcessId

      

To get the PID of grandparent, open the parent process using the parent PID and call it NtQueryInformationProcess

again in the parent process.



Note * - Strictly speaking, the parent process (the process that created the child process) is not actually recorded. InheritedFromUniqueProcessId

just gives you the process from which the attributes were inherited. But this is very rarely a problem.

Alternatively, if you don't like the native API, use CreateToolhelp32Snapshot s TH32CS_SNAPPROCESS

, which gives you the information you need, except that you have to search through the list.

+5


source


Wj32's answer should do what you need, but I figured I would mention another way in case anyone else needs an ancestor on a different level. You can also take a snapshot, list the process tree, and traverse the ancestors until you reach the level you want to reach, as described here .

The following example gets the process ID of the parent process (the process started the current one):



// Speed up build process with minimal headers.
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN

#include <tchar.h>
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

/* Macros for prettier code. */
#ifndef MAX_PATH
#   define MAX_PATH _MAX_PATH
#endif

// Search each process in the snapshot for id.
BOOL FindProcessID(HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe)
{
    BOOL fOk;
    ppe->dwSize = sizeof(PROCESSENTRY32);
    for (fOk = Process32First( snap, ppe ); fOk; fOk = Process32Next( snap, ppe ))
        if (ppe->th32ProcessID == id)
            break;
    return fOk;
}

// Obtain the process and thread identifiers of the parent process.
BOOL ParentProcess(LPPROCESS_INFORMATION ppi)
{
    HANDLE hSnap;
    PROCESSENTRY32 pe;
    THREADENTRY32   te;
    DWORD id = GetCurrentProcessId();
    BOOL fOk;

    hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD, id );

    if (hSnap == INVALID_HANDLE_VALUE)
        return FALSE;

    FindProcessID( hSnap, id, &pe );
    if (!FindProcessID( hSnap, pe.th32ParentProcessID, &pe ))
    {
        CloseHandle( hSnap );
        return FALSE;
    }

    te.dwSize = sizeof(te);
    for (fOk = Thread32First( hSnap, &te ); fOk; fOk = Thread32Next( hSnap, &te ))
        if (te.th32OwnerProcessID == pe.th32ProcessID)
            break;

    CloseHandle( hSnap );

    ppi->dwProcessId = pe.th32ProcessID;
    ppi->dwThreadId = te.th32ThreadID;

    return fOk;
}

int _tmain(int argc, _TCHAR* argv[])
{
    PROCESS_INFORMATION parentInformation;
    if(!ParentProcess(&parentInformation)) {
        _tprintf(TEXT("Fatal: Could not get parent information.\n"));
        return 1;
    }
    _tprintf(TEXT("Parent Process ID: %ul\n"), parentInformation.dwProcessId);
    return 0;
}

      

+1


source


AFAIK, there is no standard way to find the grandparent process of the current process. Searching for parent process is normal, but not grandparents. If you really need this information, the parenting process should educate their child in their own parenting process - rather like in real life, when parents should teach their children about life in general.

How communication occurs depends on whether the process is just replication (forking) or if it is running another process. If the processes are just forked, the parent just has to set the appropriate variable. If processes are executed by other programs, you need to look at the environment variable or command line argument to pass information

0


source


Here is a C program to get the parent process id (just one loop for processes in general). The GetParentProcessId () function returns the parent Windows process ID in its original parent_process_id parameter.

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

// Find a process with a given id in a snapshot
BOOL FindProcessID(HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe)
{
  BOOL res;
  ppe->dwSize = sizeof(PROCESSENTRY32); // (mandatory)
  res = Process32First(snap, ppe); 
  while (res) {
    if (ppe->th32ProcessID == id) {
      return TRUE;
    }
    res = Process32Next(snap, ppe);
  }
  return FALSE;
}

// Get the parent process id of the current process
BOOL GetParentProcessId(DWORD* parent_process_id)
{
  HANDLE hSnap;
  PROCESSENTRY32 pe;
  DWORD current_pid = GetCurrentProcessId();

  // Take a snapshot of all Windows processes
  hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if (INVALID_HANDLE_VALUE == hSnap) {
    return FALSE;
  }

  // Find the current process in the snapshot
  if (!FindProcessID(hSnap, current_pid, &pe)) {
    return FALSE;
  }

  // Close the snapshot
  if (!CloseHandle(hSnap)) {
    return FALSE;    
  }

  *parent_process_id = pe.th32ParentProcessID;
  return TRUE;
}

      

0


source







All Articles