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 */
32 #pragma comment(linker, "/alternatename:___pfnDliNotifyHook2=___pfnDliNotifyHook2Default")
33 #pragma comment(linker, "/alternatename:___pfnDliFailureHook2=___pfnDliFailureHook2Default")
34 #elif defined (_M_IA64) || defined (_M_AMD64)
35 #pragma comment(linker, "/alternatename:__pfnDliNotifyHook2=__pfnDliNotifyHook2Default")
36 #pragma comment(linker, "/alternatename:__pfnDliFailureHook2=__pfnDliFailureHook2Default")
38 #error Unsupported platform, please find the correct decoration for your arch!
43 /**** Helper functions to convert from RVA to address ****/
47 IndexFromPImgThunkData(PCImgThunkData pData
, PCImgThunkData pBase
)
52 extern const IMAGE_DOS_HEADER __ImageBase
;
58 return (PVOID
)(((ULONG_PTR
)(rva
)) + ((ULONG_PTR
)&__ImageBase
));
62 /**** load helper ****/
65 __delayLoadHelper2(PCImgDelayDescr pidd
, PImgThunkData pIATEntry
)
67 DelayLoadInfo dli
= {0};
73 pIAT
= PFromRva(pidd
->rvaIAT
);
74 pINT
= PFromRva(pidd
->rvaINT
);
75 phMod
= PFromRva(pidd
->rvaHmod
);
76 index
= IndexFromPImgThunkData(pIATEntry
, pIAT
);
80 dli
.ppfn
= (FARPROC
*)&pIAT
[index
].u1
.Function
;
81 dli
.szDll
= PFromRva(pidd
->rvaDLLName
);
82 dli
.dlp
.fImportByName
= !IMAGE_SNAP_BY_ORDINAL(pINT
[index
].u1
.Ordinal
);
83 if (dli
.dlp
.fImportByName
)
85 /* u1.AdressOfData points to a IMAGE_IMPORT_BY_NAME struct */
86 PIMAGE_IMPORT_BY_NAME piibn
= PFromRva((RVA
)pINT
[index
].u1
.AddressOfData
);
87 dli
.dlp
.szProcName
= (LPCSTR
)&piibn
->Name
;
91 dli
.dlp
.dwOrdinal
= IMAGE_ORDINAL(pINT
[index
].u1
.Ordinal
);
94 if (__pfnDliNotifyHook2
)
96 dli
.pfnCur
= __pfnDliNotifyHook2(dliStartProcessing
, &dli
);
99 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
100 if (__pfnDliNotifyHook2
)
101 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);
107 dli
.hmodCur
= *phMod
;
109 if (dli
.hmodCur
== NULL
)
111 if (__pfnDliNotifyHook2
)
112 dli
.hmodCur
= (HMODULE
)__pfnDliNotifyHook2(dliNotePreLoadLibrary
, &dli
);
113 if (dli
.hmodCur
== NULL
)
115 dli
.hmodCur
= LoadLibraryA(dli
.szDll
);
116 if (dli
.hmodCur
== NULL
)
118 dli
.dwLastError
= GetLastError();
119 if (__pfnDliFailureHook2
)
120 dli
.hmodCur
= (HMODULE
)__pfnDliFailureHook2(dliFailLoadLib
, &dli
);
122 if (dli
.hmodCur
== NULL
)
124 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
125 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_MOD_NOT_FOUND
), 0, 1, args
);
127 /* If we survive the exception, we are expected to use pfnCur directly.. */
132 *phMod
= dli
.hmodCur
;
135 dli
.dwLastError
= ERROR_SUCCESS
;
137 if (__pfnDliNotifyHook2
)
138 dli
.pfnCur
= (FARPROC
)__pfnDliNotifyHook2(dliNotePreGetProcAddress
, &dli
);
139 if (dli
.pfnCur
== NULL
)
141 /* dli.dlp.szProcName might also contain the ordinal */
142 dli
.pfnCur
= GetProcAddress(dli
.hmodCur
, dli
.dlp
.szProcName
);
143 if (dli
.pfnCur
== NULL
)
145 dli
.dwLastError
= GetLastError();
146 if (__pfnDliFailureHook2
)
147 dli
.pfnCur
= __pfnDliFailureHook2(dliFailGetProc
, &dli
);
149 if (dli
.pfnCur
== NULL
)
151 ULONG_PTR args
[] = { (ULONG_PTR
)&dli
};
152 RaiseException(VcppException(ERROR_SEVERITY_ERROR
, ERROR_PROC_NOT_FOUND
), 0, 1, args
);
159 pIAT
[index
].u1
.Function
= (DWORD_PTR
)dli
.pfnCur
;
160 dli
.dwLastError
= ERROR_SUCCESS
;
162 if (__pfnDliNotifyHook2
)
163 __pfnDliNotifyHook2(dliNoteEndProcessing
, &dli
);