VS2010 - Structure change in CryptoAPI - v7.0A Vs v6.0A - WinCrypt.h - c++

In C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinCrypt.h, the definition for CERT_CHAIN_ENGINE_CONFIG is
typedef struct _CERT_CHAIN_ENGINE_CONFIG {
DWORD cbSize;
HCERTSTORE hRestrictedRoot;
HCERTSTORE hRestrictedTrust;
HCERTSTORE hRestrictedOther;
DWORD cAdditionalStore;
HCERTSTORE* rghAdditionalStore;
DWORD dwFlags;
DWORD dwUrlRetrievalTimeout; // milliseconds
DWORD MaximumCachedCertificates;
DWORD CycleDetectionModulus;
*#if (NTDDI_VERSION >= NTDDI_WIN7)
HCERTSTORE hExclusiveRoot;
HCERTSTORE hExclusiveTrustedPeople;
#endif*
} CERT_CHAIN_ENGINE_CONFIG, *PCERT_CHAIN_ENGINE_CONFIG;
I am using visual studio 2010 in an XP sp3 machine, in which case, i expect that the following two members in the above structure gets greyed out. But this is not happening,
#if (NTDDI_VERSION >= NTDDI_WIN7)
HCERTSTORE hExclusiveRoot;
HCERTSTORE hExclusiveTrustedPeople;
#endif
NTDDI_VERSION in-turn is defined in sdkddkver.h as follows, and _WIN32_WINNT somehow takes the value of NTDDI_WIN7 which in my case is incorrect as mine is a XP SP3 machine.
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define _WIN32_WINNT 0x0601
#endif
#ifndef NTDDI_VERSION
#ifdef _WIN32_WINNT
// set NTDDI_VERSION based on _WIN32_WINNT
#define NTDDI_VERSION NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
#else
#define NTDDI_VERSION 0x06010000
#endif
#endif
The above two members of the structure CERT_CHAIN_ENGINE_CONFIG in question is not present in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\WinCrypt.hBut my 2010 visual studio project automatically pulls in the header and lib files from C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinCrypt.h Because of the conflicting structures, i am getting parameter is incorrect
Please advise how i can over come this issue?
Should i have to install visual studio 2010 sp1?
I found one reference in the web where it says initialising the structure will resolve the issue, but it will not, as the two parameters in question will not be greyed out and will be taken in while building.
UPDATE1:
Settings of my project:
$(VCInstalDir) - >C:\Program Files\Microsoft Visual Studio 10.0\VC
$(WindowsSdkDir) ->C:\Program Files\Microsoft SDKs\Windows\v7.0A
$(FrameworkSdkDir) ->C:\Program Files\Microsoft SDKs\Windows\v7.0A
Library file settings,
$(VCInstallDir)lib
$(VCInstallDir)atlmfc\lib
$(WindowsSdkDir)lib
$(FrameworkSDKDir)\lib
UPDATE 2:
My preprocessor definitions are
WIN32;_DEBUG;_WINDOWS;_USRDLL;MY_DLL_EXPORTS;%(PreprocessorDefinitions)
%(PreprocessorDefinitions) inherited values as follows
_WINDLL
_MBCS
Thanks

The problem which you have can be very easy explained. If you use v7.0A or v7.1 you are able to compile your project so that it will run under Windows 7. So the default value for the _WIN32_WINNT is 0x0601.
If you want co compile the program so that it will run on Windows XP you can define WINVER and _WIN32_WINNT explicitly. Typically one do this in the settings of the Visual Studio project inside of the preprocessor definitions. If you will do this the corresponding part of CERT_CHAIN_ENGINE_CONFIG structure will be displayed gray like you as want.
In the most cases and in the case of CERT_CHAIN_ENGINE_CONFIG it is not really needed. The Windows API are designed mostly so, that you will have no problems in the usage of CERT_CHAIN_ENGINE_CONFIG defined for Windows 7 in case of the start of the program on Windows XP. If you do define
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
(or 0x0501 instead of 0x0500) you will be able to run your program in the Windows 7, but you will be not able to use the hExclusiveRoot and the hExclusiveTrustedPeople members. The reason is the cbSize field which you should initialize as sizeof(CERT_CHAIN_ENGINE_CONFIG). It gives for the CertCreateCertificateChainEngine function enough information about the size of the input structure CERT_CHAIN_ENGINE_CONFIG. In case of small value of cbSize, the last HCERTSTORE members hExclusiveRoot and hExclusiveTrustedPeople will be just not used.

the value of NTDDI_WIN7 which in my case is incorrect as mine is a XP SP3 machine.
As I understand it, the variables are initialized according to what system you are targeting, not what system you are compiling the code on. So you need to look at your project settings and see, what is your target platform, what headers are referenced etc. .

Related

Intel TBB - 'InitializeCriticalSectionEx': identifier not found compiler error

I have a VS (C++) project that relies on OpenCV and TBB, so I created property sheets for each library and included them in the project. Everything worked fine and the code compiled.
Yesterday, I have started using vcpkg package manager. I installed OpenCV and TBB via vcpkg and everything seemed to work. I created an empty project, included the headers of both and tested if the new compiled libraries work. After verifying that, I went back to my main project and removed the property sheets, so I can use the libraries from vcpkg. I did not change the code in any way since the last successful compilation.
But when I try to compile the code now I get this error two times (in main.cpp and in a submodule)
tbb\critical_section.h(53): error C3861: 'InitializeCriticalSectionEx': identifier not found
Does anybody know what is going on here or why this error occurs?
Update
I found the error myself. I'm adding the poco-libraries tag, because it's actually a conflict between TBB and Poco.
I found the source of the problem and it has actually nothing to do with TBB but with the Poco library.
Consider the minimum example:
#include <Poco/Poco.h>
#include <tbb/tbb.h>
void main()
{
}
This will throw an compiler error.
Tracing down the path
When including tbb.h, critical_section.h is included in line 51 of tbb.h. However, ciritcal_section.hpp includes machine/winwdows_api.h which looks like this (unnecessary stuff is cut out):
tbb/machine/winwdows_api.h:
#if _WIN32 || _WIN64
#include <windows.h>
#if _WIN32_WINNT < 0x0600
#define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx
inline BOOL WINAPI inlineInitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD )
{
return InitializeCriticalSectionAndSpinCount( lpCriticalSection, dwSpinCount );
}
#endif
As you can see, windows.h is included before the check of the _WIN32_WINNT macro. This macro is defined in sdkddkver.h (which is included in windows.h), iff it's not already defined (in my case it's set to Win10):
sdkddkver.h:
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define _WIN32_WINNT 0x0A00
#endif
In windows.h, the _WIN32_WINNT macro controls which version of the windows header files are actually included. If _WIN32_WINNT is set to an earlier version than Windows Vista, the function InitializeCriticalSectionEx is not defined.
This issue is catched by machine/winwdows_api.h (as you can see in the code block of that file) by simply defining a macro InitializeCriticalSectionEx that calls an appropriate alternative function.
So far so good.
The problem
The root of all evil lies in Poco/UnWindows.h of the Poco library. When including a poco header, at some point UnWindows.h will be included.
Poco/UnWindows.h (shortened):
#if defined(_WIN32_WINNT)
#if (_WIN32_WINNT < 0x0501)
#error Unsupported Windows version.
#endif
#elif defined(NTDDI_VERSION)
#if (NTDDI_VERSION < 0x05010100)
#error Unsupported Windows version.
#endif
#elif !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#define NTDDI_VERSION 0x05010100
#endif
#endif
#include <windows.h>
The preprocessor checks, if _WIN32_WINNT is already defined, and if not, sets it to 0x0501 which is Windows XP. After that, windows.h is included. In the previous chapter I mentioned that _WIN32_WINNT controls which version of the windows header files are actually included.
Now imagine, the very first include in our project is a header from Poco. This means, that _WIN32_WINNT will be set to Windows XP and windows.h will include the windows headers of Windows XP (which imo is already a bad sign).
But don't worry, it gets worse.
If we trace the include hierarchy one level up, we reach Poco/Platform_WIN32.h.
Poco/Platform_WIN32.h (shortened):
#include "Poco/UnWindows.h"
...
#if defined (_WIN32_WINNT_WINBLUE)
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT _WIN32_WINNT_WINBLUE
...
Funny, isn't it? First, it includes UnWindows.h, which sets _WIN32_WINNT and causes Windows XP headers to be included, and next it redefines _WIN32_WINNT to be Windows 8.1. I have no clue why it does that, maybe there is a good reason, idk.
If we now look at the minimum example at the very top we see that Poco is included before TBB. What now happens is:
Include Poco headers
Set _WIN32_WINNT to Windows XP
Include windows headers (Windows XP version, because of 2)
Reset _WIN32_WINNT to Windows 8.1
Include TBB headers (windows headers are already included, so TBB doesn't need to include them again in tbb/windows_api.h)
TBB checks the windows version via _WIN32_WINNT and recognizes Windows 8.1 (as set by Poco)
TBB thinks InitializeCriticalSectionEx is defined, because the Windows version is 8.1 (or is it? Poco says: get rekt) and InitializeCriticalSectionEx is defined since Windows Vista.
Unfortunately Poco ensured that the Windows XP headers are loaded, so compiler says: no.
The solution
Either include windows.h yourself beforehand, or set _WIN32_WINNT yourself beforehand:
#define _WIN32_WINNT 0x0A00 // either this
#include <Windows.h> // or this
#include <Poco/Poco.h>
#include <tbb/tbb.h>
void main()
{
}
Maybe someone of the Poco contributors can clarify some things here. The Poco version is 1.8.1-1 built with x64 (via vcpkg).
Update
Poco is on the issue. Updates can be found here.

identifier "PLVGROUP" is undefined afxcmn.h

I have a Visual Studio 2015 project which uses the afxcmn header and is having a lot of "is undefined" errors.
I read in the documentation those data types are included in commctrl.h which is already included in the Visual Studio project as external dependency.
// Adds a group to the control.
AFX_ANSI_DEPRECATED int InsertGroup(_In_ int index, _In_ PLVGROUP pgrp);
// Sets information about the specified group (by ID) in the control.
AFX_ANSI_DEPRECATED int SetGroupInfo(_In_ int iGroupId, _In_ PLVGROUP pGroup);
// Retrieves information for the specified group in the control.
AFX_ANSI_DEPRECATED int GetGroupInfo(_In_ int iGroupId, _Out_ PLVGROUP pgrp) const;
That is some code example of the afxcmn.h which gives those errors.
I dont know if I have to configure something else in the project to include the commctrl header
yes, PLVGROUP is defined in commctrl.h, but it depends on WINVER
#if (NTDDI_VERSION >= NTDDI_WINXP)
that means WINVER >= 501, see:
error-Direktive: MFC does not support WINVER less than 0x0501. Please change the definition of WINVER in your project properties or precompiled header.
So I had to change my stdafx.h
//#define WINVER 0x0500
#define WINVER NTDDI_WINXP //0x05010000
They are IntelliSense errors generated by Visual Studio 2015.
My environment is Windows 10 1903/VS2017
I don't know exactly why, but this solves the problem for me:
FYI, this is the original stdafx.h in my project that produce the error in the question:
#pragma once
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
#endif
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
......
after adding these two lines bellow "#pragma once" the problem is solved:
#define WINVER 0x0603
#define _WIN32_WINNT 0x0603
Only adding the first line still produce those errors.

Error: identifier :"SHGetKnownFolderPath" is unidentified

I am writing a Windows Store app with Visual Studio 2015 on Windows 10. My code is as follows:
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00
#include <Shlobj.h>
...
HRESULT hr;
hr= SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &tempPath);
I tried to adding above version and header files. still nothing changed.
How can I fix this?
According to the documentation of the function, this function is available on the desktop only.
Minimum supported client Windows Vista [desktop apps only]
You are writing a store app, and so the function is not available to you.
Please refer to the documentation at MSDN. There, you will find both the required header and the required libs. Also, you will find the minimal system requirements (WINVER etc) that you seem to be aware of already.

This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended

I have got a project which was built using older version(8) of Visual Studio and i upgraded to Visual Studio 2010 on 32 bit windows 7 operating system.Now i am trying to built the application again and it is giving me error in my .h file like..
Error 1 error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended. c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\atlcore.h 35 1 Phone
The entire project is built on c, c++ and some external .dll's.I tried to search the solution on the web but not succeded to sort it out as i am very new to c and C++ technology..
Please help me to get it done.Thanks..
Update
I am getting error at altcore.h file of my application at following line:
#if _WIN32_WINNT < 0x0403
#error This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended.
#endif

Help! error C2040: 'HWINEVENTHOOK' : 'DWORD' differs in levels of indirection from 'HWINEVENTHOOK__ *'

I'm compiling my application on a new box (vista 64) and now it doesn't compile anymore. The compiler gives me the error in the title. The problem seems(?) to be that HWINEVENTHOOK is defined twice in
windef.h
#if(WINVER >= 0x0400)
DECLARE_HANDLE(HWINEVENTHOOK);
#endif /* WINVER >= 0x0400 */
and then in winable.h it's
#if WINVER < 0x0500 // these structures and functions
// are in NT 5.00 and above winuser.h
typedef DWORD HWINEVENTHOOK;
However, I just looked up WINVER for vista and it is 0x0600 and windows XP is 0x0501 so why is DWORD being defined? I'm at a loss. Anyone help?
According to this MSDN forum thread:
winable.h was moved from the Windows
SDK in July 2005 because functionality
was duplicated in winuser.h. It was
determined at that time that efforts
would be better spent on updating
winuser.h to Windows Vista-level
functionality rather than updating the
functionality of both files.
What version of the Windows SDK are you using, and what Windows version is your code targetting? The target Windows version may be specified in a makefile, project file, or header file. Compiling your code on Vista doesn't necessarily mean that the target version is Vista.
Also, have you tried switching from winable.h to winuser.h?
You might need to explicitly set WINVER to the version corresponding to the minimum version of Windows you are targeting. I suspect its default value is not much above Win2K...
You could check its default value with a quick (untested) hack like this:
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv) {
printf("WINVER=0x%04x\n", WINVER);
return 0;
}
Compiled as a console app and run at the command prompt it might provide a clue. Otherwise, you'll spend ages chasing through include files trying to identify where it set the default.
Edit: In general, it is safest to always specify WINVER for a project. Either do it in the project settings in Visual Studio (and for all builds, not just the current build!) or do it in a common header file included by every module in the project. Doing so explicitly will reduce the chance that different build environment might have a different assumption.