#include "dxwnd.h" #include "dxwcore.hpp" #include "syslibs.h" #include "dxhook.h" #include "dxhelper.h" #include "hddraw.h" #include "ddproxy.h" #include "stdio.h" //#undef IsTraceDW //#define IsTraceDW TRUE BOOL WINAPI extCheckRemoteDebuggerPresent(HANDLE, PBOOL); typedef BOOL (WINAPI *CreateProcessA_Type)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION); CreateProcessA_Type pCreateProcessA = NULL; // v2.02.96: the GetSystemInfo API is NOT hot patchable on Win7. This can cause problems because it can't be hooked by simply // enabling hot patch. A solution is making all LiadLibrary* calls hot patchable, so that when loading the module, the call // can be hooked by the IAT lookup. This fixes a problem after movie playing in Wind Fantasy SP. static HookEntry_Type Hooks[]={ {HOOK_IAT_CANDIDATE, "IsDebuggerPresent", (FARPROC)NULL, (FARPROC *)NULL, (FARPROC)extIsDebuggerPresent}, {HOOK_IAT_CANDIDATE, "CheckRemoteDebuggerPresent", (FARPROC)NULL, (FARPROC *)NULL, (FARPROC)extCheckRemoteDebuggerPresent}, {HOOK_IAT_CANDIDATE, "GetProcAddress", (FARPROC)GetProcAddress, (FARPROC *)&pGetProcAddress, (FARPROC)extGetProcAddress}, {HOOK_HOT_CANDIDATE, "LoadLibraryA", (FARPROC)LoadLibraryA, (FARPROC *)&pLoadLibraryA, (FARPROC)extLoadLibraryA}, {HOOK_HOT_CANDIDATE, "LoadLibraryExA", (FARPROC)LoadLibraryExA, (FARPROC *)&pLoadLibraryExA, (FARPROC)extLoadLibraryExA}, {HOOK_HOT_CANDIDATE, "LoadLibraryW", (FARPROC)LoadLibraryW, (FARPROC *)&pLoadLibraryW, (FARPROC)extLoadLibraryW}, {HOOK_HOT_CANDIDATE, "LoadLibraryExW", (FARPROC)LoadLibraryExW, (FARPROC *)&pLoadLibraryExW, (FARPROC)extLoadLibraryExW}, {HOOK_IAT_CANDIDATE, "GetDriveTypeA", (FARPROC)NULL, (FARPROC *)&pGetDriveType, (FARPROC)extGetDriveType}, {HOOK_IAT_CANDIDATE, "GetLogicalDrives", (FARPROC)NULL, (FARPROC *)&pGetLogicalDrives, (FARPROC)extGetLogicalDrives}, {HOOK_IAT_CANDIDATE, "GetTempFileNameA", (FARPROC)GetTempFileNameA, (FARPROC *)&pGetTempFileName, (FARPROC)extGetTempFileName}, {HOOK_IAT_CANDIDATE, "CreateProcessA", (FARPROC)NULL, (FARPROC *)&pCreateProcessA, (FARPROC)extCreateProcessA}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type FixIOHooks[]={ {HOOK_IAT_CANDIDATE, "ReadFile", (FARPROC)NULL, (FARPROC *)&pReadFile, (FARPROC)extReadFile}, {HOOK_IAT_CANDIDATE, "CreateFileA", (FARPROC)NULL, (FARPROC *)&pCreateFile, (FARPROC)extCreateFile}, {HOOK_IAT_CANDIDATE, "SetFilePointer", (FARPROC)NULL, (FARPROC *)&pSetFilePointer, (FARPROC)extSetFilePointer}, {HOOK_IAT_CANDIDATE, "CloseHandle", (FARPROC)NULL, (FARPROC *)&pCloseHandle, (FARPROC)extCloseHandle}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type LimitHooks[]={ {HOOK_HOT_CANDIDATE, "GetDiskFreeSpaceA", (FARPROC)GetDiskFreeSpaceA, (FARPROC *)&pGetDiskFreeSpaceA, (FARPROC)extGetDiskFreeSpaceA}, {HOOK_HOT_CANDIDATE, "GlobalMemoryStatus", (FARPROC)GlobalMemoryStatus, (FARPROC *)&pGlobalMemoryStatus, (FARPROC)extGlobalMemoryStatus}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type TimeHooks[]={ {HOOK_HOT_CANDIDATE, "GetTickCount", (FARPROC)GetTickCount, (FARPROC *)&pGetTickCount, (FARPROC)extGetTickCount}, {HOOK_HOT_CANDIDATE, "GetLocalTime", (FARPROC)GetLocalTime, (FARPROC *)&pGetLocalTime, (FARPROC)extGetLocalTime}, {HOOK_HOT_CANDIDATE, "GetSystemTime", (FARPROC)GetSystemTime, (FARPROC *)&pGetSystemTime, (FARPROC)extGetSystemTime}, {HOOK_HOT_CANDIDATE, "GetSystemTimeAsFileTime", (FARPROC)GetSystemTimeAsFileTime, (FARPROC *)&pGetSystemTimeAsFileTime, (FARPROC)extGetSystemTimeAsFileTime}, {HOOK_HOT_CANDIDATE, "Sleep", (FARPROC)Sleep, (FARPROC *)&pSleep, (FARPROC)extSleep}, {HOOK_HOT_CANDIDATE, "SleepEx", (FARPROC)SleepEx, (FARPROC *)&pSleepEx, (FARPROC)extSleepEx}, {HOOK_HOT_CANDIDATE, "QueryPerformanceCounter", (FARPROC)QueryPerformanceCounter, (FARPROC *)&pQueryPerformanceCounter, (FARPROC)extQueryPerformanceCounter}, {HOOK_HOT_CANDIDATE, "QueryPerformanceFrequency", (FARPROC)QueryPerformanceFrequency, (FARPROC *)&pQueryPerformanceFrequency, (FARPROC)extQueryPerformanceFrequency}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static HookEntry_Type VersionHooks[]={ {HOOK_IAT_CANDIDATE, "GetVersion", (FARPROC)GetVersion, (FARPROC *)&pGetVersion, (FARPROC)extGetVersion}, {HOOK_IAT_CANDIDATE, "GetVersionExA", (FARPROC)GetVersionExA, (FARPROC *)&pGetVersionExA, (FARPROC)extGetVersionExA}, {HOOK_IAT_CANDIDATE, "GetVersionExW", (FARPROC)GetVersionExW, (FARPROC *)&pGetVersionExW, (FARPROC)extGetVersionExW}, {HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator }; static char *libname = "kernel32.dll"; void HookKernel32(HMODULE module) { HookLibrary(module, Hooks, libname); if(dxw.dwFlags3 & BUFFEREDIOFIX) HookLibrary(module, FixIOHooks, libname); if(dxw.dwFlags2 & LIMITRESOURCES) HookLibrary(module, LimitHooks, libname); if(dxw.dwFlags2 & TIMESTRETCH) HookLibrary(module, TimeHooks, libname); if(dxw.dwFlags2 & FAKEVERSION) HookLibrary(module, VersionHooks, libname); } void HookKernel32Init() { HookLibInit(Hooks); HookLibInit(LimitHooks); HookLibInit(TimeHooks); HookLibInit(VersionHooks); } FARPROC Remap_kernel32_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; if (dxw.dwFlags4 & NOPERFCOUNTER){ if( !strcmp(proc, "QueryPerformanceCounter") || !strcmp(proc, "QueryPerformanceFrequency")){ OutTraceDW("GetProcAddress: HIDING proc=%s\n", proc); return NULL; } } if (addr=RemapLibrary(proc, hModule, Hooks)) return addr; if(dxw.dwFlags3 & BUFFEREDIOFIX) if (addr=RemapLibrary(proc, hModule, FixIOHooks)) return addr; if(dxw.dwFlags2 & LIMITRESOURCES) if (addr=RemapLibrary(proc, hModule, LimitHooks)) return addr; if(dxw.dwFlags2 & TIMESTRETCH) if (addr=RemapLibrary(proc, hModule, TimeHooks)) return addr; if(dxw.dwFlags2 & FAKEVERSION) if (addr=RemapLibrary(proc, hModule, VersionHooks)) return addr; return NULL; } extern DirectDrawEnumerate_Type pDirectDrawEnumerate; extern DirectDrawEnumerateEx_Type pDirectDrawEnumerateEx; extern void HookModule(HMODULE, int); int WINAPI extIsDebuggerPresent(void) { OutTraceDW("extIsDebuggerPresent: return FALSE\n"); return FALSE; } BOOL WINAPI extGetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters) { BOOL ret; OutTraceDW("GetDiskFreeSpace: RootPathName=\"%s\"\n", lpRootPathName); ret=(*pGetDiskFreeSpaceA)(lpRootPathName, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters); if(!ret) OutTraceE("GetDiskFreeSpace: ERROR err=%d at %d\n", GetLastError(), __LINE__); *lpNumberOfFreeClusters = 16000; return ret; } /* ------------------------------------------------------------------------------- GlobalMemoryStatus: MSDN documents that on modern PCs that have more than DWORD memory values the GlobalMemoryStatus sets the fields to -1 (0xFFFFFFFF) and you should use GlobalMemoryStatusEx instead. But in some cases the value is less that DWORD max, but greater that DWORD>>1, that is the calling application may get a big value and see it as a signed negative value, as it happened to Nocturne on my PC. That's why it's not adviseable to write: if(lpBuffer->dwTotalPhys== -1) ... but this way: if ((int)lpBuffer->dwTotalPhys < 0) ... and also don't set BIGENOUGH 0x80000000 // possibly negative!!! but: BIGENOUGH 0x20000000 // surely positive !!! /* ---------------------------------------------------------------------------- */ #define BIGENOUGH 0x20000000 void WINAPI extGlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { (*pGlobalMemoryStatus)(lpBuffer); OutTraceDW("GlobalMemoryStatus: Length=%x MemoryLoad=%x " "TotalPhys=%x AvailPhys=%x TotalPageFile=%x AvailPageFile=%x TotalVirtual=%x AvailVirtual=%x\n", lpBuffer->dwMemoryLoad, lpBuffer->dwTotalPhys, lpBuffer->dwAvailPhys, lpBuffer->dwTotalPageFile, lpBuffer->dwAvailPageFile, lpBuffer->dwTotalVirtual, lpBuffer->dwAvailVirtual); if(lpBuffer->dwLength==sizeof(MEMORYSTATUS)){ if ((int)lpBuffer->dwTotalPhys < 0) lpBuffer->dwTotalPhys = BIGENOUGH; if ((int)lpBuffer->dwAvailPhys < 0) lpBuffer->dwAvailPhys = BIGENOUGH; if ((int)lpBuffer->dwTotalPageFile < 0) lpBuffer->dwTotalPageFile = BIGENOUGH; if ((int)lpBuffer->dwAvailPageFile < 0) lpBuffer->dwAvailPageFile = BIGENOUGH; if ((int)lpBuffer->dwTotalVirtual < 0) lpBuffer->dwTotalVirtual = BIGENOUGH; if ((int)lpBuffer->dwAvailVirtual < 0) lpBuffer->dwAvailVirtual = BIGENOUGH; } } /* From MSDN: Operating system Version number dwMajorVersion dwMinorVersion Other Windows 8 6.2 6 2 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION Windows Server 2012 6.2 6 2 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION Windows 7 6.1 6 1 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION Windows Server 2008 R2 6.1 6 1 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION Windows Server 2008 6.0 6 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION Windows Vista 6.0 6 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION Windows Server 2003 R2 5.2 5 2 GetSystemMetrics(SM_SERVERR2) != 0 Windows Home Server 5.2 5 2 OSVERSIONINFOEX.wSuiteMask & VER_SUITE_WH_SERVER Windows Server 2003 5.2 5 2 GetSystemMetrics(SM_SERVERR2) == 0 Windows XP Pro x64 Ed. 5.2 5 2 (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) Windows XP 5.1 5 1 Not applicable Windows 2000 5.0 5 0 Not applicable From http://delphi.about.com/cs/adptips2000/a/bltip1100_2.htm Windows 95 4.0 4 0 Windows 98/SE" 4.10 4 10 if osVerInfo.szCSDVersion[1] = 'A' then Windows98SE Windows ME 4.90 4 90 */ static struct {char bMajor; char bMinor; char *sName;} WinVersions[9]= { {4, 0, "Windows 95"}, {4,10, "Windows 98/SE"}, {4,90, "Windows ME"}, {5, 0, "Windows 2000"}, {5, 1, "Windows XP"}, {5, 2, "Windows Server 2003"}, {6, 0, "Windows Vista"}, {6, 1, "Windows 7"}, {6, 2, "Windows 8"} }; BOOL WINAPI extGetVersionExA(LPOSVERSIONINFOA lpVersionInfo) { BOOL ret; ret=(*pGetVersionExA)(lpVersionInfo); if(!ret) { OutTraceE("GetVersionEx: ERROR err=%d\n", GetLastError()); return ret; } OutTraceDW("GetVersionEx: version=%d.%d build=(%d)\n", lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber); if(dxw.dwFlags2 & FAKEVERSION) { // fake Win XP build 0 lpVersionInfo->dwMajorVersion = WinVersions[dxw.FakeVersionId].bMajor; lpVersionInfo->dwMinorVersion = WinVersions[dxw.FakeVersionId].bMinor; lpVersionInfo->dwBuildNumber = 0; OutTraceDW("GetVersionEx: FIXED version=%d.%d build=(%d) os=\"%s\"\n", lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber, WinVersions[dxw.FakeVersionId].sName); } return TRUE; } BOOL WINAPI extGetVersionExW(LPOSVERSIONINFOW lpVersionInfo) { BOOL ret; ret=(*pGetVersionExW)(lpVersionInfo); if(!ret) { OutTraceE("GetVersionEx: ERROR err=%d\n", GetLastError()); return ret; } OutTraceDW("GetVersionEx: version=%d.%d build=(%d)\n", lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber); if(dxw.dwFlags2 & FAKEVERSION) { // fake Win XP build 0 lpVersionInfo->dwMajorVersion = WinVersions[dxw.FakeVersionId].bMajor; lpVersionInfo->dwMinorVersion = WinVersions[dxw.FakeVersionId].bMinor; lpVersionInfo->dwBuildNumber = 0; OutTraceDW("GetVersionEx: FIXED version=%d.%d build=(%d) os=\"%ls\"\n", lpVersionInfo->dwMajorVersion, lpVersionInfo->dwMinorVersion, lpVersionInfo->dwBuildNumber, WinVersions[dxw.FakeVersionId].sName); } return TRUE; } DWORD WINAPI extGetVersion(void) { DWORD dwVersion; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuild = 0; dwVersion = (*pGetVersion)(); // Get the Windows version. dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); // Get the build number. if (dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion)); OutTraceDW("GetVersion: version=%d.%d build=(%d)\n", dwMajorVersion, dwMinorVersion, dwBuild); if(dxw.dwFlags2 & FAKEVERSION) { dwVersion = WinVersions[dxw.FakeVersionId].bMajor | (WinVersions[dxw.FakeVersionId].bMinor << 8); dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); dwBuild = (DWORD)(HIWORD(dwVersion)); OutTraceDW("GetVersion: FIXED version=%d.%d build=(%d) os=\"%s\"\n", dwMajorVersion, dwMinorVersion, dwBuild, WinVersions[dxw.FakeVersionId].sName); } return dwVersion; } /* ------------------------------------------------------------------------------- time related APIs /* ---------------------------------------------------------------------------- */ DWORD WINAPI extGetTickCount(void) { return dxw.GetTickCount(); } void WINAPI extGetSystemTime(LPSYSTEMTIME lpSystemTime) { dxw.GetSystemTime(lpSystemTime); if (IsDebug) OutTrace("GetSystemTime: %02d:%02d:%02d.%03d\n", lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond, lpSystemTime->wMilliseconds); } void WINAPI extGetLocalTime(LPSYSTEMTIME lpLocalTime) { SYSTEMTIME SystemTime; dxw.GetSystemTime(&SystemTime); SystemTimeToTzSpecificLocalTime(NULL, &SystemTime, lpLocalTime); if (IsDebug) OutTrace("GetLocalTime: %02d:%02d:%02d.%03d\n", lpLocalTime->wHour, lpLocalTime->wMinute, lpLocalTime->wSecond, lpLocalTime->wMilliseconds); } VOID WINAPI extSleep(DWORD dwMilliseconds) { DWORD dwNewDelay; dwNewDelay=dwMilliseconds; if ((dwMilliseconds!=INFINITE) && (dwMilliseconds!=0)){ dwNewDelay = dxw.StretchTime(dwMilliseconds); if (dwNewDelay==0) dwNewDelay=1; // minimum allowed... } if (IsDebug) OutTrace("Sleep: msec=%d->%d timeshift=%d\n", dwMilliseconds, dwNewDelay, dxw.TimeShift); (*pSleep)(dwNewDelay); } DWORD WINAPI extSleepEx(DWORD dwMilliseconds, BOOL bAlertable) { DWORD dwNewDelay; dwNewDelay=dwMilliseconds; if ((dwMilliseconds!=INFINITE) && (dwMilliseconds!=0)){ dwNewDelay = dxw.StretchTime(dwMilliseconds); if (dwNewDelay==0) dwNewDelay=1; // minimum allowed... } if (IsDebug) OutTrace("SleepEx: msec=%d->%d alertable=%x, timeshift=%d\n", dwMilliseconds, dwNewDelay, bAlertable, dxw.TimeShift); return (*pSleepEx)(dwNewDelay, bAlertable); } void WINAPI extGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) { if (IsDebug) OutTrace("GetSystemTimeAsFileTime\n"); dxw.GetSystemTimeAsFileTime(lpSystemTimeAsFileTime); } BOOL WINAPI extQueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) { BOOL ret; if(dxw.dwFlags4 & NOPERFCOUNTER){ ret=0; (*lpPerformanceCount).QuadPart = 0; } else{ LARGE_INTEGER CurrentInCount; ret=(*pQueryPerformanceCounter)(&CurrentInCount); *lpPerformanceCount = dxw.StretchLargeCounter(CurrentInCount); } OutTraceB("QueryPerformanceCounter: ret=%x Count=[%x-%x]\n", ret, lpPerformanceCount->HighPart, lpPerformanceCount->LowPart); return ret; } BOOL WINAPI extQueryPerformanceFrequency(LARGE_INTEGER *lpPerformanceFrequency) { BOOL ret; if(dxw.dwFlags4 & NOPERFCOUNTER){ LARGE_INTEGER myPerfFrequency; myPerfFrequency.LowPart = 0L; myPerfFrequency.HighPart = 0L; *lpPerformanceFrequency=myPerfFrequency; ret = 0; } else ret=(*pQueryPerformanceFrequency)(lpPerformanceFrequency); OutTraceDW("QueryPerformanceFrequency: ret=%x Frequency=%x-%x\n", ret, lpPerformanceFrequency->HighPart, lpPerformanceFrequency->LowPart); return ret; } /* ------------------------------------------------------------------------------- LoadLibrary (hooking) related APIs /* ---------------------------------------------------------------------------- */ HMODULE SysLibs[SYSLIBIDX_MAX]; HMODULE WINAPI LoadLibraryExWrapper(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags, char *api) { HMODULE libhandle; int idx; libhandle=(*pLoadLibraryExA)(lpFileName, hFile, dwFlags); OutTraceDW("%s: FileName=%s hFile=%x Flags=%x(%s) hmodule=%x\n", api, lpFileName, hFile, dwFlags, ExplainLoadLibFlags(dwFlags), libhandle); if(!libhandle){ OutTraceE("%s: ERROR FileName=%s err=%d\n", api, lpFileName, GetLastError()); return libhandle; } // when loaded with LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flags, // there's no symbol map, then itěs no possible to hook function calls. if(dwFlags & (LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE|LOAD_LIBRARY_AS_DATAFILE)) return libhandle; idx=dxw.GetDLLIndex((char *)lpFileName); if(idx != -1) { OutTraceDW("%s: push idx=%x library=%s hdl=%x\n", api, idx, lpFileName, libhandle); SysLibs[idx]=libhandle; } // handle custom OpenGL library if(!lstrcmpi(lpFileName,dxw.CustomOpenGLLib)){ idx=SYSLIBIDX_OPENGL; SysLibs[idx]=libhandle; } if (idx == -1) { OutTraceDW("%s: hooking lib=\"%s\" handle=%x\n", api, lpFileName, libhandle); HookModule(libhandle, 0); } return libhandle; } HMODULE WINAPI extLoadLibraryA(LPCTSTR lpFileName) { return LoadLibraryExWrapper(lpFileName, NULL, 0, "LoadLibraryA"); } HMODULE WINAPI extLoadLibraryW(LPCWSTR lpFileName) { char sFileName[256+1]; wcstombs_s(NULL, sFileName, lpFileName, 80); return LoadLibraryExWrapper(sFileName, NULL, 0, "LoadLibraryW");; } HMODULE WINAPI extLoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags) { return LoadLibraryExWrapper(lpFileName, hFile, dwFlags, "LoadLibraryExA"); } HMODULE WINAPI extLoadLibraryExW(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags) { char sFileName[256+1]; wcstombs_s(NULL, sFileName, lpFileName, 80); return LoadLibraryExWrapper(sFileName, hFile, dwFlags, "LoadLibraryExW");; } extern DirectDrawCreate_Type pDirectDrawCreate; extern DirectDrawCreateEx_Type pDirectDrawCreateEx; extern HRESULT WINAPI extDirectDrawCreate(GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); extern HRESULT WINAPI extDirectDrawCreateEx(GUID FAR *, LPDIRECTDRAW FAR *, REFIID, IUnknown FAR *); extern GetProcAddress_Type pGetProcAddress; //extern HRESULT STDAPICALLTYPE extCoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) { FARPROC ret; int idx; // WARNING: seems to be called with bad LPCSTR value.... // from MSDN: // The function or variable name, or the function's ordinal value. // If this parameter is an ordinal value, it must be in the low-order word; // the high-order word must be zero. OutTraceDW("GetProcAddress: hModule=%x proc=%s\n", hModule, ProcToString(proc)); for(idx=0; idx(Offset=0x%x OffsetHigh=0x%x)", lpOverlapped->Offset, lpOverlapped->OffsetHigh); OutTrace("\n"); } ret = (*pReadFile)(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); if(IsTraceDW){ if(ret){ OutTrace("ReadFile: NumberOfBytesRead=%d\n", *lpNumberOfBytesRead); OutTrace("ReadFile: "); for(unsigned int i=0; i<*lpNumberOfBytesRead; i++) OutTrace("%02X,", *((unsigned char *)lpBuffer+i)); OutTrace("\n"); } else OutTrace("ReadFile: ERROR err=%d\n", GetLastError()); } return ret; } HANDLE WINAPI extCreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { HANDLE ret; OutTraceDW("CreateFile: FileName=%s DesiredAccess=%x SharedMode=%x Disposition=%x Flags=%x\n", lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes); // just proxy if(!(dxw.dwFlags3 & BUFFEREDIOFIX)) return (*pCreateFile)(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); if((dxw.dwFlags3 & BUFFEREDIOFIX) && (dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)){ OutTraceDW("CreateFile: suppress FILE_FLAG_NO_BUFFERING\n"); dwFlagsAndAttributes &= ~FILE_FLAG_NO_BUFFERING; } ret=(*pCreateFile)(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); if(IsTraceDW){ if(ret && (ret != (HANDLE)INVALID_SET_FILE_POINTER)) OutTrace("CreateFile: ret=%x\n", ret); else OutTrace("CreateFile ERROR: err=%d\n", GetLastError()); } return ret; } BOOL WINAPI extCloseHandle(HANDLE hObject) { OutTrace("CloseHandle: hFile=%x\n", hObject); return (*pCloseHandle)(hObject); } DWORD WINAPI extSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) { OutTrace("SetFilePointer: hFile=%x DistanceToMove=0x%lx DistanceToMoveHigh=0x%x MoveMethod=%x\n", hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); return (*pSetFilePointer)(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); } BOOL WINAPI extCreateProcessA( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ) { BOOL res; OutTraceDW("CreateProcess: ApplicationName=\"%s\" CommandLine=\"%s\"\n", lpApplicationName, lpCommandLine); if(dxw.dwFlags4 & SUPPRESSCHILD) { OutTraceDW("CreateProcess: SUPPRESS\n"); return TRUE; } //#define RELEASEHOOKTOSONPROCESS TRUE // extern void UnhookProc(); // if(RELEASEHOOKTOSONPROCESS) UnhookProc(); res=(*pCreateProcessA)( lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation ); if(!res) OutTraceE("CreateProcess: ERROR err=%d\n", GetLastError()); return res; } BOOL WINAPI extCheckRemoteDebuggerPresent(HANDLE hProcess, PBOOL pbDebuggerPresent) { BOOL ret; if(pbDebuggerPresent) *pbDebuggerPresent = FALSE; ret= (hProcess==(HANDLE)0xFFFFFFFF) ? FALSE : TRUE; OutTraceDW("CheckRemoteDebuggerPresent: hProcess=%x ret=%x\n", hProcess, ret); return ret; } UINT WINAPI extGetTempFileName(LPCTSTR lpPathName, LPCTSTR lpPrefixString, UINT uUnique, LPTSTR lpTempFileName) { UINT ret; OutTraceDW("GetTempFileName: PathName=\"%s\" PrefixString=%s Unique=%d\n", lpPathName, lpPrefixString, uUnique); ret = (*pGetTempFileName)(lpPathName, lpPrefixString, uUnique, lpTempFileName); if(ret == 0){ // GetTempFileName patch to make "Powerslide" working OutTraceDW("GetTempFileName FAILED: error=%d at %d\n", GetLastError(), __LINE__); char sTmpDir[MAX_PATH+1]; GetTempPath(sizeof(sTmpDir), sTmpDir); ret = (*pGetTempFileName)(sTmpDir, lpPrefixString, uUnique, lpTempFileName); if(ret == 0) OutTraceDW("GetTempFileName FAILED: PathName=\"%s\" error=%d line %d\n", sTmpDir, GetLastError(), __LINE__); } if(ret){ OutTraceDW("GetTempFileName: TempFileName=\"%s\" ret=%d\n", lpTempFileName, ret); } return ret; }