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 ****/
19 PfnDliHook __pfnDliNotifyHook2
;
20 PfnDliHook __pfnDliFailureHook2
;
22 /* The actual items we use */
23 extern PfnDliHook __pfnDliNotifyHook2
;
24 extern PfnDliHook __pfnDliFailureHook2
;
26 /* The fallback symbols */
27 PfnDliHook __pfnDliNotifyHook2Default
= NULL
;
28 PfnDliHook __pfnDliFailureHook2Default
= NULL
;
30 /* Tell the linker to use the fallback symbols */
32 #pragma comment(linker, "/alternatename:___pfnDliNotifyHook2=___pfnDliNotifyHook2Default")
33 #pragma comment(linker, "/alternatename:___pfnDliFailureHook2=___pfnDliFailureHook2Default")
35 #pragma comment(linker, "/alternatename:__pfnDliNotifyHook2=__pfnDliNotifyHook2Default")
36 #pragma comment(linker, "/alternatename:__pfnDliFailureHook2=__pfnDliFailureHook2Default")
41 /**** Helper functions to convert from RVA to address ****/
45 IndexFromPImgThunkData(PCImgThunkData pData
, PCImgThunkData pBase
)
50 extern const IMAGE_DOS_HEADER __ImageBase
;
56 return (PVOID
)(((ULONG_PTR
)(rva
)) + ((ULONG_PTR
)&__ImageBase
));
60 /**** load helper ****/
63 __delayLoadHelper2(PCImgDelayDescr pidd
, PImgThunkData pIATEntry
)
65 DelayLoadInfo dli
= {0};
71 pIAT
= PFromRva(pidd
->rvaIAT
);
72 pINT
= PFromRva(pidd
->rvaINT
);
73 phMod
= PFromRva(pidd
->rvaHmod
);
74 index
= IndexFromPImgThunkData(pIATEntry
, pIAT
);
78 dli
.ppfn
= (FARPROC
*)&pIAT
[index
].u1
.Function
;
79 dli
.szDll
= PFromRva(pidd
->rvaDLLName
);
80 dli
.dlp
.fImportByName
= !IMAGE_SNAP_BY_ORDINAL(pINT
[index
].u1
.Ordinal
);
81 if (dli
.dlp
.fImportByName
)
83 /* u1.AdressOfData points to a IMAGE_IMPORT_BY_NAME struct */
84 PIMAGE_IMPORT_BY_NAME piibn
= PFromRva((RVA
)pINT
[index
].u1
.AddressOfData
);
85 dli
.dlp
.szProcName
= (LPCSTR
)&piibn
->Name
;
89 dli
.dlp
.dwOrdinal
= IMAGE_ORDINAL(pINT
[index
].u1
.Ordinal
);
92 if (__pfnDliNotifyHook2
)
94 dli
.pfnCur
= __pfnDliNotifyHook2(dliStartProcessing
, &dli
);
97 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
98 if (__pfnDliNotifyHook2
)
99 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);
105 dli
.hmodCur
= *phMod
;
107 if (dli
.hmodCur
== NULL
)
109 if (__pfnDliNotifyHook2
)
110 dli
.hmodCur
= (HMODULE
)__pfnDliNotifyHook2(dliNotePreLoadLibrary
, &dli
);
111 if (dli
.hmodCur
== NULL
)
113 dli
.hmodCur
= LoadLibraryA(dli
.szDll
);
114 if (dli
.hmodCur
== NULL
)
116 dli
.dwLastError
= GetLastError();
117 if (__pfnDliFailureHook2
)
118 dli
.hmodCur
= (HMODULE
)__pfnDliFailureHook2(dliFailLoadLib
, &dli
);
120 if (dli
.hmodCur
== NULL
)
122 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
123 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_MOD_NOT_FOUND
), 0, 1, args
);
125 /* If we survive the exception, we are expected to use pfnCur directly.. */
130 *phMod
= dli
.hmodCur
;
133 dli
.dwLastError
= ERROR_SUCCESS
;
135 if (__pfnDliNotifyHook2
)
136 dli
.pfnCur
= (FARPROC
)__pfnDliNotifyHook2(dliNotePreGetProcAddress
, &dli
);
137 if (dli
.pfnCur
== NULL
)
139 /* dli.dlp.szProcName might also contain the ordinal */
140 dli
.pfnCur
= GetProcAddress(dli
.hmodCur
, dli
.dlp
.szProcName
);
141 if (dli
.pfnCur
== NULL
)
143 dli
.dwLastError
= GetLastError();
144 if (__pfnDliFailureHook2
)
145 dli
.pfnCur
= __pfnDliFailureHook2(dliFailGetProc
, &dli
);
147 if (dli
.pfnCur
== NULL
)
149 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
150 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_PROC_NOT_FOUND
), 0, 1, args
);
157 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
158 dli
.dwLastError
= ERROR_SUCCESS
;
160 if (__pfnDliNotifyHook2
)
161 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);