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 extern PfnDliHook __pfnDliNotifyHook2Default
= NULL
;
28 extern PfnDliHook __pfnDliFailureHook2Default
= NULL
;
30 /* Tell the linker to use the fallback symbols */
31 #pragma comment(linker, "/alternatename:___pfnDliNotifyHook2=___pfnDliNotifyHook2Default")
32 #pragma comment(linker, "/alternatename:___pfnDliFailureHook2=___pfnDliFailureHook2Default")
36 /**** Helper functions to convert from RVA to address ****/
40 IndexFromPImgThunkData(PCImgThunkData pData
, PCImgThunkData pBase
)
45 extern const IMAGE_DOS_HEADER __ImageBase
;
51 return (PVOID
)(((ULONG_PTR
)(rva
)) + ((ULONG_PTR
)&__ImageBase
));
55 /**** load helper ****/
58 __delayLoadHelper2(PCImgDelayDescr pidd
, PImgThunkData pIATEntry
)
60 DelayLoadInfo dli
= {0};
66 pIAT
= PFromRva(pidd
->rvaIAT
);
67 pINT
= PFromRva(pidd
->rvaINT
);
68 phMod
= PFromRva(pidd
->rvaHmod
);
69 index
= IndexFromPImgThunkData(pIATEntry
, pIAT
);
73 dli
.ppfn
= (FARPROC
*)&pIAT
[index
].u1
.Function
;
74 dli
.szDll
= PFromRva(pidd
->rvaDLLName
);
75 dli
.dlp
.fImportByName
= !IMAGE_SNAP_BY_ORDINAL(pINT
[index
].u1
.Ordinal
);
76 if (dli
.dlp
.fImportByName
)
78 /* u1.AdressOfData points to a IMAGE_IMPORT_BY_NAME struct */
79 PIMAGE_IMPORT_BY_NAME piibn
= PFromRva((RVA
)pINT
[index
].u1
.AddressOfData
);
80 dli
.dlp
.szProcName
= (LPCSTR
)&piibn
->Name
;
84 dli
.dlp
.dwOrdinal
= IMAGE_ORDINAL(pINT
[index
].u1
.Ordinal
);
87 if (__pfnDliNotifyHook2
)
89 dli
.pfnCur
= __pfnDliNotifyHook2(dliStartProcessing
, &dli
);
92 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
93 if (__pfnDliNotifyHook2
)
94 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);
100 dli
.hmodCur
= *phMod
;
102 if (dli
.hmodCur
== NULL
)
104 if (__pfnDliNotifyHook2
)
105 dli
.hmodCur
= (HMODULE
)__pfnDliNotifyHook2(dliNotePreLoadLibrary
, &dli
);
106 if (dli
.hmodCur
== NULL
)
108 dli
.hmodCur
= LoadLibraryA(dli
.szDll
);
109 if (dli
.hmodCur
== NULL
)
111 dli
.dwLastError
= GetLastError();
112 if (__pfnDliFailureHook2
)
113 dli
.hmodCur
= (HMODULE
)__pfnDliFailureHook2(dliFailLoadLib
, &dli
);
115 if (dli
.hmodCur
== NULL
)
117 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
118 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_MOD_NOT_FOUND
), 0, 1, args
);
120 /* If we survive the exception, we are expected to use pfnCur directly.. */
125 *phMod
= dli
.hmodCur
;
128 dli
.dwLastError
= ERROR_SUCCESS
;
130 if (__pfnDliNotifyHook2
)
131 dli
.pfnCur
= (FARPROC
)__pfnDliNotifyHook2(dliNotePreGetProcAddress
, &dli
);
132 if (dli
.pfnCur
== NULL
)
134 /* dli.dlp.szProcName might also contain the ordinal */
135 dli
.pfnCur
= GetProcAddress(dli
.hmodCur
, dli
.dlp
.szProcName
);
136 if (dli
.pfnCur
== NULL
)
138 dli
.dwLastError
= GetLastError();
139 if (__pfnDliFailureHook2
)
140 dli
.pfnCur
= __pfnDliFailureHook2(dliFailGetProc
, &dli
);
142 if (dli
.pfnCur
== NULL
)
144 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
145 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_PROC_NOT_FOUND
), 0, 1, args
);
152 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
153 dli
.dwLastError
= ERROR_SUCCESS
;
155 if (__pfnDliNotifyHook2
)
156 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);