From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/virtual.c | 25 +++++++++-------- dlls/ntdll/unix/virtual.c | 57 +++++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c index d3ee66e3716..ff7e82260d1 100644 --- a/dlls/ntdll/tests/virtual.c +++ b/dlls/ntdll/tests/virtual.c @@ -2736,8 +2736,8 @@ static void test_query_region_information(void) ok(!info.MappedPageFile, "Unexpected flag %d.\n", info.MappedPageFile); ok(!info.MappedPhysical, "Unexpected flag %d.\n", info.MappedPhysical); ok(!info.DirectMapped, "Unexpected flag %d.\n", info.DirectMapped); - todo_wine ok(info.RegionSize == 0x10000, "Unexpected region size %#Ix.\n", info.RegionSize); - todo_wine ok(info.CommitSize == 0x10000, "Unexpected commit size %#Ix.\n", info.CommitSize); + ok(info.RegionSize == 0x10000, "Unexpected region size %#Ix.\n", info.RegionSize); + ok(info.CommitSize == 0x10000, "Unexpected commit size %#Ix.\n", info.CommitSize);
status = NtQueryVirtualMemory(NtCurrentProcess(), (char *)ptr + 0x1000, MemoryRegionInformation, &info, sizeof(info), &len); ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); @@ -2749,8 +2749,8 @@ static void test_query_region_information(void) ok(!info.MappedPageFile, "Unexpected flag %d.\n", info.MappedPageFile); ok(!info.MappedPhysical, "Unexpected flag %d.\n", info.MappedPhysical); ok(!info.DirectMapped, "Unexpected flag %d.\n", info.DirectMapped); - todo_wine ok(info.RegionSize == 0x10000, "Unexpected region size %#Ix.\n", info.RegionSize); - todo_wine ok(info.CommitSize == 0x10000, "Unexpected commit size %#Ix.\n", info.CommitSize); + ok(info.RegionSize == 0x10000, "Unexpected region size %#Ix.\n", info.RegionSize); + ok(info.CommitSize == 0x10000, "Unexpected commit size %#Ix.\n", info.CommitSize);
size = 0; status = NtFreeVirtualMemory(NtCurrentProcess(), &ptr, &size, MEM_RELEASE); @@ -2758,13 +2758,13 @@ static void test_query_region_information(void)
memset(&info, 0xcc, sizeof(info)); status = NtQueryVirtualMemory(NtCurrentProcess(), ptr, MemoryRegionInformation, &info, sizeof(info), &len); - todo_wine ok(status == STATUS_INVALID_ADDRESS, "Unexpected status %08lx.\n", status); - todo_wine ok(info.AllocationBase == (void *)(ULONG_PTR)0xcccccccccccccccc, "got %p.\n", info.AllocationBase); - todo_wine ok(info.AllocationProtect == 0xcccccccc, "Unexpected protection %lu.\n", info.AllocationProtect); - todo_wine ok(info.RegionType == 0xcccccccc, "got %#lx.\n", info.RegionType); + ok(status == STATUS_INVALID_ADDRESS, "Unexpected status %08lx.\n", status); + ok(info.AllocationBase == (void *)(ULONG_PTR)0xcccccccccccccccc, "got %p.\n", info.AllocationBase); + ok(info.AllocationProtect == 0xcccccccc, "Unexpected protection %lu.\n", info.AllocationProtect); + ok(info.RegionType == 0xcccccccc, "got %#lx.\n", info.RegionType);
/* Pagefile mapping */ - mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, NULL); + mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 4096, NULL); ok(mapping != 0, "CreateFileMapping failed\n");
ptr = NULL; @@ -2785,7 +2785,7 @@ static void test_query_region_information(void) ok(!info.MappedPhysical, "Unexpected flag %d.\n", info.MappedPhysical); ok(!info.DirectMapped, "Unexpected flag %d.\n", info.DirectMapped); ok(info.RegionSize == 4096, "Unexpected region size.\n"); - todo_wine ok(!info.CommitSize, "Unexpected commit size %#Ix.\n", info.CommitSize); + ok(!info.CommitSize, "Unexpected commit size %#Ix.\n", info.CommitSize);
status = NtUnmapViewOfSection(NtCurrentProcess(), ptr); ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); @@ -2810,7 +2810,7 @@ static void test_query_region_information(void) ok(info.RegionSize == 4096, "Unexpected region size.\n"); ok(info.CommitSize == 4096, "Unexpected commit size %#Ix.\n", info.CommitSize);
- *(int *)ptr = 1; + *(volatile int *)ptr = 1; memset(&info, 0x11, sizeof(info)); status = NtQueryVirtualMemory(NtCurrentProcess(), ptr, MemoryRegionInformation, &info, sizeof(info), &len); ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); @@ -2833,6 +2833,7 @@ static void test_query_region_information(void) offset.QuadPart = 0; status = NtMapViewOfSection(mapping, NtCurrentProcess(), &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE); ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); + *(volatile int *)ptr = 1;
memset(&info, 0x11, sizeof(info)); status = NtQueryVirtualMemory(NtCurrentProcess(), ptr, MemoryRegionInformation, &info, sizeof(info), &len); @@ -2846,7 +2847,7 @@ static void test_query_region_information(void) ok(!info.MappedPhysical, "Unexpected flag %d.\n", info.MappedPhysical); ok(!info.DirectMapped, "Unexpected flag %d.\n", info.DirectMapped); ok(info.RegionSize == 4096, "Unexpected region size.\n"); - todo_wine ok(!info.CommitSize, "Unexpected commit size %#Ix.\n", info.CommitSize); + ok(!info.CommitSize, "Unexpected commit size %#Ix.\n", info.CommitSize);
status = NtUnmapViewOfSection(NtCurrentProcess(), ptr); ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index a57da1b5d09..d4fc64235b6 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -5590,8 +5590,12 @@ static unsigned int get_basic_memory_info( HANDLE process, LPCVOID addr, static unsigned int get_memory_region_info( HANDLE process, LPCVOID addr, MEMORY_REGION_INFORMATION *info, SIZE_T len, SIZE_T *res_len ) { - MEMORY_BASIC_INFORMATION basic_info; - unsigned int status; + char *base, *region_start, *region_end; + struct file_view *view; + BYTE vprot, vprot_mask; + BOOL fake_reserved; + sigset_t sigset; + SIZE_T size;
if (len < FIELD_OFFSET(MEMORY_REGION_INFORMATION, CommitSize)) return STATUS_INFO_LENGTH_MISMATCH; @@ -5602,15 +5606,48 @@ static unsigned int get_memory_region_info( HANDLE process, LPCVOID addr, MEMORY return STATUS_NOT_IMPLEMENTED; }
- if ((status = fill_basic_memory_info( addr, &basic_info ))) return status; + base = ROUND_ADDR( addr, page_mask ); + + if (is_beyond_limit( base, 1, working_set_limit )) return STATUS_INVALID_PARAMETER; + + server_enter_uninterrupted_section( &virtual_mutex, &sigset ); + + if ((view = get_memory_region_size( base, ®ion_start, ®ion_end, &fake_reserved ))) + { + info->AllocationBase = view->base; + info->AllocationProtect = get_win32_prot( view->protect, view->protect ); + info->RegionType = 0; /* FIXME */ + if (len >= FIELD_OFFSET(MEMORY_REGION_INFORMATION, CommitSize)) + info->RegionSize = view->size; + if (len >= FIELD_OFFSET(MEMORY_REGION_INFORMATION, PartitionId)) + { + base = region_start; + info->CommitSize = 0; + vprot_mask = VPROT_COMMITTED; + if (!is_view_valloc( view )) vprot_mask |= PAGE_WRITECOPY; + while (base != region_end && + (size = get_committed_size( view, base, ~(size_t)0, &vprot, vprot_mask ))) + { + if ((vprot & vprot_mask) == vprot_mask) info->CommitSize += size; + base += size; + } + } + } + else + { + if (!fake_reserved) + { + server_leave_uninterrupted_section( &virtual_mutex, &sigset ); + return STATUS_INVALID_ADDRESS; + } + info->AllocationBase = region_start; + info->AllocationProtect = PAGE_NOACCESS; + info->RegionType = 0; /* FIXME */ + info->RegionSize = region_end - region_start; + info->CommitSize = 0; + }
- info->AllocationBase = basic_info.AllocationBase; - info->AllocationProtect = basic_info.AllocationProtect; - info->RegionType = 0; /* FIXME */ - if (len >= FIELD_OFFSET(MEMORY_REGION_INFORMATION, CommitSize)) - info->RegionSize = basic_info.RegionSize; - if (len >= FIELD_OFFSET(MEMORY_REGION_INFORMATION, PartitionId)) - info->CommitSize = basic_info.State == MEM_COMMIT ? basic_info.RegionSize : 0; + server_leave_uninterrupted_section( &virtual_mutex, &sigset );
if (res_len) *res_len = sizeof(*info); return STATUS_SUCCESS;