window核心编程 20.4延迟载入dll的使用案例

 导入库的一些代码。

//延迟加载
#include<windowsx.h>
#include<tchar.h>
#include<StrSafe.h>
#include<Delayimp.h>

#pragma comment(lib,"Delayimp.lib")
TCHAR g_szDelayLoadModuleName[] = TEXT("20-DelayLoadLib");

LONG WINAPI DelayLoadDllExceptionDilter(PEXCEPTION_POINTERS pep);

void IsModuleLoaded(PCTSTR pszModuleName)
{
	HMODULE hmod = GetModuleHandle(pszModuleName);
	char sz[100];
#ifdef  UNICODE
	StringCchPrintfA(sz, _countof(sz), "Module \"%S\" is %Sloaded.",
		pszModuleName,(hmod == NULL)? L"not" : L"");
#else
	StringCchPrintfA(sz, _countof(sz), "Module \"%s\" is %sloaded.",
		pszModuleName, (hmod == NULL) ? L"not" : L"");
#endif //  UNICODE
	//chMB(sz);
}

int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int)
{
	//wrap all calls to delay-load DLL functions inside SEH
	__try {
		int x = 0;

		//if you're in the debugger ,try the new debug .Modules menu item to 
		//see that the DLL is not loaded prior to executing the line below
		IsModuleLoaded(g_szDelayLoadModuleName);
		x = fnLib();//Attempt to call delay-load function//随便的导入函数1
		//Use debug. Modules to see that the DLL is now loaded
		IsModuleLoaded(g_szDelayLoadModuleName);
		x = fnLib2();//Attempt to call delay-load function //随便的导入函数2
		//Unload the delay-loaded DLL
		//NOTE:name must exactly match /DelayLoad:(DllName)
		__FUnloadDelayLoadedDLL2("20-DelayLoadLib.dll");

		//Use debug. Modules to see that the DLL is now unloaded
		IsModuleLoaded(g_szDelayLoadModuleName);
		x = fnLib();//Attempt to call delay-load function//随便的导入函数1
		//Use debug. Modules to see that the DLL is now loaded again
		IsModuleLoaded(g_szDelayLoadModuleName);
	}
	__except (DelayLoadDllExceptionDilter(GetExceptionInformation()))
	{
		//nothing to do in here, thread continues to run normally
	}
	//More code can go here...
	return 0;
}
LONG WINAPI DelayLoadDllExceptionDilter(PEXCEPTION_POINTERS pep)
{
	//assume wo recognize this exception
	LONG lDisposition = EXCEPTION_EXECUTE_HANDLER;

	//If this is a Delay-load problem. ExceptionInformation[0]points
	//to a DelayLoadInfo structure that has detailed error info
	PDelayLoadInfo pdli = PDelayLoadInfo(pep->ExceptionRecord->ExceptionInformation[0]);
	
	//Create a buffer where wo construct error messages
	char sz[500] = { 0 };
	switch (pep->ExceptionRecord->ExceptionCode)
	{
	case VcppException(ERROR_SEVERITY_ERROR,ERROR_MOD_NOT_FOUND):
		//the Dll module was not found at runtime
		StringCchPrintfA(sz, _countof(sz), "Dll not found: %s", pdli->szDll);
		break;
	case VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND):
		if (pdli->dlp.fImportByName)
		{
			StringCchPrintfA(sz, _countof(sz), "Function %s was not found in %s",
				pdli->dlp.szProcName, pdli->szDll);
		}
		else
		{
			StringCchPrintfA(sz, _countof(sz), "Function ordinal %d was not found in %s",
				pdli->dlp.dwOrdinal,pdli->szDll);
		}
		break;
	default:
		lDisposition = EXCEPTION_CONTINUE_SEARCH;
		break;
	}
	if (lDisposition == EXCEPTION_CONTINUE_SEARCH)
	{
		//chMB(sz);
	}
	return (lDisposition);
}

FARPROC WINAPI DliHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
	FARPROC fp = NULL;//default return value

	//NOTE: the members of the DelayLoadInfo structure pointed
	//to by pdli show the results of progress made so far
	switch (dliNotify)
	{
	case dliStartProcessing:
		//call when __delayloadhelper2 attempts to find a DLL/function
		//return 0 to have normal behavior or nonzero ti override
		//everything (you will still get dliNoteEndProcessing)
		break;
	case dliNotePreLoadLibrary:
		//called if loadlibrary
		//return NULL to have __delayLoadHelper2 call LoadLibrary
		//or you can call LoadLibrary yourself and return the HMODULE
		fp = (FARPROC)(HMODULE)NULL;
		break;
	case dliFailLoadLib:
		//called if loadLibrary fails
		//again ,you can call loadlibrary yourself here and return an HMODULE
		//if you return NULL, __delayLoadHelper2 raises the
		//ERROR_MOD_NOT_FOUND exception
		fp = (FARPROC)(HMODULE)NULL;
		break;
	case dliNotePreGetProcAddress:
		//called just befor GetProcAddress
		//Return NULL to have __delayLoadHelper2 call GetProcAddress,
		//or you can call GetProcAddress yourself and return the address
		fp = (FARPROC)NULL;
		break;
	case dliFailGetProc:
		//called if GetProcAddress fails
		//you can call GetProcAddress yourself here and return an address
		//If you return NULL ,__delayLoadHelper2 raises the 
		//ERROR_PROC_NOT_FOUND exception
		fp = (FARPROC)NULL;
		break;
	case dliNoteEndProcessing:
		//A simple notification that __delayLoadHelper2 is done
		//you can examine the members of the DelayLoadInfo structure
		//pointed to by pdli and raise an exception if you desire

		break;
	default:
		break;
	}
	return (fp);

}
//Tell __delayLoadHelper2 to call my hook function
PfnDliHook __pfnDliNotifyHook2 = DliHook;
PfnDliHook __pfnDliFailureHook2 = DliHook;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值