This was written with project Hangover in mind, we hoped that we can get rid of https://github.com/AndreRH/wine/commit/8935bdf941f5f2866c2fa4695eb15d94337fa... Sadly this seems not to be the case, as Wine already behaves like modern Windows here
Signed-off-by: André Hentschel nerv@dawncrow.de --- dlls/kernel32/tests/virtual.c | 96 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index 4a449fd..56eb456 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -1608,10 +1608,79 @@ static void test_NtAreMappedFilesTheSame(void) DeleteFileA( testfile ); }
+static BOOL create_foreign_dll( LPCSTR filename ) +{ + IMAGE_DOS_HEADER *dos; + IMAGE_NT_HEADERS *nt; + IMAGE_SECTION_HEADER *sec; + BYTE *buffer; + DWORD lfanew = sizeof(*dos); + DWORD size = lfanew + sizeof(*nt) + sizeof(*sec); + DWORD written; + BOOL ret; + + HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); + if (file == INVALID_HANDLE_VALUE) return FALSE; + + buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ); + + dos = (IMAGE_DOS_HEADER *)buffer; + dos->e_magic = IMAGE_DOS_SIGNATURE; + dos->e_cblp = sizeof(*dos); + dos->e_cp = 1; + dos->e_cparhdr = lfanew / 16; + dos->e_minalloc = 0; + dos->e_maxalloc = 0xffff; + dos->e_ss = 0x0000; + dos->e_sp = 0x00b8; + dos->e_lfarlc = lfanew; + dos->e_lfanew = lfanew; + + nt = (IMAGE_NT_HEADERS *)(buffer + lfanew); + nt->Signature = IMAGE_NT_SIGNATURE; +#if defined __aarch64__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; +#else + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64; +#endif + nt->FileHeader.NumberOfSections = 1; + nt->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); + nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE; + nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; + nt->OptionalHeader.MajorLinkerVersion = 1; + nt->OptionalHeader.MinorLinkerVersion = 0; + nt->OptionalHeader.ImageBase = 0x10000000; + nt->OptionalHeader.SectionAlignment = 0x1000; + nt->OptionalHeader.FileAlignment = 0x1000; + nt->OptionalHeader.MajorOperatingSystemVersion = 1; + nt->OptionalHeader.MinorOperatingSystemVersion = 0; + nt->OptionalHeader.MajorImageVersion = 1; + nt->OptionalHeader.MinorImageVersion = 0; + nt->OptionalHeader.MajorSubsystemVersion = 4; + nt->OptionalHeader.MinorSubsystemVersion = 0; + nt->OptionalHeader.SizeOfImage = 0x2000; + nt->OptionalHeader.SizeOfHeaders = size; + nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; + nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + + sec = (IMAGE_SECTION_HEADER *)(nt + 1); + memcpy( sec->Name, ".rodata", sizeof(".rodata") ); + sec->Misc.VirtualSize = 0x1000; + sec->VirtualAddress = 0x1000; + sec->SizeOfRawData = 0; + sec->PointerToRawData = 0; + sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; + + ret = WriteFile( file, buffer, size, &written, NULL ) && written == size; + HeapFree( GetProcessHeap(), 0, buffer ); + CloseHandle( file ); + return ret; +} + static void test_CreateFileMapping(void) { - HANDLE handle, handle2, file[3]; - char path[MAX_PATH], filename[MAX_PATH]; + HANDLE handle, handle2, file[4]; + char path[MAX_PATH], filename[MAX_PATH], filename2[MAX_PATH]; unsigned int i; NTSTATUS status;
@@ -1664,6 +1733,14 @@ static void test_CreateFileMapping(void) { 2, SEC_IMAGE | SEC_WRITECOMBINE, ERROR_INVALID_PARAMETER }, { 2, SEC_IMAGE | SEC_RESERVE, ERROR_INVALID_PARAMETER }, { 2, SEC_IMAGE | SEC_COMMIT, ERROR_INVALID_PARAMETER }, + /* foreign PE image file */ + { 3, SEC_IMAGE, ERROR_BAD_EXE_FORMAT, SEC_FILE | SEC_IMAGE }, + { 3, SEC_IMAGE | SEC_FILE, ERROR_INVALID_PARAMETER }, /* 45 */ + { 3, SEC_IMAGE | SEC_NOCACHE, ERROR_BAD_EXE_FORMAT, SEC_FILE | SEC_IMAGE }, + { 3, SEC_IMAGE | SEC_LARGE_PAGES, ERROR_INVALID_PARAMETER }, + { 3, SEC_IMAGE | SEC_WRITECOMBINE, ERROR_INVALID_PARAMETER }, + { 3, SEC_IMAGE | SEC_RESERVE, ERROR_INVALID_PARAMETER }, + { 3, SEC_IMAGE | SEC_COMMIT, ERROR_INVALID_PARAMETER }, /* 50 */ };
/* test case sensitivity */ @@ -1716,17 +1793,26 @@ static void test_CreateFileMapping(void) file[2] = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); ok( file[2] != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
+ GetTempPathA( MAX_PATH, path ); + GetTempFileNameA( path, "foreign", 0, filename2 ); + ok(create_foreign_dll(filename2), "Creation of foreign dll failed\n"); + file[3] = CreateFileA( filename2, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); + for (i = 0; i < sizeof(sec_flag_tests) / sizeof(sec_flag_tests[0]); i++) { DWORD flags = sec_flag_tests[i].flags; - DWORD perm = sec_flag_tests[i].file == 2 ? PAGE_READONLY : PAGE_READWRITE; + DWORD perm = sec_flag_tests[i].file >= 2 ? PAGE_READONLY : PAGE_READWRITE; SetLastError( 0xdeadbeef ); handle = CreateFileMappingA( file[sec_flag_tests[i].file], NULL, flags | perm, 0, 0x1000, "Wine Test Mapping" ); if (sec_flag_tests[i].error) { + /* SEC_IMAGE_NO_EXECUTE produces ERROR_INVALID_PARAMETER on older Windows */ + BOOL wrong_err = ((flags & SEC_IMAGE_NO_EXECUTE) == SEC_IMAGE_NO_EXECUTE) && + (GetLastError() == ERROR_INVALID_PARAMETER); ok( !handle, "%u: CreateFileMapping succeeded\n", i ); - ok( GetLastError() == sec_flag_tests[i].error, "%u: wrong error %u\n", i, GetLastError()); + ok( GetLastError() == sec_flag_tests[i].error || broken(wrong_err), + "%u: wrong error %u\n", i, GetLastError()); } else { @@ -1754,7 +1840,9 @@ static void test_CreateFileMapping(void) } CloseHandle( file[1] ); CloseHandle( file[2] ); + CloseHandle( file[3] ); DeleteFileA( filename ); + DeleteFileA( filename2 ); }
static void test_IsBadReadPtr(void)
André Hentschel nerv@dawncrow.de wrote:
This was written with project Hangover in mind, we hoped that we can get rid of https://github.com/AndreRH/wine/commit/8935bdf941f5f2866c2fa4695eb15d94337fa... Sadly this seems not to be the case, as Wine already behaves like modern Windows here
Wouldn't this kind of test be simpler adding on top of 8a3624afc27953732013a90a54d71b9b66b34205?
Am 07.01.2018 um 17:21 schrieb Dmitry Timoshkov:
André Hentschel nerv@dawncrow.de wrote:
This was written with project Hangover in mind, we hoped that we can get rid of https://github.com/AndreRH/wine/commit/8935bdf941f5f2866c2fa4695eb15d94337fa... Sadly this seems not to be the case, as Wine already behaves like modern Windows here
Wouldn't this kind of test be simpler adding on top of 8a3624afc27953732013a90a54d71b9b66b34205?
Those tests are not loop based, so not cleaning them up is simpler
André Hentschel nerv@dawncrow.de writes:
Am 07.01.2018 um 17:21 schrieb Dmitry Timoshkov:
André Hentschel nerv@dawncrow.de wrote:
This was written with project Hangover in mind, we hoped that we can get rid of https://github.com/AndreRH/wine/commit/8935bdf941f5f2866c2fa4695eb15d94337fa... Sadly this seems not to be the case, as Wine already behaves like modern Windows here
Wouldn't this kind of test be simpler adding on top of 8a3624afc27953732013a90a54d71b9b66b34205?
Those tests are not loop based, so not cleaning them up is simpler
You can just add a single test, I don't think testing all flag combinations is meaningful.