mirror of
https://github.com/reactos/reactos.git
synced 2025-07-24 12:23:41 +00:00
[KERNEL32_WINETEST] Sync with Wine Staging 1.9.14 except thread tests. CORE-11511
svn path=/trunk/; revision=71910
This commit is contained in:
parent
54f3884769
commit
5ec6f3d9fc
12 changed files with 628 additions and 163 deletions
|
@ -1139,8 +1139,8 @@ static void test_threadcp(void)
|
|||
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 @@ static void test_dbcs_to_widechar(void)
|
|||
|
||||
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 @@ static void test_dbcs_to_widechar(void)
|
|||
|
||||
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 @@ static void test_dbcs_to_widechar(void)
|
|||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2151,13 +2151,9 @@ static void test_read_write(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -2779,6 +2779,165 @@ static void test_GetLargestConsoleWindowSize(HANDLE std_output)
|
|||
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 @@ START_TEST(console)
|
|||
test_GetCurrentConsoleFont(hConOut);
|
||||
test_GetConsoleFontSize(hConOut);
|
||||
test_GetLargestConsoleWindowSize(hConOut);
|
||||
test_GetConsoleFontInfo(hConOut);
|
||||
test_SetConsoleFont(hConOut);
|
||||
}
|
||||
|
|
|
@ -157,6 +157,7 @@ static void test_GetSystemDirectoryW(void)
|
|||
static void test_CreateDirectoryA(void)
|
||||
{
|
||||
char tmpdir[MAX_PATH];
|
||||
WCHAR curdir[MAX_PATH];
|
||||
BOOL ret;
|
||||
|
||||
ret = CreateDirectoryA(NULL, NULL);
|
||||
|
@ -172,6 +173,7 @@ static void test_CreateDirectoryA(void)
|
|||
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 @@ static void test_CreateDirectoryA(void)
|
|||
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 void test_CreateDirectoryW(void)
|
|||
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 @@ static void test_CreateDirectoryW(void)
|
|||
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 @@ static void test_CreateDirectoryW(void)
|
|||
ret, GetLastError());
|
||||
ret = RemoveDirectoryW(tmpdir);
|
||||
ok(ret == FALSE, "RemoveDirectoryW should have failed\n");
|
||||
|
||||
SetCurrentDirectoryW(curdir);
|
||||
}
|
||||
|
||||
static void test_RemoveDirectoryA(void)
|
||||
|
|
|
@ -1214,6 +1214,7 @@ static void test_CreateFileA(void)
|
|||
{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 @@ static void test_CreateFileA(void)
|
|||
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 @@ static void test_CreateFileA(void)
|
|||
}
|
||||
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 @@ static void test_overlapped(void)
|
|||
"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 @@ static void test_CreateFile(void)
|
|||
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
|
|||
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,10 +4544,29 @@ static void test_GetFinalPathNameByHandleA(void)
|
|||
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));
|
||||
count = pGetFinalPathNameByHandleA(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
|
||||
|
@ -4608,6 +4628,10 @@ static void test_GetFinalPathNameByHandleW(void)
|
|||
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);
|
||||
|
@ -4621,6 +4645,23 @@ static void test_GetFinalPathNameByHandleW(void)
|
|||
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));
|
||||
count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
|
||||
|
|
|
@ -2750,6 +2750,24 @@ static void test_ResolveDelayLoadedAPI(void)
|
|||
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 @@ START_TEST(loader)
|
|||
test_section_access();
|
||||
test_import_resolution();
|
||||
test_ExitProcess();
|
||||
test_InMemoryOrderModuleList();
|
||||
}
|
||||
|
|
|
@ -74,7 +74,6 @@ static inline BOOL isdigitW( WCHAR wc )
|
|||
}
|
||||
|
||||
/* 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 *pGetGeoInfoA)(GEOID, GEOTYPE, LPSTR, INT, LANGID);
|
|||
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");
|
||||
HMODULE mod = GetModuleHandleA("kernel32");
|
||||
|
||||
#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
|
||||
#define X(f) p##f = (void*)GetProcAddress(mod, #f)
|
||||
X(GetTimeFormatEx);
|
||||
X(GetDateFormatEx);
|
||||
X(EnumSystemLanguageGroupsA);
|
||||
|
@ -130,6 +131,10 @@ static void InitFunctionPointers(void)
|
|||
X(GetGeoInfoW);
|
||||
X(EnumSystemGeoID);
|
||||
X(GetSystemPreferredUILanguages);
|
||||
X(GetThreadPreferredUILanguages);
|
||||
|
||||
mod = GetModuleHandleA("ntdll");
|
||||
X(RtlUpcaseUnicodeChar);
|
||||
#undef X
|
||||
}
|
||||
|
||||
|
@ -2458,7 +2463,7 @@ static void test_LocaleNameToLCID(void)
|
|||
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 @@ static void test_GetStringTypeW(void)
|
|||
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 @@ static void test_IsValidLocaleName(void)
|
|||
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 @@ static void test_CompareStringOrdinal(void)
|
|||
WCHAR coop2[] = { 'c','o','o','p',0 };
|
||||
WCHAR nonascii1[] = { 0x0102,0 };
|
||||
WCHAR nonascii2[] = { 0x0201,0 };
|
||||
WCHAR ch1, ch2;
|
||||
|
||||
if (!pCompareStringOrdinal)
|
||||
{
|
||||
|
@ -4252,6 +4272,21 @@ static void test_CompareStringOrdinal(void)
|
|||
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 @@ static void test_GetSystemPreferredUILanguages(void)
|
|||
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 @@ static void test_GetSystemPreferredUILanguages(void)
|
|||
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 @@ START_TEST(locale)
|
|||
test_EnumSystemGeoID();
|
||||
test_invariant();
|
||||
test_GetSystemPreferredUILanguages();
|
||||
test_GetThreadPreferredUILanguages();
|
||||
test_sorting();
|
||||
}
|
||||
|
|
|
@ -1116,10 +1116,9 @@ static void test_GetTempPath(void)
|
|||
{
|
||||
char save_TMP[MAX_PATH];
|
||||
char windir[MAX_PATH];
|
||||
char origdir[MAX_PATH];
|
||||
char buf[MAX_PATH];
|
||||
WCHAR curdir[MAX_PATH];
|
||||
|
||||
GetCurrentDirectoryA(sizeof(origdir), origdir);
|
||||
if (!GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP))) save_TMP[0] = 0;
|
||||
|
||||
/* test default configuration */
|
||||
|
@ -1151,6 +1150,7 @@ static void test_GetTempPath(void)
|
|||
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 @@ static void test_GetTempPath(void)
|
|||
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 @@ static void test_GetLongPathNameA(void)
|
|||
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 void test_GetShortPathNameW(void)
|
|||
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 @@ static void test_GetShortPathNameW(void)
|
|||
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 @@ static void test_relative_path(void)
|
|||
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 @@ static void test_relative_path(void)
|
|||
DeleteFileA("foo\\file");
|
||||
RemoveDirectoryA("foo");
|
||||
RemoveDirectoryA("bar");
|
||||
SetCurrentDirectoryW(curdir);
|
||||
}
|
||||
|
||||
static void test_CheckNameLegalDOS8Dot3(void)
|
||||
|
|
|
@ -2571,6 +2571,64 @@ static void test_overlapped(void)
|
|||
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 @@ START_TEST(pipe)
|
|||
test_CloseHandle();
|
||||
test_impersonation();
|
||||
test_overlapped();
|
||||
test_overlapped_error();
|
||||
test_nowait(PIPE_TYPE_BYTE);
|
||||
test_nowait(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE);
|
||||
test_NamedPipeHandleState();
|
||||
|
|
|
@ -88,6 +88,7 @@ static BOOL (WINAPI *pProcess32Next)(HANDLE, PROCESSENTRY32*);
|
|||
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 @@ static BOOL init(void)
|
|||
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 @@ static void test_process_info(void)
|
|||
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 @@ static void test_GetLogicalProcessorInformationEx(void)
|
|||
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 @@ START_TEST(process)
|
|||
test_GetNumaProcessorNode();
|
||||
test_session_info();
|
||||
test_GetLogicalProcessorInformationEx();
|
||||
test_largepages();
|
||||
|
||||
/* things that can be tested:
|
||||
* lookup: check the way program to be executed is searched
|
||||
|
|
|
@ -1740,9 +1740,9 @@ static SRWLOCK condvar_srwlock;
|
|||
|
||||
/* 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
|
||||
|
|
|
@ -43,7 +43,6 @@ static UINT (WINAPI *pResetWriteWatch)(LPVOID,SIZE_T);
|
|||
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 @@ static void test_MapViewOfFile(void)
|
|||
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 @@ static void test_MapViewOfFile(void)
|
|||
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,9 +1848,96 @@ static void test_write_watch(void)
|
|||
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 *)NtCurrentTeb()->DeallocationStack + 4 * 0x1000)
|
||||
{
|
||||
p[0] |= 0;
|
||||
p -= 0x1000;
|
||||
}
|
||||
|
||||
ok( arg == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg );
|
||||
return 42;
|
||||
}
|
||||
|
||||
static void test_stack_commit(void)
|
||||
{
|
||||
#ifdef __i386__
|
||||
static const char code_call_on_stack[] = {
|
||||
0x55, /* pushl %ebp */
|
||||
0x56, /* pushl %esi */
|
||||
0x89, 0xe6, /* movl %esp,%esi */
|
||||
0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */
|
||||
0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */
|
||||
0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */
|
||||
0x83, 0xe0, 0xf0, /* andl $~15,%eax */
|
||||
0x83, 0xe8, 0x0c, /* subl $12,%eax */
|
||||
0x89, 0xc4, /* movl %eax,%esp */
|
||||
0x52, /* pushl %edx */
|
||||
0x31, 0xed, /* xorl %ebp,%ebp */
|
||||
0xff, 0xd1, /* call *%ecx */
|
||||
0x89, 0xf4, /* movl %esi,%esp */
|
||||
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;
|
||||
|
||||
call_on_stack = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
ok( call_on_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
|
||||
memcpy( call_on_stack, code_call_on_stack, sizeof(code_call_on_stack) );
|
||||
|
||||
/* allocate a new stack, only the first guard page is committed */
|
||||
new_stack = VirtualAlloc( 0, 0x400000, MEM_RESERVE, PAGE_READWRITE );
|
||||
ok( new_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
|
||||
new_stack_base = (char *)new_stack + 0x400000;
|
||||
VirtualAlloc( (char *)new_stack_base - 0x1000, 0x1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD );
|
||||
|
||||
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 );
|
||||
|
||||
VirtualFree( new_stack, 0, MEM_RELEASE );
|
||||
VirtualFree( call_on_stack, 0, MEM_RELEASE );
|
||||
}
|
||||
|
||||
#endif /* defined(__i386__) || defined(__x86_64__) */
|
||||
#ifdef __i386__
|
||||
|
||||
static DWORD num_guard_page_calls;
|
||||
static LONG num_guard_page_calls;
|
||||
|
||||
static DWORD guard_page_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
|
||||
|
@ -1838,7 +1949,7 @@ static DWORD guard_page_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_R
|
|||
ok( rec->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION, "ExceptionCode is %08x instead of %08x\n",
|
||||
rec->ExceptionCode, STATUS_GUARD_PAGE_VIOLATION );
|
||||
|
||||
num_guard_page_calls++;
|
||||
InterlockedIncrement( &num_guard_page_calls );
|
||||
*(int *)rec->ExceptionInformation[1] += 0x100;
|
||||
|
||||
return ExceptionContinueExecution;
|
||||
|
@ -1856,12 +1967,6 @@ static void test_guard_page(void)
|
|||
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() );
|
||||
|
@ -1924,16 +2029,16 @@ static void test_guard_page(void)
|
|||
|
||||
/* 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;
|
||||
frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
|
||||
NtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = 0;
|
||||
old_value = *value; /* exception handler increments value by 0x100 */
|
||||
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 );
|
||||
|
||||
pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
|
||||
/* check info structure again, PAGE_GUARD should be removed now */
|
||||
ret = VirtualQuery( base, &info, sizeof(info) );
|
||||
|
@ -1946,16 +2051,16 @@ static void test_guard_page(void)
|
|||
|
||||
/* test accessing second integer in memory */
|
||||
frame.Handler = guard_page_handler;
|
||||
frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
|
||||
pNtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
|
||||
NtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = 0;
|
||||
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 );
|
||||
|
||||
pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
|
||||
success = VirtualLock( base, size );
|
||||
ok( success, "VirtualLock failed %u\n", GetLastError() );
|
||||
|
@ -2000,15 +2105,15 @@ static void test_guard_page(void)
|
|||
|
||||
/* 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;
|
||||
frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
|
||||
NtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = 0;
|
||||
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 );
|
||||
|
||||
pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
|
||||
count = 64;
|
||||
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
|
||||
|
@ -2021,16 +2126,16 @@ static void test_guard_page(void)
|
|||
|
||||
/* 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;
|
||||
frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
|
||||
NtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = 0;
|
||||
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 );
|
||||
|
||||
pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
|
||||
count = 64;
|
||||
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
|
||||
|
@ -2075,82 +2180,7 @@ static void test_guard_page(void)
|
|||
VirtualFree( base, 0, MEM_RELEASE );
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
p[0] |= 0;
|
||||
p -= 0x1000;
|
||||
}
|
||||
|
||||
ok( arg == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg );
|
||||
return 42;
|
||||
}
|
||||
|
||||
static void test_stack_commit(void)
|
||||
{
|
||||
static const char code_call_on_stack[] = {
|
||||
0x55, /* pushl %ebp */
|
||||
0x56, /* pushl %esi */
|
||||
0x89, 0xe6, /* movl %esp,%esi */
|
||||
0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */
|
||||
0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */
|
||||
0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */
|
||||
0x83, 0xe0, 0xf0, /* andl $~15,%eax */
|
||||
0x83, 0xe8, 0x0c, /* subl $12,%eax */
|
||||
0x89, 0xc4, /* movl %eax,%esp */
|
||||
0x52, /* pushl %edx */
|
||||
0x31, 0xed, /* xorl %ebp,%ebp */
|
||||
0xff, 0xd1, /* call *%ecx */
|
||||
0x89, 0xf4, /* movl %esi,%esp */
|
||||
0x5e, /* popl %esi */
|
||||
0x5d, /* popl %ebp */
|
||||
0xc2, 0x0c, 0x00 }; /* ret $12 */
|
||||
|
||||
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() );
|
||||
memcpy( call_on_stack, code_call_on_stack, sizeof(code_call_on_stack) );
|
||||
|
||||
/* allocate a new stack, only the first guard page is committed */
|
||||
new_stack = VirtualAlloc( 0, 0x400000, MEM_RESERVE, PAGE_READWRITE );
|
||||
ok( new_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
|
||||
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;
|
||||
|
||||
result = call_on_stack( stack_commit_func, (void *)0xdeadbeef, new_stack_base );
|
||||
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;
|
||||
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 @@ static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTR
|
|||
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 @@ static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTR
|
|||
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 @@ static LONG CALLBACK execute_fault_vec_handler( EXCEPTION_POINTERS *ExceptionInf
|
|||
"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 @@ static inline DWORD send_message_excpt( HWND hWnd, UINT uMsg, WPARAM wParam, LPA
|
|||
DWORD ret;
|
||||
|
||||
frame.Handler = execute_fault_seh_handler;
|
||||
frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
|
||||
pNtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
|
||||
NtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = num_execute_fault_calls = 0;
|
||||
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 @@ static inline DWORD call_proc_excpt( DWORD (CALLBACK *code)(void *), void *arg )
|
|||
DWORD ret;
|
||||
|
||||
frame.Handler = execute_fault_seh_handler;
|
||||
frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
|
||||
pNtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
|
||||
NtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = num_execute_fault_calls = 0;
|
||||
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 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
|||
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 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
|||
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 @@ static void test_CreateFileMapping_protection(void)
|
|||
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 @@ static void test_CreateFileMapping_protection(void)
|
|||
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 @@ static void test_NtQuerySection(void)
|
|||
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 @@ todo_wine
|
|||
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 @@ todo_wine
|
|||
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 @@ todo_wine
|
|||
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 @@ START_TEST(virtual)
|
|||
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 @@ START_TEST(virtual)
|
|||
test_IsBadWritePtr();
|
||||
test_IsBadCodePtr();
|
||||
test_write_watch();
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
test_stack_commit();
|
||||
#endif
|
||||
#ifdef __i386__
|
||||
if (!winetest_interactive)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue