Commit 332eee40 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

ntdll: Replace WRITE by WRITECOPY protection on an image section as Windows does.

parent bb8d47bd
...@@ -647,9 +647,6 @@ static void test_VirtualProtect(void *base, void *section) ...@@ -647,9 +647,6 @@ static void test_VirtualProtect(void *base, void *section)
ok(ret, "VirtualQuery failed %d\n", GetLastError()); ok(ret, "VirtualQuery failed %d\n", GetLastError());
ok(info.BaseAddress == section, "%d: got %p != expected %p\n", i, info.BaseAddress, section); ok(info.BaseAddress == section, "%d: got %p != expected %p\n", i, info.BaseAddress, section);
ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize); ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize);
if (info.Protect != td[i].prot_get)
todo_wine ok(info.Protect == td[i].prot_get, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_get);
else
ok(info.Protect == td[i].prot_get, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_get); ok(info.Protect == td[i].prot_get, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_get);
ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base); ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base);
ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect); ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#x != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect);
...@@ -667,12 +664,7 @@ static void test_VirtualProtect(void *base, void *section) ...@@ -667,12 +664,7 @@ static void test_VirtualProtect(void *base, void *section)
ret = VirtualProtect(section, si.dwPageSize, PAGE_NOACCESS, &old_prot); ret = VirtualProtect(section, si.dwPageSize, PAGE_NOACCESS, &old_prot);
ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError()); ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError());
if (td[i].prot_get) if (td[i].prot_get)
{
if (old_prot != td[i].prot_get)
todo_wine ok(old_prot == td[i].prot_get, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_get);
else
ok(old_prot == td[i].prot_get, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_get); ok(old_prot == td[i].prot_get, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_get);
}
else else
ok(old_prot == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, old_prot); ok(old_prot == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, old_prot);
} }
......
...@@ -552,7 +552,7 @@ static DWORD VIRTUAL_GetWin32Prot( BYTE vprot ) ...@@ -552,7 +552,7 @@ static DWORD VIRTUAL_GetWin32Prot( BYTE vprot )
* RETURNS * RETURNS
* Value of page protection flags * Value of page protection flags
*/ */
static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot ) static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot, BOOL image )
{ {
switch(protect & 0xff) switch(protect & 0xff)
{ {
...@@ -560,7 +560,10 @@ static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot ) ...@@ -560,7 +560,10 @@ static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot )
*vprot = VPROT_READ; *vprot = VPROT_READ;
break; break;
case PAGE_READWRITE: case PAGE_READWRITE:
*vprot = VPROT_READ | VPROT_WRITE; if (image)
*vprot = VPROT_READ | VPROT_WRITECOPY;
else
*vprot = VPROT_READ | VPROT_WRITE;
break; break;
case PAGE_WRITECOPY: case PAGE_WRITECOPY:
*vprot = VPROT_READ | VPROT_WRITECOPY; *vprot = VPROT_READ | VPROT_WRITECOPY;
...@@ -572,7 +575,10 @@ static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot ) ...@@ -572,7 +575,10 @@ static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot )
*vprot = VPROT_EXEC | VPROT_READ; *vprot = VPROT_EXEC | VPROT_READ;
break; break;
case PAGE_EXECUTE_READWRITE: case PAGE_EXECUTE_READWRITE:
*vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE; if (image)
*vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY;
else
*vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE;
break; break;
case PAGE_EXECUTE_WRITECOPY: case PAGE_EXECUTE_WRITECOPY:
*vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY; *vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY;
...@@ -1860,7 +1866,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_ ...@@ -1860,7 +1866,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
if (is_beyond_limit( 0, size, working_set_limit )) return STATUS_WORKING_SET_LIMIT_RANGE; if (is_beyond_limit( 0, size, working_set_limit )) return STATUS_WORKING_SET_LIMIT_RANGE;
if ((status = get_vprot_flags( protect, &vprot ))) return status; if ((status = get_vprot_flags( protect, &vprot, FALSE ))) return status;
if (vprot & VPROT_WRITECOPY) return STATUS_INVALID_PAGE_PROTECTION; if (vprot & VPROT_WRITECOPY) return STATUS_INVALID_PAGE_PROTECTION;
vprot |= VPROT_VALLOC; vprot |= VPROT_VALLOC;
if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED; if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED;
...@@ -2087,7 +2093,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T ...@@ -2087,7 +2093,7 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
/* Make sure all the pages are committed */ /* Make sure all the pages are committed */
if (get_committed_size( view, base, &vprot ) >= size && (vprot & VPROT_COMMITTED)) if (get_committed_size( view, base, &vprot ) >= size && (vprot & VPROT_COMMITTED))
{ {
if (!(status = get_vprot_flags( new_prot, &new_vprot ))) if (!(status = get_vprot_flags( new_prot, &new_vprot, view->protect & VPROT_IMAGE )))
{ {
if ((new_vprot & VPROT_WRITECOPY) && (view->protect & VPROT_VALLOC)) if ((new_vprot & VPROT_WRITECOPY) && (view->protect & VPROT_VALLOC))
status = STATUS_INVALID_PAGE_PROTECTION; status = STATUS_INVALID_PAGE_PROTECTION;
...@@ -2392,7 +2398,7 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC ...@@ -2392,7 +2398,7 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC
if (len > MAX_PATH*sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; if (len > MAX_PATH*sizeof(WCHAR)) return STATUS_NAME_TOO_LONG;
if ((ret = get_vprot_flags( protect, &vprot ))) return ret; if ((ret = get_vprot_flags( protect, &vprot, sec_flags & SEC_IMAGE ))) return ret;
objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 ); objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 );
objattr.sd_len = 0; objattr.sd_len = 0;
...@@ -2602,7 +2608,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -2602,7 +2608,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
server_enter_uninterrupted_section( &csVirtual, &sigset ); server_enter_uninterrupted_section( &csVirtual, &sigset );
get_vprot_flags( protect, &vprot ); get_vprot_flags( protect, &vprot, map_vprot & VPROT_IMAGE );
vprot |= (map_vprot & VPROT_COMMITTED); vprot |= (map_vprot & VPROT_COMMITTED);
res = map_view( &view, *addr_ptr, size, mask, FALSE, vprot ); res = map_view( &view, *addr_ptr, size, mask, FALSE, vprot );
if (res) if (res)
......
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