none
Draft: How to rebuild the 8.0 CRT Library for use on NT 4.0 SP6 RRS feed

  • General discussion

  • DRAFT 0.2 - comments welcome 

    HOW TO REBUILD THE 8.0 CRT LIBRARY FOR USE ON NT 4.0 SP6

    The shipping 8.0 C Runtime Library DLL (MSVCR80.DLL) does not support NT 4.0 SP6 for one reason and one reason only: someone at Microsoft added a function call to GetLongPathNameW which does not exist in kernel32.dll on NT 4.0.  You cannot delayload the CRT, therefore there's no way around it.  In order to run on NT 4.0, you must rebuild the MSVCR80.DLL to remove this reference.  

    Fortunately, very little work needs to be done to rebuild the 8.0 C Runtime Library DLL to support NT 4.0 SP6. 

    First, let's identify the location of the CRT source code.  It resides in a folder named:

     C:\Program Files\Microsoft Visual Studio 8\VC\CRT\SRC

    In the above folder, there is file named makefile.  This is what builds the CRT.  The default names provided in the makefile are _SAMPLE_, SAMPLE_P, SAMPLE_M, and SAMPLE_U. Each of these have both debug and release versions.  There are associated RC and DEF files for each of these names (however, SAMPLE_U does not have an associated RC)  We need to copy them to the names we require, i.e. do the following:

    copy _SAMPLE_.RC MSVCR80.RC
    copy SAMPLE_P.RC MSVCP80.RC
    copy SAMPLE_M.RC MSVCM80.RC
    copy SAMPLE_P.DEF MSVCP80.DEF
    copy SAMPLD_P.DEF MSVCP80D.DEF
    copy SAMPLE_M.DEF MSVCM80.DEF
    copy SAMPLD_M.DEF MSVCM80D.DEF
    copy SAMPLE_U.DEF MSVCU80.DEF
    copy SAMPLD_U.DEF MSVCU80D.DEF
    copy Intel\_SAMPLE_.DEF Intel\MSVCR80.DEF
    copy Intel\_SAMPLD_.DEF Intel\MSVCR80D.DEF

    Next we need to change the LIBRARY name inside each of the above 8 DEF files to match the name of the DEF file (an exception to this is MSVCU80.DEF and MSVCU80D.DEF - please use LIBRARY name MSVCM80 and MSVCM80D respectively) Open up each file in notepad to make the change.

    1. The provided makefile needs some minor changes to use the correct names.  Change the top block of defines to the following: RETAIL_DLL_NAME=MSVCR80
      RETAIL_LIB_NAME=MSVCR80
      RETAIL_DLLCPP_NAME=MSVCP80
      RETAIL_LIBCPP_NAME=MSVCP80
      RETAIL_DLLMIXED_NAME=MSVCM80
      RETAIL_LIBMIXED_NAME=MSVCM80
      RETAIL_LIBPURE_NAME=MSVCU80
      RETAIL_PT_LIBMIXED_NAME=PTRUSTM
      RETAIL_PT_LIBPURE_NAME=PTRUSTU
      DEBUG_DLL_NAME=MSVCR80D
      DEBUG_LIB_NAME=MSVCR80D
      DEBUG_DLLCPP_NAME=MSVCP80D
      DEBUG_LIBCPP_NAME=MSVCP80D
      DEBUG_DLLMIXED_NAME=MSVCM80D
      DEBUG_LIBMIXED_NAME=MSVCM80D
      DEBUG_LIBPURE_NAME=MSVCU80D
      DEBUG_PT_LIBMIXED_NAME=PTRUSTMD
      DEBUG_PT_LIBPURE_NAME=PTRUSTUD
      RC_NAME=MSVCR80
      RCCPP_NAME=MSVCP80
      RCMIXED_NAME=MSVCM80 
    2. The VCTOOLS path should be changed to point to the path where you installed Visual Studio 2005, e.g. VCTOOLS=C:\Program Files\Microsoft Visual Studio 8\VC
    3. We need to make a change to the following file: CRTLIB.C   On line 577, there is a call to GetLongPathNameW.  We could replace this code with code that does a GetProcAddress of the function call, but since it is never going to be called because we are definitely on a pre-fusion OS, you can simply replace it with:   ret = 0;    

    4. Once we make these changes, we are ready to build the DLLs. It's simple - launch a Visual Studio 2005 command prompt (start menu-programs-Microsoft Visual Studio 2005 - Visual Studio tools - Visual Studio 2005 command prompt) and then go to the C:\Program Files\Microsoft Visual Studio 8\VC\CRT\SRC folder and type the following two commands:

      set VCTOOLS=C:\Program Files\Microsoft Visual Studio 8\VC 
      BLDNT

      Once the DLLs finish building the newly created MSVCR80.DLL will be in a subfolder of SRC named BUILD\INTEL.  This is the DLL you need to use when shipping your app on NT 4.0 SP6. 

    Important Warning: do NOT use this MSVCR80.DLL on any other platform - only use it on NT 4.0.   DO NOT USE ANY OF THE OTHER DLLs that were built by this process (e.g. MSVCP80.DLL) - the originals are already fine on NT 4.0. 

    Second Important Warning: Microsoft does not support NT 4.0 officially starting with Visual C++ 2005.  So if you do decide to use the above rebuilt DLL, it is at your own risk.    I can tell you that I've tested some large apps using the above rebuilt DLL and it has worked just fine, however, do not go to Microsoft for support.

    Wednesday, November 23, 2005 11:13 PM

All replies

  • You must not use the same names of files.

    Please carefully review the EULA with your legal team before rebuilding CRT/MFC/ATL.

    Thanks,
    Nikola
    VC++
    Friday, December 9, 2005 7:10 PM
  • Yes, please use another name.  When you do use another name then you need to rebuild MFC, and msvcp80.dll with another name as well (if you require MFC or STL in your app).   More info on how to do this can be found here (ignoring the mentions of unicows and MSLU):

    http://blogs.msdn.com/michkap/articles/478235.aspx

    The appropriate section of eula.txt is quoted below:

    MFCs, ATLs and CRTs.  You may modify the source code form of Microsoft
    Foundation Classes (MFCs), Active Template Libraries (ATLs), and C runtimes
    (CRTs) to design, develop and test your programs, and copy and distribute
    the object code form of your modified files under a new name.
    Friday, December 9, 2005 8:52 PM
  • I've thought about rebuilding the CRTs to get NT4.0 to work. Has anyone checked out NewAPIs.h in their SDK include directory?

    That header contains a complete implementation of GetLongPathName (and IsDebuggerPresent) that works in Windows NT. So if you were to include this file after you include windows.h, it would call the real GetLongPathName if it's available, otherwise, it emulates it (using Shell32.dll).

    I'm also wondering why Microsoft didn't notice newapis.h, even though it was documented in MSDN (methinks they did notice it, but some other programmer came along, wondered what that #include line was for, and removed it).

     

    Friday, December 16, 2005 4:14 PM
    Moderator
  • I've heard NewApis.h is not thread safe.  You would have to rewrite it to fix that. 

    Even easier is the technique they already use in the code for other functions, which is to do a GetProcAddress, and call the function.  There is no point at all in writing the other side of it (downlevel GetLongPathName) because this code will never be executed on platforms that don't have fusion (WinSxS)

    i.e. in crtlib.c where GetLongPathNameW is called:

    typedef DWORD (WINAPI *PFN_GETLONGPATHNAME)(LPCWSTR, LPWSTR, DWORD);

      HINSTANCE hK32 = NULL;
      PFN_GETLONGPATHNAME pfnGetLongPathName = NULL;

    hK32 = GetModuleHandle("kernel32.dll");
            
    if (hK32 == NULL)
    {
        return TRUE;
    }

    pfnGetLongPathName = (PFN_GETLONGPATHNAME) GetProcAddress(hK32, "GetLongPathNameW");

    if (pfnGetLongPathName == NULL)
       ret = 0;
    else
       ret = pfnGetLongPathName(tempPath, moduleFilePath, _countof(moduleFilePath));
     

    Friday, December 16, 2005 4:29 PM
  • Special note for Visual Studio 2005 Service Pack 1 users:
    The Visual Studio 2005 Service Pack 1 C Runtime Library source code shipped with some minor problems that prevent it from being built successfully.   If you've installed Service Pack 1, please follow these steps before proceeding with the rest of the CRT rebuild instructions.
     
    1) In the SRC folder, two files need minor changes.  Open up the following two files in notepad and make these changes:
    a) in the MAKEFILE
     
        On lines 302, 303, 304, 307, 308 and 309, remove the -wx option
     
    b) In the MAKEFILE.SUB
     
        On line 103 remove the -wx option
    2) A file named unhandld.obj was inadvertently left out of the CRT source distribution.  To recover this file, we will extract it from the eh.lib library
    From a Visual Studio 2005 Command Prompt, do the following:
    C:
    CD \SRC
    for %i in (dll mt xdll xmt) do pushd intel\%i_lib && lib /extract:..\build\intel\%i_obj\unhandld.obj eh.lib && popd

    Thursday, September 6, 2007 4:33 AM