Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
fc5cb9b5
Commit
fc5cb9b5
authored
Jun 28, 2022
by
Nikolay Sivov
Committed by
Alexandre Julliard
Oct 31, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Partially implement MemoryRegionInformation query.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
parent
0d21e1cb
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
233 additions
and
37 deletions
+233
-37
virtual.c
dlls/ntdll/tests/virtual.c
+97
-0
virtual.c
dlls/ntdll/unix/virtual.c
+78
-37
struct32.h
dlls/wow64/struct32.h
+11
-0
virtual.c
dlls/wow64/virtual.c
+23
-0
winternl.h
include/winternl.h
+24
-0
No files found.
dlls/ntdll/tests/virtual.c
View file @
fc5cb9b5
...
...
@@ -1574,6 +1574,102 @@ static void test_prefetch(void)
"NtSetInformationVirtualMemory unexpected status on 2 page-aligned entries: %08lx
\n
"
,
status
);
}
static
void
test_query_region_information
(
void
)
{
MEMORY_REGION_INFORMATION
info
;
LARGE_INTEGER
offset
;
SIZE_T
len
,
size
;
NTSTATUS
status
;
HANDLE
mapping
;
void
*
ptr
;
size
=
0x10000
;
ptr
=
NULL
;
status
=
NtAllocateVirtualMemory
(
NtCurrentProcess
(),
&
ptr
,
0
,
&
size
,
MEM_RESERVE
,
PAGE_READWRITE
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
#ifdef _WIN64
status
=
NtQueryVirtualMemory
(
NtCurrentProcess
(),
ptr
,
MemoryRegionInformation
,
&
info
,
FIELD_OFFSET
(
MEMORY_REGION_INFORMATION
,
PartitionId
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
status
=
NtQueryVirtualMemory
(
NtCurrentProcess
(),
ptr
,
MemoryRegionInformation
,
&
info
,
FIELD_OFFSET
(
MEMORY_REGION_INFORMATION
,
CommitSize
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
status
=
NtQueryVirtualMemory
(
NtCurrentProcess
(),
ptr
,
MemoryRegionInformation
,
&
info
,
FIELD_OFFSET
(
MEMORY_REGION_INFORMATION
,
RegionSize
),
&
len
);
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"Unexpected status %08lx.
\n
"
,
status
);
#endif
len
=
0
;
memset
(
&
info
,
0x11
,
sizeof
(
info
));
status
=
NtQueryVirtualMemory
(
NtCurrentProcess
(),
ptr
,
MemoryRegionInformation
,
&
info
,
sizeof
(
info
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
info
.
AllocationBase
==
ptr
,
"Unexpected base %p.
\n
"
,
info
.
AllocationBase
);
ok
(
info
.
AllocationProtect
==
PAGE_READWRITE
,
"Unexpected protection %lu.
\n
"
,
info
.
AllocationProtect
);
ok
(
!
info
.
Private
,
"Unexpected flag %d.
\n
"
,
info
.
Private
);
ok
(
!
info
.
MappedDataFile
,
"Unexpected flag %d.
\n
"
,
info
.
MappedDataFile
);
ok
(
!
info
.
MappedImage
,
"Unexpected flag %d.
\n
"
,
info
.
MappedImage
);
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
);
ok
(
info
.
RegionSize
==
size
,
"Unexpected region size.
\n
"
);
size
=
0
;
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
&
ptr
,
&
size
,
MEM_RELEASE
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
/* Committed size */
size
=
0x10000
;
ptr
=
NULL
;
status
=
NtAllocateVirtualMemory
(
NtCurrentProcess
(),
&
ptr
,
0
,
&
size
,
MEM_RESERVE
|
MEM_COMMIT
,
PAGE_READWRITE
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
memset
(
&
info
,
0x11
,
sizeof
(
info
));
status
=
NtQueryVirtualMemory
(
NtCurrentProcess
(),
ptr
,
MemoryRegionInformation
,
&
info
,
sizeof
(
info
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
info
.
AllocationBase
==
ptr
,
"Unexpected base %p.
\n
"
,
info
.
AllocationBase
);
ok
(
info
.
AllocationProtect
==
PAGE_READWRITE
,
"Unexpected protection %lu.
\n
"
,
info
.
AllocationProtect
);
ok
(
!
info
.
Private
,
"Unexpected flag %d.
\n
"
,
info
.
Private
);
ok
(
!
info
.
MappedDataFile
,
"Unexpected flag %d.
\n
"
,
info
.
MappedDataFile
);
ok
(
!
info
.
MappedImage
,
"Unexpected flag %d.
\n
"
,
info
.
MappedImage
);
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
);
ok
(
info
.
RegionSize
==
size
,
"Unexpected region size.
\n
"
);
size
=
0
;
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
&
ptr
,
&
size
,
MEM_RELEASE
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
/* Pagefile mapping */
mapping
=
CreateFileMappingA
(
INVALID_HANDLE_VALUE
,
NULL
,
PAGE_READWRITE
,
0
,
4096
,
NULL
);
ok
(
mapping
!=
0
,
"CreateFileMapping failed
\n
"
);
ptr
=
NULL
;
size
=
0
;
offset
.
QuadPart
=
0
;
status
=
NtMapViewOfSection
(
mapping
,
NtCurrentProcess
(),
&
ptr
,
0
,
0
,
&
offset
,
&
size
,
1
,
0
,
PAGE_READONLY
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
memset
(
&
info
,
0x11
,
sizeof
(
info
));
status
=
NtQueryVirtualMemory
(
NtCurrentProcess
(),
ptr
,
MemoryRegionInformation
,
&
info
,
sizeof
(
info
),
&
len
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
info
.
AllocationBase
==
ptr
,
"Unexpected base %p.
\n
"
,
info
.
AllocationBase
);
ok
(
info
.
AllocationProtect
==
PAGE_READONLY
,
"Unexpected protection %lu.
\n
"
,
info
.
AllocationProtect
);
ok
(
!
info
.
Private
,
"Unexpected flag %d.
\n
"
,
info
.
Private
);
ok
(
!
info
.
MappedDataFile
,
"Unexpected flag %d.
\n
"
,
info
.
MappedDataFile
);
ok
(
!
info
.
MappedImage
,
"Unexpected flag %d.
\n
"
,
info
.
MappedImage
);
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
);
ok
(
info
.
RegionSize
==
4096
,
"Unexpected region size.
\n
"
);
status
=
NtUnmapViewOfSection
(
NtCurrentProcess
(),
ptr
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
NtClose
(
mapping
);
}
START_TEST
(
virtual
)
{
HMODULE
mod
;
...
...
@@ -1619,4 +1715,5 @@ START_TEST(virtual)
test_prefetch
();
test_user_shared_data
();
test_syscalls
();
test_query_region_information
();
}
dlls/ntdll/unix/virtual.c
View file @
fc5cb9b5
...
...
@@ -4080,48 +4080,13 @@ static int get_free_mem_state_callback( void *start, SIZE_T size, void *arg )
return
1
;
}
/* 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
)
static
NTSTATUS
fill_basic_memory_info
(
const
void
*
addr
,
MEMORY_BASIC_INFORMATION
*
info
)
{
struct
file_view
*
view
;
char
*
base
,
*
alloc_base
=
0
,
*
alloc_end
=
working_set_limit
;
struct
wine_rb_entry
*
ptr
;
struct
file_view
*
view
;
sigset_t
sigset
;
if
(
len
<
sizeof
(
MEMORY_BASIC_INFORMATION
))
return
STATUS_INFO_LENGTH_MISMATCH
;
if
(
process
!=
NtCurrentProcess
())
{
NTSTATUS
status
;
apc_call_t
call
;
apc_result_t
result
;
memset
(
&
call
,
0
,
sizeof
(
call
)
);
call
.
virtual_query
.
type
=
APC_VIRTUAL_QUERY
;
call
.
virtual_query
.
addr
=
wine_server_client_ptr
(
addr
);
status
=
server_queue_process_apc
(
process
,
&
call
,
&
result
);
if
(
status
!=
STATUS_SUCCESS
)
return
status
;
if
(
result
.
virtual_query
.
status
==
STATUS_SUCCESS
)
{
info
->
BaseAddress
=
wine_server_get_ptr
(
result
.
virtual_query
.
base
);
info
->
AllocationBase
=
wine_server_get_ptr
(
result
.
virtual_query
.
alloc_base
);
info
->
RegionSize
=
result
.
virtual_query
.
size
;
info
->
Protect
=
result
.
virtual_query
.
prot
;
info
->
AllocationProtect
=
result
.
virtual_query
.
alloc_prot
;
info
->
State
=
(
DWORD
)
result
.
virtual_query
.
state
<<
12
;
info
->
Type
=
(
DWORD
)
result
.
virtual_query
.
alloc_type
<<
16
;
if
(
info
->
RegionSize
!=
result
.
virtual_query
.
size
)
/* truncated */
return
STATUS_INVALID_PARAMETER
;
/* FIXME */
if
(
res_len
)
*
res_len
=
sizeof
(
*
info
);
}
return
result
.
virtual_query
.
status
;
}
base
=
ROUND_ADDR
(
addr
,
page_mask
);
if
(
is_beyond_limit
(
base
,
1
,
working_set_limit
))
return
STATUS_INVALID_PARAMETER
;
...
...
@@ -4195,6 +4160,79 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
}
server_leave_uninterrupted_section
(
&
virtual_mutex
,
&
sigset
);
return
STATUS_SUCCESS
;
}
/* 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
)
{
NTSTATUS
status
;
if
(
len
<
sizeof
(
*
info
))
return
STATUS_INFO_LENGTH_MISMATCH
;
if
(
process
!=
NtCurrentProcess
())
{
NTSTATUS
status
;
apc_call_t
call
;
apc_result_t
result
;
memset
(
&
call
,
0
,
sizeof
(
call
)
);
call
.
virtual_query
.
type
=
APC_VIRTUAL_QUERY
;
call
.
virtual_query
.
addr
=
wine_server_client_ptr
(
addr
);
status
=
server_queue_process_apc
(
process
,
&
call
,
&
result
);
if
(
status
!=
STATUS_SUCCESS
)
return
status
;
if
(
result
.
virtual_query
.
status
==
STATUS_SUCCESS
)
{
info
->
BaseAddress
=
wine_server_get_ptr
(
result
.
virtual_query
.
base
);
info
->
AllocationBase
=
wine_server_get_ptr
(
result
.
virtual_query
.
alloc_base
);
info
->
RegionSize
=
result
.
virtual_query
.
size
;
info
->
Protect
=
result
.
virtual_query
.
prot
;
info
->
AllocationProtect
=
result
.
virtual_query
.
alloc_prot
;
info
->
State
=
(
DWORD
)
result
.
virtual_query
.
state
<<
12
;
info
->
Type
=
(
DWORD
)
result
.
virtual_query
.
alloc_type
<<
16
;
if
(
info
->
RegionSize
!=
result
.
virtual_query
.
size
)
/* truncated */
return
STATUS_INVALID_PARAMETER
;
/* FIXME */
if
(
res_len
)
*
res_len
=
sizeof
(
*
info
);
}
return
result
.
virtual_query
.
status
;
}
if
((
status
=
fill_basic_memory_info
(
addr
,
info
)))
return
status
;
if
(
res_len
)
*
res_len
=
sizeof
(
*
info
);
return
STATUS_SUCCESS
;
}
static
NTSTATUS
get_memory_region_info
(
HANDLE
process
,
LPCVOID
addr
,
MEMORY_REGION_INFORMATION
*
info
,
SIZE_T
len
,
SIZE_T
*
res_len
)
{
MEMORY_BASIC_INFORMATION
basic_info
;
NTSTATUS
status
;
if
(
len
<
FIELD_OFFSET
(
MEMORY_REGION_INFORMATION
,
CommitSize
))
return
STATUS_INFO_LENGTH_MISMATCH
;
if
(
process
!=
NtCurrentProcess
())
{
FIXME
(
"Unimplemented for other processes.
\n
"
);
return
STATUS_NOT_IMPLEMENTED
;
}
if
((
status
=
fill_basic_memory_info
(
addr
,
&
basic_info
)))
return
status
;
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
;
if
(
res_len
)
*
res_len
=
sizeof
(
*
info
);
return
STATUS_SUCCESS
;
}
...
...
@@ -4371,6 +4409,9 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
case
MemoryMappedFilenameInformation
:
return
get_memory_section_name
(
process
,
addr
,
buffer
,
len
,
res_len
);
case
MemoryRegionInformation
:
return
get_memory_region_info
(
process
,
addr
,
buffer
,
len
,
res_len
);
case
MemoryWineUnixFuncs
:
case
MemoryWineUnixWow64Funcs
:
if
(
len
!=
sizeof
(
unixlib_handle_t
))
return
STATUS_INFO_LENGTH_MISMATCH
;
...
...
dlls/wow64/struct32.h
View file @
fc5cb9b5
...
...
@@ -158,6 +158,17 @@ typedef struct
typedef
struct
{
ULONG
AllocationBase
;
ULONG
AllocationProtect
;
ULONG
RegionType
;
ULONG
RegionSize
;
ULONG
CommitSize
;
ULONG
PartitionId
;
ULONG
NodePreference
;
}
MEMORY_REGION_INFORMATION32
;
typedef
struct
{
UNICODE_STRING32
SectionFileName
;
}
MEMORY_SECTION_NAME32
;
...
...
dlls/wow64/virtual.c
View file @
fc5cb9b5
...
...
@@ -422,6 +422,29 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
break
;
}
case
MemoryRegionInformation
:
/* MEMORY_REGION_INFORMATION */
{
if
(
len
>=
sizeof
(
MEMORY_REGION_INFORMATION32
))
{
MEMORY_REGION_INFORMATION
info
;
MEMORY_REGION_INFORMATION32
*
info32
=
ptr
;
if
(
!
(
status
=
NtQueryVirtualMemory
(
handle
,
addr
,
class
,
&
info
,
sizeof
(
info
),
&
res_len
)))
{
info32
->
AllocationBase
=
PtrToUlong
(
info
.
AllocationBase
);
info32
->
AllocationProtect
=
info
.
AllocationProtect
;
info32
->
RegionType
=
info
.
RegionType
;
info32
->
RegionSize
=
info
.
RegionSize
;
info32
->
CommitSize
=
info
.
CommitSize
;
info32
->
PartitionId
=
info
.
PartitionId
;
info32
->
NodePreference
=
info
.
NodePreference
;
}
}
else
status
=
STATUS_INFO_LENGTH_MISMATCH
;
res_len
=
sizeof
(
MEMORY_REGION_INFORMATION32
);
break
;
}
case
MemoryWorkingSetExInformation
:
/* MEMORY_WORKING_SET_EX_INFORMATION */
{
MEMORY_WORKING_SET_EX_INFORMATION32
*
info32
=
ptr
;
...
...
include/winternl.h
View file @
fc5cb9b5
...
...
@@ -1971,6 +1971,30 @@ typedef struct _MEMORY_WORKING_SET_EX_INFORMATION {
MEMORY_WORKING_SET_EX_BLOCK
VirtualAttributes
;
}
MEMORY_WORKING_SET_EX_INFORMATION
,
*
PMEMORY_WORKING_SET_EX_INFORMATION
;
typedef
struct
_MEMORY_REGION_INFORMATION
{
PVOID
AllocationBase
;
ULONG
AllocationProtect
;
union
{
ULONG
RegionType
;
struct
{
ULONG
Private
:
1
;
ULONG
MappedDataFile
:
1
;
ULONG
MappedImage
:
1
;
ULONG
MappedPageFile
:
1
;
ULONG
MappedPhysical
:
1
;
ULONG
DirectMapped
:
1
;
ULONG
Reserved
:
26
;
}
DUMMYSTRUCTNAME
;
}
DUMMYUNIONNAME
;
SIZE_T
RegionSize
;
SIZE_T
CommitSize
;
ULONG_PTR
PartitionId
;
ULONG_PTR
NodePreference
;
}
MEMORY_REGION_INFORMATION
,
*
PMEMORY_REGION_INFORMATION
;
typedef
enum
_MUTANT_INFORMATION_CLASS
{
MutantBasicInformation
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment