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