That would a function pointer typedef
, which defines the type QUERYINFORMATIONPROCESS
as an alias for this type:
NTSTATUS(NTAPI*)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
When used as in the example,
QUERYINFORMATIONPROCESS QueryInformationProcess =
(QUERYINFORMATIONPROCESS)GetProcAddress(
hDll, "NtQueryInformationProcess");
it expands into something like this:
NTSTATUS(NTAPI* QueryInformationProcess)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
) =
(NTSTATUS(NTAPI*)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
))GetProcAddress(hDll, "NtQueryInformationProcess");
(Not 100% sure if that's the correct expansion, I find function pointers awkward in general.)
Function pointer typedefs are used because function pointer syntax is really awkward in and of itself, while function pointer aliases like that use the standard syntax.
For more information on function pointers, see this answer.
Moreover, it's a pointer to a Windows function, which uses standard Windows identifiers (NTSTATUS, NTAPI, IN, OUT, HANDLE, PROCESSINFOCLASS, PVOID, ULONG, and PULONG).
According to Windows files, these identifiers are:
// ntdef.h
typedef __success(return >= 0) LONG NTSTATUS;
// See https://stackoverflow.com/questions/3378622/how-to-understand-the-ntstatus-nt-success-typedef-in-windows-ddk
// WinNT.h
#define NTAPI __stdcall
// __stdcall is a Windows calling convention, used by Visual Studio when compiling Windows code.
typedef void *PVOID;
#ifdef STRICT
typedef void *HANDLE;
#if 0 && (_MSC_VER > 1000)
#define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name
#else
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
#endif
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
// WinDef.h
typedef unsigned long ULONG;
typedef ULONG *PULONG;
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
IN and OUT are used as programmer aids, while the types are to give programmers a consistent interface. Not entirely sure about PROCESSINFOCLASS
; it seems to be defined in ntdll.dll
, along with NtQueryInformationProcess
itself. According to this MSDN thread, it's defined as follows:
private enum PROCESSINFOCLASS : int
{
ProcessBasicInformation = 0,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
MaxProcessInfoClass
} ;
This appears to be outdated, but this site seems to have a more recent version, which appears to be consistent with official MS NtQueryInformationProcess() documentation.
Hope this helps.