diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 7dcc1af9293..e845e0d5264 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -223,6 +223,68 @@ static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_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 */ 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 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 ); + query_image_section( 1000, dll_name, nt_header ); } if (map) CloseHandle( map ); CloseHandle( file ); @@ -588,6 +651,8 @@ static void test_Loader(void) SetLastError(0xdeadbeef); ret = FreeLibrary(hlib_as_data_file); ok(ret, "FreeLibrary error %d\n", GetLastError()); + + query_image_section( i, dll_name, &nt_header ); } else { @@ -614,6 +679,8 @@ static void test_Loader(void) nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); 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.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; diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index 37d3c6282e7..2a13857f567 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -410,6 +410,7 @@ static void test_MapViewOfFile(void) HANDLE file, mapping, map2; void *ptr, *ptr2, *addr; SECTION_BASIC_INFORMATION section_info; + SECTION_IMAGE_INFORMATION image_info; MEMORY_BASIC_INFORMATION info; BOOL ret; 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.Size.QuadPart == 0x4000, "NtQuerySection wrong size %x%08x\n", 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(file); diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 818e2641d86..fc1349d445e 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -2537,9 +2537,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p SIZE_T size, mask = get_mask( zero_bits ); int unix_handle = -1, needs_close; unsigned int map_vprot, vprot, sec_flags; - void *base; struct file_view *view; - DWORD header_size; + pe_image_info_t image_info; HANDLE dup_mapping, shared_file; LARGE_INTEGER offset; 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->access = access; + wine_server_set_reply( req, &image_info, sizeof(image_info) ); res = wine_server_call( req ); map_vprot = reply->protect; sec_flags = reply->flags; - base = wine_server_get_ptr( reply->base ); full_size = reply->size; - header_size = reply->header_size; dup_mapping = wine_server_ptr_handle( reply->mapping ); shared_file = wine_server_ptr_handle( reply->shared_file ); - if ((ULONG_PTR)base != reply->base) base = NULL; } SERVER_END_REQ; if (res) return res; @@ -2636,6 +2633,9 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p 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; 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, &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 ); if (shared_needs_close) close( shared_fd ); close_handle( shared_file ); } 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 ); } if (needs_close) close( unix_handle ); @@ -2769,25 +2769,59 @@ NTSTATUS WINAPI NtQuerySection( HANDLE handle, SECTION_INFORMATION_CLASS class, ULONG size, ULONG *ret_size ) { 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 ); 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 ) { req->handle = wine_server_obj_handle( handle ); req->access = SECTION_QUERY; + wine_server_set_reply( req, &image_info, sizeof(image_info) ); if (!(status = wine_server_call( req ))) { - basic_info->Attributes = reply->flags; - basic_info->BaseAddress = NULL; - basic_info->Size.QuadPart = reply->size; - if (ret_size) *ret_size = sizeof(*basic_info); + if (class == SectionBasicInformation) + { + SECTION_BASIC_INFORMATION *info = ptr; + 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; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 11373899470..15fb5a30163 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -677,6 +677,29 @@ typedef union } ioctl; } 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 { unsigned short usage_page; @@ -2189,11 +2212,9 @@ struct get_mapping_info_reply mem_size_t size; unsigned int flags; int protect; - client_ptr_t base; - int header_size; obj_handle_t mapping; 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; }; -#define SERVER_PROTOCOL_VERSION 505 +#define SERVER_PROTOCOL_VERSION 506 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/mapping.c b/server/mapping.c index 5f593d96947..71c34371d64 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -63,8 +63,7 @@ struct mapping int protect; /* protection flags */ struct fd *fd; /* fd for mapped file */ enum cpu_type cpu; /* client CPU (for PE image mapping) */ - int header_size; /* size of headers (for PE image mapping) */ - client_ptr_t base; /* default base addr (for PE image mapping) */ + pe_image_info_t image; /* image info (for PE image mapping) */ struct ranges *committed; /* list of committed ranges in this mapping */ struct file *shared_file; /* temp file for shared PE mapping */ 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 */ -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_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 ); 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 */ + size = min( size, nt.FileHeader.SizeOfOptionalHeader ); if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size ); if (nt.Signature != IMAGE_NT_SIGNATURE) { @@ -438,23 +438,48 @@ static unsigned int get_image_params( struct mapping *mapping, int unix_fd ) switch (nt.opt.hdr32.Magic) { case IMAGE_NT_OPTIONAL_HDR32_MAGIC: - mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage ); - mapping->base = nt.opt.hdr32.ImageBase; - mapping->header_size = nt.opt.hdr32.SizeOfHeaders; + mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage ); + mapping->image.base = nt.opt.hdr32.ImageBase; + 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; case IMAGE_NT_OPTIONAL_HDR64_MAGIC: - mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage ); - mapping->base = nt.opt.hdr64.ImageBase; - mapping->header_size = nt.opt.hdr64.SizeOfHeaders; + mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage ); + mapping->image.base = nt.opt.hdr64.ImageBase; + 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; } + 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 */ pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader; size = sizeof(*sec) * nt.FileHeader.NumberOfSections; 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 (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) 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->protect = protect; mapping->fd = NULL; @@ -527,18 +550,18 @@ static struct object *create_mapping( struct object *root, const struct unicode_ if (!mapping->fd) 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) { file_set_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 = st.st_size)) @@ -604,11 +627,9 @@ static void mapping_dump( struct object *obj, int verbose ) { struct mapping *mapping = (struct mapping *)obj; assert( obj->ops == &mapping_ops ); - fprintf( stderr, "Mapping size=%08x%08x flags=%08x prot=%08x fd=%p header_size=%08x base=%08lx " - "shared_file=%p\n", + fprintf( stderr, "Mapping size=%08x%08x flags=%08x prot=%08x fd=%p shared_file=%p\n", (unsigned int)(mapping->size >> 32), (unsigned int)mapping->size, - mapping->flags, mapping->protect, mapping->fd, mapping->header_size, - (unsigned long)mapping->base, mapping->shared_file ); + mapping->flags, mapping->protect, mapping->fd, mapping->shared_file ); } static struct object_type *mapping_get_type( struct object *obj ) @@ -698,11 +719,12 @@ DECL_HANDLER(get_mapping_info) if (!(mapping = get_mapping_obj( current->process, req->handle, req->access ))) return; - reply->size = mapping->size; - reply->flags = mapping->flags; - reply->protect = mapping->protect; - reply->header_size = mapping->header_size; - reply->base = mapping->base; + reply->size = mapping->size; + reply->flags = mapping->flags; + reply->protect = mapping->protect; + + 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 */ { diff --git a/server/protocol.def b/server/protocol.def index 61cd7b0088a..cce91d572db 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -693,6 +693,29 @@ typedef union } ioctl; } 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 { unsigned short usage_page; @@ -1694,10 +1717,9 @@ enum char_info_mode mem_size_t size; /* mapping size */ unsigned int flags; /* SEC_* 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 shared_file; /* shared mapping file handle */ + VARARG(image,pe_image_info);/* image info for SEC_IMAGE mappings */ @END diff --git a/server/request.h b/server/request.h index 76a8a25cb6e..4efc057e25f 100644 --- a/server/request.h +++ b/server/request.h @@ -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, flags) == 16 ); 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, header_size) == 32 ); -C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, mapping) == 36 ); -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_info_reply, mapping) == 24 ); +C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, shared_file) == 28 ); +C_ASSERT( sizeof(struct get_mapping_info_reply) == 32 ); 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( sizeof(struct get_mapping_committed_range_request) == 24 ); diff --git a/server/trace.c b/server/trace.c index d11c97838e4..cd3c50886bd 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1136,6 +1136,27 @@ static void dump_varargs_filesystem_event( const char *prefix, data_size_t size 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 ) { 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 ); fprintf( stderr, ", flags=%08x", req->flags ); 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, ", 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 )