Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.6k views
in Technique[技术] by (71.8m points)

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

I'm working under the VS2013 ARM Developer Prompt. I'm trying to use Microsoft's Cryptography Next Generation (CNG), but I'm experiencing some non-trivial problems.

I'm trying to compile a simple test program:

#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;
}

I attempt to compile it with:

C:UsersTest>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

When I attempt to include <ntstatus.h> (scrapped from PJ Naughter's blog because I can't seem to find anything useful from 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 Kits8.1includeshared
tstatus.h(66) : warning
C4005: 'STATUS_WAIT_0' : macro redefinition
        C:Program Files (x86)Windows Kits8.1includeumwinnt.h(2202) : see p
revious definition of 'STATUS_WAIT_0'
C:Program Files (x86)Windows Kits8.1includeshared
tstatus.h(212) : warning
 C4005: 'STATUS_ABANDONED_WAIT_0' : macro redefinition
        C:Program Files (x86)Windows Kits8.1includeumwinnt.h(2203) : see p
revious definition of 'STATUS_ABANDONED_WAIT_0'
C:Program Files (x86)Windows Kits8.1includeshared
tstatus.h(235) : warning
 C4005: 'STATUS_USER_APC' : macro redefinition
...

I can't make it a LONG because Microsoft macros like BCRYPT_SUCCESS cast it to a NTSTATUS code.

I can also duplicate the missing NTSTATUS problem under VS2012 ARM Developer Prompt.

What header file should I include to get a declaration for NTSTATUS under ARM?


I think this might be related, but I'm not certain: fatal error LNK1104: cannot open file 'bcrypt.lib' when building for Surface RT tablet. About all I know is this stuff does not appear to be well tested by Microsoft because there are too many damn problems trying to use it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The main issue is that BCRYPT is supported for the Universal Windows Platform apps (aka Windows 10 Store apps), but was not supported for Windows 8.x Store apps. VS 2013 toolset always uses the Windows 8.1 SDK so you were building a Windows 8.1 Store app. When you tried VS 2012, you were using the Windows 8.0 SDK so you were building a Windows 8.0 Store apps. Again, neither of this support BCRYPT. If you build with VS 2015 and have the Windows 10 SDK installed, then your code builds fine.

Note that /D_MBCS is not an option for Windows Store apps. All Windows Store apps should be built for Unicode /DUNICODE /D_UNICODE and not ANSI/Multibyte as you were trying to do.

Also, be sure to link with windowsapp.lib to make sure you pick up the correct DLLs when you link.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...