Source code of Windows XP (NT5)
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.

231 lines
3.8 KiB

  1. /*++
  2. Copyright (c) 2000 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. --*/
  13. #include "precomp.h"
  14. IMPLEMENT_SHIM_BEGIN(EmulateEnvironmentBlock)
  15. #include "ShimHookMacro.h"
  16. APIHOOK_ENUM_BEGIN
  17. APIHOOK_ENUM_ENTRY(GetEnvironmentStrings)
  18. APIHOOK_ENUM_ENTRY(GetEnvironmentStringsA)
  19. APIHOOK_ENUM_ENTRY(GetEnvironmentStringsW)
  20. APIHOOK_ENUM_ENTRY(FreeEnvironmentStringsA)
  21. APIHOOK_ENUM_ENTRY(FreeEnvironmentStringsW)
  22. APIHOOK_ENUM_END
  23. #define MAX_ENV 1024
  24. CHAR g_szBlockA[MAX_ENV];
  25. WCHAR g_szBlockW[MAX_ENV];
  26. WCHAR *g_szEnv[] = {
  27. L"TMP=%TMP%",
  28. L"TEMP=%TEMP%",
  29. L"PROMPT=%PROMPT%",
  30. L"winbootdir=%WINDIR%",
  31. L"PATH=%WINDIR%",
  32. L"COMSPEC=%COMSPEC%",
  33. L"WINDIR=%WINDIR%",
  34. NULL
  35. };
  36. /*++
  37. Build a reasonable looking environment block
  38. --*/
  39. BOOL BuildEnvironmentStrings()
  40. {
  41. DWORD dwSize;
  42. WCHAR szTmp[MAX_PATH];
  43. LPWSTR lpCurr = &g_szBlockW[0];
  44. DPFN( eDbgLevelError, "Building Environment Block");
  45. //
  46. // Run g_szEnv, expand all the strings and cat them together to form the
  47. // new block
  48. //
  49. DWORD i = 0;
  50. while (g_szEnv[i])
  51. {
  52. dwSize = ExpandEnvironmentStringsW(g_szEnv[i], szTmp, MAX_PATH);
  53. if ((dwSize > 0) && (dwSize < MAX_PATH))
  54. {
  55. if (lpCurr + wcslen(szTmp) - g_szBlockW < MAX_ENV)
  56. {
  57. wcscat(lpCurr, szTmp);
  58. lpCurr += wcslen(lpCurr) + 1;
  59. DPFN( eDbgLevelError, "\tAdding: %S", szTmp);
  60. }
  61. else
  62. {
  63. DPFN( eDbgLevelError, "Enviroment > %08lx, ignoring %S", MAX_ENV, szTmp);
  64. }
  65. }
  66. i++;
  67. }
  68. //
  69. // Calculate the size of the new block
  70. //
  71. dwSize = lpCurr - g_szBlockW;
  72. //
  73. // ANSI conversion for the A functions
  74. //
  75. WideCharToMultiByte(
  76. CP_ACP,
  77. 0,
  78. (LPWSTR) g_szBlockW,
  79. dwSize,
  80. (LPSTR) g_szBlockA,
  81. dwSize,
  82. 0,
  83. 0);
  84. return TRUE;
  85. }
  86. /*++
  87. Return our block
  88. --*/
  89. LPVOID
  90. APIHOOK(GetEnvironmentStrings)()
  91. {
  92. return (LPVOID) g_szBlockA;
  93. }
  94. /*++
  95. Return our block
  96. --*/
  97. LPVOID
  98. APIHOOK(GetEnvironmentStringsA)()
  99. {
  100. return (LPVOID) g_szBlockA;
  101. }
  102. /*++
  103. Return our block
  104. --*/
  105. LPVOID
  106. APIHOOK(GetEnvironmentStringsW)()
  107. {
  108. return (LPVOID) g_szBlockW;
  109. }
  110. /*++
  111. Check for our block.
  112. --*/
  113. BOOL
  114. APIHOOK(FreeEnvironmentStringsA)(
  115. LPSTR lpszEnvironmentBlock
  116. )
  117. {
  118. if ((lpszEnvironmentBlock == (LPSTR)&g_szBlockA[0]) ||
  119. (lpszEnvironmentBlock == (LPSTR)&g_szBlockW[0]))
  120. {
  121. return TRUE;
  122. }
  123. else
  124. {
  125. return ORIGINAL_API(FreeEnvironmentStringsA)(lpszEnvironmentBlock);
  126. }
  127. }
  128. /*++
  129. Check for our block.
  130. --*/
  131. BOOL
  132. APIHOOK(FreeEnvironmentStringsW)(
  133. LPWSTR lpszEnvironmentBlock
  134. )
  135. {
  136. if ((lpszEnvironmentBlock == (LPWSTR)&g_szBlockA[0]) ||
  137. (lpszEnvironmentBlock == (LPWSTR)&g_szBlockW[0]))
  138. {
  139. return TRUE;
  140. }
  141. else
  142. {
  143. return ORIGINAL_API(FreeEnvironmentStringsW)(lpszEnvironmentBlock);
  144. }
  145. }
  146. /*++
  147. Register hooked functions
  148. --*/
  149. BOOL
  150. NOTIFY_FUNCTION(
  151. DWORD fdwReason
  152. )
  153. {
  154. if (fdwReason == DLL_PROCESS_ATTACH)
  155. {
  156. return BuildEnvironmentStrings();
  157. }
  158. return TRUE;
  159. }
  160. HOOK_BEGIN
  161. CALL_NOTIFY_FUNCTION
  162. APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStrings)
  163. APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStringsA)
  164. APIHOOK_ENTRY(KERNEL32.DLL, GetEnvironmentStringsW)
  165. APIHOOK_ENTRY(KERNEL32.DLL, FreeEnvironmentStringsA)
  166. APIHOOK_ENTRY(KERNEL32.DLL, FreeEnvironmentStringsW)
  167. HOOK_END
  168. IMPLEMENT_SHIM_END