我不确定如何阅读此代码:
typedef NTSTATUS(NTAPI* QUERYINFORMATIONPROCESS)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTSTATUS
或QUERYINFORMATIONPROCESS
是typedef
的名称吗?如果是这样,实际类型是什么?这是一个函数指针类型吗?用法是:
QUERYINFORMATIONPROCESS QueryInformationProcess =
(QUERYINFORMATIONPROCESS)GetProcAddress(
hDll, "NtQueryInformationProcess");
if (QueryInformationProcess)
{
NTSTATUS ntStatus = QueryInformationProcess(
processInformation.hProcess,
PROCESSINFOCLASS::ProcessBasicInformation,
&pbi, sizeof(pbi), &uLength);
[…]
这来自“C ++ Multithreading Cookbook”,它没有解释这段代码。感谢您的帮助!
答案 0 :(得分:4)
typedef NTSTATUS(NTAPI* QUERYINFORMATIONPROCESS)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
这里的难点在于这是一个函数指针:
当声明一个函数指针时,为了将它与返回指针的函数区分开来,我们需要围绕它的括号括起来:
(*QUERYINFORMATIONPROCESS)
指针之前的NTAPI告诉编译器调用约定(如何传递参数[寄存器,堆栈,参数的顺序],如何完成参数的清理等)。
剩下的东西只是返回类型(NTSTATUS
)和函数的参数。
一个更简单的例子是:
typedef int (*funcptr)(int x);
现在,相对容易看出它是一个返回int
的函数,它是指向函数的指针,并且它采用的是一个参数int x
。
答案 1 :(得分:3)
在没有Microsoft宏的情况下编写它,它是
typedef NTSTATUS (*QUERYINFORMATIONPROCESS)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);
这是一个名为" QUERYINFORMATIONPROCESS"的函数指针类型。
具体来说,它是指向NtQueryInformationProcess的指针,需要从DLL加载。
(看来你的书的作者有拼写问题。)
答案 2 :(得分:1)
它是指向函数的指针的typedef,称为QUERYINFORMATIONPROCESS。此函数需要5个参数,并返回NTSTATUS。
答案 3 :(得分:1)
有一条规则可以帮助阅读称为Clockwise/Spiral规则的详细类型定义。该规则是一个三步算法,引用原始文章的步骤是:
通常有用的是知道哪个标识符对应于类型以识别未知元素(可能存在多个这样的元素)。在您的情况下 - 了解所有(NTSTATUS
,NTAPI
,HANDLE
,PROCESSINFOCLASS
,PVOID
,ULONG
,PULONG
)是类型。
本文提供了有关应用规则的有用示例。
识别未知元素:
void
是一种类型signal
,嗯,看起来像一个未知元素。此外,它是
位于星号的右侧,就我而言,不能是变量/ typedef名称int
,void
- types fp
,第二个未知元素(请记住,我之前提到过可能有多个未知元素)int
,int
- types 现在首先应用最左边未知元素的规则,即signal
:
signal
向右移动并遇到第一个左括号:signal
是一个带有int
的功能和精心设计的功能fp
,它也是signal
的第二个参数。从fp
顺时针旋转并遇到右括号,然后是星号:fp
是指向某个东西的指针。*fp
移动并遇到左括号:fp
是一个指向函数的指针,该函数采用int
并返回一些内容。void
:fp
是一个指向int
并返回void
的函数的指针。signal
:signal
是一个函数,它采用int, and a pointer to a function taking an
int and returning
void` signal(
移动并遇到星号:signal
是一个返回指针的函数... (*
移动并遇到最右边的左括号:signal
是一个函数(我在这里省略了参数)返回指向函数的指针int
void
:signal
是一个函数(我在这里省略了参数)返回指向函数的指针,该函数采用int
并返回{{1} }。 P.S。您的问题中的typedef可以使用void
声明用现代C ++编写:
using
它没有太大变化,但using QUERYINFORMATIONPROCESS = NTSTATUS(NTAPI*)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
与实际定义有更多分离,使其更具可读性。在编写新代码时,请考虑使用typedef-name
代替using
: - )
答案 4 :(得分:0)
这将是一个函数指针typedef
,它将类型QUERYINFORMATIONPROCESS
定义为此类型的别名:
NTSTATUS(NTAPI*)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
如示例所示,
QUERYINFORMATIONPROCESS QueryInformationProcess =
(QUERYINFORMATIONPROCESS)GetProcAddress(
hDll, "NtQueryInformationProcess");
它扩展成这样的东西:
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");
(不是100%肯定,如果这是正确的扩展,我发现函数指针一般都很尴尬。)
使用函数指针typedef是因为函数指针语法实际上本身就是笨拙的,而像这样的函数指针别名使用标准语法。
有关函数指针的更多信息,请参阅this answer。
此外,它是一个Windows功能的指针,它使用标准的Windows标识符(NTSTATUS,NTAPI,IN,OUT,HANDLE,PROCESSINFOCLASS,PVOID,ULONG和PULONG)。
根据Windows文件,这些标识符为:
// 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和OUT用作程序员辅助,而类型是为程序员提供一致的界面。不完全确定PROCESSINFOCLASS
;它似乎在ntdll.dll
中定义,与NtQueryInformationProcess
本身一起定义。根据{{3}},它的定义如下:
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 MSDN thread似乎有更新版本,似乎与this site一致。
希望这有帮助。