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
af8bb2e9
Commit
af8bb2e9
authored
Nov 25, 2008
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add support for virtual write watches.
parent
81b9ca5d
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
128 additions
and
18 deletions
+128
-18
virtual.c
dlls/kernel32/tests/virtual.c
+1
-1
virtual.c
dlls/ntdll/virtual.c
+125
-17
server_protocol.h
include/wine/server_protocol.h
+1
-0
protocol.def
server/protocol.def
+1
-0
No files found.
dlls/kernel32/tests/virtual.c
View file @
af8bb2e9
...
...
@@ -757,7 +757,7 @@ static void test_write_watch(void)
if
(
!
base
&&
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
||
GetLastError
()
==
ERROR_NOT_SUPPORTED
))
{
todo_wine
win_skip
(
"MEM_WRITE_WATCH not supported
\n
"
);
win_skip
(
"MEM_WRITE_WATCH not supported
\n
"
);
return
;
}
ok
(
base
!=
NULL
,
"VirtualAlloc failed %u
\n
"
,
GetLastError
()
);
...
...
dlls/ntdll/virtual.c
View file @
af8bb2e9
...
...
@@ -178,6 +178,7 @@ static int VIRTUAL_GetUnixProt( BYTE vprot )
if
(
vprot
&
VPROT_WRITE
)
prot
|=
PROT_WRITE
;
if
(
vprot
&
VPROT_WRITECOPY
)
prot
|=
PROT_WRITE
;
if
(
vprot
&
VPROT_EXEC
)
prot
|=
PROT_EXEC
;
if
(
vprot
&
VPROT_WRITEWATCH
)
prot
&=
~
PROT_WRITE
;
}
if
(
!
prot
)
prot
=
PROT_NONE
;
return
prot
;
...
...
@@ -565,18 +566,42 @@ static BOOL VIRTUAL_SetProt( FILE_VIEW *view, /* [in] Pointer to view */
BYTE
vprot
)
/* [in] Protections to use */
{
int
unix_prot
=
VIRTUAL_GetUnixProt
(
vprot
);
BYTE
*
p
=
view
->
prot
+
(((
char
*
)
base
-
(
char
*
)
view
->
base
)
>>
page_shift
);
TRACE
(
"%p-%p %s
\n
"
,
base
,
(
char
*
)
base
+
size
-
1
,
VIRTUAL_GetProtStr
(
vprot
)
);
if
(
view
->
protect
&
VPROT_WRITEWATCH
)
{
/* each page may need different protections depending on write watch flag */
UINT
i
,
count
;
char
*
addr
=
base
;
int
prot
;
p
[
0
]
=
vprot
|
(
p
[
0
]
&
VPROT_WRITEWATCH
);
unix_prot
=
VIRTUAL_GetUnixProt
(
p
[
0
]
);
for
(
count
=
i
=
1
;
i
<
size
>>
page_shift
;
i
++
,
count
++
)
{
p
[
i
]
=
vprot
|
(
p
[
i
]
&
VPROT_WRITEWATCH
);
prot
=
VIRTUAL_GetUnixProt
(
p
[
i
]
);
if
(
prot
==
unix_prot
)
continue
;
mprotect
(
addr
,
count
<<
page_shift
,
unix_prot
);
addr
+=
count
<<
page_shift
;
unix_prot
=
prot
;
count
=
0
;
}
if
(
count
)
mprotect
(
addr
,
count
<<
page_shift
,
unix_prot
);
VIRTUAL_DEBUG_DUMP_VIEW
(
view
);
return
TRUE
;
}
/* if setting stack guard pages, store the permissions first, as the guard may be
* triggered at any point after mprotect and change the permissions again */
if
((
vprot
&
VPROT_GUARD
)
&&
((
char
*
)
base
>=
(
char
*
)
NtCurrentTeb
()
->
DeallocationStack
)
&&
((
char
*
)
base
<
(
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
))
{
memset
(
view
->
prot
+
(((
char
*
)
base
-
(
char
*
)
view
->
base
)
>>
page_shift
),
vprot
,
size
>>
page_shift
);
memset
(
p
,
vprot
,
size
>>
page_shift
);
mprotect
(
base
,
size
,
unix_prot
);
VIRTUAL_DEBUG_DUMP_VIEW
(
view
);
return
TRUE
;
...
...
@@ -594,14 +619,41 @@ static BOOL VIRTUAL_SetProt( FILE_VIEW *view, /* [in] Pointer to view */
if
(
mprotect
(
base
,
size
,
unix_prot
))
return
FALSE
;
/* FIXME: last error */
done:
memset
(
view
->
prot
+
(((
char
*
)
base
-
(
char
*
)
view
->
base
)
>>
page_shift
),
vprot
,
size
>>
page_shift
);
memset
(
p
,
vprot
,
size
>>
page_shift
);
VIRTUAL_DEBUG_DUMP_VIEW
(
view
);
return
TRUE
;
}
/***********************************************************************
* reset_write_watches
*
* Reset write watches in a memory range.
*/
static
void
reset_write_watches
(
struct
file_view
*
view
,
void
*
base
,
SIZE_T
size
)
{
SIZE_T
i
,
count
;
int
prot
,
unix_prot
;
char
*
addr
=
base
;
BYTE
*
p
=
view
->
prot
+
((
addr
-
(
char
*
)
view
->
base
)
>>
page_shift
);
p
[
0
]
|=
VPROT_WRITEWATCH
;
unix_prot
=
VIRTUAL_GetUnixProt
(
p
[
0
]
);
for
(
count
=
i
=
1
;
i
<
size
>>
page_shift
;
i
++
,
count
++
)
{
p
[
i
]
|=
VPROT_WRITEWATCH
;
prot
=
VIRTUAL_GetUnixProt
(
p
[
i
]
);
if
(
prot
==
unix_prot
)
continue
;
mprotect
(
addr
,
count
<<
page_shift
,
unix_prot
);
addr
+=
count
<<
page_shift
;
unix_prot
=
prot
;
count
=
0
;
}
if
(
count
)
mprotect
(
addr
,
count
<<
page_shift
,
unix_prot
);
}
/***********************************************************************
* unmap_extra_space
*
* Release the extra memory while keeping the range starting on the granularity boundary.
...
...
@@ -1411,12 +1463,18 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err )
if
((
view
=
VIRTUAL_FindView
(
addr
,
0
)))
{
void
*
page
=
ROUND_ADDR
(
addr
,
page_mask
);
BYTE
vprot
=
view
->
prot
[((
const
char
*
)
page
-
(
const
char
*
)
view
->
base
)
>>
page_shift
];
if
(
vprot
&
VPROT_GUARD
)
BYTE
*
vprot
=
&
view
->
prot
[((
const
char
*
)
page
-
(
const
char
*
)
view
->
base
)
>>
page_shift
];
if
(
*
vprot
&
VPROT_GUARD
)
{
VIRTUAL_SetProt
(
view
,
page
,
page_size
,
vprot
&
~
VPROT_GUARD
);
VIRTUAL_SetProt
(
view
,
page
,
page_size
,
*
vprot
&
~
VPROT_GUARD
);
ret
=
STATUS_GUARD_PAGE_VIOLATION
;
}
if
((
err
&
EXCEPTION_WRITE_FAULT
)
&&
(
*
vprot
&
VPROT_WRITEWATCH
))
{
*
vprot
&=
~
VPROT_WRITEWATCH
;
VIRTUAL_SetProt
(
view
,
page
,
page_size
,
*
vprot
);
ret
=
STATUS_SUCCESS
;
}
}
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
return
ret
;
...
...
@@ -1614,11 +1672,6 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
WARN
(
"called with wrong alloc type flags (%08x) !
\n
"
,
type
);
return
STATUS_INVALID_PARAMETER
;
}
if
(
type
&
MEM_WRITE_WATCH
)
{
FIXME
(
"MEM_WRITE_WATCH type not supported
\n
"
);
return
STATUS_INVALID_PARAMETER
;
}
/* Reserve the memory */
...
...
@@ -1626,6 +1679,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
if
((
type
&
MEM_RESERVE
)
||
!
base
)
{
if
(
type
&
MEM_WRITE_WATCH
)
vprot
|=
VPROT_WRITEWATCH
;
status
=
map_view
(
&
view
,
base
,
size
,
mask
,
type
&
MEM_TOP_DOWN
,
vprot
);
if
(
status
==
STATUS_SUCCESS
)
base
=
view
->
base
;
}
...
...
@@ -1974,7 +2028,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
else
if
(
view
->
protect
&
VPROT_VALLOC
)
info
->
Type
=
MEM_PRIVATE
;
else
info
->
Type
=
MEM_MAPPED
;
for
(
size
=
base
-
alloc_base
;
size
<
base
+
range_size
-
alloc_base
;
size
+=
page_size
)
if
(
view
->
prot
[
size
>>
page_shift
]
!=
vprot
)
break
;
if
(
(
view
->
prot
[
size
>>
page_shift
]
^
vprot
)
&
~
VPROT_WRITEWATCH
)
break
;
info
->
RegionSize
=
size
-
(
base
-
alloc_base
);
}
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
...
...
@@ -2398,8 +2452,44 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
NTSTATUS
WINAPI
NtGetWriteWatch
(
HANDLE
process
,
ULONG
flags
,
PVOID
base
,
SIZE_T
size
,
PVOID
*
addresses
,
ULONG_PTR
*
count
,
ULONG
*
granularity
)
{
FIXME
(
"%p %x %p-%p %p %lu
\n
"
,
process
,
flags
,
base
,
(
char
*
)
base
+
size
,
addresses
,
*
count
);
return
STATUS_NOT_IMPLEMENTED
;
struct
file_view
*
view
;
NTSTATUS
status
=
STATUS_SUCCESS
;
sigset_t
sigset
;
size
=
ROUND_SIZE
(
base
,
size
);
base
=
ROUND_ADDR
(
base
,
page_mask
);
if
(
!
count
||
!
granularity
)
return
STATUS_ACCESS_VIOLATION
;
if
(
!*
count
||
!
size
)
return
STATUS_INVALID_PARAMETER
;
if
(
flags
&
~
WRITE_WATCH_FLAG_RESET
)
return
STATUS_INVALID_PARAMETER
;
if
(
!
addresses
)
return
STATUS_ACCESS_VIOLATION
;
TRACE
(
"%p %x %p-%p %p %lu
\n
"
,
process
,
flags
,
base
,
(
char
*
)
base
+
size
,
addresses
,
count
?
*
count
:
0
);
server_enter_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
if
((
view
=
VIRTUAL_FindView
(
base
,
size
))
&&
(
view
->
protect
&
VPROT_WRITEWATCH
))
{
ULONG_PTR
pos
=
0
;
char
*
addr
=
base
;
char
*
end
=
addr
+
size
;
while
(
pos
<
*
count
&&
addr
<
end
)
{
BYTE
prot
=
view
->
prot
[(
addr
-
(
char
*
)
view
->
base
)
>>
page_shift
];
if
(
!
(
prot
&
VPROT_WRITEWATCH
))
addresses
[
pos
++
]
=
addr
;
addr
+=
page_size
;
}
if
(
flags
&
WRITE_WATCH_FLAG_RESET
)
reset_write_watches
(
view
,
base
,
addr
-
(
char
*
)
base
);
*
count
=
pos
;
*
granularity
=
page_size
;
}
else
status
=
STATUS_INVALID_PARAMETER
;
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
return
status
;
}
...
...
@@ -2409,8 +2499,26 @@ NTSTATUS WINAPI NtGetWriteWatch( HANDLE process, ULONG flags, PVOID base, SIZE_T
*/
NTSTATUS
WINAPI
NtResetWriteWatch
(
HANDLE
process
,
PVOID
base
,
SIZE_T
size
)
{
FIXME
(
"%p %p-%p
\n
"
,
process
,
base
,
(
char
*
)
base
+
size
);
return
STATUS_NOT_IMPLEMENTED
;
struct
file_view
*
view
;
NTSTATUS
status
=
STATUS_SUCCESS
;
sigset_t
sigset
;
size
=
ROUND_SIZE
(
base
,
size
);
base
=
ROUND_ADDR
(
base
,
page_mask
);
TRACE
(
"%p %p-%p
\n
"
,
process
,
base
,
(
char
*
)
base
+
size
);
if
(
!
size
)
return
STATUS_INVALID_PARAMETER
;
server_enter_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
if
((
view
=
VIRTUAL_FindView
(
base
,
size
))
&&
(
view
->
protect
&
VPROT_WRITEWATCH
))
reset_write_watches
(
view
,
base
,
size
);
else
status
=
STATUS_INVALID_PARAMETER
;
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
return
status
;
}
...
...
include/wine/server_protocol.h
View file @
af8bb2e9
...
...
@@ -1688,6 +1688,7 @@ struct create_mapping_reply
#define VPROT_GUARD 0x10
#define VPROT_NOCACHE 0x20
#define VPROT_COMMITTED 0x40
#define VPROT_WRITEWATCH 0x80
#define VPROT_IMAGE 0x0100
#define VPROT_SYSTEM 0x0200
...
...
server/protocol.def
View file @
af8bb2e9
...
...
@@ -1330,6 +1330,7 @@ enum char_info_mode
#define VPROT_GUARD 0x10
#define VPROT_NOCACHE 0x20
#define VPROT_COMMITTED 0x40
#define VPROT_WRITEWATCH 0x80
/* per-mapping protection flags */
#define VPROT_IMAGE 0x0100 /* mapping for an exe image */
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
...
...
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