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
290 lines
7.3 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|
|
|