From 1d5ed7be366c36c9ca16a8783e4fb7dfc7e9bc73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 25 May 2017 07:02:46 +0200
Subject: [PATCH] kernel32/tests: Add basic tests for fake dlls.

---
 dlls/kernel32/tests/loader.c | 91 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 1e3b00e..cb5b8ed 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -1564,6 +1564,96 @@ static void test_filenames(void)
     DeleteFileA( long_path );
 }
 
+static void test_FakeDLL(void)
+{
+#ifdef __i386__
+    NTSTATUS (WINAPI *pNtSetEvent)(HANDLE, ULONG *) = NULL;
+    IMAGE_EXPORT_DIRECTORY *dir;
+    HMODULE module = GetModuleHandleA("ntdll.dll");
+    HANDLE file, map, event;
+    WCHAR path[MAX_PATH];
+    DWORD *names, *funcs;
+    WORD *ordinals;
+    ULONG size;
+    void *ptr;
+    int i;
+
+    GetModuleFileNameW(module, path, MAX_PATH);
+
+    file = CreateFileW(path, GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+    ok(file != INVALID_HANDLE_VALUE, "Failed to open %s (error %u)\n", wine_dbgstr_w(path), GetLastError());
+
+    map = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READ | SEC_IMAGE, 0, 0, NULL);
+    ok(map != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
+    ptr = MapViewOfFile(map, FILE_MAP_READ | FILE_MAP_EXECUTE, 0, 0, 0);
+    ok(ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError());
+
+    dir = RtlImageDirectoryEntryToData(ptr, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
+todo_wine
+    ok(dir != NULL, "RtlImageDirectoryEntryToData failed\n");
+    if (dir == NULL) goto done;
+
+    names    = RVAToAddr(dir->AddressOfNames, ptr);
+    ordinals = RVAToAddr(dir->AddressOfNameOrdinals, ptr);
+    funcs    = RVAToAddr(dir->AddressOfFunctions, ptr);
+    ok(dir->NumberOfNames > 0, "Could not find any exported functions\n");
+
+    for (i = 0; i < dir->NumberOfNames; i++)
+    {
+        DWORD map_rva, dll_rva, map_offset, dll_offset;
+        char *func_name = RVAToAddr(names[i], ptr);
+        BYTE *dll_func, *map_func;
+
+        /* check only Nt functions for now */
+        if (strncmp(func_name, "Zw", 2) && strncmp(func_name, "Nt", 2))
+            continue;
+
+        dll_func = (BYTE *)GetProcAddress(module, func_name);
+        ok(dll_func != NULL, "%s: GetProcAddress returned NULL\n", func_name);
+        if (dll_func[0] == 0x90 && dll_func[1] == 0x90 &&
+            dll_func[2] == 0x90 && dll_func[3] == 0x90)
+        {
+            todo_wine ok(0, "%s: Export is a stub-function, skipping\n", func_name);
+            continue;
+        }
+
+        /* check position in memory */
+        dll_rva = (DWORD_PTR)dll_func - (DWORD_PTR)module;
+        map_rva = funcs[ordinals[i]];
+        ok(map_rva == dll_rva, "%s: Rva of mapped function (0x%x) does not match dll (0x%x)\n",
+           func_name, dll_rva, map_rva);
+
+        /* check position in file */
+        map_offset = (DWORD_PTR)RtlImageRvaToVa(RtlImageNtHeader(ptr),    ptr,    map_rva, NULL) - (DWORD_PTR)ptr;
+        dll_offset = (DWORD_PTR)RtlImageRvaToVa(RtlImageNtHeader(module), module, dll_rva, NULL) - (DWORD_PTR)module;
+        ok(map_offset == dll_offset, "%s: File offset of mapped function (0x%x) does not match dll (0x%x)\n",
+           func_name, map_offset, dll_offset);
+
+        /* check function content */
+        map_func = RVAToAddr(map_rva, ptr);
+        ok(!memcmp(map_func, dll_func, 0x20), "%s: Function content does not match!\n", func_name);
+
+        if (!strcmp(func_name, "NtSetEvent"))
+            pNtSetEvent = (void *)map_func;
+    }
+
+    ok(pNtSetEvent != NULL, "Could not find NtSetEvent export\n");
+    if (pNtSetEvent)
+    {
+        event = CreateEventA(NULL, TRUE, FALSE, NULL);
+        ok(event != NULL, "CreateEvent failed with error %u\n", GetLastError());
+        pNtSetEvent(event, 0);
+        ok(WaitForSingleObject(event, 0) == WAIT_OBJECT_0, "Event was not signaled\n");
+        CloseHandle(event);
+    }
+
+done:
+    UnmapViewOfFile(ptr);
+    CloseHandle(map);
+    CloseHandle(file);
+#endif
+}
+
 /* Verify linking style of import descriptors */
 static void test_ImportDescriptors(void)
 {
@@ -3978,6 +4068,7 @@ START_TEST(loader)
         return;
     }
 
+    test_FakeDLL();
     test_filenames();
     test_ResolveDelayLoadedAPI();
     test_ImportDescriptors();
-- 
1.9.1

