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