| /* | |
| * IMAGEHLP library | |
| * | |
| * Copyright 1998 Patrik Stridvall | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #include <stdarg.h> | |
| #include <string.h> | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "winnt.h" | |
| #include "winternl.h" | |
| #include "winerror.h" | |
| #include "wine/debug.h" | |
| #include "imagehlp.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(imagehlp); | |
| /*********************************************************************** | |
| * Data | |
| */ | |
| static PLOADED_IMAGE IMAGEHLP_pFirstLoadedImage=NULL; | |
| static PLOADED_IMAGE IMAGEHLP_pLastLoadedImage=NULL; | |
| static LOADED_IMAGE IMAGEHLP_EmptyLoadedImage = { | |
| NULL, /* ModuleName */ | |
| 0, /* hFile */ | |
| NULL, /* MappedAddress */ | |
| NULL, /* FileHeader */ | |
| NULL, /* LastRvaSection */ | |
| 0, /* NumberOfSections */ | |
| NULL, /* Sections */ | |
| 1, /* Characteristics */ | |
| FALSE, /* fSystemImage */ | |
| FALSE, /* fDOSImage */ | |
| FALSE, /* fReadOnly */ | |
| 0, /* Version */ | |
| { &IMAGEHLP_EmptyLoadedImage.Links, &IMAGEHLP_EmptyLoadedImage.Links }, /* Links */ | |
| 148, /* SizeOfImage; */ | |
| }; | |
| extern HANDLE IMAGEHLP_hHeap; | |
| /*********************************************************************** | |
| * GetImageConfigInformation (IMAGEHLP.@) | |
| */ | |
| BOOL WINAPI GetImageConfigInformation( | |
| PLOADED_IMAGE LoadedImage, | |
| PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) | |
| { | |
| FIXME("(%p, %p): stub\n", | |
| LoadedImage, ImageConfigInformation | |
| ); | |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * GetImageUnusedHeaderBytes (IMAGEHLP.@) | |
| */ | |
| DWORD WINAPI GetImageUnusedHeaderBytes( | |
| PLOADED_IMAGE LoadedImage, | |
| LPDWORD SizeUnusedHeaderBytes) | |
| { | |
| FIXME("(%p, %p): stub\n", | |
| LoadedImage, SizeUnusedHeaderBytes | |
| ); | |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
| return 0; | |
| } | |
| /*********************************************************************** | |
| * ImageLoad (IMAGEHLP.@) | |
| */ | |
| PLOADED_IMAGE WINAPI ImageLoad(PCSTR DllName, PCSTR DllPath) | |
| { | |
| PLOADED_IMAGE pLoadedImage; | |
| FIXME("(%s, %s): stub\n", DllName, DllPath); | |
| pLoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE)); | |
| if (pLoadedImage) | |
| pLoadedImage->FileHeader = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(IMAGE_NT_HEADERS)); | |
| return pLoadedImage; | |
| } | |
| /*********************************************************************** | |
| * ImageUnload (IMAGEHLP.@) | |
| */ | |
| BOOL WINAPI ImageUnload(PLOADED_IMAGE pLoadedImage) | |
| { | |
| LIST_ENTRY *pCurrent, *pFind; | |
| TRACE("(%p)\n", pLoadedImage); | |
| if(!IMAGEHLP_pFirstLoadedImage || !pLoadedImage) | |
| { | |
| /* No image loaded or null pointer */ | |
| SetLastError(ERROR_INVALID_PARAMETER); | |
| return FALSE; | |
| } | |
| pFind=&pLoadedImage->Links; | |
| pCurrent=&IMAGEHLP_pFirstLoadedImage->Links; | |
| while((pCurrent != pFind) && | |
| (pCurrent != NULL)) | |
| pCurrent = pCurrent->Flink; | |
| if(!pCurrent) | |
| { | |
| /* Not found */ | |
| SetLastError(ERROR_INVALID_PARAMETER); | |
| return FALSE; | |
| } | |
| if(pCurrent->Blink) | |
| pCurrent->Blink->Flink = pCurrent->Flink; | |
| else | |
| IMAGEHLP_pFirstLoadedImage = pCurrent->Flink?CONTAINING_RECORD( | |
| pCurrent->Flink, LOADED_IMAGE, Links):NULL; | |
| if(pCurrent->Flink) | |
| pCurrent->Flink->Blink = pCurrent->Blink; | |
| else | |
| IMAGEHLP_pLastLoadedImage = pCurrent->Blink?CONTAINING_RECORD( | |
| pCurrent->Blink, LOADED_IMAGE, Links):NULL; | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * MapAndLoad (IMAGEHLP.@) | |
| */ | |
| BOOL WINAPI MapAndLoad(PCSTR pszImageName, PCSTR pszDllPath, PLOADED_IMAGE pLoadedImage, | |
| BOOL bDotDll, BOOL bReadOnly) | |
| { | |
| CHAR szFileName[MAX_PATH]; | |
| HANDLE hFile = INVALID_HANDLE_VALUE; | |
| HANDLE hFileMapping = NULL; | |
| PVOID mapping = NULL; | |
| PIMAGE_NT_HEADERS pNtHeader = NULL; | |
| TRACE("(%s, %s, %p, %d, %d)\n", | |
| pszImageName, pszDllPath, pLoadedImage, bDotDll, bReadOnly); | |
| if (!SearchPathA(pszDllPath, pszImageName, bDotDll ? ".DLL" : ".EXE", | |
| sizeof(szFileName), szFileName, NULL)) | |
| { | |
| SetLastError(ERROR_FILE_NOT_FOUND); | |
| goto Error; | |
| } | |
| hFile = CreateFileA(szFileName, | |
| GENERIC_READ | (bReadOnly ? 0 : GENERIC_WRITE), | |
| FILE_SHARE_READ, | |
| NULL, OPEN_EXISTING, 0, NULL); | |
| if (hFile == INVALID_HANDLE_VALUE) | |
| { | |
| WARN("CreateFile: Error = %d\n", GetLastError()); | |
| goto Error; | |
| } | |
| hFileMapping = CreateFileMappingA(hFile, NULL, | |
| (bReadOnly ? PAGE_READONLY : PAGE_READWRITE) | SEC_COMMIT, | |
| 0, 0, NULL); | |
| if (!hFileMapping) | |
| { | |
| WARN("CreateFileMapping: Error = %d\n", GetLastError()); | |
| goto Error; | |
| } | |
| mapping = MapViewOfFile(hFileMapping, bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0); | |
| CloseHandle(hFileMapping); | |
| if (!mapping) | |
| { | |
| WARN("MapViewOfFile: Error = %d\n", GetLastError()); | |
| goto Error; | |
| } | |
| if (!(pNtHeader = RtlImageNtHeader(mapping))) | |
| { | |
| WARN("Not an NT header\n"); | |
| UnmapViewOfFile(mapping); | |
| goto Error; | |
| } | |
| pLoadedImage->ModuleName = HeapAlloc(GetProcessHeap(), 0, | |
| strlen(szFileName) + 1); | |
| if (pLoadedImage->ModuleName) strcpy(pLoadedImage->ModuleName, szFileName); | |
| pLoadedImage->hFile = hFile; | |
| pLoadedImage->MappedAddress = mapping; | |
| pLoadedImage->FileHeader = pNtHeader; | |
| pLoadedImage->Sections = (PIMAGE_SECTION_HEADER) | |
| ((LPBYTE) &pNtHeader->OptionalHeader + | |
| pNtHeader->FileHeader.SizeOfOptionalHeader); | |
| pLoadedImage->NumberOfSections = pNtHeader->FileHeader.NumberOfSections; | |
| pLoadedImage->SizeOfImage = GetFileSize(hFile, NULL); | |
| pLoadedImage->Characteristics = pNtHeader->FileHeader.Characteristics; | |
| pLoadedImage->LastRvaSection = pLoadedImage->Sections; | |
| pLoadedImage->fSystemImage = FALSE; /* FIXME */ | |
| pLoadedImage->fDOSImage = FALSE; /* FIXME */ | |
| pLoadedImage->Links.Flink = &pLoadedImage->Links; | |
| pLoadedImage->Links.Blink = &pLoadedImage->Links; | |
| return TRUE; | |
| Error: | |
| if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * SetImageConfigInformation (IMAGEHLP.@) | |
| */ | |
| BOOL WINAPI SetImageConfigInformation( | |
| PLOADED_IMAGE LoadedImage, | |
| PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) | |
| { | |
| FIXME("(%p, %p): stub\n", | |
| LoadedImage, ImageConfigInformation | |
| ); | |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * UnMapAndLoad (IMAGEHLP.@) | |
| */ | |
| BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE pLoadedImage) | |
| { | |
| HeapFree(GetProcessHeap(), 0, pLoadedImage->ModuleName); | |
| /* FIXME: MSDN states that a new checksum is computed and stored into the file */ | |
| if (pLoadedImage->MappedAddress) UnmapViewOfFile(pLoadedImage->MappedAddress); | |
| if (pLoadedImage->hFile != INVALID_HANDLE_VALUE) CloseHandle(pLoadedImage->hFile); | |
| return TRUE; | |
| } |