kernel32/tests: Test ResolveDelayLoadedAPI with generated dll
André Hentschel
nerv at dawncrow.de
Thu Oct 31 12:43:54 CDT 2013
---
dlls/kernel32/tests/loader.c | 265 ++++++++++++++++++++++++++++++++++---------
1 file changed, 211 insertions(+), 54 deletions(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 732806c..02853fd 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -2197,12 +2197,37 @@ static PVOID WINAPI failuredllhook(ULONG ul, DELAYLOAD_INFO* pd)
static void test_ResolveDelayLoadedAPI(void)
{
+ static const char test_dll[] = "secur32.dll";
+ static const char test_func[] = "SealMessage";
+ static const char filler[0x1000];
+ char temp_path[MAX_PATH];
+ char dll_name[MAX_PATH];
+ IMAGE_DELAYLOAD_DESCRIPTOR idd, *delaydir;
+ IMAGE_THUNK_DATA itd32;
+ HANDLE hfile;
HMODULE hlib;
- int i;
- static const char* td[] =
+ DWORD dummy, file_size, i;
+ WORD hint = 0;
+ BOOL ret;
+ static const struct test_data
{
- "advapi32.dll",
- "comdlg32.dll",
+ BOOL func;
+ UINT_PTR ordinal;
+ BOOL succeeds;
+ } td[] =
+ {
+ {
+ TRUE, 0, TRUE
+ },
+ {
+ FALSE, IMAGE_ORDINAL_FLAG | 2, TRUE
+ },
+ {
+ FALSE, IMAGE_ORDINAL_FLAG | 5, TRUE
+ },
+ {
+ FALSE, IMAGE_ORDINAL_FLAG | 0, FALSE
+ },
};
if (!pResolveDelayLoadedAPI)
@@ -2226,66 +2251,198 @@ static void test_ResolveDelayLoadedAPI(void)
ok(cb_count == 1, "Wrong callback count: %d\n", cb_count);
}
- for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
+ GetTempPathA(MAX_PATH, temp_path);
+ GetTempFileNameA(temp_path, "ldr", 0, dll_name);
+ trace("creating %s\n", dll_name);
+ hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+ if (hfile == INVALID_HANDLE_VALUE)
{
- IMAGE_DELAYLOAD_DESCRIPTOR *delaydir;
- ULONG size;
+ ok(0, "could not create %s\n", dll_name);
+ return;
+ }
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ nt_header.FileHeader.NumberOfSections = 2;
+ nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
+ nt_header.OptionalHeader.SectionAlignment = 0x1000;
+ 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.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress = 0x1000;
+ nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 0x100;
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &nt_header.OptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ /* sections */
+ section.PointerToRawData = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress;
+ section.VirtualAddress = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress;
+ section.Misc.VirtualSize = nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size;
+ section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ section.PointerToRawData = 0x2000;
+ section.VirtualAddress = 0x2000;
+ i = sizeof(td)/sizeof(td[0]);
+ section.Misc.VirtualSize = sizeof(test_dll) + sizeof(hint) + sizeof(test_func) + sizeof(HMODULE) +
+ 2 * (i + 1) * sizeof(IMAGE_THUNK_DATA);
+ ok(section.Misc.VirtualSize <= 0x1000, "Too much tests, add a new section!\n");
+ section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ /* fill up to delay data */
+ file_size = GetFileSize(hfile, NULL);
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, filler,
+ nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress - file_size,
+ &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ /* delay data */
+ idd.Attributes.AllAttributes = 1;
+ idd.DllNameRVA = 0x2000;
+ idd.ModuleHandleRVA = idd.DllNameRVA + sizeof(test_dll) + sizeof(hint) + sizeof(test_func);
+ idd.ImportAddressTableRVA = idd.ModuleHandleRVA + sizeof(HMODULE);
+ idd.ImportNameTableRVA = idd.ImportAddressTableRVA + (i + 1) * sizeof(IMAGE_THUNK_DATA);
+ idd.BoundImportAddressTableRVA = 0;
+ idd.UnloadInformationTableRVA = 0;
+ idd.TimeDateStamp = 0;
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &idd, sizeof(idd), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, filler, sizeof(idd), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ /* fill up to extended delay data */
+ file_size = GetFileSize(hfile, NULL);
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, filler, idd.DllNameRVA - file_size, &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ /* extended delay data */
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, test_dll, sizeof(test_dll), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &hint, sizeof(hint), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, test_func, sizeof(test_func), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ file_size = GetFileSize(hfile, NULL);
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, filler, idd.ImportNameTableRVA - file_size, &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
+ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
+ {
+ if (td[i].func)
+ itd32.u1.AddressOfData = idd.DllNameRVA + sizeof(test_dll);
+ else
+ itd32.u1.Ordinal = td[i].ordinal;
SetLastError(0xdeadbeef);
- hlib = LoadLibraryA(td[i]);
- ok(hlib != NULL, "LoadLibrary error %u\n", GetLastError());
- if (!hlib)
- {
- skip("couldn't load %s.\n", td[i]);
- continue;
- }
+ ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+ }
- delaydir = RtlImageDirectoryEntryToData(hlib, TRUE, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, &size);
- if (!delaydir)
- {
- skip("haven't found section for delay import directory in %s.\n", td[i]);
- FreeLibrary(hlib);
- continue;
- }
+ itd32.u1.Ordinal = 0;
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
- for (;;)
+ /* fill up to eof */
+ file_size = GetFileSize(hfile, NULL);
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, filler, section.VirtualAddress + section.Misc.VirtualSize - file_size, &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+ CloseHandle(hfile);
+
+ SetLastError(0xdeadbeef);
+ hlib = LoadLibraryA(dll_name);
+ ok(hlib != NULL, "LoadLibrary error %u\n", GetLastError());
+ if (!hlib)
+ {
+ skip("couldn't load %s.\n", dll_name);
+ DeleteFileA(dll_name);
+ return;
+ }
+
+ delaydir = RtlImageDirectoryEntryToData(hlib, TRUE, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, &file_size);
+ if (!delaydir)
+ {
+ skip("haven't found section for delay import directory.\n");
+ FreeLibrary(hlib);
+ DeleteFileA(dll_name);
+ return;
+ }
+
+ for (;;)
+ {
+ IMAGE_THUNK_DATA *itdn, *itda;
+ HMODULE htarget;
+
+ if (!delaydir->DllNameRVA ||
+ !delaydir->ImportAddressTableRVA ||
+ !delaydir->ImportNameTableRVA) break;
+
+ itdn = RVAToAddr(delaydir->ImportNameTableRVA, hlib);
+ itda = RVAToAddr(delaydir->ImportAddressTableRVA, hlib);
+ htarget = LoadLibraryA(RVAToAddr(delaydir->DllNameRVA, hlib));
+
+ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
{
- const IMAGE_THUNK_DATA *itdn;
- IMAGE_THUNK_DATA *itda;
- HMODULE htarget;
- int j;
-
- if (!delaydir->DllNameRVA ||
- !delaydir->ImportAddressTableRVA ||
- !delaydir->ImportNameTableRVA) break;
-
- itdn = RVAToAddr(delaydir->ImportNameTableRVA, hlib);
- itda = RVAToAddr(delaydir->ImportAddressTableRVA, hlib);
- htarget = LoadLibraryA(RVAToAddr(delaydir->DllNameRVA, hlib));
- for (j = 0; itdn[j].u1.Ordinal; j++)
- {
- void *ret, *load;
+ void *ret, *load;
- if (IMAGE_SNAP_BY_ORDINAL(itdn[j].u1.Ordinal))
- load = (void *)GetProcAddress(htarget, (LPSTR)IMAGE_ORDINAL(itdn[j].u1.Ordinal));
- else
- {
- const IMAGE_IMPORT_BY_NAME* iibn = RVAToAddr(itdn[j].u1.AddressOfData, hlib);
- load = (void *)GetProcAddress(htarget, (char*)iibn->Name);
- }
+ if (IMAGE_SNAP_BY_ORDINAL(itdn[i].u1.Ordinal))
+ load = (void *)GetProcAddress(htarget, (LPSTR)IMAGE_ORDINAL(itdn[i].u1.Ordinal));
+ else
+ {
+ const IMAGE_IMPORT_BY_NAME* iibn = RVAToAddr(itdn[i].u1.AddressOfData, hlib);
+ load = (void *)GetProcAddress(htarget, (char*)iibn->Name);
+ }
- cb_count = 0;
- ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, NULL, &itda[j], 0);
- ok(ret != NULL, "ResolveDelayLoadedAPI failed\n");
- ok(ret == load, "expected %p, got %p\n", ret, load);
- ok(ret == (void*)itda[j].u1.AddressOfData, "expected %p, got %p\n",
- ret, (void*)itda[j].u1.AddressOfData);
- ok(!cb_count, "Wrong callback count: %d\n", cb_count);
+ cb_count = 0;
+ ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, NULL, &itda[i], 0);
+ if (td[i].succeeds)
+ {
+ ok(ret != NULL, "Test %u: ResolveDelayLoadedAPI failed\n", i);
+ ok(ret == load, "Test %u: expected %p, got %p\n", i, load, ret);
+ ok(ret == (void*)itda[i].u1.AddressOfData, "Test %u: expected %p, got %p\n",
+ i, ret, (void*)itda[i].u1.AddressOfData);
+ ok(!cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
+ }
+ else
+ {
+ ok(ret == NULL, "Test %u: ResolveDelayLoadedAPI succeeded\n", i);
+ ok(cb_count, "Test %u: Wrong callback count: %d\n", i, cb_count);
}
- delaydir++;
}
- FreeLibrary(hlib);
+ delaydir++;
}
+
+ FreeLibrary(hlib);
+ trace("deleting %s\n", dll_name);
+ DeleteFileA(dll_name);
}
START_TEST(loader)
@@ -2330,8 +2487,8 @@ START_TEST(loader)
}
test_Loader();
+ test_ResolveDelayLoadedAPI();
test_ImportDescriptors();
test_section_access();
test_ExitProcess();
- test_ResolveDelayLoadedAPI();
}
--
1.8.1.2
More information about the wine-patches
mailing list