Alexandre Julliard : kernel32/tests: Add some tests for dll import resolution.
Alexandre Julliard
julliard at winehq.org
Mon Feb 17 13:45:15 CST 2014
Module: wine
Branch: master
Commit: a4c8943c7015fc82b6b083f70fd952e09d88d416
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a4c8943c7015fc82b6b083f70fd952e09d88d416
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 17 16:15:06 2014 +0100
kernel32/tests: Add some tests for dll import resolution.
---
dlls/kernel32/tests/loader.c | 114 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 113 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 5173e91..9a56794 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define NONAMELESSUNION
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
@@ -1207,6 +1208,116 @@ nt4_is_broken:
}
}
+static void test_import_resolution(void)
+{
+ char temp_path[MAX_PATH];
+ char dll_name[MAX_PATH];
+ DWORD dummy;
+ void *expect;
+ HANDLE hfile;
+ HMODULE mod, mod2;
+ struct imports
+ {
+ IMAGE_IMPORT_DESCRIPTOR descr[2];
+ IMAGE_THUNK_DATA original_thunks[2];
+ IMAGE_THUNK_DATA thunks[2];
+ char module[16];
+ struct { WORD hint; char name[32]; } function;
+ } data, *ptr;
+ IMAGE_NT_HEADERS nt;
+ IMAGE_SECTION_HEADER section;
+ int test;
+
+ for (test = 0; test < 3; test++)
+ {
+#define DATA_RVA(ptr) (page_size + ((char *)(ptr) - (char *)&data))
+ nt = nt_header;
+ nt.FileHeader.NumberOfSections = 1;
+ nt.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
+ nt.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_RELOCS_STRIPPED;
+ if (test != 2) nt.FileHeader.Characteristics |= IMAGE_FILE_DLL;
+ nt.OptionalHeader.ImageBase = 0x12340000;
+ nt.OptionalHeader.SizeOfImage = 2 * page_size;
+ nt.OptionalHeader.SizeOfHeaders = nt.OptionalHeader.FileAlignment;
+ nt.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+ memset( nt.OptionalHeader.DataDirectory, 0, sizeof(nt.OptionalHeader.DataDirectory) );
+ nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = sizeof(data.descr);
+ nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = DATA_RVA(data.descr);
+
+ memset( &data, 0, sizeof(data) );
+ data.descr[0].u.OriginalFirstThunk = DATA_RVA( data.original_thunks );
+ data.descr[0].FirstThunk = DATA_RVA( data.thunks );
+ data.descr[0].Name = DATA_RVA( data.module );
+ strcpy( data.module, "kernel32.dll" );
+ strcpy( data.function.name, "CreateEventA" );
+ data.original_thunks[0].u1.AddressOfData = DATA_RVA( &data.function );
+ data.thunks[0].u1.AddressOfData = 0xdeadbeef;
+
+ GetTempPathA(MAX_PATH, temp_path);
+ GetTempFileNameA(temp_path, "ldr", 0, dll_name);
+
+ hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
+ ok( hfile != INVALID_HANDLE_VALUE, "creation failed\n" );
+
+ memset( §ion, 0, sizeof(section) );
+ memcpy( section.Name, ".text", sizeof(".text") );
+ section.PointerToRawData = nt.OptionalHeader.FileAlignment;
+ section.VirtualAddress = nt.OptionalHeader.SectionAlignment;
+ section.Misc.VirtualSize = sizeof(data);
+ section.SizeOfRawData = sizeof(data);
+ section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+
+ WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL);
+ WriteFile(hfile, &nt, sizeof(nt), &dummy, NULL);
+ WriteFile(hfile, §ion, sizeof(section), &dummy, NULL);
+
+ SetFilePointer( hfile, section.PointerToRawData, NULL, SEEK_SET );
+ WriteFile(hfile, &data, sizeof(data), &dummy, NULL);
+
+ CloseHandle( hfile );
+
+ switch (test)
+ {
+ case 0: /* normal load */
+ mod = LoadLibraryA( dll_name );
+ ok( mod != NULL, "failed to load err %u\n", GetLastError() );
+ if (!mod) break;
+ ptr = (struct imports *)((char *)mod + page_size);
+ expect = GetProcAddress( GetModuleHandleA( data.module ), data.function.name );
+ ok( (void *)ptr->thunks[0].u1.Function == expect, "thunk %p instead of %p for %s.%s\n",
+ (void *)ptr->thunks[0].u1.Function, expect, data.module, data.function.name );
+ FreeLibrary( mod );
+ break;
+ case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */
+ mod = LoadLibraryExA( dll_name, 0, DONT_RESOLVE_DLL_REFERENCES );
+ ok( mod != NULL, "failed to load err %u\n", GetLastError() );
+ if (!mod) break;
+ ptr = (struct imports *)((char *)mod + page_size);
+ ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
+ (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
+ mod2 = LoadLibraryA( dll_name );
+ ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 );
+ todo_wine
+ ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
+ (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
+ FreeLibrary( mod );
+ break;
+ case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */
+ mod = LoadLibraryA( dll_name );
+ ok( mod != NULL, "failed to load err %u\n", GetLastError() );
+ if (!mod) break;
+ ptr = (struct imports *)((char *)mod + page_size);
+ todo_wine
+ ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
+ (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
+ FreeLibrary( mod );
+ break;
+ }
+ DeleteFileA( dll_name );
+#undef DATA_RVA
+ }
+}
+
#define MAX_COUNT 10
static HANDLE attached_thread[MAX_COUNT];
static DWORD attached_thread_count;
@@ -2444,7 +2555,7 @@ static void test_ResolveDelayLoadedAPI(void)
nt_header.OptionalHeader.FileAlignment = 0x1000;
nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x2200;
nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + 2 * sizeof(IMAGE_SECTION_HEADER);
- nt_header.OptionalHeader.NumberOfRvaAndSizes = 15;
+ nt_header.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress = 0x1000;
nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 0x100;
@@ -2668,5 +2779,6 @@ START_TEST(loader)
test_ResolveDelayLoadedAPI();
test_ImportDescriptors();
test_section_access();
+ test_import_resolution();
test_ExitProcess();
}
More information about the wine-cvs
mailing list