mirror of
https://github.com/reactos/reactos.git
synced 2024-11-18 21:13:52 +00:00
165 lines
4.7 KiB
C
165 lines
4.7 KiB
C
/*
|
|
* PROJECT: ReactOS SDK Library
|
|
* LICENSE: LGPL, see LGPL.txt in top level directory.
|
|
* FILE: lib/sdk/delayimp/delayimp.c
|
|
* PURPOSE: Library for delay importing from dlls
|
|
* PROGRAMMERS: Timo Kreuzer <timo.kreuzer@reactos.org>
|
|
* Mark Jansen
|
|
*
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <delayimp.h>
|
|
|
|
/**** Linker magic: provide a default (NULL) pointer, but allow the user to override it ****/
|
|
|
|
#if defined(__GNUC__)
|
|
PfnDliHook __pfnDliNotifyHook2;
|
|
PfnDliHook __pfnDliFailureHook2;
|
|
#else
|
|
/* The actual items we use */
|
|
extern PfnDliHook __pfnDliNotifyHook2;
|
|
extern PfnDliHook __pfnDliFailureHook2;
|
|
|
|
/* The fallback symbols */
|
|
extern PfnDliHook __pfnDliNotifyHook2Default = NULL;
|
|
extern PfnDliHook __pfnDliFailureHook2Default = NULL;
|
|
|
|
/* Tell the linker to use the fallback symbols */
|
|
#if defined (_M_IX86)
|
|
#pragma comment(linker, "/alternatename:___pfnDliNotifyHook2=___pfnDliNotifyHook2Default")
|
|
#pragma comment(linker, "/alternatename:___pfnDliFailureHook2=___pfnDliFailureHook2Default")
|
|
#else
|
|
#pragma comment(linker, "/alternatename:__pfnDliNotifyHook2=__pfnDliNotifyHook2Default")
|
|
#pragma comment(linker, "/alternatename:__pfnDliFailureHook2=__pfnDliFailureHook2Default")
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/**** Helper functions to convert from RVA to address ****/
|
|
|
|
FORCEINLINE
|
|
unsigned
|
|
IndexFromPImgThunkData(PCImgThunkData pData, PCImgThunkData pBase)
|
|
{
|
|
return pData - pBase;
|
|
}
|
|
|
|
extern const IMAGE_DOS_HEADER __ImageBase;
|
|
|
|
FORCEINLINE
|
|
PVOID
|
|
PFromRva(RVA rva)
|
|
{
|
|
return (PVOID)(((ULONG_PTR)(rva)) + ((ULONG_PTR)&__ImageBase));
|
|
}
|
|
|
|
|
|
/**** load helper ****/
|
|
|
|
FARPROC WINAPI
|
|
__delayLoadHelper2(PCImgDelayDescr pidd, PImgThunkData pIATEntry)
|
|
{
|
|
DelayLoadInfo dli = {0};
|
|
int index;
|
|
PImgThunkData pIAT;
|
|
PImgThunkData pINT;
|
|
HMODULE *phMod;
|
|
|
|
pIAT = PFromRva(pidd->rvaIAT);
|
|
pINT = PFromRva(pidd->rvaINT);
|
|
phMod = PFromRva(pidd->rvaHmod);
|
|
index = IndexFromPImgThunkData(pIATEntry, pIAT);
|
|
|
|
dli.cb = sizeof(dli);
|
|
dli.pidd = pidd;
|
|
dli.ppfn = (FARPROC*)&pIAT[index].u1.Function;
|
|
dli.szDll = PFromRva(pidd->rvaDLLName);
|
|
dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pINT[index].u1.Ordinal);
|
|
if (dli.dlp.fImportByName)
|
|
{
|
|
/* u1.AdressOfData points to a IMAGE_IMPORT_BY_NAME struct */
|
|
PIMAGE_IMPORT_BY_NAME piibn = PFromRva((RVA)pINT[index].u1.AddressOfData);
|
|
dli.dlp.szProcName = (LPCSTR)&piibn->Name;
|
|
}
|
|
else
|
|
{
|
|
dli.dlp.dwOrdinal = IMAGE_ORDINAL(pINT[index].u1.Ordinal);
|
|
}
|
|
|
|
if (__pfnDliNotifyHook2)
|
|
{
|
|
dli.pfnCur = __pfnDliNotifyHook2(dliStartProcessing, &dli);
|
|
if (dli.pfnCur)
|
|
{
|
|
pIAT[index].u1.Function = (DWORD_PTR)dli.pfnCur;
|
|
if (__pfnDliNotifyHook2)
|
|
__pfnDliNotifyHook2(dliNoteEndProcessing, &dli);
|
|
|
|
return dli.pfnCur;
|
|
}
|
|
}
|
|
|
|
dli.hmodCur = *phMod;
|
|
|
|
if (dli.hmodCur == NULL)
|
|
{
|
|
if (__pfnDliNotifyHook2)
|
|
dli.hmodCur = (HMODULE)__pfnDliNotifyHook2(dliNotePreLoadLibrary, &dli);
|
|
if (dli.hmodCur == NULL)
|
|
{
|
|
dli.hmodCur = LoadLibraryA(dli.szDll);
|
|
if (dli.hmodCur == NULL)
|
|
{
|
|
dli.dwLastError = GetLastError();
|
|
if (__pfnDliFailureHook2)
|
|
dli.hmodCur = (HMODULE)__pfnDliFailureHook2(dliFailLoadLib, &dli);
|
|
|
|
if (dli.hmodCur == NULL)
|
|
{
|
|
ULONG_PTR args[] = { (ULONG_PTR)&dli };
|
|
RaiseException(VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND), 0, 1, args);
|
|
|
|
/* If we survive the exception, we are expected to use pfnCur directly.. */
|
|
return dli.pfnCur;
|
|
}
|
|
}
|
|
}
|
|
*phMod = dli.hmodCur;
|
|
}
|
|
|
|
dli.dwLastError = ERROR_SUCCESS;
|
|
|
|
if (__pfnDliNotifyHook2)
|
|
dli.pfnCur = (FARPROC)__pfnDliNotifyHook2(dliNotePreGetProcAddress, &dli);
|
|
if (dli.pfnCur == NULL)
|
|
{
|
|
/* dli.dlp.szProcName might also contain the ordinal */
|
|
dli.pfnCur = GetProcAddress(dli.hmodCur, dli.dlp.szProcName);
|
|
if (dli.pfnCur == NULL)
|
|
{
|
|
dli.dwLastError = GetLastError();
|
|
if (__pfnDliFailureHook2)
|
|
dli.pfnCur = __pfnDliFailureHook2(dliFailGetProc, &dli);
|
|
|
|
if (dli.pfnCur == NULL)
|
|
{
|
|
ULONG_PTR args[] = { (ULONG_PTR)&dli };
|
|
RaiseException(VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND), 0, 1, args);
|
|
}
|
|
|
|
//return NULL;
|
|
}
|
|
}
|
|
|
|
pIAT[index].u1.Function = (DWORD_PTR)dli.pfnCur;
|
|
dli.dwLastError = ERROR_SUCCESS;
|
|
|
|
if (__pfnDliNotifyHook2)
|
|
__pfnDliNotifyHook2(dliNoteEndProcessing, &dli);
|
|
|
|
return dli.pfnCur;
|
|
}
|
|
|