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)