在为 ARM 平台构建时要为 NTSTATUS 添加什么 header?

What header to include for an NTSTATUS when building for ARM platforms?

我在 VS2013 ARM 开发人员提示下工作。我正在尝试使用 Microsoft 的下一代密码术 (CNG),但我遇到了一些 non-trivial 问题。

我正在尝试编译一个简单的测试程序:

#include <windows.h>
#include <bcrypt.h>

int main(int argc, char* argv[])
{
    BCRYPT_ALG_HANDLE hProvider = NULL;
    NTSTATUS ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        return -1;
    }

    unsigned char buffer[20];
    ret = BCryptGenRandom(hProvider, buffer, (ULONG)sizeof(buffer), 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        return -2;
    }

    ret = BCryptCloseAlgorithmProvider(hProvider, 0);
    if (!(BCRYPT_SUCCESS(ret)))
    {
        return -3;
    }

    return 0;
}

我尝试编译它:

C:\Users\Test>cl.exe /nologo /W4 /D_MBCS /Zi /TP /EHs c /MD /FI sdkddkver.h /FI winapifamily.h /DWINAPI_FAMILY=WINAPI_FAMILY_APP /c test.cxx
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for ARM
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cxx
test.cxx(6) : error C2065: 'BCRYPT_ALG_HANDLE' : undeclared identifier
test.cxx(6) : error C2146: syntax error : missing ';' before identifier 'hProvid
er'
test.cxx(6) : error C2065: 'hProvider' : undeclared identifier
test.cxx(7) : error C2065: 'NTSTATUS' : undeclared identifier
test.cxx(7) : error C2146: syntax error : missing ';' before identifier 'ret'
test.cxx(7) : error C2065: 'ret' : undeclared identifier
test.cxx(7) : error C2065: 'hProvider' : undeclared identifier
test.cxx(7) : error C2065: 'BCRYPT_RNG_ALGORITHM' : undeclared identifier
test.cxx(7) : error C2065: 'MS_PRIMITIVE_PROVIDER' : undeclared identifier
test.cxx(7) : error C3861: 'BCryptOpenAlgorithmProvider': identifier not found
test.cxx(8) : error C2065: 'ret' : undeclared identifier
test.cxx(8) : error C3861: 'BCRYPT_SUCCESS': identifier not found
test.cxx(14) : error C2065: 'ret' : undeclared identifier
test.cxx(14) : error C2065: 'hProvider' : undeclared identifier
test.cxx(14) : error C3861: 'BCryptGenRandom': identifier not found
test.cxx(15) : error C2065: 'ret' : undeclared identifier
test.cxx(15) : error C3861: 'BCRYPT_SUCCESS': identifier not found
test.cxx(20) : error C2065: 'ret' : undeclared identifier
test.cxx(20) : error C2065: 'hProvider' : undeclared identifier
test.cxx(20) : error C3861: 'BCryptCloseAlgorithmProvider': identifier not found

test.cxx(21) : error C2065: 'ret' : undeclared identifier
test.cxx(21) : error C3861: 'BCRYPT_SUCCESS': identifier not found

当我尝试包含 <ntstatus.h> 时(从 PJ Naughter's blog 中删除,因为我似乎无法从 Microsoft 找到任何有用的信息):

cl.exe /nologo /W4 /D_MBCS /Zi /TP /EHsc /MD /FI sdkddkver.h /FI winapifamily.h /DWINAPI_FAMILY=WINAPI_FAMILY_APP /c osrng.cpp
osrng.cpp
C:\Program Files (x86)\Windows Kits.1\include\shared\ntstatus.h(66) : warning
C4005: 'STATUS_WAIT_0' : macro redefinition
        C:\Program Files (x86)\Windows Kits.1\include\um\winnt.h(2202) : see p
revious definition of 'STATUS_WAIT_0'
C:\Program Files (x86)\Windows Kits.1\include\shared\ntstatus.h(212) : warning
 C4005: 'STATUS_ABANDONED_WAIT_0' : macro redefinition
        C:\Program Files (x86)\Windows Kits.1\include\um\winnt.h(2203) : see p
revious definition of 'STATUS_ABANDONED_WAIT_0'
C:\Program Files (x86)\Windows Kits.1\include\shared\ntstatus.h(235) : warning
 C4005: 'STATUS_USER_APC' : macro redefinition
...

我无法将其设为 LONG,因为 BCRYPT_SUCCESS 等 Microsoft 宏将其转换为 NTSTATUS 代码。

我也可以在 VS2012 ARM Developer Prompt 下复制丢失的 NTSTATUS 问题。

我应该包含什么 header 文件以获得 ARM 下 NTSTATUS 的声明?


认为这可能是相关的,但我不确定:fatal error LNK1104: cannot open file 'bcrypt.lib' when building for Surface RT tablet。据我所知,这些东西似乎没有经过 Microsoft 的良好测试,因为尝试使用它时遇到了太多该死的问题。

主要问题是通用 Windows 平台应用程序(又名 Windows 10 商店应用程序)支持 BCRYPT,但 支持Windows 8.x 商店应用程序。 VS 2013 工具集始终使用 Windows 8.1 SDK,因此您构建的是 Windows 8.1 Store 应用程序。当您尝试 VS 2012 时,您使用的是 Windows 8.0 SDK,因此您正在构建一个 Windows 8.0 商店应用程序。同样,这两者都不支持 BCRYPT。如果您使用 VS 2015 构建并安装了 Windows 10 SDK,那么您的代码可以正常构建。

请注意,/D_MBCS 不是 Windows 商店应用程序的选项。所有 Windows 商店应用程序都应针对 Unicode /DUNICODE /D_UNICODE 而不是您尝试做的 ANSI/Multibyte 构建。

此外,请务必 link 和 windowsapp.lib 以确保在 link 时选择正确的 DLL。

You can easily confirm that all the errors you are seeing happen in VS 2012/2013 if you do not have #include <bcrypt.h> in the file at all. The DWINAPI_FAMILY=WINAPI_FAMILY_APP ensures that all unsupported APIs are undefined, so with Windows 8.x Store that header was basically an empty file.