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