Rebase against 2d6b0b67d91b6433744ec859b10b8ee8eb4a37b3.

This commit is contained in:
Zebediah Figura
2021-02-10 19:09:42 -06:00
parent 6347bdd1fc
commit 41e15516bd
36 changed files with 318 additions and 1419 deletions

View File

@@ -1,273 +0,0 @@
From d945688dd6b41731ea1ea515556e78d8de73979f Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Sun, 28 May 2017 05:19:30 +0200
Subject: [PATCH] ntdll: Implement NtQueryVirtualMemory(MemorySectionName).
(v3)
Contains several improvements by Sebastian Lackner <sebastian@fds-team.de>.
---
dlls/ntdll/unix/file.c | 2 +-
dlls/ntdll/unix/process.c | 2 +-
dlls/ntdll/unix/unix_private.h | 2 +
dlls/ntdll/unix/virtual.c | 101 ++++++++++++++++++++++++++++++++-
dlls/psapi/tests/psapi_main.c | 8 +--
server/mapping.c | 29 ++++++++++
server/protocol.def | 9 +++
7 files changed, 143 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 6a47422ac7f..82f314691c0 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -2014,7 +2014,7 @@ static NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
}
-static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name, BOOL nofollow )
+NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name, BOOL nofollow )
{
data_size_t size = 1024;
NTSTATUS ret;
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c
index a094c607da4..90617594411 100644
--- a/dlls/ntdll/unix/process.c
+++ b/dlls/ntdll/unix/process.c
@@ -478,7 +478,7 @@ static ULONG get_env_size( const RTL_USER_PROCESS_PARAMETERS *params, char **win
*
* Simplified version of RtlDosPathNameToNtPathName_U.
*/
-static WCHAR *get_nt_pathname( const UNICODE_STRING *str )
+WCHAR *get_nt_pathname( const UNICODE_STRING *str )
{
static const WCHAR ntprefixW[] = {'\\','?','?','\\',0};
static const WCHAR uncprefixW[] = {'U','N','C','\\',0};
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 6b7b8a4ce7c..3371a2ffaf0 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -108,6 +108,7 @@ extern void CDECL get_initial_directory( UNICODE_STRING *dir ) DECLSPEC_HIDDEN;
extern void CDECL get_initial_console( RTL_USER_PROCESS_PARAMETERS *params ) DECLSPEC_HIDDEN;
extern USHORT * CDECL get_unix_codepage_data(void) DECLSPEC_HIDDEN;
extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
+extern WCHAR *get_nt_pathname( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
@@ -161,6 +162,7 @@ extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *
apc_result_t *result ) DECLSPEC_HIDDEN;
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
int *needs_close, enum server_fd_type *type, unsigned int *options ) DECLSPEC_HIDDEN;
+extern NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name, BOOL nofollow ) DECLSPEC_HIDDEN;
extern size_t server_init_process(void) DECLSPEC_HIDDEN;
extern void server_init_process_done(void) DECLSPEC_HIDDEN;
extern void server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index a136390c994..457bd45e516 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4042,6 +4042,103 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr,
return STATUS_SUCCESS;
}
+/* get file name for mapped section */
+static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
+ MEMORY_SECTION_NAME *info,
+ SIZE_T len, SIZE_T *res_len )
+{
+ UNICODE_STRING nt_name, dos_path_name;
+ WCHAR *nt_nameW;
+ char *unix_name;
+ data_size_t size = 1024;
+ WCHAR *name = NULL;
+ NTSTATUS status;
+ HANDLE mapping;
+
+ if (!addr || !info || !res_len) return STATUS_INVALID_PARAMETER;
+
+ SERVER_START_REQ( get_mapping_file )
+ {
+ req->process = wine_server_obj_handle( process );
+ req->addr = wine_server_client_ptr( addr );
+ status = wine_server_call( req );
+ mapping = wine_server_ptr_handle( reply->handle );
+ }
+ SERVER_END_REQ;
+
+ memset( &nt_name, 0, sizeof(nt_name) );
+
+ if (!status && mapping)
+ {
+ status = server_get_unix_name( mapping, &unix_name, FALSE );
+ NtClose( mapping );
+ if (!status)
+ {
+ status = unix_to_nt_file_name( unix_name, &nt_nameW );
+ free( unix_name );
+ }
+ if (!status)
+ {
+ nt_name.Buffer = nt_nameW;
+ goto found;
+ }
+ if (status == STATUS_OBJECT_TYPE_MISMATCH) status = STATUS_FILE_INVALID;
+ return status;
+ }
+
+ for (;;)
+ {
+ if (!(name = malloc( (size + 1) * sizeof(WCHAR) )))
+ return STATUS_NO_MEMORY;
+
+ SERVER_START_REQ( get_dll_info )
+ {
+ req->handle = wine_server_obj_handle( process );
+ req->base_address = (ULONG_PTR)addr;
+ wine_server_set_reply( req, name, size * sizeof(WCHAR) );
+ status = wine_server_call( req );
+ size = reply->filename_len / sizeof(WCHAR);
+ }
+ SERVER_END_REQ;
+
+ if (!status)
+ {
+ name[size] = 0;
+ break;
+ }
+ free( name );
+ if (status == STATUS_DLL_NOT_FOUND) return STATUS_INVALID_ADDRESS;
+ if (status != STATUS_BUFFER_TOO_SMALL) return status;
+ }
+
+ dos_path_name.Buffer = name;
+ dos_path_name.Length = size * sizeof(WCHAR);
+
+ if (!(nt_name.Buffer = get_nt_pathname( &dos_path_name )))
+ {
+ free( name );
+ return STATUS_INVALID_PARAMETER;
+ }
+found:
+ nt_name.Length = wcslen( nt_name.Buffer ) * sizeof(WCHAR);
+ *res_len = sizeof(MEMORY_SECTION_NAME) + nt_name.Length + sizeof(WCHAR);
+ if (len >= *res_len)
+ {
+ info->SectionFileName.Length = nt_name.Length;
+ info->SectionFileName.MaximumLength = nt_name.Length + sizeof(WCHAR);
+ info->SectionFileName.Buffer = (WCHAR *)(info + 1);
+ memcpy(info->SectionFileName.Buffer, nt_name.Buffer, nt_name.Length);
+ info->SectionFileName.Buffer[ nt_name.Length / sizeof(WCHAR) ] = 0;
+ }
+ else
+ status = (len < sizeof(MEMORY_SECTION_NAME)) ? STATUS_INFO_LENGTH_MISMATCH : STATUS_BUFFER_OVERFLOW;
+
+ free( name );
+ free( nt_name.Buffer );
+ return status;
+}
+
+
#define UNIMPLEMENTED_INFO_CLASS(c) \
case c: \
FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
@@ -4066,8 +4163,10 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
case MemoryWorkingSetExInformation:
return get_working_set_ex( process, addr, buffer, len, res_len );
+ case MemorySectionName:
+ return get_section_name( process, addr, buffer, len, res_len );
+
UNIMPLEMENTED_INFO_CLASS(MemoryWorkingSetList);
- UNIMPLEMENTED_INFO_CLASS(MemorySectionName);
UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation);
default:
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index be12af58311..3e211a771f9 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -384,14 +384,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",
@@ -513,6 +506,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);
}
diff --git a/server/mapping.c b/server/mapping.c
index 9e481646f2f..399d0c76918 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -1178,6 +1178,35 @@ DECL_HANDLER(unmap_view)
if (view) free_memory_view( view );
}
+/* get file handle from mapping by address */
+DECL_HANDLER(get_mapping_file)
+{
+ struct memory_view *view;
+ struct process *process;
+ struct file *file;
+
+ if (!(process = get_process_from_handle( req->process, 0 ))) return;
+
+ LIST_FOR_EACH_ENTRY( view, &process->views, struct memory_view, entry )
+ if (req->addr >= view->base && req->addr < view->base + view->size) break;
+
+ if (&view->entry == &process->views)
+ {
+ set_error( STATUS_NOT_MAPPED_VIEW );
+ release_object( process );
+ return;
+ }
+
+ if (view->fd && (file = create_file_for_fd_obj( view->fd, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE )))
+ {
+ reply->handle = alloc_handle( process, file, GENERIC_READ, 0 );
+ release_object( file );
+ }
+
+ release_object( process );
+}
+
/* get a range of committed pages in a file mapping */
DECL_HANDLER(get_mapping_committed_range)
{
diff --git a/server/protocol.def b/server/protocol.def
index 957ef25f967..4888cb63506 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1539,6 +1539,15 @@ enum server_fd_type
@END
+/* Get file for a mapping */
+@REQ(get_mapping_file)
+ obj_handle_t process; /* process handle */
+ client_ptr_t addr; /* arbitrary address in view */
+@REPLY
+ obj_handle_t handle; /* handle to file */
+@END
+
+
/* Get a range of committed pages in a file mapping */
@REQ(get_mapping_committed_range)
client_ptr_t base; /* view base address */
--
2.29.2

View File

@@ -1,61 +0,0 @@
From 3c24fb315d12b0f5f052cfe5d885947adc5be75c Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Sun, 28 May 2017 10:30:43 +0200
Subject: [PATCH] ntdll/tests: Add tests for
NtQueryVirtualMemory(MemorySectionName).
---
dlls/ntdll/tests/info.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 974db1badf09..ff2d388399da 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -2239,6 +2239,8 @@ static void test_queryvirtualmemory(void)
char stackbuf[42];
HMODULE module;
void *user_shared_data = (void *)0x7ffe0000;
+ char buffer_name[sizeof(MEMORY_SECTION_NAME) + MAX_PATH * sizeof(WCHAR)];
+ MEMORY_SECTION_NAME *msn = (MEMORY_SECTION_NAME *)buffer_name;
module = GetModuleHandleA( "ntdll.dll" );
status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
@@ -2321,6 +2323,34 @@ static void test_queryvirtualmemory(void)
/* check error code when len is less than MEMORY_BASIC_INFORMATION size */
status = pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION) - 1, &readcount);
ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+
+ module = GetModuleHandleA( "ntdll.dll" );
+ memset(msn, 0, sizeof(*msn));
+ readcount = 0;
+ status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemorySectionName, msn, sizeof(*msn), &readcount);
+ ok( status == STATUS_BUFFER_OVERFLOW, "Expected STATUS_BUFFER_OVERFLOW, got %08x\n", status);
+ ok( readcount > 0, "Expected readcount to be > 0\n");
+
+ module = GetModuleHandleA( "ntdll.dll" );
+ memset(msn, 0, sizeof(*msn));
+ readcount = 0;
+ status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemorySectionName, msn, sizeof(*msn) - 1, &readcount);
+ ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+ ok( readcount > 0, "Expected readcount to be > 0\n");
+
+ module = GetModuleHandleA( "ntdll.dll" );
+ memset(msn, 0x55, sizeof(*msn));
+ memset(buffer_name, 0x77, sizeof(buffer_name));
+ readcount = 0;
+ status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemorySectionName, msn, sizeof(buffer_name), &readcount);
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+ ok( readcount > 0, "Expected readcount to be > 0\n");
+
+ memset(msn, 0, sizeof(*msn));
+ readcount = 0;
+ status = pNtQueryVirtualMemory(NtCurrentProcess(), &buffer_name, MemorySectionName, msn, sizeof(buffer_name), &readcount);
+ ok( status == STATUS_INVALID_ADDRESS, "Expected STATUS_INVALID_ADDRESS, got %08x\n", status);
+ ok( readcount == 0 || broken(readcount != 0) /* wow64 */, "Expected readcount to be 0\n");
}
static void test_affinity(void)
--
2.29.2

View File

@@ -1,57 +0,0 @@
From 6c2aad105cc878f2a0c3777a9a72fa63361d1ce8 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 28 May 2017 05:44:38 +0200
Subject: [PATCH] ntdll: Allow to query section names from other processes.
(v2)
---
dlls/psapi/tests/psapi_main.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index 3e211a771f93..40fd08e6adbc 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -410,6 +410,10 @@ static void test_GetMappedFileName(void)
char temp_path[MAX_PATH], file_name[MAX_PATH], map_name[MAX_PATH], device_name[MAX_PATH], drive[3];
WCHAR map_nameW[MAX_PATH], nt_map_name[MAX_PATH];
HANDLE hfile, hmap;
+ HANDLE current_process;
+
+ DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(),
+ GetCurrentProcess(), &current_process, 0, 0, DUPLICATE_SAME_ACCESS );
SetLastError(0xdeadbeef);
ret = GetMappedFileNameA(NULL, hMod, szMapPath, sizeof(szMapPath));
@@ -510,6 +514,20 @@ 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);
}
+ SetLastError(0xdeadbeef);
+ ret = GetMappedFileNameW(current_process, base, map_nameW, sizeof(map_nameW)/sizeof(map_nameW[0]));
+todo_wine {
+ ok(ret, "GetMappedFileNameW error %d\n", GetLastError());
+ ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
+}
+ if (nt_get_mapped_file_name(current_process, base, nt_map_name, sizeof(nt_map_name)/sizeof(nt_map_name[0])))
+ {
+ 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);
+ }
+
SetLastError(0xdeadbeef);
ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
todo_wine {
@@ -555,6 +573,7 @@ todo_wine
todo_wine
ok(GetLastError() == ERROR_FILE_INVALID, "expected ERROR_FILE_INVALID, got %d\n", GetLastError());
+ CloseHandle(current_process);
UnmapViewOfFile(base);
CloseHandle(hmap);
}
--
2.29.2

View File

@@ -1,26 +0,0 @@
From e2a538dcaee4c59055b877b63d143a93a6e6abdb Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Tue, 15 Dec 2020 00:20:43 +0300
Subject: [PATCH] server: Fix process access rights in get_mapping_file
handler.
---
server/mapping.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/mapping.c b/server/mapping.c
index d5f889771e50..3df9fb97a1c5 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -1146,7 +1146,7 @@ DECL_HANDLER(get_mapping_file)
struct process *process;
struct file *file;
- if (!(process = get_process_from_handle( req->process, 0 ))) return;
+ if (!(process = get_process_from_handle( req->process, PROCESS_QUERY_INFORMATION ))) return;
LIST_FOR_EACH_ENTRY( view, &process->views, struct memory_view, entry )
if (req->addr >= view->base && req->addr < view->base + view->size) break;
--
2.29.2

View File

@@ -3,4 +3,5 @@ Fixes: [27248] Implement K32GetMappedFileName
Depends: ntdll-NtDevicePath
Depends: ntdll-ForceBottomUpAlloc
Depends: ntdll-Junction_Points
# In the process of upstreaming.
Disabled: true