mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:54:05 +00:00
ntdll: Implement NtQueryVirtualMemory(MemoryImageInformation).
This commit is contained in:
parent
884cff8214
commit
a5ff427acb
|
@ -2483,7 +2483,6 @@ static void test_query_image_information(void)
|
|||
&info, sizeof(info), &len );
|
||||
if (status == STATUS_INVALID_INFO_CLASS)
|
||||
{
|
||||
todo_wine
|
||||
win_skip( "MemoryImageInformation not supported\n" );
|
||||
NtUnmapViewOfSection( NtCurrentProcess(), ptr );
|
||||
return;
|
||||
|
@ -2578,6 +2577,7 @@ static void test_query_image_information(void)
|
|||
offset.QuadPart = 0;
|
||||
status = NtMapViewOfSection( mapping, NtCurrentProcess(), &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READONLY );
|
||||
ok( status == STATUS_IMAGE_NOT_AT_BASE, "Unexpected status %08lx\n", status );
|
||||
todo_wine
|
||||
ok( size == 0x4000, "wrong size %Ix\n", size );
|
||||
NtClose( mapping );
|
||||
|
||||
|
@ -2589,6 +2589,7 @@ static void test_query_image_information(void)
|
|||
ok( info.ImageBase == ptr, "wrong image base %p/%p\n", info.ImageBase, ptr );
|
||||
ok( info.SizeOfImage == nt->OptionalHeader.SizeOfImage, "wrong size %Ix/%x\n",
|
||||
info.SizeOfImage, (UINT)nt->OptionalHeader.SizeOfImage );
|
||||
todo_wine
|
||||
ok( info.ImagePartialMap, "wrong partial map\n" );
|
||||
ok( !info.ImageNotExecutable, "wrong not executable\n" );
|
||||
ok( info.ImageSigningLevel == 0 || info.ImageSigningLevel == 12,
|
||||
|
@ -2606,6 +2607,7 @@ static void test_query_image_information(void)
|
|||
offset.QuadPart = 0;
|
||||
status = NtMapViewOfSection( mapping, NtCurrentProcess(), &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READONLY );
|
||||
ok( status == STATUS_IMAGE_NOT_AT_BASE, "Unexpected status %08lx\n", status );
|
||||
todo_wine
|
||||
ok( size == 0x5000, "wrong size %Ix\n", size );
|
||||
NtClose( mapping );
|
||||
|
||||
|
@ -2617,6 +2619,7 @@ static void test_query_image_information(void)
|
|||
ok( info.ImageBase == ptr, "wrong image base %p/%p\n", info.ImageBase, ptr );
|
||||
ok( info.SizeOfImage == nt->OptionalHeader.SizeOfImage, "wrong size %Ix/%x\n",
|
||||
info.SizeOfImage, (UINT)nt->OptionalHeader.SizeOfImage );
|
||||
todo_wine
|
||||
ok( info.ImagePartialMap, "wrong partial map\n" );
|
||||
ok( !info.ImageNotExecutable, "wrong not executable\n" );
|
||||
ok( info.ImageSigningLevel == 0 || info.ImageSigningLevel == 12,
|
||||
|
|
|
@ -4967,6 +4967,40 @@ static unsigned int get_memory_section_name( HANDLE process, LPCVOID addr,
|
|||
return status;
|
||||
}
|
||||
|
||||
static unsigned int get_memory_image_info( HANDLE process, LPCVOID addr, MEMORY_IMAGE_INFORMATION *info,
|
||||
SIZE_T len, SIZE_T *res_len )
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
if (len < sizeof(*info)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
memset( info, 0, sizeof(*info) );
|
||||
|
||||
SERVER_START_REQ( get_image_view_info )
|
||||
{
|
||||
req->process = wine_server_obj_handle( process );
|
||||
req->addr = wine_server_client_ptr( addr );
|
||||
status = wine_server_call( req );
|
||||
if (!status && reply->base)
|
||||
{
|
||||
info->ImageBase = wine_server_get_ptr( reply->base );
|
||||
info->SizeOfImage = reply->size;
|
||||
info->ImageSigningLevel = 12;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (status == STATUS_NOT_MAPPED_VIEW)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION basic_info;
|
||||
|
||||
status = get_basic_memory_info( process, addr, &basic_info, sizeof(basic_info), NULL );
|
||||
if (status || basic_info.State == MEM_FREE) status = STATUS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (!status && res_len) *res_len = sizeof(*info);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NtQueryVirtualMemory (NTDLL.@)
|
||||
|
@ -4995,6 +5029,9 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
|||
case MemoryRegionInformation:
|
||||
return get_memory_region_info( process, addr, buffer, len, res_len );
|
||||
|
||||
case MemoryImageInformation:
|
||||
return get_memory_image_info( process, addr, buffer, len, res_len );
|
||||
|
||||
case MemoryWineUnixFuncs:
|
||||
case MemoryWineUnixWow64Funcs:
|
||||
if (len != sizeof(unixlib_handle_t)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
|
|
@ -190,6 +190,23 @@ typedef struct
|
|||
MEMORY_WORKING_SET_EX_BLOCK32 VirtualAttributes;
|
||||
} MEMORY_WORKING_SET_EX_INFORMATION32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG ImageBase;
|
||||
ULONG SizeOfImage;
|
||||
union
|
||||
{
|
||||
ULONG ImageFlags;
|
||||
struct
|
||||
{
|
||||
ULONG ImagePartialMap : 1;
|
||||
ULONG ImageNotExecutable : 1;
|
||||
ULONG ImageSigningLevel : 4;
|
||||
ULONG Reserved : 26;
|
||||
};
|
||||
};
|
||||
} MEMORY_IMAGE_INFORMATION32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NTSTATUS ExitStatus;
|
||||
|
|
|
@ -493,7 +493,7 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
|
|||
{
|
||||
if (len < sizeof(MEMORY_REGION_INFORMATION32))
|
||||
status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
if ((ULONG_PTR)addr > highest_user_address)
|
||||
else if ((ULONG_PTR)addr > highest_user_address)
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
else
|
||||
{
|
||||
|
@ -534,6 +534,27 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
|
|||
break;
|
||||
}
|
||||
|
||||
case MemoryImageInformation: /* MEMORY_IMAEG_INFORMATION */
|
||||
{
|
||||
if (len < sizeof(MEMORY_IMAGE_INFORMATION32)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
if ((ULONG_PTR)addr > highest_user_address) status = STATUS_INVALID_PARAMETER;
|
||||
else
|
||||
{
|
||||
MEMORY_IMAGE_INFORMATION info;
|
||||
MEMORY_IMAGE_INFORMATION32 *info32 = ptr;
|
||||
|
||||
if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len )))
|
||||
{
|
||||
info32->ImageBase = PtrToUlong( info.ImageBase );
|
||||
info32->SizeOfImage = info.SizeOfImage;
|
||||
info32->ImageFlags = info.ImageFlags;
|
||||
}
|
||||
}
|
||||
res_len = sizeof(MEMORY_IMAGE_INFORMATION32);
|
||||
break;
|
||||
}
|
||||
|
||||
case MemoryWineUnixWow64Funcs:
|
||||
return STATUS_INVALID_INFO_CLASS;
|
||||
|
||||
|
|
|
@ -2027,6 +2027,21 @@ struct map_builtin_view_reply
|
|||
|
||||
|
||||
|
||||
struct get_image_view_info_request
|
||||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t process;
|
||||
client_ptr_t addr;
|
||||
};
|
||||
struct get_image_view_info_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
client_ptr_t base;
|
||||
mem_size_t size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct unmap_view_request
|
||||
{
|
||||
struct request_header __header;
|
||||
|
@ -5629,6 +5644,7 @@ enum request
|
|||
REQ_map_view,
|
||||
REQ_map_image_view,
|
||||
REQ_map_builtin_view,
|
||||
REQ_get_image_view_info,
|
||||
REQ_unmap_view,
|
||||
REQ_get_mapping_committed_range,
|
||||
REQ_add_mapping_committed_range,
|
||||
|
@ -5916,6 +5932,7 @@ union generic_request
|
|||
struct map_view_request map_view_request;
|
||||
struct map_image_view_request map_image_view_request;
|
||||
struct map_builtin_view_request map_builtin_view_request;
|
||||
struct get_image_view_info_request get_image_view_info_request;
|
||||
struct unmap_view_request unmap_view_request;
|
||||
struct get_mapping_committed_range_request get_mapping_committed_range_request;
|
||||
struct add_mapping_committed_range_request add_mapping_committed_range_request;
|
||||
|
@ -6201,6 +6218,7 @@ union generic_reply
|
|||
struct map_view_reply map_view_reply;
|
||||
struct map_image_view_reply map_image_view_reply;
|
||||
struct map_builtin_view_reply map_builtin_view_reply;
|
||||
struct get_image_view_info_reply get_image_view_info_reply;
|
||||
struct unmap_view_reply unmap_view_reply;
|
||||
struct get_mapping_committed_range_reply get_mapping_committed_range_reply;
|
||||
struct add_mapping_committed_range_reply add_mapping_committed_range_reply;
|
||||
|
@ -6418,7 +6436,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 778
|
||||
#define SERVER_PROTOCOL_VERSION 779
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -1325,6 +1325,23 @@ DECL_HANDLER(unmap_view)
|
|||
free_memory_view( view );
|
||||
}
|
||||
|
||||
/* get information about a mapped image view */
|
||||
DECL_HANDLER(get_image_view_info)
|
||||
{
|
||||
struct process *process;
|
||||
struct memory_view *view;
|
||||
|
||||
if (!(process = get_process_from_handle( req->process, PROCESS_QUERY_INFORMATION ))) return;
|
||||
|
||||
if ((view = find_mapped_addr( process, req->addr )) && (view->flags & SEC_IMAGE))
|
||||
{
|
||||
reply->base = view->base;
|
||||
reply->size = view->size;
|
||||
}
|
||||
|
||||
release_object( process );
|
||||
}
|
||||
|
||||
/* get a range of committed pages in a file mapping */
|
||||
DECL_HANDLER(get_mapping_committed_range)
|
||||
{
|
||||
|
|
|
@ -1628,6 +1628,16 @@ enum server_fd_type
|
|||
@END
|
||||
|
||||
|
||||
/* Get information about a mapped image view */
|
||||
@REQ(get_image_view_info)
|
||||
obj_handle_t process; /* process handle */
|
||||
client_ptr_t addr; /* address inside mapped view (in process address space) */
|
||||
@REPLY
|
||||
client_ptr_t base; /* view base address */
|
||||
mem_size_t size; /* view size */
|
||||
@END
|
||||
|
||||
|
||||
/* Unmap a memory view from the current process */
|
||||
@REQ(unmap_view)
|
||||
client_ptr_t base; /* view base address */
|
||||
|
|
|
@ -186,6 +186,7 @@ DECL_HANDLER(get_mapping_info);
|
|||
DECL_HANDLER(map_view);
|
||||
DECL_HANDLER(map_image_view);
|
||||
DECL_HANDLER(map_builtin_view);
|
||||
DECL_HANDLER(get_image_view_info);
|
||||
DECL_HANDLER(unmap_view);
|
||||
DECL_HANDLER(get_mapping_committed_range);
|
||||
DECL_HANDLER(add_mapping_committed_range);
|
||||
|
@ -472,6 +473,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_map_view,
|
||||
(req_handler)req_map_image_view,
|
||||
(req_handler)req_map_builtin_view,
|
||||
(req_handler)req_get_image_view_info,
|
||||
(req_handler)req_unmap_view,
|
||||
(req_handler)req_get_mapping_committed_range,
|
||||
(req_handler)req_add_mapping_committed_range,
|
||||
|
@ -1145,6 +1147,12 @@ C_ASSERT( FIELD_OFFSET(struct map_image_view_request, entry) == 32 );
|
|||
C_ASSERT( FIELD_OFFSET(struct map_image_view_request, machine) == 36 );
|
||||
C_ASSERT( sizeof(struct map_image_view_request) == 40 );
|
||||
C_ASSERT( sizeof(struct map_builtin_view_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_request, process) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_request, addr) == 16 );
|
||||
C_ASSERT( sizeof(struct get_image_view_info_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_reply, base) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_reply, size) == 16 );
|
||||
C_ASSERT( sizeof(struct get_image_view_info_reply) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct unmap_view_request, base) == 16 );
|
||||
C_ASSERT( sizeof(struct unmap_view_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, base) == 16 );
|
||||
|
|
|
@ -2210,6 +2210,18 @@ static void dump_map_builtin_view_request( const struct map_builtin_view_request
|
|||
dump_varargs_unicode_str( ", name=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_image_view_info_request( const struct get_image_view_info_request *req )
|
||||
{
|
||||
fprintf( stderr, " process=%04x", req->process );
|
||||
dump_uint64( ", addr=", &req->addr );
|
||||
}
|
||||
|
||||
static void dump_get_image_view_info_reply( const struct get_image_view_info_reply *req )
|
||||
{
|
||||
dump_uint64( " base=", &req->base );
|
||||
dump_uint64( ", size=", &req->size );
|
||||
}
|
||||
|
||||
static void dump_unmap_view_request( const struct unmap_view_request *req )
|
||||
{
|
||||
dump_uint64( " base=", &req->base );
|
||||
|
@ -4622,6 +4634,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_map_view_request,
|
||||
(dump_func)dump_map_image_view_request,
|
||||
(dump_func)dump_map_builtin_view_request,
|
||||
(dump_func)dump_get_image_view_info_request,
|
||||
(dump_func)dump_unmap_view_request,
|
||||
(dump_func)dump_get_mapping_committed_range_request,
|
||||
(dump_func)dump_add_mapping_committed_range_request,
|
||||
|
@ -4905,6 +4918,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(dump_func)dump_get_image_view_info_reply,
|
||||
NULL,
|
||||
(dump_func)dump_get_mapping_committed_range_reply,
|
||||
NULL,
|
||||
|
@ -5188,6 +5202,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"map_view",
|
||||
"map_image_view",
|
||||
"map_builtin_view",
|
||||
"get_image_view_info",
|
||||
"unmap_view",
|
||||
"get_mapping_committed_range",
|
||||
"add_mapping_committed_range",
|
||||
|
|
Loading…
Reference in a new issue