1 /* 2 * IMAGEHLP library 3 * 4 * Copyright 1998 Patrik Stridvall 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "precomp.h" 22 23 #include <winternl.h> 24 25 /*********************************************************************** 26 * Data 27 */ 28 LIST_ENTRY image_list = { &image_list, &image_list }; 29 30 DECLSPEC_HIDDEN extern HANDLE IMAGEHLP_hHeap; 31 32 /*********************************************************************** 33 * GetImageConfigInformation (IMAGEHLP.@) 34 */ 35 BOOL WINAPI GetImageConfigInformation( 36 PLOADED_IMAGE LoadedImage, 37 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) 38 { 39 FIXME("(%p, %p): stub\n", 40 LoadedImage, ImageConfigInformation 41 ); 42 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 43 return FALSE; 44 } 45 46 /*********************************************************************** 47 * GetImageUnusedHeaderBytes (IMAGEHLP.@) 48 */ 49 DWORD WINAPI GetImageUnusedHeaderBytes( 50 PLOADED_IMAGE LoadedImage, 51 LPDWORD SizeUnusedHeaderBytes) 52 { 53 FIXME("(%p, %p): stub\n", 54 LoadedImage, SizeUnusedHeaderBytes 55 ); 56 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 57 return 0; 58 } 59 60 /*********************************************************************** 61 * ImageLoad (IMAGEHLP.@) 62 */ 63 PLOADED_IMAGE WINAPI ImageLoad(PCSTR dll_name, PCSTR dll_path) 64 { 65 LOADED_IMAGE *image; 66 67 TRACE("(%s, %s)\n", dll_name, dll_path); 68 69 image = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*image)); 70 if (!image) return NULL; 71 72 if (!MapAndLoad(dll_name, dll_path, image, TRUE, TRUE)) 73 { 74 HeapFree(IMAGEHLP_hHeap, 0, image); 75 return NULL; 76 } 77 78 image->Links.Flink = image_list.Flink; 79 image->Links.Blink = &image_list; 80 image_list.Flink->Blink = &image->Links; 81 image_list.Flink = &image->Links; 82 83 return image; 84 } 85 86 /*********************************************************************** 87 * ImageUnload (IMAGEHLP.@) 88 */ 89 BOOL WINAPI ImageUnload(PLOADED_IMAGE loaded_image) 90 { 91 LIST_ENTRY *entry, *mark; 92 PLOADED_IMAGE image; 93 94 FIXME("(%p)\n", loaded_image); 95 96 if (!loaded_image) 97 { 98 /* No image loaded or null pointer */ 99 SetLastError(ERROR_INVALID_PARAMETER); 100 return FALSE; 101 } 102 103 /* FIXME: do we really need to check this? */ 104 mark = &image_list; 105 for (entry = mark->Flink; entry != mark; entry = entry->Flink) 106 { 107 image = CONTAINING_RECORD(entry, LOADED_IMAGE, Links); 108 if (image == loaded_image) 109 break; 110 } 111 112 if (entry == mark) 113 { 114 /* Not found */ 115 SetLastError(ERROR_INVALID_PARAMETER); 116 return FALSE; 117 } 118 119 entry->Blink->Flink = entry->Flink; 120 entry->Flink->Blink = entry->Blink; 121 122 UnMapAndLoad(loaded_image); 123 HeapFree(IMAGEHLP_hHeap, 0, loaded_image); 124 125 return TRUE; 126 } 127 128 /*********************************************************************** 129 * MapAndLoad (IMAGEHLP.@) 130 */ 131 BOOL WINAPI MapAndLoad(PCSTR pszImageName, PCSTR pszDllPath, PLOADED_IMAGE pLoadedImage, 132 BOOL bDotDll, BOOL bReadOnly) 133 { 134 CHAR szFileName[MAX_PATH]; 135 HANDLE hFile = INVALID_HANDLE_VALUE; 136 HANDLE hFileMapping = NULL; 137 PVOID mapping = NULL; 138 PIMAGE_NT_HEADERS pNtHeader = NULL; 139 140 TRACE("(%s, %s, %p, %d, %d)\n", 141 pszImageName, pszDllPath, pLoadedImage, bDotDll, bReadOnly); 142 143 if (!SearchPathA(pszDllPath, pszImageName, bDotDll ? ".DLL" : ".EXE", 144 sizeof(szFileName), szFileName, NULL)) 145 { 146 SetLastError(ERROR_FILE_NOT_FOUND); 147 goto Error; 148 } 149 150 hFile = CreateFileA(szFileName, 151 GENERIC_READ | (bReadOnly ? 0 : GENERIC_WRITE), 152 FILE_SHARE_READ, 153 NULL, OPEN_EXISTING, 0, NULL); 154 if (hFile == INVALID_HANDLE_VALUE) 155 { 156 WARN("CreateFile: Error = %d\n", GetLastError()); 157 goto Error; 158 } 159 160 hFileMapping = CreateFileMappingA(hFile, NULL, 161 (bReadOnly ? PAGE_READONLY : PAGE_READWRITE) | SEC_COMMIT, 162 0, 0, NULL); 163 if (!hFileMapping) 164 { 165 WARN("CreateFileMapping: Error = %d\n", GetLastError()); 166 goto Error; 167 } 168 169 mapping = MapViewOfFile(hFileMapping, bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0); 170 CloseHandle(hFileMapping); 171 if (!mapping) 172 { 173 WARN("MapViewOfFile: Error = %d\n", GetLastError()); 174 goto Error; 175 } 176 177 if (!(pNtHeader = RtlImageNtHeader(mapping))) 178 { 179 WARN("Not an NT header\n"); 180 UnmapViewOfFile(mapping); 181 goto Error; 182 } 183 184 pLoadedImage->ModuleName = HeapAlloc(GetProcessHeap(), 0, 185 strlen(szFileName) + 1); 186 if (pLoadedImage->ModuleName) strcpy(pLoadedImage->ModuleName, szFileName); 187 pLoadedImage->hFile = hFile; 188 pLoadedImage->MappedAddress = mapping; 189 pLoadedImage->FileHeader = pNtHeader; 190 pLoadedImage->Sections = (PIMAGE_SECTION_HEADER) 191 ((LPBYTE) &pNtHeader->OptionalHeader + 192 pNtHeader->FileHeader.SizeOfOptionalHeader); 193 pLoadedImage->NumberOfSections = pNtHeader->FileHeader.NumberOfSections; 194 pLoadedImage->SizeOfImage = GetFileSize(hFile, NULL); 195 pLoadedImage->Characteristics = pNtHeader->FileHeader.Characteristics; 196 pLoadedImage->LastRvaSection = pLoadedImage->Sections; 197 198 pLoadedImage->fSystemImage = FALSE; /* FIXME */ 199 pLoadedImage->fDOSImage = FALSE; /* FIXME */ 200 201 pLoadedImage->Links.Flink = &pLoadedImage->Links; 202 pLoadedImage->Links.Blink = &pLoadedImage->Links; 203 204 return TRUE; 205 206 Error: 207 if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); 208 return FALSE; 209 } 210 211 /*********************************************************************** 212 * SetImageConfigInformation (IMAGEHLP.@) 213 */ 214 BOOL WINAPI SetImageConfigInformation( 215 PLOADED_IMAGE LoadedImage, 216 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) 217 { 218 FIXME("(%p, %p): stub\n", 219 LoadedImage, ImageConfigInformation 220 ); 221 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 222 return FALSE; 223 } 224 225 /*********************************************************************** 226 * UnMapAndLoad (IMAGEHLP.@) 227 */ 228 BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE pLoadedImage) 229 { 230 HeapFree(GetProcessHeap(), 0, pLoadedImage->ModuleName); 231 /* FIXME: MSDN states that a new checksum is computed and stored into the file */ 232 if (pLoadedImage->MappedAddress) UnmapViewOfFile(pLoadedImage->MappedAddress); 233 if (pLoadedImage->hFile != INVALID_HANDLE_VALUE) CloseHandle(pLoadedImage->hFile); 234 return TRUE; 235 } 236