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.

240 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. EmulateEnvironmentBlock.cpp
  5. Abstract:
  6. Shrink the enviroment strings to avoid memory corruption experienced by
  7. some apps when they get a larger than expected enviroment.
  8. Notes:
  9. This is a general purpose shim.
  10. History:
  11. 01/19/2001 linstev Created
  12. 02/18/2002 mnikkel modified to use strsafe routines.
  13. --*/
  14. #include "precomp.h"
  15. IMPLEMENT_SHIM_BEGIN(EmulateEnvironmentBlock)
  16. #include "ShimHookMacro.h"
  17. APIHOOK_ENUM_BEGIN
  18. APIHOOK_ENUM_ENTRY(GetEnvironmentStrings)
  19. APIHOOK_ENUM_ENTRY(GetEnvironmentStringsA)
  20. APIHOOK_ENUM_ENTRY(GetEnvironmentStringsW)
  21. APIHOOK_ENUM_ENTRY(FreeEnvironmentStringsA)
  22. APIHOOK_ENUM_ENTRY(FreeEnvironmentStringsW)
  23. APIHOOK_ENUM_END
  24. #define MAX_ENV 1024
  25. CHAR g_szBlockA[MAX_ENV];
  26. WCHAR g_szBlockW[MAX_ENV];
  27. WCHAR *g_szEnv[] = {
  28. L"TMP=%TMP%",
  29. L"TEMP=%TEMP%",
  30. L"PROMPT=%PROMPT%",
  31. L"winbootdir=%WINDIR%",
  32. L"PATH=%WINDIR%",
  33. L"COMSPEC=%COMSPEC%",
  34. L"WINDIR=%WINDIR%",
  35. NULL
  36. };
  37. /*++
  38. Build a reasonable looking environment block
  39. --*/
  40. BOOL BuildEnvironmentStrings()
  41. {
  42. WCHAR *pPtr = g_szBlockW;
  43. WCHAR szTmp[MAX_PATH];
  44. DWORD dwSize = 0; DWORD i = 0;
  45. DPFN( eDbgLevelError, "Building Environment Block");
  46. // Calculate the remaining block size, subtract one so we can add extra null
  47. // terminator after all variables are added.
  48. DWORD dwRemainingBlockSize = ARRAYSIZE(g_szBlockW)-1;
  49. //
  50. // Run g_szEnv, expand all the strings and cat them together to form the
  51. // new block. pPtr points to current location to write to in g_szBlockW.
  52. //
  53. while (g_szEnv[i])
  54. {
  55. // Expand the environment string, Note: dwSize DOES include the null terminator.
  56. dwSize = ExpandEnvironmentStringsW(g_szEnv[i], szTmp, MAX_PATH);
  57. if ((dwSize > 0) && (dwSize <= MAX_PATH))
  58. {
  59. // If expansion was successful add the string to our environment block
  60. // if there is room.
  61. if (dwSize <= dwRemainingBlockSize &&
  62. S_OK == StringCchCopy(pPtr, dwRemainingBlockSize, szTmp))
  63. {
  64. // update the block size remaining and move the location pointer.
  65. dwRemainingBlockSize -= dwSize;
  66. pPtr += dwSize;
  67. DPFN( eDbgLevelError, "\tAdding: %S", szTmp);
  68. }
  69. else
  70. {
  71. DPFN( eDbgLevelError, "Enviroment > %08lx, ignoring %S", MAX_ENV, szTmp);
  72. }
  73. }
  74. i++;
  75. }
  76. //
  77. // Add the extra null terminator and calculate size of env block.
  78. //
  79. *pPtr = L'\0';
  80. pPtr++;
  81. dwSize = pPtr - g_szBlockW;
  82. //
  83. // ANSI conversion for the A functions
  84. //
  85. WideCharToMultiByte(
  86. CP_ACP,
  87. 0,
  88. (LPWSTR) g_szBlockW,
  89. dwSize,
  90. (LPSTR) g_szBlockA,
  91. dwSize,
  92. 0,
  93. 0);
  94. return TRUE;
  95. }
  96. /*++
  97. Return our block
  98. --*/
  99. LPVOID
  100. APIHOOK(GetEnvironmentStrings)()
  101. {
  102. return (LPVOID) g_szBlockA;
  103. }
  104. /*++
  105. Return our block
  106. --*/
  107. LPVOID
  108. APIHOOK(GetEnvironmentStringsA)()
  109. {
  110. return (LPVOID) g_szBlockA;
  111. }
  112. /*++
  113. Return our block
  114. --*/
  115. LPVOID
  116. APIHOOK(GetEnvironmentStringsW)()
  117. {
  118. return (LPVOID) g_szBlockW;
  119. }
  120. /*++
  121. Check for our block.
  122. --*/
  123. BOOL
  124. APIHOOK(FreeEnvironmentStringsA)(
  125. LPSTR lpszEnvironmentBlock
  126. )
  127. {
  128. if ((lpszEnvironmentBlock == (LPSTR)&g_szBlockA[0]) ||
  129. (lpszEnvironmentBlock == (LPSTR)&g_szBlockW[0]))
  130. {
  131. return TRUE;
  132. }
  133. else
  134. {
  135. return ORIGINAL_API(FreeEnvironmentStringsA)(lpszEnvironmentBlock);
  136. }
  137. }
  138. /*++
  139. Check for our block.
  140. --*/
  141. BOOL
  142. APIHOOK(FreeEnvironmentStringsW)(
  143. LPWSTR lpszEnvironmentBlock
  144. )
  145. {
  146. if ((lpszEnvironmentBlock == (LPWSTR)&g_szBlockA[0]) ||
  147. (lpszEnvironmentBlock == (LPWSTR)&g_szBlockW[0]))
  148. {
  149. return TRUE;
  150. }
  151. else
  152. {
  153. return ORIGINAL_API(FreeEnvironmentStringsW)(lpszEnvironmentBlock);
  154. }
  155. }
  156. /*++
  157. Register hooked functions
  158. --*/
  159. BOOL
  160. NOTIFY_FUNCTION(
  161. DWORD fdwReason
  162. )
  163. {
  164. if (fdwReason == DLL_PROCESS_ATTACH)
  165. {
  166. return BuildEnvironmentStrings();
  167. }
  168. return TRUE;
  169. }
  170. HOOK_BEGIN
  171. CALL_NOTIFY_FUNCTION
  172. APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStrings)
  173. APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStringsA)
  174. APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStringsW)
  175. APIHOOK_ENTRY(KERNEL32.DLL, FreeEnvironmentStringsA)
  176. APIHOOK_ENTRY(KERNEL32.DLL, FreeEnvironmentStringsW)
  177. HOOK_END
  178. IMPLEMENT_SHIM_END