mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
ntdll-NtQueryVirtualMemory: Update patchset and return proper Nt paths.
This commit is contained in:
parent
70d09b1977
commit
43973275f2
@ -1,4 +1,4 @@
|
||||
From 02109af7e131fe02a3d7d467210a0ea6f64a334a Mon Sep 17 00:00:00 2001
|
||||
From ed78d7dd56fe29c5a310dc228576ce683730727a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Fri, 26 May 2017 05:17:17 +0200
|
||||
Subject: ntdll: Implement opening files through nt device paths.
|
||||
@ -9,10 +9,10 @@ Subject: ntdll: Implement opening files through nt device paths.
|
||||
2 files changed, 149 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
|
||||
index 5f3c2dfc31a..fc2b1f63752 100644
|
||||
index 32699fe3cc4..97b42398bb0 100644
|
||||
--- a/dlls/ntdll/directory.c
|
||||
+++ b/dlls/ntdll/directory.c
|
||||
@@ -2806,16 +2806,10 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *
|
||||
@@ -2811,16 +2811,10 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
@ -32,7 +32,7 @@ index 5f3c2dfc31a..fc2b1f63752 100644
|
||||
{
|
||||
static const WCHAR unixW[] = {'u','n','i','x'};
|
||||
static const WCHAR pipeW[] = {'p','i','p','e'};
|
||||
@@ -2932,6 +2926,128 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
|
||||
@@ -2937,6 +2931,128 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ index 5f3c2dfc31a..fc2b1f63752 100644
|
||||
+{
|
||||
+ static const WCHAR dosdevicesW[] = {'\\','D','o','s','D','e','v','i','c','e','s',0};
|
||||
+ UNICODE_STRING dosdevW;
|
||||
+ WCHAR symlinkW[MAX_PATH];
|
||||
+ WCHAR symlinkW[MAX_DIR_ENTRY_LEN];
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
+ NTSTATUS status;
|
||||
+ char data[1024];
|
||||
@ -89,7 +89,7 @@ index 5f3c2dfc31a..fc2b1f63752 100644
|
||||
+
|
||||
+ while (!NtQueryDirectoryObject( handle, info, sizeof(data), TRUE, FALSE, &ctx, NULL ))
|
||||
+ {
|
||||
+ if (read_nt_symlink( handle, &info->ObjectName, symlinkW, MAX_PATH )) continue;
|
||||
+ if (read_nt_symlink( handle, &info->ObjectName, symlinkW, MAX_DIR_ENTRY_LEN )) continue;
|
||||
+ if (strlenW( symlinkW ) != length || memicmpW( symlinkW, name, length )) continue;
|
||||
+ if (info->ObjectName.Length != 2 * sizeof(WCHAR) || info->ObjectName.Buffer[1] != ':') continue;
|
||||
+
|
||||
@ -162,10 +162,10 @@ index 5f3c2dfc31a..fc2b1f63752 100644
|
||||
/******************************************************************
|
||||
* RtlWow64EnableFsRedirection (NTDLL.@)
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 53504286366..43f56a7a40f 100644
|
||||
index 9de9009b10e..1751865a682 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -161,18 +161,22 @@ static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
|
||||
@@ -159,18 +159,22 @@ static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
|
||||
|
||||
static void create_file_test(void)
|
||||
{
|
||||
@ -189,7 +189,7 @@ index 53504286366..43f56a7a40f 100644
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
UNICODE_STRING nameW;
|
||||
@@ -352,6 +356,25 @@ static void create_file_test(void)
|
||||
@@ -351,6 +355,25 @@ static void create_file_test(void)
|
||||
status = pNtQueryFullAttributesFile( &attr, &info );
|
||||
ok( status == STATUS_OBJECT_NAME_INVALID,
|
||||
"query %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
|
||||
|
@ -1,275 +0,0 @@
|
||||
From 805c61e62ca54cb4b7240c2313bd0fc4c97a902f Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Wed, 1 Feb 2017 19:22:56 +0800
|
||||
Subject: ntdll: Implement NtQueryVirtualMemory(MemorySectionName). (v2)
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/info.c | 35 ++++++++++
|
||||
dlls/ntdll/virtual.c | 156 ++++++++++++++++++++++++++++++++++--------
|
||||
dlls/psapi/tests/psapi_main.c | 8 +--
|
||||
3 files changed, 164 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
|
||||
index 448bc64c28a..90eb5bea015 100644
|
||||
--- a/dlls/ntdll/tests/info.c
|
||||
+++ b/dlls/ntdll/tests/info.c
|
||||
@@ -1714,6 +1714,8 @@ static void test_queryvirtualmemory(void)
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
char stackbuf[42];
|
||||
HMODULE module;
|
||||
+ char buffer_name[sizeof(MEMORY_SECTION_NAME) + MAX_PATH * sizeof(WCHAR)];
|
||||
+ MEMORY_SECTION_NAME *msn = (MEMORY_SECTION_NAME *)buffer_name;
|
||||
|
||||
module = GetModuleHandleA( "ntdll.dll" );
|
||||
trace("Check flags of the PE header of NTDLL.DLL at %p\n", module);
|
||||
@@ -1787,6 +1789,39 @@ static void test_queryvirtualmemory(void)
|
||||
"mbi.Protect is 0x%x\n", mbi.Protect);
|
||||
}
|
||||
else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
|
||||
+
|
||||
+ trace("Check section name of NTDLL.DLL with invalid size\n");
|
||||
+ 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");
|
||||
+
|
||||
+ trace("Check section name of NTDLL.DLL with invalid size\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");
|
||||
+
|
||||
+ trace("Check section name of NTDLL.DLL\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");
|
||||
+ trace ("Section Name: %s\n", wine_dbgstr_w(msn->SectionFileName.Buffer));
|
||||
+
|
||||
+ trace("Check section name of non mapped memory\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)
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index e826fa03c0c..fcf7733b5a1 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -2240,41 +2240,17 @@ static int get_free_mem_state_callback( void *start, size_t size, void *arg )
|
||||
return 1;
|
||||
}
|
||||
|
||||
-#define UNIMPLEMENTED_INFO_CLASS(c) \
|
||||
- case c: \
|
||||
- FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
|
||||
- return STATUS_INVALID_INFO_CLASS
|
||||
-
|
||||
-/***********************************************************************
|
||||
- * NtQueryVirtualMemory (NTDLL.@)
|
||||
- * ZwQueryVirtualMemory (NTDLL.@)
|
||||
- */
|
||||
-NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
||||
- MEMORY_INFORMATION_CLASS info_class, PVOID buffer,
|
||||
- SIZE_T len, SIZE_T *res_len )
|
||||
+/* get basic information about a memory block */
|
||||
+static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
|
||||
+ MEMORY_BASIC_INFORMATION *info,
|
||||
+ SIZE_T len, SIZE_T *res_len )
|
||||
{
|
||||
struct file_view *view;
|
||||
char *base, *alloc_base = 0;
|
||||
struct list *ptr;
|
||||
SIZE_T size = 0;
|
||||
- MEMORY_BASIC_INFORMATION *info = buffer;
|
||||
sigset_t sigset;
|
||||
|
||||
- if (info_class != MemoryBasicInformation)
|
||||
- {
|
||||
- switch(info_class)
|
||||
- {
|
||||
- UNIMPLEMENTED_INFO_CLASS(MemoryWorkingSetList);
|
||||
- UNIMPLEMENTED_INFO_CLASS(MemorySectionName);
|
||||
- UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation);
|
||||
-
|
||||
- default:
|
||||
- FIXME("(%p,%p,info_class=%d,%p,%ld,%p) Unknown information class\n",
|
||||
- process, addr, info_class, buffer, len, res_len);
|
||||
- return STATUS_INVALID_INFO_CLASS;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
NTSTATUS status;
|
||||
@@ -2389,6 +2365,130 @@ NTSTATUS WINAPI NtQueryVirtualMemory( 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 )
|
||||
+{
|
||||
+ NTSTATUS status;
|
||||
+ char *base;
|
||||
+ struct file_view *view;
|
||||
+ sigset_t sigset;
|
||||
+
|
||||
+ if (!addr || !info || !res_len) return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ if (process != NtCurrentProcess())
|
||||
+ {
|
||||
+ FIXME("(%p,%p,%p,%ld,%p): semi-stub\n", process, addr, info, len, res_len);
|
||||
+ goto query_dll_name;
|
||||
+ }
|
||||
+
|
||||
+ status = STATUS_INVALID_ADDRESS;
|
||||
+
|
||||
+ base = ROUND_ADDR( addr, page_mask );
|
||||
+
|
||||
+ server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||
+ if ((view = VIRTUAL_FindView( base, 0 )))
|
||||
+ {
|
||||
+ if (view->mapping)
|
||||
+ {
|
||||
+ ANSI_STRING unix_filename;
|
||||
+ UNICODE_STRING nt_name;
|
||||
+
|
||||
+ status = server_get_unix_name( view->mapping, &unix_filename );
|
||||
+ if (status)
|
||||
+ {
|
||||
+ status = STATUS_FILE_INVALID;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ status = wine_unix_to_nt_file_name( &unix_filename, &nt_name );
|
||||
+ RtlFreeAnsiString( &unix_filename );
|
||||
+ if (status == STATUS_SUCCESS)
|
||||
+ {
|
||||
+ *res_len = sizeof(MEMORY_SECTION_NAME) + nt_name.MaximumLength;
|
||||
+ if (len >= *res_len)
|
||||
+ {
|
||||
+ info->SectionFileName.Length = nt_name.Length;
|
||||
+ info->SectionFileName.MaximumLength = nt_name.MaximumLength;
|
||||
+ info->SectionFileName.Buffer = (WCHAR *)(info + 1);
|
||||
+ memcpy(info->SectionFileName.Buffer, nt_name.Buffer, nt_name.MaximumLength);
|
||||
+ }
|
||||
+ else
|
||||
+ status = (len < sizeof(MEMORY_SECTION_NAME)) ? STATUS_INFO_LENGTH_MISMATCH : STATUS_BUFFER_OVERFLOW;
|
||||
+
|
||||
+ RtlFreeUnicodeString( &nt_name );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
+ if (status != STATUS_INVALID_ADDRESS) return status;
|
||||
+
|
||||
+query_dll_name:
|
||||
+ /* FIXME: this will return a DOS path. Windows returns an NT path. */
|
||||
+ SERVER_START_REQ(get_dll_info)
|
||||
+ {
|
||||
+ req->handle = wine_server_obj_handle( process );
|
||||
+ req->base_address = (ULONG_PTR)addr;
|
||||
+ wine_server_set_reply( req, info + 1,
|
||||
+ len > sizeof(MEMORY_SECTION_NAME) ? len - sizeof(MEMORY_SECTION_NAME) : 0 );
|
||||
+ status = wine_server_call( req );
|
||||
+
|
||||
+ if (status != STATUS_DLL_NOT_FOUND)
|
||||
+ {
|
||||
+ *res_len = sizeof(MEMORY_SECTION_NAME) + reply->filename_len + sizeof(WCHAR);
|
||||
+ if (status == STATUS_SUCCESS && len >= *res_len)
|
||||
+ {
|
||||
+ info->SectionFileName.Length = reply->filename_len;
|
||||
+ info->SectionFileName.MaximumLength = reply->filename_len + sizeof(WCHAR);
|
||||
+ info->SectionFileName.Buffer = (WCHAR *)(info + 1);
|
||||
+ *(WCHAR *)((char *)(info + 1) + reply->filename_len) = 0;
|
||||
+ }
|
||||
+ else if (status == STATUS_BUFFER_TOO_SMALL)
|
||||
+ status = (len < sizeof(MEMORY_SECTION_NAME)) ? STATUS_INFO_LENGTH_MISMATCH : STATUS_BUFFER_OVERFLOW;
|
||||
+ }
|
||||
+ else
|
||||
+ status = STATUS_INVALID_ADDRESS;
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+#define UNIMPLEMENTED_INFO_CLASS(c) \
|
||||
+ case c: \
|
||||
+ FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
|
||||
+ return STATUS_INVALID_INFO_CLASS
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * NtQueryVirtualMemory (NTDLL.@)
|
||||
+ * ZwQueryVirtualMemory (NTDLL.@)
|
||||
+ */
|
||||
+NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
||||
+ MEMORY_INFORMATION_CLASS info_class,
|
||||
+ PVOID buffer, SIZE_T len, SIZE_T *res_len )
|
||||
+{
|
||||
+ TRACE("(%p, %p, info_class=%d, %p, %ld, %p)\n",
|
||||
+ process, addr, info_class, buffer, len, res_len);
|
||||
+
|
||||
+ switch(info_class)
|
||||
+ {
|
||||
+ case MemoryBasicInformation:
|
||||
+ return get_basic_memory_info( 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(MemoryBasicVlmInformation);
|
||||
+
|
||||
+ default:
|
||||
+ FIXME("(%p,%p,info_class=%d,%p,%ld,%p) Unknown information class\n",
|
||||
+ process, addr, info_class, buffer, len, res_len);
|
||||
+ return STATUS_INVALID_INFO_CLASS;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
|
||||
/***********************************************************************
|
||||
* NtLockVirtualMemory (NTDLL.@)
|
||||
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
|
||||
index 7bc26fe8de9..ebb4e453e61 100644
|
||||
--- a/dlls/psapi/tests/psapi_main.c
|
||||
+++ b/dlls/psapi/tests/psapi_main.c
|
||||
@@ -332,14 +332,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",
|
||||
@@ -461,6 +454,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);
|
||||
}
|
||||
|
||||
--
|
||||
2.11.0
|
||||
|
@ -0,0 +1,91 @@
|
||||
From d3932f7ec92691aa77a75840883597a1c652f8c9 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 28 May 2017 09:04:10 +0200
|
||||
Subject: server: Store full path for ntdll/kernel32 dll.
|
||||
|
||||
---
|
||||
dlls/ntdll/loader.c | 8 ++++++++
|
||||
server/process.c | 23 +++++++++++++++++++++++
|
||||
server/protocol.def | 6 ++++++
|
||||
3 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index 518a99f5900..76d399a6cc6 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -3309,6 +3309,14 @@ void CDECL __wine_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir )
|
||||
RtlInitUnicodeString( &mod->FullDllName, buffer );
|
||||
RtlInitUnicodeString( &mod->BaseDllName, p );
|
||||
}
|
||||
+
|
||||
+ /* do the same for the wineserver dll list */
|
||||
+ SERVER_START_REQ( init_system_dir )
|
||||
+ {
|
||||
+ wine_server_add_data( req, system_dir.Buffer, system_dir.Length );
|
||||
+ wine_server_call( req );
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 5eabbbef8ef..9204c8954c7 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -49,6 +49,8 @@
|
||||
#include "user.h"
|
||||
#include "security.h"
|
||||
|
||||
+#include "wine/unicode.h"
|
||||
+
|
||||
/* process structure */
|
||||
|
||||
static struct list process_list = LIST_INIT(process_list);
|
||||
@@ -1502,6 +1504,27 @@ DECL_HANDLER(load_dll)
|
||||
if (mapping) release_object( mapping );
|
||||
}
|
||||
|
||||
+/* prepend the system dir to the name of the already created modules */
|
||||
+DECL_HANDLER(init_system_dir)
|
||||
+{
|
||||
+ struct process *process = current->process;
|
||||
+ struct process_dll *dll;
|
||||
+ WCHAR *filename, *p;
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry )
|
||||
+ {
|
||||
+ if (memchrW( dll->filename, '\\', dll->namelen / sizeof(WCHAR) )) continue;
|
||||
+ if (!(filename = mem_alloc( get_req_data_size() + dll->namelen + sizeof(WCHAR) ))) continue;
|
||||
+ memcpy( filename, get_req_data(), get_req_data_size() );
|
||||
+ p = filename + get_req_data_size() / sizeof(WCHAR);
|
||||
+ if (p > filename && p[-1] != '\\') *p++ = '\\';
|
||||
+ memcpy( p, dll->filename, dll->namelen );
|
||||
+ free( dll->filename );
|
||||
+ dll->namelen += (p - filename) * sizeof(WCHAR);
|
||||
+ dll->filename = filename;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* notify the server that a dll is being unloaded */
|
||||
DECL_HANDLER(unload_dll)
|
||||
{
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 7eaaec2b823..2f043bef50d 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -949,6 +949,12 @@ struct rawinput_device
|
||||
@END
|
||||
|
||||
|
||||
+/* Prepend the system directory to already loaded modules */
|
||||
+@REQ(init_system_dir)
|
||||
+ VARARG(sysdir,unicode_str); /* system directory */
|
||||
+@END
|
||||
+
|
||||
+
|
||||
/* Notify the server that a dll is being unloaded */
|
||||
@REQ(unload_dll)
|
||||
mod_handle_t base; /* base address */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -0,0 +1,103 @@
|
||||
From 0da9b9bdc6862bd2ebe58f64798f55dd1f83cf1b Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Sun, 28 May 2017 04:19:06 +0200
|
||||
Subject: ntdll: Split logic for MemoryBasicInformation into a separate
|
||||
function.
|
||||
|
||||
---
|
||||
dlls/ntdll/virtual.c | 64 ++++++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 37 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index e826fa03c0c..9f9ed6bfe7e 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -2240,41 +2240,18 @@ static int get_free_mem_state_callback( void *start, size_t size, void *arg )
|
||||
return 1;
|
||||
}
|
||||
|
||||
-#define UNIMPLEMENTED_INFO_CLASS(c) \
|
||||
- case c: \
|
||||
- FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
|
||||
- return STATUS_INVALID_INFO_CLASS
|
||||
|
||||
-/***********************************************************************
|
||||
- * NtQueryVirtualMemory (NTDLL.@)
|
||||
- * ZwQueryVirtualMemory (NTDLL.@)
|
||||
- */
|
||||
-NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
||||
- MEMORY_INFORMATION_CLASS info_class, PVOID buffer,
|
||||
- SIZE_T len, SIZE_T *res_len )
|
||||
+/* get basic information about a memory block */
|
||||
+static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
|
||||
+ MEMORY_BASIC_INFORMATION *info,
|
||||
+ SIZE_T len, SIZE_T *res_len )
|
||||
{
|
||||
struct file_view *view;
|
||||
char *base, *alloc_base = 0;
|
||||
struct list *ptr;
|
||||
SIZE_T size = 0;
|
||||
- MEMORY_BASIC_INFORMATION *info = buffer;
|
||||
sigset_t sigset;
|
||||
|
||||
- if (info_class != MemoryBasicInformation)
|
||||
- {
|
||||
- switch(info_class)
|
||||
- {
|
||||
- UNIMPLEMENTED_INFO_CLASS(MemoryWorkingSetList);
|
||||
- UNIMPLEMENTED_INFO_CLASS(MemorySectionName);
|
||||
- UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation);
|
||||
-
|
||||
- default:
|
||||
- FIXME("(%p,%p,info_class=%d,%p,%ld,%p) Unknown information class\n",
|
||||
- process, addr, info_class, buffer, len, res_len);
|
||||
- return STATUS_INVALID_INFO_CLASS;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
NTSTATUS status;
|
||||
@@ -2390,6 +2367,39 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
||||
}
|
||||
|
||||
|
||||
+#define UNIMPLEMENTED_INFO_CLASS(c) \
|
||||
+ case c: \
|
||||
+ FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
|
||||
+ return STATUS_INVALID_INFO_CLASS
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * NtQueryVirtualMemory (NTDLL.@)
|
||||
+ * ZwQueryVirtualMemory (NTDLL.@)
|
||||
+ */
|
||||
+NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
||||
+ MEMORY_INFORMATION_CLASS info_class,
|
||||
+ PVOID buffer, SIZE_T len, SIZE_T *res_len )
|
||||
+{
|
||||
+ TRACE("(%p, %p, info_class=%d, %p, %ld, %p)\n",
|
||||
+ process, addr, info_class, buffer, len, res_len);
|
||||
+
|
||||
+ switch(info_class)
|
||||
+ {
|
||||
+ case MemoryBasicInformation:
|
||||
+ return get_basic_memory_info( process, addr, buffer, len, res_len );
|
||||
+
|
||||
+ UNIMPLEMENTED_INFO_CLASS(MemoryWorkingSetList);
|
||||
+ UNIMPLEMENTED_INFO_CLASS(MemorySectionName);
|
||||
+ UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation);
|
||||
+
|
||||
+ default:
|
||||
+ FIXME("(%p,%p,info_class=%d,%p,%ld,%p) Unknown information class\n",
|
||||
+ process, addr, info_class, buffer, len, res_len);
|
||||
+ return STATUS_INVALID_INFO_CLASS;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
/***********************************************************************
|
||||
* NtLockVirtualMemory (NTDLL.@)
|
||||
* ZwLockVirtualMemory (NTDLL.@)
|
||||
--
|
||||
2.12.2
|
||||
|
@ -0,0 +1,176 @@
|
||||
From 60d3299d2e2924023542dcb7245ddfd2f901b319 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Sun, 28 May 2017 05:19:30 +0200
|
||||
Subject: ntdll: Implement NtQueryVirtualMemory(MemorySectionName). (v3)
|
||||
|
||||
Contains several improvements by Sebastian Lackner <sebastian@fds-team.de>.
|
||||
---
|
||||
dlls/ntdll/virtual.c | 109 +++++++++++++++++++++++++++++++++++++++++-
|
||||
dlls/psapi/tests/psapi_main.c | 8 +---
|
||||
2 files changed, 109 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index 9f9ed6bfe7e..7d419de07b8 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -2241,6 +2241,33 @@ static int get_free_mem_state_callback( void *start, size_t size, void *arg )
|
||||
}
|
||||
|
||||
|
||||
+/* get the section mapping handle */
|
||||
+static NTSTATUS get_section_mapping( HANDLE process, LPCVOID addr, HANDLE *mapping )
|
||||
+{
|
||||
+ struct file_view *view;
|
||||
+ NTSTATUS status = STATUS_INVALID_ADDRESS;
|
||||
+ sigset_t sigset;
|
||||
+ char *base;
|
||||
+
|
||||
+ if (process != NtCurrentProcess())
|
||||
+ {
|
||||
+ FIXME( "query section mapping from other process not implemented yet\n" );
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+ }
|
||||
+
|
||||
+ base = ROUND_ADDR( addr, page_mask );
|
||||
+
|
||||
+ server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||
+ if ((view = VIRTUAL_FindView( base, 0 )) && view->mapping)
|
||||
+ {
|
||||
+ status = NtDuplicateObject( NtCurrentProcess(), view->mapping, NtCurrentProcess(),
|
||||
+ mapping, 0, 0, DUP_HANDLE_SAME_ACCESS );
|
||||
+ }
|
||||
+ server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* get basic information about a memory block */
|
||||
static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
|
||||
MEMORY_BASIC_INFORMATION *info,
|
||||
@@ -2367,6 +2394,84 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
|
||||
}
|
||||
|
||||
|
||||
+/* 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;
|
||||
+ ANSI_STRING unix_name;
|
||||
+ data_size_t size = 1024;
|
||||
+ WCHAR *name = NULL;
|
||||
+ NTSTATUS status;
|
||||
+ HANDLE mapping;
|
||||
+
|
||||
+ if (!addr || !info || !res_len) return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ if (!(status = get_section_mapping( process, addr, &mapping )))
|
||||
+ {
|
||||
+ status = server_get_unix_name( mapping, &unix_name );
|
||||
+ close_handle( mapping );
|
||||
+ if (!status)
|
||||
+ {
|
||||
+ status = wine_unix_to_nt_file_name( &unix_name, &nt_name );
|
||||
+ RtlFreeAnsiString( &unix_name );
|
||||
+ }
|
||||
+ if (!status) goto found;
|
||||
+ if (status == STATUS_OBJECT_TYPE_MISMATCH) status = STATUS_FILE_INVALID;
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, (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;
|
||||
+ }
|
||||
+ RtlFreeHeap( GetProcessHeap(), 0, name );
|
||||
+ if (status == STATUS_DLL_NOT_FOUND) return STATUS_INVALID_ADDRESS;
|
||||
+ if (status != STATUS_BUFFER_TOO_SMALL) return status;
|
||||
+ }
|
||||
+
|
||||
+ if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
|
||||
+ {
|
||||
+ RtlFreeHeap( GetProcessHeap(), 0, name );
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+found:
|
||||
+ *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;
|
||||
+
|
||||
+ RtlFreeHeap( GetProcessHeap(), 0, name );
|
||||
+ RtlFreeUnicodeString( &nt_name );
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+
|
||||
#define UNIMPLEMENTED_INFO_CLASS(c) \
|
||||
case c: \
|
||||
FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \
|
||||
@@ -2388,8 +2493,10 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
|
||||
case MemoryBasicInformation:
|
||||
return get_basic_memory_info( 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 e35a7b694cb..56bf11a9a85 100644
|
||||
--- a/dlls/psapi/tests/psapi_main.c
|
||||
+++ b/dlls/psapi/tests/psapi_main.c
|
||||
@@ -330,14 +330,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",
|
||||
@@ -459,6 +452,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);
|
||||
}
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -0,0 +1,65 @@
|
||||
From f16058fd2551d42166df18a9d2dd784f57b35144 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Sun, 28 May 2017 10:30:43 +0200
|
||||
Subject: ntdll/tests: Add tests for NtQueryVirtualMemory(MemorySectionName).
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/info.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
|
||||
index f1de20698a5..1b54bd41320 100644
|
||||
--- a/dlls/ntdll/tests/info.c
|
||||
+++ b/dlls/ntdll/tests/info.c
|
||||
@@ -1751,6 +1751,8 @@ static void test_queryvirtualmemory(void)
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
char stackbuf[42];
|
||||
HMODULE module;
|
||||
+ char buffer_name[sizeof(MEMORY_SECTION_NAME) + MAX_PATH * sizeof(WCHAR)];
|
||||
+ MEMORY_SECTION_NAME *msn = (MEMORY_SECTION_NAME *)buffer_name;
|
||||
|
||||
module = GetModuleHandleA( "ntdll.dll" );
|
||||
trace("Check flags of the PE header of NTDLL.DLL at %p\n", module);
|
||||
@@ -1824,6 +1826,39 @@ static void test_queryvirtualmemory(void)
|
||||
"mbi.Protect is 0x%x\n", mbi.Protect);
|
||||
}
|
||||
else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */
|
||||
+
|
||||
+ trace("Check section name of NTDLL.DLL with invalid size\n");
|
||||
+ 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");
|
||||
+
|
||||
+ trace("Check section name of NTDLL.DLL with invalid size\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");
|
||||
+
|
||||
+ trace("Check section name of NTDLL.DLL\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");
|
||||
+ trace ("Section Name: %s\n", wine_dbgstr_w(msn->SectionFileName.Buffer));
|
||||
+
|
||||
+ trace("Check section name of non mapped memory\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.12.2
|
||||
|
@ -0,0 +1,60 @@
|
||||
From ace7d4f4d6f6de1e2ba60c43d8e79d2b54d03523 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 28 May 2017 10:33:40 +0200
|
||||
Subject: ntdll/tests: Add test to ensure section name is full path.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/info.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
|
||||
index 1b54bd41320..4bd4b755de5 100644
|
||||
--- a/dlls/ntdll/tests/info.c
|
||||
+++ b/dlls/ntdll/tests/info.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <winnls.h>
|
||||
#include <stdio.h>
|
||||
|
||||
+static NTSTATUS (WINAPI * pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
|
||||
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
||||
static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*);
|
||||
static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG);
|
||||
@@ -66,6 +67,7 @@ static BOOL InitFunctionPtrs(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ NTDLL_GET_PROC(RtlDowncaseUnicodeString);
|
||||
NTDLL_GET_PROC(NtQuerySystemInformation);
|
||||
NTDLL_GET_PROC(NtPowerInformation);
|
||||
NTDLL_GET_PROC(NtQueryInformationProcess);
|
||||
@@ -1745,6 +1747,7 @@ static void test_queryvirtualmemory(void)
|
||||
{
|
||||
NTSTATUS status;
|
||||
SIZE_T readcount;
|
||||
+ static const WCHAR windowsW[] = {'w','i','n','d','o','w','s'};
|
||||
static const char teststring[] = "test string";
|
||||
static char datatestbuf[42] = "abc";
|
||||
static char rwtestbuf[42];
|
||||
@@ -1753,6 +1756,8 @@ static void test_queryvirtualmemory(void)
|
||||
HMODULE module;
|
||||
char buffer_name[sizeof(MEMORY_SECTION_NAME) + MAX_PATH * sizeof(WCHAR)];
|
||||
MEMORY_SECTION_NAME *msn = (MEMORY_SECTION_NAME *)buffer_name;
|
||||
+ BOOL found;
|
||||
+ int i;
|
||||
|
||||
module = GetModuleHandleA( "ntdll.dll" );
|
||||
trace("Check flags of the PE header of NTDLL.DLL at %p\n", module);
|
||||
@@ -1852,6 +1857,10 @@ static void test_queryvirtualmemory(void)
|
||||
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
|
||||
ok( readcount > 0, "Expected readcount to be > 0\n");
|
||||
trace ("Section Name: %s\n", wine_dbgstr_w(msn->SectionFileName.Buffer));
|
||||
+ pRtlDowncaseUnicodeString( &msn->SectionFileName, &msn->SectionFileName, FALSE );
|
||||
+ for (found = FALSE, i = (msn->SectionFileName.Length - sizeof(windowsW)) / sizeof(WCHAR); i >= 0; i--)
|
||||
+ found |= !memcmp( &msn->SectionFileName.Buffer[i], windowsW, sizeof(windowsW) );
|
||||
+ ok( found, "Section name does not contain \"Windows\"\n");
|
||||
|
||||
trace("Check section name of non mapped memory\n");
|
||||
memset(msn, 0, sizeof(*msn));
|
||||
--
|
||||
2.12.2
|
||||
|
@ -0,0 +1,204 @@
|
||||
From d98c5a09b04c6082a085e313284379e70bb108b5 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 28 May 2017 05:44:38 +0200
|
||||
Subject: ntdll: Allow to query section names from other processes.
|
||||
|
||||
---
|
||||
dlls/ntdll/ntdll_misc.h | 1 +
|
||||
dlls/ntdll/server.c | 12 ++++++++++++
|
||||
dlls/ntdll/virtual.c | 18 ++++++++++++++----
|
||||
dlls/psapi/tests/psapi_main.c | 19 +++++++++++++++++++
|
||||
server/protocol.def | 13 +++++++++++++
|
||||
server/thread.c | 9 +++++++++
|
||||
6 files changed, 68 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index 5e4c39e8bd6..0e7749af4c3 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -161,6 +161,7 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
|
||||
UINT disposition ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* virtual memory */
|
||||
+extern NTSTATUS virtual_get_section_mapping( HANDLE process, LPCVOID addr, HANDLE *mapping ) DECLSPEC_HIDDEN;
|
||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size ) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
|
||||
index c02a12ab19a..fa2802beb6b 100644
|
||||
--- a/dlls/ntdll/server.c
|
||||
+++ b/dlls/ntdll/server.c
|
||||
@@ -464,6 +464,18 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
|
||||
}
|
||||
break;
|
||||
}
|
||||
+ case APC_VIRTUAL_SECTION:
|
||||
+ {
|
||||
+ HANDLE mapping;
|
||||
+ addr = wine_server_get_ptr( call->virtual_section.addr );
|
||||
+ if ((ULONG_PTR)addr == call->virtual_section.addr)
|
||||
+ {
|
||||
+ result->virtual_section.status = virtual_get_section_mapping( NtCurrentProcess(), addr, &mapping );
|
||||
+ result->virtual_section.mapping = wine_server_obj_handle( mapping );
|
||||
+ }
|
||||
+ else result->virtual_section.status = STATUS_WORKING_SET_LIMIT_RANGE;
|
||||
+ break;
|
||||
+ }
|
||||
case APC_VIRTUAL_PROTECT:
|
||||
result->type = call->type;
|
||||
addr = wine_server_get_ptr( call->virtual_protect.addr );
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index 60f5f2946ba..80700437a45 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -2242,7 +2242,7 @@ static int get_free_mem_state_callback( void *start, size_t size, void *arg )
|
||||
|
||||
|
||||
/* get the section mapping handle */
|
||||
-static NTSTATUS get_section_mapping( HANDLE process, LPCVOID addr, HANDLE *mapping )
|
||||
+NTSTATUS virtual_get_section_mapping( HANDLE process, LPCVOID addr, HANDLE *mapping )
|
||||
{
|
||||
struct file_view *view;
|
||||
NTSTATUS status = STATUS_INVALID_ADDRESS;
|
||||
@@ -2251,8 +2251,18 @@ static NTSTATUS get_section_mapping( HANDLE process, LPCVOID addr, HANDLE *mappi
|
||||
|
||||
if (process != NtCurrentProcess())
|
||||
{
|
||||
- FIXME( "query section mapping from other process not implemented yet\n" );
|
||||
- return STATUS_NOT_IMPLEMENTED;
|
||||
+ apc_call_t call;
|
||||
+ apc_result_t result;
|
||||
+
|
||||
+ memset( &call, 0, sizeof(call) );
|
||||
+
|
||||
+ call.virtual_section.type = APC_VIRTUAL_SECTION;
|
||||
+ call.virtual_section.addr = wine_server_client_ptr( addr );
|
||||
+ status = server_queue_process_apc( process, &call, &result );
|
||||
+ if (status != STATUS_SUCCESS) return status;
|
||||
+
|
||||
+ *mapping = wine_server_ptr_handle( result.virtual_section.mapping );
|
||||
+ return result.virtual_section.status;
|
||||
}
|
||||
|
||||
base = ROUND_ADDR( addr, page_mask );
|
||||
@@ -2408,7 +2418,7 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
|
||||
|
||||
if (!addr || !info || !res_len) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
- if (!(status = get_section_mapping( process, addr, &mapping )))
|
||||
+ if (!(status = virtual_get_section_mapping( process, addr, &mapping )))
|
||||
{
|
||||
status = server_get_unix_name( mapping, &unix_name );
|
||||
close_handle( mapping );
|
||||
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
|
||||
index 56bf11a9a85..23025eedab3 100644
|
||||
--- a/dlls/psapi/tests/psapi_main.c
|
||||
+++ b/dlls/psapi/tests/psapi_main.c
|
||||
@@ -356,6 +356,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(), ¤t_process, 0, 0, DUPLICATE_SAME_ACCESS );
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameA(NULL, hMod, szMapPath, sizeof(szMapPath));
|
||||
@@ -457,6 +461,20 @@ todo_wine
|
||||
}
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
+ ret = pGetMappedFileNameW(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 = pGetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
|
||||
todo_wine {
|
||||
ok(ret, "GetMappedFileName error %d\n", GetLastError());
|
||||
@@ -501,6 +519,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);
|
||||
}
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index 2f043bef50d..7f509dce29c 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -448,6 +448,7 @@ enum apc_type
|
||||
APC_VIRTUAL_ALLOC,
|
||||
APC_VIRTUAL_FREE,
|
||||
APC_VIRTUAL_QUERY,
|
||||
+ APC_VIRTUAL_SECTION,
|
||||
APC_VIRTUAL_PROTECT,
|
||||
APC_VIRTUAL_FLUSH,
|
||||
APC_VIRTUAL_LOCK,
|
||||
@@ -506,6 +507,12 @@ typedef union
|
||||
} virtual_query;
|
||||
struct
|
||||
{
|
||||
+ enum apc_type type; /* APC_VIRTUAL_SECTION */
|
||||
+ int __pad;
|
||||
+ client_ptr_t addr; /* requested address */
|
||||
+ } virtual_section;
|
||||
+ struct
|
||||
+ {
|
||||
enum apc_type type; /* APC_VIRTUAL_PROTECT */
|
||||
unsigned int prot; /* new protection flags */
|
||||
client_ptr_t addr; /* requested address */
|
||||
@@ -597,6 +604,12 @@ typedef union
|
||||
} virtual_query;
|
||||
struct
|
||||
{
|
||||
+ enum apc_type type; /* APC_VIRTUAL_SECTION */
|
||||
+ unsigned int status; /* status returned by call */
|
||||
+ obj_handle_t mapping; /* resulting mapping */
|
||||
+ } virtual_section;
|
||||
+ struct
|
||||
+ {
|
||||
enum apc_type type; /* APC_VIRTUAL_PROTECT */
|
||||
unsigned int status; /* status returned by call */
|
||||
client_ptr_t addr; /* resulting address */
|
||||
diff --git a/server/thread.c b/server/thread.c
|
||||
index 10a5bf14b62..dc3323fe4dc 100644
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -1481,6 +1481,14 @@ DECL_HANDLER(select)
|
||||
apc->result.create_thread.handle = handle;
|
||||
clear_error(); /* ignore errors from the above calls */
|
||||
}
|
||||
+ else if (apc->result.type == APC_VIRTUAL_SECTION) /* duplicate the handle to the caller process */
|
||||
+ {
|
||||
+ obj_handle_t mapping = duplicate_handle( current->process, apc->result.virtual_section.mapping,
|
||||
+ apc->caller->process, 0, 0, DUP_HANDLE_SAME_ACCESS );
|
||||
+ close_handle( current->process, apc->result.virtual_section.mapping );
|
||||
+ apc->result.virtual_section.mapping = mapping;
|
||||
+ clear_error(); /* ignore errors from the above calls */
|
||||
+ }
|
||||
else if (apc->result.type == APC_ASYNC_IO)
|
||||
{
|
||||
if (apc->owner)
|
||||
@@ -1541,6 +1549,7 @@ DECL_HANDLER(queue_apc)
|
||||
process = get_process_from_handle( req->handle, PROCESS_VM_OPERATION );
|
||||
break;
|
||||
case APC_VIRTUAL_QUERY:
|
||||
+ case APC_VIRTUAL_SECTION:
|
||||
process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION );
|
||||
break;
|
||||
case APC_MAP_VIEW:
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,12 +1,12 @@
|
||||
From 2cd035059cfc7c77ca63c3e46fc85dde1a2a7ccc Mon Sep 17 00:00:00 2001
|
||||
From d0f1010e925785febb306d0fd22b70165585b0a2 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Wed, 16 Mar 2016 20:23:28 +0800
|
||||
Subject: kernel32: Implement K32GetMappedFileName. (v2)
|
||||
|
||||
---
|
||||
dlls/kernel32/virtual.c | 67 +++++++++++++++++++++++++++++++++++--------
|
||||
dlls/psapi/tests/psapi_main.c | 21 +++-----------
|
||||
2 files changed, 59 insertions(+), 29 deletions(-)
|
||||
dlls/psapi/tests/psapi_main.c | 25 ++++------------
|
||||
2 files changed, 60 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/virtual.c b/dlls/kernel32/virtual.c
|
||||
index 5733a42bbf5..efdddfafc97 100644
|
||||
@ -98,10 +98,10 @@ index 5733a42bbf5..efdddfafc97 100644
|
||||
|
||||
/***********************************************************************
|
||||
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
|
||||
index ebb4e453e61..375bffb9c4a 100644
|
||||
index 23025eedab3..0751bb24fb8 100644
|
||||
--- a/dlls/psapi/tests/psapi_main.c
|
||||
+++ b/dlls/psapi/tests/psapi_main.c
|
||||
@@ -362,18 +362,15 @@ static void test_GetMappedFileName(void)
|
||||
@@ -364,27 +364,22 @@ static void test_GetMappedFileName(void)
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameA(NULL, hMod, szMapPath, sizeof(szMapPath));
|
||||
ok(!ret, "GetMappedFileName should fail\n");
|
||||
@ -120,15 +120,16 @@ index ebb4e453e61..375bffb9c4a 100644
|
||||
ok( ret || broken(GetLastError() == ERROR_UNEXP_NET_ERR), /* win2k */
|
||||
"GetMappedFileNameA failed with error %u\n", GetLastError() );
|
||||
if (ret)
|
||||
@@ -382,7 +379,6 @@ todo_wine
|
||||
todo_wine
|
||||
{
|
||||
ok(ret == strlen(szMapPath), "szMapPath=\"%s\" ret=%d\n", szMapPath, ret);
|
||||
- todo_wine
|
||||
ok(szMapPath[0] == '\\', "szMapPath=\"%s\"\n", szMapPath);
|
||||
szMapBaseName = strrchr(szMapPath, '\\'); /* That's close enough for us */
|
||||
- todo_wine
|
||||
ok(szMapBaseName && *szMapBaseName, "szMapPath=\"%s\"\n", szMapPath);
|
||||
if (szMapBaseName)
|
||||
{
|
||||
@@ -420,36 +416,31 @@ todo_wine
|
||||
@@ -422,36 +417,31 @@ todo_wine
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameA(GetCurrentProcess(), base, map_name, 0);
|
||||
ok(!ret, "GetMappedFileName should fail\n");
|
||||
@ -167,7 +168,19 @@ index ebb4e453e61..375bffb9c4a 100644
|
||||
if (nt_get_mapped_file_name(GetCurrentProcess(), 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);
|
||||
@@ -460,16 +451,14 @@ todo_wine
|
||||
@@ -462,10 +452,9 @@ todo_wine
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameW(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);
|
||||
@@ -476,16 +465,14 @@ todo_wine
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
|
||||
@ -185,7 +198,7 @@ index ebb4e453e61..375bffb9c4a 100644
|
||||
ok(GetLastError() == ERROR_UNEXP_NET_ERR, "expected ERROR_UNEXP_NET_ERR, got %d\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
@@ -481,7 +470,6 @@ todo_wine
|
||||
@@ -497,7 +484,6 @@ todo_wine
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameA(0, base, map_name, sizeof(map_name));
|
||||
ok(!ret, "GetMappedFileName should fail\n");
|
||||
@ -193,15 +206,15 @@ index ebb4e453e61..375bffb9c4a 100644
|
||||
ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
|
||||
|
||||
UnmapViewOfFile(base);
|
||||
@@ -500,7 +488,6 @@ todo_wine
|
||||
@@ -516,7 +502,6 @@ todo_wine
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pGetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
|
||||
ok(!ret, "GetMappedFileName should fail\n");
|
||||
-todo_wine
|
||||
ok(GetLastError() == ERROR_FILE_INVALID, "expected ERROR_FILE_INVALID, got %d\n", GetLastError());
|
||||
|
||||
UnmapViewOfFile(base);
|
||||
@@ -549,7 +536,7 @@ static void test_GetProcessImageFileName(void)
|
||||
CloseHandle(current_process);
|
||||
@@ -566,7 +551,7 @@ static void test_GetProcessImageFileName(void)
|
||||
if(ret && ret1)
|
||||
{
|
||||
/* Windows returns 2*strlen-1 */
|
||||
@ -211,5 +224,5 @@ index ebb4e453e61..375bffb9c4a 100644
|
||||
}
|
||||
|
||||
--
|
||||
2.11.0
|
||||
2.12.2
|
||||
|
@ -0,0 +1,163 @@
|
||||
From 2ea8d5c16d9ab714f8cecde6cd6b2ff51738535a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 28 May 2017 11:17:26 +0200
|
||||
Subject: ntdll: Resolve drive symlinks before returning section name.
|
||||
|
||||
---
|
||||
dlls/ntdll/directory.c | 2 +-
|
||||
dlls/ntdll/ntdll_misc.h | 1 +
|
||||
dlls/ntdll/virtual.c | 38 ++++++++++++++++++++++++++++++++------
|
||||
dlls/psapi/tests/psapi_main.c | 6 +-----
|
||||
4 files changed, 35 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
|
||||
index 97b42398bb0..c0b2a1ea83e 100644
|
||||
--- a/dlls/ntdll/directory.c
|
||||
+++ b/dlls/ntdll/directory.c
|
||||
@@ -2932,7 +2932,7 @@ static NTSTATUS nt_to_unix_file_name_internal( const UNICODE_STRING *nameW, ANSI
|
||||
}
|
||||
|
||||
/* read the contents of an NT symlink object */
|
||||
-static NTSTATUS read_nt_symlink( HANDLE root, UNICODE_STRING *name, WCHAR *target, size_t length )
|
||||
+NTSTATUS read_nt_symlink( HANDLE root, UNICODE_STRING *name, WCHAR *target, size_t length )
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING targetW;
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index 0e7749af4c3..e56a781fc29 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -161,6 +161,7 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
|
||||
UINT disposition ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* virtual memory */
|
||||
+extern NTSTATUS read_nt_symlink( HANDLE root, UNICODE_STRING *name, WCHAR *target, size_t length ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_get_section_mapping( HANDLE process, LPCVOID addr, HANDLE *mapping ) DECLSPEC_HIDDEN;
|
||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
|
||||
index 80700437a45..1f3be783fb3 100644
|
||||
--- a/dlls/ntdll/virtual.c
|
||||
+++ b/dlls/ntdll/virtual.c
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "wine/library.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/exception.h"
|
||||
+#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ntdll_misc.h"
|
||||
@@ -146,6 +147,8 @@ static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
|
||||
|
||||
#define VIRTUAL_HEAP_SIZE (sizeof(void*)*1024*1024)
|
||||
|
||||
+#define MAX_DIR_ENTRY_LEN 255 /* max length of a directory entry in chars */
|
||||
+
|
||||
static HANDLE virtual_heap;
|
||||
static void *preload_reserve_start;
|
||||
static void *preload_reserve_end;
|
||||
@@ -2409,12 +2412,15 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
|
||||
MEMORY_SECTION_NAME *info,
|
||||
SIZE_T len, SIZE_T *res_len )
|
||||
{
|
||||
+ static const WCHAR dosprefixW[] = {'\\','?','?','\\'};
|
||||
+ WCHAR symlinkW[MAX_DIR_ENTRY_LEN] = {0};
|
||||
UNICODE_STRING nt_name;
|
||||
ANSI_STRING unix_name;
|
||||
data_size_t size = 1024;
|
||||
- WCHAR *name = NULL;
|
||||
+ WCHAR *ptr, *name = NULL;
|
||||
NTSTATUS status;
|
||||
HANDLE mapping;
|
||||
+ size_t offset = 0;
|
||||
|
||||
if (!addr || !info || !res_len) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
@@ -2464,14 +2470,34 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
|
||||
}
|
||||
|
||||
found:
|
||||
- *res_len = sizeof(MEMORY_SECTION_NAME) + nt_name.Length + sizeof(WCHAR);
|
||||
+ if (nt_name.Length >= sizeof(dosprefixW) &&
|
||||
+ !memcmp( nt_name.Buffer, dosprefixW, sizeof(dosprefixW) ))
|
||||
+ {
|
||||
+ UNICODE_STRING device_name = nt_name;
|
||||
+ offset = sizeof(dosprefixW) / sizeof(WCHAR);
|
||||
+ while (offset * sizeof(WCHAR) < nt_name.Length && nt_name.Buffer[ offset ] != '\\') offset++;
|
||||
+ device_name.Length = offset * sizeof(WCHAR);
|
||||
+ if (read_nt_symlink( NULL, &device_name, symlinkW, MAX_DIR_ENTRY_LEN ))
|
||||
+ {
|
||||
+ symlinkW[0] = 0;
|
||||
+ offset = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *res_len = sizeof(MEMORY_SECTION_NAME) + strlenW(symlinkW) * sizeof(WCHAR) +
|
||||
+ nt_name.Length - offset * sizeof(WCHAR) + sizeof(WCHAR);
|
||||
if (len >= *res_len)
|
||||
{
|
||||
- info->SectionFileName.Length = nt_name.Length;
|
||||
- info->SectionFileName.MaximumLength = nt_name.Length + sizeof(WCHAR);
|
||||
+ info->SectionFileName.Length = strlenW(symlinkW) * sizeof(WCHAR) +
|
||||
+ nt_name.Length - offset * sizeof(WCHAR);
|
||||
+ info->SectionFileName.MaximumLength = info->SectionFileName.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;
|
||||
+
|
||||
+ ptr = (WCHAR *)(info + 1);
|
||||
+ strcpyW( ptr, symlinkW );
|
||||
+ ptr += strlenW(symlinkW);
|
||||
+ memcpy( ptr, nt_name.Buffer + offset, nt_name.Length - offset * sizeof(WCHAR) );
|
||||
+ ptr[ nt_name.Length / sizeof(WCHAR) - offset ] = 0;
|
||||
}
|
||||
else
|
||||
status = (len < sizeof(MEMORY_SECTION_NAME)) ? STATUS_INFO_LENGTH_MISMATCH : STATUS_BUFFER_OVERFLOW;
|
||||
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
|
||||
index 0751bb24fb8..dd592a9ab21 100644
|
||||
--- a/dlls/psapi/tests/psapi_main.c
|
||||
+++ b/dlls/psapi/tests/psapi_main.c
|
||||
@@ -434,7 +434,6 @@ static void test_GetMappedFileName(void)
|
||||
ret = pGetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
|
||||
ok(ret, "GetMappedFileName error %d\n", GetLastError());
|
||||
ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
|
||||
-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);
|
||||
@@ -446,7 +445,6 @@ 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);
|
||||
}
|
||||
|
||||
@@ -459,7 +457,6 @@ 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);
|
||||
}
|
||||
|
||||
@@ -467,7 +464,6 @@ todo_wine
|
||||
ret = pGetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
|
||||
ok(ret, "GetMappedFileName error %d\n", GetLastError());
|
||||
ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
|
||||
-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);
|
||||
@@ -552,7 +548,7 @@ static void test_GetProcessImageFileName(void)
|
||||
{
|
||||
/* Windows returns 2*strlen-1 */
|
||||
ok(ret >= strlen(szImgPath), "szImgPath=\"%s\" ret=%d\n", szImgPath, ret);
|
||||
- todo_wine ok(!strcmp(szImgPath, szMapPath), "szImgPath=\"%s\" szMapPath=\"%s\"\n", szImgPath, szMapPath);
|
||||
+ ok(!strcmp(szImgPath, szMapPath), "szImgPath=\"%s\" szMapPath=\"%s\"\n", szImgPath, szMapPath);
|
||||
}
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1 +1,2 @@
|
||||
Fixes: [23999] Implement MemorySectionName class in NtQueryVirtualMemory
|
||||
Depends: ntdll-NtDevicePath
|
||||
|
@ -2373,6 +2373,13 @@ if test "$enable_ntdll_NtSuspendProcess" -eq 1; then
|
||||
enable_kernel32_K32GetPerformanceInfo=1
|
||||
fi
|
||||
|
||||
if test "$enable_ntdll_NtQueryVirtualMemory" -eq 1; then
|
||||
if test "$enable_ntdll_NtDevicePath" -gt 1; then
|
||||
abort "Patchset ntdll-NtDevicePath disabled, but ntdll-NtQueryVirtualMemory depends on that."
|
||||
fi
|
||||
enable_ntdll_NtDevicePath=1
|
||||
fi
|
||||
|
||||
if test "$enable_ntdll_NtDevicePath" -eq 1; then
|
||||
if test "$enable_ntdll_Pipe_SpecialCharacters" -gt 1; then
|
||||
abort "Patchset ntdll-Pipe_SpecialCharacters disabled, but ntdll-NtDevicePath depends on that."
|
||||
@ -5754,19 +5761,36 @@ fi
|
||||
|
||||
# Patchset ntdll-NtQueryVirtualMemory
|
||||
# |
|
||||
# | This patchset has the following (direct or indirect) dependencies:
|
||||
# | * ntdll-Pipe_SpecialCharacters, ntdll-NtDevicePath
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#23999] Implement MemorySectionName class in NtQueryVirtualMemory
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/virtual.c, dlls/ntdll/tests/info.c, dlls/ntdll/virtual.c, dlls/psapi/tests/psapi_main.c
|
||||
# | * dlls/kernel32/virtual.c, dlls/ntdll/directory.c, dlls/ntdll/loader.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/server.c,
|
||||
# | dlls/ntdll/tests/info.c, dlls/ntdll/virtual.c, dlls/psapi/tests/psapi_main.c, server/process.c, server/protocol.def,
|
||||
# | server/thread.c
|
||||
# |
|
||||
if test "$enable_ntdll_NtQueryVirtualMemory" -eq 1; then
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0001-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0002-kernel32-Implement-K32GetMappedFileName.-v2.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0003-ntdll-Fix-error-code-when-querying-too-large-memory-.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0001-server-Store-full-path-for-ntdll-kernel32-dll.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0002-ntdll-Split-logic-for-MemoryBasicInformation-into-a-.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0003-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0004-ntdll-tests-Add-tests-for-NtQueryVirtualMemory-Memor.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0005-ntdll-tests-Add-test-to-ensure-section-name-is-full-.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0006-ntdll-Allow-to-query-section-names-from-other-proces.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0007-kernel32-Implement-K32GetMappedFileName.-v2.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0008-ntdll-Resolve-drive-symlinks-before-returning-sectio.patch
|
||||
patch_apply ntdll-NtQueryVirtualMemory/0009-ntdll-Fix-error-code-when-querying-too-large-memory-.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Dmitry Timoshkov", "ntdll: Implement NtQueryVirtualMemory(MemorySectionName).", 2 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "server: Store full path for ntdll/kernel32 dll.", 1 },';
|
||||
printf '%s\n' '+ { "Dmitry Timoshkov", "ntdll: Split logic for MemoryBasicInformation into a separate function.", 1 },';
|
||||
printf '%s\n' '+ { "Dmitry Timoshkov", "ntdll: Implement NtQueryVirtualMemory(MemorySectionName).", 3 },';
|
||||
printf '%s\n' '+ { "Dmitry Timoshkov", "ntdll/tests: Add tests for NtQueryVirtualMemory(MemorySectionName).", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll/tests: Add test to ensure section name is full path.", 1 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Allow to query section names from other processes.", 1 },';
|
||||
printf '%s\n' '+ { "Dmitry Timoshkov", "kernel32: Implement K32GetMappedFileName.", 2 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Resolve drive symlinks before returning section name.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Müller", "ntdll: Fix error code when querying too large memory address.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user