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.

290 lines
7.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: L O O K U P . C
  7. //
  8. // Contents: Routines to find a handler for a DLL procedure.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 21 May 1998
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. VOID
  18. WINAPI
  19. AssertDelayLoadFailureMapsAreSorted (
  20. VOID
  21. )
  22. {
  23. #if DBG // Leave the function existing in free builds for binary compat on mixed checked/free,
  24. // since the checked in .lib is only free.
  25. UINT iDll, iProcName, iOrdinal;
  26. INT nRet;
  27. CHAR pszMsg [1024];
  28. const DLOAD_DLL_ENTRY* pDll;
  29. const DLOAD_PROCNAME_MAP* pProcNameMap;
  30. const DLOAD_ORDINAL_MAP* pOrdinalMap;
  31. for (iDll = 0;
  32. iDll < g_DllMap.NumberOfEntries;
  33. iDll++)
  34. {
  35. if (iDll >= 1)
  36. {
  37. nRet = strcmp (
  38. g_DllMap.pDllEntry[iDll].pszDll,
  39. g_DllMap.pDllEntry[iDll-1].pszDll);
  40. if (nRet <= 0)
  41. {
  42. sprintf (pszMsg,
  43. "dload: rows %u and %u are out of order in dload!g_DllMap",
  44. iDll-1, iDll);
  45. DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg);
  46. }
  47. }
  48. pDll = g_DllMap.pDllEntry + iDll;
  49. pProcNameMap = pDll->pProcNameMap;
  50. pOrdinalMap = pDll->pOrdinalMap;
  51. if (pProcNameMap)
  52. {
  53. MYASSERT (pProcNameMap->NumberOfEntries);
  54. for (iProcName = 0;
  55. iProcName < pProcNameMap->NumberOfEntries;
  56. iProcName++)
  57. {
  58. if (iProcName >= 1)
  59. {
  60. nRet = strcmp (
  61. pProcNameMap->pProcNameEntry[iProcName].pszProcName,
  62. pProcNameMap->pProcNameEntry[iProcName-1].pszProcName);
  63. if (nRet <= 0)
  64. {
  65. sprintf (pszMsg,
  66. "dload: rows %u and %u of pProcNameMap are out "
  67. "of order in dload!g_DllMap for pszDll=%s",
  68. iProcName-1, iProcName, pDll->pszDll);
  69. DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg);
  70. }
  71. }
  72. }
  73. }
  74. if (pOrdinalMap)
  75. {
  76. MYASSERT (pOrdinalMap->NumberOfEntries);
  77. for (iOrdinal = 0;
  78. iOrdinal < pOrdinalMap->NumberOfEntries;
  79. iOrdinal++)
  80. {
  81. if (iOrdinal >= 1)
  82. {
  83. if (pOrdinalMap->pOrdinalEntry[iOrdinal].dwOrdinal <=
  84. pOrdinalMap->pOrdinalEntry[iOrdinal-1].dwOrdinal)
  85. {
  86. sprintf (pszMsg,
  87. "dload: rows %u and %u of pOrdinalMap are out "
  88. "of order in dload!g_DllMap for pszDll=%s",
  89. iOrdinal-1, iOrdinal, pDll->pszDll);
  90. DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg);
  91. }
  92. }
  93. }
  94. }
  95. }
  96. #endif
  97. }
  98. const DLOAD_DLL_ENTRY*
  99. FindDll (
  100. LPCSTR pszDll
  101. )
  102. {
  103. const DLOAD_DLL_ENTRY* pDll = NULL;
  104. CHAR pszDllLowerCased [MAX_PATH + 1] = {0};
  105. INT nResult;
  106. // These must be signed integers for the following binary search
  107. // to work correctly when iMiddle == 0 and nResult < 0.
  108. //
  109. INT iLow;
  110. INT iMiddle;
  111. INT iHigh;
  112. MYASSERT (pszDll);
  113. MYASSERT (strlen (pszDll) <= MAX_PATH);
  114. strncat (pszDllLowerCased, pszDll, sizeof(pszDllLowerCased)-1);
  115. _strlwr (pszDllLowerCased);
  116. iLow = 0;
  117. iHigh = g_DllMap.NumberOfEntries - 1;
  118. while (iHigh >= iLow)
  119. {
  120. iMiddle = (iLow + iHigh) / 2;
  121. nResult = strcmp (pszDllLowerCased, g_DllMap.pDllEntry[iMiddle].pszDll);
  122. if (nResult < 0)
  123. {
  124. iHigh = iMiddle - 1;
  125. }
  126. else if (nResult > 0)
  127. {
  128. iLow = iMiddle + 1;
  129. }
  130. else
  131. {
  132. MYASSERT (0 == nResult);
  133. pDll = &g_DllMap.pDllEntry[iMiddle];
  134. break;
  135. }
  136. }
  137. return pDll;
  138. }
  139. FARPROC
  140. LookupHandlerByName (
  141. LPCSTR pszProcName,
  142. const DLOAD_PROCNAME_MAP* pMap
  143. )
  144. {
  145. FARPROC pfnHandler = NULL;
  146. INT nResult;
  147. // These must be signed integers for the following binary search
  148. // to work correctly when iMiddle == 0 and nResult < 0.
  149. //
  150. INT iLow;
  151. INT iMiddle;
  152. INT iHigh;
  153. MYASSERT (pszProcName);
  154. iLow = 0;
  155. iHigh = pMap->NumberOfEntries - 1;
  156. while (iHigh >= iLow)
  157. {
  158. iMiddle = (iLow + iHigh) / 2;
  159. nResult = strcmp (
  160. pszProcName,
  161. pMap->pProcNameEntry[iMiddle].pszProcName);
  162. if (nResult < 0)
  163. {
  164. iHigh = iMiddle - 1;
  165. }
  166. else if (nResult > 0)
  167. {
  168. iLow = iMiddle + 1;
  169. }
  170. else
  171. {
  172. MYASSERT (0 == nResult);
  173. pfnHandler = pMap->pProcNameEntry[iMiddle].pfnProc;
  174. break;
  175. }
  176. }
  177. return pfnHandler;
  178. }
  179. FARPROC
  180. LookupHandlerByOrdinal (
  181. DWORD dwOrdinal,
  182. const DLOAD_ORDINAL_MAP* pMap
  183. )
  184. {
  185. FARPROC pfnHandler = NULL;
  186. DWORD dwOrdinalProbe;
  187. // These must be signed integers for the following binary search
  188. // to work correctly when iMiddle == 0 and dwOrdinal < dwOrdinalProbe.
  189. //
  190. INT iLow;
  191. INT iMiddle;
  192. INT iHigh;
  193. iLow = 0;
  194. iHigh = pMap->NumberOfEntries - 1;
  195. while (iHigh >= iLow)
  196. {
  197. iMiddle = (iLow + iHigh) / 2;
  198. dwOrdinalProbe = pMap->pOrdinalEntry[iMiddle].dwOrdinal;
  199. if (dwOrdinal < dwOrdinalProbe)
  200. {
  201. iHigh = iMiddle - 1;
  202. }
  203. else if (dwOrdinal > dwOrdinalProbe)
  204. {
  205. iLow = iMiddle + 1;
  206. }
  207. else
  208. {
  209. MYASSERT (dwOrdinal == dwOrdinalProbe);
  210. pfnHandler = pMap->pOrdinalEntry[iMiddle].pfnProc;
  211. break;
  212. }
  213. }
  214. return pfnHandler;
  215. }
  216. FARPROC
  217. LookupHandler (
  218. LPCSTR pszDllName,
  219. LPCSTR pszProcName
  220. )
  221. {
  222. FARPROC pfnHandler = NULL;
  223. const DLOAD_DLL_ENTRY* pDll;
  224. MYASSERT (pszDllName);
  225. MYASSERT (pszProcName);
  226. // Find the DLL record if we have one.
  227. //
  228. pDll = FindDll (pszDllName);
  229. if (pDll)
  230. {
  231. // Now find the handler whether it be by name or ordinal.
  232. //
  233. if (!IS_INTRESOURCE(pszProcName) &&
  234. pDll->pProcNameMap)
  235. {
  236. pfnHandler = LookupHandlerByName (
  237. pszProcName,
  238. pDll->pProcNameMap);
  239. }
  240. else if (pDll->pOrdinalMap)
  241. {
  242. pfnHandler = LookupHandlerByOrdinal (
  243. PtrToUlong(pszProcName),
  244. pDll->pOrdinalMap);
  245. }
  246. }
  247. return pfnHandler;
  248. }