i'm trying to use the CheckTokenMembership function, i copied the example piece of code on Microsofts website ( https://msdn.microsoft.com/pt-br/library/windows/desktop/aa376389(v=vs.85).aspx ), but i just can't get it to work!
I get "error: 'CheckTokenMembership' was not declared in this scope" (on CodeBlocks) no matter what i do.
I am including Windows.h and even Winbase.h as the website says. Does anyone have any idea on how to fix this?
Before including windows.h you need to specify the minimum version of Windows your application will support. The idea here is that the build will fail if you use an API function that isn't available in the specified Windows version.
You can do this by defining the _WIN32_WINNT macro, e.g., for Windows 7:
#define _WIN32_WINNT _WIN32_WINNT_WIN7
If you need to be more specific you can also define the NTDDI_VERSION macro, e.g., for Windows 10 version 1607:
#define _WIN32_WINNT _WIN32_WINNT_WIN10
#define NTDDI_VERSION NTDDI_WIN10_RS1
The documentation tends to lag behind, but you can find the definitions in sdkddkver.h in the SDK.
Addendum:
In some cases, e.g., if using an old or third-party version of the SDK, the named constants may not work and you will have to resort to magic values, e.g., the examples above would become
#define _WIN32_WINNT 0x0601
and
#define _WIN32_WINNT 0x0A00
#define NTDDI_VERSION 0x0A000002
You can look these up by obtaining a recent version of sdkddkver.h from Microsoft or you could try the search engine of your choice. :-)
Related
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.
Function AddDllDirectory was added to Windows 7 in one of the updates.
I'm using Windows 10 SDK headers in my c++ application. Is it possible to configure them to show only functions available in first Windows 7 version (without any updates) ?
I read about defines of:
WINVER, _WIN32_WINNT
I tried to set them to:
#define _WIN32_WINNT 0x601
#define NTDDI_VERSION 0x06010000
or even:
#define _WIN32_WINNT 0x600
#define NTDDI_VERSION 0x06000000
, but it doesn't work.
The NTDDI_VERSION macro uses a 32-bit number that includes service pack information. The older defines (WINVER, _WIN32_WINNT, _WIN32_WINDOWS, and _WIN32_IE) is just a 16-bit number, typically in hex: 0xaabb where aa is the Windows major version and bb is the minor version.
The correct value for Windows 7 is therefore 0x0601 for these defines and 0x06010000 is just for NTDDI_VERSION. The SdkDdkver.h header also provides macros like _WIN32_WINNT_WIN7 and NTDDI_WIN7 where the version numbers are listed for you.
EDIT 2: Ok so I changed to Orwell DevC++ which contains the "winnt.h" that contains #define KEY_WOW64_64KEY 0x0100 but it still is not working. (Refer to EDIT 1:)
EDIT 1: I looked into the "winnt.h" which came along the CodeBlock and DevC++ and the DevC++'s is missing the following lines:
#if (_WIN32_WINNT >= 0x0502)
#define KEY_WOW64_64KEY 0x0100
#define KEY_WOW64_32KEY 0x0200
#endif
And putting the above code in the wint.h of DevC++ doesn't work.
Original Post:
I have a 32bit application (developing in DevC++ and Windows 7 64bit) which reads a 64bit app's registry as one of its task, so I am trying to use "KEY_WOW64_64KEY" flag in RegOpenKeyEx, and found few posts regarding how to use it with _WIN32_WINNT : this and this
It worked like charm when I used it in a CodeBlock Project(a test project) but the same code is not working with DevC++, I can't port it to codeblock now since codeblock presents other problems.
How do I make it work with DevC++ ?
Thanks
It defines the version of the windows header files to use. It must be declared before you #include <Windows.h>.
There are a few other similar variables you should probably set if you're going to modify it:
MSDN Using Windows Headers
_WIN32_WINNT is a preprocessor token, which is replaced by (0x0601) wherever _WIN32_WINNT is used. The preprocessor just scans the whole file and replaces _WIN32_WINNT with (0x0601) everywhere it is found.
Chances are, there could be ifdef preprocessor guards that will enable/disable a preprocessor constant. Like:
#ifdef _WIN32_WINNT
#define KEY32 32
#endif
There, KEY32 will only be defined IF _WIN32_WINNT is defined.
It already works with DevC++.
I create MFC project in VS2010(windows xp). And i take this error:
error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x0500. Value 0x0501 or higher is recommended.
if I added in afxcomctl32.h: #define _WIN32_WINNT 0x0501, i take 60+ errors.
In project i dont added anything. Use such as Visual Studio created.
What i need to do with this?
afxcomctl32.h is a wrong place I think, to fix this problem make your stdafx.h looking like this:
// 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 0x0501 // 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 0x0501 // 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 0x0501 // 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 0x0500 // Change this to the appropriate value to target IE 5.0 or later.
#endif
Try adding this to the TOP of your StdAfx.h file:
#include <sdkddkver.h>
In my application, I'm defining
_WIN32_WINNT=_WIN32_WINNT_WINXP
At first I had the same problem. I discovered that because when you use MFC, you're not allowed to include windows.h, _WIN32_WINNT_WINXP is never defined and so _WIN32_WINNT didn't have a valid value. By including the header that windows.h uses to define those values (sdkddkver.h), suddenly everything works!
Blech. I hate programming for Windows.
You don't need to modify afxcomctl32.h. You just need to include Windows.h before this file.
Should work.
I solved my problem. The fact was that the file atmcore.h was different from the standart in VS2010.
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.