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 <stdarg.h> 22 #include <string.h> 23 #include "windef.h" 24 #include "winbase.h" 25 #include "winnt.h" 26 #include "winternl.h" 27 #include "winerror.h" 28 #include "wine/debug.h" 29 #include "imagehlp.h" 30 31 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp); 32 33 /*********************************************************************** 34 * Data 35 */ 36 static LIST_ENTRY image_list = { &image_list, &image_list }; 37 38 39 /*********************************************************************** 40 * GetImageConfigInformation (IMAGEHLP.@) 41 */ 42 BOOL WINAPI GetImageConfigInformation( 43 PLOADED_IMAGE LoadedImage, 44 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) 45 { 46 FIXME("(%p, %p): stub\n", 47 LoadedImage, ImageConfigInformation 48 ); 49 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 50 return FALSE; 51 } 52 53 /*********************************************************************** 54 * GetImageUnusedHeaderBytes (IMAGEHLP.@) 55 */ 56 DWORD WINAPI GetImageUnusedHeaderBytes( 57 PLOADED_IMAGE LoadedImage, 58 LPDWORD SizeUnusedHeaderBytes) 59 { 60 FIXME("(%p, %p): stub\n", 61 LoadedImage, SizeUnusedHeaderBytes 62 ); 63 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 64 return 0; 65 } 66 67 /*********************************************************************** 68 * ImageLoad (IMAGEHLP.@) 69 */ 70 PLOADED_IMAGE WINAPI ImageLoad(PCSTR dll_name, PCSTR dll_path) 71 { 72 LOADED_IMAGE *image; 73 74 TRACE("(%s, %s)\n", dll_name, dll_path); 75 76 image = HeapAlloc(GetProcessHeap(), 0, sizeof(*image)); 77 if (!image) return NULL; 78 79 if (!MapAndLoad(dll_name, dll_path, image, TRUE, TRUE)) 80 { 81 HeapFree(GetProcessHeap(), 0, image); 82 return NULL; 83 } 84 85 image->Links.Flink = image_list.Flink; 86 image->Links.Blink = &image_list; 87 image_list.Flink->Blink = &image->Links; 88 image_list.Flink = &image->Links; 89 90 return image; 91 } 92 93 /*********************************************************************** 94 * ImageUnload (IMAGEHLP.@) 95 */ 96 BOOL WINAPI ImageUnload(PLOADED_IMAGE loaded_image) 97 { 98 LIST_ENTRY *entry, *mark; 99 PLOADED_IMAGE image; 100 101 TRACE("(%p)\n", loaded_image); 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(GetProcessHeap(), 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