[PATCH] kernel32/tests: Test CreateFileMapping with a foreign architecture dll
André Hentschel
nerv at dawncrow.de
Sun Jan 7 10:03:50 CST 2018
This was written with project Hangover in mind, we hoped that we can get rid of https://github.com/AndreRH/wine/commit/8935bdf941f5f2866c2fa4695eb15d94337fae9e
Sadly this seems not to be the case, as Wine already behaves like modern Windows here
Signed-off-by: André Hentschel <nerv at 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)
--
2.7.4
More information about the wine-devel
mailing list