Avoiding problems with VC2005 SP1 Security update KB971090

KB971090 update mitigation

Problem

After installing KB971090 for Visual C++ 2005 SP1, the version of ATL/MFC/CRT referenced in the generated manifests is changed from 8.0.50727.762 to 8.0.50727.4053

The above change forces the application developer to rebuild all components to reference the 4053 version of the versions of ATL/MFC/CRT in the manifest, as well as making it necessary to ship a new vcredist_x86.exe and/or MSM files containing the new 4053 versions of ATL/MFC/CRT.

Solution

Instead of uninstalling the KB971090 update, we can force the build to use the 8.0.50727.762 version instead of the default which is 8.0.50727.4053. Microsoft provides a mechanism to specify the assembly version number to use in the manifests.

Steps to take to allow your applications to reference 8.0.50727.762 instead of 8.0.50727.4053

1) Create a file named targetsxs.h with the following content and put it in a common location

#ifndef __midl
#define _SXS_ASSEMBLY_VERSION "8.0.50727.762"
#define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

#ifdef __cplusplus
extern "C" {
#endif
__declspec(selectany) int _forceCRTManifest;
__declspec(selectany) int _forceMFCManifest;
__declspec(selectany) int _forceAtlDllManifest;
__declspec(selectany) int _forceCRTManifestRTM;
__declspec(selectany) int _forceMFCManifestRTM;
__declspec(selectany) int _forceAtlDllManifestRTM;
#ifdef __cplusplus
}
#endif
#endif

2) The above file needs to be included in every project you wish to build.

Accomplish this in one of two ways. The first method involves the changing of source code. The second involves changing of project settings.

choose A or B which ever one is more appropriate for your situation:

A) #include "targetsxs.h" near the top of every one of your stdafx.h files
(using the path you saved the targetsxs.h)

B) Use the force include (/FI) compile option to make sure that the above file is included in every file built. To accomplish that, add the following command line to your compiler options

/FIc:\path\targetsxs.h

(where c:\path is the location of the targetsxs.h you created in step 1)

There are two methods to accomplish that: either directly in your project or through a compiler environment variable:

Method i)

Add the above to the command line section of the C/C++ project properties.

Method ii)

Create an environment variable named CL with the above-mentioned /FI statement

Method (ii) is more convenient to use when you have dozens of projects that you do not wish to make changes to, but may conflict with other work you do on your machine.

3) For every MFC DLL project in your solution add the following line to the bottom of the stdafx.cpp file

#include "..\src\mfc\dllmodul.cpp"

Step three is only necessary if you have any MFC DLL projects (this step is necessary due to a bug in the handling of the assembly versions in MFC DLLs – the bug is that a reference to the latest version of the DLLs will always be included regardless of what is set in step 1)

4) Do a rebuild all of all the projects in your solution

5) Inspect manifest files (by doing a find in files for *.intermediate.manifest) to ensure that 4053 no longer appears in any of the manifests.

6) Run your app on a machine that has no 4053 components installed to WinSxS to make sure runs properly.

IMPORTANT NOTE: if you have ATL controls that are affected by this security problem please ensure you have followed the directions to modify your controls to take advantage of the security updates. A simple recompile may not be enough. For more info please see the video at:

http://channel9.msdn.com/posts/Charles/Out-of-Band-Inside-the-ATL-Security-Update/

Q&A

Does referencing 762 instead of 4053 make your application less secure?

No. Microsoft provides WinSxS policy redirection, so any application referencing 762 will end up loading the 4053 versions (if they’re installed). The ATL security update redistributable has been released as an update on Windows Update, so the 4053 version of ATL will be in place, and will be used even though your app still references the 762 version of ATL.

*Important note: you should still ship the new version of the redistributable if at all possible, as users may have not updated using Windows Update.

What are the benefits to referencing 762 instead of 4053 in your SP1 applications?

1) If you have existing applications shipped and you need to rebuild any components shipped, then new MSM or vcredist_x86.exe containing 4053 versions do not need to be shipped. You can continue to ship existing components with 762 versions.

2) If you have existing third party static libraries that reference 762, then you need not rebuild them to reference 4053.
 
Does VC2008 SP1 security update have a similar issue?
 
Yes, it does, if you use _BIND_TO_CURRENT_VCLIBS_VERSION in your project. It will bind to the security update version instead of the SP1 version. You can use a similar technique as described above (step 3 is not required) to get around this problem.

For VC2008 SP1 the values for the current versions of the CRT/MFC/ATL have changed slightly, instead of _forceCRTManifest, you should use _forceCRTManifestCUR.  The same thing applies for MFC/ATL (add the CUR). And of course, the version numbers you’re dealing with are different: SP1 9.0.30729.1 vs the new SP1+security update which is 9.0.30729.4148

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

64 Responses to Avoiding problems with VC2005 SP1 Security update KB971090

  1. Marc Perreault says:

    Thank you for your help

    I was facing the same problem. I created an ActiveX control with VC2005 that I could not register on our prod servers (Windows 2003 servers). Tryed to install vcredit_x86.exe on the prod servers but updated only to version 762. Tryed to build following your reciepe and it worked.

    Thanks again.
    Marc

  2. Jeff Benson says:

    We’ve had something of a different problem. After installing 971090 on our build machines, our applications started requiring 4053 versions to run (version specified in the manifest). Unfortunately, the merge module that is supposed to install the 4053 assemblies appears to NOT do so if the 762 versions are already installed. We use InstallShield for our setups but the updated merge modules came from MS as part of the patch. I know the right assemblies are getting into the setup because 4053 versions are installed if the target system does not any previous versions installed.

    What could be going wrong? A bug in the merge modules?

  3. tedwvc says:

    Hi Jeff, it does sound like a bug in the merge modules, can you create a quick setup project in Visual Studio and see if you get the same results? I don’t have access to a machine at the moment with the security update applied to check it for you.

  4. Dan Korn says:

    Thanks, but this didn’t completely work for me. I’m building an ATL DLL to call into a Web Service from C/C++. I added the targetsxs.h file as shown (although I added “#undef _CRT_ASSEMBLY_VERSION” to avoid the macro redefinition warning), and now I have dependencies to both 762 and 4053 in my manifest.

    But I’m not linking to anything in my project other than the standard libraries (kernel32 et al). Could one of these be keeping a dependency to the 4053 runtime? If so, what can I do about it?

  5. Jeff Benson says:

    Ted,

    I’ve done a lot of testing on this issue today and I have come to understand the problem. It is not a bug in the merge modules, you’ll be happy to know. The problem had to do with the way InstallShield knows whether or not it is appropriate to install a particular “feature”. In order to coax our setup to install the newest assemblies, I had to essentially “create a new feature” to hold the updated merge modules (translation: change a GUID in the InstallShield project files). Once I did that, the setup would correctly install the 4053 assemblies even when upgrading from a version of our product that previously installed the 762 versions.

    Once I understood the nature of the problem, it was easy to fix. But at the time I wrote my post I did not yet know the extent. So, I’m good. Sorry about the scare. On the other hand, I learned something important about InstallShield that we need to take into account in future releases of our product.

    Thanks for the reply.

    Jeff

  6. tedwvc says:

    Hi Dan, if you have some redefinition errors then you’re not including it early enough. Where in the file did you include it? The targetsxs.h needs to be before any other files are included in the stdafx.h file (especially the ATL or MFC headers). There may be other files in your project that include MFC or ATL headers but not your stdafx.h, that’s why I suggest using the /FI instead of the stdafx.h approach, so that all files (even those that do not use stdafx.h) will include this. The /FI forces it to get included first before any other files are included.

  7. Dan Korn says:

    Thanks Ted, that was it. I moved the #include to the top of my stdafx.h file (right after “#pragma once”), rebuilt, and now I only have a dependency on the 762 runtime. Hurrah!

    Going back and rereading your post again, you did specifically say to include the file “near the top” of stdafx.h, so I obviously didn’t read the instructions closely enough. And the warnings were indeed another clue that I missed. Thanks for setting me straight, and for being so thorough. Your solution was perfect all along!

    I’m sure the /FI switch would work too, but this is a very simple project with one source file [other than stdafx.cpp]. I’ll keep that in mind though. Thanks again!

  8. tedwvc says:

    // so for VC2008 SP1 it should look like this:

    #ifndef __midl
    #define _SXS_ASSEMBLY_VERSION "9.0.30729.1"
    #define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
    #define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
    #define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

    #ifdef __cplusplus
    extern "C" {
    #endif
    __declspec(selectany) int _forceCRTManifestCUR;
    __declspec(selectany) int _forceMFCManifestCUR;
    __declspec(selectany) int _forceAtlDllManifestCUR;
    __declspec(selectany) int _forceCRTManifestRTM;
    __declspec(selectany) int _forceMFCManifestRTM;
    __declspec(selectany) int _forceAtlDllManifest;
    #ifdef __cplusplus
    }
    #endif
    #endif

  9. Pingback: NW-Software » Blog Archiv » Fehler bei Aufruf in Managed C++ Assembly von C# aus nach Visual Studio 2005 Update (KB971090)

  10. Jamie Cook says:

    I’ve also had some luck using the _USE_RTM_VERSION preprocessor directive. By adding this to the command line (visual studio = /D “_USE_RTM_VERSION”) and recompiling everything I was able to generate an application (comprised of multiple static libs linked into a single dll) which relied only upon the 8.0.50608 version of the runtime… Obviously if a newer version (50727.762/4053) is available then those will be used but it makes the dll compatible with most systems.

  11. P K Nielsen says:

    Thanks Ted.
    You maked my day ;-)

    Peter

  12. Marin Siderov says:

    I was facing the same problem and thought that time had stood still for a while. I was very lucky to find your article here. I owe you a big thank you!

    Cheers!
    Marin.

  13. Frank Morales says:

    Hi,

    I am using Visual Studio 2005. I added the targetsxs.h as it appears up in this blog, but my dll’s are still 4053 referenced, and will not run on a PC that only has 762 version.

    I used the /FI switch, and don’t have the __cplusplus or the __midl defined in the project. What could be wrong? When checking my intermediate.manifest this is what I get:

    But when I analyze my dll with the Dependency Walker, it shows that my dll is depending on: c:\windows\winsxs\x86_microsoft.vc80.debugcrt_1fc8b3b9a1e18e3b_8.0.50727.4053_x-ww_d014c028\MSVCP80D.DLL
    and
    c:\windows\winsxs\x86_microsoft.vc80.debugcrt_1fc8b3b9a1e18e3b_8.0.50727.4053_x-ww_d014c028\MSVCR80D.DLL

    which are clearly 4053 dll’s. Am I doing something wrong?

    Thank you for your time in advance!

    • tedwvc says:

      i just noticed by the names of the CRT libraries that you’re compiling the DEBUG version of your app. You need to use the Release version for it to work on the other machine, otherwise install Visual Studio on the other machine as well as the hotfix, and then the debug versions will be available in the WinSxS folder.

      And using dependency walker it will always show the latest version on the machines (due to policy redirections) so don’t rely on dependency walker, always look at the manifests in a resource editor to see what’s in the binary manifest itself.

  14. Frank Morales says:

    I don’t know why, but it didn’t post the intermediate.manifest content. Here it is :)

    assemblyIdentity type=’win32′ name=’Microsoft.VC80.CRT’ version=’8.0.50727.762′ processorArchitecture=’x86′ publicKeyToken=’1fc8b3b9a1e18e3b’

  15. tedwvc says:

    Hi Frank, dependency walker will always show the latest versions of the DLL available on your machine even if your manifests show earlier builds.

    The best way to know whether your app is ok is to look at each manifest in the EXEs and DLLs you built in the Visual C++ resource editor (open up the EXE and DLLs in Visual Studio as resources) and look at the binary manifests. If they only show references to 762, then you are ok, otherwise you have some mixed components (maybe static libs that have already been built with 4053).

    Just make sure everything is built with the includes I mentioned above and you should be fine.

    Also, in your example, you are dealing with debug versions of your app. Generally you will not have debug versions of the 762 components (or any debug version for that matter) on another machine that does not have Visual Studio installed. Try compiling a release version of your app and DLLs, not debug, and then test again on a clean machine with only the 762 redist installed.

  16. ATL says:

    http://www.microsoft.com/downloads/details.aspx?familyid=766a6af7-ec73-40ff-b072-9112bab119c2&displaylang=en

    You could just ask your users to install the latest runtimes instead of targeting older, vulnerable runtimes. Microsoft does provide the downloads for it.

  17. Fainster says:

    Hi, this solution works fine in unmanaged code, but I need to compile with /clr. This causes an additional dependancy to 4053. (extract from my intermediate.manifest)

    Can anyone offer some help with how to solve this please?

  18. Brian Durand says:

    Thanks for the info. I found little information out there about this issue, and was glad to come across your blog. Installing the .4053 runtime fixed my target machines.

  19. Szymon Lukasik says:

    Thank you for a very useful post. It helped me solve my manifests dependency issues (my CLapack libraries are built for 8.0.50727.762, so mixed CRT libs make a lot of mess, especially when I port the application to the other machine).

    How did you come up with such an idea?

    • tedwvc says:

      how did I come up with the idea? – anger for one thing – waking up one morning and realizing several of my machines were messed up with a newer version of VC2005 due to the incorrect marking of this as critical on WSUS by Microsoft. I had to act fast, before all the machines rolled out. It was either uninstall them all, or come up with a workaround. So I drew from my knowledge of the CRT runtime flags (from previous experiences with _USE_RTM_VERSION and _BIND_TO_CURRENT_VCLIBS_VERSION and the various bugs in both of those) as well as a blog entry from Martin Richter at http://blog.m-ri.de/index.php/2008/05/06/hotfix-fuer-usemsprivateassembliesh-und-vc-2008/

      These things gave me the pieces necessary to combine into what you see in this blog entry. Thanks again to Martin for the germ idea for this.

  20. lcdvasrm says:

    The precision and completeness of your info qualifies you to the pro category. Thanks.

  21. Pingback: Project Aftermath patch 1.21 released « Games Faction

  22. Mark says:

    Thank you for posting this solution, but unfortunately, just like “Fainster” said, it does not work for managed C++ projects. If you could find a solution, you will be a hero again.

    • tedwvc says:

      nothing to report yet, I don’t think there is a good way other than manipulating the manifest after the fact.

  23. Darren says:

    thanks! you rock. i don’t think i could have figured this one out without this site.

  24. Kulvinder Singh says:

    Hi,

    I did whatever has been mentioned here but i am still getting the SideBySide error when i see my test machine event viewer. Please tell me how do i see the dependancy walker (although i tried it) and see what reference is actually being used on my C++ dlls.

  25. Kulvinder Singh says:

    I checked the manifest file and it still has 2 versions : 762 and 2053. How do i tune my C++ project in VS2005 SP1 so that it uses ony 762. I have already included the targetsxs.h file in my project and included in stdafx.h file.

    • tedwvc says:

      take a look at all the obj and static lib files being pulled into this project and make sure they all use 762. there should be no reason to have both unless your app is purely managed. in that case there is no good workaround at the moment.

  26. Seb says:

    Please delete my two previous posts and just consider this one. Sorry for that.

    First thanks a lot for this helpful article which has saved my ass until today.

    I recently noticed the embedded manifest content of myApp.exe is this : http://pastebin.com/f5b68075

    That sounds weird to me because it’s like it declares that myApp.exe requires version 762 or(/and ?!) version 4053 of the CRT libraries.

    C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT contains the version 4053 of the CRT libraries. So would that mean one of my thirdparty libraries (the ones I don’t compile by myself) requires the version 752 of the CRT libraries ? And so the embedded manifest of myApp.exe declares version 4053 because myApp.exe is compiled with this version of the CRT and it also declares the version 752 because one of my thirdparty library was compiled with this other version of CRT.

    thanks for your help

    • tedwvc says:

      Yes, Seb, you’re correct in your statement. You should never have more than one version listed in the manifest. You’ll need to make sure all components (yours, and the third party static libs) are compiled using the same manifest version (762 preferably). The folder you mention contains the new versions, but you can easily get the older ones by uninstalling the security hotfix and copying that folder to a safe place, then reinstalling the security hotfix.

      • Seb says:

        Hi again Ted

        I have tones of libraries to check before finding the ones which were compiled as static libraries with version 762 of the runtime (probably without a “_Static” suffix in the file name of the lib…).

        Would you have a tip to quick find what are the static libraries I link on a VC++ project without having to search where does each single linked library comes from, e.g: for each library I have to check if I have the build solution of it and if not then try to find where I did get this assembly, can I get the sources and see if I can setup a VC++ project to recompile it.

        Obviously if I can’t recompile the static library (or libraries) compiled through 762 version of the runtime then I’ll have to force 762 version linkage as you clearly explained it.

        Thanks a lot again

  27. Seb says:

    Thanks again Ted. I have to look deeper inside the whole linkage step of our numerous C++ projects to figure out where are the unsuitable embedded manifests.

    I also discovered in the deutch article you mentioned a few upper that a code project article recommands to remove publicKeyToken from the manifests to deploy a C++ application as private assemblies (http://www.codeproject.com/KB/cpp/PrivateAssemblyProjects.aspx). This is what we try to do. And this is the first time I noticed this recommandation about publicKeyToken although I did read a lot about private SxS assemblies on the msdn, VC++ team blog, etc… Anyway it seems I’m not so far to defenitly get rid of this mess.

    Some people of my team (plus the build server) compile/(re)distribute the game on Vista, others on XP, some on the x86
    version of those platforms, the others on x64 … Considering we regularly branch on our source control the redistribuable assemblies of our game from the dev team main line code to the artistic production code branch, this kind of issues about the C++ runtime libs security patches is a huge nightmare.

    Information you pointed out here is really important for me. You rock

    Cheers

  28. Kulvinder Singh says:

    Dear Sir,

    I am working on a C# .NET 2.0 project which requires a C++.NET managed code and using VS 2005 SP1. I have done whatever u suggested in your great article but how do i check why a 4053 and 762 references are there in the manifest file of C++ project. Should i remove the KB update from my machine ?

    Thanks
    Kulvinder Singh

  29. Kulvinder Singh says:

    I have removed the VC++ 2005 KB Update from my development machine, cleaned the solution and rebuild it but still the manifest file says :

  30. Kulvinder Singh says:

    I have removed the VC++ 2005 KB Update from my development machine, cleaned the solution and rebuild it but still the manifest file says :

    &LESS THAN&?xml version=’1.0′ encoding=’UTF-8′ standalone=’yes’?&GREATER THAN&
    &LESS THAN&assembly xmlns=’urn:schemas-microsoft-com:asm.v1′ manifestVersion=’1.0’&GREATER THAN&
    &LESS THAN&dependency&GREATER THAN&
    &LESS THAN&dependentAssembly&GREATER THAN&
    &LESS THAN&assemblyIdentity type=’win32′ name=’Microsoft.VC80.CRT’ version=’8.0.50727.762′ processorArchitecture=’x86′ publicKeyToken=’1fc8b3b9a1e18e3b’ /&GREATER THAN&
    &LESS THAN&/dependentAssembly&GREATER THAN&
    &LESS THAN&/dependency&GREATER THAN&
    &LESS THAN&dependency&GREATER THAN&
    &LESS THAN&dependentAssembly&GREATER THAN&
    &LESS THAN&assemblyIdentity type=’win32′ name=’Microsoft.VC80.CRT’ version=’8.0.50727.4053′ processorArchitecture=’x86′ publicKeyToken=’1fc8b3b9a1e18e3b’ /&GREATER THAN&
    &LESS THAN&/dependentAssembly&GREATER THAN&
    &LESS THAN&/dependency&GREATER THAN&
    &LESS THAN&/assembly&GREATER THAN&

  31. Kulvinder Singh says:

    Is there any property which i need to set ?

  32. tedwvc says:

    Singh, if you’re still getting components that have 4053 then you definitely have not rebuilt all components (including all static libraries). There should be no trace of that 4053 in any of your manifests after uninstalling and rebuilding.

  33. Kulvinder Singh says:

    Dear Ted,

    I have created a new C++ project in VS 2005 SP1 and copied all the code from my previous C++ project into it and rebuild. Now, the manifest of this C++ project contains only 4053 version but still when i install my utility on a test machine (i installed on this VC++ SP1 and the KB as well manually and also restarted), my utility is still not working and getting Side by Side error as seen in the Events. Can you help on how to troubleshoot furthur ?

    • Seb says:

      Hi Kulvinder
      I uninstalled the KB971090 because it was faster than forcing the C++ runtime libs version using the solution explained by Ted.
      After the KB was uninstalled (& rebooted) myApp.exe embedded manifest still declared the 4053 & 762 version of the runtime. The reason was I forgot to recompile one of my thirdparty dynamic lib md5lib.dll so the embedded manifest of md5lib.dll still declared the 4053 version of the runtime. After recompiled md5lib.dll using the 762 version of the runtime and myApp.exe, its embedded manifest became ok : declared only the 762 version.
      So you probably have one of your third party which still declares the 4053 version of the runtime in its embedded manifest. If not dependency walker (depends.exe) should help you to figure out the root cause of the Side-by-Side error you are running through.

      • Kulvinder Singh says:

        Hi Seb,

        I am only using mapi32.lib file reference and the new project file i have used is showing only 4053 version even though i have uninstalled this KB update. What should i do ?

        Thanks
        Kulvinder Singh

      • Kulvinder Singh says:

        depends.exe tells me that it is using MSVCM80.dll and MSVCR80.dll with versions 4053. How do i ensure that they doesnt use this versiob even though i had removed it manually from my system.

        Thanks
        Kulvinder Singh

      • tedwvc says:

        dependency walker will always show which version is actually loaded. So even if your app references only 762, due to policy redirection it’s going to load 4053 anyway. That’s not a bad thing, but can be confusing. What you need to do is get a completely clean machine without 4053 DLLs installed in WinSxS folder, and then you’ll see that only 762 is loaded.

  34. Pingback: Updates are tempting, but are they safe? (about KB971090) | Young, a Game Programmer Writing.

  35. pnswdv says:

    I haven’t had to do a software release in a while so this issue blindsided me a couple of days before the release was due! I downloaded and installed the latest vcredist_x86.exe from Microsoft and ran it on the target PC. When I look at the \Windows\WinSXS directory I see the directories with the 4053 dlls, but when I then install and run my app it still fails to load. This happens on a “clean” XP as well as “clean” Vista PC. The event file on the Vista PC indicates it couldn’t find the 4053 CRT, event file on XP is uninformative.

    I find it quite hard to understand why Windows is not finding the DLLs. I’ve rebooted just to make sure, but no joy.

    I guess my only option is to remove the security patch and recompile all my EXEs. Well see how that goes…

  36. Edgar says:

    I also updated to the 971090 security update. I also knew I had to adjust the InstallShield of our software, but this was OK for me.
    What I DONT like, is the fact I can debug anymore, since in installed the update.
    In my sample application I can put breakpoints and step through the OnInitDialog, but when placing a breakpoint in a say “OnButton1” method it stops like it should, pressing F5 also works.
    But when stepping through the code using F10, I now get an access violation.
    Uninstalling doesn’t solve the problem. Reverting back to a previous disk image, solves it. Again running the 971090 update breaks it..
    (Windows 7 x64)
    It looks like I am the only one, since I didnt find other with this problem.

    • tedwvc says:

      you may have to check your C:\windows\Symbols\dll folder to make sure the old ones are there (copy them from your image to your new machine)

      • Edgar says:

        Even completely removing the symbols folder didnt help, I also tried the microsoft symbol server, for auto-downloading correct symbols.
        The ‘fun’ detail is the following, when starting the application outside the debugger, and then attaching, will let me debug the application normally.
        So it looks like the debugging gets corrupt, when the first ‘OnIdle’ or ‘OnInitdialog’ is done, ONLY when the debugger is currently connected.
        On some applications it just crashes, on other application I get this error:
        Unhandled exception at 0x77c2459f (ntdll.dll) in XXXXX.exe:
        0xC0150014: The activation context activation stack for the running thread of execution is corrupt

      • Edgar says:

        I finally found the solution, after reinstalling and restoring about 7 images of the operating system.

        The problem was one of the “Debugging’ options. When ‘Checking’ the “Debug RPC commando’s”. When disabling all worked OK. When re-enabling this option on Windows 7 x64, I get the strange behaviour. Maybe other can verify this. It took me many hours to figure it out.

  37. Tim says:

    Ted,
    Could you please explain Step 3.) for MFC dll’s. I understand the other steps and they are working for me but I’m puzzled on step 3.)

    Maybe I’m having a slow morning but not sure why I would include a .cpp file in my stdafx.cpp? How does this force to use the correct files?

    #include “..\src\mfc\dllmodul.cpp”

    Thanks and your article has helped me a lot!

    • tedwvc says:

      the reason it works is because of the magic line in dllmodul.cpp that says:
      #include mfcassem.h

      the one in the LIB provided by Microsoft is pre-built with the 4053 assembly info. But because you include the cpp in your stdafx.cpp unmodified, the linker is smart enough to use your compiled dllmodul.cpp object and not the one found in the LIB file. And in this case instead of using the pre-built one provided by Microsoft with 4053 assembly info it uses yours with the 762 assembly info.

  38. Andrew says:

    Hi there,
    I end up with the aforementioned ‘duplicated’ dependencies on both 4053 and 762 version of MSVCR80 in the assembly of my app.

    However, when I profile my application loading using depends, I only ever see the 4053 version of MSVCR80 loaded. The .762 is never loaded. So what is the problem as long as you have the 4053 version installed ( through the 4053 vcredist or by including the correct MSM).

    Andrew

    • tedwvc says:

      There is no problem, as long as you have 4053 installed, as you say. This is for people that don’t want to have to guarantee that 4053 is available, for example they’ve already shipped an app and want to make a quick hot fix for it, and not have to worry about whether the system has been patched with 4053 already or not.

  39. Bill McIntosh says:

    RE C++ embedded Manifests and wrong MFC version dependencies or multiple dependencies to the same DLL name, different versions.

    I saw your note “Avoiding problems with VC2005 SP1 Security update KB971090” posted 10 Aug 2009 via a search on keword “forceMFCManifestCUR”.

    Your note turned out to be the ONLY workable solution I found after several hours work.

    I manage a set of MFC applications that depend on the correct MFC redist versions being installed with our app suite in C:\Program Files, as often the target systems do not have the correct versions, if at all, and do not have operators capable of installing them.

    So we have been using the prepocessor directive _BIND_TO_CURRENT_VCLIBS_VERSION to
    assure success for the last couple of years with variable results.

    However, this last week I installed Windows7 (install, not upgrade in place) on my 2-year-old Vista development computer. I reinstalled VC2008 and both service paks, sp1 (9.0.30729.1) and security upgrade (9.0.30729.4148).

    I then made a few changes to a project and tried it out on a target computer and found the old can’t run error, wrong mfc version. I looked at the embedded manifest which showed TWO entries for Microsoft.VC90.CRT: one for version=”9.0.30729.4148″
    and one for version=”9.0.30729.1″. I found that if I removed the prepocessor directive I would get Microsoft.VC90.CRT = “9.0.21022.8”, the original before SP1, also wrong.

    I could not find a way to force the system use 9.0.30729.4148 on new projects OR on rebuilt old projects and it has NOTHING to do with different mfc dependencies down my own dll chain.

    Your solution, using a header with

    #ifndef __midl
    #define _SXS_ASSEMBLY_VERSION “9.0.30729.4148”
    #define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
    #define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
    #define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

    #ifdef __cplusplus
    extern “C” {
    #endif
    __declspec(selectany) int _forceCRTManifest;
    __declspec(selectany) int _forceMFCManifest;
    __declspec(selectany) int _forceAtlDllManifest;
    __declspec(selectany) int _forceCRTManifestRTM;
    __declspec(selectany) int _forceMFCManifestRTM;
    __declspec(selectany) int _forceAtlDllManifestRTM;
    #ifdef __cplusplus
    }
    #endif
    #endif

    solved my problem immediately, and I can abandon use of _BIND_TO_CURRENT_VCLIBS_VERSION.

    Microsoft thinks that if I reinstall (repair) VC2008 the problem may go away but that remains to be tested, and that would be a fix only until the next SPn or OSn!

    I suspect that the install of Windows7 (not upgrade) does NOT really do a “clean” install with a completely new registry but carries over a good deal from the old registry in order to maintain control of the computer. I did NOT UNINSTALL VC2008 before I installed Windows7 and probably should have. I have a colleague who did an upgrade-in-place from Vista and he encountered a similar problem. So be warned and do a format of that partition next time or uninstall!

    At any rate my sincere thanks for your blog

    • tedwvc says:

      you’re welcome, great to hear a success story.

    • khelkun says:

      Right. It’s just amazing to consider this blog helped so much programmers who are releasing & redistributing an application supposed to be compliant with one or more Microsoft OS which insludes none or some “security” C++ runtime KB installed.
      I’ll tell you as I feel it: our world is going mad :)
      Cheers for the success story

  40. Pingback: SidebySide(WinSxS) issue « Nberserk's Blog

  41. Pingback: KB2465367 – a repeat of the KB971090 roll-out problems? « Ted's Blog

  42. Pingback: Updates are tempting, but are they safe? (about KB971090) | Wishful Thinking!

  43. Pingback: MS11-025 has been reissued – all previously mentioned problems have been solved « Ted's Blog

  44. Matt says:

    Dear Ted,

    First of all many thanks for your provided solution, i had to search many hours for that one. Unfortunately your solution leads to another problem for me: I am compiling a static library used in another project. The library itself is compiling fine, and if i check the manifest, only the 762 version of the CRT is referenced. But, when an executable in another project links to my library, it receives some linker errors apparently coming from the header:

    error LNK2005: __forceCRTManifest already defined in msvcrt.lib(crtmanifest.obj)

    Thanks
    Matt

    • khelkun says:

      Hi
      I guess you’ve already check what can be found on stackoverflow.com about you’re error but here’s a possible diagnostic : http://stackoverflow.com/questions/2728649/error-lnk2005-xxx-already-defined-in-msvcrt-libmsvcr100-dllc-something-libcm
      Dependency walker tool may help you to analyse which kind of libraries are loaded by your executable and by your homemade library.

    • tedwvc says:

      I haven’t tried this but try leaving out the
      __declspec(selectany) int _forceCRTManifest;

      (and the rest of the ones after that if applicable)

      when building the static library. I think that is only useful when building EXEs or DLLs.

      • Matt says:

        Hi Ted,

        Tank you very much, your answer helped me and saved me in the end a few hours or probably days of research. Your answer just lead me to one footstep before the working solution, but ironically this was causing another problem. After building everything with with this little correction (leaving out the declspec line), the static Libs were working and didnt had the linker errors, but instead every DLL wasn’t working anymore. If you leave out __declspec(selectany) int _forceCRTManifest in a DLL or EXE build, you will get the manifest Error again, because you will have a dependency to both the 762 and the newer runtime on your System. (In my case 6195).

        The problem now was to find something which will distinguish if i build a DLL/EXE or a static Library. For that purpose i found two preprocessormacros. (_WINDLL & _LIB) and changed the headerfile. Thats what it should look like to work in every case:

        #ifndef __midl
        # define _SXS_ASSEMBLY_VERSION “8.0.50727.762”
        # define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
        # define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
        # define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

        //Only use for EXE & DLL builds
        # if defined(_WINDLL) && !defined(_LIB)
        # ifdef __cplusplus
        extern “C” {
        # endif
        __declspec(selectany) int _forceCRTManifest;
        __declspec(selectany) int _forceMFCManifest;
        __declspec(selectany) int _forceAtlDllManifest;
        __declspec(selectany) int _forceCRTManifestRTM;
        __declspec(selectany) int _forceMFCManifestRTM;
        __declspec(selectany) int _forceAtlDllManifestRTM;
        # ifdef __cplusplus
        }
        # endif
        # endif
        #endif

        with best regards
        Matt

Leave a reply to Kulvinder Singh Cancel reply