//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: L O O K U P . C // // Contents: Routines to find a handler for a DLL procedure. // // Notes: // // Author: shaunco 21 May 1998 // //---------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop VOID WINAPI AssertDelayLoadFailureMapsAreSorted ( VOID ) { #if DBG // Leave the function existing in free builds for binary compat on mixed checked/free, // since the checked in .lib is only free. UINT iDll, iProcName, iOrdinal; INT nRet; CHAR pszMsg [1024]; const DLOAD_DLL_ENTRY* pDll; const DLOAD_PROCNAME_MAP* pProcNameMap; const DLOAD_ORDINAL_MAP* pOrdinalMap; for (iDll = 0; iDll < g_DllMap.NumberOfEntries; iDll++) { if (iDll >= 1) { nRet = strcmp ( g_DllMap.pDllEntry[iDll].pszDll, g_DllMap.pDllEntry[iDll-1].pszDll); if (nRet <= 0) { sprintf (pszMsg, "dload: rows %u and %u are out of order in dload!g_DllMap", iDll-1, iDll); DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg); } } pDll = g_DllMap.pDllEntry + iDll; pProcNameMap = pDll->pProcNameMap; pOrdinalMap = pDll->pOrdinalMap; if (pProcNameMap) { MYASSERT (pProcNameMap->NumberOfEntries); for (iProcName = 0; iProcName < pProcNameMap->NumberOfEntries; iProcName++) { if (iProcName >= 1) { nRet = strcmp ( pProcNameMap->pProcNameEntry[iProcName].pszProcName, pProcNameMap->pProcNameEntry[iProcName-1].pszProcName); if (nRet <= 0) { sprintf (pszMsg, "dload: rows %u and %u of pProcNameMap are out " "of order in dload!g_DllMap for pszDll=%s", iProcName-1, iProcName, pDll->pszDll); DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg); } } } } if (pOrdinalMap) { MYASSERT (pOrdinalMap->NumberOfEntries); for (iOrdinal = 0; iOrdinal < pOrdinalMap->NumberOfEntries; iOrdinal++) { if (iOrdinal >= 1) { if (pOrdinalMap->pOrdinalEntry[iOrdinal].dwOrdinal <= pOrdinalMap->pOrdinalEntry[iOrdinal-1].dwOrdinal) { sprintf (pszMsg, "dload: rows %u and %u of pOrdinalMap are out " "of order in dload!g_DllMap for pszDll=%s", iOrdinal-1, iOrdinal, pDll->pszDll); DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg); } } } } } #endif } const DLOAD_DLL_ENTRY* FindDll ( LPCSTR pszDll ) { const DLOAD_DLL_ENTRY* pDll = NULL; CHAR pszDllLowerCased [MAX_PATH + 1] = {0}; INT nResult; // These must be signed integers for the following binary search // to work correctly when iMiddle == 0 and nResult < 0. // INT iLow; INT iMiddle; INT iHigh; MYASSERT (pszDll); MYASSERT (strlen (pszDll) <= MAX_PATH); strncat (pszDllLowerCased, pszDll, sizeof(pszDllLowerCased)-1); _strlwr (pszDllLowerCased); iLow = 0; iHigh = g_DllMap.NumberOfEntries - 1; while (iHigh >= iLow) { iMiddle = (iLow + iHigh) / 2; nResult = strcmp (pszDllLowerCased, g_DllMap.pDllEntry[iMiddle].pszDll); if (nResult < 0) { iHigh = iMiddle - 1; } else if (nResult > 0) { iLow = iMiddle + 1; } else { MYASSERT (0 == nResult); pDll = &g_DllMap.pDllEntry[iMiddle]; break; } } return pDll; } FARPROC LookupHandlerByName ( LPCSTR pszProcName, const DLOAD_PROCNAME_MAP* pMap ) { FARPROC pfnHandler = NULL; INT nResult; // These must be signed integers for the following binary search // to work correctly when iMiddle == 0 and nResult < 0. // INT iLow; INT iMiddle; INT iHigh; MYASSERT (pszProcName); iLow = 0; iHigh = pMap->NumberOfEntries - 1; while (iHigh >= iLow) { iMiddle = (iLow + iHigh) / 2; nResult = strcmp ( pszProcName, pMap->pProcNameEntry[iMiddle].pszProcName); if (nResult < 0) { iHigh = iMiddle - 1; } else if (nResult > 0) { iLow = iMiddle + 1; } else { MYASSERT (0 == nResult); pfnHandler = pMap->pProcNameEntry[iMiddle].pfnProc; break; } } return pfnHandler; } FARPROC LookupHandlerByOrdinal ( DWORD dwOrdinal, const DLOAD_ORDINAL_MAP* pMap ) { FARPROC pfnHandler = NULL; DWORD dwOrdinalProbe; // These must be signed integers for the following binary search // to work correctly when iMiddle == 0 and dwOrdinal < dwOrdinalProbe. // INT iLow; INT iMiddle; INT iHigh; iLow = 0; iHigh = pMap->NumberOfEntries - 1; while (iHigh >= iLow) { iMiddle = (iLow + iHigh) / 2; dwOrdinalProbe = pMap->pOrdinalEntry[iMiddle].dwOrdinal; if (dwOrdinal < dwOrdinalProbe) { iHigh = iMiddle - 1; } else if (dwOrdinal > dwOrdinalProbe) { iLow = iMiddle + 1; } else { MYASSERT (dwOrdinal == dwOrdinalProbe); pfnHandler = pMap->pOrdinalEntry[iMiddle].pfnProc; break; } } return pfnHandler; } FARPROC LookupHandler ( LPCSTR pszDllName, LPCSTR pszProcName ) { FARPROC pfnHandler = NULL; const DLOAD_DLL_ENTRY* pDll; MYASSERT (pszDllName); MYASSERT (pszProcName); // Find the DLL record if we have one. // pDll = FindDll (pszDllName); if (pDll) { // Now find the handler whether it be by name or ordinal. // if (!IS_INTRESOURCE(pszProcName) && pDll->pProcNameMap) { pfnHandler = LookupHandlerByName ( pszProcName, pDll->pProcNameMap); } else if (pDll->pOrdinalMap) { pfnHandler = LookupHandlerByOrdinal ( PtrToUlong(pszProcName), pDll->pOrdinalMap); } } return pfnHandler; }