imagehlp: Partially implement BindImageEx().
[wine/zf.git] / dlls / imagehlp / modify.c
blobd740d221bfcd9ee9f2fe404ca91dbd7ac621da89
1 /*
2 * IMAGEHLP library
4 * Copyright 1998 Patrik Stridvall
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winternl.h"
26 #include "winerror.h"
27 #include "wine/debug.h"
28 #include "imagehlp.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
32 static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount);
35 /***********************************************************************
36 * BindImage (IMAGEHLP.@)
38 BOOL WINAPI BindImage(
39 PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath)
41 return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
44 /***********************************************************************
45 * BindImageEx (IMAGEHLP.@)
47 BOOL WINAPI BindImageEx(DWORD flags, const char *module, const char *dll_path,
48 const char *symbol_path, PIMAGEHLP_STATUS_ROUTINE cb)
50 const IMAGE_IMPORT_DESCRIPTOR *import;
51 LOADED_IMAGE image;
52 ULONG size;
54 TRACE("flags %#x, module %s, dll_path %s, symbol_path %s, cb %p.\n",
55 flags, debugstr_a(module), debugstr_a(dll_path), debugstr_a(symbol_path), cb);
57 if (!(flags & BIND_NO_UPDATE))
58 FIXME("Image modification is not implemented.\n");
59 if (flags & ~BIND_NO_UPDATE)
60 FIXME("Ignoring flags %#x.\n", flags);
62 if (!MapAndLoad(module, dll_path, &image, TRUE, TRUE))
63 return FALSE;
65 if (!(import = ImageDirectoryEntryToData(image.MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size)))
67 UnMapAndLoad(&image);
68 return TRUE; /* no imports */
71 if (image.FileHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
73 FIXME("Unhandled architecture %#x.\n", image.FileHeader->OptionalHeader.Magic);
74 UnMapAndLoad(&image);
75 return TRUE;
78 for (; import->Name && import->FirstThunk; ++import)
80 char full_path[MAX_PATH];
81 IMAGE_THUNK_DATA *thunk;
82 const char *dll_name;
83 DWORD thunk_rva;
85 if (!(dll_name = ImageRvaToVa(image.FileHeader, image.MappedAddress, import->Name, 0)))
87 ERR("Failed to get VA for import name RVA %#x.\n", import->Name);
88 continue;
91 if (cb) cb(BindImportModule, module, dll_name, 0, 0);
93 if (!SearchPathA(dll_path, dll_name, 0, sizeof(full_path), full_path, 0))
95 ERR("Import %s was not found.\n", debugstr_a(dll_path));
96 continue;
99 thunk_rva = import->OriginalFirstThunk ? import->OriginalFirstThunk : import->FirstThunk;
100 if (!(thunk = ImageRvaToVa(image.FileHeader, image.MappedAddress, thunk_rva, 0)))
102 ERR("Failed to get VA for import thunk RVA %#x.\n", thunk_rva);
103 continue;
106 for (; thunk->u1.Ordinal; ++thunk)
108 if (IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
110 /* FIXME: We apparently need to subtract the actual module's
111 * ordinal base. */
112 FIXME("Ordinal imports are not implemented.\n");
114 else
116 IMAGE_IMPORT_BY_NAME *name;
118 if (!(name = ImageRvaToVa(image.FileHeader, image.MappedAddress, thunk->u1.AddressOfData, 0)))
120 ERR("Failed to get VA for name RVA %#x.\n", thunk->u1.AddressOfData);
121 continue;
124 if (cb) cb(BindImportProcedure, module, full_path, 0, (ULONG_PTR)name->Name);
129 UnMapAndLoad(&image);
130 return TRUE;
134 /***********************************************************************
135 * CheckSum (internal)
137 static WORD CalcCheckSum(
138 DWORD StartValue, LPVOID BaseAddress, DWORD WordCount)
140 LPWORD Ptr;
141 DWORD Sum;
142 DWORD i;
144 Sum = StartValue;
145 Ptr = (LPWORD)BaseAddress;
146 for (i = 0; i < WordCount; i++)
148 Sum += *Ptr;
149 if (HIWORD(Sum) != 0)
151 Sum = LOWORD(Sum) + HIWORD(Sum);
153 Ptr++;
156 return (WORD)(LOWORD(Sum) + HIWORD(Sum));
160 /***********************************************************************
161 * CheckSumMappedFile (IMAGEHLP.@)
163 PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(
164 LPVOID BaseAddress, DWORD FileLength,
165 LPDWORD HeaderSum, LPDWORD CheckSum)
167 PIMAGE_NT_HEADERS header;
168 DWORD CalcSum;
169 DWORD HdrSum;
171 TRACE("(%p, %d, %p, %p)\n", BaseAddress, FileLength, HeaderSum, CheckSum);
173 CalcSum = CalcCheckSum(0, BaseAddress, (FileLength + 1) / sizeof(WORD));
174 header = RtlImageNtHeader(BaseAddress);
176 if (!header)
177 return NULL;
179 *HeaderSum = HdrSum = header->OptionalHeader.CheckSum;
181 /* Subtract image checksum from calculated checksum. */
182 /* fix low word of checksum */
183 if (LOWORD(CalcSum) >= LOWORD(HdrSum))
185 CalcSum -= LOWORD(HdrSum);
187 else
189 CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1;
192 /* fix high word of checksum */
193 if (LOWORD(CalcSum) >= HIWORD(HdrSum))
195 CalcSum -= HIWORD(HdrSum);
197 else
199 CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1;
202 /* add file length */
203 CalcSum += FileLength;
205 *CheckSum = CalcSum;
207 return header;
210 /***********************************************************************
211 * MapFileAndCheckSumA (IMAGEHLP.@)
213 DWORD WINAPI MapFileAndCheckSumA(
214 PCSTR Filename, PDWORD HeaderSum, PDWORD CheckSum)
216 HANDLE hFile;
217 HANDLE hMapping;
218 LPVOID BaseAddress;
219 DWORD FileLength;
221 TRACE("(%s, %p, %p): stub\n",
222 debugstr_a(Filename), HeaderSum, CheckSum
225 hFile = CreateFileA(Filename,
226 GENERIC_READ,
227 FILE_SHARE_READ | FILE_SHARE_WRITE,
228 NULL,
229 OPEN_EXISTING,
230 FILE_ATTRIBUTE_NORMAL,
232 if (hFile == INVALID_HANDLE_VALUE)
234 return CHECKSUM_OPEN_FAILURE;
237 hMapping = CreateFileMappingW(hFile,
238 NULL,
239 PAGE_READONLY,
242 NULL);
243 if (hMapping == 0)
245 CloseHandle(hFile);
246 return CHECKSUM_MAP_FAILURE;
249 BaseAddress = MapViewOfFile(hMapping,
250 FILE_MAP_READ,
254 if (BaseAddress == 0)
256 CloseHandle(hMapping);
257 CloseHandle(hFile);
258 return CHECKSUM_MAPVIEW_FAILURE;
261 FileLength = GetFileSize(hFile,
262 NULL);
264 CheckSumMappedFile(BaseAddress,
265 FileLength,
266 HeaderSum,
267 CheckSum);
269 UnmapViewOfFile(BaseAddress);
270 CloseHandle(hMapping);
271 CloseHandle(hFile);
273 return 0;
276 /***********************************************************************
277 * MapFileAndCheckSumW (IMAGEHLP.@)
279 DWORD WINAPI MapFileAndCheckSumW(
280 PCWSTR Filename, PDWORD HeaderSum, PDWORD CheckSum)
282 HANDLE hFile;
283 HANDLE hMapping;
284 LPVOID BaseAddress;
285 DWORD FileLength;
287 TRACE("(%s, %p, %p): stub\n",
288 debugstr_w(Filename), HeaderSum, CheckSum
291 hFile = CreateFileW(Filename,
292 GENERIC_READ,
293 FILE_SHARE_READ | FILE_SHARE_WRITE,
294 NULL,
295 OPEN_EXISTING,
296 FILE_ATTRIBUTE_NORMAL,
298 if (hFile == INVALID_HANDLE_VALUE)
300 return CHECKSUM_OPEN_FAILURE;
303 hMapping = CreateFileMappingW(hFile,
304 NULL,
305 PAGE_READONLY,
308 NULL);
309 if (hMapping == 0)
311 CloseHandle(hFile);
312 return CHECKSUM_MAP_FAILURE;
315 BaseAddress = MapViewOfFile(hMapping,
316 FILE_MAP_READ,
320 if (BaseAddress == 0)
322 CloseHandle(hMapping);
323 CloseHandle(hFile);
324 return CHECKSUM_MAPVIEW_FAILURE;
327 FileLength = GetFileSize(hFile,
328 NULL);
330 CheckSumMappedFile(BaseAddress,
331 FileLength,
332 HeaderSum,
333 CheckSum);
335 UnmapViewOfFile(BaseAddress);
336 CloseHandle(hMapping);
337 CloseHandle(hFile);
339 return 0;
342 /***********************************************************************
343 * ReBaseImage (IMAGEHLP.@)
345 BOOL WINAPI ReBaseImage(
346 PCSTR CurrentImageName, PCSTR SymbolPath, BOOL fReBase,
347 BOOL fRebaseSysfileOk, BOOL fGoingDown, ULONG CheckImageSize,
348 ULONG *OldImageSize, ULONG_PTR *OldImageBase, ULONG *NewImageSize,
349 ULONG_PTR *NewImageBase, ULONG TimeStamp)
351 FIXME(
352 "(%s, %s, %d, %d, %d, %d, %p, %p, %p, %p, %d): stub\n",
353 debugstr_a(CurrentImageName),debugstr_a(SymbolPath), fReBase,
354 fRebaseSysfileOk, fGoingDown, CheckImageSize, OldImageSize,
355 OldImageBase, NewImageSize, NewImageBase, TimeStamp
357 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
358 return FALSE;
361 /***********************************************************************
362 * RemovePrivateCvSymbolic (IMAGEHLP.@)
364 BOOL WINAPI RemovePrivateCvSymbolic(
365 PCHAR DebugData, PCHAR *NewDebugData, ULONG *NewDebugSize)
367 FIXME("(%p, %p, %p): stub\n",
368 DebugData, NewDebugData, NewDebugSize
370 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
371 return FALSE;
374 /***********************************************************************
375 * RemoveRelocations (IMAGEHLP.@)
377 VOID WINAPI RemoveRelocations(PCHAR ImageName)
379 FIXME("(%p): stub\n", ImageName);
380 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
383 /***********************************************************************
384 * SplitSymbols (IMAGEHLP.@)
386 BOOL WINAPI SplitSymbols(
387 PSTR ImageName, PCSTR SymbolsPath,
388 PSTR SymbolFilePath, ULONG Flags)
390 FIXME("(%s, %s, %s, %d): stub\n",
391 debugstr_a(ImageName), debugstr_a(SymbolsPath),
392 debugstr_a(SymbolFilePath), Flags
394 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
395 return FALSE;
398 /***********************************************************************
399 * UpdateDebugInfoFile (IMAGEHLP.@)
401 BOOL WINAPI UpdateDebugInfoFile(
402 PCSTR ImageFileName, PCSTR SymbolPath,
403 PSTR DebugFilePath, PIMAGE_NT_HEADERS32 NtHeaders)
405 FIXME("(%s, %s, %s, %p): stub\n",
406 debugstr_a(ImageFileName), debugstr_a(SymbolPath),
407 debugstr_a(DebugFilePath), NtHeaders
409 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
410 return FALSE;
413 /***********************************************************************
414 * UpdateDebugInfoFileEx (IMAGEHLP.@)
416 BOOL WINAPI UpdateDebugInfoFileEx(
417 PCSTR ImageFileName, PCSTR SymbolPath, PSTR DebugFilePath,
418 PIMAGE_NT_HEADERS32 NtHeaders, DWORD OldChecksum)
420 FIXME("(%s, %s, %s, %p, %d): stub\n",
421 debugstr_a(ImageFileName), debugstr_a(SymbolPath),
422 debugstr_a(DebugFilePath), NtHeaders, OldChecksum
424 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
425 return FALSE;