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.

197 lines
5.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation.
  5. //
  6. // File: D L O A D . C
  7. //
  8. // Contents: Delay Load Failure Hook
  9. //
  10. // Notes: This lib implements all of the stub functions for modules
  11. // that are delayloaded by the OS. It merges together all of the
  12. // dloadXXX.lib files from each depot.
  13. //
  14. // To Use: In your sources file, right after you specify the modules you
  15. // are delayloading do:
  16. //
  17. // DLOAD_ERROR_HANDLER=kernel32
  18. //
  19. // If you want to use kernel32 as your dload error handler. If you
  20. // do this, your dll will be checked that everything it delayloads
  21. // has a proper error handler function by the delayload.cmd postbuild
  22. // script.
  23. //
  24. // To check that all functions you delayload have error handlers you
  25. // can do the following:
  26. //
  27. // 1. do a "link -dump -imports foo.dll", and find all functions
  28. // that you delay-import.
  29. //
  30. // 2. do a "link -dump -symbols \nt\public\internal\base\lib\*\dload.lib"
  31. // and make sure every function that shows up as delayloaded in step #1
  32. // has a error handler fn. in dload.lib.
  33. //
  34. // 3. if a function is missing in step #2 (dlcheck will also fails as
  35. // part of postbuild), you need to add an error handler. Go to the depot
  36. // where that dll is build, and go to the dload subdir (usually under
  37. // the root or under the published\dload subdir) and add an error handler.
  38. //
  39. //
  40. // Author: shaunco 19 May 1998
  41. // Modified: reinerf 12 Jan 2001 Changed above comment
  42. //
  43. //----------------------------------------------------------------------------
  44. #include "pch.h"
  45. #pragma hdrstop
  46. // External global variables
  47. //
  48. extern HANDLE BaseDllHandle;
  49. #if DBG
  50. extern int DloadBreakOnFail;
  51. extern int DloadDbgPrint;
  52. #endif
  53. #if DBG
  54. #define DBG_ERROR 0
  55. #define DBG_INFO 1
  56. //+---------------------------------------------------------------------------
  57. // Trace a message to the debug console. Prefix with who we are so
  58. // people know who to contact.
  59. //
  60. INT
  61. __cdecl
  62. DbgTrace (
  63. INT nLevel,
  64. PCSTR Format,
  65. ...
  66. )
  67. {
  68. INT cch = 0;
  69. if (DloadDbgPrint) {
  70. if (nLevel <= DBG_INFO)
  71. {
  72. CHAR szBuf [1024];
  73. va_list argptr;
  74. va_start (argptr, Format);
  75. cch = vsprintf (szBuf, Format, argptr);
  76. va_end (argptr);
  77. OutputDebugStringA ("dload: ");
  78. OutputDebugStringA (szBuf);
  79. }
  80. }
  81. return cch;
  82. }
  83. //+---------------------------------------------------------------------------
  84. // Cannot use RtlAssert since doing so will cause setupapi.dll to fail
  85. // for upgrade over win95(gold)
  86. //
  87. VOID
  88. WINAPI
  89. DelayLoadAssertFailed(
  90. IN PCSTR FailedAssertion,
  91. IN PVOID FileName,
  92. IN ULONG LineNumber,
  93. IN PCSTR Message OPTIONAL
  94. )
  95. {
  96. DbgTrace (
  97. DBG_ERROR,
  98. "Assertion failure at line %u in file %s: %s%s%s\r\n",
  99. LineNumber,
  100. FileName,
  101. FailedAssertion,
  102. (Message && Message[0] && FailedAssertion[0]) ? " " : "",
  103. Message ? Message : ""
  104. );
  105. if (DloadBreakOnFail) {
  106. DebugBreak();
  107. }
  108. }
  109. #endif // DBG
  110. //+---------------------------------------------------------------------------
  111. //
  112. //
  113. FARPROC
  114. WINAPI
  115. DelayLoadFailureHook (
  116. LPCSTR pszDllName,
  117. LPCSTR pszProcName
  118. )
  119. {
  120. FARPROC ReturnValue = NULL;
  121. MYASSERT (pszDllName);
  122. MYASSERT (pszProcName);
  123. // Trace some potentially useful information about why we were called.
  124. //
  125. #if DBG
  126. if (!IS_INTRESOURCE(pszProcName))
  127. {
  128. DbgTrace (DBG_INFO,
  129. "DelayloadFailureHook: Dll=%s, ProcName=%s\n",
  130. pszDllName,
  131. pszProcName);
  132. }
  133. else
  134. {
  135. DbgTrace (DBG_INFO,
  136. "DelayloadFailureHook: Dll=%s, Ordinal=%u\n",
  137. pszDllName,
  138. (DWORD)((DWORD_PTR)pszProcName));
  139. }
  140. #endif
  141. ReturnValue = LookupHandler(pszDllName, pszProcName);
  142. if (ReturnValue)
  143. {
  144. #if DBG
  145. DbgTrace (DBG_INFO,
  146. "Returning handler function at address 0x%08x\n",
  147. (LONG_PTR)ReturnValue);
  148. #endif
  149. }
  150. #if DBG
  151. else
  152. {
  153. CHAR pszMsg [MAX_PATH];
  154. if (!IS_INTRESOURCE(pszProcName))
  155. {
  156. sprintf (pszMsg,
  157. "No delayload handler found for Dll=%s, ProcName=%s\n"
  158. "Please add one in private\\dload.",
  159. pszDllName,
  160. pszProcName);
  161. }
  162. else
  163. {
  164. sprintf (pszMsg,
  165. "No delayload handler found for Dll=%s, Ordinal=%u\n"
  166. "Please add one in private\\dload.",
  167. pszDllName,
  168. (DWORD)((DWORD_PTR)pszProcName));
  169. }
  170. DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg);
  171. }
  172. #endif
  173. return ReturnValue;
  174. }