ntdll: Implement the SectionImageInformation class of NtQuerySection.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2602df14d8
commit
6f0979b983
|
@ -223,6 +223,68 @@ static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_size,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header )
|
||||||
|
{
|
||||||
|
SECTION_IMAGE_INFORMATION image;
|
||||||
|
ULONG info_size = 0xdeadbeef;
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE file, mapping;
|
||||||
|
ULONG file_size;
|
||||||
|
|
||||||
|
file = CreateFileA( dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
ok( file != INVALID_HANDLE_VALUE, "%u: CreateFile error %d\n", id, GetLastError() );
|
||||||
|
file_size = GetFileSize( file, NULL );
|
||||||
|
|
||||||
|
status = pNtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_QUERY,
|
||||||
|
NULL, NULL, PAGE_READONLY, SEC_IMAGE, file );
|
||||||
|
ok( !status, "%u: NtCreateSection failed err %x\n", id, status );
|
||||||
|
if (status) return;
|
||||||
|
status = pNtQuerySection( mapping, SectionImageInformation, &image, sizeof(image), &info_size );
|
||||||
|
ok( !status, "%u: NtQuerySection failed err %x\n", id, status );
|
||||||
|
ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %u\n", id, info_size );
|
||||||
|
ok( (char *)image.TransferAddress == (char *)nt_header->OptionalHeader.ImageBase + nt_header->OptionalHeader.AddressOfEntryPoint,
|
||||||
|
"%u: TransferAddress wrong %p / %p+%08x\n", id,
|
||||||
|
image.TransferAddress, (char *)nt_header->OptionalHeader.ImageBase,
|
||||||
|
nt_header->OptionalHeader.AddressOfEntryPoint );
|
||||||
|
ok( image.ZeroBits == 0, "%u: ZeroBits wrong %08x\n", id, image.ZeroBits );
|
||||||
|
ok( image.MaximumStackSize == nt_header->OptionalHeader.SizeOfStackReserve,
|
||||||
|
"%u: MaximumStackSize wrong %lx / %lx\n", id,
|
||||||
|
image.MaximumStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackReserve );
|
||||||
|
ok( image.CommittedStackSize == nt_header->OptionalHeader.SizeOfStackCommit,
|
||||||
|
"%u: CommittedStackSize wrong %lx / %lx\n", id,
|
||||||
|
image.CommittedStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackCommit );
|
||||||
|
ok( image.SubSystemType == nt_header->OptionalHeader.Subsystem,
|
||||||
|
"%u: SubSystemType wrong %08x / %08x\n", id,
|
||||||
|
image.SubSystemType, nt_header->OptionalHeader.Subsystem );
|
||||||
|
ok( image.SubsystemVersionLow == nt_header->OptionalHeader.MinorSubsystemVersion,
|
||||||
|
"%u: SubsystemVersionLow wrong %04x / %04x\n", id,
|
||||||
|
image.SubsystemVersionLow, nt_header->OptionalHeader.MinorSubsystemVersion );
|
||||||
|
ok( image.SubsystemVersionHigh == nt_header->OptionalHeader.MajorSubsystemVersion,
|
||||||
|
"%u: SubsystemVersionHigh wrong %04x / %04x\n", id,
|
||||||
|
image.SubsystemVersionHigh, nt_header->OptionalHeader.MajorSubsystemVersion );
|
||||||
|
ok( image.GpValue == 0, "%u: GpValue wrong %08x\n", id, image.GpValue );
|
||||||
|
ok( image.ImageCharacteristics == nt_header->FileHeader.Characteristics,
|
||||||
|
"%u: ImageCharacteristics wrong %04x / %04x\n", id,
|
||||||
|
image.ImageCharacteristics, nt_header->FileHeader.Characteristics );
|
||||||
|
ok( image.DllCharacteristics == nt_header->OptionalHeader.DllCharacteristics,
|
||||||
|
"%u: DllCharacteristics wrong %04x / %04x\n", id,
|
||||||
|
image.DllCharacteristics, nt_header->OptionalHeader.DllCharacteristics );
|
||||||
|
ok( image.Machine == nt_header->FileHeader.Machine, "%u: Machine wrong %04x / %04x\n", id,
|
||||||
|
image.Machine, nt_header->FileHeader.Machine );
|
||||||
|
ok( image.LoaderFlags == nt_header->OptionalHeader.LoaderFlags,
|
||||||
|
"%u: LoaderFlags wrong %08x / %08x\n", id,
|
||||||
|
image.LoaderFlags, nt_header->OptionalHeader.LoaderFlags );
|
||||||
|
ok( image.ImageFileSize == file_size, "%u: ImageFileSize wrong %08x / %08x\n", id,
|
||||||
|
image.ImageFileSize, file_size );
|
||||||
|
ok( image.CheckSum == nt_header->OptionalHeader.CheckSum, "%u: CheckSum wrong %08x / %08x\n", id,
|
||||||
|
image.CheckSum, nt_header->OptionalHeader.CheckSum );
|
||||||
|
/* FIXME: needs more work: */
|
||||||
|
/* image.ImageFlags */
|
||||||
|
/* image.ImageContainsCode */
|
||||||
|
CloseHandle( mapping );
|
||||||
|
CloseHandle( file );
|
||||||
|
}
|
||||||
|
|
||||||
/* helper to test image section mapping */
|
/* helper to test image section mapping */
|
||||||
static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
|
static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
|
||||||
{
|
{
|
||||||
|
@ -256,6 +318,7 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
|
||||||
todo_wine
|
todo_wine
|
||||||
ok( info.Size.QuadPart == size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
|
ok( info.Size.QuadPart == size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
|
||||||
info.Size.u.HighPart, info.Size.u.LowPart, size.u.HighPart, size.u.LowPart );
|
info.Size.u.HighPart, info.Size.u.LowPart, size.u.HighPart, size.u.LowPart );
|
||||||
|
query_image_section( 1000, dll_name, nt_header );
|
||||||
}
|
}
|
||||||
if (map) CloseHandle( map );
|
if (map) CloseHandle( map );
|
||||||
CloseHandle( file );
|
CloseHandle( file );
|
||||||
|
@ -588,6 +651,8 @@ static void test_Loader(void)
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = FreeLibrary(hlib_as_data_file);
|
ret = FreeLibrary(hlib_as_data_file);
|
||||||
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
||||||
|
|
||||||
|
query_image_section( i, dll_name, &nt_header );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -614,6 +679,8 @@ static void test_Loader(void)
|
||||||
nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
|
nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
|
||||||
|
|
||||||
nt_header.OptionalHeader.SectionAlignment = page_size;
|
nt_header.OptionalHeader.SectionAlignment = page_size;
|
||||||
|
nt_header.OptionalHeader.AddressOfEntryPoint = 0x1234;
|
||||||
|
nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
|
||||||
nt_header.OptionalHeader.FileAlignment = page_size;
|
nt_header.OptionalHeader.FileAlignment = page_size;
|
||||||
nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER);
|
nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER);
|
||||||
nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size;
|
nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size;
|
||||||
|
|
|
@ -410,6 +410,7 @@ static void test_MapViewOfFile(void)
|
||||||
HANDLE file, mapping, map2;
|
HANDLE file, mapping, map2;
|
||||||
void *ptr, *ptr2, *addr;
|
void *ptr, *ptr2, *addr;
|
||||||
SECTION_BASIC_INFORMATION section_info;
|
SECTION_BASIC_INFORMATION section_info;
|
||||||
|
SECTION_IMAGE_INFORMATION image_info;
|
||||||
MEMORY_BASIC_INFORMATION info;
|
MEMORY_BASIC_INFORMATION info;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
SIZE_T size;
|
SIZE_T size;
|
||||||
|
@ -1042,6 +1043,16 @@ static void test_MapViewOfFile(void)
|
||||||
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
|
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
|
||||||
ok( section_info.Size.QuadPart == 0x4000, "NtQuerySection wrong size %x%08x\n",
|
ok( section_info.Size.QuadPart == 0x4000, "NtQuerySection wrong size %x%08x\n",
|
||||||
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
|
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
|
||||||
|
status = pNtQuerySection( mapping, SectionBasicInformation, §ion_info, sizeof(section_info)-1, NULL );
|
||||||
|
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySection failed err %x\n", status );
|
||||||
|
status = pNtQuerySection( mapping, SectionBasicInformation, §ion_info, sizeof(section_info)+1, NULL );
|
||||||
|
ok( !status, "NtQuerySection failed err %x\n", status );
|
||||||
|
status = pNtQuerySection( mapping, SectionImageInformation, &image_info, sizeof(image_info)-1, NULL );
|
||||||
|
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySection failed err %x\n", status );
|
||||||
|
status = pNtQuerySection( mapping, SectionImageInformation, &image_info, sizeof(image_info), NULL );
|
||||||
|
ok( status == STATUS_SECTION_NOT_IMAGE, "NtQuerySection failed err %x\n", status );
|
||||||
|
status = pNtQuerySection( mapping, SectionImageInformation, &image_info, sizeof(image_info)+1, NULL );
|
||||||
|
ok( status == STATUS_SECTION_NOT_IMAGE, "NtQuerySection failed err %x\n", status );
|
||||||
CloseHandle(mapping);
|
CloseHandle(mapping);
|
||||||
|
|
||||||
CloseHandle(file);
|
CloseHandle(file);
|
||||||
|
|
|
@ -2537,9 +2537,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
||||||
SIZE_T size, mask = get_mask( zero_bits );
|
SIZE_T size, mask = get_mask( zero_bits );
|
||||||
int unix_handle = -1, needs_close;
|
int unix_handle = -1, needs_close;
|
||||||
unsigned int map_vprot, vprot, sec_flags;
|
unsigned int map_vprot, vprot, sec_flags;
|
||||||
void *base;
|
|
||||||
struct file_view *view;
|
struct file_view *view;
|
||||||
DWORD header_size;
|
pe_image_info_t image_info;
|
||||||
HANDLE dup_mapping, shared_file;
|
HANDLE dup_mapping, shared_file;
|
||||||
LARGE_INTEGER offset;
|
LARGE_INTEGER offset;
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
|
@ -2615,15 +2614,13 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
||||||
{
|
{
|
||||||
req->handle = wine_server_obj_handle( handle );
|
req->handle = wine_server_obj_handle( handle );
|
||||||
req->access = access;
|
req->access = access;
|
||||||
|
wine_server_set_reply( req, &image_info, sizeof(image_info) );
|
||||||
res = wine_server_call( req );
|
res = wine_server_call( req );
|
||||||
map_vprot = reply->protect;
|
map_vprot = reply->protect;
|
||||||
sec_flags = reply->flags;
|
sec_flags = reply->flags;
|
||||||
base = wine_server_get_ptr( reply->base );
|
|
||||||
full_size = reply->size;
|
full_size = reply->size;
|
||||||
header_size = reply->header_size;
|
|
||||||
dup_mapping = wine_server_ptr_handle( reply->mapping );
|
dup_mapping = wine_server_ptr_handle( reply->mapping );
|
||||||
shared_file = wine_server_ptr_handle( reply->shared_file );
|
shared_file = wine_server_ptr_handle( reply->shared_file );
|
||||||
if ((ULONG_PTR)base != reply->base) base = NULL;
|
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
if (res) return res;
|
if (res) return res;
|
||||||
|
@ -2636,6 +2633,9 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
||||||
|
|
||||||
if (sec_flags & SEC_IMAGE)
|
if (sec_flags & SEC_IMAGE)
|
||||||
{
|
{
|
||||||
|
void *base = wine_server_get_ptr( image_info.base );
|
||||||
|
|
||||||
|
if ((ULONG_PTR)base != image_info.base) base = NULL;
|
||||||
size = full_size;
|
size = full_size;
|
||||||
if (size != full_size) /* truncated */
|
if (size != full_size) /* truncated */
|
||||||
{
|
{
|
||||||
|
@ -2649,14 +2649,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
||||||
|
|
||||||
if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
|
if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
|
||||||
&shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
|
&shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
|
||||||
res = map_image( handle, unix_handle, base, size, mask, header_size,
|
res = map_image( handle, unix_handle, base, size, mask, image_info.header_size,
|
||||||
shared_fd, dup_mapping, map_vprot, addr_ptr );
|
shared_fd, dup_mapping, map_vprot, addr_ptr );
|
||||||
if (shared_needs_close) close( shared_fd );
|
if (shared_needs_close) close( shared_fd );
|
||||||
close_handle( shared_file );
|
close_handle( shared_file );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = map_image( handle, unix_handle, base, size, mask, header_size,
|
res = map_image( handle, unix_handle, base, size, mask, image_info.header_size,
|
||||||
-1, dup_mapping, map_vprot, addr_ptr );
|
-1, dup_mapping, map_vprot, addr_ptr );
|
||||||
}
|
}
|
||||||
if (needs_close) close( unix_handle );
|
if (needs_close) close( unix_handle );
|
||||||
|
@ -2769,25 +2769,59 @@ NTSTATUS WINAPI NtQuerySection( HANDLE handle, SECTION_INFORMATION_CLASS class,
|
||||||
ULONG size, ULONG *ret_size )
|
ULONG size, ULONG *ret_size )
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SECTION_BASIC_INFORMATION *basic_info = ptr;
|
pe_image_info_t image_info;
|
||||||
|
|
||||||
if (class != SectionBasicInformation)
|
switch (class)
|
||||||
{
|
{
|
||||||
|
case SectionBasicInformation:
|
||||||
|
if (size < sizeof(SECTION_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
case SectionImageInformation:
|
||||||
|
if (size < sizeof(SECTION_IMAGE_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
FIXME( "class %u not implemented\n", class );
|
FIXME( "class %u not implemented\n", class );
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
if (size < sizeof(*basic_info)) return STATUS_INFO_LENGTH_MISMATCH;
|
if (!ptr) return STATUS_ACCESS_VIOLATION;
|
||||||
|
|
||||||
SERVER_START_REQ( get_mapping_info )
|
SERVER_START_REQ( get_mapping_info )
|
||||||
{
|
{
|
||||||
req->handle = wine_server_obj_handle( handle );
|
req->handle = wine_server_obj_handle( handle );
|
||||||
req->access = SECTION_QUERY;
|
req->access = SECTION_QUERY;
|
||||||
|
wine_server_set_reply( req, &image_info, sizeof(image_info) );
|
||||||
if (!(status = wine_server_call( req )))
|
if (!(status = wine_server_call( req )))
|
||||||
{
|
{
|
||||||
basic_info->Attributes = reply->flags;
|
if (class == SectionBasicInformation)
|
||||||
basic_info->BaseAddress = NULL;
|
{
|
||||||
basic_info->Size.QuadPart = reply->size;
|
SECTION_BASIC_INFORMATION *info = ptr;
|
||||||
if (ret_size) *ret_size = sizeof(*basic_info);
|
info->Attributes = reply->flags;
|
||||||
|
info->BaseAddress = NULL;
|
||||||
|
info->Size.QuadPart = reply->size;
|
||||||
|
if (ret_size) *ret_size = sizeof(*info);
|
||||||
|
}
|
||||||
|
else if (reply->flags & SEC_IMAGE)
|
||||||
|
{
|
||||||
|
SECTION_IMAGE_INFORMATION *info = ptr;
|
||||||
|
info->TransferAddress = wine_server_get_ptr( image_info.entry_point );
|
||||||
|
info->ZeroBits = image_info.zerobits;
|
||||||
|
info->MaximumStackSize = image_info.stack_size;
|
||||||
|
info->CommittedStackSize = image_info.stack_commit;
|
||||||
|
info->SubSystemType = image_info.subsystem;
|
||||||
|
info->SubsystemVersionLow = image_info.subsystem_low;
|
||||||
|
info->SubsystemVersionHigh = image_info.subsystem_high;
|
||||||
|
info->GpValue = image_info.gp;
|
||||||
|
info->ImageCharacteristics = image_info.image_charact;
|
||||||
|
info->DllCharacteristics = image_info.dll_charact;
|
||||||
|
info->Machine = image_info.machine;
|
||||||
|
info->ImageContainsCode = image_info.contains_code;
|
||||||
|
info->ImageFlags = image_info.image_flags;
|
||||||
|
info->LoaderFlags = image_info.loader_flags;
|
||||||
|
info->ImageFileSize = image_info.file_size;
|
||||||
|
info->CheckSum = image_info.checksum;
|
||||||
|
if (ret_size) *ret_size = sizeof(*info);
|
||||||
|
}
|
||||||
|
else status = STATUS_SECTION_NOT_IMAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
|
@ -677,6 +677,29 @@ typedef union
|
||||||
} ioctl;
|
} ioctl;
|
||||||
} irp_params_t;
|
} irp_params_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
client_ptr_t base;
|
||||||
|
client_ptr_t entry_point;
|
||||||
|
mem_size_t stack_size;
|
||||||
|
mem_size_t stack_commit;
|
||||||
|
unsigned int zerobits;
|
||||||
|
unsigned int subsystem;
|
||||||
|
unsigned short subsystem_low;
|
||||||
|
unsigned short subsystem_high;
|
||||||
|
unsigned int gp;
|
||||||
|
unsigned short image_charact;
|
||||||
|
unsigned short dll_charact;
|
||||||
|
unsigned short machine;
|
||||||
|
unsigned char contains_code;
|
||||||
|
unsigned char image_flags;
|
||||||
|
unsigned int loader_flags;
|
||||||
|
unsigned int header_size;
|
||||||
|
unsigned int file_size;
|
||||||
|
unsigned int checksum;
|
||||||
|
} pe_image_info_t;
|
||||||
|
|
||||||
struct rawinput_device
|
struct rawinput_device
|
||||||
{
|
{
|
||||||
unsigned short usage_page;
|
unsigned short usage_page;
|
||||||
|
@ -2189,11 +2212,9 @@ struct get_mapping_info_reply
|
||||||
mem_size_t size;
|
mem_size_t size;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int protect;
|
int protect;
|
||||||
client_ptr_t base;
|
|
||||||
int header_size;
|
|
||||||
obj_handle_t mapping;
|
obj_handle_t mapping;
|
||||||
obj_handle_t shared_file;
|
obj_handle_t shared_file;
|
||||||
char __pad_44[4];
|
/* VARARG(image,pe_image_info); */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6223,6 +6244,6 @@ union generic_reply
|
||||||
struct terminate_job_reply terminate_job_reply;
|
struct terminate_job_reply terminate_job_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 505
|
#define SERVER_PROTOCOL_VERSION 506
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -63,8 +63,7 @@ struct mapping
|
||||||
int protect; /* protection flags */
|
int protect; /* protection flags */
|
||||||
struct fd *fd; /* fd for mapped file */
|
struct fd *fd; /* fd for mapped file */
|
||||||
enum cpu_type cpu; /* client CPU (for PE image mapping) */
|
enum cpu_type cpu; /* client CPU (for PE image mapping) */
|
||||||
int header_size; /* size of headers (for PE image mapping) */
|
pe_image_info_t image; /* image info (for PE image mapping) */
|
||||||
client_ptr_t base; /* default base addr (for PE image mapping) */
|
|
||||||
struct ranges *committed; /* list of committed ranges in this mapping */
|
struct ranges *committed; /* list of committed ranges in this mapping */
|
||||||
struct file *shared_file; /* temp file for shared PE mapping */
|
struct file *shared_file; /* temp file for shared PE mapping */
|
||||||
struct list shared_entry; /* entry in global shared PE mappings list */
|
struct list shared_entry; /* entry in global shared PE mappings list */
|
||||||
|
@ -373,7 +372,7 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retrieve the mapping parameters for an executable (PE) image */
|
/* retrieve the mapping parameters for an executable (PE) image */
|
||||||
static unsigned int get_image_params( struct mapping *mapping, int unix_fd )
|
static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_size, int unix_fd )
|
||||||
{
|
{
|
||||||
IMAGE_DOS_HEADER dos;
|
IMAGE_DOS_HEADER dos;
|
||||||
IMAGE_SECTION_HEADER *sec = NULL;
|
IMAGE_SECTION_HEADER *sec = NULL;
|
||||||
|
@ -399,6 +398,7 @@ static unsigned int get_image_params( struct mapping *mapping, int unix_fd )
|
||||||
size = pread( unix_fd, &nt, sizeof(nt), pos );
|
size = pread( unix_fd, &nt, sizeof(nt), pos );
|
||||||
if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) return STATUS_INVALID_IMAGE_FORMAT;
|
if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) return STATUS_INVALID_IMAGE_FORMAT;
|
||||||
/* zero out Optional header in the case it's not present or partial */
|
/* zero out Optional header in the case it's not present or partial */
|
||||||
|
size = min( size, nt.FileHeader.SizeOfOptionalHeader );
|
||||||
if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );
|
if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );
|
||||||
if (nt.Signature != IMAGE_NT_SIGNATURE)
|
if (nt.Signature != IMAGE_NT_SIGNATURE)
|
||||||
{
|
{
|
||||||
|
@ -439,22 +439,47 @@ static unsigned int get_image_params( struct mapping *mapping, int unix_fd )
|
||||||
{
|
{
|
||||||
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
|
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
|
||||||
mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
|
mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
|
||||||
mapping->base = nt.opt.hdr32.ImageBase;
|
mapping->image.base = nt.opt.hdr32.ImageBase;
|
||||||
mapping->header_size = nt.opt.hdr32.SizeOfHeaders;
|
mapping->image.entry_point = nt.opt.hdr32.ImageBase + nt.opt.hdr32.AddressOfEntryPoint;
|
||||||
|
mapping->image.stack_size = nt.opt.hdr32.SizeOfStackReserve;
|
||||||
|
mapping->image.stack_commit = nt.opt.hdr32.SizeOfStackCommit;
|
||||||
|
mapping->image.subsystem = nt.opt.hdr32.Subsystem;
|
||||||
|
mapping->image.subsystem_low = nt.opt.hdr32.MinorSubsystemVersion;
|
||||||
|
mapping->image.subsystem_high = nt.opt.hdr32.MajorSubsystemVersion;
|
||||||
|
mapping->image.dll_charact = nt.opt.hdr32.DllCharacteristics;
|
||||||
|
mapping->image.loader_flags = nt.opt.hdr32.LoaderFlags;
|
||||||
|
mapping->image.header_size = nt.opt.hdr32.SizeOfHeaders;
|
||||||
|
mapping->image.checksum = nt.opt.hdr32.CheckSum;
|
||||||
break;
|
break;
|
||||||
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
||||||
mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
|
mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
|
||||||
mapping->base = nt.opt.hdr64.ImageBase;
|
mapping->image.base = nt.opt.hdr64.ImageBase;
|
||||||
mapping->header_size = nt.opt.hdr64.SizeOfHeaders;
|
mapping->image.entry_point = nt.opt.hdr64.ImageBase + nt.opt.hdr64.AddressOfEntryPoint;
|
||||||
|
mapping->image.stack_size = nt.opt.hdr64.SizeOfStackReserve;
|
||||||
|
mapping->image.stack_commit = nt.opt.hdr64.SizeOfStackCommit;
|
||||||
|
mapping->image.subsystem = nt.opt.hdr64.Subsystem;
|
||||||
|
mapping->image.subsystem_low = nt.opt.hdr64.MinorSubsystemVersion;
|
||||||
|
mapping->image.subsystem_high = nt.opt.hdr64.MajorSubsystemVersion;
|
||||||
|
mapping->image.dll_charact = nt.opt.hdr64.DllCharacteristics;
|
||||||
|
mapping->image.loader_flags = nt.opt.hdr64.LoaderFlags;
|
||||||
|
mapping->image.header_size = nt.opt.hdr64.SizeOfHeaders;
|
||||||
|
mapping->image.checksum = nt.opt.hdr64.CheckSum;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
mapping->image.image_charact = nt.FileHeader.Characteristics;
|
||||||
|
mapping->image.machine = nt.FileHeader.Machine;
|
||||||
|
mapping->image.zerobits = 0; /* FIXME */
|
||||||
|
mapping->image.gp = 0; /* FIXME */
|
||||||
|
mapping->image.contains_code = 0; /* FIXME */
|
||||||
|
mapping->image.image_flags = 0; /* FIXME */
|
||||||
|
mapping->image.file_size = file_size;
|
||||||
|
|
||||||
/* load the section headers */
|
/* load the section headers */
|
||||||
|
|
||||||
pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;
|
pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;
|
||||||
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
||||||
if (pos + size > mapping->size) goto error;
|
if (pos + size > mapping->size) goto error;
|
||||||
if (pos + size > mapping->header_size) mapping->header_size = pos + size;
|
if (pos + size > mapping->image.header_size) mapping->image.header_size = pos + size;
|
||||||
if (!(sec = malloc( size ))) goto error;
|
if (!(sec = malloc( size ))) goto error;
|
||||||
if (pread( unix_fd, sec, size, pos ) != size) goto error;
|
if (pread( unix_fd, sec, size, pos ) != size) goto error;
|
||||||
|
|
||||||
|
@ -488,8 +513,6 @@ static struct object *create_mapping( struct object *root, const struct unicode_
|
||||||
if (get_error() == STATUS_OBJECT_NAME_EXISTS)
|
if (get_error() == STATUS_OBJECT_NAME_EXISTS)
|
||||||
return &mapping->obj; /* Nothing else to do */
|
return &mapping->obj; /* Nothing else to do */
|
||||||
|
|
||||||
mapping->header_size = 0;
|
|
||||||
mapping->base = 0;
|
|
||||||
mapping->flags = flags & (SEC_IMAGE | SEC_NOCACHE | SEC_WRITECOMBINE | SEC_LARGE_PAGES);
|
mapping->flags = flags & (SEC_IMAGE | SEC_NOCACHE | SEC_WRITECOMBINE | SEC_LARGE_PAGES);
|
||||||
mapping->protect = protect;
|
mapping->protect = protect;
|
||||||
mapping->fd = NULL;
|
mapping->fd = NULL;
|
||||||
|
@ -527,18 +550,18 @@ static struct object *create_mapping( struct object *root, const struct unicode_
|
||||||
if (!mapping->fd) goto error;
|
if (!mapping->fd) goto error;
|
||||||
|
|
||||||
if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
|
if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error;
|
||||||
if (flags & SEC_IMAGE)
|
|
||||||
{
|
|
||||||
unsigned int err = get_image_params( mapping, unix_fd );
|
|
||||||
if (!err) return &mapping->obj;
|
|
||||||
set_error( err );
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (fstat( unix_fd, &st ) == -1)
|
if (fstat( unix_fd, &st ) == -1)
|
||||||
{
|
{
|
||||||
file_set_error();
|
file_set_error();
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (flags & SEC_IMAGE)
|
||||||
|
{
|
||||||
|
unsigned int err = get_image_params( mapping, st.st_size, unix_fd );
|
||||||
|
if (!err) return &mapping->obj;
|
||||||
|
set_error( err );
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (!size)
|
if (!size)
|
||||||
{
|
{
|
||||||
if (!(size = st.st_size))
|
if (!(size = st.st_size))
|
||||||
|
@ -604,11 +627,9 @@ static void mapping_dump( struct object *obj, int verbose )
|
||||||
{
|
{
|
||||||
struct mapping *mapping = (struct mapping *)obj;
|
struct mapping *mapping = (struct mapping *)obj;
|
||||||
assert( obj->ops == &mapping_ops );
|
assert( obj->ops == &mapping_ops );
|
||||||
fprintf( stderr, "Mapping size=%08x%08x flags=%08x prot=%08x fd=%p header_size=%08x base=%08lx "
|
fprintf( stderr, "Mapping size=%08x%08x flags=%08x prot=%08x fd=%p shared_file=%p\n",
|
||||||
"shared_file=%p\n",
|
|
||||||
(unsigned int)(mapping->size >> 32), (unsigned int)mapping->size,
|
(unsigned int)(mapping->size >> 32), (unsigned int)mapping->size,
|
||||||
mapping->flags, mapping->protect, mapping->fd, mapping->header_size,
|
mapping->flags, mapping->protect, mapping->fd, mapping->shared_file );
|
||||||
(unsigned long)mapping->base, mapping->shared_file );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct object_type *mapping_get_type( struct object *obj )
|
static struct object_type *mapping_get_type( struct object *obj )
|
||||||
|
@ -701,8 +722,9 @@ DECL_HANDLER(get_mapping_info)
|
||||||
reply->size = mapping->size;
|
reply->size = mapping->size;
|
||||||
reply->flags = mapping->flags;
|
reply->flags = mapping->flags;
|
||||||
reply->protect = mapping->protect;
|
reply->protect = mapping->protect;
|
||||||
reply->header_size = mapping->header_size;
|
|
||||||
reply->base = mapping->base;
|
if (mapping->flags & SEC_IMAGE)
|
||||||
|
set_reply_data( &mapping->image, min( sizeof(mapping->image), get_reply_max_size() ));
|
||||||
|
|
||||||
if (!(req->access & (SECTION_MAP_READ | SECTION_MAP_WRITE))) /* query only */
|
if (!(req->access & (SECTION_MAP_READ | SECTION_MAP_WRITE))) /* query only */
|
||||||
{
|
{
|
||||||
|
|
|
@ -693,6 +693,29 @@ typedef union
|
||||||
} ioctl;
|
} ioctl;
|
||||||
} irp_params_t;
|
} irp_params_t;
|
||||||
|
|
||||||
|
/* information about a PE image mapping, roughly equivalent to SECTION_IMAGE_INFORMATION */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
client_ptr_t base;
|
||||||
|
client_ptr_t entry_point;
|
||||||
|
mem_size_t stack_size;
|
||||||
|
mem_size_t stack_commit;
|
||||||
|
unsigned int zerobits;
|
||||||
|
unsigned int subsystem;
|
||||||
|
unsigned short subsystem_low;
|
||||||
|
unsigned short subsystem_high;
|
||||||
|
unsigned int gp;
|
||||||
|
unsigned short image_charact;
|
||||||
|
unsigned short dll_charact;
|
||||||
|
unsigned short machine;
|
||||||
|
unsigned char contains_code;
|
||||||
|
unsigned char image_flags;
|
||||||
|
unsigned int loader_flags;
|
||||||
|
unsigned int header_size;
|
||||||
|
unsigned int file_size;
|
||||||
|
unsigned int checksum;
|
||||||
|
} pe_image_info_t;
|
||||||
|
|
||||||
struct rawinput_device
|
struct rawinput_device
|
||||||
{
|
{
|
||||||
unsigned short usage_page;
|
unsigned short usage_page;
|
||||||
|
@ -1694,10 +1717,9 @@ enum char_info_mode
|
||||||
mem_size_t size; /* mapping size */
|
mem_size_t size; /* mapping size */
|
||||||
unsigned int flags; /* SEC_* flags */
|
unsigned int flags; /* SEC_* flags */
|
||||||
int protect; /* protection flags */
|
int protect; /* protection flags */
|
||||||
client_ptr_t base; /* default base addr (for VPROT_IMAGE mapping) */
|
|
||||||
int header_size; /* header size (for VPROT_IMAGE mapping) */
|
|
||||||
obj_handle_t mapping; /* duplicate mapping handle unless removable */
|
obj_handle_t mapping; /* duplicate mapping handle unless removable */
|
||||||
obj_handle_t shared_file; /* shared mapping file handle */
|
obj_handle_t shared_file; /* shared mapping file handle */
|
||||||
|
VARARG(image,pe_image_info);/* image info for SEC_IMAGE mappings */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1230,11 +1230,9 @@ C_ASSERT( sizeof(struct get_mapping_info_request) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, size) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, size) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, flags) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, flags) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, protect) == 20 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, protect) == 20 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, base) == 24 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, mapping) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, header_size) == 32 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, shared_file) == 28 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, mapping) == 36 );
|
C_ASSERT( sizeof(struct get_mapping_info_reply) == 32 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, shared_file) == 40 );
|
|
||||||
C_ASSERT( sizeof(struct get_mapping_info_reply) == 48 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, handle) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, handle) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, offset) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, offset) == 16 );
|
||||||
C_ASSERT( sizeof(struct get_mapping_committed_range_request) == 24 );
|
C_ASSERT( sizeof(struct get_mapping_committed_range_request) == 24 );
|
||||||
|
|
|
@ -1136,6 +1136,27 @@ static void dump_varargs_filesystem_event( const char *prefix, data_size_t size
|
||||||
fputc( '}', stderr );
|
fputc( '}', stderr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_varargs_pe_image_info( const char *prefix, data_size_t size )
|
||||||
|
{
|
||||||
|
pe_image_info_t info;
|
||||||
|
|
||||||
|
memset( &info, 0, sizeof(info) );
|
||||||
|
memcpy( &info, cur_data, min( size, sizeof(info) ));
|
||||||
|
|
||||||
|
fprintf( stderr, "%s{", prefix );
|
||||||
|
dump_uint64( "base=", &info.base );
|
||||||
|
dump_uint64( ",entry_point=", &info.entry_point );
|
||||||
|
dump_uint64( ",stack_size=", &info.stack_size );
|
||||||
|
dump_uint64( ",stack_commit=", &info.stack_commit );
|
||||||
|
fprintf( stderr, ",zerobits=%08x,subsystem=%08x,subsystem_low=%04x,subsystem_high=%04x,gp=%08x"
|
||||||
|
",image_charact=%04x,dll_charact=%04x,machine=%04x,contains_code=%u,image_flags=%02x"
|
||||||
|
",loader_flags=%08x,header_size=%08x,file_size=%08x,checksum=%08x}",
|
||||||
|
info.zerobits, info.subsystem, info.subsystem_low, info.subsystem_high, info.gp,
|
||||||
|
info.image_charact, info.dll_charact, info.machine, info.contains_code, info.image_flags,
|
||||||
|
info.loader_flags, info.header_size, info.file_size, info.checksum );
|
||||||
|
remove_data( size );
|
||||||
|
}
|
||||||
|
|
||||||
static void dump_varargs_rawinput_devices(const char *prefix, data_size_t size )
|
static void dump_varargs_rawinput_devices(const char *prefix, data_size_t size )
|
||||||
{
|
{
|
||||||
const struct rawinput_device *device;
|
const struct rawinput_device *device;
|
||||||
|
@ -2180,10 +2201,9 @@ static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *re
|
||||||
dump_uint64( " size=", &req->size );
|
dump_uint64( " size=", &req->size );
|
||||||
fprintf( stderr, ", flags=%08x", req->flags );
|
fprintf( stderr, ", flags=%08x", req->flags );
|
||||||
fprintf( stderr, ", protect=%d", req->protect );
|
fprintf( stderr, ", protect=%d", req->protect );
|
||||||
dump_uint64( ", base=", &req->base );
|
|
||||||
fprintf( stderr, ", header_size=%d", req->header_size );
|
|
||||||
fprintf( stderr, ", mapping=%04x", req->mapping );
|
fprintf( stderr, ", mapping=%04x", req->mapping );
|
||||||
fprintf( stderr, ", shared_file=%04x", req->shared_file );
|
fprintf( stderr, ", shared_file=%04x", req->shared_file );
|
||||||
|
dump_varargs_pe_image_info( ", image=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_get_mapping_committed_range_request( const struct get_mapping_committed_range_request *req )
|
static void dump_get_mapping_committed_range_request( const struct get_mapping_committed_range_request *req )
|
||||||
|
|
Loading…
Reference in New Issue