Author: akhaldi
Date: Tue Jul 12 21:10:24 2016
New Revision: 71910

URL: http://svn.reactos.org/svn/reactos?rev=71910&view=rev
Log:
[KERNEL32_WINETEST] Sync with Wine Staging 1.9.14 except thread tests. 
CORE-11511

Modified:
    trunk/rostests/winetests/kernel32/codepage.c
    trunk/rostests/winetests/kernel32/comm.c
    trunk/rostests/winetests/kernel32/console.c
    trunk/rostests/winetests/kernel32/directory.c
    trunk/rostests/winetests/kernel32/file.c
    trunk/rostests/winetests/kernel32/loader.c
    trunk/rostests/winetests/kernel32/locale.c
    trunk/rostests/winetests/kernel32/path.c
    trunk/rostests/winetests/kernel32/pipe.c
    trunk/rostests/winetests/kernel32/process.c
    trunk/rostests/winetests/kernel32/sync.c
    trunk/rostests/winetests/kernel32/virtual.c

Modified: trunk/rostests/winetests/kernel32/codepage.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/codepage.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/codepage.c        [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/codepage.c        [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -1139,8 +1139,8 @@
 static void test_dbcs_to_widechar(void)
 {
     int i, count, count2;
-    WCHAR wbuf[2];
-    unsigned char buf[] = {0xbf, 0xb4, 0xc7};
+    WCHAR wbuf[5];
+    unsigned char buf[] = {0xbf, 0xb4, 0xc7, '\0', 'x'};
     static const DWORD flags[] = {
         MB_PRECOMPOSED,
         MB_COMPOSITE,
@@ -1157,8 +1157,7 @@
 
     for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
     {
-        wbuf[0] = 0xffff;
-        wbuf[1] = 0xffff;
+        memset(wbuf, 0xff, sizeof(wbuf));
         count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 2, NULL, 0);
         count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 2, wbuf, 
count);
 
@@ -1170,8 +1169,7 @@
 
     for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
     {
-        wbuf[0] = 0xffff;
-        wbuf[1] = 0xffff;
+        memset(wbuf, 0xff, sizeof(wbuf));
         count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 3, NULL, 0);
         SetLastError( 0xdeadbeef );
         count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 3, wbuf, 
count);
@@ -1190,6 +1188,65 @@
             ok(wbuf[0] == 0x770b, "%04x: returned %04x (expected 770b)\n", 
flags[i], wbuf[0]);
             ok(wbuf[1] == 0x003f || broken(wbuf[1] == 0), /*windows xp*/
                "%04x: wrong wide char: %04x\n", flags[i], wbuf[1]);
+            ok(wbuf[2] == 0xffff, "%04x: returned %04x (expected ffff)\n", 
flags[i], wbuf[2]);
+        }
+    }
+
+    /* src ends with null character */
+    for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
+    {
+        memset(wbuf, 0xff, sizeof(wbuf));
+        count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 4, NULL, 0);
+        SetLastError( 0xdeadbeef );
+        count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 4, wbuf, 
count);
+        ok(count == count2, "%04x: returned %d (expected %d)\n", flags[i], 
count2, count);
+
+        if (flags[i] & MB_ERR_INVALID_CHARS)
+        {
+            ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], 
count);
+            ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned 
%d (expected %d)\n",
+               flags[i], GetLastError(), ERROR_NO_UNICODE_TRANSLATION);
+        }
+        else
+        {
+            WCHAR wbuf_ok[]     = { 0x770b, 0x003f, '\0', 0xffff };
+            WCHAR wbuf_broken[] = { 0x770b, '\0', 0xffff, 0xffff };
+            ok(count == 3 || broken(count == 2 /*windows xp*/),
+               "%04x: returned %d (expected 3)\n", flags[i], count);
+            ok(!memcmp(wbuf, wbuf_ok, sizeof(wbuf_ok))
+               || broken(!memcmp(wbuf, wbuf_broken, sizeof(wbuf_broken))),
+               "%04x: returned %04x %04x %04x %04x (expected %04x %04x %04x 
%04x)\n",
+               flags[i], wbuf[0], wbuf[1], wbuf[2], wbuf[3],
+               wbuf_ok[0], wbuf_ok[1], wbuf_ok[2], wbuf_ok[3]);
+        }
+    }
+
+    /* src has null character, but not ends with it */
+    for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
+    {
+        memset(wbuf, 0xff, sizeof(wbuf));
+        count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 5, NULL, 0);
+        SetLastError( 0xdeadbeef );
+        count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 5, wbuf, 
count);
+        ok(count == count2, "%04x: returned %d (expected %d)\n", flags[i], 
count2, count);
+
+        if (flags[i] & MB_ERR_INVALID_CHARS)
+        {
+            ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], 
count);
+            ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned 
%d (expected %d)\n",
+               flags[i], GetLastError(), ERROR_NO_UNICODE_TRANSLATION);
+        }
+        else
+        {
+            WCHAR wbuf_ok[]     = { 0x770b, 0x003f, '\0', 'x', 0xffff };
+            WCHAR wbuf_broken[] = { 0x770b, '\0', 'x', 0xffff, 0xffff };
+            ok(count == 4 || broken(count == 3),
+               "%04x: returned %d (expected 4)\n", flags[i], count);
+            ok(!memcmp(wbuf, wbuf_ok, sizeof(wbuf_ok))
+               || broken(!memcmp(wbuf, wbuf_broken, sizeof(wbuf_broken))),
+               "%04x: returned %04x %04x %04x %04x %04x (expected %04x %04x 
%04x %04x %04x)\n",
+               flags[i], wbuf[0], wbuf[1], wbuf[2], wbuf[3], wbuf[4],
+               wbuf_ok[0], wbuf_ok[1], wbuf_ok[2], wbuf_ok[3], wbuf_ok[4]);
         }
     }
 }

Modified: trunk/rostests/winetests/kernel32/comm.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/comm.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/comm.c    [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/comm.c    [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -2151,13 +2151,9 @@
                     iob.Information = -1;
                     offset.QuadPart = (LONGLONG)i;
                     status = pNtReadFile(hcom, 0, NULL, NULL, &iob, buf, 0, 
&offset, NULL);
-                    /* FIXME: Remove once Wine is fixed */
-                    if (status == STATUS_PENDING) WaitForSingleObject(hcom, 
TIMEOUT);
                     if (i >= 0)
                     {
-todo_wine
                         ok(status == STATUS_SUCCESS, "%d: expected 
STATUS_SUCCESS, got %#x\n", i, status);
-todo_wine
                         ok(U(iob).Status == STATUS_SUCCESS, "%d: expected 
STATUS_SUCCESS, got %#x\n", i, U(iob).Status);
                         ok(iob.Information == 0, "%d: expected 0, got %lu\n", 
i, iob.Information);
                     }

Modified: trunk/rostests/winetests/kernel32/console.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/console.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/console.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/console.c [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -2779,6 +2779,165 @@
     pSetConsoleFont(std_output, index); /* restore original font size */
 }
 
+static void test_GetConsoleFontInfo(HANDLE std_output)
+{
+    HANDLE hmod;
+    BOOL (WINAPI *pGetConsoleFontInfo)(HANDLE, BOOL, DWORD, CONSOLE_FONT_INFO 
*);
+    DWORD (WINAPI *pGetNumberOfConsoleFonts)(void);
+    DWORD num_fonts, index, i;
+    int memsize, win_width, win_height, tmp_w, tmp_h;
+    CONSOLE_FONT_INFO *cfi;
+    BOOL ret;
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+    COORD orig_sb_size, tmp_sb_size, orig_font, tmp_font;
+
+    hmod = GetModuleHandleA("kernel32.dll");
+    pGetConsoleFontInfo = (void *)GetProcAddress(hmod, "GetConsoleFontInfo");
+    if (!pGetConsoleFontInfo)
+    {
+        win_skip("GetConsoleFontInfo is not available\n");
+        return;
+    }
+
+    pGetNumberOfConsoleFonts = (void *)GetProcAddress(hmod, 
"GetNumberOfConsoleFonts");
+    if (!pGetNumberOfConsoleFonts)
+    {
+        win_skip("GetNumberOfConsoleFonts is not available\n");
+        return;
+    }
+
+    num_fonts = pGetNumberOfConsoleFonts();
+    memsize = num_fonts * sizeof(CONSOLE_FONT_INFO);
+    cfi = HeapAlloc(GetProcessHeap(), 0, memsize);
+    memset(cfi, 0, memsize);
+
+    GetConsoleScreenBufferInfo(std_output, &csbi);
+    orig_sb_size = csbi.dwSize;
+    tmp_sb_size.X = csbi.dwSize.X + 3;
+    tmp_sb_size.Y = csbi.dwSize.Y + 5;
+    SetConsoleScreenBufferSize(std_output, tmp_sb_size);
+
+    SetLastError(0xdeadbeef);
+    ret = pGetConsoleFontInfo(NULL, FALSE, 0, cfi);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 
6\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE), FALSE, 0, cfi);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 
6\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = pGetConsoleFontInfo(std_output, FALSE, 0, cfi);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == 0xdeadbeef, "got %u, expected 
0xdeadbeef\n", GetLastError());
+
+    GetConsoleScreenBufferInfo(std_output, &csbi);
+    win_width = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+    win_height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+
+    GetCurrentConsoleFont(std_output, FALSE, &cfi[0]);
+    index = cfi[0].nFont;
+    orig_font = GetConsoleFontSize(std_output, index);
+
+    memset(cfi, 0, memsize);
+    ret = pGetConsoleFontInfo(std_output, FALSE, num_fonts, cfi);
+    todo_wine ok(ret, "got %d, expected non-zero\n", ret);
+
+    todo_wine ok(cfi[index].dwFontSize.X == win_width, "got %d, expected %d\n",
+                 cfi[index].dwFontSize.X, win_width);
+    todo_wine ok(cfi[index].dwFontSize.Y == win_height, "got %d, expected 
%d\n",
+                 cfi[index].dwFontSize.Y, win_height);
+
+    for (i = 0; i < num_fonts; i++)
+    {
+        ok(cfi[i].nFont == i, "element out of order, got nFont %d, expected 
%d\n", cfi[i].nFont, i);
+        tmp_font = GetConsoleFontSize(std_output, cfi[i].nFont);
+        tmp_w = (double)orig_font.X / tmp_font.X * win_width;
+        tmp_h = (double)orig_font.Y / tmp_font.Y * win_height;
+        todo_wine ok(cfi[i].dwFontSize.X == tmp_w, "got %d, expected %d\n", 
cfi[i].dwFontSize.X, tmp_w);
+        todo_wine ok(cfi[i].dwFontSize.Y == tmp_h, "got %d, expected %d\n", 
cfi[i].dwFontSize.Y, tmp_h);
+    }
+
+    SetLastError(0xdeadbeef);
+    ret = pGetConsoleFontInfo(NULL, TRUE, 0, cfi);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 
6\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE), TRUE, 0, cfi);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 
6\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = pGetConsoleFontInfo(std_output, TRUE, 0, cfi);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == 0xdeadbeef, "got %u, expected 
0xdeadbeef\n", GetLastError());
+
+    memset(cfi, 0, memsize);
+    ret = pGetConsoleFontInfo(std_output, TRUE, num_fonts, cfi);
+    todo_wine ok(ret, "got %d, expected non-zero\n", ret);
+
+    todo_wine ok(cfi[index].dwFontSize.X == csbi.dwMaximumWindowSize.X, "got 
%d, expected %d\n",
+                 cfi[index].dwFontSize.X, csbi.dwMaximumWindowSize.X);
+    todo_wine ok(cfi[index].dwFontSize.Y == csbi.dwMaximumWindowSize.Y, "got 
%d, expected %d\n",
+                 cfi[index].dwFontSize.Y, csbi.dwMaximumWindowSize.Y);
+
+    for (i = 0; i < num_fonts; i++)
+    {
+        ok(cfi[i].nFont == i, "element out of order, got nFont %d, expected 
%d\n", cfi[i].nFont, i);
+        tmp_font = GetConsoleFontSize(std_output, cfi[i].nFont);
+        tmp_w = (double)orig_font.X / tmp_font.X * csbi.dwMaximumWindowSize.X;
+        tmp_h = (double)orig_font.Y / tmp_font.Y * csbi.dwMaximumWindowSize.Y;
+        todo_wine ok(cfi[i].dwFontSize.X == tmp_w, "got %d, expected %d\n", 
cfi[i].dwFontSize.X, tmp_w);
+        todo_wine ok(cfi[i].dwFontSize.Y == tmp_h, "got %d, expected %d\n", 
cfi[i].dwFontSize.Y, tmp_h);
+     }
+
+    HeapFree(GetProcessHeap(), 0, cfi);
+    SetConsoleScreenBufferSize(std_output, orig_sb_size);
+}
+
+static void test_SetConsoleFont(HANDLE std_output)
+{
+    HANDLE hmod;
+    BOOL (WINAPI *pSetConsoleFont)(HANDLE, DWORD);
+    BOOL ret;
+    DWORD (WINAPI *pGetNumberOfConsoleFonts)(void);
+    DWORD num_fonts;
+
+    hmod = GetModuleHandleA("kernel32.dll");
+    pSetConsoleFont = (void *)GetProcAddress(hmod, "SetConsoleFont");
+    if (!pSetConsoleFont)
+    {
+        win_skip("SetConsoleFont is not available\n");
+        return;
+    }
+
+    SetLastError(0xdeadbeef);
+    ret = pSetConsoleFont(NULL, 0);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 
6\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = pSetConsoleFont(GetStdHandle(STD_INPUT_HANDLE), 0);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got %u, expected 
6\n", GetLastError());
+
+    pGetNumberOfConsoleFonts = (void *)GetProcAddress(hmod, 
"GetNumberOfConsoleFonts");
+    if (!pGetNumberOfConsoleFonts)
+    {
+        win_skip("GetNumberOfConsoleFonts is not available\n");
+        return;
+    }
+
+    num_fonts = pGetNumberOfConsoleFonts();
+
+    SetLastError(0xdeadbeef);
+    ret = pSetConsoleFont(std_output, num_fonts);
+    ok(!ret, "got %d, expected zero\n", ret);
+    todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u, expected 
87\n", GetLastError());
+}
+
 START_TEST(console)
 {
     static const char font_name[] = "Lucida Console";
@@ -2925,4 +3084,6 @@
     test_GetCurrentConsoleFont(hConOut);
     test_GetConsoleFontSize(hConOut);
     test_GetLargestConsoleWindowSize(hConOut);
-}
+    test_GetConsoleFontInfo(hConOut);
+    test_SetConsoleFont(hConOut);
+}

Modified: trunk/rostests/winetests/kernel32/directory.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/directory.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/directory.c       [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/directory.c       [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -157,6 +157,7 @@
 static void test_CreateDirectoryA(void)
 {
     char tmpdir[MAX_PATH];
+    WCHAR curdir[MAX_PATH];
     BOOL ret;
 
     ret = CreateDirectoryA(NULL, NULL);
@@ -172,6 +173,7 @@
     ret = GetSystemDirectoryA(tmpdir, MAX_PATH);
     ok(ret < MAX_PATH, "System directory should fit into MAX_PATH\n");
 
+    GetCurrentDirectoryW(MAX_PATH, curdir);
     ret = SetCurrentDirectoryA(tmpdir);
     ok(ret == TRUE, "could not chdir to the System directory\n");
 
@@ -329,6 +331,7 @@
     ret = RemoveDirectoryA(tmpdir);
     ok(ret == TRUE,
        "RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
+    SetCurrentDirectoryW(curdir);
 }
 
 static void test_CreateDirectoryW(void)
@@ -341,6 +344,7 @@
     static const WCHAR slashW[] = {'/',0};
     static const WCHAR dotdotW[] = {'.','.',0};
     static const WCHAR questionW[] = {'?',0};
+    WCHAR curdir[MAX_PATH];
 
     ret = CreateDirectoryW(NULL, NULL);
     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
@@ -358,6 +362,7 @@
     ret = GetSystemDirectoryW(tmpdir, MAX_PATH);
     ok(ret < MAX_PATH, "System directory should fit into MAX_PATH\n");
 
+    GetCurrentDirectoryW(MAX_PATH, curdir);
     ret = SetCurrentDirectoryW(tmpdir);
     ok(ret == TRUE, "could not chdir to the System directory ret %u err %u\n", 
ret, GetLastError());
 
@@ -413,6 +418,8 @@
        ret, GetLastError());
     ret = RemoveDirectoryW(tmpdir);
     ok(ret == FALSE, "RemoveDirectoryW should have failed\n");
+
+    SetCurrentDirectoryW(curdir);
 }
 
 static void test_RemoveDirectoryA(void)

Modified: trunk/rostests/winetests/kernel32/file.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/file.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/file.c    [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/file.c    [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -1214,6 +1214,7 @@
     {NULL, 0, -1, 0, FALSE}
     };
     BY_HANDLE_FILE_INFORMATION  Finfo;
+    WCHAR curdir[MAX_PATH];
 
     ret = GetTempPathA(MAX_PATH, temp_path);
     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
@@ -1278,6 +1279,7 @@
     ret = CreateDirectoryA(dirname, NULL);
     ok( ret, "Createdirectory failed, gle=%d\n", GetLastError() );
     /* set current drive & directory to known location */
+    GetCurrentDirectoryW( MAX_PATH, curdir);
     SetCurrentDirectoryA( temp_path );
     i = 0;
     while (p[i].file)
@@ -1332,7 +1334,7 @@
     }
     ret = RemoveDirectoryA(dirname);
     ok(ret, "RemoveDirectoryA: error %d\n", GetLastError());
-
+    SetCurrentDirectoryW(curdir);
 
     /* test opening directory as a directory */
     hFile = CreateFileA( temp_path, GENERIC_READ,
@@ -3450,6 +3452,11 @@
         "wrong error %u\n", GetLastError() );
     ok( r == FALSE, "should return false\n");
 
+    r = GetOverlappedResult( 0, &ov, &result, TRUE );
+    ok( r == TRUE, "should return TRUE\n" );
+    ok( result == 0xabcd, "wrong result %u\n", result );
+    ok( ov.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08lx\n", 
ov.Internal );
+
     ResetEvent( ov.hEvent );
 
     SetLastError( 0xb00 );
@@ -3845,17 +3852,13 @@
         if (i == 0 || i == 5)
         {
 /* FIXME: remove once Wine is fixed */
-if (i == 5) todo_wine
-            ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected 
ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
-else
+todo_wine_if (i == 5)
             ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected 
ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
         }
         else
         {
 /* FIXME: remove once Wine is fixed */
-if (i == 1) todo_wine
-            ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected 
ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
-else
+todo_wine_if (i == 1)
             ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected 
ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
         }
 
@@ -3867,9 +3870,7 @@
         else
         {
 /* FIXME: remove once Wine is fixed */
-if (i == 1) todo_wine
-            ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected 
ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
-else
+todo_wine_if (i == 1)
             ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected 
ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
         }
     }
@@ -4543,9 +4544,28 @@
     strcpy(dos_path, dos_prefix);
     strcat(dos_path, long_path);
 
+    count = pGetFinalPathNameByHandleA(INVALID_HANDLE_VALUE, NULL, 0, 
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    ok(count == 0, "Expected length 0, got %u\n", count);
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, 
got %u\n", GetLastError());
+
     file = CreateFileA(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                        CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
     ok(file != INVALID_HANDLE_VALUE, "CreateFileA error %u\n", GetLastError());
+
+    if (0) {
+        /* Windows crashes on NULL path */
+        count = pGetFinalPathNameByHandleA(file, NULL, MAX_PATH, 
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+        ok(count == 0, "Expected length 0, got %u\n", count);
+        ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected 
ERROR_INVALID_HANDLE, got %u\n", GetLastError());
+    }
+
+    /* Test 0-length path */
+    count = pGetFinalPathNameByHandleA(file, result_path, 0, 
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    ok(count == strlen(dos_path), "Expected length %u, got %u\n", 
lstrlenA(dos_path), count);
+
+    /* Test 0 and NULL path */
+    count = pGetFinalPathNameByHandleA(file, NULL, 0, FILE_NAME_NORMALIZED | 
VOLUME_NAME_DOS);
+    ok(count == strlen(dos_path), "Expected length %u, got %u\n", 
lstrlenA(dos_path), count);
 
     /* Test VOLUME_NAME_DOS with sufficient buffer size */
     memset(result_path, 0x11, sizeof(result_path));
@@ -4608,6 +4628,10 @@
     ok(count == 0, "Expected length 0, got %u\n", count);
     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, 
got %u\n", GetLastError());
 
+    count = pGetFinalPathNameByHandleW(INVALID_HANDLE_VALUE, NULL, 0, 
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    ok(count == 0, "Expected length 0, got %u\n", count);
+    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, 
got %u\n", GetLastError());
+
     count = GetTempPathW(MAX_PATH, temp_path);
     ok(count, "Failed to get temp path, error %u\n", GetLastError());
     ret = GetTempFileNameW(temp_path, prefix, 0, test_path);
@@ -4620,6 +4644,23 @@
     file = CreateFileW(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                        CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
     ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %u\n", GetLastError());
+
+    if (0) {
+        /* Windows crashes on NULL path */
+        count = pGetFinalPathNameByHandleW(file, NULL, MAX_PATH, 
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+        ok(count == 0, "Expected length 0, got %u\n", count);
+        ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected 
ERROR_INVALID_HANDLE, got %u\n", GetLastError());
+    }
+
+    /* Test 0-length path */
+    count = pGetFinalPathNameByHandleW(file, result_path, 0, 
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    ok(count == lstrlenW(dos_path) + 1 ||
+            broken(count == lstrlenW(dos_path) + 2), "Expected length %u, got 
%u\n", lstrlenW(dos_path) + 1, count);
+
+    /* Test 0 and NULL path */
+    count = pGetFinalPathNameByHandleW(file, NULL, 0, FILE_NAME_NORMALIZED | 
VOLUME_NAME_DOS);
+    ok(count == lstrlenW(dos_path) + 1 ||
+            broken(count == lstrlenW(dos_path) + 2), "Expected length %u, got 
%u\n", lstrlenW(dos_path) + 1, count);
 
     /* Test VOLUME_NAME_DOS with sufficient buffer size */
     memset(result_path, 0x11, sizeof(result_path));

Modified: trunk/rostests/winetests/kernel32/loader.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/loader.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/loader.c  [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/loader.c  [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -2750,6 +2750,24 @@
     DeleteFileA(dll_name);
 }
 
+static void test_InMemoryOrderModuleList(void)
+{
+    LIST_ENTRY *entry1, *mark1 = 
&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
+    LIST_ENTRY *entry2, *mark2 = 
&NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+    LDR_MODULE *module1, *module2;
+
+    for (entry1 = mark1->Flink, entry2 = mark2->Flink;
+         entry1 != mark1 && entry2 != mark2;
+         entry1 = entry1->Flink, entry2 = entry2->Flink)
+    {
+        module1 = CONTAINING_RECORD(entry1, LDR_MODULE, InLoadOrderModuleList);
+        module2 = CONTAINING_RECORD(entry2, LDR_MODULE, 
InMemoryOrderModuleList);
+        ok(module1 == module2, "expected module1 == module2, got %p and %p\n", 
module1, module2);
+    }
+    ok(entry1 == mark1, "expected entry1 == mark1, got %p and %p\n", entry1, 
mark1);
+    ok(entry2 == mark2, "expected entry2 == mark2, got %p and %p\n", entry2, 
mark2);
+}
+
 START_TEST(loader)
 {
     int argc;
@@ -2804,4 +2822,5 @@
     test_section_access();
     test_import_resolution();
     test_ExitProcess();
+    test_InMemoryOrderModuleList();
 }

Modified: trunk/rostests/winetests/kernel32/locale.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/locale.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/locale.c  [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/locale.c  [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -74,7 +74,6 @@
 }
 
 /* Some functions are only in later versions of kernel32.dll */
-static HMODULE hKernel32;
 static WORD enumCount;
 
 static INT (WINAPI *pGetTimeFormatEx)(LPCWSTR, DWORD, const SYSTEMTIME *, 
LPCWSTR, LPWSTR, INT);
@@ -101,12 +100,14 @@
 static INT (WINAPI *pGetGeoInfoW)(GEOID, GEOTYPE, LPWSTR, INT, LANGID);
 static BOOL (WINAPI *pEnumSystemGeoID)(GEOCLASS, GEOID, GEO_ENUMPROC);
 static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, 
ULONG*);
+static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, 
ULONG*);
+static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
 
 static void InitFunctionPointers(void)
 {
-  hKernel32 = GetModuleHandleA("kernel32");
-
-#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
+  HMODULE mod = GetModuleHandleA("kernel32");
+
+#define X(f) p##f = (void*)GetProcAddress(mod, #f)
   X(GetTimeFormatEx);
   X(GetDateFormatEx);
   X(EnumSystemLanguageGroupsA);
@@ -130,6 +131,10 @@
   X(GetGeoInfoW);
   X(EnumSystemGeoID);
   X(GetSystemPreferredUILanguages);
+  X(GetThreadPreferredUILanguages);
+
+  mod = GetModuleHandleA("ntdll");
+  X(RtlUpcaseUnicodeChar);
 #undef X
 }
 
@@ -2458,7 +2463,7 @@
     SetLastError(0xdeadbeef);
     lcid = pLocaleNameToLCID(fooW, 0);
     ok(!lcid && GetLastError() == ERROR_INVALID_PARAMETER,
-       "Expected lcid == 0, got got %08x, error %d\n", lcid, GetLastError());
+       "Expected lcid == 0, got %08x, error %d\n", lcid, GetLastError());
 
     /* english neutral name */
     lcid = pLocaleNameToLCID(enW, 0);
@@ -3767,6 +3772,18 @@
     GetStringTypeW(CT_CTYPE1, ch, 2, types);
     ok(types[0] == (C1_DEFINED|C1_SPACE), "got %x\n", types[0]);
     ok(types[1] == (C1_DEFINED|C1_SPACE), "got %x\n", types[1]);
+
+    /* check Arabic range for kashida flag */
+    for (ch[0] = 0x600; ch[0] <= 0x6ff; ch[0] += 1)
+    {
+        types[0] = 0;
+        ret = GetStringTypeW(CT_CTYPE3, ch, 1, types);
+        ok(ret, "%#x: failed %d\n", ch[0], ret);
+        if (ch[0] == 0x640) /* ARABIC TATWEEL (Kashida) */
+            ok(types[0] & C3_KASHIDA, "%#x: type %#x\n", ch[0], types[0]);
+        else
+            ok(!(types[0] & C3_KASHIDA), "%#x: type %#x\n", ch[0], types[0]);
+    }
 }
 
 static void test_IdnToNameprepUnicode(void)
@@ -4180,6 +4197,8 @@
     ok(!ret, "IsValidLocaleName should have failed\n");
     ret = pIsValidLocaleName(LOCALE_NAME_INVARIANT);
     ok(ret, "IsValidLocaleName failed\n");
+    ret = pIsValidLocaleName(NULL);
+    ok(!ret, "IsValidLocaleName should have failed\n");
 }
 
 static void test_CompareStringOrdinal(void)
@@ -4196,6 +4215,7 @@
     WCHAR coop2[] = { 'c','o','o','p',0 };
     WCHAR nonascii1[] = { 0x0102,0 };
     WCHAR nonascii2[] = { 0x0201,0 };
+    WCHAR ch1, ch2;
 
     if (!pCompareStringOrdinal)
     {
@@ -4252,6 +4272,21 @@
     ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN);
     ret = pCompareStringOrdinal(nonascii1, -1, nonascii2, -1, TRUE);
     ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN);
+
+    for (ch1 = 0; ch1 < 512; ch1++)
+    {
+        for (ch2 = 0; ch2 < 1024; ch2++)
+        {
+            int diff = ch1 - ch2;
+            ret = pCompareStringOrdinal( &ch1, 1, &ch2, 1, FALSE );
+            ok( ret == (diff > 0 ? CSTR_GREATER_THAN : diff < 0 ? 
CSTR_LESS_THAN : CSTR_EQUAL),
+                        "wrong result %d %04x %04x\n", ret, ch1, ch2 );
+            diff = pRtlUpcaseUnicodeChar( ch1 ) - pRtlUpcaseUnicodeChar( ch2 );
+            ret = pCompareStringOrdinal( &ch1, 1, &ch2, 1, TRUE );
+            ok( ret == (diff > 0 ? CSTR_GREATER_THAN : diff < 0 ? 
CSTR_LESS_THAN : CSTR_EQUAL),
+                        "wrong result %d %04x %04x\n", ret, ch1, ch2 );
+        }
+    }
 }
 
 static void test_GetGeoInfo(void)
@@ -4685,7 +4720,7 @@
     size_buffer = max(size_id, size_name);
     if(!size_buffer)
     {
-        skip("No vaild buffer size\n");
+        skip("No valid buffer size\n");
         return;
     }
 
@@ -4771,6 +4806,34 @@
     ok(!ret, "Expected GetSystemPreferredUILanguages to fail\n");
     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(),
        "Expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
+
+    HeapFree(GetProcessHeap(), 0, buffer);
+}
+
+static void test_GetThreadPreferredUILanguages(void)
+{
+    BOOL ret;
+    ULONG count, size;
+    WCHAR *buf;
+
+    if (!pGetThreadPreferredUILanguages)
+    {
+        win_skip("GetThreadPreferredUILanguages is not available.\n");
+        return;
+    }
+
+    size = count = 0;
+    ret = pGetThreadPreferredUILanguages(MUI_LANGUAGE_ID|MUI_UI_FALLBACK, 
&count, NULL, &size);
+    ok(ret, "got %u\n", GetLastError());
+    ok(count, "expected count > 0\n");
+    ok(size, "expected size > 0\n");
+
+    count = 0;
+    buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * sizeof(WCHAR));
+    ret = pGetThreadPreferredUILanguages(MUI_LANGUAGE_ID|MUI_UI_FALLBACK, 
&count, buf, &size);
+    ok(ret, "got %u\n", GetLastError());
+    ok(count, "expected count > 0\n");
+    HeapFree(GetProcessHeap(), 0, buf);
 }
 
 START_TEST(locale)
@@ -4816,5 +4879,6 @@
   test_EnumSystemGeoID();
   test_invariant();
   test_GetSystemPreferredUILanguages();
+  test_GetThreadPreferredUILanguages();
   test_sorting();
 }

Modified: trunk/rostests/winetests/kernel32/path.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/path.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/path.c    [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/path.c    [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -1116,10 +1116,9 @@
 {
     char save_TMP[MAX_PATH];
     char windir[MAX_PATH];
-    char origdir[MAX_PATH];
     char buf[MAX_PATH];
-
-    GetCurrentDirectoryA(sizeof(origdir), origdir);
+    WCHAR curdir[MAX_PATH];
+
     if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) 
save_TMP[0] = 0;
 
     /* test default configuration */
@@ -1151,6 +1150,7 @@
     test_GetTempPathA(windir);
     test_GetTempPathW(windir);
 
+    GetCurrentDirectoryW(MAX_PATH, curdir);
     /* TMP=C: i.e. use current working directory of the specified drive */
     GetWindowsDirectoryA(windir, sizeof(windir));
     SetCurrentDirectoryA(windir);
@@ -1164,13 +1164,13 @@
     test_GetTempPathW(windir);
 
     SetEnvironmentVariableA("TMP", save_TMP);
-    SetCurrentDirectoryA(origdir);
+    SetCurrentDirectoryW(curdir);
 }
 
 static void test_GetLongPathNameA(void)
 {
     DWORD length, explength, hostsize;
-    char tempfile[MAX_PATH];
+    char tempfile[MAX_PATH], *name;
     char longpath[MAX_PATH];
     char unc_prefix[MAX_PATH];
     char unc_short[MAX_PATH], unc_long[MAX_PATH];
@@ -1181,7 +1181,15 @@
         return;
 
     GetTempPathA(MAX_PATH, tempfile);
-    lstrcatA(tempfile, "longfilename.longext");
+    name = tempfile + strlen(tempfile);
+
+    strcpy(name, "*");
+    SetLastError(0xdeadbeef);
+    length = pGetLongPathNameA(tempfile, temppath, MAX_PATH);
+    ok(!length, "GetLongPathNameA should fail\n");
+    ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", 
GetLastError());
+
+    strcpy(name, "longfilename.longext");
 
     file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     CloseHandle(file);
@@ -1385,6 +1393,7 @@
     static const WCHAR name[] = { 't', 'e', 's', 't', 0 };
     static const WCHAR backSlash[] = { '\\', 0 };
     static const WCHAR a_bcdeW[] = {'a','.','b','c','d','e',0};
+    static const WCHAR wildW[] = { '*',0 };
     WCHAR path[MAX_PATH], tmppath[MAX_PATH], *ptr;
     WCHAR short_path[MAX_PATH];
     DWORD length;
@@ -1447,6 +1456,13 @@
     length = GetShortPathNameW( path, short_path, 
sizeof(short_path)/sizeof(*short_path) );
     ok( length, "GetShortPathNameW failed: %u.\n", GetLastError() );
 
+    lstrcpyW(ptr, wildW);
+    SetLastError(0xdeadbeef);
+    length = GetShortPathNameW( path, short_path, 
sizeof(short_path)/sizeof(*short_path) );
+    ok(!length, "GetShortPathNameW should fail\n");
+    ok(GetLastError() == ERROR_INVALID_NAME, "wrong error %d\n", 
GetLastError());
+
+    lstrcpyW(ptr, a_bcdeW);
     ret = DeleteFileW( path );
     ok( ret, "Cannot delete file.\n" );
     *ptr = 0;
@@ -2142,9 +2158,11 @@
     char path[MAX_PATH], buf[MAX_PATH];
     HANDLE file;
     int ret;
+    WCHAR curdir[MAX_PATH];
 
     if (!pGetLongPathNameA) return;
 
+    GetCurrentDirectoryW(MAX_PATH, curdir);
     GetTempPathA(MAX_PATH, path);
     ret = SetCurrentDirectoryA(path);
     ok(ret, "SetCurrentDirectory error %d\n", GetLastError());
@@ -2202,6 +2220,7 @@
     DeleteFileA("foo\\file");
     RemoveDirectoryA("foo");
     RemoveDirectoryA("bar");
+    SetCurrentDirectoryW(curdir);
 }
 
 static void test_CheckNameLegalDOS8Dot3(void)

Modified: trunk/rostests/winetests/kernel32/pipe.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/pipe.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/pipe.c    [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/pipe.c    [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -2571,6 +2571,64 @@
     CloseHandle(thread);
 }
 
+static void test_overlapped_error(void)
+{
+    HANDLE pipe, file, event;
+    DWORD err, numbytes;
+    OVERLAPPED overlapped;
+    BOOL ret;
+
+    event = CreateEventA(NULL, TRUE, FALSE, NULL);
+    ok(event != NULL, "CreateEventA failed with %u\n", GetLastError());
+
+    pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | 
FILE_FLAG_OVERLAPPED,
+                            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | 
PIPE_WAIT,
+                            1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
+    ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", 
GetLastError());
+
+    memset(&overlapped, 0, sizeof(overlapped));
+    overlapped.hEvent = event;
+    ret = ConnectNamedPipe(pipe, &overlapped);
+    err = GetLastError();
+    ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
+    ok(err == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", err);
+
+    file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+                       OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+    ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", 
GetLastError());
+
+    numbytes = 0xdeadbeef;
+    ret = GetOverlappedResult(pipe, &overlapped, &numbytes, TRUE);
+    ok(ret == TRUE, "GetOverlappedResult failed\n");
+    ok(numbytes == 0, "expected 0, got %u\n", numbytes);
+    ok(overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got 
%08lx\n", overlapped.Internal);
+
+    CloseHandle(file);
+    CloseHandle(pipe);
+
+    pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | 
FILE_FLAG_OVERLAPPED,
+                            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | 
PIPE_WAIT,
+                            1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
+    ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", 
GetLastError());
+
+    file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+                       OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+    ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", 
GetLastError());
+
+    memset(&overlapped, 0, sizeof(overlapped));
+    overlapped.hEvent = event;
+    ret = ConnectNamedPipe(pipe, &overlapped);
+    err = GetLastError();
+    ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
+    ok(err == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", 
err);
+    ok(overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got 
%08lx\n", overlapped.Internal);
+
+    CloseHandle(file);
+    CloseHandle(pipe);
+
+    CloseHandle(event);
+}
+
 static void test_nowait(int pipemode)
 {
     HANDLE hnp;
@@ -3400,6 +3458,7 @@
     test_CloseHandle();
     test_impersonation();
     test_overlapped();
+    test_overlapped_error();
     test_nowait(PIPE_TYPE_BYTE);
     test_nowait(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE);
     test_NamedPipeHandleState();

Modified: trunk/rostests/winetests/kernel32/process.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/process.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/process.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/process.c [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -88,6 +88,7 @@
 static BOOL   (WINAPI *pThread32First)(HANDLE, THREADENTRY32*);
 static BOOL   (WINAPI *pThread32Next)(HANDLE, THREADENTRY32*);
 static BOOL   (WINAPI 
*pGetLogicalProcessorInformationEx)(LOGICAL_PROCESSOR_RELATIONSHIP,SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*,DWORD*);
+static SIZE_T (WINAPI *pGetLargePageMinimum)(void);
 
 /* ############################### */
 static char     base[MAX_PATH];
@@ -252,6 +253,7 @@
     pThread32First = (void *)GetProcAddress(hkernel32, "Thread32First");
     pThread32Next = (void *)GetProcAddress(hkernel32, "Thread32Next");
     pGetLogicalProcessorInformationEx = (void *)GetProcAddress(hkernel32, 
"GetLogicalProcessorInformationEx");
+    pGetLargePageMinimum = (void *)GetProcAddress(hkernel32, 
"GetLargePageMinimum");
 
     return TRUE;
 }
@@ -2991,7 +2993,7 @@
         sizeof(buf) /* ProcessHandleTracing */,
         sizeof(ULONG) /* ProcessIoPriority */,
         sizeof(ULONG) /* ProcessExecuteFlags */,
-#if 0 /* FIXME: Add remaning classes */
+#if 0 /* FIXME: Add remaining classes */
         ProcessResourceManagement,
         sizeof(ULONG) /* ProcessCookie */,
         sizeof(SECTION_IMAGE_INFORMATION) /* ProcessImageInformation */,
@@ -3138,6 +3140,19 @@
     HeapFree(GetProcessHeap(), 0, info);
 }
 
+static void test_largepages(void)
+{
+    SIZE_T size;
+
+    if (!pGetLargePageMinimum) {
+        skip("No GetLargePageMinimum support.\n");
+        return;
+    }
+    size = pGetLargePageMinimum();
+
+    ok((size == 0) || (size == 2*1024*1024) || (size == 4*1024*1024), 
"GetLargePageMinimum reports %ld size\n", size);
+}
+
 START_TEST(process)
 {
     HANDLE job;
@@ -3210,6 +3225,7 @@
     test_GetNumaProcessorNode();
     test_session_info();
     test_GetLogicalProcessorInformationEx();
+    test_largepages();
 
     /* things that can be tested:
      *  lookup:         check the way program to be executed is searched

Modified: trunk/rostests/winetests/kernel32/sync.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/sync.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/sync.c    [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/sync.c    [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -1740,9 +1740,9 @@
 
 /* Sequence of wake/sleep to check boundary conditions:
  * 0: init
- * 1: producer emits a WakeConditionVaribale without consumer waiting.
+ * 1: producer emits a WakeConditionVariable without consumer waiting.
  * 2: consumer sleeps without a wake expecting timeout
- * 3: producer emits a WakeAllConditionVaribale without consumer waiting.
+ * 3: producer emits a WakeAllConditionVariable without consumer waiting.
  * 4: consumer sleeps without a wake expecting timeout
  * 5: a wake is handed to a SleepConditionVariableCS
  * 6: a wakeall is handed to a SleepConditionVariableCS

Modified: trunk/rostests/winetests/kernel32/virtual.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/kernel32/virtual.c?rev=71910&r1=71909&r2=71910&view=diff
==============================================================================
--- trunk/rostests/winetests/kernel32/virtual.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/kernel32/virtual.c [iso-8859-1] Tue Jul 12 
21:10:24 2016
@@ -43,7 +43,6 @@
 static NTSTATUS (WINAPI *pNtAreMappedFilesTheSame)(PVOID,PVOID);
 static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG, 
SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG);
 static DWORD (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID);
-static struct _TEB * (WINAPI *pNtCurrentTeb)(void);
 static PVOID  (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG, 
PVECTORED_EXCEPTION_HANDLER);
 static ULONG  (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID);
 static BOOL   (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL);
@@ -454,7 +453,7 @@
     SetLastError(0xdeadbeef);
     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
CREATE_ALWAYS, 0, 0 );
     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() 
);
-    SetFilePointer( file, 4096, NULL, FILE_BEGIN );
+    SetFilePointer( file, 12288, NULL, FILE_BEGIN );
     SetEndOfFile( file );
 
     /* read/write mapping */
@@ -1013,6 +1012,31 @@
     ok(info.State == MEM_FREE, "%#x != MEM_FREE\n", info.State);
     ok(info.Type == 0, "%#x != 0\n", info.Type);
 
+    mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 12288, NULL );
+    ok( mapping != 0, "CreateFileMappingA failed with error %u\n", 
GetLastError() );
+
+    ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 );
+    ok( ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError() );
+
+    ret = UnmapViewOfFile( (char *)ptr + 100 );
+    ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() );
+    if (!ret) UnmapViewOfFile( ptr );
+
+    ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 );
+    ok( ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError() );
+
+    ret = UnmapViewOfFile( (char *)ptr + 4096 );
+    ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() );
+    if (!ret) UnmapViewOfFile( ptr );
+
+    ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 );
+    ok( ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError() );
+
+    ret = UnmapViewOfFile( (char *)ptr + 4096 + 100 );
+    ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() );
+    if (!ret) UnmapViewOfFile( ptr );
+
+    CloseHandle(mapping);
     CloseHandle(file);
     DeleteFileA(testfile);
 }
@@ -1824,263 +1848,14 @@
     VirtualFree( base, 0, MEM_RELEASE );
 }
 
-#ifdef __i386__
-
-static DWORD num_guard_page_calls;
-
-static DWORD guard_page_handler( EXCEPTION_RECORD *rec, 
EXCEPTION_REGISTRATION_RECORD *frame,
-                                 CONTEXT *context, 
EXCEPTION_REGISTRATION_RECORD **dispatcher )
-{
-    trace( "exception: %08x flags:%x addr:%p\n",
-           rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
-
-    ok( rec->NumberParameters == 2, "NumberParameters is %d instead of 2\n", 
rec->NumberParameters );
-    ok( rec->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION, "ExceptionCode is 
%08x instead of %08x\n",
-        rec->ExceptionCode, STATUS_GUARD_PAGE_VIOLATION );
-
-    num_guard_page_calls++;
-    *(int *)rec->ExceptionInformation[1] += 0x100;
-
-    return ExceptionContinueExecution;
-}
-
-static void test_guard_page(void)
-{
-    EXCEPTION_REGISTRATION_RECORD frame;
-    MEMORY_BASIC_INFORMATION info;
-    DWORD ret, size, old_prot;
-    int *value, old_value;
-    void *results[64];
-    ULONG_PTR count;
-    ULONG pagesize;
-    BOOL success;
-    char *base;
-
-    if (!pNtCurrentTeb)
-    {
-        win_skip( "NtCurrentTeb not supported\n" );
-        return;
-    }
-
-    size = 0x1000;
-    base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | 
PAGE_GUARD );
-    ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
-    value = (int *)base;
-
-    /* verify info structure */
-    ret = VirtualQuery( base, &info, sizeof(info) );
-    ok( ret, "VirtualQuery failed %u\n", GetLastError());
-    ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", 
info.BaseAddress, base );
-    ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong 
AllocationProtect %x\n", info.AllocationProtect );
-    ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
-    ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
-    ok( info.Protect == (PAGE_READWRITE | PAGE_GUARD), "wrong Protect 0x%x\n", 
info.Protect );
-    ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
-
-    /* put some initial value into the memory */
-    success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
-    ok( success, "VirtualProtect failed %u\n", GetLastError() );
-    ok( old_prot == (PAGE_READWRITE | PAGE_GUARD), "wrong old prot %x\n", 
old_prot );
-
-    *value       = 1;
-    *(value + 1) = 2;
-
-    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
-    ok( success, "VirtualProtect failed %u\n", GetLastError() );
-    ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
-
-    /* test behaviour of VirtualLock - first attempt should fail */
-    SetLastError( 0xdeadbeef );
-    success = VirtualLock( base, size );
-    ok( !success, "VirtualLock unexpectedly succeeded\n" );
-    todo_wine
-    ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION, "wrong error %u\n", 
GetLastError() );
-
-    success = VirtualLock( base, size );
-    todo_wine
-    ok( success, "VirtualLock failed %u\n", GetLastError() );
-    if (success)
-    {
-        ok( *value == 1, "memory block contains wrong value, expected 1, got 
0x%x\n", *value );
-        success = VirtualUnlock( base, size );
-        ok( success, "VirtualUnlock failed %u\n", GetLastError() );
-    }
-
-    /* check info structure again, PAGE_GUARD should be removed now */
-    ret = VirtualQuery( base, &info, sizeof(info) );
-    ok( ret, "VirtualQuery failed %u\n", GetLastError());
-    ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", 
info.BaseAddress, base );
-    ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong 
AllocationProtect %x\n", info.AllocationProtect );
-    ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
-    ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
-    todo_wine
-    ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
-    ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
-
-    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
-    ok( success, "VirtualProtect failed %u\n", GetLastError() );
-    todo_wine
-    ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
-
-    /* test directly accessing the memory - we need to setup an exception 
handler first */
-    frame.Handler = guard_page_handler;
-    frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
-    pNtCurrentTeb()->Tib.ExceptionList = &frame;
-
-    num_guard_page_calls = 0;
-    old_value = *value; /* exception handler increments value by 0x100 */
-    *value = 2;
-    ok( old_value == 0x101, "memory block contains wrong value, expected 
0x101, got 0x%x\n", old_value );
-    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
-
-    pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
-
-    /* check info structure again, PAGE_GUARD should be removed now */
-    ret = VirtualQuery( base, &info, sizeof(info) );
-    ok( ret, "VirtualQuery failed %u\n", GetLastError());
-    ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
-
-    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
-    ok( success, "VirtualProtect failed %u\n", GetLastError() );
-    ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
-
-    /* test accessing second integer in memory */
-    frame.Handler = guard_page_handler;
-    frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
-    pNtCurrentTeb()->Tib.ExceptionList = &frame;
-
-    num_guard_page_calls = 0;
-    old_value = *(value + 1);
-    ok( old_value == 0x102, "memory block contains wrong value, expected 
0x102, got 0x%x\n", old_value );
-    ok( *value == 2, "memory block contains wrong value, expected 2, got 
0x%x\n", *value );
-    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
-
-    pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
-
-    success = VirtualLock( base, size );
-    ok( success, "VirtualLock failed %u\n", GetLastError() );
-    if (success)
-    {
-        ok( *value == 2, "memory block contains wrong value, expected 2, got 
0x%x\n", *value );
-        success = VirtualUnlock( base, size );
-        ok( success, "VirtualUnlock failed %u\n", GetLastError() );
-    }
-
-    VirtualFree( base, 0, MEM_RELEASE );
-
-    /* combined guard page / write watch tests */
-    if (!pGetWriteWatch || !pResetWriteWatch)
-    {
-        win_skip( "GetWriteWatch not supported, skipping combined guard page / 
write watch tests\n" );
-        return;
-    }
-
-    base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, 
PAGE_READWRITE | PAGE_GUARD  );
-    if (!base && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() 
== ERROR_NOT_SUPPORTED))
-    {
-        win_skip( "MEM_WRITE_WATCH not supported\n" );
-        return;
-    }
-    ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
-    value = (int *)base;
-
-    ret = VirtualQuery( base, &info, sizeof(info) );
-    ok( ret, "VirtualQuery failed %u\n", GetLastError() );
-    ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", 
info.BaseAddress, base );
-    ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong 
AllocationProtect %x\n", info.AllocationProtect );
-    ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
-    ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
-    ok( info.Protect == (PAGE_READWRITE | PAGE_GUARD), "wrong Protect 0x%x\n", 
info.Protect );
-    ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
-
-    count = 64;
-    ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
-    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
-    ok( count == 0, "wrong count %lu\n", count );
-
-    /* writing to a page should trigger should trigger guard page, even if 
write watch is set */
-    frame.Handler = guard_page_handler;
-    frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
-    pNtCurrentTeb()->Tib.ExceptionList = &frame;
-
-    num_guard_page_calls = 0;
-    *value       = 1;
-    *(value + 1) = 2;
-    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
-
-    pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
-
-    count = 64;
-    ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, 
&pagesize );
-    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
-    ok( count == 1, "wrong count %lu\n", count );
-    ok( results[0] == base, "wrong result %p\n", results[0] );
-
-    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
-    ok( success, "VirtualProtect failed %u\n", GetLastError() );
-
-    /* write watch is triggered from inside of the guard page handler */
-    frame.Handler = guard_page_handler;
-    frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
-    pNtCurrentTeb()->Tib.ExceptionList = &frame;
-
-    num_guard_page_calls = 0;
-    old_value = *(value + 1); /* doesn't trigger write watch */
-    ok( old_value == 0x102, "memory block contains wrong value, expected 
0x102, got 0x%x\n", old_value );
-    ok( *value == 1, "memory block contains wrong value, expected 1, got 
0x%x\n", *value );
-    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
-
-    pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
-
-    count = 64;
-    ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, 
&pagesize );
-    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
-    ok( count == 1, "wrong count %lu\n", count );
-    ok( results[0] == base, "wrong result %p\n", results[0] );
-
-    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
-    ok( success, "VirtualProtect failed %u\n", GetLastError() );
-
-    /* test behaviour of VirtualLock - first attempt should fail without 
triggering write watches */
-    SetLastError( 0xdeadbeef );
-    success = VirtualLock( base, size );
-    ok( !success, "VirtualLock unexpectedly succeeded\n" );
-    todo_wine
-    ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION, "wrong error %u\n", 
GetLastError() );
-
-    count = 64;
-    ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
-    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
-    ok( count == 0, "wrong count %lu\n", count );
-
-    success = VirtualLock( base, size );
-    todo_wine
-    ok( success, "VirtualLock failed %u\n", GetLastError() );
-    if (success)
-    {
-        ok( *value == 1, "memory block contains wrong value, expected 1, got 
0x%x\n", *value );
-        success = VirtualUnlock( base, size );
-        ok( success, "VirtualUnlock failed %u\n", GetLastError() );
-    }
-
-    count = 64;
-    results[0] = (void *)0xdeadbeef;
-    ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, 
&pagesize );
-    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
-    todo_wine
-    ok( count == 1 || broken(count == 0) /* Windows 8 */, "wrong count %lu\n", 
count );
-    todo_wine
-    ok( results[0] == base || broken(results[0] == (void *)0xdeadbeef) /* 
Windows 8 */, "wrong result %p\n", results[0] );
-
-    VirtualFree( base, 0, MEM_RELEASE );
-}
+#if defined(__i386__) || defined(__x86_64__)
 
 static DWORD WINAPI stack_commit_func( void *arg )
 {
     volatile char *p = (char *)&p;
 
     /* trigger all guard pages, to ensure that the pages are committed */
-    while (p >= (char *)pNtCurrentTeb()->DeallocationStack + 3 * 0x1000)
+    while (p >= (char *)NtCurrentTeb()->DeallocationStack + 4 * 0x1000)
     {
         p[0] |= 0;
         p -= 0x1000;
@@ -2092,6 +1867,7 @@
 
 static void test_stack_commit(void)
 {
+#ifdef __i386__
     static const char code_call_on_stack[] = {
         0x55,                   /* pushl %ebp */
         0x56,                   /* pushl %esi */
@@ -2109,17 +1885,24 @@
         0x5e,                   /* popl %esi */
         0x5d,                   /* popl %ebp */
         0xc2, 0x0c, 0x00 };     /* ret $12 */
-
+#else
+    static const char code_call_on_stack[] = {
+        0x55,                   /* pushq %rbp */
+        0x48, 0x89, 0xe5,       /* movq %rsp,%rbp */
+                                /* %rcx - func, %rdx - arg, %r8 - stack */
+        0x48, 0x87, 0xca,       /* xchgq %rcx,%rdx */
+        0x49, 0x83, 0xe0, 0xf0, /* andq $~15,%r8 */
+        0x49, 0x83, 0xe8, 0x20, /* subq $0x20,%r8 */
+        0x4c, 0x89, 0xc4,       /* movq %r8,%rsp */
+        0xff, 0xd2,             /* callq *%rdx */
+        0x48, 0x89, 0xec,       /* movq %rbp,%rsp */
+        0x5d,                   /* popq %rbp */
+        0xc3 };                 /* ret */
+#endif
     DWORD (WINAPI *call_on_stack)( DWORD (WINAPI *func)(void *), void *arg, 
void *stack );
     void *old_stack, *old_stack_base, *old_stack_limit;
     void *new_stack, *new_stack_base;
     DWORD result;
-
-    if (!pNtCurrentTeb)
-    {
-        win_skip( "NtCurrentTeb not supported\n" );
-        return;
-    }
 
     call_on_stack = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, 
PAGE_EXECUTE_READWRITE );
     ok( call_on_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
@@ -2131,26 +1914,273 @@
     new_stack_base = (char *)new_stack + 0x400000;
     VirtualAlloc( (char *)new_stack_base - 0x1000, 0x1000, MEM_COMMIT, 
PAGE_READWRITE | PAGE_GUARD );
 
-    old_stack       = pNtCurrentTeb()->DeallocationStack;
-    old_stack_base  = pNtCurrentTeb()->Tib.StackBase;
-    old_stack_limit = pNtCurrentTeb()->Tib.StackLimit;
-
-    pNtCurrentTeb()->DeallocationStack  = new_stack;
-    pNtCurrentTeb()->Tib.StackBase      = new_stack_base;
-    pNtCurrentTeb()->Tib.StackLimit     = new_stack_base;
+    old_stack       = NtCurrentTeb()->DeallocationStack;
+    old_stack_base  = NtCurrentTeb()->Tib.StackBase;
+    old_stack_limit = NtCurrentTeb()->Tib.StackLimit;
+
+    NtCurrentTeb()->DeallocationStack  = new_stack;
+    NtCurrentTeb()->Tib.StackBase      = new_stack_base;
+    NtCurrentTeb()->Tib.StackLimit     = new_stack_base;
 
     result = call_on_stack( stack_commit_func, (void *)0xdeadbeef, 
new_stack_base );
+
+    NtCurrentTeb()->DeallocationStack  = old_stack;
+    NtCurrentTeb()->Tib.StackBase      = old_stack_base;
+    NtCurrentTeb()->Tib.StackLimit     = old_stack_limit;
+
     ok( result == 42, "expected 42, got %u\n", result );
-
-    pNtCurrentTeb()->DeallocationStack  = old_stack;
-    pNtCurrentTeb()->Tib.StackBase      = old_stack_base;
-    pNtCurrentTeb()->Tib.StackLimit     = old_stack_limit;
 
     VirtualFree( new_stack, 0, MEM_RELEASE );
     VirtualFree( call_on_stack, 0, MEM_RELEASE );
 }
 
-DWORD num_execute_fault_calls;
+#endif  /* defined(__i386__) || defined(__x86_64__) */
+#ifdef __i386__
+
+static LONG num_guard_page_calls;
+
+static DWORD guard_page_handler( EXCEPTION_RECORD *rec, 
EXCEPTION_REGISTRATION_RECORD *frame,
+                                 CONTEXT *context, 
EXCEPTION_REGISTRATION_RECORD **dispatcher )
+{
+    trace( "exception: %08x flags:%x addr:%p\n",
+           rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
+
+    ok( rec->NumberParameters == 2, "NumberParameters is %d instead of 2\n", 
rec->NumberParameters );
+    ok( rec->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION, "ExceptionCode is 
%08x instead of %08x\n",
+        rec->ExceptionCode, STATUS_GUARD_PAGE_VIOLATION );
+
+    InterlockedIncrement( &num_guard_page_calls );
+    *(int *)rec->ExceptionInformation[1] += 0x100;
+
+    return ExceptionContinueExecution;
+}
+
+static void test_guard_page(void)
+{
+    EXCEPTION_REGISTRATION_RECORD frame;
+    MEMORY_BASIC_INFORMATION info;
+    DWORD ret, size, old_prot;
+    int *value, old_value;
+    void *results[64];
+    ULONG_PTR count;
+    ULONG pagesize;
+    BOOL success;
+    char *base;
+
+    size = 0x1000;
+    base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | 
PAGE_GUARD );
+    ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
+    value = (int *)base;
+
+    /* verify info structure */
+    ret = VirtualQuery( base, &info, sizeof(info) );
+    ok( ret, "VirtualQuery failed %u\n", GetLastError());
+    ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", 
info.BaseAddress, base );
+    ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong 
AllocationProtect %x\n", info.AllocationProtect );
+    ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
+    ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
+    ok( info.Protect == (PAGE_READWRITE | PAGE_GUARD), "wrong Protect 0x%x\n", 
info.Protect );
+    ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
+
+    /* put some initial value into the memory */
+    success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
+    ok( success, "VirtualProtect failed %u\n", GetLastError() );
+    ok( old_prot == (PAGE_READWRITE | PAGE_GUARD), "wrong old prot %x\n", 
old_prot );
+
+    *value       = 1;
+    *(value + 1) = 2;
+
+    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
+    ok( success, "VirtualProtect failed %u\n", GetLastError() );
+    ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
+
+    /* test behaviour of VirtualLock - first attempt should fail */
+    SetLastError( 0xdeadbeef );
+    success = VirtualLock( base, size );
+    ok( !success, "VirtualLock unexpectedly succeeded\n" );
+    todo_wine
+    ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION, "wrong error %u\n", 
GetLastError() );
+
+    success = VirtualLock( base, size );
+    todo_wine
+    ok( success, "VirtualLock failed %u\n", GetLastError() );
+    if (success)
+    {
+        ok( *value == 1, "memory block contains wrong value, expected 1, got 
0x%x\n", *value );
+        success = VirtualUnlock( base, size );
+        ok( success, "VirtualUnlock failed %u\n", GetLastError() );
+    }
+
+    /* check info structure again, PAGE_GUARD should be removed now */
+    ret = VirtualQuery( base, &info, sizeof(info) );
+    ok( ret, "VirtualQuery failed %u\n", GetLastError());
+    ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", 
info.BaseAddress, base );
+    ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong 
AllocationProtect %x\n", info.AllocationProtect );
+    ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
+    ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
+    todo_wine
+    ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
+    ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
+
+    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
+    ok( success, "VirtualProtect failed %u\n", GetLastError() );
+    todo_wine
+    ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
+
+    /* test directly accessing the memory - we need to setup an exception 
handler first */
+    frame.Handler = guard_page_handler;
+    frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
+    NtCurrentTeb()->Tib.ExceptionList = &frame;
+
+    InterlockedExchange( &num_guard_page_calls, 0 );
+    InterlockedExchange( &old_value, *value ); /* exception handler increments 
value by 0x100 */
+    *value = 2;
+    ok( old_value == 0x101, "memory block contains wrong value, expected 
0x101, got 0x%x\n", old_value );
+    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
+
+    NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
+
+    /* check info structure again, PAGE_GUARD should be removed now */
+    ret = VirtualQuery( base, &info, sizeof(info) );
+    ok( ret, "VirtualQuery failed %u\n", GetLastError());
+    ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
+
+    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
+    ok( success, "VirtualProtect failed %u\n", GetLastError() );
+    ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
+
+    /* test accessing second integer in memory */
+    frame.Handler = guard_page_handler;
+    frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
+    NtCurrentTeb()->Tib.ExceptionList = &frame;
+
+    InterlockedExchange( &num_guard_page_calls, 0 );
+    old_value = *(value + 1);
+    ok( old_value == 0x102, "memory block contains wrong value, expected 
0x102, got 0x%x\n", old_value );
+    ok( *value == 2, "memory block contains wrong value, expected 2, got 
0x%x\n", *value );
+    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
+
+    NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
+
+    success = VirtualLock( base, size );
+    ok( success, "VirtualLock failed %u\n", GetLastError() );
+    if (success)
+    {
+        ok( *value == 2, "memory block contains wrong value, expected 2, got 
0x%x\n", *value );
+        success = VirtualUnlock( base, size );
+        ok( success, "VirtualUnlock failed %u\n", GetLastError() );
+    }
+
+    VirtualFree( base, 0, MEM_RELEASE );
+
+    /* combined guard page / write watch tests */
+    if (!pGetWriteWatch || !pResetWriteWatch)
+    {
+        win_skip( "GetWriteWatch not supported, skipping combined guard page / 
write watch tests\n" );
+        return;
+    }
+
+    base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, 
PAGE_READWRITE | PAGE_GUARD  );
+    if (!base && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() 
== ERROR_NOT_SUPPORTED))
+    {
+        win_skip( "MEM_WRITE_WATCH not supported\n" );
+        return;
+    }
+    ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
+    value = (int *)base;
+
+    ret = VirtualQuery( base, &info, sizeof(info) );
+    ok( ret, "VirtualQuery failed %u\n", GetLastError() );
+    ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", 
info.BaseAddress, base );
+    ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong 
AllocationProtect %x\n", info.AllocationProtect );
+    ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
+    ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
+    ok( info.Protect == (PAGE_READWRITE | PAGE_GUARD), "wrong Protect 0x%x\n", 
info.Protect );
+    ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
+
+    count = 64;
+    ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
+    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
+    ok( count == 0, "wrong count %lu\n", count );
+
+    /* writing to a page should trigger should trigger guard page, even if 
write watch is set */
+    frame.Handler = guard_page_handler;
+    frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
+    NtCurrentTeb()->Tib.ExceptionList = &frame;
+
+    InterlockedExchange( &num_guard_page_calls, 0 );
+    *value       = 1;
+    *(value + 1) = 2;
+    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
+
+    NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
+
+    count = 64;
+    ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, 
&pagesize );
+    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
+    ok( count == 1, "wrong count %lu\n", count );
+    ok( results[0] == base, "wrong result %p\n", results[0] );
+
+    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
+    ok( success, "VirtualProtect failed %u\n", GetLastError() );
+
+    /* write watch is triggered from inside of the guard page handler */
+    frame.Handler = guard_page_handler;
+    frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
+    NtCurrentTeb()->Tib.ExceptionList = &frame;
+
+    InterlockedExchange( &num_guard_page_calls, 0 );
+    old_value = *(value + 1); /* doesn't trigger write watch */
+    ok( old_value == 0x102, "memory block contains wrong value, expected 
0x102, got 0x%x\n", old_value );
+    ok( *value == 1, "memory block contains wrong value, expected 1, got 
0x%x\n", *value );
+    ok( num_guard_page_calls == 1, "expected one callback of guard page 
handler, got %d calls\n", num_guard_page_calls );
+
+    NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
+
+    count = 64;
+    ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, 
&pagesize );
+    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
+    ok( count == 1, "wrong count %lu\n", count );
+    ok( results[0] == base, "wrong result %p\n", results[0] );
+
+    success = VirtualProtect( base, size, PAGE_READWRITE | PAGE_GUARD, 
&old_prot );
+    ok( success, "VirtualProtect failed %u\n", GetLastError() );
+
+    /* test behaviour of VirtualLock - first attempt should fail without 
triggering write watches */
+    SetLastError( 0xdeadbeef );
+    success = VirtualLock( base, size );
+    ok( !success, "VirtualLock unexpectedly succeeded\n" );
+    todo_wine
+    ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION, "wrong error %u\n", 
GetLastError() );
+
+    count = 64;
+    ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
+    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
+    ok( count == 0, "wrong count %lu\n", count );
+
+    success = VirtualLock( base, size );
+    todo_wine
+    ok( success, "VirtualLock failed %u\n", GetLastError() );
+    if (success)
+    {
+        ok( *value == 1, "memory block contains wrong value, expected 1, got 
0x%x\n", *value );
+        success = VirtualUnlock( base, size );
+        ok( success, "VirtualUnlock failed %u\n", GetLastError() );
+    }
+
+    count = 64;
+    results[0] = (void *)0xdeadbeef;
+    ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, 
&pagesize );
+    ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
+    todo_wine
+    ok( count == 1 || broken(count == 0) /* Windows 8 */, "wrong count %lu\n", 
count );
+    todo_wine
+    ok( results[0] == base || broken(results[0] == (void *)0xdeadbeef) /* 
Windows 8 */, "wrong result %p\n", results[0] );
+
+    VirtualFree( base, 0, MEM_RELEASE );
+}
+
+static LONG num_execute_fault_calls;
 
 static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, 
EXCEPTION_REGISTRATION_RECORD *frame,
                                         CONTEXT *context, 
EXCEPTION_REGISTRATION_RECORD **dispatcher )
@@ -2175,7 +2205,7 @@
         ok( rec->ExceptionInformation[0] == err, "ExceptionInformation[0] is 
%d instead of %d\n",
             (DWORD)rec->ExceptionInformation[0], err );
 
-        num_guard_page_calls++;
+        InterlockedIncrement( &num_guard_page_calls );
     }
     else if (rec->ExceptionCode == STATUS_ACCESS_VIOLATION)
     {
@@ -2190,7 +2220,7 @@
         ok( success, "VirtualProtect failed %u\n", GetLastError() );
         ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
 
-        num_execute_fault_calls++;
+        InterlockedIncrement( &num_execute_fault_calls );
     }
 
     return ExceptionContinueExecution;
@@ -2211,7 +2241,7 @@
         "ExceptionCode is %08x instead of STATUS_ACCESS_VIOLATION\n", 
rec->ExceptionCode );
 
     if (rec->ExceptionCode == STATUS_ACCESS_VIOLATION)
-        num_execute_fault_calls++;
+        InterlockedIncrement( &num_execute_fault_calls );
 
     if (rec->ExceptionInformation[0] == EXCEPTION_READ_FAULT)
         return EXCEPTION_CONTINUE_SEARCH;
@@ -2229,13 +2259,14 @@
     DWORD ret;
 
     frame.Handler = execute_fault_seh_handler;
-    frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
-    pNtCurrentTeb()->Tib.ExceptionList = &frame;
-
-    num_guard_page_calls = num_execute_fault_calls = 0;
+    frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
+    NtCurrentTeb()->Tib.ExceptionList = &frame;
+
+    InterlockedExchange( &num_guard_page_calls, 0 );
+    InterlockedExchange( &num_execute_fault_calls, 0 );
     ret = SendMessageA( hWnd, uMsg, wParam, lParam );
 
-    pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
+    NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
 
     return ret;
 }
@@ -2246,13 +2277,14 @@
     DWORD ret;
 
     frame.Handler = execute_fault_seh_handler;
-    frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
-    pNtCurrentTeb()->Tib.ExceptionList = &frame;
-
-    num_guard_page_calls = num_execute_fault_calls = 0;
+    frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
+    NtCurrentTeb()->Tib.ExceptionList = &frame;
+
+    InterlockedExchange( &num_guard_page_calls, 0 );
+    InterlockedExchange( &num_execute_fault_calls, 0 );
     ret = code( arg );
 
-    pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
+    NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
 
     return ret;
 }
@@ -2299,12 +2331,6 @@
     char *base;
     HWND hWnd;
 
-    if (!pNtCurrentTeb)
-    {
-        win_skip( "NtCurrentTeb not supported\n" );
-        return;
-    }
-
     trace( "Running DEP tests with ProcessExecuteFlags = %d\n", dep_flags );
 
     NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, 
&old_flags, sizeof(old_flags), NULL );
@@ -2608,7 +2634,7 @@
     ok( count == 1, "wrong count %lu\n", count );
     ok( results[0] == base, "wrong result %p\n", results[0] );
 
-    /* Create a new window class and associcated Window (see above) */
+    /* Create a new window class and associated Window (see above) */
 
     success = VirtualProtect( base, size, PAGE_EXECUTE_READWRITE, &old_prot );
     ok( success, "VirtualProtect failed %u\n", GetLastError() );
@@ -3296,7 +3322,9 @@
                 SetLastError(0xdeadbeef);
                 ret = VirtualQuery(base, &info, sizeof(info));
                 ok(ret, "VirtualQuery failed %d\n", GetLastError());
-                ok(info.Protect == td[i].prot_after_write, "%d: got %#x != 
expected %#x\n", i, info.Protect, td[i].prot_after_write);
+                /* FIXME: remove the condition below once Wine is fixed */
+                todo_wine_if (td[i].prot == PAGE_WRITECOPY || td[i].prot == 
PAGE_EXECUTE_WRITECOPY)
+                    ok(info.Protect == td[i].prot_after_write, "%d: got %#x != 
expected %#x\n", i, info.Protect, td[i].prot_after_write);
             }
         }
         else
@@ -3310,7 +3338,9 @@
         SetLastError(0xdeadbeef);
         ret = VirtualProtect(base, si.dwPageSize, PAGE_NOACCESS, &old_prot);
         ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError());
-        ok(old_prot == td[i].prot_after_write, "%d: got %#x != expected 
%#x\n", i, old_prot, td[i].prot_after_write);
+        /* FIXME: remove the condition below once Wine is fixed */
+        todo_wine_if (td[i].prot == PAGE_WRITECOPY || td[i].prot == 
PAGE_EXECUTE_WRITECOPY)
+            ok(old_prot == td[i].prot_after_write, "%d: got %#x != expected 
%#x\n", i, old_prot, td[i].prot_after_write);
     }
 
     UnmapViewOfFile(base);
@@ -3840,7 +3870,6 @@
     ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", 
info.basic.BaseAddress);
 todo_wine
     ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", 
info.basic.Attributes);
-todo_wine
     ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", 
fsize, info.basic.Size.HighPart, info.basic.Size.LowPart);
 
     status = pNtQuerySection(mapping, SectionImageInformation, &info, 
sizeof(info.basic), &ret);
@@ -3864,7 +3893,6 @@
     ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", 
info.basic.BaseAddress);
 todo_wine
     ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", 
info.basic.Attributes);
-todo_wine
     ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", 
fsize, info.basic.Size.HighPart, info.basic.Size.LowPart);
 
     UnmapViewOfFile(p);
@@ -3950,16 +3978,13 @@
     ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", 
info.basic.BaseAddress);
 todo_wine
     ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", 
info.basic.Attributes);
-todo_wine
     ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", 
fsize, info.basic.Size.HighPart, info.basic.Size.LowPart);
 
     CloseHandle(mapping);
 
     SetLastError(0xdeadbef);
     mapping = CreateFileMappingA(file, NULL, PAGE_READONLY|SEC_RESERVE, 0, 0, 
NULL);
-todo_wine
     ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError());
-    if (!mapping) goto skip1;
 
     memset(&info, 0x55, sizeof(info));
     ret = 0xdeadbeef;
@@ -3967,11 +3992,11 @@
     ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status);
     ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret);
     ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", 
info.basic.BaseAddress);
+todo_wine
     ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", 
info.basic.Attributes);
     ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", 
fsize, info.basic.Size.HighPart, info.basic.Size.LowPart);
 
     CloseHandle(mapping);
-skip1:
     CloseHandle(file);
 
     SetLastError(0xdeadbef);
@@ -4076,7 +4101,6 @@
     pNtAreMappedFilesTheSame = (void *)GetProcAddress( hntdll, 
"NtAreMappedFilesTheSame" );
     pNtMapViewOfSection = (void *)GetProcAddress( hntdll, "NtMapViewOfSection" 
);
     pNtUnmapViewOfSection = (void *)GetProcAddress( hntdll, 
"NtUnmapViewOfSection" );
-    pNtCurrentTeb = (void *)GetProcAddress( hntdll, "NtCurrentTeb" );
     pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, 
"RtlAddVectoredExceptionHandler" );
     pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, 
"RtlRemoveVectoredExceptionHandler" );
     pNtQuerySection = (void *)GetProcAddress( hntdll, "NtQuerySection" );
@@ -4103,7 +4127,9 @@
     test_IsBadWritePtr();
     test_IsBadCodePtr();
     test_write_watch();
+#if defined(__i386__) || defined(__x86_64__)
     test_stack_commit();
+#endif
 #ifdef __i386__
     if (!winetest_interactive)
     {


Reply via email to