VirtualProtect test patch

Robert Reif reif at earthlink.net
Tue May 18 06:23:52 CDT 2004


Adds a test to make sure VirtualProtect has an effect on memory accesses.

I don't know how to make this code portable but the tests work
on XP when the #if 1 is changed to a #if 0.  3 of the tests fail with
wine.  I tried wrapping them with todo_wine but didn't see any
difference.
-------------- next part --------------
Index: dlls/kernel/tests/virtual.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/virtual.c,v
retrieving revision 1.2
diff -u -r1.2 virtual.c
--- dlls/kernel/tests/virtual.c	10 Feb 2004 20:07:56 -0000	1.2
+++ dlls/kernel/tests/virtual.c	18 May 2004 11:14:07 -0000
@@ -25,6 +25,150 @@
 #include "winerror.h"
 #include "wine/test.h"
 
+#if 1
+#include "excpt.h"
+#include "wine/exception.h"
+
+static WINE_EXCEPTION_FILTER(page_fault)
+{
+    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
+        return EXCEPTION_EXECUTE_HANDLER;
+    return EXCEPTION_CONTINUE_SEARCH;
+}
+
+static BOOL readException(char * memory)
+{
+    char temp;
+    int flag = FALSE;
+
+    __TRY {
+        temp = *memory;
+    } __EXCEPT(page_fault) {
+        flag = TRUE;
+    } __ENDTRY
+
+    return flag;
+}
+
+static BOOL writeException(char * memory)
+{
+    int flag = FALSE;
+
+    __TRY {
+        *memory = 0;
+    } __EXCEPT(page_fault) {
+        flag = TRUE;
+    } __ENDTRY
+
+    return flag;
+}
+
+#else
+
+INT PageFaultExceptionFilter(DWORD dwCode)
+{
+    if (dwCode == EXCEPTION_ACCESS_VIOLATION)
+        return EXCEPTION_EXECUTE_HANDLER;
+    return EXCEPTION_CONTINUE_SEARCH;
+}
+
+static BOOL readException(char * memory)
+{
+    char temp;
+    int flag = FALSE;
+
+    __try {
+        temp = *memory;
+    } __except(PageFaultExceptionFilter(GetExceptionCode())) {
+        flag = TRUE;
+    }
+
+    return flag;
+}
+
+static BOOL writeException(char * memory)
+{
+    int flag = FALSE;
+
+    __try {
+        *memory = 0;
+    } __except(PageFaultExceptionFilter(GetExceptionCode())) {
+        flag = TRUE;
+    }
+
+    return flag;
+}
+#endif
+
+static void test_VirtualProtect()
+{
+    DWORD dwPageSize;
+    BYTE * twoPages;
+    DWORD old_prot;
+    SYSTEM_INFO sSysInfo;
+
+    GetSystemInfo(&sSysInfo);
+    dwPageSize = sSysInfo.dwPageSize;
+
+    twoPages = VirtualAlloc(0, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+    ok(twoPages!=NULL,"Failed to allocate two pages\n");
+    if (twoPages==NULL)
+        return;
+
+    /* should be able to read and write both pages */
+    ok(readException(twoPages) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages) == FALSE, "write should not fail\n");
+    ok(readException(twoPages + dwPageSize) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages + dwPageSize) == FALSE, "write should not fail\n");
+
+    ok(VirtualProtect(twoPages, 2 * dwPageSize, PAGE_READONLY, &old_prot),
+       "Failed to set protection\n");
+
+    /* should be able to only read both pages */
+    ok(readException(twoPages) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages) == TRUE, "write should fail\n");
+    ok(readException(twoPages + dwPageSize) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages + dwPageSize) == TRUE, "write should fail\n");
+
+    ok(VirtualProtect(twoPages, 2 * dwPageSize, PAGE_NOACCESS, &old_prot),
+       "Failed to set protection\n");
+
+    /* should not be able to read or write both pages */
+    ok(readException(twoPages) == TRUE, "read should fail\n");
+    ok(writeException(twoPages) == TRUE, "write should fail\n");
+    ok(readException(twoPages + dwPageSize) == TRUE, "read should fail\n");
+    ok(writeException(twoPages + dwPageSize) == TRUE, "write should fail\n");
+
+    ok(VirtualProtect(twoPages, 2 * dwPageSize, PAGE_READWRITE, &old_prot),
+       "Failed to set protection\n");
+
+    /* should be able to read and write both pages */
+    ok(readException(twoPages) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages) == FALSE, "write should not fail\n");
+    ok(readException(twoPages + dwPageSize) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages + dwPageSize) == FALSE, "write should not fail\n");
+
+    ok(VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_READONLY, &old_prot),
+       "Failed to set protection for second page\n");
+
+    /* should be able to read and write first page and only read second */
+    ok(readException(twoPages) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages) == FALSE, "write should not fail\n");
+    ok(readException(twoPages + dwPageSize) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages + dwPageSize) == TRUE, "write should fail\n");
+
+    ok(VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &old_prot),
+       "Failed to set protection for second page\n");
+
+    /* should be able to read and write first page only */
+    ok(readException(twoPages) == FALSE, "read should not fail\n");
+    ok(writeException(twoPages) == FALSE, "write should not fail\n");
+    ok(readException(twoPages + dwPageSize) == TRUE, "read should fail\n");
+    ok(writeException(twoPages + dwPageSize) == TRUE, "write should fail\n");
+
+    ok(VirtualFree(twoPages, 0, MEM_RELEASE), "VirtualFree failed\n");
+}
+
 static void test_VirtualAlloc(void)
 {
     void *addr1, *addr2;
@@ -93,6 +237,14 @@
     ok(old_prot == PAGE_READONLY,
         "wrong old protection: got %04lx instead of PAGE_READONLY\n", old_prot);
 
+    ok(VirtualProtect(addr1, 0x1000, PAGE_NOACCESS, &old_prot), "VirtualProtect failed\n");
+    ok(old_prot == PAGE_READWRITE,
+        "wrong old protection: got %04lx instead of PAGE_READWRITE\n", old_prot);
+
+    ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtect failed\n");
+    ok(old_prot == PAGE_NOACCESS,
+        "wrong old protection: got %04lx instead of PAGE_NOACCESS\n", old_prot);
+
     ok(!VirtualFree(addr1, 0x10000, 0), "VirtualFree should fail with type 0\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER,
         "got %ld, expected ERROR_INVALID_PARAMETER\n", GetLastError());
@@ -110,4 +262,5 @@
 START_TEST(virtual)
 {
     test_VirtualAlloc();
+    test_VirtualProtect();
 }


More information about the wine-patches mailing list