Module: wine Branch: master Commit: bed1e5c8f5813904b858269d5bfe02c76c56f39b URL: http://source.winehq.org/git/wine.git/?a=commit;h=bed1e5c8f5813904b858269d5b...
Author: Dmitry Timoshkov dmitry@baikal.ru Date: Tue Nov 22 18:02:38 2011 +0800
kernel32: Add a test to show that Windows changes the WRITECOPY to WRITE protection on an image section write.
---
dlls/kernel32/tests/loader.c | 83 +++++++++++++++++++++++++++++------------- 1 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 4d420ea..8f88907 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -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 const struct test_data { - DWORD scn_file_access, scn_page_access; + DWORD scn_file_access, scn_page_access, scn_page_access_after_write; } td[] = { - { 0, PAGE_NOACCESS }, - { IMAGE_SCN_MEM_READ, PAGE_READONLY }, - { IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, - { IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE }, - { IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, + { 0, PAGE_NOACCESS, 0 }, + { IMAGE_SCN_MEM_READ, PAGE_READONLY, 0 }, + { IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE }, + { IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE, 0 }, + { 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_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, - { IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE_WRITECOPY }, - - { IMAGE_SCN_CNT_INITIALIZED_DATA, PAGE_NOACCESS }, - { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY }, - { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, - { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE }, - { 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_EXECUTE, PAGE_EXECUTE_READ }, - { IMAGE_SCN_CNT_INITIALIZED_DATA | 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 }, - - { IMAGE_SCN_CNT_UNINITIALIZED_DATA, PAGE_NOACCESS }, - { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY }, - { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY }, - { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE, PAGE_EXECUTE }, - { 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_EXECUTE, PAGE_EXECUTE_READ }, - { IMAGE_SCN_CNT_UNINITIALIZED_DATA | 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 } + { 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, PAGE_EXECUTE_READWRITE }, + + { IMAGE_SCN_CNT_INITIALIZED_DATA, PAGE_NOACCESS, 0 }, + { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY, 0 }, + { IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE }, + { 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, PAGE_READWRITE }, + { 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, PAGE_EXECUTE_READWRITE }, + { 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, 0 }, + { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ, PAGE_READONLY, 0 }, + { IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE, PAGE_WRITECOPY, PAGE_READWRITE }, + { 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, PAGE_READWRITE }, + { 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, PAGE_EXECUTE_READWRITE }, + { 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 section_data[0x10] = "section data"; @@ -664,6 +679,7 @@ static void test_section_access(void) hlib = LoadLibrary(dll_name); ok(hlib != 0, "LoadLibrary error %d\n", GetLastError());
+ SetLastError(0xdeadbeef); size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info)); ok(size == sizeof(info), "%d: VirtualQuery error %d\n", i, GetLastError()); @@ -682,6 +698,21 @@ static void test_section_access(void) if (info.Protect != PAGE_NOACCESS) 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); ret = FreeLibrary(hlib); ok(ret, "FreeLibrary error %d\n", GetLastError());