Bernhard Reiter : imagehlp: Partially implement BindImageEx().
Alexandre Julliard
julliard at winehq.org
Mon Jun 7 15:02:05 CDT 2021
Module: wine
Branch: stable
Commit: f40379a9d1762de99f6b6f624c6f57a90be648d8
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f40379a9d1762de99f6b6f624c6f57a90be648d8
Author: Bernhard Reiter <ockham at raz.or.at>
Date: Sat Feb 13 11:30:11 2021 -0600
imagehlp: Partially implement BindImageEx().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=3591
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit d129a89d228190baeb8983ecfc18e093255148b9)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
dlls/imagehlp/modify.c | 91 +++++++++++++++++++++++++++++++++++++++++----
dlls/imagehlp/tests/image.c | 10 ++---
2 files changed, 88 insertions(+), 13 deletions(-)
diff --git a/dlls/imagehlp/modify.c b/dlls/imagehlp/modify.c
index 434a666ae94..d740d221bfc 100644
--- a/dlls/imagehlp/modify.c
+++ b/dlls/imagehlp/modify.c
@@ -44,15 +44,90 @@ BOOL WINAPI BindImage(
/***********************************************************************
* BindImageEx (IMAGEHLP.@)
*/
-BOOL WINAPI BindImageEx(
- DWORD Flags, PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath,
- PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
+BOOL WINAPI BindImageEx(DWORD flags, const char *module, const char *dll_path,
+ const char *symbol_path, PIMAGEHLP_STATUS_ROUTINE cb)
{
- FIXME("(%d, %s, %s, %s, %p): stub\n",
- Flags, debugstr_a(ImageName), debugstr_a(DllPath),
- debugstr_a(SymbolPath), StatusRoutine
- );
- return TRUE;
+ const IMAGE_IMPORT_DESCRIPTOR *import;
+ LOADED_IMAGE image;
+ ULONG size;
+
+ TRACE("flags %#x, module %s, dll_path %s, symbol_path %s, cb %p.\n",
+ flags, debugstr_a(module), debugstr_a(dll_path), debugstr_a(symbol_path), cb);
+
+ if (!(flags & BIND_NO_UPDATE))
+ FIXME("Image modification is not implemented.\n");
+ if (flags & ~BIND_NO_UPDATE)
+ FIXME("Ignoring flags %#x.\n", flags);
+
+ if (!MapAndLoad(module, dll_path, &image, TRUE, TRUE))
+ return FALSE;
+
+ if (!(import = ImageDirectoryEntryToData(image.MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size)))
+ {
+ UnMapAndLoad(&image);
+ return TRUE; /* no imports */
+ }
+
+ if (image.FileHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+ {
+ FIXME("Unhandled architecture %#x.\n", image.FileHeader->OptionalHeader.Magic);
+ UnMapAndLoad(&image);
+ return TRUE;
+ }
+
+ for (; import->Name && import->FirstThunk; ++import)
+ {
+ char full_path[MAX_PATH];
+ IMAGE_THUNK_DATA *thunk;
+ const char *dll_name;
+ DWORD thunk_rva;
+
+ if (!(dll_name = ImageRvaToVa(image.FileHeader, image.MappedAddress, import->Name, 0)))
+ {
+ ERR("Failed to get VA for import name RVA %#x.\n", import->Name);
+ continue;
+ }
+
+ if (cb) cb(BindImportModule, module, dll_name, 0, 0);
+
+ if (!SearchPathA(dll_path, dll_name, 0, sizeof(full_path), full_path, 0))
+ {
+ ERR("Import %s was not found.\n", debugstr_a(dll_path));
+ continue;
+ }
+
+ thunk_rva = import->OriginalFirstThunk ? import->OriginalFirstThunk : import->FirstThunk;
+ if (!(thunk = ImageRvaToVa(image.FileHeader, image.MappedAddress, thunk_rva, 0)))
+ {
+ ERR("Failed to get VA for import thunk RVA %#x.\n", thunk_rva);
+ continue;
+ }
+
+ for (; thunk->u1.Ordinal; ++thunk)
+ {
+ if (IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
+ {
+ /* FIXME: We apparently need to subtract the actual module's
+ * ordinal base. */
+ FIXME("Ordinal imports are not implemented.\n");
+ }
+ else
+ {
+ IMAGE_IMPORT_BY_NAME *name;
+
+ if (!(name = ImageRvaToVa(image.FileHeader, image.MappedAddress, thunk->u1.AddressOfData, 0)))
+ {
+ ERR("Failed to get VA for name RVA %#x.\n", thunk->u1.AddressOfData);
+ continue;
+ }
+
+ if (cb) cb(BindImportProcedure, module, full_path, 0, (ULONG_PTR)name->Name);
+ }
+ }
+ }
+
+ UnMapAndLoad(&image);
+ return TRUE;
}
diff --git a/dlls/imagehlp/tests/image.c b/dlls/imagehlp/tests/image.c
index 888744ac203..e2aa9485510 100644
--- a/dlls/imagehlp/tests/image.c
+++ b/dlls/imagehlp/tests/image.c
@@ -372,7 +372,7 @@ static BOOL WINAPI bind_image_cb(IMAGEHLP_STATUS_REASON reason, const char *file
char full_path[MAX_PATH];
BOOL ret;
- ok(!!va, "expected nonzero VA\n");
+ todo_wine ok(!!va, "expected nonzero VA\n");
ret = SearchPathA(NULL, last_module, ".dll", sizeof(full_path), full_path, NULL);
ok(ret, "got error %u\n", GetLastError());
ok(!strcmp(module, full_path), "expected %s, got %s\n", debugstr_a(full_path), debugstr_a(module));
@@ -408,15 +408,15 @@ static void test_bind_image_ex(void)
SetLastError(0xdeadbeef);
ret = BindImageEx(BIND_ALL_IMAGES | BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE,
"nonexistent.dll", 0, 0, bind_image_cb);
- todo_wine ok(!ret, "expected failure\n");
- todo_wine ok(GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
+ ok(!ret, "expected failure\n");
+ ok(GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER,
"got error %u\n", GetLastError());
ret = BindImageEx(BIND_ALL_IMAGES | BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE,
filename, NULL, NULL, bind_image_cb);
ok(ret, "got error %u\n", GetLastError());
- todo_wine ok(got_SysAllocString == 1, "got %u imports of SysAllocString\n", got_SysAllocString);
- todo_wine ok(got_GetOpenFileNameA == 1, "got %u imports of GetOpenFileNameA\n", got_GetOpenFileNameA);
+ ok(got_SysAllocString == 1, "got %u imports of SysAllocString\n", got_SysAllocString);
+ ok(got_GetOpenFileNameA == 1, "got %u imports of GetOpenFileNameA\n", got_GetOpenFileNameA);
todo_wine ok(got_SHRegGetIntW == 1, "got %u imports of SHRegGetIntW\n", got_SHRegGetIntW);
ret = DeleteFileA(filename);
More information about the wine-cvs
mailing list