windows.h中的WINVER和_WIN32_WINNT警卫怎么了?

Ros*_*der 8 windows winapi visual-c++

使用Windows标头中,Microsoft声称_WIN32_WINNT和NTDDI_VERSION可用于防止为较新版本的Windows定义API函数.然而,这似乎并非普遍适用.

例如,CancelSynchronousIo需要Vista或更高版本,但在我拥有的两个版本的Windows SDK(v6.0和v7.1)中根本没有保护它.

WINBASEAPI
BOOL
WINAPI
CancelIoEx(
    __in HANDLE hFile,
    __in_opt LPOVERLAPPED lpOverlapped
    );
Run Code Online (Sandbox Code Playgroud)

与此同时,GetVolumeInformationByHandleW(也需要Vista)可以像您预期的那样得到保护:

#if(_WIN32_WINNT >= 0x0600)
WINBASEAPI
BOOL
WINAPI
GetVolumeInformationByHandleW(
    __in      HANDLE hFile,
    __out_ecount_opt(nVolumeNameSize) LPWSTR lpVolumeNameBuffer,
    __in      DWORD nVolumeNameSize,
    __out_opt LPDWORD lpVolumeSerialNumber,
    __out_opt LPDWORD lpMaximumComponentLength,
    __out_opt LPDWORD lpFileSystemFlags,
    __out_ecount_opt(nFileSystemNameSize) LPWSTR lpFileSystemNameBuffer,
    __in      DWORD nFileSystemNameSize
    );
#endif /* _WIN32_WINNT >=  0x0600 */
Run Code Online (Sandbox Code Playgroud)

这种事情只是一个错误吗?_WIN32_WINT卫兵没用吗?任何人都可以推荐一种可靠的方法来确定哪个版本的Windows引入了哪些API函数?

编辑添加:

这是一个测试.foo.h包含:

#include <windows.h>
Run Code Online (Sandbox Code Playgroud)

然后运行:

cl /E /D_WIN32_WINNT=0x0501 /DNTDDI_VERSION=0x05010000 foo.h | grep CancelSynchronousIo
Run Code Online (Sandbox Code Playgroud)

我的期望是我没有输出,而是定义了CancelSynchronousIo.

Han*_*ant 7

这是一个错误.参考示例在这里这里.一些次要证据表明Longhorn项目确实是一个非常困难的项目.Windows团队没有像DevDiv那样接受反馈,很难修复错误.您可以在MSDN Library页面的底部留下注释.

  • 所以我决定做一个小实验.从kernel32导出有*数百*个错误保护的函数.详情:http://www.kndr.org/windows-sdk-brokenness (3认同)