241 lines
4.7 KiB
C++
241 lines
4.7 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000-2002 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
EmulateEnvironmentBlock.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Shrink the enviroment strings to avoid memory corruption experienced by
|
||
|
some apps when they get a larger than expected enviroment.
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
This is a general purpose shim.
|
||
|
|
||
|
History:
|
||
|
|
||
|
01/19/2001 linstev Created
|
||
|
02/18/2002 mnikkel modified to use strsafe routines.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(EmulateEnvironmentBlock)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
|
||
|
APIHOOK_ENUM_ENTRY(GetEnvironmentStrings)
|
||
|
APIHOOK_ENUM_ENTRY(GetEnvironmentStringsA)
|
||
|
APIHOOK_ENUM_ENTRY(GetEnvironmentStringsW)
|
||
|
APIHOOK_ENUM_ENTRY(FreeEnvironmentStringsA)
|
||
|
APIHOOK_ENUM_ENTRY(FreeEnvironmentStringsW)
|
||
|
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
#define MAX_ENV 1024
|
||
|
|
||
|
CHAR g_szBlockA[MAX_ENV];
|
||
|
WCHAR g_szBlockW[MAX_ENV];
|
||
|
|
||
|
WCHAR *g_szEnv[] = {
|
||
|
L"TMP=%TMP%",
|
||
|
L"TEMP=%TEMP%",
|
||
|
L"PROMPT=%PROMPT%",
|
||
|
L"winbootdir=%WINDIR%",
|
||
|
L"PATH=%WINDIR%",
|
||
|
L"COMSPEC=%COMSPEC%",
|
||
|
L"WINDIR=%WINDIR%",
|
||
|
NULL
|
||
|
};
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Build a reasonable looking environment block
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL BuildEnvironmentStrings()
|
||
|
{
|
||
|
WCHAR *pPtr = g_szBlockW;
|
||
|
WCHAR szTmp[MAX_PATH];
|
||
|
DWORD dwSize = 0; DWORD i = 0;
|
||
|
|
||
|
DPFN( eDbgLevelError, "Building Environment Block");
|
||
|
|
||
|
// Calculate the remaining block size, subtract one so we can add extra null
|
||
|
// terminator after all variables are added.
|
||
|
DWORD dwRemainingBlockSize = ARRAYSIZE(g_szBlockW)-1;
|
||
|
|
||
|
//
|
||
|
// Run g_szEnv, expand all the strings and cat them together to form the
|
||
|
// new block. pPtr points to current location to write to in g_szBlockW.
|
||
|
//
|
||
|
while (g_szEnv[i])
|
||
|
{
|
||
|
// Expand the environment string, Note: dwSize DOES include the null terminator.
|
||
|
dwSize = ExpandEnvironmentStringsW(g_szEnv[i], szTmp, MAX_PATH);
|
||
|
if ((dwSize > 0) && (dwSize <= MAX_PATH))
|
||
|
{
|
||
|
// If expansion was successful add the string to our environment block
|
||
|
// if there is room.
|
||
|
if (dwSize <= dwRemainingBlockSize &&
|
||
|
S_OK == StringCchCopy(pPtr, dwRemainingBlockSize, szTmp))
|
||
|
{
|
||
|
// update the block size remaining and move the location pointer.
|
||
|
dwRemainingBlockSize -= dwSize;
|
||
|
pPtr += dwSize;
|
||
|
DPFN( eDbgLevelError, "\tAdding: %S", szTmp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN( eDbgLevelError, "Enviroment > %08lx, ignoring %S", MAX_ENV, szTmp);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Add the extra null terminator and calculate size of env block.
|
||
|
//
|
||
|
*pPtr = L'\0';
|
||
|
pPtr++;
|
||
|
dwSize = pPtr - g_szBlockW;
|
||
|
|
||
|
//
|
||
|
// ANSI conversion for the A functions
|
||
|
//
|
||
|
|
||
|
WideCharToMultiByte(
|
||
|
CP_ACP,
|
||
|
0,
|
||
|
(LPWSTR) g_szBlockW,
|
||
|
dwSize,
|
||
|
(LPSTR) g_szBlockA,
|
||
|
dwSize,
|
||
|
0,
|
||
|
0);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Return our block
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LPVOID
|
||
|
APIHOOK(GetEnvironmentStrings)()
|
||
|
{
|
||
|
return (LPVOID) g_szBlockA;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Return our block
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LPVOID
|
||
|
APIHOOK(GetEnvironmentStringsA)()
|
||
|
{
|
||
|
return (LPVOID) g_szBlockA;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Return our block
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LPVOID
|
||
|
APIHOOK(GetEnvironmentStringsW)()
|
||
|
{
|
||
|
return (LPVOID) g_szBlockW;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Check for our block.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(FreeEnvironmentStringsA)(
|
||
|
LPSTR lpszEnvironmentBlock
|
||
|
)
|
||
|
{
|
||
|
if ((lpszEnvironmentBlock == (LPSTR)&g_szBlockA[0]) ||
|
||
|
(lpszEnvironmentBlock == (LPSTR)&g_szBlockW[0]))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ORIGINAL_API(FreeEnvironmentStringsA)(lpszEnvironmentBlock);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Check for our block.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(FreeEnvironmentStringsW)(
|
||
|
LPWSTR lpszEnvironmentBlock
|
||
|
)
|
||
|
{
|
||
|
if ((lpszEnvironmentBlock == (LPWSTR)&g_szBlockA[0]) ||
|
||
|
(lpszEnvironmentBlock == (LPWSTR)&g_szBlockW[0]))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ORIGINAL_API(FreeEnvironmentStringsW)(lpszEnvironmentBlock);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
NOTIFY_FUNCTION(
|
||
|
DWORD fdwReason
|
||
|
)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_ATTACH)
|
||
|
{
|
||
|
return BuildEnvironmentStrings();
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
|
||
|
CALL_NOTIFY_FUNCTION
|
||
|
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStrings)
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStringsA)
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStringsW)
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, FreeEnvironmentStringsA)
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, FreeEnvironmentStringsW)
|
||
|
|
||
|
HOOK_END
|
||
|
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|