Commit bed1e5c8 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

kernel32: Add a test to show that Windows changes the WRITECOPY to WRITE…

kernel32: Add a test to show that Windows changes the WRITECOPY to WRITE protection on an image section write.
parent 30882eb0
...@@ -553,39 +553,54 @@ static void test_ImportDescriptors(void) ...@@ -553,39 +553,54 @@ static void test_ImportDescriptors(void)
} }
} }
static BOOL is_mem_writable(DWORD prot)
{
switch (prot & 0xff)
{
case PAGE_READWRITE:
case PAGE_WRITECOPY:
case PAGE_EXECUTE_READWRITE:
case PAGE_EXECUTE_WRITECOPY:
return TRUE;
default:
return FALSE;
}
}
static void test_section_access(void) static void test_section_access(void)
{ {
static const struct test_data static const struct test_data
{ {
DWORD scn_file_access, scn_page_access; DWORD scn_file_access, scn_page_access, scn_page_access_after_write;
} td[] = } td[] =
{ {
{ 0, PAGE_NOACCESS }, { 0, PAGE_NOACCESS, 0 },
{ IMAGE_SCN_MEM_READ, PAGE_READONLY }, { IMAGE_SCN_MEM_READ, PAGE_READONLY, 0 },
{ IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, { IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE },
{ IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE }, { IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE, 0 },
{ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, { IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE },
{ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_READ }, { IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_READ },
{ IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, { IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY, PAGE_EXECUTE_READWRITE },
{ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, { IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY, PAGE_EXECUTE_READWRITE },
{ IMAGE_SCN_CNT_INITIALIZED_DATA, PAGE_NOACCESS }, { IMAGE_SCN_CNT_INITIALIZED_DATA, PAGE_NOACCESS, 0 },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY, 0 },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE, 0 },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_READ }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_READ, 0 },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY, PAGE_EXECUTE_READWRITE },
{ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY, PAGE_EXECUTE_READWRITE },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA, PAGE_NOACCESS }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA, PAGE_NOACCESS, 0 },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY, 0 },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE, 0 },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_READ }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_READ, 0 },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY, PAGE_EXECUTE_READWRITE },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY } { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY, PAGE_EXECUTE_READWRITE }
}; };
static const char filler[0x1000]; static const char filler[0x1000];
static const char section_data[0x10] = "section data"; static const char section_data[0x10] = "section data";
...@@ -664,6 +679,7 @@ static void test_section_access(void) ...@@ -664,6 +679,7 @@ static void test_section_access(void)
hlib = LoadLibrary(dll_name); hlib = LoadLibrary(dll_name);
ok(hlib != 0, "LoadLibrary error %d\n", GetLastError()); ok(hlib != 0, "LoadLibrary error %d\n", GetLastError());
SetLastError(0xdeadbeef);
size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info)); size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info));
ok(size == sizeof(info), ok(size == sizeof(info),
"%d: VirtualQuery error %d\n", i, GetLastError()); "%d: VirtualQuery error %d\n", i, GetLastError());
...@@ -682,6 +698,21 @@ static void test_section_access(void) ...@@ -682,6 +698,21 @@ static void test_section_access(void)
if (info.Protect != PAGE_NOACCESS) if (info.Protect != PAGE_NOACCESS)
ok(!memcmp((const char *)info.BaseAddress, section_data, section.SizeOfRawData), "wrong section data\n"); ok(!memcmp((const char *)info.BaseAddress, section_data, section.SizeOfRawData), "wrong section data\n");
/* Windows changes the WRITECOPY to WRITE protection on an image section write (for a changed page only) */
if (is_mem_writable(info.Protect))
{
char *p = info.BaseAddress;
*p = 0xfe;
SetLastError(0xdeadbeef);
size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info));
ok(size == sizeof(info), "%d: VirtualQuery error %d\n", i, GetLastError());
/* FIXME: remove the condition below once Wine is fixed */
if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY)
todo_wine ok(info.Protect == td[i].scn_page_access_after_write, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].scn_page_access_after_write);
else
ok(info.Protect == td[i].scn_page_access_after_write, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].scn_page_access_after_write);
}
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = FreeLibrary(hlib); ret = FreeLibrary(hlib);
ok(ret, "FreeLibrary error %d\n", GetLastError()); ok(ret, "FreeLibrary error %d\n", GetLastError());
......
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