windows-nt/Source/XPSP1/NT/public/sdk/inc/delayimp.h
2020-09-26 16:20:57 +08:00

232 lines
6.6 KiB
C++

//
// DelayImp.h
//
// define structures and prototypes necessary for delay loading of imports
//
#if !defined(_delayimp_h)
#define _delayimp_h
#if _MSC_VER > 1000
#pragma once
#endif
#ifndef DELAYLOAD_VERSION
#ifdef _WIN64
#define DELAYLOAD_VERSION 0x200
#else
#define DELAYLOAD_VERSION 0x100
#endif
#endif
#if defined(__cplusplus)
#define ExternC extern "C"
#else
#define ExternC
#endif
typedef IMAGE_THUNK_DATA * PImgThunkData;
typedef const IMAGE_THUNK_DATA * PCImgThunkData;
typedef DWORD RVA;
typedef struct ImgDelayDescrV2 {
DWORD grAttrs; // attributes
RVA rvaDLLName; // RVA to dll name
RVA rvaHmod; // RVA of module handle
RVA rvaIAT; // RVA of the IAT
RVA rvaINT; // RVA of the INT
RVA rvaBoundIAT; // RVA of the optional bound IAT
RVA rvaUnloadIAT; // RVA of optional copy of original IAT
DWORD dwTimeStamp; // 0 if not bound,
// O.W. date/time stamp of DLL bound to (Old BIND)
} ImgDelayDescrV2, * PImgDelayDescrV2;
typedef struct ImgDelayDescrV1 {
DWORD grAttrs; // attributes
LPCSTR szName; // pointer to dll name
HMODULE * phmod; // address of module handle
PImgThunkData pIAT; // address of the IAT
PCImgThunkData pINT; // address of the INT
PCImgThunkData pBoundIAT; // address of the optional bound IAT
PCImgThunkData pUnloadIAT; // address of optional copy of original IAT
DWORD dwTimeStamp; // 0 if not bound,
// O.W. date/time stamp of DLL bound to (Old BIND)
} ImgDelayDescrV1, * PImgDelayDescrV1;
#if DELAYLOAD_VERSION >= 0x0200
typedef ImgDelayDescrV2 ImgDelayDescr;
typedef PImgDelayDescrV2 PImgDelayDescr;
#else
typedef ImgDelayDescrV1 ImgDelayDescr;
typedef PImgDelayDescrV1 PImgDelayDescr;
#endif
typedef const ImgDelayDescr * PCImgDelayDescr;
enum DLAttr { // Delay Load Attributes
dlattrRva = 0x1, // RVAs are used instead of pointers
};
//
// Delay load import hook notifications
//
enum {
dliStartProcessing, // used to bypass or note helper only
dliNotePreLoadLibrary, // called just before LoadLibrary, can
// override w/ new HMODULE return val
dliNotePreGetProcAddress, // called just before GetProcAddress, can
// override w/ new FARPROC return value
dliFailLoadLib, // failed to load library, fix it by
// returning a valid HMODULE
dliFailGetProc, // failed to get proc address, fix it by
// returning a valid FARPROC
dliNoteEndProcessing, // called after all processing is done, no
// no bypass possible at this point except
// by longjmp()/throw()/RaiseException.
};
typedef struct DelayLoadProc {
BOOL fImportByName;
union {
LPCSTR szProcName;
DWORD dwOrdinal;
};
} DelayLoadProc;
typedef struct DelayLoadInfo {
DWORD cb; // size of structure
PCImgDelayDescr pidd; // raw form of data (everything is there)
FARPROC * ppfn; // points to address of function to load
LPCSTR szDll; // name of dll
DelayLoadProc dlp; // name or ordinal of procedure
HMODULE hmodCur; // the hInstance of the library we have loaded
FARPROC pfnCur; // the actual function that will be called
DWORD dwLastError;// error received (if an error notification)
} DelayLoadInfo, * PDelayLoadInfo;
typedef FARPROC (WINAPI *PfnDliHook)(
unsigned dliNotify,
PDelayLoadInfo pdli
);
// utility function for calculating the index of the current import
// for all the tables (INT, BIAT, UIAT, and IAT).
__inline unsigned
IndexFromPImgThunkData(PCImgThunkData pitdCur, PCImgThunkData pitdBase) {
return (unsigned)(pitdCur - pitdBase);
}
// C++ template utility function for converting RVAs to pointers
//
#if defined(_WIN64) && defined(_M_IA64)
#pragma section(".base", long, read, write)
ExternC
__declspec(allocate(".base"))
extern
IMAGE_DOS_HEADER __ImageBase;
#else
ExternC
extern
IMAGE_DOS_HEADER __ImageBase;
#endif
#if defined(__cplusplus)
template <class X>
X * PFromRva(RVA rva, const X *) {
return (X*)(PBYTE(&__ImageBase) + rva);
}
#else
__inline
void *
WINAPI
PFromRva(RVA rva, void *unused) {
return (PVOID)(((PBYTE)&__ImageBase) + rva);
}
#endif
//
// Unload support
//
// routine definition; takes a pointer to a name to unload
//
#if DELAYLOAD_VERSION >= 0x0200
ExternC
BOOL WINAPI
__FUnloadDelayLoadedDLL2(LPCSTR szDll);
#else
ExternC
BOOL WINAPI
__FUnloadDelayLoadedDLL(LPCSTR szDll);
#endif
// structure definitions for the list of unload records
typedef struct UnloadInfo * PUnloadInfo;
typedef struct UnloadInfo {
PUnloadInfo puiNext;
PCImgDelayDescr pidd;
} UnloadInfo;
// the default delay load helper places the unloadinfo records in the list
// headed by the following pointer.
ExternC
extern
PUnloadInfo __puiHead;
//
// Exception information
//
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
// utility function for calculating the count of imports given the base
// of the IAT. NB: this only works on a valid IAT!
__inline unsigned
CountOfImports(PCImgThunkData pitdBase) {
unsigned cRet = 0;
PCImgThunkData pitd = pitdBase;
while (pitd->u1.Function) {
pitd++;
cRet++;
}
return cRet;
}
//
// Hook pointers
//
// The "notify hook" gets called for every call to the
// delay load helper. This allows a user to hook every call and
// skip the delay load helper entirely.
//
// dliNotify == {
// dliStartProcessing |
// dliPreLoadLibrary |
// dliPreGetProc |
// dliNoteEndProcessing}
// on this call.
//
ExternC
extern
PfnDliHook __pfnDliNotifyHook;
ExternC
extern
PfnDliHook __pfnDliNotifyHook2;
// This is the failure hook, dliNotify = {dliFailLoadLib|dliFailGetProc}
ExternC
extern
PfnDliHook __pfnDliFailureHook;
ExternC
extern
PfnDliHook __pfnDliFailureHook2;
#if DELAYLOAD_VERSION >= 0x0200
#define __pfnDliFailureHook __pfnDliFailureHook2
#define __pfnDliNotifyHook __pfnDliNotifyHook2
#endif
#endif