Commit 5f49f07d authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

ntdll: Handle write watches in virtual_uninterrupted_write_memory.

parent 33766482
...@@ -1729,12 +1729,31 @@ SIZE_T virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_ ...@@ -1729,12 +1729,31 @@ SIZE_T virtual_uninterrupted_write_memory( void *addr, const void *buffer, SIZE_
{ {
if (!(view->protect & VPROT_SYSTEM)) if (!(view->protect & VPROT_SYSTEM))
{ {
void *page = ROUND_ADDR( addr, page_mask ); while (bytes_written < size)
BYTE *p = view->prot + (((const char *)page - (const char *)view->base) >> page_shift);
while (bytes_written < size && (VIRTUAL_GetUnixProt( *p++ ) & PROT_WRITE))
{ {
SIZE_T block_size = min( size, page_size - ((UINT_PTR)addr & page_mask) ); void *page = ROUND_ADDR( addr, page_mask );
BYTE *p = view->prot + (((const char *)page - (const char *)view->base) >> page_shift);
SIZE_T block_size;
/* If the page is not writeable then check for write watches
* before giving up. This can be done without raising a real
* exception. Similar to virtual_handle_fault. */
if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE))
{
if (!(view->protect & VPROT_WRITEWATCH))
break;
if (*p & VPROT_WRITEWATCH)
{
*p &= ~VPROT_WRITEWATCH;
VIRTUAL_SetProt( view, page, page_size, *p );
}
/* ignore fault if page is writable now */
if (!(VIRTUAL_GetUnixProt( *p ) & PROT_WRITE))
break;
}
block_size = min( size, page_size - ((UINT_PTR)addr & page_mask) );
memcpy( addr, buffer, block_size ); memcpy( addr, buffer, block_size );
addr = (void *)((char *)addr + block_size); addr = (void *)((char *)addr + block_size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment