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.
Printable View
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.
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.
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
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.
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
I wonder was that really difficult to take a look if the API is supported by target OS?Quote:
Originally Posted by cmioci
Now you've got the reason. I hope that. :)Quote:
Originally Posted by MSDN
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 */
...
Well, and?.. Does it work for you? 'Cause personally me never need NT4 compatibility, you know... :D
Problem NOT solved.
Any info http://www.gamedev.net/community/for...opic_id=399282
Well, then you may take a look at my sample. The only thing is... to follow NewAPIs.h instructions literally. :DQuote:
Originally Posted by cmioci
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. :D
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.
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.
another way is to rebuild the msvcr80.dll for NT4 SP6
http://forums.microsoft.com/MSDN/Sho...46362&SiteID=1
Good info, thanks!Quote:
Originally Posted by Ted.