www.pudn.com > ecc-0.3.16-src.zip > NewAPIs_Fixed.h
// == Following lines added by Erik:
#define COMPILE_NEWAPIS_STUBS
#define WANT_GETDISKFREESPACEEX_WRAPPER
#define WANT_GETLONGPATHNAME_WRAPPER
//#define WANT_GETFILEATTRIBUTESEX_WRAPPER
//#define WANT_ISDEBUGGERPRESENT_WRAPPER
// == End of lines added by Erik.
/*
Erik:
There were some errors in the original NewAPIs.h file.
The changes I made are below.
(1)
In this file I replaced all occurrences of:
SetLastError(ERROR_something);
to:
SetLastError((unsigned long)ERROR_something);
(2)
Near line 340 (this file) I changed this:
BOOL (CALLBACK *RealGetLongPathName)(LPCTSTR, LPTSTR, DWORD);
to:
DWORD (CALLBACK *RealGetLongPathName)(LPCTSTR, LPTSTR, DWORD);
*/
/*
* Copyright (c) 1997-1999, 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.
*
*/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/*****************************************************************************
*
* GetDiskFreeSpaceEx
*
*****************************************************************************/
#ifdef WANT_GETDISKFREESPACEEX_WRAPPER
#undef GetDiskFreeSpaceEx
#define GetDiskFreeSpaceEx _GetDiskFreeSpaceEx
extern BOOL (CALLBACK *GetDiskFreeSpaceEx)
(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
/*
* Exactly one file should define this symbol.
*/
#ifdef COMPILE_NEWAPIS_STUBS
/*
* The version to use if we are forced to emulate.
*/
static BOOL WINAPI
Emulate_GetDiskFreeSpaceEx(LPCTSTR ptszRoot, PULARGE_INTEGER pliQuota,
PULARGE_INTEGER pliTotal, PULARGE_INTEGER pliFree)
{
DWORD dwSecPerClus, dwBytesPerSec, dwFreeClus, dwTotalClus;
BOOL fRc;
fRc = GetDiskFreeSpace(ptszRoot, &dwSecPerClus, &dwBytesPerSec,
&dwFreeClus, &dwTotalClus);
if (fRc) {
DWORD dwBytesPerClus = dwSecPerClus * dwBytesPerSec;
/*
* Curiously, of all the output parameters, only pliFree is
* allowed to be NULL.
*/
*(__int64 *)pliQuota = Int32x32To64(dwBytesPerClus, dwFreeClus);
if (pliFree) {
*pliFree = *pliQuota;
}
*(__int64 *)pliTotal = Int32x32To64(dwBytesPerClus, dwTotalClus);
}
return fRc;
}
/*
* The stub that probes to decide which version to use.
*/
static BOOL WINAPI
Probe_GetDiskFreeSpaceEx(LPCTSTR ptszRoot, PULARGE_INTEGER pliQuota,
PULARGE_INTEGER pliTotal, PULARGE_INTEGER pliFree)
{
HINSTANCE hinst;
FARPROC fp;
BOOL fRc;
BOOL (CALLBACK *RealGetDiskFreeSpaceEx)
(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
hinst = GetModuleHandle(TEXT("KERNEL32"));
#ifdef UNICODE
fp = GetProcAddress(hinst, "GetDiskFreeSpaceExW");
#else
fp = GetProcAddress(hinst, "GetDiskFreeSpaceExA");
#endif
if (fp) {
*(FARPROC *)&RealGetDiskFreeSpaceEx = fp;
fRc = RealGetDiskFreeSpaceEx(ptszRoot, pliQuota, pliTotal, pliFree);
if (fRc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
GetDiskFreeSpaceEx = RealGetDiskFreeSpaceEx;
} else {
GetDiskFreeSpaceEx = Emulate_GetDiskFreeSpaceEx;
fRc = GetDiskFreeSpaceEx(ptszRoot, pliQuota, pliTotal, pliFree);
}
} else {
GetDiskFreeSpaceEx = Emulate_GetDiskFreeSpaceEx;
fRc = GetDiskFreeSpaceEx(ptszRoot, pliQuota, pliTotal, pliFree);
}
return fRc;
}
BOOL (CALLBACK *GetDiskFreeSpaceEx)
(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
Probe_GetDiskFreeSpaceEx;
#endif /* COMPILE_NEWAPIS_STUBS */
#endif /* WANT_GETDISKFREESPACEEX_WRAPPER */
/*****************************************************************************
*
* GetLongPathName
*
*****************************************************************************/
#ifdef WANT_GETLONGPATHNAME_WRAPPER
#include
#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((unsigned long)ERROR_BUFFER_OVERFLOW); // (unsigned long) by Erik
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((unsigned long)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((unsigned long)HRESULT_CODE(hr));
} else {
SetLastError((unsigned long)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((unsigned long)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((unsigned long)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;
// ERIK: Wrong! BOOL (CALLBACK *RealGetLongPathName)(LPCTSTR, LPTSTR, DWORD);
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 */
/*****************************************************************************
*
* GetFileAttributesEx
*
*****************************************************************************/
#ifdef WANT_GETFILEATTRIBUTESEX_WRAPPER
#undef GetFileAttributesEx
#define GetFileAttributesEx _GetFileAttributesEx
/*
* Really old header files don't even have definitions for these constants
* and structures.
*/
#if WINVER < 0x040A
typedef enum _GET_FILEEX_INFO_LEVELS {
GetFileExInfoStandard,
GetFileExMaxInfoLevel
} GET_FILEEX_INFO_LEVELS;
typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
#endif
extern BOOL (CALLBACK *GetFileAttributesEx)
(LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
/*
* Exactly one file should define this symbol.
*/
#ifdef COMPILE_NEWAPIS_STUBS
/*
* The version to use if we are forced to emulate.
*/
static BOOL WINAPI
Emulate_GetFileAttributesEx(LPCTSTR ptszFile, GET_FILEEX_INFO_LEVELS level,
LPVOID pv)
{
BOOL fRc;
if (level == GetFileExInfoStandard) {
/*
* Must call GetFileAttributes first to avoid returning random
* values if the so-called filename contains wildcards.
*/
if (GetFileAttributes(ptszFile) != 0xFFFFFFFF) {
HANDLE hfind;
WIN32_FIND_DATA wfd;
hfind = FindFirstFile(ptszFile, &wfd);
if (hfind != INVALID_HANDLE_VALUE) {
LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
FindClose(hfind);
pfad->dwFileAttributes = wfd.dwFileAttributes;
pfad->ftCreationTime = wfd.ftCreationTime;
pfad->ftLastAccessTime = wfd.ftLastAccessTime;
pfad->ftLastWriteTime = wfd.ftLastWriteTime;
pfad->nFileSizeHigh = wfd.nFileSizeHigh;
pfad->nFileSizeLow = wfd.nFileSizeLow;
fRc = TRUE;
} else {
/*
* FindFirstFile already called SetLastError() for us.
*/
fRc = FALSE;
}
} else {
/*
* GetFileAttributes already called SetLastError() for us.
*/
fRc = FALSE;
}
} else {
/*
* Unknown info level.
*/
SetLastError(ERROR_INVALID_PARAMETER);
fRc = FALSE;
}
return fRc;
}
/*
* The stub that probes to decide which version to use.
*/
static BOOL WINAPI
Probe_GetFileAttributesEx(LPCTSTR ptszFile, GET_FILEEX_INFO_LEVELS level,
LPVOID pv)
{
HINSTANCE hinst;
FARPROC fp;
BOOL fRc;
BOOL (CALLBACK *RealGetFileAttributesEx)
(LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
hinst = GetModuleHandle(TEXT("KERNEL32"));
#ifdef UNICODE
fp = GetProcAddress(hinst, "GetFileAttributesExW");
#else
fp = GetProcAddress(hinst, "GetFileAttributesExA");
#endif
if (fp) {
*(FARPROC *)&RealGetFileAttributesEx = fp;
fRc = RealGetFileAttributesEx(ptszFile, level, pv);
if (fRc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
GetFileAttributesEx = RealGetFileAttributesEx;
} else {
GetFileAttributesEx = Emulate_GetFileAttributesEx;
fRc = GetFileAttributesEx(ptszFile, level, pv);
}
} else {
GetFileAttributesEx = Emulate_GetFileAttributesEx;
fRc = GetFileAttributesEx(ptszFile, level, pv);
}
return fRc;
}
BOOL (CALLBACK *GetFileAttributesEx)
(LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID) =
Probe_GetFileAttributesEx;
#endif /* COMPILE_NEWAPIS_STUBS */
#endif /* WANT_GETFILEATTRIBUTESEX_WRAPPER */
/*****************************************************************************
*
* IsDebuggerPresent
*
*****************************************************************************/
#ifdef WANT_ISDEBUGGERPRESENT_WRAPPER
#define IsDebuggerPresent _IsDebuggerPresent
extern BOOL (CALLBACK *IsDebuggerPresent)(VOID);
/*
* Exactly one file should define this symbol.
*/
#ifdef COMPILE_NEWAPIS_STUBS
/*
* The version to use if we are forced to emulate.
*/
static BOOL WINAPI
Emulate_IsDebuggerPresent(VOID)
{
/* No way to tell, so just say "no". */
return FALSE;
}
/*
* The stub that probes to decide which version to use.
*/
static BOOL WINAPI
Probe_IsDebuggerPresent(VOID)
{
HINSTANCE hinst;
FARPROC fp;
BOOL (CALLBACK *RealIsDebuggerPresent)(VOID);
hinst = GetModuleHandle(TEXT("KERNEL32"));
fp = GetProcAddress(hinst, "IsDebuggerPresent");
if (fp) {
*(FARPROC *)&IsDebuggerPresent = fp;
} else {
IsDebuggerPresent = Emulate_IsDebuggerPresent;
}
return IsDebuggerPresent();
}
BOOL (CALLBACK *IsDebuggerPresent)(VOID) =
Probe_IsDebuggerPresent;
#endif /* COMPILE_NEWAPIS_STUBS */
#endif /* WANT_ISDEBUGGERPRESENT_WRAPPER */
#ifdef __cplusplus
}
#endif /* __cplusplus */