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