server: Implement NtQueryVirtualMemory(MemorySectionName).

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-02-10 16:09:49 +01:00
parent 61abc500f5
commit 3472387777
7 changed files with 119 additions and 10 deletions

View File

@ -3865,6 +3865,37 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr,
return STATUS_SUCCESS;
}
static NTSTATUS get_memory_section_name( HANDLE process, LPCVOID addr,
MEMORY_SECTION_NAME *info, SIZE_T len, SIZE_T *ret_len )
{
NTSTATUS status;
if (!info) return STATUS_ACCESS_VIOLATION;
SERVER_START_REQ( get_mapping_filename )
{
req->process = wine_server_obj_handle( process );
req->addr = wine_server_client_ptr( addr );
if (len > sizeof(*info) + sizeof(WCHAR))
wine_server_set_reply( req, info + 1, len - sizeof(*info) - sizeof(WCHAR) );
status = wine_server_call( req );
if (!status || status == STATUS_BUFFER_OVERFLOW)
{
if (ret_len) *ret_len = sizeof(*info) + reply->len + sizeof(WCHAR);
if (len < sizeof(*info)) status = STATUS_INFO_LENGTH_MISMATCH;
if (!status)
{
info->SectionFileName.Buffer = (WCHAR *)(info + 1);
info->SectionFileName.Length = reply->len;
info->SectionFileName.MaximumLength = reply->len + sizeof(WCHAR);
info->SectionFileName.Buffer[reply->len / sizeof(WCHAR)] = 0;
}
}
}
SERVER_END_REQ;
return status;
}
#define UNIMPLEMENTED_INFO_CLASS(c) \
case c: \
FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
@ -3885,12 +3916,12 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
{
case MemoryBasicInformation:
return get_basic_memory_info( process, addr, buffer, len, res_len );
case MemoryWorkingSetExInformation:
return get_working_set_ex( process, addr, buffer, len, res_len );
case MemorySectionName:
return get_memory_section_name( process, addr, buffer, len, res_len );
UNIMPLEMENTED_INFO_CLASS(MemoryWorkingSetList);
UNIMPLEMENTED_INFO_CLASS(MemorySectionName);
UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation);
default:

View File

@ -372,14 +372,7 @@ static BOOL nt_get_mapped_file_name(HANDLE process, LPVOID addr, LPWSTR name, DW
ret_len = 0xdeadbeef;
status = pNtQueryVirtualMemory(process, addr, MemorySectionName, buf, buf_len, &ret_len);
todo_wine
ok(!status, "NtQueryVirtualMemory error %x\n", status);
/* FIXME: remove once Wine is fixed */
if (status)
{
HeapFree(GetProcessHeap(), 0, buf);
return FALSE;
}
section_name = (MEMORY_SECTION_NAME *)buf;
ok(ret_len == section_name->SectionFileName.MaximumLength + sizeof(*section_name), "got %lu, %u\n",
@ -501,6 +494,7 @@ todo_wine {
{
ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name);
WideCharToMultiByte(CP_ACP, 0, map_nameW, -1, map_name, MAX_PATH, NULL, NULL);
todo_wine
ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
}

View File

@ -2017,6 +2017,22 @@ struct is_same_mapping_reply
};
struct get_mapping_filename_request
{
struct request_header __header;
obj_handle_t process;
client_ptr_t addr;
};
struct get_mapping_filename_reply
{
struct reply_header __header;
data_size_t len;
/* VARARG(filename,unicode_str); */
char __pad_12[4];
};
struct thread_info
{
timeout_t start_time;
@ -5502,6 +5518,7 @@ enum request
REQ_get_mapping_committed_range,
REQ_add_mapping_committed_range,
REQ_is_same_mapping,
REQ_get_mapping_filename,
REQ_list_processes,
REQ_create_debug_obj,
REQ_wait_debug_event,
@ -5787,6 +5804,7 @@ union generic_request
struct get_mapping_committed_range_request get_mapping_committed_range_request;
struct add_mapping_committed_range_request add_mapping_committed_range_request;
struct is_same_mapping_request is_same_mapping_request;
struct get_mapping_filename_request get_mapping_filename_request;
struct list_processes_request list_processes_request;
struct create_debug_obj_request create_debug_obj_request;
struct wait_debug_event_request wait_debug_event_request;
@ -6070,6 +6088,7 @@ union generic_reply
struct get_mapping_committed_range_reply get_mapping_committed_range_reply;
struct add_mapping_committed_range_reply add_mapping_committed_range_reply;
struct is_same_mapping_reply is_same_mapping_reply;
struct get_mapping_filename_reply get_mapping_filename_reply;
struct list_processes_reply list_processes_reply;
struct create_debug_obj_reply create_debug_obj_reply;
struct wait_debug_event_reply wait_debug_event_reply;
@ -6280,7 +6299,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 672
#define SERVER_PROTOCOL_VERSION 673
/* ### protocol_version end ### */

View File

@ -329,6 +329,18 @@ struct memory_view *find_mapped_view( struct process *process, client_ptr_t base
return NULL;
}
/* find a memory view from any address inside it */
static struct memory_view *find_mapped_addr( struct process *process, client_ptr_t addr )
{
struct memory_view *view;
LIST_FOR_EACH_ENTRY( view, &process->views, struct memory_view, entry )
if (addr >= view->base && addr < view->base + view->size) return view;
set_error( STATUS_NOT_MAPPED_VIEW );
return NULL;
}
/* get the main exe memory view */
struct memory_view *get_exe_view( struct process *process )
{
@ -1209,3 +1221,23 @@ DECL_HANDLER(is_same_mapping)
!is_same_file_fd( view1->fd, view2->fd ))
set_error( STATUS_NOT_SAME_DEVICE );
}
/* get the filename of a mapping */
DECL_HANDLER(get_mapping_filename)
{
struct process *process;
struct memory_view *view;
struct unicode_str name;
if (!(process = get_process_from_handle( req->process, PROCESS_QUERY_INFORMATION ))) return;
if ((view = find_mapped_addr( process, req->addr )) && get_view_nt_name( view, &name ))
{
reply->len = name.len;
if (name.len <= get_reply_max_size()) set_reply_data( name.str, name.len );
else set_error( STATUS_BUFFER_OVERFLOW );
}
else set_error( STATUS_INVALID_ADDRESS );
release_object( process );
}

View File

@ -1588,6 +1588,16 @@ enum server_fd_type
@END
/* Get the filename of a mapping */
@REQ(get_mapping_filename)
obj_handle_t process; /* process handle */
client_ptr_t addr; /* address inside mapped view (in process address space) */
@REPLY
data_size_t len; /* total filename length in bytes */
VARARG(filename,unicode_str); /* filename in NT format */
@END
struct thread_info
{
timeout_t start_time;

View File

@ -191,6 +191,7 @@ DECL_HANDLER(unmap_view);
DECL_HANDLER(get_mapping_committed_range);
DECL_HANDLER(add_mapping_committed_range);
DECL_HANDLER(is_same_mapping);
DECL_HANDLER(get_mapping_filename);
DECL_HANDLER(list_processes);
DECL_HANDLER(create_debug_obj);
DECL_HANDLER(wait_debug_event);
@ -475,6 +476,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_mapping_committed_range,
(req_handler)req_add_mapping_committed_range,
(req_handler)req_is_same_mapping,
(req_handler)req_get_mapping_filename,
(req_handler)req_list_processes,
(req_handler)req_create_debug_obj,
(req_handler)req_wait_debug_event,
@ -1142,6 +1144,11 @@ C_ASSERT( sizeof(struct add_mapping_committed_range_request) == 40 );
C_ASSERT( FIELD_OFFSET(struct is_same_mapping_request, base1) == 16 );
C_ASSERT( FIELD_OFFSET(struct is_same_mapping_request, base2) == 24 );
C_ASSERT( sizeof(struct is_same_mapping_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct get_mapping_filename_request, process) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_mapping_filename_request, addr) == 16 );
C_ASSERT( sizeof(struct get_mapping_filename_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_mapping_filename_reply, len) == 8 );
C_ASSERT( sizeof(struct get_mapping_filename_reply) == 16 );
C_ASSERT( sizeof(struct list_processes_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct list_processes_reply, info_size) == 8 );
C_ASSERT( FIELD_OFFSET(struct list_processes_reply, process_count) == 12 );

View File

@ -2202,6 +2202,18 @@ static void dump_is_same_mapping_request( const struct is_same_mapping_request *
dump_uint64( ", base2=", &req->base2 );
}
static void dump_get_mapping_filename_request( const struct get_mapping_filename_request *req )
{
fprintf( stderr, " process=%04x", req->process );
dump_uint64( ", addr=", &req->addr );
}
static void dump_get_mapping_filename_reply( const struct get_mapping_filename_reply *req )
{
fprintf( stderr, " len=%u", req->len );
dump_varargs_unicode_str( ", filename=", cur_size );
}
static void dump_list_processes_request( const struct list_processes_request *req )
{
}
@ -4541,6 +4553,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_mapping_committed_range_request,
(dump_func)dump_add_mapping_committed_range_request,
(dump_func)dump_is_same_mapping_request,
(dump_func)dump_get_mapping_filename_request,
(dump_func)dump_list_processes_request,
(dump_func)dump_create_debug_obj_request,
(dump_func)dump_wait_debug_event_request,
@ -4822,6 +4835,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_mapping_committed_range_reply,
NULL,
NULL,
(dump_func)dump_get_mapping_filename_reply,
(dump_func)dump_list_processes_reply,
(dump_func)dump_create_debug_obj_reply,
(dump_func)dump_wait_debug_event_reply,
@ -5103,6 +5117,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_mapping_committed_range",
"add_mapping_committed_range",
"is_same_mapping",
"get_mapping_filename",
"list_processes",
"create_debug_obj",
"wait_debug_event",
@ -5363,6 +5378,7 @@ static const struct
{ "INFO_LENGTH_MISMATCH", STATUS_INFO_LENGTH_MISMATCH },
{ "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE },
{ "INSUFFICIENT_RESOURCES", STATUS_INSUFFICIENT_RESOURCES },
{ "INVALID_ADDRESS", STATUS_INVALID_ADDRESS },
{ "INVALID_CID", STATUS_INVALID_CID },
{ "INVALID_DEVICE_REQUEST", STATUS_INVALID_DEVICE_REQUEST },
{ "INVALID_FILE_FOR_SECTION", STATUS_INVALID_FILE_FOR_SECTION },