Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45667 Signed-off-by: Andrew Wesie awesie@gmail.com --- dlls/ntdll/virtual.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ include/winternl.h | 21 ++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index ad91cffd8f..529f9575d3 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -3134,6 +3134,65 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr, return STATUS_SUCCESS; }
+static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr, + MEMORY_WORKING_SET_EX_INFORMATION *info, + SIZE_T len, SIZE_T *res_len ) +{ + char pagemap_path[32]; + FILE *f; + MEMORY_WORKING_SET_EX_INFORMATION *p; + sigset_t sigset; + + if (process != NtCurrentProcess()) + { + FIXME( "(process=%p,addr=%p) Unimplemented information class: MemoryWorkingSetExInformation\n", process, addr ); + return STATUS_INVALID_INFO_CLASS; + } + + snprintf( pagemap_path, sizeof(pagemap_path), "/proc/%u/pagemap", getpid() ); + f = fopen( pagemap_path, "rb" ); + if (!f) + { + static int once; + if (!once++) WARN( "unable to open %s for MemoryWorkingSetExInformation", pagemap_path ); + } + + server_enter_uninterrupted_section( &csVirtual, &sigset ); + for (p = info; (UINT_PTR)(p + 1) <= (UINT_PTR)info + len; p++) + { + BYTE vprot; + UINT64 pagemap; + struct file_view *view; + + memset( &p->VirtualAttributes, 0, sizeof(p->VirtualAttributes) ); + + /* If we don't have pagemap information, default to invalid. */ + if (!f || fseek( f, ((UINT_PTR)p->VirtualAddress >> 12) * sizeof(pagemap), SEEK_SET ) == -1 || + fread( &pagemap, sizeof(pagemap), 1, f ) != 1) + { + pagemap = 0; + } + + if ((view = VIRTUAL_FindView( p->VirtualAddress, 0 )) && + get_committed_size( view, p->VirtualAddress, &vprot ) && + (vprot & VPROT_COMMITTED)) + { + p->VirtualAttributes.Valid = !(vprot & VPROT_GUARD) && (vprot & 0x0f) && (pagemap >> 63); + p->VirtualAttributes.Shared = !is_view_valloc( view ) && ((pagemap >> 61) & 1); + if (p->VirtualAttributes.Shared && p->VirtualAttributes.Valid) + p->VirtualAttributes.ShareCount = 1; /* FIXME */ + if (p->VirtualAttributes.Valid) + p->VirtualAttributes.Win32Protection = VIRTUAL_GetWin32Prot( vprot, view->protect ); + } + } + server_leave_uninterrupted_section( &csVirtual, &sigset ); + + if (f) + fclose( f ); + if (res_len) + *res_len = (UINT_PTR)p - (UINT_PTR)info; + return STATUS_SUCCESS; +}
#define UNIMPLEMENTED_INFO_CLASS(c) \ case c: \ @@ -3156,6 +3215,9 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr, case MemoryBasicInformation: return get_basic_memory_info( process, addr, buffer, len, res_len );
+ case MemoryWorkingSetExInformation: + return get_working_set_ex( process, addr, buffer, len, res_len ); + UNIMPLEMENTED_INFO_CLASS(MemoryWorkingSetList); UNIMPLEMENTED_INFO_CLASS(MemorySectionName); UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation); diff --git a/include/winternl.h b/include/winternl.h index e5aed5acb1..ea6707714d 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1051,7 +1051,8 @@ typedef enum _MEMORY_INFORMATION_CLASS { MemoryBasicInformation, MemoryWorkingSetList, MemorySectionName, - MemoryBasicVlmInformation + MemoryBasicVlmInformation, + MemoryWorkingSetExInformation } MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_SECTION_NAME @@ -1059,6 +1060,24 @@ typedef struct _MEMORY_SECTION_NAME UNICODE_STRING SectionFileName; } MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
+typedef union _MEMORY_WORKING_SET_EX_BLOCK { + ULONG_PTR Flags; + struct { + ULONG_PTR Valid : 1; + ULONG_PTR ShareCount : 3; + ULONG_PTR Win32Protection : 11; + ULONG_PTR Shared : 1; + ULONG_PTR Node : 6; + ULONG_PTR Locked : 1; + ULONG_PTR LargePage : 1; + } DUMMYSTRUCTNAME; +} MEMORY_WORKING_SET_EX_BLOCK, *PMEMORY_WORKING_SET_EX_BLOCK; + +typedef struct _MEMORY_WORKING_SET_EX_INFORMATION { + PVOID VirtualAddress; + MEMORY_WORKING_SET_EX_BLOCK VirtualAttributes; +} MEMORY_WORKING_SET_EX_INFORMATION, *PMEMORY_WORKING_SET_EX_INFORMATION; + typedef enum _MUTANT_INFORMATION_CLASS { MutantBasicInformation