windows-nt/Source/XPSP1/NT/mergedcomponents/dload/dload.c
2020-09-26 16:20:57 +08:00

198 lines
5 KiB
C

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: D L O A D . C
//
// Contents: Delay Load Failure Hook
//
// Notes: This lib implements all of the stub functions for modules
// that are delayloaded by the OS. It merges together all of the
// dloadXXX.lib files from each depot.
//
// To Use: In your sources file, right after you specify the modules you
// are delayloading do:
//
// DLOAD_ERROR_HANDLER=kernel32
//
// If you want to use kernel32 as your dload error handler. If you
// do this, your dll will be checked that everything it delayloads
// has a proper error handler function by the delayload.cmd postbuild
// script.
//
// To check that all functions you delayload have error handlers you
// can do the following:
//
// 1. do a "link -dump -imports foo.dll", and find all functions
// that you delay-import.
//
// 2. do a "link -dump -symbols \nt\public\internal\base\lib\*\dload.lib"
// and make sure every function that shows up as delayloaded in step #1
// has a error handler fn. in dload.lib.
//
// 3. if a function is missing in step #2 (dlcheck will also fails as
// part of postbuild), you need to add an error handler. Go to the depot
// where that dll is build, and go to the dload subdir (usually under
// the root or under the published\dload subdir) and add an error handler.
//
//
// Author: shaunco 19 May 1998
// Modified: reinerf 12 Jan 2001 Changed above comment
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
// External global variables
//
extern HANDLE BaseDllHandle;
#if DBG
extern int DloadBreakOnFail;
extern int DloadDbgPrint;
#endif
#if DBG
#define DBG_ERROR 0
#define DBG_INFO 1
//+---------------------------------------------------------------------------
// Trace a message to the debug console. Prefix with who we are so
// people know who to contact.
//
INT
__cdecl
DbgTrace (
INT nLevel,
PCSTR Format,
...
)
{
INT cch = 0;
if (DloadDbgPrint) {
if (nLevel <= DBG_INFO)
{
CHAR szBuf [1024];
va_list argptr;
va_start (argptr, Format);
cch = vsprintf (szBuf, Format, argptr);
va_end (argptr);
OutputDebugStringA ("dload: ");
OutputDebugStringA (szBuf);
}
}
return cch;
}
//+---------------------------------------------------------------------------
// Cannot use RtlAssert since doing so will cause setupapi.dll to fail
// for upgrade over win95(gold)
//
VOID
WINAPI
DelayLoadAssertFailed(
IN PCSTR FailedAssertion,
IN PVOID FileName,
IN ULONG LineNumber,
IN PCSTR Message OPTIONAL
)
{
DbgTrace (
DBG_ERROR,
"Assertion failure at line %u in file %s: %s%s%s\r\n",
LineNumber,
FileName,
FailedAssertion,
(Message && Message[0] && FailedAssertion[0]) ? " " : "",
Message ? Message : ""
);
if (DloadBreakOnFail) {
DebugBreak();
}
}
#endif // DBG
//+---------------------------------------------------------------------------
//
//
FARPROC
WINAPI
DelayLoadFailureHook (
LPCSTR pszDllName,
LPCSTR pszProcName
)
{
FARPROC ReturnValue = NULL;
MYASSERT (pszDllName);
MYASSERT (pszProcName);
// Trace some potentially useful information about why we were called.
//
#if DBG
if (!IS_INTRESOURCE(pszProcName))
{
DbgTrace (DBG_INFO,
"DelayloadFailureHook: Dll=%s, ProcName=%s\n",
pszDllName,
pszProcName);
}
else
{
DbgTrace (DBG_INFO,
"DelayloadFailureHook: Dll=%s, Ordinal=%u\n",
pszDllName,
(DWORD)((DWORD_PTR)pszProcName));
}
#endif
ReturnValue = LookupHandler(pszDllName, pszProcName);
if (ReturnValue)
{
#if DBG
DbgTrace (DBG_INFO,
"Returning handler function at address 0x%08x\n",
(LONG_PTR)ReturnValue);
#endif
}
#if DBG
else
{
CHAR pszMsg [MAX_PATH];
if (!IS_INTRESOURCE(pszProcName))
{
sprintf (pszMsg,
"No delayload handler found for Dll=%s, ProcName=%s\n"
"Please add one in private\\dload.",
pszDllName,
pszProcName);
}
else
{
sprintf (pszMsg,
"No delayload handler found for Dll=%s, Ordinal=%u\n"
"Please add one in private\\dload.",
pszDllName,
(DWORD)((DWORD_PTR)pszProcName));
}
DelayLoadAssertFailed ( "" , __FILE__, __LINE__, pszMsg);
}
#endif
return ReturnValue;
}