|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
CorrectFilePaths.cpp
Abstract:
This APIHooks CreateProcess and attempts to convert paths from Win9x locations to Win2000 locations. For example "C:\WINNT\WRITE.EXE" will be converted to C:\WINNT\SYSTEM32\WRITE.EXE"
Notes:
This APIHook emulates Windows 9x.
Created:
12/15/1999 robkenny
Modified:
03/14/2000 robkenny Now uses ClassCFP instead of global routines. 03/31/2000 robkenny ShellExecuteEx now handle lpDirectory path as well. 05/18/2000 a-sesk GetCommandLineA and GetCommandLineW convert cmd line args to short path. 06/20/2000 robkenny Added SetFileAttributes() 06/22/2000 robkenny Reordered enum list and DECLARE_APIHOOK list to match each other. --SERIOUS CHANGE-- 10/30/2000 robkenny Added path specific fixes. Command lines now have the EXE path removed and corrected separately from the remainder of the command line. 11/13/2000 a-alexsm Added SetArguments & SetIconLocation hooks 11/13/2000 robkenny Changed CorrectPath to always return a valid string by returning the original string. Must call CorrectFree to properly release the memory. 12/14/2000 prashkud Added hooks for _lopen and _lcreat 03/10/2001 robkenny Do not convert any paths until *after* all shims have been loaded. 03/15/2001 robkenny Converted to CString
--*/
#include "precomp.h"
#include "ClassCFP.h"
IMPLEMENT_SHIM_BEGIN(CorrectFilePaths) #include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(CreateProcessA) APIHOOK_ENUM_ENTRY(CreateProcessW) APIHOOK_ENUM_ENTRY(WinExec) APIHOOK_ENUM_ENTRY(ShellExecuteA) APIHOOK_ENUM_ENTRY(ShellExecuteW) APIHOOK_ENUM_ENTRY(ShellExecuteExA) APIHOOK_ENUM_ENTRY(ShellExecuteExW)
APIHOOK_ENUM_ENTRY(GetCommandLineA) APIHOOK_ENUM_ENTRY(GetCommandLineW)
APIHOOK_ENUM_ENTRY(GetPrivateProfileIntA) APIHOOK_ENUM_ENTRY(GetPrivateProfileIntW) APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionA) APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionW) APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionNamesA) APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionNamesW) APIHOOK_ENUM_ENTRY(GetPrivateProfileStringA) APIHOOK_ENUM_ENTRY(GetPrivateProfileStringW) APIHOOK_ENUM_ENTRY(GetPrivateProfileStructA) APIHOOK_ENUM_ENTRY(GetPrivateProfileStructW)
APIHOOK_ENUM_ENTRY(WritePrivateProfileSectionA) APIHOOK_ENUM_ENTRY(WritePrivateProfileSectionW) APIHOOK_ENUM_ENTRY(WritePrivateProfileStringA) APIHOOK_ENUM_ENTRY(WritePrivateProfileStringW) APIHOOK_ENUM_ENTRY(WritePrivateProfileStructA) APIHOOK_ENUM_ENTRY(WritePrivateProfileStructW)
APIHOOK_ENUM_ENTRY(CopyFileA) APIHOOK_ENUM_ENTRY(CopyFileW) APIHOOK_ENUM_ENTRY(CopyFileExA) APIHOOK_ENUM_ENTRY(CopyFileExW) APIHOOK_ENUM_ENTRY(CreateDirectoryA) APIHOOK_ENUM_ENTRY(CreateDirectoryW) APIHOOK_ENUM_ENTRY(CreateDirectoryExA) APIHOOK_ENUM_ENTRY(CreateDirectoryExW)
APIHOOK_ENUM_ENTRY(CreateFileA) APIHOOK_ENUM_ENTRY(CreateFileW) APIHOOK_ENUM_ENTRY(DeleteFileA) APIHOOK_ENUM_ENTRY(DeleteFileW)
APIHOOK_ENUM_ENTRY(FindFirstFileA) APIHOOK_ENUM_ENTRY(FindFirstFileW) APIHOOK_ENUM_ENTRY(FindFirstFileExA) APIHOOK_ENUM_ENTRY(FindFirstFileExW)
APIHOOK_ENUM_ENTRY(GetBinaryTypeA) APIHOOK_ENUM_ENTRY(GetBinaryTypeW) APIHOOK_ENUM_ENTRY(GetFileAttributesA) APIHOOK_ENUM_ENTRY(GetFileAttributesW) APIHOOK_ENUM_ENTRY(GetFileAttributesExA) APIHOOK_ENUM_ENTRY(GetFileAttributesExW) APIHOOK_ENUM_ENTRY(SetFileAttributesA) APIHOOK_ENUM_ENTRY(SetFileAttributesW)
APIHOOK_ENUM_ENTRY(MoveFileA) APIHOOK_ENUM_ENTRY(MoveFileW) APIHOOK_ENUM_ENTRY(MoveFileExA) APIHOOK_ENUM_ENTRY(MoveFileExW) APIHOOK_ENUM_ENTRY(MoveFileWithProgressA) APIHOOK_ENUM_ENTRY(MoveFileWithProgressW)
APIHOOK_ENUM_ENTRY(RemoveDirectoryA) APIHOOK_ENUM_ENTRY(RemoveDirectoryW) APIHOOK_ENUM_ENTRY(SetCurrentDirectoryA) APIHOOK_ENUM_ENTRY(SetCurrentDirectoryW)
APIHOOK_ENUM_ENTRY(OpenFile)
APIHOOK_ENUM_ENTRY(RegSetValueA) APIHOOK_ENUM_ENTRY(RegSetValueW) APIHOOK_ENUM_ENTRY(RegSetValueExA) APIHOOK_ENUM_ENTRY(RegSetValueExW)
APIHOOK_ENUM_ENTRY(_lopen) APIHOOK_ENUM_ENTRY(_lcreat)
APIHOOK_ENUM_ENTRY_COMSERVER(SHELL32)
APIHOOK_ENUM_ENTRY(LoadImageA) APIHOOK_ENUM_END
// This is a private define (shlapip.h) that can mess up ShellExecuteEx
#ifndef SEE_MASK_FILEANDURL
#define SEE_MASK_FILEANDURL 0x00400000
#endif
/*++
CorrectFree: free lpMalloc if it is different from lpOrig
--*/ inline void CorrectFree(char * lpMalloc, const char * lpOrig) { if (lpMalloc != lpOrig) { free(lpMalloc); } }
inline void CorrectFree(WCHAR * lpMalloc, const WCHAR * lpOrig) { if (lpMalloc != lpOrig) { free(lpMalloc); } }
/*++
Our path changing class. Note: This is a pointer to the base class. Note: g_PathCorrector *MUST* remain NULL until after SHIM_STATIC_DLLS_INITIALIZED
--*/ CorrectPathChangesBase * g_PathCorrector = NULL; CorrectPathChangesBase * g_AllocatedPathCorrector = NULL;
/*++
Values that can be modified by the command line
--*/ enum PathCorrectorEnum { ePathCorrectorBase, ePathCorrectorUser, ePathCorrectorAllUser, };
BOOL g_bCreateProcessRoutines = TRUE; BOOL g_bGetCommandLineRoutines = FALSE; BOOL g_bRegSetValueRoutines = FALSE; BOOL g_bFileRoutines = TRUE; BOOL g_bProfileRoutines = TRUE; BOOL g_bShellLinkRoutines = TRUE; BOOL g_bW9xPath = FALSE; BOOL g_bLoadImage = FALSE;
PathCorrectorEnum g_pathcorrectorType = ePathCorrectorAllUser;
int g_nExtraPathCorrections = 0; CString * g_ExtraPathCorrections;
/*++
Parse the command line.
--*/ BOOL ParseCommandLine(const char * commandLine) { // Force the default values
g_bCreateProcessRoutines = TRUE; g_bGetCommandLineRoutines = FALSE; g_bRegSetValueRoutines = FALSE; g_bFileRoutines = TRUE; g_bProfileRoutines = TRUE; g_bShellLinkRoutines = TRUE; g_bW9xPath = FALSE; g_bLoadImage = FALSE;
g_pathcorrectorType = ePathCorrectorAllUser; g_nExtraPathCorrections = 0; g_ExtraPathCorrections = NULL;
// Search the beginning of the command line for these switches
//
// Switch Default Meaning
//================ ======= =========================================================
// -a Y Force shortcuts to All Users
// -c N Do not shim Create process routines
// -f N Do not shim File routines
// -p N Do not shim GetPrivateProfile routines
// -s N Do not shim IShellLink routines
// -b N Bare: Use the base corrector (has no built-in path changes)
// -u N User: Built-in paths correct to <username>/Start Menu and <username>/Desktop
// +GetCommandLine N shim GetCommandLine routines
// +RegSetValue N shim the RegSetValue and RegSetValueEx routines
// +Win9xPath N Apply Win9x *path* specific fixes (does not apply to command lines)
// -Profiles N Do not force shortcuts to All Users
// +LoadBitmap N shim the LoadBitmapA routine
//
CSTRING_TRY { CString csCl(commandLine); CStringParser csParser(csCl, L" "); int argc = csParser.GetCount(); if (csParser.GetCount() == 0) { return TRUE; // Not an error
}
// allocate for worst case
g_ExtraPathCorrections = new CString[argc]; if (!g_ExtraPathCorrections) { return FALSE; // Failure
} g_nExtraPathCorrections = 0; for (int i = 0; i < argc; ++i) { CString & csArg = csParser[i]; DPFN( eDbgLevelSpew, "Argv[%d] == (%S)\n", i, csArg.Get()); if (csArg == L"-a") { g_pathcorrectorType = ePathCorrectorAllUser; } else if (csArg == L"-b") { g_pathcorrectorType = ePathCorrectorBase; } else if (csArg == L"-u" || csArg == L"-Profiles") { g_pathcorrectorType = ePathCorrectorUser; } else if (csArg == L"-c") { g_bCreateProcessRoutines = FALSE; } else if (csArg == L"-f") { g_bFileRoutines = FALSE; } else if (csArg == L"-p") { g_bProfileRoutines = FALSE; } else if (csArg == L"-s") { g_bShellLinkRoutines = FALSE; } else if (csArg == L"+GetCommandLine") { DPFN( eDbgLevelInfo, "Command line routines will be shimmed\n"); g_bGetCommandLineRoutines = TRUE; } else if (csArg == L"+RegSetValue") { DPFN( eDbgLevelInfo, "RegSetValue routines will be shimmed\n"); g_bRegSetValueRoutines = TRUE; } else if (csArg == L"+Win9xPath") { DPFN( eDbgLevelInfo, "Win9x Path corrections will be applied\n"); g_bW9xPath = TRUE; } else if (csArg == L"+LoadImage") { DPFN( eDbgLevelInfo, "LoadImageA will be shimmed\n"); g_bLoadImage = TRUE; } else { g_ExtraPathCorrections[g_nExtraPathCorrections] = csArg; g_nExtraPathCorrections += 1; } }
#if DBG
// Dump out the new path correction values.
{ const char *lpszPathCorrectorType = "Unknown"; if (g_pathcorrectorType == ePathCorrectorBase) { lpszPathCorrectorType = "ePathCorrectorBase"; } else if (g_pathcorrectorType == ePathCorrectorUser) { lpszPathCorrectorType = "ePathCorrectorUser"; } else if (g_pathcorrectorType == ePathCorrectorAllUser) { lpszPathCorrectorType = "ePathCorrectorAllUser"; } DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim CreateProcessRoutines = %d\n", g_bCreateProcessRoutines); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim GetCommandLineRoutines = %d\n", g_bGetCommandLineRoutines); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim RegSetValueRoutines = %d\n", g_bRegSetValueRoutines); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim FileRoutines = %d\n", g_bFileRoutines); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim ProfileRoutines = %d\n", g_bProfileRoutines); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim ShellLinkRoutines = %d\n", g_bShellLinkRoutines); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim LoadImageA = %d\n", g_bLoadImage); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim W9xPath = %d\n", g_bW9xPath); DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim Path Corrector Type = %s\n", lpszPathCorrectorType);
for (int i = 0; i < g_nExtraPathCorrections; ++i) { DPFN( eDbgLevelInfo, "[ParseCommandLine] Extra Path Change(%S)\n", g_ExtraPathCorrections[i].Get()); } } #endif
} CSTRING_CATCH { return FALSE; }
return TRUE; }
/*++
Create the appropriate g_PathCorrector Return TRUE if we were successful in creating and initializing.
Note: We create g_AllocatedPathCorrector because g_PathCorrector must remain NULL until SHIM_STATIC_DLLS_INITIALIZED
--*/ BOOL InitPathcorrectorClass() { switch (g_pathcorrectorType) { case ePathCorrectorBase: g_AllocatedPathCorrector = new CorrectPathChangesBase; break;
case ePathCorrectorUser: g_AllocatedPathCorrector = new CorrectPathChangesUser; break;
case ePathCorrectorAllUser: default: g_AllocatedPathCorrector = new CorrectPathChangesAllUser; break;
};
if (g_AllocatedPathCorrector) { return g_AllocatedPathCorrector->ClassInit(); }
return FALSE; }
/*++
Add all the path corrections to the path corrector. Call after SHIM_STATIC_DLLS_INITIALIZED
--*/ void InitializePathCorrections() { if (g_PathCorrector) { g_PathCorrector->InitializeCorrectPathChanges();
if (g_ExtraPathCorrections && g_nExtraPathCorrections) { // Add the command line to this Path Corrector
for (int i = 0; i < g_nExtraPathCorrections; ++i) { g_PathCorrector->AddFromToPairW(g_ExtraPathCorrections[i]); }
delete [] g_ExtraPathCorrections; g_ExtraPathCorrections = NULL; g_nExtraPathCorrections = 0; } } }
/*++
Return a pointer to the PathCorrecting object
--*/ inline CorrectPathChangesBase * GetPathcorrecter() { return g_PathCorrector; }
inline void DebugSpew(const WCHAR * uncorrect, const WCHAR * correct, const char * debugMsg) { if (correct && uncorrect && _wcsicmp(correct, uncorrect) != 0) { LOGN( eDbgLevelError, "%s corrected path:\n %S\n %S\n", debugMsg, uncorrect, correct); } else // Massive Spew:
{ DPFN( eDbgLevelSpew, "%s unchanged %S\n", debugMsg, uncorrect); } }
inline void DebugSpew(const char * uncorrect, const char * correct, const char * debugMsg) { if (correct && uncorrect && _stricmp(correct, uncorrect) != 0) { LOGN( eDbgLevelError, "%s corrected path:\n %s\n %s\n", debugMsg, uncorrect, correct); } else // Massive Spew:
{ DPFN( eDbgLevelSpew, "%s unchanged %s\n", debugMsg, uncorrect); } }
/*++
Given a string, correct the path. bMassagePath determines of path specific fixes are applied (should be FALSE for command lines)
--*/ WCHAR * CorrectorCorrectPath(CorrectPathChangesBase * pathCorrector, const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath) { if (uncorrect == NULL) return NULL;
if (!pathCorrector) return (WCHAR *)uncorrect;
const WCHAR * W9xCorrectedPath = uncorrect;
// Check and see if we need to perform the special Win9x path massaging
if (bMassagePath) { W9xCorrectedPath = W9xPathMassageW(uncorrect); }
WCHAR * strCorrectFile = pathCorrector->CorrectPathAllocW(W9xCorrectedPath);
// If the allocation failed, return the original string.
// This should allow the shim routines to pass along the orignal
// values to the hooked APIs, which if they fail, will have the
// proper error codes.
if (!strCorrectFile) { strCorrectFile = (WCHAR *)uncorrect; } else if (debugMsg) { DebugSpew(uncorrect, strCorrectFile, debugMsg); }
if (W9xCorrectedPath != uncorrect) free((WCHAR *)W9xCorrectedPath);
return strCorrectFile; }
WCHAR * CorrectPath(const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath) { WCHAR * wstrCorrectFile = const_cast<WCHAR *>(uncorrect); CSTRING_TRY { CorrectPathChangesBase * pathCorrector = GetPathcorrecter();
wstrCorrectFile = CorrectorCorrectPath(pathCorrector, uncorrect, debugMsg, bMassagePath); } CSTRING_CATCH { // Fall through
}
return wstrCorrectFile; }
/*++
Given a string, correct the path. bMassagePath determines of path specific fixes are applied (should be FALSE for command lines)
--*/ char * CorrectPath(const char * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath) { char * strCorrectFile = const_cast<char *>(uncorrect);
CSTRING_TRY { CString csUncorrect(uncorrect);
WCHAR * wstrCorrectFile = CorrectPath(csUncorrect, NULL, bMassagePath);
// Don't assign to strCorrectFile unless we successfully allocate the memory.
char * lpszChar = ToAnsi(wstrCorrectFile); if (lpszChar) { strCorrectFile = lpszChar; }
CorrectFree(wstrCorrectFile, csUncorrect); } CSTRING_CATCH { // Fall through
}
if (debugMsg) { DebugSpew(uncorrect, strCorrectFile, debugMsg); }
return strCorrectFile; }
DWORD APIHOOK(GetFileAttributesA)( LPCSTR lpFileName // name of file or directory
) { char * strCorrect = CorrectPath(lpFileName, "GetFileAttributesA");
DWORD returnValue = ORIGINAL_API(GetFileAttributesA)(strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
DWORD APIHOOK(GetFileAttributesW)( LPCWSTR lpFileName // name of file or directory
) { WCHAR * strCorrect = CorrectPath(lpFileName, "GetFileAttributesW");
DWORD returnValue = ORIGINAL_API(GetFileAttributesW)(strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
BOOL APIHOOK(SetFileAttributesA)( LPCSTR lpFileName, // file name
DWORD dwFileAttributes // attributes
) { char * strCorrect = CorrectPath(lpFileName, "SetFileAttributesA");
DWORD returnValue = ORIGINAL_API(SetFileAttributesA)(strCorrect, dwFileAttributes);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
DWORD APIHOOK(SetFileAttributesW)( LPCWSTR lpFileName, // file name
DWORD dwFileAttributes // attributes
) { WCHAR * strCorrect = CorrectPath(lpFileName, "SetFileAttributesW");
DWORD returnValue = ORIGINAL_API(SetFileAttributesW)(strCorrect, dwFileAttributes);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
BOOL APIHOOK(GetFileAttributesExA)( LPCSTR lpFileName, // file or directory name
GET_FILEEX_INFO_LEVELS fInfoLevelId, // attribute
LPVOID lpFileInformation // attribute information
) { char * strCorrect = CorrectPath(lpFileName, "GetFileAttributesExA");
BOOL returnValue = ORIGINAL_API(GetFileAttributesExA)(strCorrect, fInfoLevelId, lpFileInformation);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
BOOL APIHOOK(GetFileAttributesExW)( LPCWSTR lpFileName, // file or directory name
GET_FILEEX_INFO_LEVELS fInfoLevelId, // attribute
LPVOID lpFileInformation // attribute information
) { WCHAR * strCorrect = CorrectPath(lpFileName, "GetFileAttributesExW");
BOOL returnValue = ORIGINAL_API(GetFileAttributesExW)(strCorrect, fInfoLevelId, lpFileInformation);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for CreateProcessA
--*/ BOOL APIHOOK(CreateProcessA)( LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { // Application name and command line that is passed to CreateProcess
// Will either point to lpApplicationName or strCorrectApplicationName
// Will either point to lpCommandLine or strCorrectCommandLine
const char * pstrCorrectApplicationName = lpApplicationName; char * pstrCorrectCommandLine = lpCommandLine;
if (lpApplicationName != NULL) { // Get a buffer containing the application name with the corrected path
pstrCorrectApplicationName = CorrectPath(lpApplicationName, "CreateProcessA ApplicationName:"); }
if (lpCommandLine != NULL) { // Get a buffer containing the command line with the corrected path
pstrCorrectCommandLine = CorrectPath(lpCommandLine, "CreateProcessA CommandLine:", FALSE); }
DPFN( eDbgLevelInfo, "CreateProcessA Application(%s) CommandLine(%s)\n", pstrCorrectApplicationName, pstrCorrectCommandLine); BOOL returnValue = ORIGINAL_API(CreateProcessA)(pstrCorrectApplicationName, pstrCorrectCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
CorrectFree(const_cast<char*>(pstrCorrectApplicationName), lpApplicationName); CorrectFree(pstrCorrectCommandLine, lpCommandLine);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for CreateProcessW
--*/
BOOL APIHOOK(CreateProcessW)( LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { // Application name and command line that is passed to CreateProcess
// Will either point to lpApplicationName or strCorrectApplicationName
// Will either point to lpCommandLine or strCorrectCommandLine
const WCHAR * pstrCorrectApplicationName = lpApplicationName; WCHAR * pstrCorrectCommandLine = lpCommandLine;
if (lpApplicationName != NULL) { // Get a buffer containing the application name with the corrected path
pstrCorrectApplicationName = CorrectPath(lpApplicationName, "CreateProcessW ApplicationName:"); }
if (lpCommandLine != NULL) { // Get a buffer containing the command line with the corrected path
pstrCorrectCommandLine = CorrectPath(lpCommandLine, "CreateProcessW CommandLine:", FALSE); }
DPFN( eDbgLevelInfo, "CreateProcessW Application(%S) CommandLine(%S)\n", pstrCorrectApplicationName, pstrCorrectCommandLine);
BOOL returnValue = ORIGINAL_API(CreateProcessW)(pstrCorrectApplicationName, pstrCorrectCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
CorrectFree(const_cast<WCHAR *>(pstrCorrectApplicationName), lpApplicationName); CorrectFree(pstrCorrectCommandLine, lpCommandLine);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for WinExec
--*/
UINT APIHOOK(WinExec)(LPCSTR lpCmdLine, UINT uCmdShow) { // Get a buffer containing the command line with the corrected path
char * strCorrect = CorrectPath(lpCmdLine, "WinExec", FALSE);
UINT returnValue = ORIGINAL_API(WinExec)(strCorrect, uCmdShow);
CorrectFree(strCorrect, lpCmdLine);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for ShellExecuteA
--*/
HINSTANCE APIHOOK(ShellExecuteA)( HWND hwnd, LPCSTR lpVerb, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd ) { HINSTANCE returnValue = (HINSTANCE)SE_ERR_OOM; // Since this command is executed by the shell, it may contain %env% variables,
// expand them before calling correctpath.
CSTRING_TRY { CString csExpandFile(lpFile); csExpandFile.ExpandEnvironmentStringsW();
returnValue = ORIGINAL_API(ShellExecuteA)(hwnd, lpVerb, csExpandFile.GetAnsi(), lpParameters, lpDirectory, nShowCmd); } CSTRING_CATCH { // Error expanding the string, just pass the value thru.
returnValue = ORIGINAL_API(ShellExecuteA)(hwnd, lpVerb, lpFile, lpParameters, lpDirectory, nShowCmd); }
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for ShellExecuteW
--*/
HINSTANCE APIHOOK(ShellExecuteW)( HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd ) { HINSTANCE returnValue = (HINSTANCE)SE_ERR_OOM; // Since this command is executed by the shell, it may contain %env% variables,
// expand them before calling correctpath.
CSTRING_TRY { CString csExpandFile(lpFile); csExpandFile.ExpandEnvironmentStringsW();
returnValue = ORIGINAL_API(ShellExecuteW)(hwnd, lpVerb, csExpandFile, lpParameters, lpDirectory, nShowCmd); } CSTRING_CATCH { // Error expanding the string, just pass the value thru.
returnValue = ORIGINAL_API(ShellExecuteW)(hwnd, lpVerb, lpFile, lpParameters, lpDirectory, nShowCmd); }
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for ShellExecuteExA
--*/
BOOL APIHOOK(ShellExecuteExA)( LPSHELLEXECUTEINFOA lpExecInfo ) { // Check for this magical internal flag that tells the system
// that lpExecInfo->lpFile is actually a file and URL combined with
// a 0 byte seperator, (file\0url\0)
// Since this is internal only, we should not be receiving bad paths.
if (lpExecInfo->fMask & SEE_MASK_FILEANDURL) { return ORIGINAL_API(ShellExecuteExA)(lpExecInfo); }
const char * lpFile = lpExecInfo->lpFile; const char * lpDirectory = lpExecInfo->lpDirectory;
char * strFileCorrect; char * strDirCorrect;
// Check to see if app is expecting %env% substitution
if (lpExecInfo->fMask & SEE_MASK_DOENVSUBST ) { CSTRING_TRY { CString csExpandedFile(lpFile); CString csExpandedDir(lpDirectory);
csExpandedFile.ExpandEnvironmentStringsW(); csExpandedDir.ExpandEnvironmentStringsW();
strFileCorrect = CorrectPath(csExpandedFile.GetAnsi(), "ShellExecuteExA"); strDirCorrect = CorrectPath(csExpandedDir.GetAnsi(), "ShellExecuteExA"); } CSTRING_CATCH { // Failed to expand the env values, pass all values untouched.
return ORIGINAL_API(ShellExecuteExA)(lpExecInfo); } } else { strFileCorrect = CorrectPath(lpFile, "ShellExecuteExA"); strDirCorrect = CorrectPath(lpDirectory, "ShellExecuteExA"); }
// Save the original fileName
lpExecInfo->lpFile = strFileCorrect; lpExecInfo->lpDirectory = strDirCorrect; BOOL returnValue = ORIGINAL_API(ShellExecuteExA)(lpExecInfo); lpExecInfo->lpFile = lpFile; lpExecInfo->lpDirectory = lpDirectory;
CorrectFree(strFileCorrect, lpFile); CorrectFree(strDirCorrect, lpDirectory);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for ShellExecuteExW
--*/
BOOL APIHOOK(ShellExecuteExW)( LPSHELLEXECUTEINFOW lpExecInfo ) { // Check for this magical *internal* flag that tells the system
// that lpExecInfo->lpFile is actually a file and URL combined with
// a 0 byte seperator, (file\0url\0)
// Since this is internal only, we should not be receiving bad paths.
if (lpExecInfo->fMask & SEE_MASK_FILEANDURL) { return ORIGINAL_API(ShellExecuteExW)(lpExecInfo); }
const WCHAR * lpFile = lpExecInfo->lpFile; const WCHAR * lpDirectory = lpExecInfo->lpDirectory;
WCHAR * strFileCorrect; WCHAR * strDirCorrect;
// Check to see if app is expecting %env% substitution
if (lpExecInfo->fMask & SEE_MASK_DOENVSUBST ) { CSTRING_TRY { CString csExpandedFile(lpFile); CString csExpandedDir(lpDirectory);
csExpandedFile.ExpandEnvironmentStringsW(); csExpandedDir.ExpandEnvironmentStringsW();
strFileCorrect = CorrectPath(csExpandedFile, "ShellExecuteExW"); strDirCorrect = CorrectPath(csExpandedDir, "ShellExecuteExW"); } CSTRING_CATCH { // Failed to expand the env values, pass all values untouched.
return ORIGINAL_API(ShellExecuteExW)(lpExecInfo); } } else { strFileCorrect = CorrectPath(lpFile, "ShellExecuteExW"); strDirCorrect = CorrectPath(lpDirectory, "ShellExecuteExW"); }
// Save the original fileName
lpExecInfo->lpFile = strFileCorrect; lpExecInfo->lpDirectory = strDirCorrect; BOOL returnValue = ORIGINAL_API(ShellExecuteExW)(lpExecInfo); lpExecInfo->lpFile = lpFile; lpExecInfo->lpDirectory = lpDirectory;
CorrectFree(strFileCorrect, lpFile); CorrectFree(strDirCorrect, lpDirectory);
return returnValue; }
/*++
Convert long command line paths to short paths for GetCommandLineW
--*/
LPCWSTR APIHOOK(GetCommandLineW)() { static LPCWSTR wstrCorrectCommandLine = NULL;
if (wstrCorrectCommandLine == NULL) { LPCWSTR wstrCommandLine = ORIGINAL_API(GetCommandLineW)();
wstrCorrectCommandLine = CorrectPath(wstrCommandLine, "GetCommandLineW", FALSE); } return wstrCorrectCommandLine; }
/*++
Convert long command line paths to short paths for GetCommandLineA
--*/
LPCSTR APIHOOK(GetCommandLineA)() { static LPCSTR strCorrectCommandLine = NULL;
if (strCorrectCommandLine == NULL) { LPCSTR strCommandLine = ORIGINAL_API(GetCommandLineA)();
strCorrectCommandLine = CorrectPath(strCommandLine, "GetCommandLineA", FALSE); } return strCorrectCommandLine; }
/*++
The PrivateProfile routines treat filenames differently than pathnames. If we have Win9xPath corrections enabled, it is possible to "fix" a path from .\example.ini to example.ini. Unfortunately the PrivateProfile routines look for example.ini in %windir% If we have a path that contains path seperators, we must ensure that the resulting string also contains path separators.
--*/
char * ProfileCorrectPath(const char * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath) { char * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
if (bMassagePath && uncorrect != strCorrect) { char * returnString = NULL;
CSTRING_TRY { CString csUncorrect(uncorrect); if (csUncorrect.FindOneOf(L"\\/") >= 0) { // Found some path separators in the original string, check the corrected string.
// If the corrected string does not have any path separators,
// then the path was corrected from .\example.ini to example.ini
CString csCorrect(strCorrect); if (csCorrect.FindOneOf(L"\\/") < 0) { // No path seperators, make this a CWD relative path
csCorrect.Insert(0, L".\\");
returnString = csCorrect.ReleaseAnsi(); } } } CSTRING_CATCH { // Some CString error occured, make sure returnString is NULL
if (returnString != NULL) { free(returnString); } returnString = NULL; }
if (returnString) { CorrectFree(strCorrect, uncorrect); strCorrect = returnString; } }
if (debugMsg) { DebugSpew(uncorrect, strCorrect, debugMsg); }
return strCorrect; }
/*++
The PrivateProfile routines treat filenames differently than pathnames. If we have Win9xPath corrections enabled, it is possible to "fix" a path from .\example.ini to example.ini. Unfortunately the PrivateProfile routines look for example.ini in %windir% If we have a path that contains path seperators, we must ensure that the resulting string also contains path separators.
--*/
WCHAR * ProfileCorrectPath(const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath) { WCHAR * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
if (bMassagePath && uncorrect != strCorrect) { WCHAR * returnString = NULL;
CSTRING_TRY { CString csUncorrect(uncorrect); if (csUncorrect.FindOneOf(L"\\/") >= 0) { // Found some path separators in the original string, check the corrected string.
// If the corrected string does not have any path separators,
// then the path was corrected from .\example.ini to example.ini
CString csCorrect(strCorrect); if (csCorrect.FindOneOf(L"\\/") < 0) { // No path seperators, make this a CWD relative path
csCorrect.Insert(0, L".\\");
// Manually copy the buffer
size_t nBytes = (csCorrect.GetLength() + 1) * sizeof(WCHAR); returnString = (WCHAR*) malloc(nBytes); if (returnString) { memcpy(returnString, csCorrect.Get(), nBytes); } } } } CSTRING_CATCH { // Some CString error occured, make sure returnString is NULL
if (returnString != NULL) { free(returnString); } returnString = NULL; }
if (returnString) { CorrectFree(strCorrect, uncorrect); strCorrect = returnString; } } if (debugMsg) { DebugSpew(uncorrect, strCorrect, debugMsg); }
return strCorrect; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileIntA
--*/
UINT APIHOOK(GetPrivateProfileIntA)( LPCSTR lpAppName, // section name
LPCSTR lpKeyName, // key name
INT nDefault, // return value if key name not found
LPCSTR lpFileName // initialization file name
) { char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileIntA");
UINT returnValue = ORIGINAL_API(GetPrivateProfileIntA)(lpAppName, lpKeyName, nDefault, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileIntW
--*/
UINT APIHOOK(GetPrivateProfileIntW)( LPCWSTR lpAppName, // section name
LPCWSTR lpKeyName, // key name
INT nDefault, // return value if key name not found
LPCWSTR lpFileName // initialization file name
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileIntW");
UINT returnValue = ORIGINAL_API(GetPrivateProfileIntW)(lpAppName, lpKeyName, nDefault, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileSectionA
--*/
DWORD APIHOOK(GetPrivateProfileSectionA)( LPCSTR lpAppName, // section name
LPSTR lpReturnedString, // return buffer
DWORD nSize, // size of return buffer
LPCSTR lpFileName // initialization file name
) { char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionA");
DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionA)(lpAppName, lpReturnedString, nSize, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileSectionW
--*/
DWORD APIHOOK(GetPrivateProfileSectionW)( LPCWSTR lpAppName, // section name
LPWSTR lpReturnedString, // return buffer
DWORD nSize, // size of return buffer
LPCWSTR lpFileName // initialization file name
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionW");
DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionW)(lpAppName, lpReturnedString, nSize, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesA
--*/
DWORD APIHOOK(GetPrivateProfileSectionNamesA)( LPSTR lpszReturnBuffer, // return buffer
DWORD nSize, // size of return buffer
LPCSTR lpFileName // initialization file name
) { char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionNamesA");
DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionNamesA)(lpszReturnBuffer, nSize, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesW
--*/
DWORD APIHOOK(GetPrivateProfileSectionNamesW)( LPWSTR lpszReturnBuffer, // return buffer
DWORD nSize, // size of return buffer
LPCWSTR lpFileName // initialization file name
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionNamesW");
DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionNamesW)(lpszReturnBuffer, nSize, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesA
--*/
DWORD APIHOOK(GetPrivateProfileStringA)( LPCSTR lpAppName, // section name
LPCSTR lpKeyName, // key name
LPCSTR lpDefault, // default string
LPSTR lpReturnedString, // destination buffer
DWORD nSize, // size of destination buffer
LPCSTR lpFileName // initialization file name
) { char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStringA");
DWORD returnValue = ORIGINAL_API(GetPrivateProfileStringA)(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesA
--*/
DWORD APIHOOK(GetPrivateProfileStringW)( LPCWSTR lpAppName, // section name
LPCWSTR lpKeyName, // key name
LPCWSTR lpDefault, // default string
LPWSTR lpReturnedString, // destination buffer
DWORD nSize, // size of destination buffer
LPCWSTR lpFileName // initialization file name
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStringW");
DWORD returnValue = ORIGINAL_API(GetPrivateProfileStringW)(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; } /*++
Convert Win9x paths to WinNT paths for GetPrivateProfileStructA
--*/
BOOL APIHOOK(GetPrivateProfileStructA)( LPCSTR lpszSection, // section name
LPCSTR lpszKey, // key name
LPVOID lpStruct, // return buffer
UINT uSizeStruct, // size of return buffer
LPCSTR lpFileName // initialization file name
) { char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStructA");
BOOL returnValue = ORIGINAL_API(GetPrivateProfileStructA)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileStructW
--*/
BOOL APIHOOK(GetPrivateProfileStructW)( LPCWSTR lpszSection, // section name
LPCWSTR lpszKey, // key name
LPVOID lpStruct, // return buffer
UINT uSizeStruct, // size of return buffer
LPCWSTR lpFileName // initialization file name
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStructW");
BOOL returnValue = ORIGINAL_API(GetPrivateProfileStructW)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for GetPrivateProfileStructA
--*/
BOOL APIHOOK(WritePrivateProfileSectionA)( LPCSTR lpAppName, // section name
LPCSTR lpString, // data
LPCSTR lpFileName // file name
) { char * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileSectionA");
BOOL returnValue = ORIGINAL_API(WritePrivateProfileSectionA)(lpAppName, lpString, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for WritePrivateProfileSectionW
--*/
BOOL APIHOOK(WritePrivateProfileSectionW)( LPCWSTR lpAppName, // section name
LPCWSTR lpString, // data
LPCWSTR lpFileName // file name
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileSectionW");
BOOL returnValue = ORIGINAL_API(WritePrivateProfileSectionW)(lpAppName, lpString, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for WritePrivateProfileStringA
--*/
BOOL APIHOOK(WritePrivateProfileStringA)( LPCSTR lpAppName, // section name
LPCSTR lpKeyName, // key name
LPCSTR lpString, // string to add
LPCSTR lpFileName // initialization file
) { char * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStringA");
BOOL returnValue = ORIGINAL_API(WritePrivateProfileStringA)(lpAppName, lpKeyName, lpString, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for WritePrivateProfileStringW
--*/
BOOL APIHOOK(WritePrivateProfileStringW)( LPCWSTR lpAppName, // section name
LPCWSTR lpKeyName, // key name
LPCWSTR lpString, // string to add
LPCWSTR lpFileName // initialization file
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStringW");
BOOL returnValue = ORIGINAL_API(WritePrivateProfileStringW)(lpAppName, lpKeyName, lpString, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for WritePrivateProfileStructA
--*/ BOOL APIHOOK(WritePrivateProfileStructA)( LPCSTR lpszSection, // section name
LPCSTR lpszKey, // key name
LPVOID lpStruct, // data buffer
UINT uSizeStruct, // size of data buffer
LPCSTR lpFileName // initialization file
) { char * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStructA");
BOOL returnValue = ORIGINAL_API(WritePrivateProfileStructA)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Convert Win9x paths to WinNT paths for WritePrivateProfileStructW
--*/ BOOL APIHOOK(WritePrivateProfileStructW)( LPCWSTR lpszSection, // section name
LPCWSTR lpszKey, // key name
LPVOID lpStruct, // data buffer
UINT uSizeStruct, // size of data buffer
LPCWSTR lpFileName // initialization file
) { WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStructW");
BOOL returnValue = ORIGINAL_API(WritePrivateProfileStructW)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; } /*++
Convert Win9x paths to WinNT paths for IShellLinkA::SetArguments
--*/ HRESULT COMHOOK(IShellLinkA, SetArguments)( PVOID pThis, LPCSTR pszArgs ) { HRESULT hrReturn = E_FAIL;
char * strCorrect = CorrectPath(pszArgs, "IShellLinkA::SetArguments", FALSE);
_pfn_IShellLinkA_SetArguments pfnOld = ORIGINAL_COM(IShellLinkA, SetArguments, pThis); if (pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect );
CorrectFree(strCorrect, pszArgs); return hrReturn; }
/*++
Convert Win9x paths to WinNT paths for IShellLinkW::SetArguments
--*/ HRESULT COMHOOK(IShellLinkW, SetArguments)( PVOID pThis, LPCWSTR pszArgs ) { HRESULT hrReturn = E_FAIL;
WCHAR * strCorrect = CorrectPath(pszArgs, "IShellLinkA::SetArguments", FALSE);
_pfn_IShellLinkW_SetArguments pfnOld = ORIGINAL_COM(IShellLinkW, SetArguments, pThis); if(pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect );
CorrectFree(strCorrect, pszArgs);
return hrReturn; }
/*++
Convert Win9x paths to WinNT paths for IShellLinkA::SetIconLocation
--*/ HRESULT COMHOOK(IShellLinkA, SetIconLocation)(PVOID pThis, LPCSTR pszIconLocation, int nIcon ) { HRESULT hrReturn = E_FAIL;
char * strCorrect = CorrectPath(pszIconLocation, "IShellLinkA::SetIconLocation");
_pfn_IShellLinkA_SetIconLocation pfnOld = ORIGINAL_COM(IShellLinkA, SetIconLocation, pThis); if (pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect, nIcon );
CorrectFree(strCorrect, pszIconLocation);
return hrReturn; }
/*++
Convert Win9x paths to WinNT paths for IShellLinkW::SetIconLocation
--*/ HRESULT COMHOOK(IShellLinkW, SetIconLocation)(PVOID pThis, LPCWSTR pszIconLocation, int nIcon ) { HRESULT hrReturn = E_FAIL;
WCHAR * strCorrect = CorrectPath(pszIconLocation, "IShellLinkW::SetIconLocation");
_pfn_IShellLinkW_SetIconLocation pfnOld = ORIGINAL_COM(IShellLinkW, SetIconLocation, pThis); if(pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect, nIcon );
CorrectFree(strCorrect, pszIconLocation);
return hrReturn; }
/*++
Convert Win9x paths to WinNT paths for IShellLinkA::SetPath
--*/ HRESULT COMHOOK(IShellLinkA, SetPath)(PVOID pThis, LPCSTR pszFile ) { HRESULT hrReturn = E_FAIL;
char * strCorrect = CorrectPath(pszFile, "IShellLinkA::SetPath");
_pfn_IShellLinkA_SetPath pfnOld = ORIGINAL_COM(IShellLinkA, SetPath, pThis); if (pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect );
CorrectFree(strCorrect, pszFile);
return hrReturn; }
/*++
Convert Win9x paths to WinNT paths for IShellLinkW::SetPath
--*/ HRESULT COMHOOK(IShellLinkW, SetPath)(PVOID pThis, LPCWSTR pszFile ) { HRESULT hrReturn = E_FAIL;
WCHAR * strCorrect = CorrectPath(pszFile, "IShellLinkW::SetPath");
_pfn_IShellLinkW_SetPath pfnOld = ORIGINAL_COM(IShellLinkW, SetPath, pThis); if (pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect );
CorrectFree(strCorrect, pszFile);
return hrReturn; }
/*++
Convert Win9x paths to WinNT paths for IPersistFile::Save
--*/ HRESULT COMHOOK(IPersistFile, Save)(PVOID pThis, LPCOLESTR pszFileName, BOOL fRemember) { HRESULT hrReturn = E_FAIL;
WCHAR * strCorrect = CorrectPath(pszFileName, "IPersistFile_Save");
_pfn_IPersistFile_Save pfnOld = ORIGINAL_COM(IPersistFile, Save, pThis); if (pfnOld) hrReturn = (*pfnOld)( pThis, strCorrect, fRemember );
CorrectFree(strCorrect, pszFileName);
return hrReturn; }
BOOL APIHOOK(CopyFileA)( LPCSTR lpExistingFileName, // name of an existing file
LPCSTR lpNewFileName, // name of new file
BOOL bFailIfExists // operation if file exists
) { char * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileA"); char * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileA");
BOOL returnValue = ORIGINAL_API(CopyFileA)(strExistingCorrect, strNewCorrect, bFailIfExists);
CorrectFree(strExistingCorrect, lpExistingFileName); CorrectFree(strNewCorrect, lpNewFileName);
return returnValue; }
BOOL APIHOOK(CopyFileW)( LPCWSTR lpExistingFileName, // name of an existing file
LPCWSTR lpNewFileName, // name of new file
BOOL bFailIfExists // operation if file exists
) { WCHAR * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileW"); WCHAR * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileW");
BOOL returnValue = ORIGINAL_API(CopyFileW)(strExistingCorrect, strNewCorrect, bFailIfExists);
CorrectFree(strExistingCorrect, lpExistingFileName); CorrectFree(strNewCorrect, lpNewFileName);
return returnValue; }
BOOL APIHOOK(CopyFileExA)( LPCSTR lpExistingFileName, // name of existing file
LPCSTR lpNewFileName, // name of new file
LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
LPVOID lpData, // callback parameter
LPBOOL pbCancel, // cancel status
DWORD dwCopyFlags // copy options
) { char * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileExA"); char * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileExA");
BOOL returnValue = ORIGINAL_API(CopyFileExA)(strExistingCorrect, strNewCorrect, lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
CorrectFree(strExistingCorrect, lpExistingFileName); CorrectFree(strNewCorrect, lpNewFileName);
return returnValue; }
BOOL APIHOOK(CopyFileExW)( LPCWSTR lpExistingFileName, // name of existing file
LPCWSTR lpNewFileName, // name of new file
LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
LPVOID lpData, // callback parameter
LPBOOL pbCancel, // cancel status
DWORD dwCopyFlags // copy options
) { WCHAR * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileExW"); WCHAR * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileExW");
BOOL returnValue = ORIGINAL_API(CopyFileExW)(strExistingCorrect, strNewCorrect, lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
CorrectFree(strExistingCorrect, lpExistingFileName); CorrectFree(strNewCorrect, lpNewFileName);
return returnValue; }
BOOL APIHOOK(CreateDirectoryA)( LPCSTR lpPathName, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
) { char * strCorrect = CorrectPath(lpPathName, "CreateDirectoryA");
BOOL returnValue = ORIGINAL_API(CreateDirectoryA)(strCorrect, lpSecurityAttributes);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
BOOL APIHOOK(CreateDirectoryW)( LPCWSTR lpPathName, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
) { WCHAR * strCorrect = CorrectPath(lpPathName, "CreateDirectoryW");
BOOL returnValue = ORIGINAL_API(CreateDirectoryW)(strCorrect, lpSecurityAttributes);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
BOOL APIHOOK(CreateDirectoryExA)( LPCSTR lpTemplateDirectory, // template directory
LPCSTR lpNewDirectory, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
) { char * strTemplateCorrect = CorrectPath(lpTemplateDirectory, "CreateDirectoryExA"); char * strNewCorrect = CorrectPath(lpNewDirectory, "CreateDirectoryExA");
BOOL returnValue = ORIGINAL_API(CreateDirectoryExA)(strTemplateCorrect, strNewCorrect, lpSecurityAttributes);
CorrectFree(strTemplateCorrect, lpTemplateDirectory); CorrectFree(strNewCorrect, lpNewDirectory);
return returnValue; }
BOOL APIHOOK(CreateDirectoryExW)( LPCWSTR lpTemplateDirectory, // template directory
LPCWSTR lpNewDirectory, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
) { WCHAR * strTemplateCorrect = CorrectPath(lpTemplateDirectory, "CreateDirectoryExW"); WCHAR * strNewCorrect = CorrectPath(lpNewDirectory, "CreateDirectoryExW");
BOOL returnValue = ORIGINAL_API(CreateDirectoryExW)(strTemplateCorrect, strNewCorrect, lpSecurityAttributes);
CorrectFree(strTemplateCorrect, lpTemplateDirectory); CorrectFree(strNewCorrect, lpNewDirectory);
return returnValue; }
HANDLE APIHOOK(CreateFileA)( LPCSTR lpFileName, // file name
DWORD dwDesiredAccess, // access mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
DWORD dwCreationDisposition, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to template file
) { char * strCorrect = CorrectPath(lpFileName, "CreateFileA");
HANDLE returnValue = ORIGINAL_API(CreateFileA)(strCorrect, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
HANDLE APIHOOK(CreateFileW)( LPCWSTR lpFileName, // file name
DWORD dwDesiredAccess, // access mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
DWORD dwCreationDisposition, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to template file
) { WCHAR * strCorrect = CorrectPath(lpFileName, "CreateFileW");
HANDLE returnValue = ORIGINAL_API(CreateFileW)( strCorrect, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
BOOL APIHOOK(DeleteFileA)( LPCSTR lpFileName // file name
) { char * strCorrect = CorrectPath(lpFileName, "DeleteFileA");
BOOL returnValue = ORIGINAL_API(DeleteFileA)(strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
BOOL APIHOOK(DeleteFileW)(
LPCWSTR lpFileName // file name
) { WCHAR * strCorrect = CorrectPath(lpFileName, "DeleteFileW");
BOOL returnValue = ORIGINAL_API(DeleteFileW)(strCorrect);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
/*++
Win9xPath corrections will strip a trailing . from the end of a search string. As a path, the . is not significant, but as a wildcard it is important--the difference between finding files without an extension and finding all files in the directory.
--*/
char * FindFirstFileCorrectPath(const char * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath) { char * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
if (bMassagePath && uncorrect != strCorrect) { char * returnString = NULL;
CSTRING_TRY { CString csUncorrect(uncorrect); CString csCorrect(strCorrect);
CString csUncorrectLast; CString csCorrectLast;
csUncorrect.GetLastPathComponent(csUncorrectLast); csCorrect.GetLastPathComponent(csCorrectLast);
if (csUncorrectLast.Compare(L"*.") == 0 && csCorrectLast.Compare(L"*") == 0) { csCorrectLast += L"."; returnString = csCorrectLast.ReleaseAnsi(); } } CSTRING_CATCH { // Some CString error occured, make sure returnString is NULL
if (returnString != NULL) { free(returnString); } returnString = NULL; }
if (returnString) { CorrectFree(strCorrect, uncorrect); strCorrect = returnString; } }
if (debugMsg) { DebugSpew(uncorrect, strCorrect, debugMsg); }
return strCorrect; }
/*++
Win9xPath corrections will strip a trailing . from the end of a search string. As a path, the . is not significant, but as a wildcard it is important--the difference between finding files without an extension and finding all files in the directory.
--*/
WCHAR * FindFirstFileCorrectPath(const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath) { WCHAR * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
if (bMassagePath && uncorrect != strCorrect) { WCHAR * returnString = NULL;
CSTRING_TRY { CString csUncorrect(uncorrect); CString csCorrect(strCorrect);
CString csUncorrectLast; CString csCorrectLast;
csUncorrect.GetLastPathComponent(csUncorrectLast); csCorrect.GetLastPathComponent(csCorrectLast);
if (csUncorrectLast.Compare(L"*.") == 0 && csCorrectLast.Compare(L"*") == 0) { csCorrectLast += L".";
// Manually copy the buffer
size_t nBytes = (csCorrectLast.GetLength() + 1) * sizeof(WCHAR); returnString = (WCHAR*) malloc(nBytes); if (returnString) { memcpy(returnString, csCorrectLast.Get(), nBytes); } } } CSTRING_CATCH { // Some CString error occured, make sure returnString is NULL
if (returnString != NULL) { free(returnString); } returnString = NULL; }
if (returnString) { CorrectFree(strCorrect, uncorrect); strCorrect = returnString; } }
if (debugMsg) { DebugSpew(uncorrect, strCorrect, debugMsg); }
return strCorrect; }
HANDLE APIHOOK(FindFirstFileA)( LPCSTR lpFileName, // file name
LPWIN32_FIND_DATAA lpFindFileData // data buffer
) { char * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileA");
HANDLE returnValue = ORIGINAL_API(FindFirstFileA)(strCorrect, lpFindFileData);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
HANDLE APIHOOK(FindFirstFileW)( LPCWSTR lpFileName, // file name
LPWIN32_FIND_DATAW lpFindFileData // data buffer
) { WCHAR * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileW");
HANDLE returnValue = ORIGINAL_API(FindFirstFileW)(strCorrect, lpFindFileData);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
HANDLE APIHOOK(FindFirstFileExA)( LPCSTR lpFileName, // file name
FINDEX_INFO_LEVELS fInfoLevelId, // information level
LPVOID lpFindFileData, // information buffer
FINDEX_SEARCH_OPS fSearchOp, // filtering type
LPVOID lpSearchFilter, // search criteria
DWORD dwAdditionalFlags // additional search control
) { char * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileExA");
HANDLE returnValue = ORIGINAL_API(FindFirstFileExA)( strCorrect, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
HANDLE APIHOOK(FindFirstFileExW)( LPCWSTR lpFileName, // file name
FINDEX_INFO_LEVELS fInfoLevelId, // information level
LPVOID lpFindFileData, // information buffer
FINDEX_SEARCH_OPS fSearchOp, // filtering type
LPVOID lpSearchFilter, // search criteria
DWORD dwAdditionalFlags // additional search control
) { WCHAR * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileExW");
HANDLE returnValue = ORIGINAL_API(FindFirstFileExW)( strCorrect, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
BOOL APIHOOK(GetBinaryTypeA)( LPCSTR lpApplicationName, // full file path
LPDWORD lpBinaryType // binary type information
) { char * strCorrect = CorrectPath(lpApplicationName, "GetBinaryTypeA");
BOOL returnValue = ORIGINAL_API(GetBinaryTypeA)(strCorrect, lpBinaryType);
CorrectFree(strCorrect, lpApplicationName);
return returnValue; }
BOOL APIHOOK(GetBinaryTypeW)( LPCWSTR lpApplicationName, // full file path
LPDWORD lpBinaryType // binary type information
) { WCHAR * strCorrect = CorrectPath(lpApplicationName, "GetBinaryTypeW");
BOOL returnValue = ORIGINAL_API(GetBinaryTypeW)(strCorrect, lpBinaryType);
CorrectFree(strCorrect, lpApplicationName);
return returnValue; }
BOOL APIHOOK(MoveFileA)( LPCSTR lpExistingFileName, // file name
LPCSTR lpNewFileName // new file name
) { char * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileA"); char * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileA");
BOOL returnValue = ORIGINAL_API(MoveFileA)(strCorrectExisting, strCorrectNew);
CorrectFree(strCorrectExisting, lpExistingFileName); CorrectFree(strCorrectNew, lpNewFileName);
return returnValue; }
BOOL APIHOOK(MoveFileW)( LPCWSTR lpExistingFileName, // file name
LPCWSTR lpNewFileName // new file name
) { WCHAR * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileW"); WCHAR * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileW");
BOOL returnValue = ORIGINAL_API(MoveFileW)(strCorrectExisting, strCorrectNew);
CorrectFree(strCorrectExisting, lpExistingFileName); CorrectFree(strCorrectNew, lpNewFileName);
return returnValue; }
BOOL APIHOOK(MoveFileExA)( LPCSTR lpExistingFileName, // file name
LPCSTR lpNewFileName, // new file name
DWORD dwFlags // move options
) { char * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileExA"); char * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileExA");
BOOL returnValue = ORIGINAL_API(MoveFileExA)(strCorrectExisting, strCorrectNew, dwFlags);
CorrectFree(strCorrectExisting, lpExistingFileName); CorrectFree(strCorrectNew, lpNewFileName);
return returnValue; }
BOOL APIHOOK(MoveFileExW)( LPCWSTR lpExistingFileName, // file name
LPCWSTR lpNewFileName, // new file name
DWORD dwFlags // move options
) { WCHAR * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileExW"); WCHAR * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileExW");
BOOL returnValue = ORIGINAL_API(MoveFileExW)(strCorrectExisting, strCorrectNew, dwFlags);
CorrectFree(strCorrectExisting, lpExistingFileName); CorrectFree(strCorrectNew, lpNewFileName);
return returnValue; }
BOOL APIHOOK(MoveFileWithProgressA)( LPCSTR lpExistingFileName, // file name
LPCSTR lpNewFileName, // new file name
LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
LPVOID lpData, // parameter for callback
DWORD dwFlags // move options
) { char * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileWithProgressA"); char * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileWithProgressA");
BOOL returnValue = ORIGINAL_API(MoveFileWithProgressA)(strCorrectExisting, strCorrectNew, lpProgressRoutine, lpData, dwFlags);
CorrectFree(strCorrectExisting, lpExistingFileName); CorrectFree(strCorrectNew, lpNewFileName);
return returnValue; }
BOOL APIHOOK(MoveFileWithProgressW)( LPCWSTR lpExistingFileName, // file name
LPCWSTR lpNewFileName, // new file name
LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
LPVOID lpData, // parameter for callback
DWORD dwFlags // move options
) { WCHAR * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileW"); WCHAR * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileW");
BOOL returnValue = ORIGINAL_API(MoveFileWithProgressW)(strCorrectExisting, strCorrectNew, lpProgressRoutine, lpData, dwFlags);
CorrectFree(strCorrectExisting, lpExistingFileName); CorrectFree(strCorrectNew, lpNewFileName);
return returnValue; }
BOOL APIHOOK(RemoveDirectoryA)( LPCSTR lpPathName // directory name
) { char * strCorrect = CorrectPath(lpPathName, "RemoveDirectoryA");
BOOL returnValue = ORIGINAL_API(RemoveDirectoryA)(strCorrect);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
BOOL APIHOOK(RemoveDirectoryW)( LPCWSTR lpPathName // directory name
) { WCHAR * strCorrect = CorrectPath(lpPathName, "RemoveDirectoryW");
BOOL returnValue = ORIGINAL_API(RemoveDirectoryW)(strCorrect);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
BOOL APIHOOK(SetCurrentDirectoryA)( LPCSTR lpPathName // new directory name
) { char * strCorrect = CorrectPath(lpPathName, "SetCurrentDirectoryA");
BOOL returnValue = ORIGINAL_API(SetCurrentDirectoryA)(strCorrect);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
BOOL APIHOOK(SetCurrentDirectoryW)( LPCWSTR lpPathName // new directory name
) { WCHAR * strCorrect = CorrectPath(lpPathName, "SetCurrentDirectoryW");
BOOL returnValue = ORIGINAL_API(SetCurrentDirectoryW)(strCorrect);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
HFILE APIHOOK(OpenFile)( LPCSTR lpFileName, // file name
LPOFSTRUCT lpReOpenBuff, // file information
UINT uStyle // action and attributes
) { char * strCorrect = CorrectPath(lpFileName, "OpenFile");
HFILE returnValue = ORIGINAL_API(OpenFile)(strCorrect, lpReOpenBuff, uStyle);
CorrectFree(strCorrect, lpFileName);
return returnValue; }
LONG APIHOOK(RegSetValueA)( HKEY hKey, // handle to key
LPCSTR lpSubKey, // subkey name
DWORD dwType, // information type
LPCSTR lpData, // value data
DWORD cbData // size of value data
) { char * strCorrect = CorrectPath(lpData, "RegSetValueA", FALSE);
// Data key is length of string *not* including null byte.
if (strCorrect) { cbData = strlen(strCorrect); }
LONG returnValue = ORIGINAL_API(RegSetValueA)(hKey, lpSubKey, dwType, strCorrect, cbData);
CorrectFree(strCorrect, lpData);
return returnValue; }
LONG APIHOOK(RegSetValueW)( HKEY hKey, // handle to key
LPCWSTR lpSubKey, // subkey name
DWORD dwType, // information type
LPCWSTR lpData, // value data
DWORD cbData // size of value data
) { WCHAR * strCorrect = CorrectPath(lpData, "RegSetValueW", FALSE);
// Data key is length of string *not* including null byte.
if (strCorrect) cbData = wcslen(strCorrect);
LONG returnValue = ORIGINAL_API(RegSetValueW)(hKey, lpSubKey, dwType, strCorrect, cbData);
CorrectFree(strCorrect, lpData);
return returnValue; }
LONG APIHOOK(RegSetValueExA)( HKEY hKey, // handle to key
LPCSTR lpValueName, // value name
DWORD Reserved, // reserved
DWORD dwType, // value type
CONST BYTE *lpData, // value data
DWORD cbData // size of value data
) { if (dwType == REG_SZ) { char * strCorrect = CorrectPath((const char *)lpData, "RegSetValueExA", FALSE);
// Data key is length of string *including* null byte.
if (strCorrect) { cbData = strlen(strCorrect) + 1; }
LONG returnValue = ORIGINAL_API(RegSetValueExA)( hKey, // handle to key
lpValueName, // value name
Reserved, // reserved
dwType, // value type
(CONST BYTE *)strCorrect, // value data
cbData); CorrectFree(strCorrect, (const char *)lpData);
return returnValue; } else { // Pass data on through
LONG returnValue = ORIGINAL_API(RegSetValueExA)( hKey, // handle to key
lpValueName, // value name
Reserved, // reserved
dwType, // value type
lpData, // value data
cbData); return returnValue; } }
LONG APIHOOK(RegSetValueExW)( HKEY hKey, // handle to key
LPCWSTR lpValueName, // value name
DWORD Reserved, // reserved
DWORD dwType, // value type
CONST BYTE *lpData, // value data
DWORD cbData // size of value data
) { if (dwType == REG_SZ) { WCHAR * strCorrect = CorrectPath((const WCHAR*)lpData, "RegSetValueExW", FALSE);
// Data key is length of string *including* null byte.
if (strCorrect) { cbData = wcslen(strCorrect) + 1; }
LONG returnValue = ORIGINAL_API(RegSetValueExW)( hKey, // handle to key
lpValueName, // value name
Reserved, // reserved
dwType, // value type
(CONST BYTE *)strCorrect, // value data
cbData); CorrectFree(strCorrect, (const WCHAR *)lpData);
return returnValue; } else { // Pass data on through
LONG returnValue = ORIGINAL_API(RegSetValueExW)( hKey, // handle to key
lpValueName, // value name
Reserved, // reserved
dwType, // value type
lpData, // value data
cbData); return returnValue; } }
HFILE APIHOOK(_lopen)( LPCSTR lpPathName, int iReadWrite ) { char * strCorrect = CorrectPath(lpPathName, "lopen");
HFILE returnValue = ORIGINAL_API(_lopen)(strCorrect, iReadWrite);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
HFILE APIHOOK(_lcreat)( LPCSTR lpPathName, int iAttribute ) { char * strCorrect = CorrectPath(lpPathName, "lcreat");
HFILE returnValue = ORIGINAL_API(_lcreat)(strCorrect, iAttribute);
CorrectFree(strCorrect, lpPathName);
return returnValue; }
HANDLE APIHOOK(LoadImageA)( HINSTANCE hinst, // handle to instance
LPCSTR lpszName, // name or identifier of the image
UINT uType, // image type
int cxDesired, // desired width
int cyDesired, // desired height
UINT fuLoad // load options
) { HANDLE returnValue = NULL;
// Another one of those incredibly overloaded API's:
// lpszName is not always a path
if ((uType == IMAGE_BITMAP) && (fuLoad & LR_LOADFROMFILE) && !IsBadStringPtrA(lpszName, 1)) { char * strCorrect = CorrectPath(lpszName, "LoadImageA");
returnValue = ORIGINAL_API(LoadImageA)(hinst, strCorrect, uType, cxDesired, cyDesired, fuLoad);
CorrectFree(strCorrect, lpszName); } else { returnValue = ORIGINAL_API(LoadImageA)(hinst, lpszName, uType, cxDesired, cyDesired, fuLoad); }
return returnValue; }
IMPLEMENT_COMSERVER_HOOK(SHELL32)
BOOL NOTIFY_FUNCTION( DWORD fdwReason ) { BOOL bSuccess = TRUE;
if (fdwReason == DLL_PROCESS_ATTACH) { bSuccess = ParseCommandLine(COMMAND_LINE); if (bSuccess) { // Create g_AllocatedPathCorrector
return InitPathcorrectorClass(); } } else if (fdwReason == SHIM_STATIC_DLLS_INITIALIZED) { // It is now safe for us to do our work
g_PathCorrector = g_AllocatedPathCorrector; InitializePathCorrections(); } return bSuccess; }
/*++
Register hooked functions
--*/
HOOK_BEGIN
CALL_NOTIFY_FUNCTION
if (g_bCreateProcessRoutines) { APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA) APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessW) APIHOOK_ENTRY(KERNEL32.DLL, WinExec)
APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteA) APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteW) APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteExA) APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteExW) }
if (g_bGetCommandLineRoutines) { APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA) APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineW) }
if (g_bProfileRoutines) { APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileIntA) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileIntW) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionA) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionW) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionNamesA) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionNamesW) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStringA) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStringW) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStructA) APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStructW) APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileSectionA) APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileSectionW) APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStringA) APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStringW) APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStructA) APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStructW) }
if (g_bFileRoutines) { APIHOOK_ENTRY(KERNEL32.DLL, CopyFileA) APIHOOK_ENTRY(KERNEL32.DLL, CopyFileW) APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExA) APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExW) APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryA) APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryW) APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExA) APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA) APIHOOK_ENTRY(KERNEL32.DLL, CreateFileW) APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileA) APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileW)
APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA) APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW) APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileExA) APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileExW)
APIHOOK_ENTRY(KERNEL32.DLL, GetBinaryTypeA) APIHOOK_ENTRY(KERNEL32.DLL, GetBinaryTypeW) APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA) APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW) APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesExA) APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesExW) APIHOOK_ENTRY(KERNEL32.DLL, SetFileAttributesA) APIHOOK_ENTRY(KERNEL32.DLL, SetFileAttributesW)
APIHOOK_ENTRY(KERNEL32.DLL, MoveFileA) APIHOOK_ENTRY(KERNEL32.DLL, MoveFileW) APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExA) APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExW) APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressA) APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressW)
APIHOOK_ENTRY(KERNEL32.DLL, RemoveDirectoryA) APIHOOK_ENTRY(KERNEL32.DLL, RemoveDirectoryW) APIHOOK_ENTRY(KERNEL32.DLL, SetCurrentDirectoryA) APIHOOK_ENTRY(KERNEL32.DLL, SetCurrentDirectoryW)
APIHOOK_ENTRY(KERNEL32.DLL, OpenFile) // 16 bit compatibility file routines
APIHOOK_ENTRY(KERNEL32.DLL, _lopen) APIHOOK_ENTRY(KERNEL32.DLL, _lcreat) }
if (g_bRegSetValueRoutines) { APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueA) APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueW) APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExA) APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExW) }
if (g_bShellLinkRoutines) { APIHOOK_ENTRY_COMSERVER(SHELL32)
COMHOOK_ENTRY(ShellLink, IShellLinkA, SetPath, 20) COMHOOK_ENTRY(ShellLink, IShellLinkW, SetPath, 20) COMHOOK_ENTRY(ShellLink, IShellLinkA, SetArguments, 11) COMHOOK_ENTRY(ShellLink, IShellLinkW, SetArguments, 11) COMHOOK_ENTRY(ShellLink, IShellLinkA, SetIconLocation, 17) COMHOOK_ENTRY(ShellLink, IShellLinkW, SetIconLocation, 17)
COMHOOK_ENTRY(ShellLink, IPersistFile, Save, 6) }
if (g_bLoadImage) { APIHOOK_ENTRY(USER32.DLL, LoadImageA) }
HOOK_END
IMPLEMENT_SHIM_END
|