| /* |
| * 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 "windef.h" |
| #include "winbase.h" |
| #include "winternl.h" |
| #include "winerror.h" |
| #include "wine/debug.h" |
| #include "imagehlp.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(imagehlp); |
| |
| static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount); |
| |
| |
| /*********************************************************************** |
| * BindImage (IMAGEHLP.@) |
| */ |
| BOOL WINAPI BindImage( |
| PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath) |
| { |
| return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL); |
| } |
| |
| /*********************************************************************** |
| * BindImageEx (IMAGEHLP.@) |
| */ |
| BOOL WINAPI BindImageEx( |
| DWORD Flags, PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath, |
| PIMAGEHLP_STATUS_ROUTINE StatusRoutine) |
| { |
| FIXME("(%d, %s, %s, %s, %p): stub\n", |
| Flags, debugstr_a(ImageName), debugstr_a(DllPath), |
| debugstr_a(SymbolPath), StatusRoutine |
| ); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * CheckSum (internal) |
| */ |
| static WORD CalcCheckSum( |
| DWORD StartValue, LPVOID BaseAddress, DWORD WordCount) |
| { |
| LPWORD Ptr; |
| DWORD Sum; |
| DWORD i; |
| |
| Sum = StartValue; |
| Ptr = (LPWORD)BaseAddress; |
| for (i = 0; i < WordCount; i++) |
| { |
| Sum += *Ptr; |
| if (HIWORD(Sum) != 0) |
| { |
| Sum = LOWORD(Sum) + HIWORD(Sum); |
| } |
| Ptr++; |
| } |
| |
| return (WORD)(LOWORD(Sum) + HIWORD(Sum)); |
| } |
| |
| |
| /*********************************************************************** |
| * CheckSumMappedFile (IMAGEHLP.@) |
| */ |
| PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile( |
| LPVOID BaseAddress, DWORD FileLength, |
| LPDWORD HeaderSum, LPDWORD CheckSum) |
| { |
| IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *) BaseAddress; |
| PIMAGE_NT_HEADERS32 Header32; |
| PIMAGE_NT_HEADERS64 Header64; |
| DWORD *ChecksumFile; |
| DWORD CalcSum; |
| DWORD HdrSum; |
| |
| TRACE("(%p, %d, %p, %p)\n", |
| BaseAddress, FileLength, HeaderSum, CheckSum |
| ); |
| |
| CalcSum = (DWORD)CalcCheckSum(0, |
| BaseAddress, |
| (FileLength + 1) / sizeof(WORD)); |
| |
| if (dos->e_magic != IMAGE_DOS_SIGNATURE) |
| return NULL; |
| |
| Header32 = (IMAGE_NT_HEADERS32 *)((char *)dos + dos->e_lfanew); |
| |
| if (Header32->Signature != IMAGE_NT_SIGNATURE) |
| return NULL; |
| |
| if (Header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) |
| ChecksumFile = &Header32->OptionalHeader.CheckSum; |
| else if (Header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) |
| { |
| Header64 = (IMAGE_NT_HEADERS64 *)Header32; |
| ChecksumFile = &Header64->OptionalHeader.CheckSum; |
| } |
| else |
| return NULL; |
| |
| HdrSum = *ChecksumFile; |
| |
| /* Subtract image checksum from calculated checksum. */ |
| /* fix low word of checksum */ |
| if (LOWORD(CalcSum) >= LOWORD(HdrSum)) |
| { |
| CalcSum -= LOWORD(HdrSum); |
| } |
| else |
| { |
| CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1; |
| } |
| |
| /* fix high word of checksum */ |
| if (LOWORD(CalcSum) >= HIWORD(HdrSum)) |
| { |
| CalcSum -= HIWORD(HdrSum); |
| } |
| else |
| { |
| CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1; |
| } |
| |
| /* add file length */ |
| CalcSum += FileLength; |
| |
| *CheckSum = CalcSum; |
| *HeaderSum = *ChecksumFile; |
| |
| return (PIMAGE_NT_HEADERS) Header32; |
| } |
| |
| /*********************************************************************** |
| * MapFileAndCheckSumA (IMAGEHLP.@) |
| */ |
| DWORD WINAPI MapFileAndCheckSumA( |
| PCSTR Filename, PDWORD HeaderSum, PDWORD CheckSum) |
| { |
| HANDLE hFile; |
| HANDLE hMapping; |
| LPVOID BaseAddress; |
| DWORD FileLength; |
| |
| TRACE("(%s, %p, %p): stub\n", |
| debugstr_a(Filename), HeaderSum, CheckSum |
| ); |
| |
| hFile = CreateFileA(Filename, |
| GENERIC_READ, |
| FILE_SHARE_READ | FILE_SHARE_WRITE, |
| NULL, |
| OPEN_EXISTING, |
| FILE_ATTRIBUTE_NORMAL, |
| 0); |
| if (hFile == INVALID_HANDLE_VALUE) |
| { |
| return CHECKSUM_OPEN_FAILURE; |
| } |
| |
| hMapping = CreateFileMappingW(hFile, |
| NULL, |
| PAGE_READONLY, |
| 0, |
| 0, |
| NULL); |
| if (hMapping == 0) |
| { |
| CloseHandle(hFile); |
| return CHECKSUM_MAP_FAILURE; |
| } |
| |
| BaseAddress = MapViewOfFile(hMapping, |
| FILE_MAP_READ, |
| 0, |
| 0, |
| 0); |
| if (BaseAddress == 0) |
| { |
| CloseHandle(hMapping); |
| CloseHandle(hFile); |
| return CHECKSUM_MAPVIEW_FAILURE; |
| } |
| |
| FileLength = GetFileSize(hFile, |
| NULL); |
| |
| CheckSumMappedFile(BaseAddress, |
| FileLength, |
| HeaderSum, |
| CheckSum); |
| |
| UnmapViewOfFile(BaseAddress); |
| CloseHandle(hMapping); |
| CloseHandle(hFile); |
| |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * MapFileAndCheckSumW (IMAGEHLP.@) |
| */ |
| DWORD WINAPI MapFileAndCheckSumW( |
| PCWSTR Filename, PDWORD HeaderSum, PDWORD CheckSum) |
| { |
| HANDLE hFile; |
| HANDLE hMapping; |
| LPVOID BaseAddress; |
| DWORD FileLength; |
| |
| TRACE("(%s, %p, %p): stub\n", |
| debugstr_w(Filename), HeaderSum, CheckSum |
| ); |
| |
| hFile = CreateFileW(Filename, |
| GENERIC_READ, |
| FILE_SHARE_READ | FILE_SHARE_WRITE, |
| NULL, |
| OPEN_EXISTING, |
| FILE_ATTRIBUTE_NORMAL, |
| 0); |
| if (hFile == INVALID_HANDLE_VALUE) |
| { |
| return CHECKSUM_OPEN_FAILURE; |
| } |
| |
| hMapping = CreateFileMappingW(hFile, |
| NULL, |
| PAGE_READONLY, |
| 0, |
| 0, |
| NULL); |
| if (hMapping == 0) |
| { |
| CloseHandle(hFile); |
| return CHECKSUM_MAP_FAILURE; |
| } |
| |
| BaseAddress = MapViewOfFile(hMapping, |
| FILE_MAP_READ, |
| 0, |
| 0, |
| 0); |
| if (BaseAddress == 0) |
| { |
| CloseHandle(hMapping); |
| CloseHandle(hFile); |
| return CHECKSUM_MAPVIEW_FAILURE; |
| } |
| |
| FileLength = GetFileSize(hFile, |
| NULL); |
| |
| CheckSumMappedFile(BaseAddress, |
| FileLength, |
| HeaderSum, |
| CheckSum); |
| |
| UnmapViewOfFile(BaseAddress); |
| CloseHandle(hMapping); |
| CloseHandle(hFile); |
| |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * ReBaseImage (IMAGEHLP.@) |
| */ |
| BOOL WINAPI ReBaseImage( |
| PCSTR CurrentImageName, PCSTR SymbolPath, BOOL fReBase, |
| BOOL fRebaseSysfileOk, BOOL fGoingDown, ULONG CheckImageSize, |
| ULONG *OldImageSize, ULONG_PTR *OldImageBase, ULONG *NewImageSize, |
| ULONG_PTR *NewImageBase, ULONG TimeStamp) |
| { |
| FIXME( |
| "(%s, %s, %d, %d, %d, %d, %p, %p, %p, %p, %d): stub\n", |
| debugstr_a(CurrentImageName),debugstr_a(SymbolPath), fReBase, |
| fRebaseSysfileOk, fGoingDown, CheckImageSize, OldImageSize, |
| OldImageBase, NewImageSize, NewImageBase, TimeStamp |
| ); |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * RemovePrivateCvSymbolic (IMAGEHLP.@) |
| */ |
| BOOL WINAPI RemovePrivateCvSymbolic( |
| PCHAR DebugData, PCHAR *NewDebugData, ULONG *NewDebugSize) |
| { |
| FIXME("(%p, %p, %p): stub\n", |
| DebugData, NewDebugData, NewDebugSize |
| ); |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * RemoveRelocations (IMAGEHLP.@) |
| */ |
| VOID WINAPI RemoveRelocations(PCHAR ImageName) |
| { |
| FIXME("(%p): stub\n", ImageName); |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| } |
| |
| /*********************************************************************** |
| * SplitSymbols (IMAGEHLP.@) |
| */ |
| BOOL WINAPI SplitSymbols( |
| PSTR ImageName, PCSTR SymbolsPath, |
| PSTR SymbolFilePath, ULONG Flags) |
| { |
| FIXME("(%s, %s, %s, %d): stub\n", |
| debugstr_a(ImageName), debugstr_a(SymbolsPath), |
| debugstr_a(SymbolFilePath), Flags |
| ); |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * UpdateDebugInfoFile (IMAGEHLP.@) |
| */ |
| BOOL WINAPI UpdateDebugInfoFile( |
| PCSTR ImageFileName, PCSTR SymbolPath, |
| PSTR DebugFilePath, PIMAGE_NT_HEADERS32 NtHeaders) |
| { |
| FIXME("(%s, %s, %s, %p): stub\n", |
| debugstr_a(ImageFileName), debugstr_a(SymbolPath), |
| debugstr_a(DebugFilePath), NtHeaders |
| ); |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * UpdateDebugInfoFileEx (IMAGEHLP.@) |
| */ |
| BOOL WINAPI UpdateDebugInfoFileEx( |
| PCSTR ImageFileName, PCSTR SymbolPath, PSTR DebugFilePath, |
| PIMAGE_NT_HEADERS32 NtHeaders, DWORD OldChecksum) |
| { |
| FIXME("(%s, %s, %s, %p, %d): stub\n", |
| debugstr_a(ImageFileName), debugstr_a(SymbolPath), |
| debugstr_a(DebugFilePath), NtHeaders, OldChecksum |
| ); |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); |
| return FALSE; |
| } |