2 * PROJECT: ReactOS SDK Library
3 * LICENSE: LGPL, see LGPL.txt in top level directory.
4 * FILE: lib/sdk/delayimp/delayimp.c
5 * PURPOSE: Library for delay importing from dlls
6 * PROGRAMMERS: Timo Kreuzer <timo.kreuzer@reactos.org>
16 /**** Linker magic: provide a default (NULL) pointer, but allow the user to override it ****/
18 /* The actual items we use */
19 PfnDliHook __pfnDliNotifyHook2
;
20 PfnDliHook __pfnDliFailureHook2
;
22 #if !defined(__GNUC__)
23 /* The fallback symbols */
24 PfnDliHook __pfnDliNotifyHook2Default
= NULL
;
25 PfnDliHook __pfnDliFailureHook2Default
= NULL
;
27 /* Tell the linker to use the fallback symbols */
29 #pragma comment(linker, "/alternatename:___pfnDliNotifyHook2=___pfnDliNotifyHook2Default")
30 #pragma comment(linker, "/alternatename:___pfnDliFailureHook2=___pfnDliFailureHook2Default")
32 #pragma comment(linker, "/alternatename:__pfnDliNotifyHook2=__pfnDliNotifyHook2Default")
33 #pragma comment(linker, "/alternatename:__pfnDliFailureHook2=__pfnDliFailureHook2Default")
38 /**** Helper functions to convert from RVA to address ****/
42 IndexFromPImgThunkData(PCImgThunkData pData
, PCImgThunkData pBase
)
47 extern const IMAGE_DOS_HEADER __ImageBase
;
53 return (PVOID
)(((ULONG_PTR
)(rva
)) + ((ULONG_PTR
)&__ImageBase
));
57 /**** load helper ****/
60 __delayLoadHelper2(PCImgDelayDescr pidd
, PImgThunkData pIATEntry
)
62 DelayLoadInfo dli
= {0};
68 pIAT
= PFromRva(pidd
->rvaIAT
);
69 pINT
= PFromRva(pidd
->rvaINT
);
70 phMod
= PFromRva(pidd
->rvaHmod
);
71 index
= IndexFromPImgThunkData(pIATEntry
, pIAT
);
75 dli
.ppfn
= (FARPROC
*)&pIAT
[index
].u1
.Function
;
76 dli
.szDll
= PFromRva(pidd
->rvaDLLName
);
77 dli
.dlp
.fImportByName
= !IMAGE_SNAP_BY_ORDINAL(pINT
[index
].u1
.Ordinal
);
78 if (dli
.dlp
.fImportByName
)
80 /* u1.AdressOfData points to a IMAGE_IMPORT_BY_NAME struct */
81 PIMAGE_IMPORT_BY_NAME piibn
= PFromRva((RVA
)pINT
[index
].u1
.AddressOfData
);
82 dli
.dlp
.szProcName
= (LPCSTR
)&piibn
->Name
;
86 dli
.dlp
.dwOrdinal
= IMAGE_ORDINAL(pINT
[index
].u1
.Ordinal
);
89 if (__pfnDliNotifyHook2
)
91 dli
.pfnCur
= __pfnDliNotifyHook2(dliStartProcessing
, &dli
);
94 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
95 if (__pfnDliNotifyHook2
)
96 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);
102 dli
.hmodCur
= *phMod
;
104 if (dli
.hmodCur
== NULL
)
106 if (__pfnDliNotifyHook2
)
107 dli
.hmodCur
= (HMODULE
)__pfnDliNotifyHook2(dliNotePreLoadLibrary
, &dli
);
108 if (dli
.hmodCur
== NULL
)
110 dli
.hmodCur
= LoadLibraryA(dli
.szDll
);
111 if (dli
.hmodCur
== NULL
)
113 dli
.dwLastError
= GetLastError();
114 if (__pfnDliFailureHook2
)
115 dli
.hmodCur
= (HMODULE
)__pfnDliFailureHook2(dliFailLoadLib
, &dli
);
117 if (dli
.hmodCur
== NULL
)
119 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
120 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_MOD_NOT_FOUND
), 0, 1, args
);
122 /* If we survive the exception, we are expected to use pfnCur directly.. */
127 *phMod
= dli
.hmodCur
;
130 dli
.dwLastError
= ERROR_SUCCESS
;
132 if (__pfnDliNotifyHook2
)
133 dli
.pfnCur
= (FARPROC
)__pfnDliNotifyHook2(dliNotePreGetProcAddress
, &dli
);
134 if (dli
.pfnCur
== NULL
)
136 /* dli.dlp.szProcName might also contain the ordinal */
137 dli
.pfnCur
= GetProcAddress(dli
.hmodCur
, dli
.dlp
.szProcName
);
138 if (dli
.pfnCur
== NULL
)
140 dli
.dwLastError
= GetLastError();
141 if (__pfnDliFailureHook2
)
142 dli
.pfnCur
= __pfnDliFailureHook2(dliFailGetProc
, &dli
);
144 if (dli
.pfnCur
== NULL
)
146 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
147 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_PROC_NOT_FOUND
), 0, 1, args
);
154 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
155 dli
.dwLastError
= ERROR_SUCCESS
;
157 if (__pfnDliNotifyHook2
)
158 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);