1 /* 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> 7 * Mark Jansen 8 * 9 */ 10 11 #include <stdarg.h> 12 #include <windef.h> 13 #include <winbase.h> 14 #include <delayimp.h> 15 16 /**** Linker magic: provide a default (NULL) pointer, but allow the user to override it ****/ 17 18 #if defined(__GNUC__) 19 PfnDliHook __pfnDliNotifyHook2; 20 PfnDliHook __pfnDliFailureHook2; 21 #else 22 /* The actual items we use */ 23 extern PfnDliHook __pfnDliNotifyHook2; 24 extern PfnDliHook __pfnDliFailureHook2; 25 26 /* The fallback symbols */ 27 extern PfnDliHook __pfnDliNotifyHook2Default = NULL; 28 extern PfnDliHook __pfnDliFailureHook2Default = NULL; 29 30 /* Tell the linker to use the fallback symbols */ 31 #if defined (_M_IX86) 32 #pragma comment(linker, "/alternatename:___pfnDliNotifyHook2=___pfnDliNotifyHook2Default") 33 #pragma comment(linker, "/alternatename:___pfnDliFailureHook2=___pfnDliFailureHook2Default") 34 #else 35 #pragma comment(linker, "/alternatename:__pfnDliNotifyHook2=__pfnDliNotifyHook2Default") 36 #pragma comment(linker, "/alternatename:__pfnDliFailureHook2=__pfnDliFailureHook2Default") 37 #endif 38 #endif 39 40 41 /**** Helper functions to convert from RVA to address ****/ 42 43 FORCEINLINE 44 unsigned 45 IndexFromPImgThunkData(PCImgThunkData pData, PCImgThunkData pBase) 46 { 47 return pData - pBase; 48 } 49 50 extern const IMAGE_DOS_HEADER __ImageBase; 51 52 FORCEINLINE 53 PVOID 54 PFromRva(RVA rva) 55 { 56 return (PVOID)(((ULONG_PTR)(rva)) + ((ULONG_PTR)&__ImageBase)); 57 } 58 59 60 /**** load helper ****/ 61 62 FARPROC WINAPI 63 __delayLoadHelper2(PCImgDelayDescr pidd, PImgThunkData pIATEntry) 64 { 65 DelayLoadInfo dli = {0}; 66 int index; 67 PImgThunkData pIAT; 68 PImgThunkData pINT; 69 HMODULE *phMod; 70 71 pIAT = PFromRva(pidd->rvaIAT); 72 pINT = PFromRva(pidd->rvaINT); 73 phMod = PFromRva(pidd->rvaHmod); 74 index = IndexFromPImgThunkData(pIATEntry, pIAT); 75 76 dli.cb = sizeof(dli); 77 dli.pidd = pidd; 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) 82 { 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; 86 } 87 else 88 { 89 dli.dlp.dwOrdinal = IMAGE_ORDINAL(pINT[index].u1.Ordinal); 90 } 91 92 if (__pfnDliNotifyHook2) 93 { 94 dli.pfnCur = __pfnDliNotifyHook2(dliStartProcessing, &dli); 95 if (dli.pfnCur) 96 { 97 pIAT[index].u1.Function = (DWORD_PTR)dli.pfnCur; 98 if (__pfnDliNotifyHook2) 99 __pfnDliNotifyHook2(dliNoteEndProcessing, &dli); 100 101 return dli.pfnCur; 102 } 103 } 104 105 dli.hmodCur = *phMod; 106 107 if (dli.hmodCur == NULL) 108 { 109 if (__pfnDliNotifyHook2) 110 dli.hmodCur = (HMODULE)__pfnDliNotifyHook2(dliNotePreLoadLibrary, &dli); 111 if (dli.hmodCur == NULL) 112 { 113 dli.hmodCur = LoadLibraryA(dli.szDll); 114 if (dli.hmodCur == NULL) 115 { 116 dli.dwLastError = GetLastError(); 117 if (__pfnDliFailureHook2) 118 dli.hmodCur = (HMODULE)__pfnDliFailureHook2(dliFailLoadLib, &dli); 119 120 if (dli.hmodCur == NULL) 121 { 122 ULONG_PTR args[] = { (ULONG_PTR)&dli }; 123 RaiseException(VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND), 0, 1, args); 124 125 /* If we survive the exception, we are expected to use pfnCur directly.. */ 126 return dli.pfnCur; 127 } 128 } 129 } 130 *phMod = dli.hmodCur; 131 } 132 133 dli.dwLastError = ERROR_SUCCESS; 134 135 if (__pfnDliNotifyHook2) 136 dli.pfnCur = (FARPROC)__pfnDliNotifyHook2(dliNotePreGetProcAddress, &dli); 137 if (dli.pfnCur == NULL) 138 { 139 /* dli.dlp.szProcName might also contain the ordinal */ 140 dli.pfnCur = GetProcAddress(dli.hmodCur, dli.dlp.szProcName); 141 if (dli.pfnCur == NULL) 142 { 143 dli.dwLastError = GetLastError(); 144 if (__pfnDliFailureHook2) 145 dli.pfnCur = __pfnDliFailureHook2(dliFailGetProc, &dli); 146 147 if (dli.pfnCur == NULL) 148 { 149 ULONG_PTR args[] = { (ULONG_PTR)&dli }; 150 RaiseException(VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND), 0, 1, args); 151 } 152 153 //return NULL; 154 } 155 } 156 157 pIAT[index].u1.Function = (DWORD_PTR)dli.pfnCur; 158 dli.dwLastError = ERROR_SUCCESS; 159 160 if (__pfnDliNotifyHook2) 161 __pfnDliNotifyHook2(dliNoteEndProcessing, &dli); 162 163 return dli.pfnCur; 164 } 165 166