Alexandre Julliard : ntdll: Support running .exe.so binaries in RtlCreateUserProcess().
Alexandre Julliard
julliard at winehq.org
Thu Nov 7 16:16:02 CST 2019
Module: wine
Branch: master
Commit: 051a8ddd045b897190279a3f451e39a61fd14dcb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=051a8ddd045b897190279a3f451e39a61fd14dcb
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Nov 7 12:28:11 2019 +0100
ntdll: Support running .exe.so binaries in RtlCreateUserProcess().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/process.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 114 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 7c108f2896..3dbd589f54 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -1161,6 +1161,112 @@ static BOOL is_builtin_path( UNICODE_STRING *path, BOOL *is_64bit )
}
+/***********************************************************************
+ * get_so_file_info
+ */
+static BOOL get_so_file_info( HANDLE handle, pe_image_info_t *info )
+{
+ union
+ {
+ struct
+ {
+ unsigned char magic[4];
+ unsigned char class;
+ unsigned char data;
+ unsigned char version;
+ unsigned char ignored1[9];
+ unsigned short type;
+ unsigned short machine;
+ unsigned char ignored2[8];
+ unsigned int phoff;
+ unsigned char ignored3[12];
+ unsigned short phnum;
+ } elf;
+ struct
+ {
+ unsigned char magic[4];
+ unsigned char class;
+ unsigned char data;
+ unsigned char ignored1[10];
+ unsigned short type;
+ unsigned short machine;
+ unsigned char ignored2[12];
+ unsigned __int64 phoff;
+ unsigned char ignored3[16];
+ unsigned short phnum;
+ } elf64;
+ struct
+ {
+ unsigned int magic;
+ unsigned int cputype;
+ unsigned int cpusubtype;
+ unsigned int filetype;
+ } macho;
+ IMAGE_DOS_HEADER mz;
+ } header;
+
+ IO_STATUS_BLOCK io;
+ LARGE_INTEGER offset;
+
+ offset.QuadPart = 0;
+ if (NtReadFile( handle, 0, NULL, NULL, &io, &header, sizeof(header), &offset, 0 )) return FALSE;
+ if (io.Information != sizeof(header)) return FALSE;
+
+ if (!memcmp( header.elf.magic, "\177ELF", 4 ))
+ {
+ unsigned int type;
+ unsigned short phnum;
+
+ if (header.elf.version != 1 /* EV_CURRENT */) return FALSE;
+#ifdef WORDS_BIGENDIAN
+ if (header.elf.data != 2 /* ELFDATA2MSB */) return FALSE;
+#else
+ if (header.elf.data != 1 /* ELFDATA2LSB */) return FALSE;
+#endif
+ switch (header.elf.machine)
+ {
+ case 3: info->cpu = CPU_x86; break;
+ case 20: info->cpu = CPU_POWERPC; break;
+ case 40: info->cpu = CPU_ARM; break;
+ case 62: info->cpu = CPU_x86_64; break;
+ case 183: info->cpu = CPU_ARM64; break;
+ }
+ if (header.elf.type != 3 /* ET_DYN */) return FALSE;
+ if (header.elf.class == 2 /* ELFCLASS64 */)
+ {
+ offset.QuadPart = header.elf64.phoff;
+ phnum = header.elf64.phnum;
+ }
+ else
+ {
+ offset.QuadPart = header.elf.phoff;
+ phnum = header.elf.phnum;
+ }
+ while (phnum--)
+ {
+ if (NtReadFile( handle, 0, NULL, NULL, &io, &type, sizeof(type), &offset, 0 )) return FALSE;
+ if (io.Information < sizeof(type)) return FALSE;
+ if (type == 3 /* PT_INTERP */) return FALSE;
+ offset.QuadPart += (header.elf.class == 2) ? 56 : 32;
+ }
+ return TRUE;
+ }
+ else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xfeedfacf)
+ {
+ switch (header.macho.cputype)
+ {
+ case 0x00000007: info->cpu = CPU_x86; break;
+ case 0x01000007: info->cpu = CPU_x86_64; break;
+ case 0x0000000c: info->cpu = CPU_ARM; break;
+ case 0x0100000c: info->cpu = CPU_ARM64; break;
+ case 0x00000012: info->cpu = CPU_POWERPC; break;
+ }
+ if (header.macho.filetype == 8) return TRUE;
+ }
+ return FALSE;
+}
+
+
/***********************************************************************
* get_pe_file_info
*/
@@ -1172,16 +1278,16 @@ static NTSTATUS get_pe_file_info( UNICODE_STRING *path, ULONG attributes,
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
+ memset( info, 0, sizeof(*info) );
InitializeObjectAttributes( &attr, path, attributes, 0, 0 );
if ((status = NtOpenFile( handle, GENERIC_READ, &attr, &io,
- FILE_SHARE_READ | FILE_SHARE_DELETE, 0 )))
+ FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT )))
{
BOOL is_64bit;
if (is_builtin_path( path, &is_64bit ))
{
TRACE( "assuming %u-bit builtin for %s\n", is_64bit ? 64 : 32, debugstr_us(path));
- memset( info, 0, sizeof(*info) );
/* assume current arch */
#if defined(__i386__) || defined(__x86_64__)
info->cpu = is_64bit ? CPU_x86_64 : CPU_x86;
@@ -1212,6 +1318,10 @@ static NTSTATUS get_pe_file_info( UNICODE_STRING *path, ULONG attributes,
SERVER_END_REQ;
NtClose( mapping );
}
+ else if (status == STATUS_INVALID_IMAGE_NOT_MZ)
+ {
+ if (get_so_file_info( *handle, info )) return STATUS_SUCCESS;
+ }
return status;
}
@@ -1341,12 +1451,11 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
switch (status)
{
case STATUS_INVALID_IMAGE_WIN_64:
- ERR( "64-bit application %s not supported in 32-bit prefix\n",
- debugstr_us( ¶ms->ImagePathName ));
+ ERR( "64-bit application %s not supported in 32-bit prefix\n", debugstr_us(path) );
break;
case STATUS_INVALID_IMAGE_FORMAT:
ERR( "%s not supported on this installation (%s binary)\n",
- debugstr_us( ¶ms->ImagePathName ), cpu_names[pe_info.cpu] );
+ debugstr_us(path), cpu_names[pe_info.cpu] );
break;
}
goto done;
More information about the wine-cvs
mailing list