可以编辑 GCC 头文件吗?

Is it OK to Edit GCC Header Files?

我试图在 Windows 7 上使用 GCC 从 MSDN 编译一些示例代码(请忽略 goto 的使用和糟糕的格式;这不是我的代码):

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

typedef struct _TOKEN_ELEVATION {
    DWORD TokenIsElevated;
} TOKEN_ELEVATION, *PTOKEN_ELEVATION;

BOOL IsProcessElevated()
{
BOOL fIsElevated = FALSE;
DWORD dwError = ERROR_SUCCESS;
HANDLE hToken = NULL;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
    dwError = GetLastError();
    goto Cleanup;
}

TOKEN_ELEVATION elevation;
DWORD dwSize;
if (!GetTokenInformation(hToken, TokenElevation, &elevation,
    sizeof(elevation), &dwSize))
{
    dwError = GetLastError();
    goto Cleanup;
}
fIsElevated = elevation.TokenIsElevated;

Cleanup:
if (hToken)
{
    CloseHandle(hToken);
    hToken = NULL;
}
if (ERROR_SUCCESS != dwError)
{
    throw dwError;
}
return fIsElevated;
}

int main()
{
try
{
    if (IsProcessElevated())
        wprintf (L"Process is elevated\n");
    else
        wprintf (L"Process is not elevated\n");
}
catch (DWORD dwError)
{
    wprintf(L"IsProcessElevated failed w/err %lu\n", dwError);
}
}

我一直收到错误 TokenElevation was not declared in this scope。在尝试弄清楚时,我看到 TOKEN_INFORMATION_CLASS 结构的 TokenElevation 成员位于两个 #ifdef 标记之间:

typedef enum _TOKEN_INFORMATION_CLASS {
TokenUser=1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
//#if (_WIN32_WINNT >= 0x0600)
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
//#endif
MaxTokenInfoClass
} TOKEN_INFORMATION_CLASS;

我注释掉了这些并且编译的代码没有错误或警告。我的问题实际上是两个问题。他们是更好的方法来做到这一点吗(在我的代码中定义一些东西?)并且,从长远来看 运行,编辑头文件会伤害我吗?

是的,您可以编辑和更改 GCC 头文件。

请注意,当 GCC 升级时,您的更改可能会丢失。您必须将更改合并到较新的头文件中。

因此,一般的经验法则是不要修改编译器头文件。

编辑 1:
此外,如果您共享您的代码,您将需要让客户对您所做的 GCC 头文件进行相同的修改。一些客户可能不想更改他们的编译器头文件。当你有其他人在同一个项目上工作时,同样的规则适用。

另外,你的改动会影响以后的项目吗?未来的项目也可能使用 GCC 头文件。

编辑 headers 会造成伤害,因为您的代码不再是针对您仅依赖的外部库构建的。相反,您已经有效地使该外部代码成为项目的一部分,现在您必须像管理项目中的其他源代码一样管理它。例如,您应该将其保存在您的版本控制系统中。

是的,有更好的方法:您可以简单地定义 _WIN32_WINNT,因为 Windows 代码希望它被定义。 Visual Studio 项目默认定义此宏,但在 Windows.

上使用 gcc 构建时必须手动执行此操作

This page 定义 Windows.

每个版本的值

您可以修改它们,但这通常是个坏主意,因为这会使您的编译难以重复。

在这种特殊情况下,正确的解决方案是将 _WIN32_WINNT 定义为 0x0600 或更高。此宏用于指定您的目标 Windows 版本,并且您显然至少目标是版本 6,否则您将无法使用此值。 Windows SDK 头文件使用此宏有条件地包含每个版本 Windows 中可用的声明,因此您不能在程序中使用 Windows 8 中的 function/field/enum 值运行 以 Windows 7 为例。

所以只需将 -D_WIN32_WINNT=0x0600 添加到您的编译命令中,而不要管头文件...