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