ntdll: Support running .exe.so binaries in RtlCreateUserProcess().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4e81171e12
commit
051a8ddd04
|
@ -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
|
* get_pe_file_info
|
||||||
*/
|
*/
|
||||||
|
@ -1172,16 +1278,16 @@ static NTSTATUS get_pe_file_info( UNICODE_STRING *path, ULONG attributes,
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
|
|
||||||
|
memset( info, 0, sizeof(*info) );
|
||||||
InitializeObjectAttributes( &attr, path, attributes, 0, 0 );
|
InitializeObjectAttributes( &attr, path, attributes, 0, 0 );
|
||||||
if ((status = NtOpenFile( handle, GENERIC_READ, &attr, &io,
|
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;
|
BOOL is_64bit;
|
||||||
|
|
||||||
if (is_builtin_path( path, &is_64bit ))
|
if (is_builtin_path( path, &is_64bit ))
|
||||||
{
|
{
|
||||||
TRACE( "assuming %u-bit builtin for %s\n", is_64bit ? 64 : 32, debugstr_us(path));
|
TRACE( "assuming %u-bit builtin for %s\n", is_64bit ? 64 : 32, debugstr_us(path));
|
||||||
memset( info, 0, sizeof(*info) );
|
|
||||||
/* assume current arch */
|
/* assume current arch */
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
info->cpu = is_64bit ? CPU_x86_64 : CPU_x86;
|
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;
|
SERVER_END_REQ;
|
||||||
NtClose( mapping );
|
NtClose( mapping );
|
||||||
}
|
}
|
||||||
|
else if (status == STATUS_INVALID_IMAGE_NOT_MZ)
|
||||||
|
{
|
||||||
|
if (get_so_file_info( *handle, info )) return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1341,12 +1451,11 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case STATUS_INVALID_IMAGE_WIN_64:
|
case STATUS_INVALID_IMAGE_WIN_64:
|
||||||
ERR( "64-bit application %s not supported in 32-bit prefix\n",
|
ERR( "64-bit application %s not supported in 32-bit prefix\n", debugstr_us(path) );
|
||||||
debugstr_us( ¶ms->ImagePathName ));
|
|
||||||
break;
|
break;
|
||||||
case STATUS_INVALID_IMAGE_FORMAT:
|
case STATUS_INVALID_IMAGE_FORMAT:
|
||||||
ERR( "%s not supported on this installation (%s binary)\n",
|
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;
|
break;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
|
Loading…
Reference in New Issue