CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Sep 2005
    Location
    Italy
    Posts
    6

    Angry Microsoft VisualStudio2005 and NT4

    Hi everyone,
    I buy MVC2005 Professional Edition March 2006 and make MFC Dialog base application. Build and make exe. Run exe on SO NT4 ServicePack 6 and "... entry point GetLongPathNameW in Kernel32.dll" error. Why ?
    Thank for reply.

  2. #2
    Join Date
    Jul 2005
    Posts
    767

    Re: Microsoft VisualStudio2005 and NT4

    Check this link.
    where it is mentioned Windows NT and Windows 95: Include an additional header file called NewAPIs.h to make GetLongPathName available on these operating systems. The function is not implemented natively, but by a wrapper that uses other native functions on these systems. For details about using preprocessor directives that make the function available, see the header file. If you do not have this header file, you can download the most recent SDK from the SDK Update Site.

    Also if you use Unicode (which I beleive you do) you may have to install Microsoft Layer for Unicode.
    Last edited by MrBeans; June 20th, 2006 at 02:01 AM.

  3. #3
    Join Date
    Sep 2005
    Location
    Italy
    Posts
    6

    Post Re: Microsoft VisualStudio2005 and NT4

    Step:

    - Insert include, #include <NewAPIs.h>, in stafx.h
    - Compiled in Release Win32
    - Copy in target PC (with SO NT4 SP6) .exe file and mfc80u.dll, msvcr80.dll

    but error persist, GetLongPathNameW in Kernel32.dll

  4. #4
    Join Date
    Jul 2005
    Posts
    767

    Re: Microsoft VisualStudio2005 and NT4

    What version of kernel32.dll do you use?
    Check your kernel32.dll version using depends tool. Also check if GetLongPathNameW exists in your kernel32.dll.

    Also did you try to install Microsoft Layer for Unicode.

  5. #5
    Join Date
    Sep 2005
    Location
    Italy
    Posts
    6

    Post Re: Microsoft VisualStudio2005 and NT4

    Steps:
    - Download Dependency Walker Version 2.1.3623 for X86 (Windows 95 / 98 / Me / NT / 2000 / XP / 2003) [415k]

    - run it

    - report:

    --- System Information ---
    Dependency Walker: 2.1.3623 (32-bit)
    Operating System: Microsoft Windows NT Professional (32-bit)
    OS Version: 4.00.1381 Service Pack 6
    Processor: x86 Family 5 Model 8 Stepping 1, GenuineIntel, ~267MHz
    Number of Processors: 1
    Computer Name: SCCI4
    User Name: Administrator
    Local Date: martedì 20 giugno 2006
    Local Time: 10.44.53 ora legale Europa occ. (GMT+02:00)
    OS Language: 0x0410: Italian (Standard)
    Memory Load: 0%
    Physical Memory Total: 133.615.616 (128 MB)
    Physical Memory Used: 98.770.944
    Physical Memory Free: 34.844.672
    Page File Memory Total: 1.194.180.608
    Page File Memory Used: 173.637.632
    Page File Memory Free: 1.020.542.976
    Virtual Memory Total: 2.147.352.576
    Virtual Memory Used: 27.906.048
    Virtual Memory Free: 2.119.446.528
    Page Size: 0x00001000 (4.096)
    Allocation Granularity: 0x00010000 (65.536)
    Min. App. Address: 0x00010000 (65.536)
    Max. App. Address: 0x7FFEFFFF (2.147.418.111)

    --- Module List (only KERNEL32.DLL) ---
    Module: KERNEL32.DLL
    File Time Stamp: 30/11/1999 12.06
    Link Time Stamp: 21/07/1999 0.19
    File Size: 83.248
    File Ver : 4.0.1381.300
    ...
    Product Ver: 4.0.1381.300
    Image Ver: 4.0
    Linker Ver: 3.10
    OS Ver: 4.0
    Subsystem Ver: 4.0

    - Not found GetLongPathNameW

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Microsoft VisualStudio2005 and NT4

    Quote Originally Posted by cmioci
    - Not found GetLongPathNameW
    I wonder was that really difficult to take a look if the API is supported by target OS?

    Quote Originally Posted by MSDN
    Platform SDK: Storage
    GetLongPathName
    . . .
    Requirements
    Client: Included in Windows XP, Windows 2000 Professional, Windows Me, and Windows 98.
    Server: Included in Windows Server 2003 and Windows 2000 Server.
    Now you've got the reason. I hope that.
    Best regards,
    Igor

  7. #7
    Join Date
    Sep 2005
    Location
    Italy
    Posts
    6

    Smile Re: Microsoft VisualStudio2005 and NT4

    Look into NewAPIs.h header:

    /*
    * Copyright (c) 1997-2004, Microsoft Corporation
    *
    * Wrapper module that "stubs" APIs that were not implemented
    * on Windows 95 or Windows NT versions less than 4.0 SP 3.
    *
    * By using this header, your code will run on older platforms.
    *
    * To enable a particular wrapper, define the corresponding symbol.
    *
    * Function Symbol
    *
    * GetDiskFreeSpaceEx WANT_GETDISKFREESPACEEX_WRAPPER
    * GetLongPathName WANT_GETLONGPATHNAME_WRAPPER
    * GetFileAttributesEx WANT_GETFILEATTRIBUTESEX_WRAPPER
    * IsDebuggerPresent WANT_ISDEBUGGERPRESENT_WRAPPER
    *
    * Exactly one source file must include the line
    *
    * #define COMPILE_NEWAPIS_STUBS
    *
    * before including this file.
    *
    */

    ...

    *****************************************************************************
    *
    * GetLongPathName
    *
    *****************************************************************************/

    #ifdef WANT_GETLONGPATHNAME_WRAPPER

    #include <shlobj.h>

    #undef GetLongPathName
    #define GetLongPathName _GetLongPathName

    extern DWORD (CALLBACK *GetLongPathName)(LPCTSTR, LPTSTR, DWORD);

    /*
    * Exactly one file should define this symbol.
    */
    #ifdef COMPILE_NEWAPIS_STUBS

    /*
    * The version to use if we are forced to emulate.
    */
    static DWORD WINAPI
    Emulate_GetLongPathName(LPCTSTR ptszShort, LPTSTR ptszLong, DWORD ctchBuf)
    {
    LPSHELLFOLDER psfDesk;
    HRESULT hr;
    LPITEMIDLIST pidl;
    TCHAR tsz[MAX_PATH]; /* Scratch TCHAR buffer */
    DWORD dwRc;
    LPMALLOC pMalloc;

    /*
    * The file had better exist. GetFileAttributes() will
    * not only tell us, but it'll even call SetLastError()
    * for us.
    */
    if (GetFileAttributes(ptszShort) == 0xFFFFFFFF) {
    return 0;
    }

    /*
    * First convert from relative path to absolute path.
    * This uses the scratch TCHAR buffer.
    */
    dwRc = GetFullPathName(ptszShort, MAX_PATH, tsz, NULL);
    if (dwRc == 0) {
    /*
    * Failed; GFPN already did SetLastError().
    */
    } else if (dwRc >= MAX_PATH) {
    /*
    * Resulting path would be too long.
    */
    SetLastError(ERROR_BUFFER_OVERFLOW);
    dwRc = 0;
    } else {
    /*
    * Just right.
    */
    hr = SHGetDesktopFolder(&psfDesk);
    if (SUCCEEDED(hr)) {
    ULONG cwchEaten;

    #ifdef UNICODE
    #ifdef __cplusplus
    hr = psfDesk->ParseDisplayName(NULL, NULL, tsz,
    &cwchEaten, &pidl, NULL);
    #else
    hr = psfDesk->lpVtbl->ParseDisplayName(psfDesk, NULL, NULL, tsz,
    &cwchEaten, &pidl, NULL);
    #endif
    #else
    WCHAR wsz[MAX_PATH]; /* Scratch WCHAR buffer */

    /*
    * ParseDisplayName requires UNICODE, so we use
    * the scratch WCHAR buffer during the conversion.
    */
    dwRc = MultiByteToWideChar(
    AreFileApisANSI() ? CP_ACP : CP_OEMCP,
    0, tsz, -1, wsz, MAX_PATH);
    if (dwRc == 0) {
    /*
    * Couldn't convert to UNICODE. MB2WC uses
    * ERROR_INSUFFICIENT_BUFFER, which we convert
    * to ERROR_BUFFER_OVERFLOW. Any other error
    * we leave alone.
    */
    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
    SetLastError(ERROR_BUFFER_OVERFLOW);
    }
    dwRc = 0;
    } else {
    #ifdef __cplusplus
    hr = psfDesk->ParseDisplayName(NULL, NULL, wsz,
    &cwchEaten, &pidl, NULL);
    #else
    hr = psfDesk->lpVtbl->ParseDisplayName(psfDesk, NULL, NULL,
    wsz, &cwchEaten, &pidl, NULL);
    #endif
    #endif

    if (FAILED(hr)) {
    /*
    * Weird. Convert the result back to a Win32
    * error code if we can. Otherwise, use the
    * generic "duh" error code ERROR_INVALID_DATA.
    */
    if (HRESULT_FACILITY(hr) == FACILITY_WIN32) {
    SetLastError(HRESULT_CODE(hr));
    } else {
    SetLastError(ERROR_INVALID_DATA);
    }
    dwRc = 0;
    } else {
    /*
    * Convert the pidl back to a filename in the
    * TCHAR scratch buffer.
    */
    dwRc = SHGetPathFromIDList(pidl, tsz);
    if (dwRc == 0 && tsz[0]) {
    /*
    * Bizarre failure.
    */
    SetLastError(ERROR_INVALID_DATA);
    } else {
    /*
    * Copy the result back to the user's buffer.
    */
    dwRc = lstrlen(tsz);
    if (dwRc + 1 > ctchBuf) {
    /*
    * On buffer overflow, return necessary
    * size including terminating null (+1).
    */
    SetLastError(ERROR_INSUFFICIENT_BUFFER);
    dwRc = dwRc + 1;
    } else {
    /*
    * On buffer okay, return actual size not
    * including terminating null.
    */
    lstrcpyn(ptszLong, tsz, ctchBuf);
    }
    }

    /*
    * Free the pidl.
    */
    if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
    #ifdef __cplusplus
    pMalloc->Free(pidl);
    pMalloc->Release();
    #else
    pMalloc->lpVtbl->Free(pMalloc, pidl);
    pMalloc->lpVtbl->Release(pMalloc);
    #endif
    }
    }
    #ifndef UNICODE
    }
    #endif
    /*
    * Release the desktop folder now that we no longer
    * need it.
    */
    #ifdef __cplusplus
    psfDesk->Release();
    #else
    psfDesk->lpVtbl->Release(psfDesk);
    #endif
    }
    }
    return dwRc;
    }

    /*
    * The stub that probes to decide which version to use.
    */
    static DWORD WINAPI
    Probe_GetLongPathName(LPCTSTR ptszShort, LPTSTR ptszLong, DWORD ctchBuf)
    {
    HINSTANCE hinst;
    FARPROC fp;
    DWORD dwRc;
    DWORD (CALLBACK *RealGetLongPathName)(LPCTSTR, LPTSTR, DWORD);

    hinst = GetModuleHandle(TEXT("KERNEL32"));
    #ifdef UNICODE
    fp = GetProcAddress(hinst, "GetLongPathNameW");
    #else
    fp = GetProcAddress(hinst, "GetLongPathNameA");
    #endif

    if (fp) {
    *(FARPROC *)&RealGetLongPathName = fp;
    dwRc = RealGetLongPathName(ptszShort, ptszLong, ctchBuf);
    if (dwRc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
    GetLongPathName = RealGetLongPathName;
    } else {
    GetLongPathName = Emulate_GetLongPathName;
    dwRc = GetLongPathName(ptszShort, ptszLong, ctchBuf);
    }
    } else {
    GetLongPathName = Emulate_GetLongPathName;
    dwRc = GetLongPathName(ptszShort, ptszLong, ctchBuf);
    }

    return dwRc;

    }

    DWORD (CALLBACK *GetLongPathName)(LPCTSTR, LPTSTR, DWORD) =
    Probe_GetLongPathName;

    #endif /* COMPILE_NEWAPIS_STUBS */
    #endif /* WANT_GETLONGPATHNAME_WRAPPER */
    ...

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Microsoft VisualStudio2005 and NT4

    Well, and?.. Does it work for you? 'Cause personally me never need NT4 compatibility, you know...
    Best regards,
    Igor

  9. #9
    Join Date
    Sep 2005
    Location
    Italy
    Posts
    6

    Thumbs down Re: Microsoft VisualStudio2005 and NT4


  10. #10
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Microsoft VisualStudio2005 and NT4

    Quote Originally Posted by cmioci
    Problem NOT solved.
    Well, then you may take a look at my sample. The only thing is... to follow NewAPIs.h instructions literally.

    In a single file you create stub implementation (using #define COMPILE_NEWAPIS_STUBS definition), and anywhere else you use #define WANT_GETLONGPATHNAME_WRAPPER definition. After that you never forget to include stub .obj file into compilation. In my case it was stdafx.obj, but you definitely may use any other one.

    Being compiled the .exe file has no GetLongPathName import from kernel32.

    Hope this will hepl.

    BTW, I have no VS2005. Thank you for citing header.
    Attached Files Attached Files
    Best regards,
    Igor

  11. #11
    Join Date
    Apr 2008
    Posts
    1

    Re: Microsoft VisualStudio2005 and NT4

    Did you manage to compile for NT4 now?

    I was just playing around with VS2005 and VS2008 to check compatibility for NT4...
    I was able to run an STATICALLY compiled MFC build on NT4 - but it was a really small application as a first step.

  12. #12
    Join Date
    Nov 2006
    Posts
    3

    Re: Microsoft VisualStudio2005 and NT4

    There is a simple solution:

    Go to:
    Project settings
    C\C++
    Code Generation
    under Runtime Library select "Multi-Threaded (/MT)"

    I've just hit the same road block trying to test my DLL. After setting this to /MT, the DLL size went up a lot but it now works perfectly fine in Win NT4 SP6.

  13. #13
    Join Date
    Jun 2006
    Posts
    25

    Re: Microsoft VisualStudio2005 and NT4

    another way is to rebuild the msvcr80.dll for NT4 SP6

    http://forums.microsoft.com/MSDN/Sho...46362&SiteID=1

  14. #14
    Join Date
    Nov 2006
    Posts
    3

    Re: Microsoft VisualStudio2005 and NT4

    Quote Originally Posted by Ted.
    another way is to rebuild the msvcr80.dll for NT4 SP6

    http://forums.microsoft.com/MSDN/Sho...46362&SiteID=1
    Good info, thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured