diff --git a/patches/ntdll-NtDevicePath/0001-ntdll-Implement-opening-files-through-nt-device-path.patch b/patches/ntdll-NtDevicePath/0001-ntdll-Implement-opening-files-through-nt-device-path.patch index 640b011e..f7ec3960 100644 --- a/patches/ntdll-NtDevicePath/0001-ntdll-Implement-opening-files-through-nt-device-path.patch +++ b/patches/ntdll-NtDevicePath/0001-ntdll-Implement-opening-files-through-nt-device-path.patch @@ -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?= 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 ); diff --git a/patches/ntdll-NtQueryVirtualMemory/0001-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch b/patches/ntdll-NtQueryVirtualMemory/0001-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch deleted file mode 100644 index 7062e190..00000000 --- a/patches/ntdll-NtQueryVirtualMemory/0001-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 805c61e62ca54cb4b7240c2313bd0fc4c97a902f Mon Sep 17 00:00:00 2001 -From: Dmitry Timoshkov -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 - diff --git a/patches/ntdll-NtQueryVirtualMemory/0001-server-Store-full-path-for-ntdll-kernel32-dll.patch b/patches/ntdll-NtQueryVirtualMemory/0001-server-Store-full-path-for-ntdll-kernel32-dll.patch new file mode 100644 index 00000000..a5af4fc9 --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0001-server-Store-full-path-for-ntdll-kernel32-dll.patch @@ -0,0 +1,91 @@ +From d3932f7ec92691aa77a75840883597a1c652f8c9 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0002-ntdll-Split-logic-for-MemoryBasicInformation-into-a-.patch b/patches/ntdll-NtQueryVirtualMemory/0002-ntdll-Split-logic-for-MemoryBasicInformation-into-a-.patch new file mode 100644 index 00000000..388a4b01 --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0002-ntdll-Split-logic-for-MemoryBasicInformation-into-a-.patch @@ -0,0 +1,103 @@ +From 0da9b9bdc6862bd2ebe58f64798f55dd1f83cf1b Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0003-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch b/patches/ntdll-NtQueryVirtualMemory/0003-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch new file mode 100644 index 00000000..dcc0cd79 --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0003-ntdll-Implement-NtQueryVirtualMemory-MemorySectionNa.patch @@ -0,0 +1,176 @@ +From 60d3299d2e2924023542dcb7245ddfd2f901b319 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Sun, 28 May 2017 05:19:30 +0200 +Subject: ntdll: Implement NtQueryVirtualMemory(MemorySectionName). (v3) + +Contains several improvements by Sebastian Lackner . +--- + 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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0004-ntdll-tests-Add-tests-for-NtQueryVirtualMemory-Memor.patch b/patches/ntdll-NtQueryVirtualMemory/0004-ntdll-tests-Add-tests-for-NtQueryVirtualMemory-Memor.patch new file mode 100644 index 00000000..de091609 --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0004-ntdll-tests-Add-tests-for-NtQueryVirtualMemory-Memor.patch @@ -0,0 +1,65 @@ +From f16058fd2551d42166df18a9d2dd784f57b35144 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0005-ntdll-tests-Add-test-to-ensure-section-name-is-full-.patch b/patches/ntdll-NtQueryVirtualMemory/0005-ntdll-tests-Add-test-to-ensure-section-name-is-full-.patch new file mode 100644 index 00000000..2380bd2c --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0005-ntdll-tests-Add-test-to-ensure-section-name-is-full-.patch @@ -0,0 +1,60 @@ +From ace7d4f4d6f6de1e2ba60c43d8e79d2b54d03523 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +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 + #include + ++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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0006-ntdll-Allow-to-query-section-names-from-other-proces.patch b/patches/ntdll-NtQueryVirtualMemory/0006-ntdll-Allow-to-query-section-names-from-other-proces.patch new file mode 100644 index 00000000..e6a938bd --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0006-ntdll-Allow-to-query-section-names-from-other-proces.patch @@ -0,0 +1,204 @@ +From d98c5a09b04c6082a085e313284379e70bb108b5 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0002-kernel32-Implement-K32GetMappedFileName.-v2.patch b/patches/ntdll-NtQueryVirtualMemory/0007-kernel32-Implement-K32GetMappedFileName.-v2.patch similarity index 86% rename from patches/ntdll-NtQueryVirtualMemory/0002-kernel32-Implement-K32GetMappedFileName.-v2.patch rename to patches/ntdll-NtQueryVirtualMemory/0007-kernel32-Implement-K32GetMappedFileName.-v2.patch index b0fdedd7..6754b831 100644 --- a/patches/ntdll-NtQueryVirtualMemory/0002-kernel32-Implement-K32GetMappedFileName.-v2.patch +++ b/patches/ntdll-NtQueryVirtualMemory/0007-kernel32-Implement-K32GetMappedFileName.-v2.patch @@ -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 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 diff --git a/patches/ntdll-NtQueryVirtualMemory/0008-ntdll-Resolve-drive-symlinks-before-returning-sectio.patch b/patches/ntdll-NtQueryVirtualMemory/0008-ntdll-Resolve-drive-symlinks-before-returning-sectio.patch new file mode 100644 index 00000000..4551a77c --- /dev/null +++ b/patches/ntdll-NtQueryVirtualMemory/0008-ntdll-Resolve-drive-symlinks-before-returning-sectio.patch @@ -0,0 +1,163 @@ +From 2ea8d5c16d9ab714f8cecde6cd6b2ff51738535a Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +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 + diff --git a/patches/ntdll-NtQueryVirtualMemory/0003-ntdll-Fix-error-code-when-querying-too-large-memory-.patch b/patches/ntdll-NtQueryVirtualMemory/0009-ntdll-Fix-error-code-when-querying-too-large-memory-.patch similarity index 100% rename from patches/ntdll-NtQueryVirtualMemory/0003-ntdll-Fix-error-code-when-querying-too-large-memory-.patch rename to patches/ntdll-NtQueryVirtualMemory/0009-ntdll-Fix-error-code-when-querying-too-large-memory-.patch diff --git a/patches/ntdll-NtQueryVirtualMemory/definition b/patches/ntdll-NtQueryVirtualMemory/definition index d1d99160..e10db0e4 100644 --- a/patches/ntdll-NtQueryVirtualMemory/definition +++ b/patches/ntdll-NtQueryVirtualMemory/definition @@ -1 +1,2 @@ Fixes: [23999] Implement MemorySectionName class in NtQueryVirtualMemory +Depends: ntdll-NtDevicePath diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 571e5cfb..0abebe79 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -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