| /* |
| * 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; */ |
| }; |
| |
| DECLSPEC_HIDDEN 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; |
| } |