How to target XP with VC2012 or VC2013 and continue to use the Windows 8.x SDK

One of the limitations of the Microsoft provided solution for targeting XP while using Visual Studio 2012 (Update 1 and above), or Visual Studio 2013, is that you must use a special “Platform toolset” in project properties that forces usage of the Windows SDK 7.1 (instead of Windows 8.x SDK which is the default).  The other function the platform toolset provides is that it sets the Linker’s “Minimum Required Version” setting to 5.01 (instead of 6 which is the default).  But that function can just as easily be done manually by setting it in project properties.

So how about the first main function of the platform toolset?   Setting the platform toolset to one that targets XP does the following:

(1) Changes the Platform SDK being used from Windows SDK 8.x (8.1 with VC2013 and 8.0 with VC2012) back to Windows SDK 7.1

(2) Adds a preprocessor define:  _USING_V110_SDK71_ to the build

The second one turns out to be important, due to a piece of code in atlwinverapi.h, namely the following:


extern inline BOOL __cdecl _AtlInitializeCriticalSectionEx(__out LPCRITICAL_SECTION lpCriticalSection, __in DWORD dwSpinCount, __in DWORD Flags)
{
#if (NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING)
     // InitializeCriticalSectionEx is available in Vista or later, desktop or store apps
     return ::InitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags);
#else
     UNREFERENCED_PARAMETER(Flags);
     // ...otherwise fall back to using InitializeCriticalSectionAndSpinCount.
     return ::InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount);
#endif

As you can see, if we do not use the platform toolset that defines _USING_V110_SDK71, i.e we don’t use the Windows SDK 7.1, then we don’t get the benefit of avoiding a call to InitializeCriticalSectionEx, which is a function only available on Vista and above.  This will cause your binary to not load on XP.

But what if we really want to use the Windows 8.x SDK (taking care, of course, that we don’t call any Windows 8.x functions directly, to keep support for older operating systems). Why would we want this? For example, we may want a structure definition, some preprocessor define, or function declaration, i.e. we may want to support some feature of Windows 8.x if actually running our app on that OS.

Say we’ve decided to use Windows 8.x SDK while still allowing our app to run on XP. Are there any options available? i.e. can you keep using the v110/v120 toolsets instead of the v110_xp/v120_xp toolsets? Yes, it turns out that Microsoft left a nice loophole in the code to do exactly that. Notice the mysterious define in the block of code above named _ATL_XP_TARGETING. Turns out this is an alternative way to support XP targeting while _USING_V110_SDK71_ is NOT defined. So if you really want to support XP while using Windows 8.x SDK, we simply need to ensure our code is built with _ATL_XP_TARGETING defined. The easiest way to do this is to add a /D_ATL_XP_TARGETING flag to our C/C++ command line options in project properties.

Then, the only other step is to set the “Minimum Required Version” in project properties under Linker – System to 5.01, and we’re all set – a simple way to target XP and still use the Windows 8.1 SDK without using the platform toolset that Microsoft provided to target XP.

In summary, the _ATL_XP_TARGETING define, while undocumented, is an interesting way to keep support for XP while also allowing continued use of the Windows 8.x SDK (rather than being forced to be permanently stuck on  the older Windows 7.1 SDK)

About these ads

About tedwvc
On this blog you'll find some tips and tricks for dealing with Visual C++ issues.

4 Responses to How to target XP with VC2012 or VC2013 and continue to use the Windows 8.x SDK

  1. B Rumm says:

    Hello.
    Any chance with VS14 CTP? There is v140_xp platform toolset provided, but it doesn’t work (that InitializeCriticalSectionEx problem again, and more)

    • tedwvc says:

      I’ll probably wait for the next CTP to see if there are more changes. But you can use techniques that I outlined in a previous blog entry (wrapping the functions with CPP and ASM)

  2. Pingback: Deploying Qt on XP and getting “not a valid Win32 application” | Tripleboot blog

  3. Pingback: 讓升級的 visual studio 2012 專案能使用 code analysis 功能,並在 windows XP 執行。 | KKWT

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: