ntqueryinformationprocess (ntdll)
Last changed: -186.136.223.176

.
Summary
Retrieves information about the specified process. This function is available in Windows 2000 and Windows XP, but it may be altered or unavailable in subsequent versions.

C# Signature:

[DllImport("ntdll.dll", SetLastError=true)]
static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, IntPtr processInformation, uint processInformationLength, IntPtr returnLength);

or:

[DllImport("NTDLL.DLL", SetLastError=true)]
static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, out int pSize);

or:

[DllImport("ntdll.dll", PreserveSig = false, SetLastError = true)]
public static extern void NtQueryInformationProcess(IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, out PROCESS_EXTENDED_BASIC_INFORMATION ProcessInformation, uint ProcessInformationLength, out uint ReturnLength);

VB Signature:

Declare Function NtQueryInformationProcess Lib "ntdll.dll" ( _
   processHandle As IntPtr, processInformationClass As Integer, _
   processInformation As IntPtr, processInformationLength As Integer, _
   returnLength As IntPtr) As Integer

User-Defined Types:

PROCESSINFOCLASS, PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION

Notes:

See also OpenProcess, CloseHandle.

Tips & Tricks:

Please add some!

Sample Code:

    public static IntPtr GetPEBAddress()
    {
        //Get a handle to our own process
        IntPtr hProc = OpenProcess(0x001F0FFF, false, Process.GetCurrentProcess().Id);
        //Allocate memory for a new PROCESS_BASIC_INFORMATION structure
        IntPtr pbi = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)));
        //Allocate memory for a long
        IntPtr outLong = Marshal.AllocHGlobal(sizeof(long));
        IntPtr outPtr = IntPtr.Zero;

        int queryStatus = false;

        //Store API call success in a boolean
        queryStatus = NtQueryInformationProcess(hProc, 0, pbi, (uint)Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), outLong);

        //Close handle and free allocated memory
        CloseHandle(hProc);
        Marshal.FreeHGlobal(outLong);

        //STATUS_SUCCESS = 0, so if API call was successful querySuccess should contain 0 ergo we reverse the check.
        if(!queryStatus )
        outPtr = PtrToStructure<PROCESS_BASIC_INFORMATION>(pbi, typeof(PROCESS_BASIC_INFORMATION)).PebBaseAddress;

        //Free allocated space
        Marshal.FreeHGlobal(pbi);

        //Return pointer to PEB base address
        return outPtr;
    }

Or:

    public static int GetParentProcessId()
    {
        PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();

        //Get a handle to our own process
        IntPtr hProc = OpenProcess((ProcessAccessFlags)0x001F0FFF, false, Process.GetCurrentProcess().Id);

        try
        {
            int sizeInfoReturned;
            int queryStatus = NtQueryInformationProcess(hProc, (PROCESSINFOCLASS)0, ref pbi, pbi.Size, out sizeInfoReturned);
        }
        finally
        {
            if (!hProc.Equals(IntPtr.Zero))
            {
            //Close handle and free allocated memory
            CloseHandle(hProc);
            hProc = IntPtr.Zero;
            }
        }

        return (int)pbi.InheritedFromUniqueProcessId;
    }

Alternative Managed API:

Do you know one? Please contribute it!

Documentation