Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2620 lines
80 KiB

/*++
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