2

I am building an existing MFC application with Visual Studio 2012. The application uses "RichEdit20A" controls and custom controls which inherit CRichEditCtrl.

During InitInstance() the application calls ::AfxInitRichEdit2(), which calls AtlLoadSystemLibraryUsingFullPath(L"RICHED20.DLL"), which callsLoadLibraryExW(pszLibrary, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32). The latter call fails and returns NULL. GetLastError() returns 87 (The parameter is incorrect.). This happens on both Win7 x64 and Win8 x64.

The failing call seems to have been introduced in the Visual Studio 2012 runtime (it is inside a conditional #if NTDDI_VERSION >= NTDDI_WIN8). The application worked just fine when built with Visual Studio 2008.

Does anyone know why this happens and how to fix (or work around) this issue? Alternatively, is there any way to "revert" the runtime to use the older load behavior?

Håvard S
  • 23,244
  • 8
  • 61
  • 72
  • Did you verify that RICHED20.DLL exists on the system? – Lynn Crumbling Nov 05 '12 at 13:45
  • Try to set `WINVER` to 0x600 or whatever it was before upgrading. If you created a new project in VS 2012 you likely ended up with a project targeting Windows 8. Change it i `targetver.h`! – l33t Nov 05 '12 at 13:47
  • @Lynn Crumbling Yes, RICHED20.DLL exists. – Håvard S Nov 05 '12 at 14:56
  • @l33t The project in its current form was created with VS2008, I believe (though not by me). We have no targetver.h, but it has a `#define _WIN32_WINNT _WIN32_WINNT_WINXP`. – Håvard S Nov 05 '12 at 14:58

1 Answers1

6

Choosing the proper target Windows version can be very important. It is here, if you don't explicitly set it yourself then the Visual Studio assumes you'll target the latest and greatest. Which is Windows 8 for VS2012.

Which includes a new option for LoadLibraryEx(), the LOAD_LIBRARY_SEARCH_SYSTEM32 option. Available on Windows 8 but requires a security patch to be installed if you use it on Windows Vista, 7 or 2008. It is a pretty critical one, clearly you don't have it installed.

If you want your program to be compatible with old or unpatched Windows versions then you need to change the target. This is typically done by the targetver.h header file, assuming your MFC project was generated by a relatively recent wizard. Modify it like this:

#pragma once

// Including SDKDDKVer.h defines the highest available Windows platform.

// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.

#define _WIN32_WINNT _WIN32_WINNT_WINXP    // NOTE: added
#include <SDKDDKVer.h>

If you don't have targetver.h then put it anywhere before the #include for <windows.h>. Tweak the value as desired. Note that XP isn't currently supported by VS2012 but will be later.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • A proper `#define _WIN32_WINNT` was in place, but the patch was missing. A follow-up: How could I have discovered that I require such a patch (besides asking the Stack Overflow community)? – Håvard S Nov 05 '12 at 15:15
  • I found it by reading the MFC code. Not for everyone but this is why SO exists. – Hans Passant Nov 05 '12 at 15:18
  • Could you reference where (and if applicable tell how) you found and/or deduced it for the sake of completeness? – Håvard S Nov 05 '12 at 19:54
  • Found what exactly? The MSDN Library article for LoadLibraryEx contains the link to the KB article. – Hans Passant Nov 05 '12 at 19:57