From: Bernhard Reiter <ockham@raz.or.at>
Subject: [1/2] imagehlp: Implement (parts of) BindImageEx (try 7)
Message-Id: <538A54DA.3080507@raz.or.at>
Date: Sun, 01 Jun 2014 00:16:58 +0200

Split the patch from the previous tries into one for the tests, and one
for the implementation.

From bfe19c7174eb50785f17d1625ac5cf852c540d04 Mon Sep 17 00:00:00 2001
From: Bernhard Reiter <ockham@raz.or.at>
Date: Wed, 7 May 2014 20:58:23 +0200
Subject: Add test for BindImageEx.

---
 dlls/imagehlp/tests/image.c | 86 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/dlls/imagehlp/tests/image.c b/dlls/imagehlp/tests/image.c
index e008b0b..fbb1992 100644
--- a/dlls/imagehlp/tests/image.c
+++ b/dlls/imagehlp/tests/image.c
@@ -31,6 +31,9 @@
 static HMODULE hImageHlp;
 
 static BOOL (WINAPI *pImageGetDigestStream)(HANDLE, DWORD, DIGEST_FUNCTION, DIGEST_HANDLE);
+static BOOL (WINAPI *pBindImageEx)(DWORD Flags, PCSTR ImageName,
+                                   PCSTR DllPath, PCSTR SymbolPath,
+                                   PIMAGEHLP_STATUS_ROUTINE StatusRoutine);
 
 /* minimal PE file image */
 #define VA_START 0x400000
@@ -273,6 +276,44 @@ static void update_checksum(void)
     bin.nt_headers.OptionalHeader.CheckSum = sum;
 }
 
+BOOL WINAPI TestingStatusRoutine(IMAGEHLP_STATUS_REASON reason, PSTR ImageName, PSTR DllName,
+                                 ULONG_PTR Va, ULONG_PTR Parameter)
+{
+  switch(reason)
+    {
+    case BindOutOfMemory:
+    case BindRvaToVaFailed:
+    case BindNoRoomInImage:
+    case BindImportModuleFailed:
+    case BindImportProcedureFailed:
+      break;
+
+    case BindImportModule:
+    ok(!strcmp(DllName, "KERNEL32.DLL"),
+       "expected DllName to be KERNEL32.DLL, got %s\n", DllName);
+    break;
+
+    case BindImportProcedure:
+    ok((!lstrcmpiA(DllName, "C:\\Winnt\\system32\\KERNEL32.DLL")) || /*Win2k*/
+       (!lstrcmpiA(DllName, "C:\\Windows\\system32\\KERNEL32.DLL")), /*later*/
+       "expected DllName to be C:\\Winnt\\system32\\KERNEL32.DLL or"
+       " C:\\Windows\\system32\\KERNEL32.DLL, got %s\n", DllName);
+    ok(!strcmp((LPSTR)Parameter, "ExitProcess"),
+       "expected Parameter to be ExitProcess, got %s\n", (LPSTR)Parameter);
+    break;
+
+    case BindForwarder:
+    case BindForwarderNOT:
+    case BindImageModified:
+    case BindExpandFileHeaders:
+    case BindImageComplete:
+    case BindMismatchedSymbols:
+    case BindSymbolsNotUpdated:
+      break;
+    }
+  return TRUE;
+}
+
 static void test_get_digest_stream(void)
 {
     BOOL ret;
@@ -329,6 +370,41 @@ static void test_get_digest_stream(void)
     DeleteFileA(temp_file);
 }
 
+static void test_bind_image_ex(void)
+{
+    BOOL ret;
+    HANDLE file;
+    char temp_file[MAX_PATH];
+    DWORD count;
+
+    /* Call with a non-existant file */
+    SetLastError(0xdeadbeef);
+    ret = pBindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES, temp_file, NULL,
+                       NULL, (void *)TestingStatusRoutine);
+    ok(!ret && ((GetLastError() == ERROR_FILE_NOT_FOUND) ||
+                (GetLastError() == ERROR_INVALID_PARAMETER)),
+       "expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n",
+       GetLastError());
+
+    file = create_temp_file(temp_file);
+    if (file == INVALID_HANDLE_VALUE)
+    {
+        skip("couldn't create temp file\n");
+        return;
+    }
+
+    WriteFile(file, &bin, sizeof(bin), &count, NULL);
+    FlushFileBuffers(file);
+    CloseHandle(file);
+
+    /* Finally, call with a proper PE file */
+    SetLastError(0xdeadbeef);
+    ret = pBindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES, temp_file, NULL,
+                       NULL, (void *)TestingStatusRoutine);
+    ok(ret, "BindImageEx failed: %d\n", GetLastError());
+    DeleteFileA(temp_file);
+}
+
 START_TEST(image)
 {
     hImageHlp = LoadLibraryA("imagehlp.dll");
@@ -349,5 +425,15 @@ START_TEST(image)
         test_get_digest_stream();
     }
 
+    pBindImageEx = (void *) GetProcAddress(hImageHlp, "BindImageEx");
+
+    if (!pBindImageEx)
+    {
+        win_skip("BindImageEx function is not available\n");
+    } else
+    {
+        test_bind_image_ex();
+    }
+
     FreeLibrary(hImageHlp);
 }
-- 
1.9.1