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.

254 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. loadwrap.cxx
  6. Abstract:
  7. This implements a wrapper for all spooler calls to the loader to ensure that
  8. no exceptions are thrown from the loader and that on exit to every loader call,
  9. the owner of the loader lock is not the current thread. This is in response to
  10. a set of stress bugs where the loader lock is orphaned.
  11. Author:
  12. Mark Lawrence (mlawrenc) - 28 Feb 2001
  13. Environment:
  14. User Mode -Win32
  15. Revision History:
  16. --*/
  17. #include "spllibp.hxx"
  18. #include "loadwrap.hxx"
  19. //
  20. // Redefine all of the loader calls back to sanity.
  21. //
  22. #undef LoadLibrary
  23. #undef GetProcAddress
  24. #undef FreeLibrary
  25. #undef LoadLibraryEx
  26. #undef LoadResource
  27. #undef LoadString
  28. #ifdef UNICODE
  29. #define LoadLibrary LoadLibraryW
  30. #define LoadLibraryEx LoadLibraryExW
  31. #define LoadString LoadStringW
  32. #else
  33. #define LoadLibrary LoadLibraryA
  34. #define LoadLibraryEx LoadLibraryExA
  35. #define LoadString LoadStringA
  36. #endif // !UNICODE
  37. inline
  38. VOID
  39. EnterNtLoaderLockCheck(
  40. OUT BOOL *pbInLock
  41. )
  42. {
  43. *pbInLock = NtCurrentTeb()->ClientId.UniqueThread ==
  44. reinterpret_cast<PRTL_CRITICAL_SECTION>(NtCurrentPeb()->LoaderLock)->OwningThread;
  45. if (*pbInLock)
  46. {
  47. DbgPrintEx(DPFLTR_PRINTSPOOLER_ID, DPFLTR_INFO_LEVEL, "Loader Lock owned by thread on entry. Probably LoadLibrary in DllMain.\n");
  48. }
  49. }
  50. inline
  51. VOID
  52. CheckNotLoaderLockOwner(
  53. IN BOOL bInLock
  54. )
  55. {
  56. if (!bInLock &&
  57. NtCurrentTeb()->ClientId.UniqueThread ==
  58. reinterpret_cast<PRTL_CRITICAL_SECTION>(NtCurrentPeb()->LoaderLock)->OwningThread)
  59. {
  60. DbgPrint("Loader Lock owned by the current thread!\n");
  61. DebugBreak();
  62. }
  63. }
  64. inline
  65. VOID
  66. BreakAndAssert(
  67. IN PCH pszMessage
  68. )
  69. {
  70. DbgPrint("Unexpected Exception thrown from loader code : ");
  71. DbgPrint(pszMessage);
  72. DbgPrint(".\n");
  73. DebugBreak();
  74. }
  75. EXTERN_C
  76. HMODULE
  77. WrapLoadLibrary(
  78. IN LPCTSTR lpFileName
  79. )
  80. {
  81. HMODULE hModule = NULL;
  82. BOOL bLock = FALSE;
  83. EnterNtLoaderLockCheck(&bLock);
  84. __try
  85. {
  86. hModule = LoadLibrary(lpFileName);
  87. }
  88. __except(EXCEPTION_EXECUTE_HANDLER)
  89. {
  90. BreakAndAssert("LoadLibrary");
  91. }
  92. CheckNotLoaderLockOwner(bLock);
  93. return hModule;
  94. }
  95. EXTERN_C
  96. FARPROC
  97. WrapGetProcAddress(
  98. IN HMODULE hModule,
  99. IN LPCSTR lpProcName
  100. )
  101. {
  102. FARPROC pfnProc = NULL;
  103. BOOL bLock = FALSE;
  104. EnterNtLoaderLockCheck(&bLock);
  105. __try
  106. {
  107. pfnProc = GetProcAddress(hModule, lpProcName);
  108. }
  109. __except(EXCEPTION_EXECUTE_HANDLER)
  110. {
  111. BreakAndAssert("GetProcAddress");
  112. }
  113. CheckNotLoaderLockOwner(bLock);
  114. return pfnProc;
  115. }
  116. EXTERN_C
  117. BOOL
  118. WrapFreeLibrary(
  119. IN HMODULE hModule
  120. )
  121. {
  122. BOOL bRet = FALSE;
  123. BOOL bLock = FALSE;
  124. EnterNtLoaderLockCheck(&bLock);
  125. __try
  126. {
  127. bRet = FreeLibrary(hModule);
  128. }
  129. __except(EXCEPTION_EXECUTE_HANDLER)
  130. {
  131. BreakAndAssert("FreeLibrary");
  132. }
  133. CheckNotLoaderLockOwner(bLock);
  134. return bRet;
  135. }
  136. EXTERN_C
  137. HMODULE
  138. WrapLoadLibraryEx(
  139. IN LPCTSTR lpFileName,
  140. IN HANDLE hFile,
  141. IN DWORD dwFlags
  142. )
  143. {
  144. HMODULE hModule = NULL;
  145. BOOL bLock = FALSE;
  146. EnterNtLoaderLockCheck(&bLock);
  147. __try
  148. {
  149. hModule = LoadLibraryEx(lpFileName, hFile, dwFlags);
  150. }
  151. __except(EXCEPTION_EXECUTE_HANDLER)
  152. {
  153. BreakAndAssert("LoadLibraryEx");
  154. }
  155. CheckNotLoaderLockOwner(bLock);
  156. return hModule;
  157. }
  158. EXTERN_C
  159. HGLOBAL
  160. WrapLoadResource(
  161. IN HMODULE hModule,
  162. IN HRSRC hResInfo
  163. )
  164. {
  165. HGLOBAL hGlobal = NULL;
  166. BOOL bLock = FALSE;
  167. EnterNtLoaderLockCheck(&bLock);
  168. __try
  169. {
  170. hGlobal = LoadResource(hModule, hResInfo);
  171. }
  172. __except(EXCEPTION_EXECUTE_HANDLER)
  173. {
  174. BreakAndAssert("LoadResource");
  175. }
  176. CheckNotLoaderLockOwner(bLock);
  177. return hGlobal;
  178. }
  179. EXTERN_C
  180. int
  181. WrapLoadString(
  182. IN HINSTANCE hInstance,
  183. IN UINT uID,
  184. IN LPTSTR lpBuffer,
  185. IN int nBufferMax
  186. )
  187. {
  188. int iRet = 0;
  189. BOOL bLock = FALSE;
  190. EnterNtLoaderLockCheck(&bLock);
  191. __try
  192. {
  193. iRet = LoadString(hInstance, uID, lpBuffer, nBufferMax);
  194. }
  195. __except(EXCEPTION_EXECUTE_HANDLER)
  196. {
  197. BreakAndAssert("LoadString");
  198. }
  199. CheckNotLoaderLockOwner(bLock);
  200. return iRet;
  201. }