From ed41a4dee2fe49ba2d1944ca9d8a2c9968ea704e Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 3 Apr 2018 13:39:42 +0100 Subject: [PATCH] [KERNEL32_WINETEST] Sync everything except file.c and virtual.c with Wine Staging 3.3. CORE-14434 --- .../winetests/kernel32/CMakeLists.txt | 1 - modules/rostests/winetests/kernel32/actctx.c | 57 +- modules/rostests/winetests/kernel32/atom.c | 9 +- modules/rostests/winetests/kernel32/change.c | 59 +- .../rostests/winetests/kernel32/codepage.c | 9 +- modules/rostests/winetests/kernel32/comm.c | 9 +- modules/rostests/winetests/kernel32/console.c | 9 +- modules/rostests/winetests/kernel32/cpu.c | 75 -- .../rostests/winetests/kernel32/debugger.c | 8 +- .../rostests/winetests/kernel32/directory.c | 8 +- modules/rostests/winetests/kernel32/drive.c | 7 +- modules/rostests/winetests/kernel32/environ.c | 8 +- modules/rostests/winetests/kernel32/fiber.c | 2 +- .../rostests/winetests/kernel32/format_msg.c | 15 +- modules/rostests/winetests/kernel32/heap.c | 30 +- modules/rostests/winetests/kernel32/loader.c | 673 ++++++++++-- modules/rostests/winetests/kernel32/locale.c | 58 +- .../rostests/winetests/kernel32/mailslot.c | 9 +- modules/rostests/winetests/kernel32/module.c | 170 ++-- modules/rostests/winetests/kernel32/path.c | 10 +- modules/rostests/winetests/kernel32/pipe.c | 293 ++++-- modules/rostests/winetests/kernel32/precomp.h | 9 +- modules/rostests/winetests/kernel32/process.c | 506 ++++++++- modules/rostests/winetests/kernel32/profile.c | 45 +- .../rostests/winetests/kernel32/resource.c | 5 +- modules/rostests/winetests/kernel32/sync.c | 251 +++-- .../rostests/winetests/kernel32/testlist.c | 1 - modules/rostests/winetests/kernel32/thread.c | 29 +- modules/rostests/winetests/kernel32/time.c | 5 +- modules/rostests/winetests/kernel32/timer.c | 8 +- .../rostests/winetests/kernel32/toolhelp.c | 10 +- modules/rostests/winetests/kernel32/version.c | 956 +++++++++--------- modules/rostests/winetests/kernel32/volume.c | 10 +- 33 files changed, 2306 insertions(+), 1048 deletions(-) delete mode 100644 modules/rostests/winetests/kernel32/cpu.c diff --git a/modules/rostests/winetests/kernel32/CMakeLists.txt b/modules/rostests/winetests/kernel32/CMakeLists.txt index 063ff851938..a33f10d99a1 100644 --- a/modules/rostests/winetests/kernel32/CMakeLists.txt +++ b/modules/rostests/winetests/kernel32/CMakeLists.txt @@ -10,7 +10,6 @@ list(APPEND SOURCE codepage.c comm.c console.c - cpu.c debugger.c directory.c drive.c diff --git a/modules/rostests/winetests/kernel32/actctx.c b/modules/rostests/winetests/kernel32/actctx.c index 8bd37c43f32..6ba8e997d4c 100644 --- a/modules/rostests/winetests/kernel32/actctx.c +++ b/modules/rostests/winetests/kernel32/actctx.c @@ -16,11 +16,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - -#include -#include -#include +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "wine/test.h" +#include +#include +#include +#include +#include +#include + +#include "oaidl.h" +#include "initguid.h" static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*); static HANDLE (WINAPI *pCreateActCtxA)(PCACTCTXA); @@ -419,9 +426,9 @@ static const char compat_manifest_vista_7_8_10_81[] = " " " " " " -" " /* Windows Vista */ +" " /* Windows Vista */ " " /* Windows 7 */ -" " /* Windows 8 */ +" " /* Windows 8 */ " " /* Windows 10 */ " " /* Windows 8.1 */ " " @@ -2323,7 +2330,7 @@ static HANDLE create_manifest(const char *filename, const char *data, int line) return handle; } -static void kernel32_find(ULONG section, const char *string_to_find, BOOL should_find, BOOL todo, int line) +static void kernel32_find(ULONG section, const char *string_to_find, BOOL should_find, int line) { UNICODE_STRING string_to_findW; ACTCTX_SECTION_KEYED_DATA data; @@ -2340,7 +2347,6 @@ static void kernel32_find(ULONG section, const char *string_to_find, BOOL should err = GetLastError(); ok_(__FILE__, line)(ret == should_find, "FindActCtxSectionStringA: expected ret = %u, got %u\n", should_find, ret); - todo_wine_if(todo) ok_(__FILE__, line)(err == (should_find ? ERROR_SUCCESS : ERROR_SXS_KEY_NOT_FOUND), "FindActCtxSectionStringA: unexpected error %u\n", err); @@ -2352,7 +2358,6 @@ static void kernel32_find(ULONG section, const char *string_to_find, BOOL should err = GetLastError(); ok_(__FILE__, line)(ret == should_find, "FindActCtxSectionStringW: expected ret = %u, got %u\n", should_find, ret); - todo_wine_if(todo) ok_(__FILE__, line)(err == (should_find ? ERROR_SUCCESS : ERROR_SXS_KEY_NOT_FOUND), "FindActCtxSectionStringW: unexpected error %u\n", err); @@ -2375,7 +2380,7 @@ static void kernel32_find(ULONG section, const char *string_to_find, BOOL should pRtlFreeUnicodeString(&string_to_findW); } -static void ntdll_find(ULONG section, const char *string_to_find, BOOL should_find, BOOL todo, int line) +static void ntdll_find(ULONG section, const char *string_to_find, BOOL should_find, int line) { UNICODE_STRING string_to_findW; ACTCTX_SECTION_KEYED_DATA data; @@ -2387,12 +2392,10 @@ static void ntdll_find(ULONG section, const char *string_to_find, BOOL should_fi data.cbSize = sizeof(data); ret = pRtlFindActivationContextSectionString(0, NULL, section, &string_to_findW, &data); - todo_wine_if(todo) ok_(__FILE__, line)(ret == (should_find ? STATUS_SUCCESS : STATUS_SXS_KEY_NOT_FOUND), "RtlFindActivationContextSectionString: unexpected status 0x%x\n", ret); ret = pRtlFindActivationContextSectionString(0, NULL, section, &string_to_findW, NULL); - todo_wine_if(todo) ok_(__FILE__, line)(ret == (should_find ? STATUS_SUCCESS : STATUS_SXS_KEY_NOT_FOUND), "RtlFindActivationContextSectionString: unexpected status 0x%x\n", ret); @@ -2410,22 +2413,22 @@ static void test_findsectionstring(void) ok(ret, "ActivateActCtx failed: %u\n", GetLastError()); /* first we show the parameter validation from kernel32 */ - kernel32_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, TRUE, __LINE__); - kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, FALSE, __LINE__); - kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, FALSE, __LINE__); - kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, FALSE, __LINE__); - kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, FALSE, __LINE__); - kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, FALSE, __LINE__); - kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, FALSE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, __LINE__); + kernel32_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, __LINE__); /* then we show that ntdll plays by different rules */ - ntdll_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, TRUE, __LINE__); - ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, FALSE, __LINE__); - ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, FALSE, __LINE__); - ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, FALSE, __LINE__); - ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, FALSE, __LINE__); - ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, FALSE, __LINE__); - ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, FALSE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, "testdep", FALSE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib.dll", TRUE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib2.dll", TRUE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, "testlib3.dll", FALSE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass", TRUE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass2", TRUE, __LINE__); + ntdll_find(ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, "wndClass3", FALSE, __LINE__); ret = pDeactivateActCtx(0, cookie); ok(ret, "DeactivateActCtx failed: %u\n", GetLastError()); diff --git a/modules/rostests/winetests/kernel32/atom.c b/modules/rostests/winetests/kernel32/atom.c index a276e966dd3..0c1740869ac 100755 --- a/modules/rostests/winetests/kernel32/atom.c +++ b/modules/rostests/winetests/kernel32/atom.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winuser.h" #define DOUBLE(x) (WCHAR)((x<<8)|(x)) diff --git a/modules/rostests/winetests/kernel32/change.c b/modules/rostests/winetests/kernel32/change.c index 997b0254612..f4abad48c58 100755 --- a/modules/rostests/winetests/kernel32/change.c +++ b/modules/rostests/winetests/kernel32/change.c @@ -26,7 +26,15 @@ * FILE_NOTIFY_CHANGE_CREATION */ -#include "precomp.h" +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "wine/test.h" +#include +#include +#include static DWORD CALLBACK NotificationThread(LPVOID arg) { @@ -375,6 +383,7 @@ static void test_readdirectorychanges(void) static const WCHAR szHoo[] = { '\\','h','o','o',0 }; static const WCHAR szGa[] = { '\\','h','o','o','\\','g','a',0 }; PFILE_NOTIFY_INFORMATION pfni; + BOOL got_subdir_change = FALSE; if (!pReadDirectoryChangesW) { @@ -542,26 +551,40 @@ static void test_readdirectorychanges(void) r = CreateDirectoryW( subsubdir, NULL ); ok( r == TRUE, "failed to create directory\n"); - r = WaitForSingleObject( ov.hEvent, 1000 ); - ok( r == WAIT_OBJECT_0, "should be ready\n" ); + while (1) + { + r = WaitForSingleObject( ov.hEvent, 1000 ); + ok(r == WAIT_OBJECT_0, "should be ready\n" ); + if (r == WAIT_TIMEOUT) break; - ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n"); - ok( ov.InternalHigh == 0x18 || ov.InternalHigh == 0x12 + 0x18, - "ov.InternalHigh wrong %lx\n", ov.InternalHigh); + ok((NTSTATUS) ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n"); - pfni = (PFILE_NOTIFY_INFORMATION) buffer; - if (pfni->NextEntryOffset) /* we may get a modified event on the parent dir */ - { - ok( pfni->NextEntryOffset == 0x12, "offset wrong %x\n", pfni->NextEntryOffset ); - ok( pfni->Action == FILE_ACTION_MODIFIED, "action wrong %d\n", pfni->Action ); - ok( pfni->FileNameLength == 3*sizeof(WCHAR), "len wrong\n" ); - ok( !memcmp(pfni->FileName,&szGa[1],3*sizeof(WCHAR)), "name wrong\n"); - pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset); + pfni = (PFILE_NOTIFY_INFORMATION) buffer; + while (1) + { + /* We might get one or more modified events on the parent dir */ + if (pfni->Action == FILE_ACTION_MODIFIED) + { + ok(pfni->FileNameLength == 3 * sizeof(WCHAR), "len wrong\n" ); + ok(!memcmp(pfni->FileName, &szGa[1], 3 * sizeof(WCHAR)), "name wrong\n"); + } + else + { + ok(pfni->Action == FILE_ACTION_ADDED, "action wrong\n"); + ok(pfni->FileNameLength == 6 * sizeof(WCHAR), "len wrong\n" ); + ok(!memcmp(pfni->FileName, &szGa[1], 6 * sizeof(WCHAR)), "name wrong\n"); + got_subdir_change = TRUE; + } + if (!pfni->NextEntryOffset) break; + pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset); + } + + if (got_subdir_change) break; + + r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL); + ok(r==TRUE, "should return true\n"); } - ok( pfni->NextEntryOffset == 0, "offset wrong\n" ); - ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" ); - ok( pfni->FileNameLength == 6*sizeof(WCHAR), "len wrong\n" ); - ok( !memcmp(pfni->FileName,&szGa[1],6*sizeof(WCHAR)), "name wrong\n" ); + ok(got_subdir_change, "didn't get subdir change\n"); r = RemoveDirectoryW( subsubdir ); ok( r == TRUE, "failed to remove directory\n"); diff --git a/modules/rostests/winetests/kernel32/codepage.c b/modules/rostests/winetests/kernel32/codepage.c index 4acc0cb5104..ac8b90298b4 100755 --- a/modules/rostests/winetests/kernel32/codepage.c +++ b/modules/rostests/winetests/kernel32/codepage.c @@ -19,7 +19,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" static const char foobarA[] = "foobar"; static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; diff --git a/modules/rostests/winetests/kernel32/comm.c b/modules/rostests/winetests/kernel32/comm.c index cb7648205bb..4fb9de1268e 100755 --- a/modules/rostests/winetests/kernel32/comm.c +++ b/modules/rostests/winetests/kernel32/comm.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "wine/test.h" +#include "winternl.h" +#include "winbase.h" +#include "winnls.h" #define TIMEOUT 1000 /* one second for Timeouts*/ #define SLOWBAUD 150 diff --git a/modules/rostests/winetests/kernel32/console.c b/modules/rostests/winetests/kernel32/console.c index 51f2162f356..926c0526864 100755 --- a/modules/rostests/winetests/kernel32/console.c +++ b/modules/rostests/winetests/kernel32/console.c @@ -19,7 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include "wine/test.h" +#include +#include static BOOL (WINAPI *pGetConsoleInputExeNameA)(DWORD, LPSTR); static DWORD (WINAPI *pGetConsoleProcessList)(LPDWORD, DWORD); @@ -2580,6 +2582,11 @@ static void test_ReadConsole(void) SetLastError(0xdeadbeef); ret = GetFileSize(std_input, NULL); + if (GetLastError() == 0xdeadbeef) + { + skip("stdin is redirected\n"); + return; + } ok(ret == INVALID_FILE_SIZE, "expected INVALID_FILE_SIZE, got %#x\n", ret); ok(GetLastError() == ERROR_INVALID_HANDLE || GetLastError() == ERROR_INVALID_FUNCTION, /* Win 8, 10 */ diff --git a/modules/rostests/winetests/kernel32/cpu.c b/modules/rostests/winetests/kernel32/cpu.c deleted file mode 100644 index ff5a6c1a648..00000000000 --- a/modules/rostests/winetests/kernel32/cpu.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Unit test suite for cpu functions - * - * Copyright 2014 Michael Müller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "precomp.h" - -static BOOL (WINAPI *pGetNumaProcessorNode)(UCHAR, PUCHAR); - -static void InitFunctionPointers(void) -{ - HMODULE hkernel32 = GetModuleHandleA("kernel32"); - - pGetNumaProcessorNode = (void *)GetProcAddress(hkernel32, "GetNumaProcessorNode"); -} - -static void test_GetNumaProcessorNode(void) -{ - SYSTEM_INFO si; - UCHAR node; - BOOL ret; - int i; - - if (!pGetNumaProcessorNode) - { - win_skip("GetNumaProcessorNode() is missing\n"); - return; - } - - GetSystemInfo(&si); - - for (i = 0; i < 256; i++) - { - ret = pGetNumaProcessorNode(i, &node); - if (i < si.dwNumberOfProcessors) - { - ok(ret, "expected TRUE, got FALSE for processor %d\n", i); - ok(node != 0xFF, "expected node != 0xFF, but got 0xFF\n"); - } - else - { - ok(!ret, "expected FALSE, got TRUE for processor %d\n", i); - ok(node == 0xFF, "expected node == 0xFF, but got %x\n", node); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - } - } - - /* crashes on windows */ - if (0) - { - ok(!pGetNumaProcessorNode(0, NULL), "expected return value FALSE, got TRUE\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - } -} - -START_TEST(cpu) -{ - InitFunctionPointers(); - test_GetNumaProcessorNode(); -} diff --git a/modules/rostests/winetests/kernel32/debugger.c b/modules/rostests/winetests/kernel32/debugger.c index 22360464324..a85fe59e423 100644 --- a/modules/rostests/winetests/kernel32/debugger.c +++ b/modules/rostests/winetests/kernel32/debugger.c @@ -18,7 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#include +#include +#include +#include "wine/test.h" #ifndef STATUS_DEBUGGER_INACTIVE #define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354) diff --git a/modules/rostests/winetests/kernel32/directory.c b/modules/rostests/winetests/kernel32/directory.c index 233fba74273..512dc6d22ad 100755 --- a/modules/rostests/winetests/kernel32/directory.c +++ b/modules/rostests/winetests/kernel32/directory.c @@ -18,7 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winternl.h" static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG); diff --git a/modules/rostests/winetests/kernel32/drive.c b/modules/rostests/winetests/kernel32/drive.c index e7872762737..98dc454f340 100755 --- a/modules/rostests/winetests/kernel32/drive.c +++ b/modules/rostests/winetests/kernel32/drive.c @@ -18,7 +18,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" static DWORD (WINAPI *pGetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); diff --git a/modules/rostests/winetests/kernel32/environ.c b/modules/rostests/winetests/kernel32/environ.c index 50d331582e7..f8452be2ee6 100755 --- a/modules/rostests/winetests/kernel32/environ.c +++ b/modules/rostests/winetests/kernel32/environ.c @@ -18,7 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winnls.h" static CHAR string[MAX_PATH]; #define ok_w(res, format, szString) \ diff --git a/modules/rostests/winetests/kernel32/fiber.c b/modules/rostests/winetests/kernel32/fiber.c index 0e0051bf7df..7501165dc87 100644 --- a/modules/rostests/winetests/kernel32/fiber.c +++ b/modules/rostests/winetests/kernel32/fiber.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include "wine/test.h" static LPVOID (WINAPI *pCreateFiber)(SIZE_T,LPFIBER_START_ROUTINE,LPVOID); static LPVOID (WINAPI *pConvertThreadToFiber)(LPVOID); diff --git a/modules/rostests/winetests/kernel32/format_msg.c b/modules/rostests/winetests/kernel32/format_msg.c index 3966b2aa6cc..290bce9f719 100755 --- a/modules/rostests/winetests/kernel32/format_msg.c +++ b/modules/rostests/winetests/kernel32/format_msg.c @@ -17,11 +17,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" #define ULL(a,b) (((ULONG64)(a) << 32) | (b)) -static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, +static DWORD WINAPIV doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, LPSTR out, DWORD outsize, ... ) { __ms_va_list list; @@ -34,7 +39,7 @@ static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, return r; } -static DWORD __cdecl doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, +static DWORD WINAPIV doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, LPWSTR out, DWORD outsize, ... ) { __ms_va_list list; @@ -1554,6 +1559,10 @@ static void test_message_from_hmodule(void) MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); ok(ret != 0, "FormatMessageA returned 0\n"); + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, TRUST_E_NOSIGNATURE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); + ok(ret != 0, "FormatMessageA returned 0\n"); + /* Test a message string with an insertion without passing any variadic arguments. */ ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 193 /* ERROR_BAD_EXE_FORMAT */, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); diff --git a/modules/rostests/winetests/kernel32/heap.c b/modules/rostests/winetests/kernel32/heap.c index 0c82d7bac95..fefd3e79561 100755 --- a/modules/rostests/winetests/kernel32/heap.c +++ b/modules/rostests/winetests/kernel32/heap.c @@ -20,7 +20,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winternl.h" +#include "wine/test.h" #define MAGIC_DEAD 0xdeadbeef @@ -200,7 +208,7 @@ static void test_heap(void) ((GetLastError() == ERROR_NOT_LOCKED) || (GetLastError() == MAGIC_DEAD)), "returned %d with %d (expected '0' with: ERROR_NOT_LOCKED or " "MAGIC_DEAD)\n", res, GetLastError()); - + GlobalFree(gbl); /* invalid handles are caught in windows: */ SetLastError(MAGIC_DEAD); @@ -209,6 +217,18 @@ static void test_heap(void) "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n", hsecond, GetLastError(), gbl); SetLastError(MAGIC_DEAD); + hsecond = GlobalFree(LongToHandle(0xdeadbeef)); /* bogus handle */ + ok( (hsecond == LongToHandle(0xdeadbeef)) && (GetLastError() == ERROR_INVALID_HANDLE), + "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n", + hsecond, GetLastError(), LongToHandle(0xdeadbeef)); + SetLastError(MAGIC_DEAD); + hsecond = GlobalFree(LongToHandle(0xdeadbee0)); /* bogus pointer */ + ok( (hsecond == LongToHandle(0xdeadbee0)) && + ((GetLastError() == ERROR_INVALID_HANDLE) || broken(GetLastError() == ERROR_NOACCESS) /* wvista+ */), + "returned %p with 0x%08x (expected %p with ERROR_NOACCESS)\n", + hsecond, GetLastError(), LongToHandle(0xdeadbee0)); + + SetLastError(MAGIC_DEAD); flags = GlobalFlags(gbl); ok( (flags == GMEM_INVALID_HANDLE) && (GetLastError() == ERROR_INVALID_HANDLE), "returned 0x%04x with 0x%08x (expected GMEM_INVALID_HANDLE with " @@ -242,7 +262,7 @@ static void test_heap(void) ok(mem == NULL, "Expected NULL, got %p\n", mem); /* invalid free */ - if (sizeof(void *) != 8) /* crashes on 64-bit Vista */ + if (sizeof(void *) != 8) /* crashes on 64-bit */ { SetLastError(MAGIC_DEAD); mem = GlobalFree(gbl); @@ -560,7 +580,7 @@ static void test_HeapCreate(void) ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n"); } - /* Check that HeapRealloc works */ + /* Check that HeapReAlloc works */ mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize); ok(mem2a!=NULL,"HeapReAlloc failed\n"); if(mem2a) { @@ -574,7 +594,7 @@ static void test_HeapCreate(void) ok(!error,"HeapReAlloc should have zeroed out its allocated memory\n"); } - /* Check that HeapRealloc honours HEAP_REALLOC_IN_PLACE_ONLY */ + /* Check that HeapReAlloc honours HEAP_REALLOC_IN_PLACE_ONLY */ error=FALSE; mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize); if(mem1a!=NULL) { diff --git a/modules/rostests/winetests/kernel32/loader.c b/modules/rostests/winetests/kernel32/loader.c index 73ca0134b8e..cc79e822ddd 100644 --- a/modules/rostests/winetests/kernel32/loader.c +++ b/modules/rostests/winetests/kernel32/loader.c @@ -18,9 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - -#include +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winuser.h" +#include "wine/test.h" +#include "delayloadhandler.h" /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000) @@ -40,10 +51,12 @@ struct PROCESS_BASIC_INFORMATION_PRIVATE static LONG *child_failures; static WORD cb_count; static DWORD page_size; +static BOOL is_win64 = sizeof(void *) > sizeof(int); +static BOOL is_wow64; static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, const LARGE_INTEGER *, ULONG, ULONG, HANDLE ); -static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, ULONG, ULONG *); +static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, SIZE_T, SIZE_T *); static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG, SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG); static NTSTATUS (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID); static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); @@ -65,6 +78,7 @@ static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION); static BOOL (WINAPI *pFlsSetValue)(DWORD, PVOID); static PVOID (WINAPI *pFlsGetValue)(DWORD); static BOOL (WINAPI *pFlsFree)(DWORD); +static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module) { @@ -154,13 +168,18 @@ static const char filler[0x1000]; static const char section_data[0x10] = "section data"; static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_size, - const IMAGE_NT_HEADERS *nt_header, const char *dll_name ) + const IMAGE_NT_HEADERS *nt_header, char dll_name[MAX_PATH] ) { + char temp_path[MAX_PATH]; DWORD dummy, size, file_align; HANDLE hfile; BOOL ret; + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); + hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0); + ok( hfile != INVALID_HANDLE_VALUE, "failed to create %s err %u\n", dll_name, GetLastError() ); if (hfile == INVALID_HANDLE_VALUE) return 0; SetLastError(0xdeadbeef); @@ -233,17 +252,64 @@ static DWORD create_test_dll( const IMAGE_DOS_HEADER *dos_header, UINT dos_size, return size; } -static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header ) +static DWORD create_test_dll_sections( const IMAGE_DOS_HEADER *dos_header, const IMAGE_NT_HEADERS *nt_header, + const IMAGE_SECTION_HEADER *sections, const void *section_data, + char dll_name[MAX_PATH] ) +{ + char temp_path[MAX_PATH]; + DWORD dummy, i, size; + HANDLE hfile; + BOOL ret; + + GetTempPathA(MAX_PATH, temp_path); + GetTempFileNameA(temp_path, "ldr", 0, dll_name); + + hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0); + ok( hfile != INVALID_HANDLE_VALUE, "failed to create %s err %u\n", dll_name, GetLastError() ); + if (hfile == INVALID_HANDLE_VALUE) return 0; + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, dos_header, sizeof(*dos_header), &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, nt_header, offsetof(IMAGE_NT_HEADERS, OptionalHeader) + nt_header->FileHeader.SizeOfOptionalHeader, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, sections, sizeof(*sections) * nt_header->FileHeader.NumberOfSections, + &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + + for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) + { + SetFilePointer(hfile, sections[i].PointerToRawData, NULL, FILE_BEGIN); + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, section_data, sections[i].SizeOfRawData, &dummy, NULL); + ok(ret, "WriteFile error %d\n", GetLastError()); + } + size = GetFileSize(hfile, NULL); + CloseHandle(hfile); + return size; +} + +static BOOL query_image_section( int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header, + const void *section_data ) { + static BOOL is_winxp; SECTION_BASIC_INFORMATION info; SECTION_IMAGE_INFORMATION image; - ULONG info_size = 0xdeadbeef; + const IMAGE_COR20_HEADER *cor_header = NULL; + SIZE_T info_size = (SIZE_T)0xdeadbeef << 16; NTSTATUS status; HANDLE file, mapping; ULONG file_size; LARGE_INTEGER map_size; + SIZE_T max_stack, commit_stack; + void *entry_point; + /* truncated header is not handled correctly in windows <= w2k3 */ - BOOL truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(nt_header->OptionalHeader); + BOOL truncated; file = CreateFileA( dll_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0 ); @@ -256,22 +322,56 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE if (status) { CloseHandle( file ); - return; + return FALSE; } status = pNtQuerySection( mapping, SectionImageInformation, &image, sizeof(image), &info_size ); ok( !status, "%u: NtQuerySection failed err %x\n", id, status ); - ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %u\n", id, info_size ); - ok( (char *)image.TransferAddress == (char *)nt_header->OptionalHeader.ImageBase + nt_header->OptionalHeader.AddressOfEntryPoint, - "%u: TransferAddress wrong %p / %p+%08x\n", id, - image.TransferAddress, (char *)nt_header->OptionalHeader.ImageBase, - nt_header->OptionalHeader.AddressOfEntryPoint ); + ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %lu\n", id, info_size ); + if (nt_header->OptionalHeader.Magic == (is_win64 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC + : IMAGE_NT_OPTIONAL_HDR32_MAGIC)) + { + max_stack = nt_header->OptionalHeader.SizeOfStackReserve; + commit_stack = nt_header->OptionalHeader.SizeOfStackCommit; + entry_point = (char *)nt_header->OptionalHeader.ImageBase + nt_header->OptionalHeader.AddressOfEntryPoint; + truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER); + if (!truncated && + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress && + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size) + cor_header = section_data; + } + else if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) + { + const IMAGE_NT_HEADERS64 *nt64 = (const IMAGE_NT_HEADERS64 *)nt_header; + max_stack = 0x100000; + commit_stack = 0x10000; + entry_point = (void *)0x81231234; + truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER64); + if (!truncated && + nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress && + nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size) + cor_header = section_data; + } + else + { + const IMAGE_NT_HEADERS32 *nt32 = (const IMAGE_NT_HEADERS32 *)nt_header; + max_stack = nt32->OptionalHeader.SizeOfStackReserve; + commit_stack = nt32->OptionalHeader.SizeOfStackCommit; + entry_point = (char *)(ULONG_PTR)nt32->OptionalHeader.ImageBase + nt32->OptionalHeader.AddressOfEntryPoint; + truncated = nt_header->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER32); + if (!truncated && + nt32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress && + nt32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size) + cor_header = section_data; + } + ok( (char *)image.TransferAddress == (char *)entry_point || + (S(U(image)).ImageDynamicallyRelocated && LOWORD(image.TransferAddress) == LOWORD(entry_point)), + "%u: TransferAddress wrong %p / %p (%08x)\n", id, + image.TransferAddress, entry_point, nt_header->OptionalHeader.AddressOfEntryPoint ); ok( image.ZeroBits == 0, "%u: ZeroBits wrong %08x\n", id, image.ZeroBits ); - ok( image.MaximumStackSize == nt_header->OptionalHeader.SizeOfStackReserve || broken(truncated), - "%u: MaximumStackSize wrong %lx / %lx\n", id, - image.MaximumStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackReserve ); - ok( image.CommittedStackSize == nt_header->OptionalHeader.SizeOfStackCommit || broken(truncated), - "%u: CommittedStackSize wrong %lx / %lx\n", id, - image.CommittedStackSize, (SIZE_T)nt_header->OptionalHeader.SizeOfStackCommit ); + ok( image.MaximumStackSize == max_stack || broken(truncated), + "%u: MaximumStackSize wrong %lx / %lx\n", id, image.MaximumStackSize, max_stack ); + ok( image.CommittedStackSize == commit_stack || broken(truncated), + "%u: CommittedStackSize wrong %lx / %lx\n", id, image.CommittedStackSize, commit_stack ); if (truncated) ok( !image.SubSystemType || broken(truncated), "%u: SubSystemType wrong %08x / 00000000\n", id, image.SubSystemType ); @@ -293,18 +393,66 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE image.DllCharacteristics, nt_header->OptionalHeader.DllCharacteristics ); ok( image.Machine == nt_header->FileHeader.Machine, "%u: Machine wrong %04x / %04x\n", id, image.Machine, nt_header->FileHeader.Machine ); - ok( image.LoaderFlags == nt_header->OptionalHeader.LoaderFlags, - "%u: LoaderFlags wrong %08x / %08x\n", id, - image.LoaderFlags, nt_header->OptionalHeader.LoaderFlags ); + ok( image.LoaderFlags == (cor_header != NULL), "%u: LoaderFlags wrong %08x\n", id, image.LoaderFlags ); ok( image.ImageFileSize == file_size || broken(!image.ImageFileSize), /* winxpsp1 */ "%u: ImageFileSize wrong %08x / %08x\n", id, image.ImageFileSize, file_size ); ok( image.CheckSum == nt_header->OptionalHeader.CheckSum || broken(truncated), "%u: CheckSum wrong %08x / %08x\n", id, image.CheckSum, nt_header->OptionalHeader.CheckSum ); + + if (nt_header->OptionalHeader.SizeOfCode || nt_header->OptionalHeader.AddressOfEntryPoint) + ok( image.ImageContainsCode == TRUE, "%u: ImageContainsCode wrong %u\n", id, + image.ImageContainsCode ); + else if ((nt_header->OptionalHeader.SectionAlignment % page_size) || + (nt_header->FileHeader.NumberOfSections == 1 && + (section.Characteristics & IMAGE_SCN_MEM_EXECUTE))) + ok( image.ImageContainsCode == TRUE || broken(!image.ImageContainsCode), /* <= win8 */ + "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode ); + else + ok( !image.ImageContainsCode, "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode ); + + if (cor_header && + (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) && + (cor_header->MajorRuntimeVersion > 2 || + (cor_header->MajorRuntimeVersion == 2 && cor_header->MinorRuntimeVersion >= 5))) + { + ok( S(U(image)).ComPlusILOnly || broken(is_winxp), + "%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags ); + if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC && + !(cor_header->Flags & COMIMAGE_FLAGS_32BITREQUIRED)) + ok( S(U(image)).ComPlusNativeReady || broken(is_winxp), + "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags ); + else + ok( !S(U(image)).ComPlusNativeReady, + "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags ); + } + else + { + ok( !S(U(image)).ComPlusILOnly, "%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags ); + ok( !S(U(image)).ComPlusNativeReady, "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags ); + } + if (!(nt_header->OptionalHeader.SectionAlignment % page_size)) + ok( !S(U(image)).ImageMappedFlat, "%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags ); + else + { + /* winxp doesn't support any of the loader flags */ + if (!S(U(image)).ImageMappedFlat) is_winxp = TRUE; + ok( S(U(image)).ImageMappedFlat || broken(is_winxp), + "%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags ); + } + if (!(nt_header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)) + ok( !S(U(image)).ImageDynamicallyRelocated || broken( S(U(image)).ComPlusILOnly ), /* <= win7 */ + "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags ); + else if (image.ImageContainsCode && !cor_header) + ok( S(U(image)).ImageDynamicallyRelocated || broken(is_winxp), + "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags ); + else + ok( !S(U(image)).ImageDynamicallyRelocated || broken(TRUE), /* <= win8 */ + "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags ); + ok( !S(U(image)).BaseBelow4gb, "%u: wrong BaseBelow4gb flags %02x\n", id, U(image).ImageFlags ); + /* FIXME: needs more work: */ /* image.GpValue */ - /* image.ImageFlags */ - /* image.ImageContainsCode */ map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1); status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL ); @@ -345,23 +493,22 @@ static void query_image_section( int id, const char *dll_name, const IMAGE_NT_HE CloseHandle( mapping ); CloseHandle( file ); + return image.ImageContainsCode && (!cor_header || !(cor_header->Flags & COMIMAGE_FLAGS_ILONLY)); } /* helper to test image section mapping */ -static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header ) +static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header, const IMAGE_SECTION_HEADER *sections, + const void *section_data, int line ) { - char temp_path[MAX_PATH]; char dll_name[MAX_PATH]; LARGE_INTEGER size; HANDLE file, map; NTSTATUS status; ULONG file_size; + BOOL has_code; + HMODULE mod; - GetTempPathA(MAX_PATH, temp_path); - GetTempFileNameA(temp_path, "ldr", 0, dll_name); - - file_size = create_test_dll( &dos_header, sizeof(dos_header), nt_header, dll_name ); - ok( file_size, "could not create %s\n", dll_name); + file_size = create_test_dll_sections( &dos_header, nt_header, sections, section_data, dll_name ); file = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); @@ -372,15 +519,39 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header ) if (!status) { SECTION_BASIC_INFORMATION info; - ULONG info_size = 0xdeadbeef; + SIZE_T info_size = 0xdeadbeef; NTSTATUS ret = pNtQuerySection( map, SectionBasicInformation, &info, sizeof(info), &info_size ); ok( !ret, "NtQuerySection failed err %x\n", ret ); - ok( info_size == sizeof(info), "NtQuerySection wrong size %u\n", info_size ); + ok( info_size == sizeof(info), "NtQuerySection wrong size %lu\n", info_size ); ok( info.Attributes == (SEC_IMAGE | SEC_FILE), "NtQuerySection wrong attr %x\n", info.Attributes ); ok( info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", info.BaseAddress ); ok( info.Size.QuadPart == file_size, "NtQuerySection wrong size %x%08x / %08x\n", info.Size.u.HighPart, info.Size.u.LowPart, file_size ); - query_image_section( 1000, dll_name, nt_header ); + has_code = query_image_section( line, dll_name, nt_header, section_data ); + /* test loading dll of wrong 32/64 bitness */ + if (nt_header->OptionalHeader.Magic == (is_win64 ? IMAGE_NT_OPTIONAL_HDR32_MAGIC + : IMAGE_NT_OPTIONAL_HDR64_MAGIC)) + { + SetLastError( 0xdeadbeef ); + mod = LoadLibraryExA( dll_name, 0, DONT_RESOLVE_DLL_REFERENCES ); + if (!has_code && nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) + { + BOOL il_only = FALSE; + if (((const IMAGE_NT_HEADERS32 *)nt_header)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress) + { + const IMAGE_COR20_HEADER *cor_header = section_data; + il_only = (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) != 0; + } + ok( mod != NULL || broken(il_only), /* <= win7 */ + "%u: loading failed err %u\n", line, GetLastError() ); + } + else + { + ok( !mod, "%u: loading succeeded\n", line ); + ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "%u: wrong error %u\n", line, GetLastError() ); + } + if (mod) FreeLibrary( mod ); + } } if (map) CloseHandle( map ); CloseHandle( file ); @@ -540,23 +711,19 @@ static void test_Loader(void) DWORD file_size; HANDLE h; HMODULE hlib, hlib_as_data_file; - char temp_path[MAX_PATH]; char dll_name[MAX_PATH]; SIZE_T size; BOOL ret; NTSTATUS status; - WORD orig_machine = nt_header_template.FileHeader.Machine; + WORD alt_machine, orig_machine = nt_header_template.FileHeader.Machine; IMAGE_NT_HEADERS nt_header; + IMAGE_COR20_HEADER cor_header; /* prevent displaying of the "Unable to load this DLL" message box */ SetErrorMode(SEM_FAILCRITICALERRORS); - GetTempPathA(MAX_PATH, temp_path); - for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) { - GetTempFileNameA(temp_path, "ldr", 0, dll_name); - nt_header = nt_header_template; nt_header.FileHeader.NumberOfSections = td[i].number_of_sections; nt_header.FileHeader.SizeOfOptionalHeader = td[i].size_of_optional_header; @@ -567,11 +734,6 @@ static void test_Loader(void) nt_header.OptionalHeader.SizeOfHeaders = td[i].size_of_headers; file_size = create_test_dll( &dos_header, td[i].size_of_dos_header, &nt_header, dll_name ); - if (!file_size) - { - ok(0, "could not create %s\n", dll_name); - break; - } SetLastError(0xdeadbeef); hlib = LoadLibraryA(dll_name); @@ -601,8 +763,6 @@ static void test_Loader(void) SetLastError(0xdeadbeef); ptr = VirtualAlloc(hlib, page_size, MEM_COMMIT, info.Protect); ok(!ptr, "%d: VirtualAlloc should fail\n", i); - /* FIXME: Remove once Wine is fixed */ - todo_wine_if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY) ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); SetLastError(0xdeadbeef); @@ -687,8 +847,6 @@ static void test_Loader(void) SetLastError(0xdeadbeef); ptr = VirtualAlloc((char *)hlib + section.VirtualAddress, page_size, MEM_COMMIT, info.Protect); ok(!ptr, "%d: VirtualAlloc should fail\n", i); - /* FIXME: Remove once Wine is fixed */ - todo_wine_if (info.Protect == PAGE_WRITECOPY || info.Protect == PAGE_EXECUTE_WRITECOPY) ok(GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == ERROR_INVALID_ADDRESS, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); } @@ -716,7 +874,7 @@ static void test_Loader(void) SetLastError(0xdeadbeef); hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE); ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError()); - ok((ULONG_PTR)hlib_as_data_file & 1, "hlib_as_data_file is even\n"); + ok(((ULONG_PTR)hlib_as_data_file & 3) == 1, "hlib_as_data_file got %p\n", hlib_as_data_file); hlib = GetModuleHandleA(dll_name); ok(!hlib, "GetModuleHandle should fail\n"); @@ -732,7 +890,7 @@ static void test_Loader(void) SetLastError(0xdeadbeef); hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); - if (!((ULONG_PTR)hlib_as_data_file & 1) || /* winxp */ + if (!((ULONG_PTR)hlib_as_data_file & 3) || /* winxp */ (!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */ { win_skip( "LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE not supported\n" ); @@ -744,10 +902,37 @@ static void test_Loader(void) SetLastError(0xdeadbeef); h = CreateFileA( dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); - todo_wine ok( h == INVALID_HANDLE_VALUE, "open succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error %u\n", GetLastError() ); + ok( h == INVALID_HANDLE_VALUE, "open succeeded\n" ); + ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error %u\n", GetLastError() ); CloseHandle( h ); + SetLastError(0xdeadbeef); + h = CreateFileA( dll_name, GENERIC_READ | DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); + ok( h != INVALID_HANDLE_VALUE, "open failed err %u\n", GetLastError() ); + CloseHandle( h ); + + SetLastError(0xdeadbeef); + ret = FreeLibrary(hlib_as_data_file); + ok(ret, "FreeLibrary error %d\n", GetLastError()); + } + + SetLastError(0xdeadbeef); + hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE); + if (!((ULONG_PTR)hlib_as_data_file & 3) || /* winxp */ + (!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */ + { + win_skip( "LOAD_LIBRARY_AS_IMAGE_RESOURCE not supported\n" ); + FreeLibrary(hlib_as_data_file); + } + else + { + ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError()); + ok(((ULONG_PTR)hlib_as_data_file & 3) == 2, "hlib_as_data_file got %p\n", + hlib_as_data_file); + + hlib = GetModuleHandleA(dll_name); + ok(!hlib, "GetModuleHandle should fail\n"); + SetLastError(0xdeadbeef); ret = FreeLibrary(hlib_as_data_file); ok(ret, "FreeLibrary error %d\n", GetLastError()); @@ -764,7 +949,8 @@ static void test_Loader(void) ok(0, "could not create %s\n", dll_name); break; } - query_image_section( i, dll_name, &nt_header ); + + query_image_section( i, dll_name, &nt_header, NULL ); } else { @@ -797,49 +983,118 @@ static void test_Loader(void) nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER); nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size; - status = map_image_section( &nt_header ); + section.SizeOfRawData = sizeof(section_data); + section.PointerToRawData = page_size; + section.VirtualAddress = page_size; + section.Misc.VirtualSize = page_size; + + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + nt_header.OptionalHeader.SizeOfCode = 0x1000; + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + nt_header.OptionalHeader.SizeOfCode = 0; + nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT; + dos_header.e_magic = 0; - status = map_image_section( &nt_header ); + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection error %08x\n", status ); dos_header.e_magic = IMAGE_DOS_SIGNATURE; nt_header.Signature = IMAGE_OS2_SIGNATURE; - status = map_image_section( &nt_header ); + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection error %08x\n", status ); nt_header.Signature = 0xdeadbeef; - status = map_image_section( &nt_header ); + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection error %08x\n", status ); nt_header.Signature = IMAGE_NT_SIGNATURE; nt_header.OptionalHeader.Magic = 0xdead; - status = map_image_section( &nt_header ); + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status ); nt_header.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; nt_header.FileHeader.Machine = 0xdead; - status = map_image_section( &nt_header ); + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ "NtCreateSection error %08x\n", status ); nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_UNKNOWN; - status = map_image_section( &nt_header ); + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ "NtCreateSection error %08x\n", status ); switch (orig_machine) { - case IMAGE_FILE_MACHINE_I386: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; break; - case IMAGE_FILE_MACHINE_AMD64: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_I386; break; - case IMAGE_FILE_MACHINE_ARMNT: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64; break; - case IMAGE_FILE_MACHINE_ARM64: nt_header.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT; break; + case IMAGE_FILE_MACHINE_I386: alt_machine = IMAGE_FILE_MACHINE_ARMNT; break; + case IMAGE_FILE_MACHINE_AMD64: alt_machine = IMAGE_FILE_MACHINE_ARM64; break; + case IMAGE_FILE_MACHINE_ARMNT: alt_machine = IMAGE_FILE_MACHINE_I386; break; + case IMAGE_FILE_MACHINE_ARM64: alt_machine = IMAGE_FILE_MACHINE_AMD64; break; } - status = map_image_section( &nt_header ); + nt_header.FileHeader.Machine = alt_machine; + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); + ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ + "NtCreateSection error %08x\n", status ); + + switch (orig_machine) + { + case IMAGE_FILE_MACHINE_I386: alt_machine = IMAGE_FILE_MACHINE_AMD64; break; + case IMAGE_FILE_MACHINE_AMD64: alt_machine = IMAGE_FILE_MACHINE_I386; break; + case IMAGE_FILE_MACHINE_ARMNT: alt_machine = IMAGE_FILE_MACHINE_ARM64; break; + case IMAGE_FILE_MACHINE_ARM64: alt_machine = IMAGE_FILE_MACHINE_ARMNT; break; + } + nt_header.FileHeader.Machine = alt_machine; + status = map_image_section( &nt_header, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(status == STATUS_SUCCESS), /* win2k */ "NtCreateSection error %08x\n", status ); + nt_header.FileHeader.Machine = orig_machine; + nt_header.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = page_size; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = sizeof(cor_header); + section.SizeOfRawData = sizeof(cor_header); + + memset( &cor_header, 0, sizeof(cor_header) ); + cor_header.cb = sizeof(cor_header); + cor_header.MajorRuntimeVersion = 2; + cor_header.MinorRuntimeVersion = 4; + cor_header.Flags = COMIMAGE_FLAGS_ILONLY; + U(cor_header).EntryPointToken = 0xbeef; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.MinorRuntimeVersion = 5; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.MajorRuntimeVersion = 3; + cor_header.MinorRuntimeVersion = 0; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITREQUIRED; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITPREFERRED; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.Flags = 0; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = 1; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = 1; + status = map_image_section( &nt_header, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + if (nt_header.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { IMAGE_NT_HEADERS64 nt64; @@ -849,17 +1104,111 @@ static void test_Loader(void) nt64.FileHeader.Machine = orig_machine; nt64.FileHeader.NumberOfSections = 1; nt64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); + nt64.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL; nt64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; nt64.OptionalHeader.MajorLinkerVersion = 1; + nt64.OptionalHeader.SizeOfCode = 0x1000; + nt64.OptionalHeader.AddressOfEntryPoint = 0x1000; nt64.OptionalHeader.ImageBase = 0x10000000; + nt64.OptionalHeader.SectionAlignment = 0x1000; + nt64.OptionalHeader.FileAlignment = 0x1000; nt64.OptionalHeader.MajorOperatingSystemVersion = 4; nt64.OptionalHeader.MajorImageVersion = 1; nt64.OptionalHeader.MajorSubsystemVersion = 4; nt64.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt64) + sizeof(IMAGE_SECTION_HEADER); nt64.OptionalHeader.SizeOfImage = nt64.OptionalHeader.SizeOfHeaders + 0x1000; nt64.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; - status = map_image_section( (IMAGE_NT_HEADERS *)&nt64 ); - ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status ); + nt64.OptionalHeader.SizeOfStackReserve = 0x321000; + nt64.OptionalHeader.SizeOfStackCommit = 0x123000; + section.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE; + + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_INVALID_IMAGE_FORMAT : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + switch (orig_machine) + { + case IMAGE_FILE_MACHINE_I386: nt64.FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64; break; + case IMAGE_FILE_MACHINE_ARMNT: nt64.FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; break; + } + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_INVALID_IMAGE_FORMAT : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.FileHeader.Machine = alt_machine; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.OptionalHeader.SizeOfCode = 0; + nt64.OptionalHeader.AddressOfEntryPoint = 0x1000; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.OptionalHeader.SizeOfCode = 0; + nt64.OptionalHeader.AddressOfEntryPoint = 0; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.OptionalHeader.SizeOfCode = 0x1000; + nt64.OptionalHeader.AddressOfEntryPoint = 0; + nt64.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.OptionalHeader.SizeOfCode = 0; + nt64.OptionalHeader.AddressOfEntryPoint = 0; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, section_data, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = page_size; + nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = sizeof(cor_header); + cor_header.MajorRuntimeVersion = 2; + cor_header.MinorRuntimeVersion = 4; + cor_header.Flags = COMIMAGE_FLAGS_ILONLY; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt64.OptionalHeader.SizeOfCode = 0x1000; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + cor_header.MinorRuntimeVersion = 5; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITREQUIRED; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITPREFERRED; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + cor_header.Flags = 0; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); + + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = 1; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = 1; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, §ion, &cor_header, __LINE__ ); + ok( status == (is_wow64 ? STATUS_SUCCESS : STATUS_INVALID_IMAGE_WIN_64), + "NtCreateSection error %08x\n", status ); } else { @@ -870,20 +1219,180 @@ static void test_Loader(void) nt32.FileHeader.Machine = orig_machine; nt32.FileHeader.NumberOfSections = 1; nt32.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER32); + nt32.FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL; nt32.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC; nt32.OptionalHeader.MajorLinkerVersion = 1; + nt32.OptionalHeader.SizeOfCode = 0x1000; + nt32.OptionalHeader.AddressOfEntryPoint = 0x1000; nt32.OptionalHeader.ImageBase = 0x10000000; + nt32.OptionalHeader.SectionAlignment = 0x1000; + nt32.OptionalHeader.FileAlignment = 0x1000; nt32.OptionalHeader.MajorOperatingSystemVersion = 4; nt32.OptionalHeader.MajorImageVersion = 1; nt32.OptionalHeader.MajorSubsystemVersion = 4; nt32.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt32) + sizeof(IMAGE_SECTION_HEADER); nt32.OptionalHeader.SizeOfImage = nt32.OptionalHeader.SizeOfHeaders + 0x1000; nt32.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; - status = map_image_section( (IMAGE_NT_HEADERS *)&nt32 ); + nt32.OptionalHeader.SizeOfStackReserve = 0x321000; + nt32.OptionalHeader.SizeOfStackCommit = 0x123000; + section.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE; + + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08x\n", status ); + + switch (orig_machine) + { + case IMAGE_FILE_MACHINE_AMD64: nt32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT; break; + case IMAGE_FILE_MACHINE_ARM64: nt32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386; break; + } + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); + ok( status == STATUS_INVALID_IMAGE_FORMAT || broken(!status) /* win8 */, + "NtCreateSection error %08x\n", status ); + + nt32.FileHeader.Machine = alt_machine; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt32.OptionalHeader.SizeOfCode = 0; + nt32.OptionalHeader.AddressOfEntryPoint = 0x1000; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt32.OptionalHeader.SizeOfCode = 0; + nt32.OptionalHeader.AddressOfEntryPoint = 0; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt32.OptionalHeader.SizeOfCode = 0x1000; + nt32.OptionalHeader.AddressOfEntryPoint = 0; + nt32.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt32.OptionalHeader.SizeOfCode = 0; + nt32.OptionalHeader.AddressOfEntryPoint = 0; + section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, section_data, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt32.OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = page_size; + nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = sizeof(cor_header); + cor_header.MajorRuntimeVersion = 2; + cor_header.MinorRuntimeVersion = 4; + cor_header.Flags = COMIMAGE_FLAGS_ILONLY; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt32.OptionalHeader.SizeOfCode = 0x1000; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.MinorRuntimeVersion = 5; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITREQUIRED; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.Flags = COMIMAGE_FLAGS_ILONLY | COMIMAGE_FLAGS_32BITPREFERRED; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + cor_header.Flags = 0; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); + + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = 1; + nt_header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = 1; + status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, §ion, &cor_header, __LINE__ ); + ok( status == STATUS_SUCCESS, "NtCreateSection error %08x\n", status ); } - nt_header.FileHeader.Machine = orig_machine; /* restore it for the next tests */ + section.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; +} + +static void test_filenames(void) +{ + IMAGE_NT_HEADERS nt_header = nt_header_template; + char dll_name[MAX_PATH], long_path[MAX_PATH], short_path[MAX_PATH], buffer[MAX_PATH]; + HMODULE mod, mod2; + BOOL ret; + + nt_header.FileHeader.NumberOfSections = 1; + nt_header.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); + + nt_header.OptionalHeader.SectionAlignment = page_size; + nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT; + nt_header.OptionalHeader.FileAlignment = page_size; + nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER); + nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size; + + create_test_dll( &dos_header, sizeof(dos_header), &nt_header, dll_name ); + strcpy( long_path, dll_name ); + strcpy( strrchr( long_path, '\\' ), "\\this-is-a-long-name.dll" ); + ret = MoveFileA( dll_name, long_path ); + ok( ret, "MoveFileA failed err %u\n", GetLastError() ); + GetShortPathNameA( long_path, short_path, MAX_PATH ); + + mod = LoadLibraryA( short_path ); + ok( mod != NULL, "loading failed err %u\n", GetLastError() ); + GetModuleFileNameA( mod, buffer, MAX_PATH ); + ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path ); + mod2 = GetModuleHandleA( short_path ); + ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path ); + mod2 = GetModuleHandleA( long_path ); + ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path ); + mod2 = LoadLibraryA( long_path ); + ok( mod2 != NULL, "loading failed err %u\n", GetLastError() ); + ok( mod == mod2, "library loaded twice\n" ); + GetModuleFileNameA( mod2, buffer, MAX_PATH ); + ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path ); + FreeLibrary( mod2 ); + FreeLibrary( mod ); + + mod = LoadLibraryA( long_path ); + ok( mod != NULL, "loading failed err %u\n", GetLastError() ); + GetModuleFileNameA( mod, buffer, MAX_PATH ); + ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path ); + mod2 = GetModuleHandleA( short_path ); + ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path ); + mod2 = GetModuleHandleA( long_path ); + ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path ); + mod2 = LoadLibraryA( short_path ); + ok( mod2 != NULL, "loading failed err %u\n", GetLastError() ); + ok( mod == mod2, "library loaded twice\n" ); + GetModuleFileNameA( mod2, buffer, MAX_PATH ); + ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path ); + FreeLibrary( mod2 ); + FreeLibrary( mod ); + + strcpy( dll_name, long_path ); + strcpy( strrchr( dll_name, '\\' ), "\\this-is-another-name.dll" ); + ret = CreateHardLinkA( dll_name, long_path, NULL ); + ok( ret, "CreateHardLinkA failed err %u\n", GetLastError() ); + if (ret) + { + mod = LoadLibraryA( dll_name ); + ok( mod != NULL, "loading failed err %u\n", GetLastError() ); + GetModuleFileNameA( mod, buffer, MAX_PATH ); + ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, dll_name ); + mod2 = GetModuleHandleA( long_path ); + ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path ); + mod2 = LoadLibraryA( long_path ); + ok( mod2 != NULL, "loading failed err %u\n", GetLastError() ); + ok( mod == mod2, "library loaded twice\n" ); + GetModuleFileNameA( mod2, buffer, MAX_PATH ); + ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, short_path ); + FreeLibrary( mod2 ); + FreeLibrary( mod ); + DeleteFileA( dll_name ); + } + DeleteFileA( long_path ); } static void test_FakeDLL(void) @@ -1536,7 +2045,7 @@ static void test_import_resolution(void) nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = DATA_RVA(&data.tls); memset( &data, 0, sizeof(data) ); - data.descr[0].OriginalFirstThunk = DATA_RVA( data.original_thunks ); + U(data.descr[0]).OriginalFirstThunk = DATA_RVA( data.original_thunks ); data.descr[0].FirstThunk = DATA_RVA( data.thunks ); data.descr[0].Name = DATA_RVA( data.module ); strcpy( data.module, "kernel32.dll" ); @@ -1647,7 +2156,7 @@ static DWORD WINAPI mutex_thread_proc(void *param) wait_list[2] = peb_lock_event; wait_list[3] = heap_lock_event; - trace("%04u: mutex_thread_proc: starting\n", GetCurrentThreadId()); + trace("%04x: mutex_thread_proc: starting\n", GetCurrentThreadId()); while (1) { ret = WaitForMultipleObjects(sizeof(wait_list)/sizeof(wait_list[0]), wait_list, FALSE, 50); @@ -1655,7 +2164,7 @@ static DWORD WINAPI mutex_thread_proc(void *param) else if (ret == WAIT_OBJECT_0 + 1) { ULONG_PTR loader_lock_magic; - trace("%04u: mutex_thread_proc: Entering loader lock\n", GetCurrentThreadId()); + trace("%04x: mutex_thread_proc: Entering loader lock\n", GetCurrentThreadId()); ret = pLdrLockLoaderLock(0, NULL, &loader_lock_magic); ok(!ret, "LdrLockLoaderLock error %#x\n", ret); inside_loader_lock++; @@ -1663,21 +2172,21 @@ static DWORD WINAPI mutex_thread_proc(void *param) } else if (ret == WAIT_OBJECT_0 + 2) { - trace("%04u: mutex_thread_proc: Entering PEB lock\n", GetCurrentThreadId()); + trace("%04x: mutex_thread_proc: Entering PEB lock\n", GetCurrentThreadId()); pRtlAcquirePebLock(); inside_peb_lock++; SetEvent(ack_event); } else if (ret == WAIT_OBJECT_0 + 3) { - trace("%04u: mutex_thread_proc: Entering heap lock\n", GetCurrentThreadId()); + trace("%04x: mutex_thread_proc: Entering heap lock\n", GetCurrentThreadId()); HeapLock(GetProcessHeap()); inside_heap_lock++; SetEvent(ack_event); } } - trace("%04u: mutex_thread_proc: exiting\n", GetCurrentThreadId()); + trace("%04x: mutex_thread_proc: exiting\n", GetCurrentThreadId()); return 196; } @@ -1693,11 +2202,11 @@ static DWORD WINAPI semaphore_thread_proc(void *param) while (1) { if (winetest_debug > 1) - trace("%04u: semaphore_thread_proc: still alive\n", GetCurrentThreadId()); + trace("%04x: semaphore_thread_proc: still alive\n", GetCurrentThreadId()); if (WaitForSingleObject(stop_event, 50) != WAIT_TIMEOUT) break; } - trace("%04u: semaphore_thread_proc: exiting\n", GetCurrentThreadId()); + trace("%04x: semaphore_thread_proc: exiting\n", GetCurrentThreadId()); return 196; } @@ -1709,7 +2218,7 @@ static DWORD WINAPI noop_thread_proc(void *param) InterlockedIncrement(noop_thread_started); } - trace("%04u: noop_thread_proc: exiting\n", GetCurrentThreadId()); + trace("%04x: noop_thread_proc: exiting\n", GetCurrentThreadId()); return 195; } @@ -2273,7 +2782,6 @@ static void child_process(const char *dll_name, DWORD target_offset) case 3: trace("signalling thread exit\n"); SetEvent(stop_event); - CloseHandle(stop_event); break; case 4: @@ -3262,8 +3770,10 @@ START_TEST(loader) pFlsSetValue = (void *)GetProcAddress(kernel32, "FlsSetValue"); pFlsGetValue = (void *)GetProcAddress(kernel32, "FlsGetValue"); pFlsFree = (void *)GetProcAddress(kernel32, "FlsFree"); + pIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process"); pResolveDelayLoadedAPI = (void *)GetProcAddress(kernel32, "ResolveDelayLoadedAPI"); + if (pIsWow64Process) pIsWow64Process( GetCurrentProcess(), &is_wow64 ); GetSystemInfo( &si ); page_size = si.dwPageSize; dos_header.e_magic = IMAGE_DOS_SIGNATURE; @@ -3289,6 +3799,7 @@ START_TEST(loader) test_Loader(); test_FakeDLL(); + test_filenames(); test_ResolveDelayLoadedAPI(); test_ImportDescriptors(); test_section_access(); diff --git a/modules/rostests/winetests/kernel32/locale.c b/modules/rostests/winetests/kernel32/locale.c index 5b68563f717..959fa965a4b 100755 --- a/modules/rostests/winetests/kernel32/locale.c +++ b/modules/rostests/winetests/kernel32/locale.c @@ -25,7 +25,16 @@ * the control panel i8n page), we will still get the expected results. */ -#include "precomp.h" +#include +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winnls.h" static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0}; static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0}; @@ -2471,7 +2480,7 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f ok(ret == ret2, "%s ret %d, expected value %d\n", func_name, ret2, ret); /* test LCMAP_FULLWIDTH | LCMAP_HIRAGANA - (half-width katakana is converted into full-wdith hiragana) */ + (half-width katakana is converted into full-width hiragana) */ ret = func_ptr(LCMAP_FULLWIDTH | LCMAP_HIRAGANA, halfwidth_text, -1, buf, sizeof(buf)/sizeof(WCHAR)); ok(ret == lstrlenW(hiragana_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name, @@ -2770,42 +2779,51 @@ static void test_LocaleNameToLCID(void) ptr++; } - /* zh-Hant */ + /* zh-Hant has LCID 0x7c04, but LocaleNameToLCID actually returns 0x0c04, which is the LCID of zh-HK */ lcid = pLocaleNameToLCID(zhHantW, 0); - todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT), + ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT), "%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhHantW), lcid); ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0); ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHantW), ret); - todo_wine ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n", + ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n", + wine_dbgstr_w(zhHantW), wine_dbgstr_w(buffer)); + /* check that 0x7c04 also works and is mapped to zh-HK */ + ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL), buffer, sizeof(buffer)/sizeof(WCHAR), 0); + todo_wine ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHantW), ret); + ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n", wine_dbgstr_w(zhHantW), wine_dbgstr_w(buffer)); /* zh-hant */ lcid = pLocaleNameToLCID(zhhantW, 0); - todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT), - "%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhantW), - MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT)); + ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT), + "%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhantW), lcid); ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0); ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhhantW), ret); - todo_wine ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n", + ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n", wine_dbgstr_w(zhhantW), wine_dbgstr_w(buffer)); - /* zh-Hans */ + /* zh-Hans has LCID 0x0004, but LocaleNameToLCID actually returns 0x0804, which is the LCID of zh-CN */ lcid = pLocaleNameToLCID(zhHansW, 0); - todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT), + /* check that LocaleNameToLCID actually returns 0x0804 */ + ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT), "%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhHansW), lcid); ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0); ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHansW), ret); - todo_wine ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n", + ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n", + wine_dbgstr_w(zhHansW), wine_dbgstr_w(buffer)); + /* check that 0x0004 also works and is mapped to zh-CN */ + ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE, SUBLANG_NEUTRAL), buffer, sizeof(buffer)/sizeof(WCHAR), 0); + ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHansW), ret); + ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n", wine_dbgstr_w(zhHansW), wine_dbgstr_w(buffer)); /* zh-hans */ lcid = pLocaleNameToLCID(zhhansW, 0); - todo_wine ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT), - "%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhansW), - MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT)); + ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT), + "%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhansW), lcid); ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0); ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhhansW), ret); - todo_wine ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n", + ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n", wine_dbgstr_w(zhhansW), wine_dbgstr_w(buffer)); } } @@ -4465,6 +4483,14 @@ static void test_GetLocaleInfoEx(void) ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret); ok(!lstrcmpW(bufferW, enuW), "got %s\n", wine_dbgstr_w(bufferW)); + ret = pGetLocaleInfoEx(enusW, LOCALE_SPARENT, bufferW, sizeof(bufferW)/sizeof(WCHAR)); + ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret); + ok(!lstrcmpW(bufferW, enW), "got %s\n", wine_dbgstr_w(bufferW)); + + ret = pGetLocaleInfoEx(enW, LOCALE_SPARENT, bufferW, sizeof(bufferW)/sizeof(WCHAR)); + ok(ret == 1, "got %d\n", ret); + ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW)); + ret = pGetLocaleInfoEx(enW, LOCALE_SCOUNTRY, bufferW, sizeof(bufferW)/sizeof(WCHAR)); ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret); if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) || diff --git a/modules/rostests/winetests/kernel32/mailslot.c b/modules/rostests/winetests/kernel32/mailslot.c index 0e6c5b17fee..da595e97143 100755 --- a/modules/rostests/winetests/kernel32/mailslot.c +++ b/modules/rostests/winetests/kernel32/mailslot.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include +#include + +#include "wine/test.h" static const char szmspath[] = "\\\\.\\mailslot\\wine_mailslot_test"; diff --git a/modules/rostests/winetests/kernel32/module.c b/modules/rostests/winetests/kernel32/module.c index 829a6587dc8..0b4ce14c46c 100755 --- a/modules/rostests/winetests/kernel32/module.c +++ b/modules/rostests/winetests/kernel32/module.c @@ -18,8 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - +#include "wine/test.h" +#include +#include #include static DWORD (WINAPI *pGetDllDirectoryA)(DWORD,LPSTR); @@ -28,8 +29,6 @@ static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR); static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*); static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE); static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD); -static BOOL (WINAPI *pGetModuleHandleExA)(DWORD,LPCSTR,HMODULE*); -static BOOL (WINAPI *pGetModuleHandleExW)(DWORD,LPCWSTR,HMODULE*); static BOOL (WINAPI *pK32GetModuleInformation)(HANDLE process, HMODULE module, MODULEINFO *modinfo, DWORD cb); @@ -179,8 +178,7 @@ static void testGetModuleFileName(const char* name) ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%d/%d)\n", len1W / 2, len2W); } - ok(len1A / 2 == len2A || - len1A / 2 == len2A + 1, /* Win9x */ + ok(len1A / 2 == len2A, "Correct length in GetModuleFilenameA with buffer too small (%d/%d)\n", len1A / 2, len2A); } @@ -199,9 +197,7 @@ static void testGetModuleFileName_Wrong(void) bufA[0] = '*'; ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n"); - ok(bufA[0] == '*' || - bufA[0] == 0 /* Win9x */, - "When failing, buffer shouldn't be written to\n"); + ok(bufA[0] == '*', "When failing, buffer shouldn't be written to\n"); } static void testLoadLibraryA(void) @@ -220,14 +216,10 @@ static void testLoadLibraryA(void) SetLastError(0xdeadbeef); hModule1 = LoadLibraryA("kernel32 "); - /* Only winNT does this */ - if (GetLastError() != ERROR_DLL_NOT_FOUND) - { - ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n"); - ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError()); - ok( hModule == hModule1, "Loaded wrong module\n"); - FreeLibrary(hModule1); - } + ok( hModule1 != NULL, "\"kernel32 \" should be loadable\n" ); + ok( GetLastError() == 0xdeadbeef, "GetLastError should be 0xdeadbeef but is %d\n", GetLastError() ); + ok( hModule == hModule1, "Loaded wrong module\n" ); + FreeLibrary(hModule1); FreeLibrary(hModule); } @@ -252,7 +244,7 @@ static void testNestedLoadLibraryA(void) hModule1 = LoadLibraryA(path1); if (!hModule1) { - /* We must be on Windows NT, so we cannot test */ + /* We must be on Windows, so we cannot test */ return; } @@ -260,12 +252,7 @@ static void testNestedLoadLibraryA(void) strcat(path2, "\\system32\\"); strcat(path2, dllname); hModule2 = LoadLibraryA(path2); - if (!hModule2) - { - /* We must be on Windows 9x, so we cannot test */ - ok(FreeLibrary(hModule1), "FreeLibrary() failed\n"); - return; - } + ok(hModule2 != NULL, "LoadLibrary(%s) failed\n", path2); /* The first LoadLibrary() call may have registered the dll under the * system32 path. So load it, again, under the '...\system\...' path so @@ -295,8 +282,7 @@ static void testLoadLibraryA_Wrong(void) SetLastError(0xdeadbeef); hModule = LoadLibraryA("non_ex_pv.dll"); ok( !hModule, "non_ex_pv.dll should be not loadable\n"); - ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_DLL_NOT_FOUND, - "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND (win9x), got %d\n", GetLastError()); + ok( GetLastError() == ERROR_MOD_NOT_FOUND, "Expected ERROR_MOD_NOT_FOUND, got %d\n", GetLastError() ); /* Just in case */ FreeLibrary(hModule); @@ -309,14 +295,12 @@ static void testGetProcAddress_Wrong(void) SetLastError(0xdeadbeef); fp = GetProcAddress(NULL, "non_ex_call"); ok( !fp, "non_ex_call should not be found\n"); - ok( GetLastError() == ERROR_PROC_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_PROC_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError()); + ok( GetLastError() == ERROR_PROC_NOT_FOUND, "Expected ERROR_PROC_NOT_FOUND, got %d\n", GetLastError() ); SetLastError(0xdeadbeef); fp = GetProcAddress((HMODULE)0xdeadbeef, "non_ex_call"); ok( !fp, "non_ex_call should not be found\n"); - ok( GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_HANDLE(win9x), got %d\n", GetLastError()); + ok( GetLastError() == ERROR_MOD_NOT_FOUND, "Expected ERROR_MOD_NOT_FOUND, got %d\n", GetLastError() ); } static void testLoadLibraryEx(void) @@ -332,28 +316,20 @@ static void testLoadLibraryEx(void) ok(hfile != INVALID_HANDLE_VALUE, "Expected a valid file handle\n"); /* NULL lpFileName */ - if (is_unicode_enabled) - { - SetLastError(0xdeadbeef); - hmodule = LoadLibraryExA(NULL, NULL, 0); - ok(hmodule == 0, "Expected 0, got %p\n", hmodule); - ok(GetLastError() == ERROR_MOD_NOT_FOUND || - GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ - "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n", - GetLastError()); - } - else - win_skip("NULL filename crashes on WinMe\n"); + SetLastError(0xdeadbeef); + hmodule = LoadLibraryExA(NULL, NULL, 0); + ok(hmodule == 0, "Expected 0, got %p\n", hmodule); + ok(GetLastError() == ERROR_MOD_NOT_FOUND || + GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); /* empty lpFileName */ SetLastError(0xdeadbeef); hmodule = LoadLibraryExA("", NULL, 0); ok(hmodule == 0, "Expected 0, got %p\n", hmodule); ok(GetLastError() == ERROR_MOD_NOT_FOUND || - GetLastError() == ERROR_DLL_NOT_FOUND /* win9x */ || GetLastError() == ERROR_INVALID_PARAMETER /* win8 */, - "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n", - GetLastError()); + "Expected ERROR_MOD_NOT_FOUND or ERROR_DLL_NOT_FOUND, got %d\n", GetLastError()); /* hFile is non-NULL */ SetLastError(0xdeadbeef); @@ -362,8 +338,7 @@ static void testLoadLibraryEx(void) todo_wine { ok(GetLastError() == ERROR_SHARING_VIOLATION || - GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */ - GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */ + GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */ "Unexpected last error, got %d\n", GetLastError()); } @@ -373,8 +348,7 @@ static void testLoadLibraryEx(void) todo_wine { ok(GetLastError() == ERROR_SHARING_VIOLATION || - GetLastError() == ERROR_INVALID_PARAMETER || /* win2k3 */ - GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */ + GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */ "Unexpected last error, got %d\n", GetLastError()); } @@ -384,10 +358,8 @@ static void testLoadLibraryEx(void) ok(hmodule == 0, "Expected 0, got %p\n", hmodule); todo_wine { - ok(GetLastError() == ERROR_SHARING_VIOLATION || - GetLastError() == ERROR_FILE_NOT_FOUND, /* win9x */ - "Expected ERROR_SHARING_VIOLATION or ERROR_FILE_NOT_FOUND, got %d\n", - GetLastError()); + ok(GetLastError() == ERROR_SHARING_VIOLATION, + "Expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); } /* lpFileName does not matter */ @@ -398,8 +370,7 @@ static void testLoadLibraryEx(void) ok(hmodule == 0, "Expected 0, got %p\n", hmodule); ok(GetLastError() == ERROR_MOD_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER, /* win2k3 */ - "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n", - GetLastError()); + "Expected ERROR_MOD_NOT_FOUND or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); } CloseHandle(hfile); @@ -410,10 +381,8 @@ static void testLoadLibraryEx(void) ok(hmodule == 0, "Expected 0, got %p\n", hmodule); todo_wine { - ok(GetLastError() == ERROR_FILE_INVALID || - GetLastError() == ERROR_BAD_FORMAT, /* win9x */ - "Expected ERROR_FILE_INVALID or ERROR_BAD_FORMAT, got %d\n", - GetLastError()); + ok(GetLastError() == ERROR_FILE_INVALID, + "Expected ERROR_FILE_INVALID, got %d\n", GetLastError()); } DeleteFileA("testfile.dll"); @@ -428,7 +397,7 @@ static void testLoadLibraryEx(void) hmodule = LoadLibraryExA(path, NULL, LOAD_LIBRARY_AS_DATAFILE); ok(hmodule != 0, "Expected valid module handle\n"); ok(GetLastError() == 0xdeadbeef || - GetLastError() == ERROR_SUCCESS, /* win9x */ + GetLastError() == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError()); /* try invalid file handle */ @@ -443,9 +412,7 @@ static void testLoadLibraryEx(void) SetLastError(0xdeadbeef); hmodule = LoadLibraryExA("kernel32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); ok(hmodule != 0, "Expected valid module handle\n"); - ok(GetLastError() == 0xdeadbeef || - GetLastError() == ERROR_SUCCESS, /* win9x */ - "Expected 0xdeadbeef or ERROR_SUCCESS, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); FreeLibrary(hmodule); @@ -461,8 +428,7 @@ static void testLoadLibraryEx(void) { ok(hmodule == 0, "Expected 0, got %p\n", hmodule); } - ok(GetLastError() == ERROR_FILE_NOT_FOUND || - broken(GetLastError() == ERROR_INVALID_HANDLE), /* nt4 */ + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); /* Free the loaded dll when it's the first time this dll is loaded @@ -730,22 +696,15 @@ static void init_pointers(void) MAKEFUNC(AddDllDirectory); MAKEFUNC(RemoveDllDirectory); MAKEFUNC(SetDefaultDllDirectories); - MAKEFUNC(GetModuleHandleExA); - MAKEFUNC(GetModuleHandleExW); MAKEFUNC(K32GetModuleInformation); #undef MAKEFUNC - /* not all Windows versions export this in kernel32 */ + /* before Windows 7 this was not exported in kernel32 */ if (!pK32GetModuleInformation) { HMODULE hPsapi = LoadLibraryA("psapi.dll"); - if (hPsapi) - { - pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation"); - if (!pK32GetModuleInformation) FreeLibrary(hPsapi); - } + pK32GetModuleInformation = (void *)GetProcAddress(hPsapi, "GetModuleInformation"); } - } static void testGetModuleHandleEx(void) @@ -756,113 +715,107 @@ static void testGetModuleHandleEx(void) DWORD error; HMODULE mod, mod_kernel32; - if (!pGetModuleHandleExA || !pGetModuleHandleExW) - { - win_skip( "GetModuleHandleEx not available\n" ); - return; - } - SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExA( 0, NULL, NULL ); + ret = GetModuleHandleExA( 0, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExA( 0, "kernel32", NULL ); + ret = GetModuleHandleExA( 0, "kernel32", NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExA( 0, "kernel32", &mod ); + ret = GetModuleHandleExA( 0, "kernel32", &mod ); ok( ret, "unexpected failure %u\n", GetLastError() ); ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); FreeLibrary( mod ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExA( 0, "nosuchmod", &mod ); + ret = GetModuleHandleExA( 0, "nosuchmod", &mod ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); ok( mod == NULL, "got %p\n", mod ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExW( 0, NULL, NULL ); + ret = GetModuleHandleExW( 0, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExW( 0, kernel32W, NULL ); + ret = GetModuleHandleExW( 0, kernel32W, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExW( 0, kernel32W, &mod ); + ret = GetModuleHandleExW( 0, kernel32W, &mod ); ok( ret, "unexpected failure %u\n", GetLastError() ); ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); FreeLibrary( mod ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExW( 0, nosuchmodW, &mod ); + ret = GetModuleHandleExW( 0, nosuchmodW, &mod ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); ok( mod == NULL, "got %p\n", mod ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod ); ok( ret, "unexpected failure %u\n", GetLastError() ); ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); ok( mod == NULL, "got %p\n", mod ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod ); ok( ret, "unexpected failure %u\n", GetLastError() ); ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); @@ -871,54 +824,54 @@ static void testGetModuleHandleEx(void) mod_kernel32 = LoadLibraryA( "kernel32" ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod ); ok( ret, "unexpected failure %u\n", GetLastError() ); ok( mod == mod_kernel32, "got %p\n", mod ); FreeLibrary( mod ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod ); + ret = GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); ok( mod == NULL, "got %p\n", mod ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod ); ok( ret, "unexpected failure %u\n", GetLastError() ); ok( mod == mod_kernel32, "got %p\n", mod ); FreeLibrary( mod ); SetLastError( 0xdeadbeef ); mod = (HMODULE)0xdeadbeef; - ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod ); + ret = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod ); error = GetLastError(); ok( !ret, "unexpected success\n" ); ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); @@ -933,12 +886,6 @@ static void testK32GetModuleInformation(void) HMODULE mod; BOOL ret; - if (!pK32GetModuleInformation) - { - win_skip("K32GetModuleInformation not available\n"); - return; - } - mod = GetModuleHandleA(NULL); memset(&info, 0xAA, sizeof(info)); ret = pK32GetModuleInformation(GetCurrentProcess(), mod, &info, sizeof(info)); @@ -971,7 +918,8 @@ static void test_AddDllDirectory(void) buf[0] = '\0'; GetTempPathW( sizeof(path)/sizeof(path[0]), path ); - GetTempFileNameW( path, tmpW, 0, buf ); + ret = GetTempFileNameW( path, tmpW, 0, buf ); + ok( ret, "GetTempFileName failed err %u\n", GetLastError() ); SetLastError( 0xdeadbeef ); cookie = pAddDllDirectory( buf ); ok( cookie != NULL, "AddDllDirectory failed err %u\n", GetLastError() ); diff --git a/modules/rostests/winetests/kernel32/path.c b/modules/rostests/winetests/kernel32/path.c index 526c872f7c4..c9afb1bee5c 100755 --- a/modules/rostests/winetests/kernel32/path.c +++ b/modules/rostests/winetests/kernel32/path.c @@ -19,7 +19,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winerror.h" +#include "winnls.h" #define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\') diff --git a/modules/rostests/winetests/kernel32/pipe.c b/modules/rostests/winetests/kernel32/pipe.c index 3e4cf97ae65..8e5c07ff56e 100755 --- a/modules/rostests/winetests/kernel32/pipe.c +++ b/modules/rostests/winetests/kernel32/pipe.c @@ -18,7 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winioctl.h" +#include "wine/test.h" #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c" #define PIPENAME_SPECIAL "\\\\.\\PiPe\\tests->pipe.c" @@ -54,7 +63,7 @@ struct rpcThreadArgs static DWORD CALLBACK rpcThreadMain(LPVOID arg) { struct rpcThreadArgs *rpcargs = (struct rpcThreadArgs *)arg; - trace("rpcThreadMain starting\n"); + if (winetest_debug > 1) trace("rpcThreadMain starting\n"); SetLastError( rpcargs->lastError ); switch (rpcargs->op) @@ -74,7 +83,7 @@ static DWORD CALLBACK rpcThreadMain(LPVOID arg) } rpcargs->lastError = GetLastError(); - trace("rpcThreadMain returning\n"); + if (winetest_debug > 1) trace("rpcThreadMain returning\n"); return 0; } @@ -201,6 +210,11 @@ static void test_CreateNamedPipe(int pipemode) ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); test_signaled(hnp); + ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); + todo_wine + ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ret = WaitNamedPipeA(PIPENAME, 2000); ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError()); @@ -211,6 +225,12 @@ static void test_CreateNamedPipe(int pipemode) ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError()); + /* Test ConnectNamedPipe() in both directions */ + ok(!ConnectNamedPipe(hnp, NULL), "ConnectNamedPipe(server) succeeded\n"); + ok(GetLastError() == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError()); + ok(!ConnectNamedPipe(hFile, NULL), "ConnectNamedPipe(client) succeeded\n"); + ok(GetLastError() == ERROR_INVALID_FUNCTION, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError()); + /* don't try to do i/o if one side couldn't be opened, as it hangs */ if (hFile != INVALID_HANDLE_VALUE) { HANDLE hFile2; @@ -343,9 +363,7 @@ static void test_CreateNamedPipe(int pipemode) ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek3\n"); if (pipemode == PIPE_TYPE_BYTE) { - /* currently the Wine behavior depends on the kernel version */ - /* ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); */ - if (readden != sizeof(obuf) + sizeof(obuf2)) todo_wine ok(0, "peek3 got %d bytes\n", readden); + ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden); ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek3 got %d bytes left\n", left); } else @@ -382,9 +400,7 @@ static void test_CreateNamedPipe(int pipemode) ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail); ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek4\n"); if (pipemode == PIPE_TYPE_BYTE) { - /* currently the Wine behavior depends on the kernel version */ - /* ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); */ - if (readden != sizeof(obuf) + sizeof(obuf2)) todo_wine ok(0, "peek4 got %d bytes\n", readden); + ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden); ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek4 got %d bytes left\n", left); } else @@ -621,7 +637,7 @@ static void test_CreateNamedPipe(int pipemode) ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe with special characters failed\n"); ok(CloseHandle(hnp), "CloseHandle\n"); - trace("test_CreateNamedPipe returning\n"); + if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n"); } static void test_CreateNamedPipe_instances_must_match(void) @@ -709,11 +725,65 @@ static void test_CreateNamedPipe_instances_must_match(void) ok(CloseHandle(hnp2), "CloseHandle\n"); } +static void test_ReadFile(void) +{ + HANDLE server, client; + OVERLAPPED overlapped; + DWORD size; + BOOL res; + + static char buf[512]; + + server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL); + ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError()); + + client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, 0, 0); + ok(client != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError()); + + ok(WriteFile(client, buf, sizeof(buf), &size, NULL), "WriteFile\n"); + + res = ReadFile(server, buf, 1, &size, NULL); + ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError()); + ok(size == 1, "size = %u\n", size); + + /* pass both overlapped and ret read */ + memset(&overlapped, 0, sizeof(overlapped)); + res = ReadFile(server, buf, 1, &size, &overlapped); + ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError()); + ok(size == 0, "size = %u\n", size); + ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "Internal = %lx\n", overlapped.Internal); + ok(overlapped.InternalHigh == 1, "InternalHigh = %lx\n", overlapped.InternalHigh); + + DisconnectNamedPipe(server); + + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.InternalHigh = 0xdeadbeef; + res = ReadFile(server, buf, 1, &size, &overlapped); + ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError()); + ok(size == 0, "size = %u\n", size); + ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal); + ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh); + + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.InternalHigh = 0xdeadbeef; + res = WriteFile(server, buf, 1, &size, &overlapped); + ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError()); + ok(size == 0, "size = %u\n", size); + ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal); + ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh); + + CloseHandle(server); + CloseHandle(client); +} + /** implementation of alarm() */ static DWORD CALLBACK alarmThreadMain(LPVOID arg) { DWORD_PTR timeout = (DWORD_PTR) arg; - trace("alarmThreadMain\n"); + if (winetest_debug > 1) trace("alarmThreadMain\n"); if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT) { ok(FALSE, "alarm\n"); @@ -729,7 +799,7 @@ static DWORD CALLBACK serverThreadMain1(LPVOID arg) { int i; - trace("serverThreadMain1 start\n"); + if (winetest_debug > 1) trace("serverThreadMain1 start\n"); /* Set up a simple echo server */ hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, @@ -747,30 +817,30 @@ static DWORD CALLBACK serverThreadMain1(LPVOID arg) BOOL success; /* Wait for client to connect */ - trace("Server calling ConnectNamedPipe...\n"); + if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); ok(ConnectNamedPipe(hnp, NULL) || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n"); - trace("ConnectNamedPipe returned.\n"); + if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n"); /* Echo bytes once */ memset(buf, 0, sizeof(buf)); - trace("Server reading...\n"); + if (winetest_debug > 1) trace("Server reading...\n"); success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL); - trace("Server done reading.\n"); + if (winetest_debug > 1) trace("Server done reading.\n"); ok(success, "ReadFile\n"); ok(readden, "short read\n"); - trace("Server writing...\n"); + if (winetest_debug > 1) trace("Server writing...\n"); ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n"); - trace("Server done writing.\n"); + if (winetest_debug > 1) trace("Server done writing.\n"); ok(written == readden, "write file len\n"); /* finish this connection, wait for next one */ ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); - trace("Server done flushing.\n"); + if (winetest_debug > 1) trace("Server done flushing.\n"); ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n"); - trace("Server done disconnecting.\n"); + if (winetest_debug > 1) trace("Server done disconnecting.\n"); } return 0; } @@ -802,28 +872,28 @@ static DWORD CALLBACK serverThreadMain2(LPVOID arg) user_apc_ran = FALSE; if (i == 0 && pQueueUserAPC) { - trace("Queueing an user APC\n"); /* verify the pipe is non alerable */ + if (winetest_debug > 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */ ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0); ok(ret, "QueueUserAPC failed: %d\n", GetLastError()); } /* Wait for client to connect */ - trace("Server calling ConnectNamedPipe...\n"); + if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); ok(ConnectNamedPipe(hnp, NULL) || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n"); - trace("ConnectNamedPipe returned.\n"); + if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n"); /* Echo bytes once */ memset(buf, 0, sizeof(buf)); - trace("Server reading...\n"); + if (winetest_debug > 1) trace("Server reading...\n"); success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL); - trace("Server done reading.\n"); + if (winetest_debug > 1) trace("Server done reading.\n"); ok(success, "ReadFile\n"); - trace("Server writing...\n"); + if (winetest_debug > 1) trace("Server writing...\n"); ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n"); - trace("Server done writing.\n"); + if (winetest_debug > 1) trace("Server done writing.\n"); ok(written == readden, "write file len\n"); /* finish this connection, wait for next one */ @@ -859,7 +929,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) int i; HANDLE hEvent; - trace("serverThreadMain3\n"); + if (winetest_debug > 1) trace("serverThreadMain3\n"); /* Set up a simple echo server */ hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, @@ -892,17 +962,17 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) /* Wait for client to connect */ if (i == 0) { - trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n"); + if (winetest_debug > 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n"); success = ConnectNamedPipe(hnp, NULL); err = GetLastError(); ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err); - trace("ConnectNamedPipe operation complete.\n"); + if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n"); } else { - trace("Server calling overlapped ConnectNamedPipe...\n"); + if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n"); success = ConnectNamedPipe(hnp, &oOverlap); err = GetLastError(); ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n"); - trace("overlapped ConnectNamedPipe returned.\n"); + if (winetest_debug > 1) trace("overlapped ConnectNamedPipe returned.\n"); if (!success && (err == ERROR_IO_PENDING)) { if (letWFSOEwait) { @@ -919,18 +989,18 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) } } ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n"); - trace("overlapped ConnectNamedPipe operation complete.\n"); + if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n"); } /* Echo bytes once */ memset(buf, 0, sizeof(buf)); - trace("Server reading...\n"); + if (winetest_debug > 1) trace("Server reading...\n"); success = ReadFile(hnp, buf, sizeof(buf), &readden, &oOverlap); - trace("Server ReadFile returned...\n"); + if (winetest_debug > 1) trace("Server ReadFile returned...\n"); err = GetLastError(); ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n"); - trace("overlapped ReadFile returned.\n"); + if (winetest_debug > 1) trace("overlapped ReadFile returned.\n"); if (!success && (err == ERROR_IO_PENDING)) { if (letWFSOEwait) { @@ -946,15 +1016,15 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE); } } - trace("Server done reading.\n"); + if (winetest_debug > 1) trace("Server done reading.\n"); ok(success, "overlapped ReadFile\n"); - trace("Server writing...\n"); + if (winetest_debug > 1) trace("Server writing...\n"); success = WriteFile(hnp, buf, readden, &written, &oOverlap); - trace("Server WriteFile returned...\n"); + if (winetest_debug > 1) trace("Server WriteFile returned...\n"); err = GetLastError(); ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n"); - trace("overlapped WriteFile returned.\n"); + if (winetest_debug > 1) trace("overlapped WriteFile returned.\n"); if (!success && (err == ERROR_IO_PENDING)) { if (letWFSOEwait) { @@ -970,7 +1040,7 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg) success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE); } } - trace("Server done writing.\n"); + if (winetest_debug > 1) trace("Server done writing.\n"); ok(success, "overlapped WriteFile\n"); ok(written == readden, "write file len\n"); @@ -988,7 +1058,7 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) HANDLE hcompletion; BOOL ret; - trace("serverThreadMain4\n"); + if (winetest_debug > 1) trace("serverThreadMain4\n"); /* Set up a simple echo server */ hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, @@ -1020,13 +1090,13 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) memset(&oWrite, 0, sizeof(oWrite)); /* Wait for client to connect */ - trace("Server calling overlapped ConnectNamedPipe...\n"); + if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n"); success = ConnectNamedPipe(hnp, &oConnect); err = GetLastError(); ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe got %u err %u\n", success, err ); if (!success && err == ERROR_IO_PENDING) { - trace("ConnectNamedPipe GetQueuedCompletionStatus\n"); + if (winetest_debug > 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n"); success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0); if (!success) { @@ -1041,14 +1111,14 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect); } } - trace("overlapped ConnectNamedPipe operation complete.\n"); + if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n"); /* Echo bytes once */ memset(buf, 0, sizeof(buf)); - trace("Server reading...\n"); + if (winetest_debug > 1) trace("Server reading...\n"); success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); - trace("Server ReadFile returned...\n"); + if (winetest_debug > 1) trace("Server ReadFile returned...\n"); err = GetLastError(); ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%i\n", err); success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, @@ -1059,11 +1129,11 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey); ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead); } - trace("Server done reading.\n"); + if (winetest_debug > 1) trace("Server done reading.\n"); - trace("Server writing...\n"); + if (winetest_debug > 1) trace("Server writing...\n"); success = WriteFile(hnp, buf, readden, &written, &oWrite); - trace("Server WriteFile returned...\n"); + if (winetest_debug > 1) trace("Server WriteFile returned...\n"); err = GetLastError(); ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%u\n", err); success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, @@ -1075,7 +1145,46 @@ static DWORD CALLBACK serverThreadMain4(LPVOID arg) ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite); ok(written == readden, "write file len\n"); } - trace("Server done writing.\n"); + if (winetest_debug > 1) trace("Server done writing.\n"); + + /* Client will finish this connection, the following ops will trigger broken pipe errors. */ + + /* Wait for the pipe to break. */ + while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written)); + + if (winetest_debug > 1) trace("Server writing on disconnected pipe...\n"); + SetLastError(ERROR_SUCCESS); + success = WriteFile(hnp, buf, readden, &written, &oWrite); + err = GetLastError(); + todo_wine_if (!success && err == ERROR_PIPE_NOT_CONNECTED) ok(!success && err == ERROR_NO_DATA, + "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success, err); + + /* No completion status is queued on immediate error. */ + SetLastError(ERROR_SUCCESS); + oResult = (OVERLAPPED *)0xdeadbeef; + success = GetQueuedCompletionStatus(hcompletion, &written, &compkey, + &oResult, 0); + err = GetLastError(); + ok(!success && err == WAIT_TIMEOUT && !oResult, + "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n", + success, err, oResult); + + if (winetest_debug > 1) trace("Server reading from disconnected pipe...\n"); + SetLastError(ERROR_SUCCESS); + success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead); + if (winetest_debug > 1) trace("Server ReadFile from disconnected pipe returned...\n"); + err = GetLastError(); + ok(!success && err == ERROR_BROKEN_PIPE, + "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success, err); + + SetLastError(ERROR_SUCCESS); + oResult = (OVERLAPPED *)0xdeadbeef; + success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey, + &oResult, 0); + err = GetLastError(); + ok(!success && err == WAIT_TIMEOUT && !oResult, + "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n", + success, err, oResult); /* finish this connection, wait for next one */ ok(FlushFileBuffers(hnp), "FlushFileBuffers\n"); @@ -1111,7 +1220,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) int i; HANDLE hEvent; - trace("serverThreadMain5\n"); + if (winetest_debug > 1) trace("serverThreadMain5\n"); /* Set up a simple echo server */ hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, @@ -1139,23 +1248,23 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) oOverlap.hEvent = hEvent; /* Wait for client to connect */ - trace("Server calling ConnectNamedPipe...\n"); + if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n"); success = ConnectNamedPipe(hnp, NULL); err = GetLastError(); ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err); - trace("ConnectNamedPipe operation complete.\n"); + if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n"); /* Echo bytes once */ memset(buf, 0, sizeof(buf)); - trace("Server reading...\n"); + if (winetest_debug > 1) trace("Server reading...\n"); completion_called = 0; ResetEvent(hEvent); success = ReadFileEx(hnp, buf, sizeof(buf), &oOverlap, completion_routine); - trace("Server ReadFileEx returned...\n"); + if (winetest_debug > 1) trace("Server ReadFileEx returned...\n"); ok(success, "ReadFileEx failed, err=%i\n", GetLastError()); ok(completion_called == 0, "completion routine called before ReadFileEx return\n"); - trace("ReadFileEx returned.\n"); + if (winetest_debug > 1) trace("ReadFileEx returned.\n"); if (success) { DWORD ret; do { @@ -1168,16 +1277,16 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) ok(completion_num_bytes != 0, "read 0 bytes\n"); ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped); readden = completion_num_bytes; - trace("Server done reading.\n"); + if (winetest_debug > 1) trace("Server done reading.\n"); - trace("Server writing...\n"); + if (winetest_debug > 1) trace("Server writing...\n"); completion_called = 0; ResetEvent(hEvent); success = WriteFileEx(hnp, buf, readden, &oOverlap, completion_routine); - trace("Server WriteFileEx returned...\n"); + if (winetest_debug > 1) trace("Server WriteFileEx returned...\n"); ok(success, "WriteFileEx failed, err=%i\n", GetLastError()); ok(completion_called == 0, "completion routine called before ReadFileEx return\n"); - trace("overlapped WriteFile returned.\n"); + if (winetest_debug > 1) trace("overlapped WriteFile returned.\n"); if (success) { DWORD ret; do { @@ -1185,7 +1294,7 @@ static DWORD CALLBACK serverThreadMain5(LPVOID arg) } while (ret == WAIT_IO_COMPLETION); ok(ret == 0, "wait WriteFileEx returned %x\n", ret); } - trace("Server done writing.\n"); + if (winetest_debug > 1) trace("Server done writing.\n"); ok(completion_called == 1, "completion routine called %i times\n", completion_called); ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode); ok(completion_num_bytes == readden, "read %i bytes wrote %i\n", readden, completion_num_bytes); @@ -1202,7 +1311,7 @@ static void exercizeServer(const char *pipename, HANDLE serverThread) { int i; - trace("exercizeServer starting\n"); + if (winetest_debug > 1) trace("exercizeServer starting\n"); for (i = 0; i < NB_SERVER_LOOPS; i++) { HANDLE hFile=INVALID_HANDLE_VALUE; static const char obuf[] = "Bit Bucket"; @@ -1213,7 +1322,7 @@ static void exercizeServer(const char *pipename, HANDLE serverThread) for (loop = 0; loop < 3; loop++) { DWORD err; - trace("Client connecting...\n"); + if (winetest_debug > 1) trace("Client connecting...\n"); /* Connect to the server */ hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); @@ -1224,28 +1333,28 @@ static void exercizeServer(const char *pipename, HANDLE serverThread) ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n"); else ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n"); - trace("connect failed, retrying\n"); + if (winetest_debug > 1) trace("connect failed, retrying\n"); Sleep(200); } ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n"); /* Make sure it can echo */ memset(ibuf, 0, sizeof(ibuf)); - trace("Client writing...\n"); + if (winetest_debug > 1) trace("Client writing...\n"); ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n"); ok(written == sizeof(obuf), "write file len\n"); - trace("Client reading...\n"); + if (winetest_debug > 1) trace("Client reading...\n"); ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n"); ok(readden == sizeof(obuf), "read file len\n"); ok(memcmp(obuf, ibuf, written) == 0, "content check\n"); - trace("Client closing...\n"); + if (winetest_debug > 1) trace("Client closing...\n"); ok(CloseHandle(hFile), "CloseHandle\n"); } ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n"); CloseHandle(hnp); - trace("exercizeServer returning\n"); + if (winetest_debug > 1) trace("exercizeServer returning\n"); } static void test_NamedPipe_2(void) @@ -1299,7 +1408,7 @@ static void test_NamedPipe_2(void) ok(SetEvent( alarm_event ), "SetEvent\n"); CloseHandle( alarm_event ); - trace("test_NamedPipe_2 returning\n"); + if (winetest_debug > 1) trace("test_NamedPipe_2 returning\n"); } static int test_DisconnectNamedPipe(void) @@ -1349,10 +1458,20 @@ static int test_DisconnectNamedPipe(void) ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile from disconnected pipe with bytes waiting\n"); + ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "DisconnectNamedPipe worked twice\n"); ret = WaitForSingleObject(hFile, 0); ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %X\n", ret); + + ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL); + todo_wine + ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL); + todo_wine + ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); ok(CloseHandle(hFile), "CloseHandle\n"); } @@ -1463,6 +1582,11 @@ static void test_CloseHandle(void) ok(ret, "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); + ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); + ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); + numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL); @@ -1480,6 +1604,12 @@ static void test_CloseHandle(void) ok(!ret, "ReadFile unexpectedly succeeded\n"); ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL); + ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes); + SetLastError(0xdeadbeef); ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL); ok(!ret, "WriteFile unexpectedly succeeded\n"); @@ -1562,6 +1692,11 @@ static void test_CloseHandle(void) "ReadFile failed with %u\n", GetLastError()); ok(numbytes == 0, "expected 0, got %u\n", numbytes); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); + ok(ret, "PeekNamedPipe failed with %u\n", GetLastError()); + ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes); + numbytes = 0xdeadbeef; memset(buffer, 0, sizeof(buffer)); ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL); @@ -1579,6 +1714,12 @@ static void test_CloseHandle(void) ok(!ret, "ReadFile unexpectedly succeeded\n"); ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError()); + numbytes = 0xdeadbeef; + ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL); + ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n", + ret, GetLastError()); + ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes); + SetLastError(0xdeadbeef); ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL); ok(!ret, "WriteFile unexpectedly succeeded\n"); @@ -2501,11 +2642,9 @@ static void test_readfileex_pending(void) SetLastError(0xdeadbeef); ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped); ok(!ret, "ReadFile should fail\n"); -todo_wine ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError()); ok(num_bytes == 0, "bytes %u\n", num_bytes); ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal); -todo_wine ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh); wait = WaitForSingleObject(event, 100); @@ -2517,11 +2656,9 @@ todo_wine ok(num_bytes == 1, "bytes %u\n", num_bytes); wait = WaitForSingleObject(event, 100); -todo_wine ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait); ok(num_bytes == 1, "bytes %u\n", num_bytes); -todo_wine ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal); ok(overlapped.InternalHigh == 0, "expected 0, got %lu\n", overlapped.InternalHigh); @@ -2587,7 +2724,7 @@ static void _overlapped_read_sync(unsigned line, HANDLE reader, void *buf, DWORD else ok_(__FILE__,line)(res, "ReadFile failed: %u\n", GetLastError()); if(partial_read) - todo_wine ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes); + ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes); else ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result); @@ -2648,7 +2785,7 @@ static void _overlapped_write_async(unsigned line, HANDLE writer, void *buf, DWO overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); res = WriteFile(writer, buf, size, &written_bytes, overlapped); ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError()); - todo_wine ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes); + ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes); _test_not_signaled(line, overlapped->hEvent); } @@ -3048,6 +3185,7 @@ START_TEST(pipe) test_CreateNamedPipe(PIPE_TYPE_BYTE); test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE); test_CreatePipe(); + test_ReadFile(); test_CloseHandle(); test_impersonation(); test_overlapped(); @@ -3057,6 +3195,5 @@ START_TEST(pipe) test_readfileex_pending(); test_overlapped_transport(TRUE, FALSE); test_overlapped_transport(TRUE, TRUE); - if (broken(1)) /* FIXME: Remove once Wine is ready. */ - test_overlapped_transport(FALSE, FALSE); + test_overlapped_transport(FALSE, FALSE); } diff --git a/modules/rostests/winetests/kernel32/precomp.h b/modules/rostests/winetests/kernel32/precomp.h index 958ccf5ae0d..877b613d840 100644 --- a/modules/rostests/winetests/kernel32/precomp.h +++ b/modules/rostests/winetests/kernel32/precomp.h @@ -1,15 +1,16 @@ + #ifndef _KERNEL32_WINETEST_PRECOMP_H_ #define _KERNEL32_WINETEST_PRECOMP_H_ #include #include -#include -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H #define COBJMACROS +#include +#define WIN32_NO_STATUS + +#include #include #include #include diff --git a/modules/rostests/winetests/kernel32/process.c b/modules/rostests/winetests/kernel32/process.c index ee3bb221172..0c973ad366d 100755 --- a/modules/rostests/winetests/kernel32/process.c +++ b/modules/rostests/winetests/kernel32/process.c @@ -20,7 +20,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "wincon.h" +#include "winnls.h" +#include "winternl.h" +#include "tlhelp32.h" + +#include "wine/test.h" + +#include "winnt.h" /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000) @@ -1399,7 +1416,7 @@ static void test_SuspendFlag(void) ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startup, &info), "CreateProcess\n"); ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n"); - Sleep(8000); + Sleep(1000); ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n"); ok(ResumeThread(info.hThread) == 1, "Resuming thread\n"); @@ -1669,6 +1686,9 @@ static void test_Console(void) ok(ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL), "Reading from child\n"); ok(strcmp(buffer, msg) == 0, "Should have received '%s'\n", msg); + /* the child may also send the final "n tests executed" string, so read it to avoid a deadlock */ + ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL); + /* wait for child to terminate */ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); /* child process has changed result file, so let profile functions know about it */ @@ -2378,6 +2398,69 @@ static void _create_process(int line, const char *command, LPPROCESS_INFORMATION ok_(__FILE__, line)(ret, "CreateProcess error %u\n", GetLastError()); } +#define test_assigned_proc(job, ...) _test_assigned_proc(__LINE__, job, __VA_ARGS__) +static void _test_assigned_proc(int line, HANDLE job, int expected_count, ...) +{ + char buf[sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * 20]; + PJOBOBJECT_BASIC_PROCESS_ID_LIST pid_list = (JOBOBJECT_BASIC_PROCESS_ID_LIST *)buf; + DWORD ret_len, pid; + va_list valist; + int n; + BOOL ret; + + memset(buf, 0, sizeof(buf)); + ret = pQueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, sizeof(buf), &ret_len); + ok_(__FILE__, line)(ret, "QueryInformationJobObject error %u\n", GetLastError()); + if (ret) + { + todo_wine_if(expected_count) + ok_(__FILE__, line)(expected_count == pid_list->NumberOfAssignedProcesses, + "Expected NumberOfAssignedProcesses to be %d (expected_count) is %d\n", + expected_count, pid_list->NumberOfAssignedProcesses); + todo_wine_if(expected_count) + ok_(__FILE__, line)(expected_count == pid_list->NumberOfProcessIdsInList, + "Expected NumberOfProcessIdsInList to be %d (expected_count) is %d\n", + expected_count, pid_list->NumberOfProcessIdsInList); + + va_start(valist, expected_count); + for (n = 0; n < min(expected_count, pid_list->NumberOfProcessIdsInList); ++n) + { + pid = va_arg(valist, DWORD); + ok_(__FILE__, line)(pid == pid_list->ProcessIdList[n], + "Expected pid_list->ProcessIdList[%d] to be %x is %lx\n", + n, pid, pid_list->ProcessIdList[n]); + } + va_end(valist); + } +} + +#define test_accounting(job, total_proc, active_proc, terminated_proc) _test_accounting(__LINE__, job, total_proc, active_proc, terminated_proc) +static void _test_accounting(int line, HANDLE job, int total_proc, int active_proc, int terminated_proc) +{ + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION basic_accounting; + DWORD ret_len; + BOOL ret; + + memset(&basic_accounting, 0, sizeof(basic_accounting)); + ret = pQueryInformationJobObject(job, JobObjectBasicAccountingInformation, &basic_accounting, sizeof(basic_accounting), &ret_len); + ok_(__FILE__, line)(ret, "QueryInformationJobObject error %u\n", GetLastError()); + if (ret) + { + /* Not going to check process times or page faults */ + + todo_wine_if(total_proc) + ok_(__FILE__, line)(total_proc == basic_accounting.TotalProcesses, + "Expected basic_accounting.TotalProcesses to be %d (total_proc) is %d\n", + total_proc, basic_accounting.TotalProcesses); + todo_wine_if(active_proc) + ok_(__FILE__, line)(active_proc == basic_accounting.ActiveProcesses, + "Expected basic_accounting.ActiveProcesses to be %d (active_proc) is %d\n", + active_proc, basic_accounting.ActiveProcesses); + ok_(__FILE__, line)(terminated_proc == basic_accounting.TotalTerminatedProcesses, + "Expected basic_accounting.TotalTerminatedProcesses to be %d (terminated_proc) is %d\n", + terminated_proc, basic_accounting.TotalTerminatedProcesses); + } +} static void test_IsProcessInJob(void) { @@ -2404,11 +2487,15 @@ static void test_IsProcessInJob(void) ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(!out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job, 0); + test_accounting(job, 0, 0, 0); out = TRUE; ret = pIsProcessInJob(pi.hProcess, job2, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(!out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job2, 0); + test_accounting(job2, 0, 0, 0); out = TRUE; ret = pIsProcessInJob(pi.hProcess, NULL, &out); @@ -2422,11 +2509,15 @@ static void test_IsProcessInJob(void) ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job, 1, pi.dwProcessId); + test_accounting(job, 1, 1, 0); out = TRUE; ret = pIsProcessInJob(pi.hProcess, job2, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(!out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job2, 0); + test_accounting(job2, 0, 0, 0); out = FALSE; ret = pIsProcessInJob(pi.hProcess, NULL, &out); @@ -2442,6 +2533,8 @@ static void test_IsProcessInJob(void) ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job, 0); + test_accounting(job, 1, 0, 0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -2458,11 +2551,15 @@ static void test_TerminateJobObject(void) job = pCreateJobObjectW(NULL, NULL); ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); + test_assigned_proc(job, 0); + test_accounting(job, 0, 0, 0); create_process("wait", &pi); ret = pAssignProcessToJobObject(job, pi.hProcess); ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); + test_assigned_proc(job, 1, pi.dwProcessId); + test_accounting(job, 1, 1, 0); ret = pTerminateJobObject(job, 123); ok(ret, "TerminateJobObject error %u\n", GetLastError()); @@ -2470,6 +2567,8 @@ static void test_TerminateJobObject(void) dwret = WaitForSingleObject(pi.hProcess, 1000); ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0); + test_assigned_proc(job, 0); + test_accounting(job, 1, 0, 0); ret = GetExitCodeProcess(pi.hProcess, &dwret); ok(ret, "GetExitCodeProcess error %u\n", GetLastError()); @@ -2489,6 +2588,8 @@ static void test_TerminateJobObject(void) ret = pAssignProcessToJobObject(job, pi.hProcess); ok(!ret, "AssignProcessToJobObject unexpectedly succeeded\n"); expect_eq_d(ERROR_ACCESS_DENIED, GetLastError()); + test_assigned_proc(job, 0); + test_accounting(job, 1, 0, 0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -2675,11 +2776,15 @@ static void test_KillOnJobClose(void) return; } ok(ret, "SetInformationJobObject error %u\n", GetLastError()); + test_assigned_proc(job, 0); + test_accounting(job, 0, 0, 0); create_process("wait", &pi); ret = pAssignProcessToJobObject(job, pi.hProcess); ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); + test_assigned_proc(job, 1, pi.dwProcessId); + test_accounting(job, 1, 1, 0); CloseHandle(job); @@ -2790,6 +2895,8 @@ static HANDLE test_AddSelfToJob(void) ret = pAssignProcessToJobObject(job, GetCurrentProcess()); ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); + test_assigned_proc(job, 1, GetCurrentProcessId()); + test_accounting(job, 1, 1, 0); return job; } @@ -2817,6 +2924,8 @@ static void test_jobInheritance(HANDLE job) ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job, 2, GetCurrentProcessId(), pi.dwProcessId); + test_accounting(job, 2, 2, 0); dwret = WaitForSingleObject(pi.hProcess, 1000); ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); @@ -2845,6 +2954,8 @@ static void test_BreakawayOk(HANDLE job) ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi); ok(!ret, "CreateProcessA expected failure\n"); expect_eq_d(ERROR_ACCESS_DENIED, GetLastError()); + test_assigned_proc(job, 1, GetCurrentProcessId()); + test_accounting(job, 2, 1, 0); if (ret) { @@ -2867,6 +2978,8 @@ static void test_BreakawayOk(HANDLE job) ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(!out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job, 1, GetCurrentProcessId()); + test_accounting(job, 2, 1, 0); dwret = WaitForSingleObject(pi.hProcess, 1000); ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); @@ -2884,6 +2997,8 @@ static void test_BreakawayOk(HANDLE job) ret = pIsProcessInJob(pi.hProcess, job, &out); ok(ret, "IsProcessInJob error %u\n", GetLastError()); ok(!out, "IsProcessInJob returned out=%u\n", out); + test_assigned_proc(job, 1, GetCurrentProcessId()); + test_accounting(job, 2, 1, 0); dwret = WaitForSingleObject(pi.hProcess, 1000); ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); @@ -2965,6 +3080,389 @@ static void test_DetachConsoleHandles(void) #endif } +#if defined(__i386__) || defined(__x86_64__) +static BOOL read_nt_header(HANDLE process_handle, MEMORY_BASIC_INFORMATION *mbi, + IMAGE_NT_HEADERS *nt_header) +{ + IMAGE_DOS_HEADER dos_header; + + if (!ReadProcessMemory(process_handle, mbi->BaseAddress, &dos_header, sizeof(dos_header), NULL)) + return FALSE; + + if ((dos_header.e_magic != IMAGE_DOS_SIGNATURE) || + ((ULONG)dos_header.e_lfanew > mbi->RegionSize) || + (dos_header.e_lfanew < sizeof(dos_header))) + return FALSE; + + if (!ReadProcessMemory(process_handle, (char *)mbi->BaseAddress + dos_header.e_lfanew, + nt_header, sizeof(*nt_header), NULL)) + return FALSE; + + return (nt_header->Signature == IMAGE_NT_SIGNATURE); +} + +static PVOID get_process_exe(HANDLE process_handle, IMAGE_NT_HEADERS *nt_header) +{ + PVOID exe_base, address; + MEMORY_BASIC_INFORMATION mbi; + + /* Find the EXE base in the new process */ + exe_base = NULL; + for (address = NULL ; + VirtualQueryEx(process_handle, address, &mbi, sizeof(mbi)) ; + address = (char *)mbi.BaseAddress + mbi.RegionSize) { + if ((mbi.Type == SEC_IMAGE) && + read_nt_header(process_handle, &mbi, nt_header) && + !(nt_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) { + exe_base = mbi.BaseAddress; + break; + } + } + + return exe_base; +} + +static BOOL are_imports_resolved(HANDLE process_handle, PVOID module_base, IMAGE_NT_HEADERS *nt_header) +{ + BOOL ret; + IMAGE_IMPORT_DESCRIPTOR iid; + ULONG_PTR orig_iat_entry_value, iat_entry_value; + + ok(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, "Import table VA is zero\n"); + ok(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size, "Import table Size is zero\n"); + + if (!nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress || + !nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) + return FALSE; + + /* Read the first IID */ + ret = ReadProcessMemory(process_handle, + (char *)module_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, + &iid, sizeof(iid), NULL); + ok(ret, "Failed to read remote module IID (%d)\n", GetLastError()); + + /* Validate the IID is present and not a bound import, and that we have + an OriginalFirstThunk to compare with */ + ok(iid.Name, "Module first IID does not have a Name\n"); + ok(iid.FirstThunk, "Module first IID does not have a FirstThunk\n"); + ok(!iid.TimeDateStamp, "Module first IID is a bound import (UNSUPPORTED for current test)\n"); + ok(iid.OriginalFirstThunk, "Module first IID does not have an OriginalFirstThunk (UNSUPPORTED for current test)\n"); + + /* Read a single IAT entry from the FirstThunk */ + ret = ReadProcessMemory(process_handle, (char *)module_base + iid.FirstThunk, + &iat_entry_value, sizeof(iat_entry_value), NULL); + ok(ret, "Failed to read IAT entry from FirstThunk (%d)\n", GetLastError()); + ok(iat_entry_value, "IAT entry in FirstThunk is NULL\n"); + + /* Read a single IAT entry from the OriginalFirstThunk */ + ret = ReadProcessMemory(process_handle, (char *)module_base + iid.OriginalFirstThunk, + &orig_iat_entry_value, sizeof(orig_iat_entry_value), NULL); + ok(ret, "Failed to read IAT entry from OriginalFirstThunk (%d)\n", GetLastError()); + ok(orig_iat_entry_value, "IAT entry in OriginalFirstThunk is NULL\n"); + + return iat_entry_value != orig_iat_entry_value; +} + +static void test_SuspendProcessNewThread(void) +{ + BOOL ret; + STARTUPINFOA si = {0}; + PROCESS_INFORMATION pi = {0}; + PVOID exe_base, exit_thread_ptr; + IMAGE_NT_HEADERS nt_header; + HANDLE thread_handle = NULL; + DWORD dret, exit_code = 0; + CONTEXT ctx; + + exit_thread_ptr = GetProcAddress(hkernel32, "ExitThread"); + ok(exit_thread_ptr != NULL, "GetProcAddress ExitThread failed\n"); + + si.cb = sizeof(si); + ret = CreateProcessA(NULL, selfname, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + ok(ret, "Failed to create process (%d)\n", GetLastError()); + + exe_base = get_process_exe(pi.hProcess, &nt_header); + ok(exe_base != NULL, "Could not find EXE in remote process\n"); + + ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header); + ok(!ret, "IAT entry resolved prematurely\n"); + + thread_handle = CreateRemoteThread(pi.hProcess, NULL, 0, + (LPTHREAD_START_ROUTINE)exit_thread_ptr, + (PVOID)(ULONG_PTR)0x1234, CREATE_SUSPENDED, NULL); + ok(thread_handle != NULL, "Could not create remote thread (%d)\n", GetLastError()); + + ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header); + ok(!ret, "IAT entry resolved prematurely\n"); + + ctx.ContextFlags = CONTEXT_ALL; + ret = GetThreadContext( thread_handle, &ctx ); + ok( ret, "Failed retrieving remote thread context (%d)\n", GetLastError() ); + ok( ctx.ContextFlags == CONTEXT_ALL, "wrong flags %x\n", ctx.ContextFlags ); +#ifdef __x86_64__ + ok( !ctx.Rax, "rax is not zero %lx\n", ctx.Rax ); + ok( !ctx.Rbx, "rbx is not zero %lx\n", ctx.Rbx ); + ok( ctx.Rcx == (ULONG_PTR)exit_thread_ptr, "wrong rcx %lx/%p\n", ctx.Rcx, exit_thread_ptr ); + ok( ctx.Rdx == 0x1234, "wrong rdx %lx\n", ctx.Rdx ); + ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi ); + ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi ); + ok( !ctx.Rbp, "rbp is not zero %lx\n", ctx.Rbp ); + ok( !ctx.R8, "r8 is not zero %lx\n", ctx.R8 ); + ok( !ctx.R9, "r9 is not zero %lx\n", ctx.R9 ); + ok( !ctx.R10, "r10 is not zero %lx\n", ctx.R10 ); + ok( !ctx.R11, "r11 is not zero %lx\n", ctx.R11 ); + ok( !ctx.R12, "r12 is not zero %lx\n", ctx.R12 ); + ok( !ctx.R13, "r13 is not zero %lx\n", ctx.R13 ); + ok( !ctx.R14, "r14 is not zero %lx\n", ctx.R14 ); + ok( !ctx.R15, "r15 is not zero %lx\n", ctx.R15 ); + ok( !((ctx.Rsp + 0x28) & 0xfff), "rsp is not at top of stack page %lx\n", ctx.Rsp ); + ok( ctx.EFlags == 0x200, "wrong flags %08x\n", ctx.EFlags ); + ok( ctx.MxCsr == 0x1f80, "wrong mxcsr %08x\n", ctx.MxCsr ); + ok( ctx.FltSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FltSave.ControlWord ); +#else + ok( !ctx.Ebp || broken(ctx.Ebp), /* winxp */ "ebp is not zero %08x\n", ctx.Ebp ); + if (!ctx.Ebp) /* winxp is completely different */ + { + ok( !ctx.Ecx, "ecx is not zero %08x\n", ctx.Ecx ); + ok( !ctx.Edx, "edx is not zero %08x\n", ctx.Edx ); + ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi ); + ok( !ctx.Edi, "edi is not zero %08x\n", ctx.Edi ); + } + ok( ctx.Eax == (ULONG_PTR)exit_thread_ptr, "wrong eax %08x/%p\n", ctx.Eax, exit_thread_ptr ); + ok( ctx.Ebx == 0x1234, "wrong ebx %08x\n", ctx.Ebx ); + ok( !((ctx.Esp + 0x10) & 0xfff) || broken( !((ctx.Esp + 4) & 0xfff) ), /* winxp, w2k3 */ + "esp is not at top of stack page or properly aligned: %08x\n", ctx.Esp ); + ok( (ctx.EFlags & ~2) == 0x200, "wrong flags %08x\n", ctx.EFlags ); + ok( (WORD)ctx.FloatSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FloatSave.ControlWord ); + ok( *(WORD *)ctx.ExtendedRegisters == 0x27f, "wrong control %08x\n", *(WORD *)ctx.ExtendedRegisters ); +#endif + + ResumeThread( thread_handle ); + dret = WaitForSingleObject(thread_handle, 60000); + ok(dret == WAIT_OBJECT_0, "Waiting for remote thread failed (%d)\n", GetLastError()); + ret = GetExitCodeThread(thread_handle, &exit_code); + ok(ret, "Failed to retrieve remote thread exit code (%d)\n", GetLastError()); + ok(exit_code == 0x1234, "Invalid remote thread exit code\n"); + + ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header); + ok(ret, "EXE IAT entry not resolved\n"); + + if (thread_handle) + CloseHandle(thread_handle); + + TerminateProcess(pi.hProcess, 0); + WaitForSingleObject(pi.hProcess, 10000); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); +} + +static void test_SuspendProcessState(void) +{ + struct pipe_params + { + ULONG pipe_write_buf; + ULONG pipe_read_buf; + ULONG bytes_returned; + CHAR pipe_name[MAX_PATH]; + }; + +#ifdef __x86_64__ + struct remote_rop_chain + { + void *exit_process_ptr; + ULONG_PTR home_rcx; + ULONG_PTR home_rdx; + ULONG_PTR home_r8; + ULONG_PTR home_r9; + ULONG_PTR pipe_read_buf_size; + ULONG_PTR bytes_returned; + ULONG_PTR timeout; + }; +#else + struct remote_rop_chain + { + void *exit_process_ptr; + ULONG_PTR pipe_name; + ULONG_PTR pipe_write_buf; + ULONG_PTR pipe_write_buf_size; + ULONG_PTR pipe_read_buf; + ULONG_PTR pipe_read_buf_size; + ULONG_PTR bytes_returned; + ULONG_PTR timeout; + void *unreached_ret; + ULONG_PTR exit_code; + }; +#endif + + static const char pipe_name[] = "\\\\.\\pipe\\TestPipe"; + static const ULONG pipe_write_magic = 0x454e4957; + STARTUPINFOA si = {0}; + PROCESS_INFORMATION pi = {0}; + PVOID exe_base, remote_pipe_params, exit_process_ptr, + call_named_pipe_a; + IMAGE_NT_HEADERS nt_header; + struct pipe_params pipe_params; + struct remote_rop_chain rop_chain; + CONTEXT ctx; + HANDLE server_pipe_handle; + BOOL pipe_connected; + ULONG pipe_magic, numb; + BOOL ret; + void *entry_ptr, *peb_ptr; + PEB child_peb; + + exit_process_ptr = GetProcAddress(hkernel32, "ExitProcess"); + ok(exit_process_ptr != NULL, "GetProcAddress ExitProcess failed\n"); + + call_named_pipe_a = GetProcAddress(hkernel32, "CallNamedPipeA"); + ok(call_named_pipe_a != NULL, "GetProcAddress CallNamedPipeA failed\n"); + + si.cb = sizeof(si); + ret = CreateProcessA(NULL, selfname, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + ok(ret, "Failed to create process (%d)\n", GetLastError()); + + exe_base = get_process_exe(pi.hProcess, &nt_header); + /* Make sure we found the EXE in the new process */ + ok(exe_base != NULL, "Could not find EXE in remote process\n"); + + ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header); + ok(!ret, "IAT entry resolved prematurely\n"); + + server_pipe_handle = CreateNamedPipeA(pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 0x20000, 0x20000, + 0, NULL); + ok(server_pipe_handle != INVALID_HANDLE_VALUE, "Failed to create communication pipe (%d)\n", GetLastError()); + + /* Set up the remote process environment */ + ctx.ContextFlags = CONTEXT_ALL; + ret = GetThreadContext(pi.hThread, &ctx); + ok(ret, "Failed retrieving remote thread context (%d)\n", GetLastError()); + ok( ctx.ContextFlags == CONTEXT_ALL, "wrong flags %x\n", ctx.ContextFlags ); + + remote_pipe_params = VirtualAllocEx(pi.hProcess, NULL, sizeof(pipe_params), MEM_COMMIT, PAGE_READWRITE); + ok(remote_pipe_params != NULL, "Failed allocating memory in remote process (%d)\n", GetLastError()); + + pipe_params.pipe_write_buf = pipe_write_magic; + pipe_params.pipe_read_buf = 0; + pipe_params.bytes_returned = 0; + strcpy(pipe_params.pipe_name, pipe_name); + + ret = WriteProcessMemory(pi.hProcess, remote_pipe_params, + &pipe_params, sizeof(pipe_params), NULL); + ok(ret, "Failed to write to remote process memory (%d)\n", GetLastError()); + +#ifdef __x86_64__ + ok( !ctx.Rax, "rax is not zero %lx\n", ctx.Rax ); + ok( !ctx.Rbx, "rbx is not zero %lx\n", ctx.Rbx ); + ok( !ctx.Rsi, "rsi is not zero %lx\n", ctx.Rsi ); + ok( !ctx.Rdi, "rdi is not zero %lx\n", ctx.Rdi ); + ok( !ctx.Rbp, "rbp is not zero %lx\n", ctx.Rbp ); + ok( !ctx.R8, "r8 is not zero %lx\n", ctx.R8 ); + ok( !ctx.R9, "r9 is not zero %lx\n", ctx.R9 ); + ok( !ctx.R10, "r10 is not zero %lx\n", ctx.R10 ); + ok( !ctx.R11, "r11 is not zero %lx\n", ctx.R11 ); + ok( !ctx.R12, "r12 is not zero %lx\n", ctx.R12 ); + ok( !ctx.R13, "r13 is not zero %lx\n", ctx.R13 ); + ok( !ctx.R14, "r14 is not zero %lx\n", ctx.R14 ); + ok( !ctx.R15, "r15 is not zero %lx\n", ctx.R15 ); + ok( !((ctx.Rsp + 0x28) & 0xfff), "rsp is not at top of stack page %lx\n", ctx.Rsp ); + ok( ctx.EFlags == 0x200, "wrong flags %08x\n", ctx.EFlags ); + ok( ctx.MxCsr == 0x1f80, "wrong mxcsr %08x\n", ctx.MxCsr ); + ok( ctx.FltSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FltSave.ControlWord ); + entry_ptr = (void *)ctx.Rcx; + peb_ptr = (void *)ctx.Rdx; + + rop_chain.exit_process_ptr = exit_process_ptr; + ctx.Rcx = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_name); + ctx.Rdx = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_write_buf); + ctx.R8 = sizeof(pipe_params.pipe_write_buf); + ctx.R9 = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_read_buf); + rop_chain.pipe_read_buf_size = sizeof(pipe_params.pipe_read_buf); + rop_chain.bytes_returned = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, bytes_returned); + rop_chain.timeout = 10000; + + ctx.Rip = (ULONG_PTR)call_named_pipe_a; + ctx.Rsp -= sizeof(rop_chain); + ret = WriteProcessMemory(pi.hProcess, (void *)ctx.Rsp, &rop_chain, sizeof(rop_chain), NULL); + ok(ret, "Failed to write to remote process thread stack (%d)\n", GetLastError()); +#else + ok( !ctx.Ebp || broken(ctx.Ebp), /* winxp */ "ebp is not zero %08x\n", ctx.Ebp ); + if (!ctx.Ebp) /* winxp is completely different */ + { + ok( !ctx.Ecx, "ecx is not zero %08x\n", ctx.Ecx ); + ok( !ctx.Edx, "edx is not zero %08x\n", ctx.Edx ); + ok( !ctx.Esi, "esi is not zero %08x\n", ctx.Esi ); + ok( !ctx.Edi, "edi is not zero %08x\n", ctx.Edi ); + } + ok( !((ctx.Esp + 0x10) & 0xfff) || broken( !((ctx.Esp + 4) & 0xfff) ), /* winxp, w2k3 */ + "esp is not at top of stack page or properly aligned: %08x\n", ctx.Esp ); + ok( (ctx.EFlags & ~2) == 0x200, "wrong flags %08x\n", ctx.EFlags ); + ok( (WORD)ctx.FloatSave.ControlWord == 0x27f, "wrong control %08x\n", ctx.FloatSave.ControlWord ); + ok( *(WORD *)ctx.ExtendedRegisters == 0x27f, "wrong control %08x\n", *(WORD *)ctx.ExtendedRegisters ); + entry_ptr = (void *)ctx.Eax; + peb_ptr = (void *)ctx.Ebx; + + rop_chain.exit_process_ptr = exit_process_ptr; + rop_chain.pipe_name = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_name); + rop_chain.pipe_write_buf = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_write_buf); + rop_chain.pipe_write_buf_size = sizeof(pipe_params.pipe_write_buf); + rop_chain.pipe_read_buf = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, pipe_read_buf); + rop_chain.pipe_read_buf_size = sizeof(pipe_params.pipe_read_buf); + rop_chain.bytes_returned = (ULONG_PTR)remote_pipe_params + offsetof(struct pipe_params, bytes_returned); + rop_chain.timeout = 10000; + rop_chain.exit_code = 0; + + ctx.Eip = (ULONG_PTR)call_named_pipe_a; + ctx.Esp -= sizeof(rop_chain); + ret = WriteProcessMemory(pi.hProcess, (void *)ctx.Esp, &rop_chain, sizeof(rop_chain), NULL); + ok(ret, "Failed to write to remote process thread stack (%d)\n", GetLastError()); +#endif + + ret = ReadProcessMemory( pi.hProcess, peb_ptr, &child_peb, sizeof(child_peb), NULL ); + ok( ret, "Failed to read PEB (%u)\n", GetLastError() ); + ok( child_peb.ImageBaseAddress == exe_base, "wrong base %p/%p\n", + child_peb.ImageBaseAddress, exe_base ); + ok( entry_ptr == (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint, + "wrong entry point %p/%p\n", entry_ptr, + (char *)exe_base + nt_header.OptionalHeader.AddressOfEntryPoint ); + + ret = SetThreadContext(pi.hThread, &ctx); + ok(ret, "Failed to set remote thread context (%d)\n", GetLastError()); + + ResumeThread(pi.hThread); + + pipe_connected = ConnectNamedPipe(server_pipe_handle, NULL) || (GetLastError() == ERROR_PIPE_CONNECTED); + ok(pipe_connected, "Pipe did not connect\n"); + + ret = ReadFile(server_pipe_handle, &pipe_magic, sizeof(pipe_magic), &numb, NULL); + ok(ret, "Failed to read buffer from pipe (%d)\n", GetLastError()); + + ok(pipe_magic == pipe_write_magic, "Did not get the correct magic from the remote process\n"); + + /* Validate the Imports, at this point the thread in the new process should have + initialized the EXE module imports and call each dll DllMain notifying it on + the new thread in the process. */ + ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header); + ok(ret, "EXE IAT is not resolved\n"); + + ret = WriteFile(server_pipe_handle, &pipe_magic, sizeof(pipe_magic), &numb, NULL); + ok(ret, "Failed to write the magic back to the pipe (%d)\n", GetLastError()); + + CloseHandle(server_pipe_handle); + TerminateProcess(pi.hProcess, 0); + WaitForSingleObject(pi.hProcess, 10000); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); +} +#else +static void test_SuspendProcessNewThread(void) +{ +} +static void test_SuspendProcessState(void) +{ +} +#endif + static void test_DetachStdHandles(void) { #ifndef _WIN64 @@ -3371,7 +3869,7 @@ static void test_ProcThreadAttributeList(void) ok(GetLastError() == ERROR_OBJECT_NAME_EXISTS, "got %d\n", GetLastError()); ret = pUpdateProcThreadAttribute(&list, 0, PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR, handles, sizeof(PROCESSOR_NUMBER), NULL, NULL); - ok(ret || (!ret && GetLastError() == ERROR_NOT_SUPPORTED), "got %d gle %d\n", ret, GetLastError()); + ok(ret || GetLastError() == ERROR_NOT_SUPPORTED, "got %d gle %d\n", ret, GetLastError()); if (ret) { @@ -3484,6 +3982,8 @@ START_TEST(process) test_GetActiveProcessorCount(); test_largepages(); test_ProcThreadAttributeList(); + test_SuspendProcessState(); + test_SuspendProcessNewThread(); /* things that can be tested: * lookup: check the way program to be executed is searched diff --git a/modules/rostests/winetests/kernel32/profile.c b/modules/rostests/winetests/kernel32/profile.c index 277d018579a..f3f1cf25df3 100755 --- a/modules/rostests/winetests/kernel32/profile.c +++ b/modules/rostests/winetests/kernel32/profile.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "windows.h" +#include "sddl.h" #define KEY "ProfileInt" #define SECTION "Test" @@ -526,6 +533,41 @@ static BOOL emptystr_ok(CHAR emptystr[MAX_PATH]) return TRUE; } +static void test_profile_directory_readonly(void) +{ + BOOL ret; + CHAR path_folder[MAX_PATH]; + CHAR path_file[MAX_PATH]; + const char *sddl_string_everyone_readonly = "D:PAI(A;;0x1200a9;;;WD)"; + SECURITY_ATTRIBUTES attributes = {0}; + char lpStruct[] = { 's', 't', 'r', 'i', 'n', 'g' }; + + attributes.nLength = sizeof(attributes); + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(sddl_string_everyone_readonly, SDDL_REVISION_1, &attributes.lpSecurityDescriptor, NULL); + ok(ret == TRUE, "ConvertStringSecurityDescriptorToSecurityDescriptor failed: %d\n", GetLastError()); + + GetTempPathA(MAX_PATH, path_folder); + lstrcatA(path_folder, "wine-test"); + + strcpy(path_file, path_folder); + lstrcatA(path_file, "\\tmp.ini"); + + ret = CreateDirectoryA(path_folder, &attributes); + ok(ret == TRUE, "CreateDirectoryA failed: %d\n", GetLastError()); + + ret = WritePrivateProfileStringA("App", "key", "string", path_file); + ok(ret == FALSE, "Expected FALSE, got %d\n", ret); + + ret = WritePrivateProfileSectionA("App", "key=string", path_file); + ok(ret == FALSE, "Expected FALSE, got %d\n", ret); + + ret = WritePrivateProfileStructA("App", "key", lpStruct, sizeof(lpStruct), path_file); + ok(ret == FALSE, "Expected FALSE, got %d\n", ret); + + ret = RemoveDirectoryA(path_folder); + ok(ret == TRUE, "RemoveDirectoryA failed: %d\n", GetLastError()); +} + static void test_GetPrivateProfileString(const char *content, const char *descript) { DWORD ret, len; @@ -1124,6 +1166,7 @@ START_TEST(profile) test_profile_existing(); test_profile_delete_on_close(); test_profile_refresh(); + test_profile_directory_readonly(); test_GetPrivateProfileString( "[section1]\r\n" "name1=val1\r\n" diff --git a/modules/rostests/winetests/kernel32/resource.c b/modules/rostests/winetests/kernel32/resource.c index b0014a38afd..74066cfba3c 100644 --- a/modules/rostests/winetests/kernel32/resource.c +++ b/modules/rostests/winetests/kernel32/resource.c @@ -18,7 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#include "wine/test.h" static const char filename[] = "test_.exe"; static DWORD GLE; diff --git a/modules/rostests/winetests/kernel32/sync.c b/modules/rostests/winetests/kernel32/sync.c index 6cbff90059d..fb368de4058 100755 --- a/modules/rostests/winetests/kernel32/sync.c +++ b/modules/rostests/winetests/kernel32/sync.c @@ -18,24 +18,28 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x500 +#endif +#include +#include +#include +#include +#include +#include + +#include "wine/test.h" + +#ifdef __REACTOS__ #define QueryDepthSList(x) RtlQueryDepthSList(x) #define InterlockedPushEntrySList(x,y) RtlInterlockedPushEntrySList(x,y) #define InterlockedPopEntrySList(x) RtlInterlockedPopEntrySList(x) #define InterlockedFlushSList(x) RtlInterlockedFlushSList(x) +#endif #undef __fastcall #define __fastcall __stdcall -static BOOL (WINAPI *pChangeTimerQueueTimer)(HANDLE, HANDLE, ULONG, ULONG); -static HANDLE (WINAPI *pCreateTimerQueue)(void); -static BOOL (WINAPI *pCreateTimerQueueTimer)(PHANDLE, HANDLE, WAITORTIMERCALLBACK, - PVOID, DWORD, DWORD, ULONG); -static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR); -static BOOL (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE); -static BOOL (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE); -static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR); static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE); static BOOL (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL); static VOID (WINAPI *pInitOnceInitialize)(PINIT_ONCE); @@ -106,25 +110,12 @@ static void init_fastcall_thunk(void) static void test_signalandwait(void) { - DWORD (WINAPI *pSignalObjectAndWait)(HANDLE, HANDLE, DWORD, BOOL); - HMODULE kernel32; DWORD r; HANDLE event[2], semaphore[2], file; int i; - kernel32 = GetModuleHandleA("kernel32.dll"); - pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait"); - - if (!pSignalObjectAndWait) - return; - /* invalid parameters */ - r = pSignalObjectAndWait(NULL, NULL, 0, 0); - if (r == ERROR_INVALID_FUNCTION) - { - win_skip("SignalObjectAndWait is not implemented\n"); - return; /* Win98/ME */ - } + r = SignalObjectAndWait(NULL, NULL, 0, 0); ok( r == WAIT_FAILED, "should fail\n"); event[0] = CreateEventW(NULL, 0, 0, NULL); @@ -132,22 +123,22 @@ static void test_signalandwait(void) ok( event[0] && event[1], "failed to create event flags\n"); - r = pSignalObjectAndWait(event[0], NULL, 0, FALSE); + r = SignalObjectAndWait(event[0], NULL, 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); - r = pSignalObjectAndWait(NULL, event[0], 0, FALSE); + r = SignalObjectAndWait(NULL, event[0], 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); /* valid parameters */ - r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); + r = SignalObjectAndWait(event[0], event[1], 0, FALSE); ok( r == WAIT_OBJECT_0, "should succeed\n"); /* event[0] is now signalled - we repeat this test multiple times * to ensure that the wineserver handles this situation properly. */ for (i = 0; i < 10000; i++) { - r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); + r = SignalObjectAndWait(event[0], event[0], 0, FALSE); ok(r == WAIT_OBJECT_0, "should succeed\n"); } @@ -155,12 +146,12 @@ static void test_signalandwait(void) r = WaitForSingleObject(event[0], 0); ok( r == WAIT_TIMEOUT, "event was signalled\n"); - r = pSignalObjectAndWait(event[0], event[0], 0, FALSE); + r = SignalObjectAndWait(event[0], event[0], 0, FALSE); ok( r == WAIT_OBJECT_0, "should succeed\n"); /* clear event[1] and check for a timeout */ ok(ResetEvent(event[1]), "failed to clear event[1]\n"); - r = pSignalObjectAndWait(event[0], event[1], 0, FALSE); + r = SignalObjectAndWait(event[0], event[1], 0, FALSE); ok( r == WAIT_TIMEOUT, "should timeout\n"); CloseHandle(event[0]); @@ -171,10 +162,10 @@ static void test_signalandwait(void) semaphore[1] = CreateSemaphoreW( NULL, 1, 1, NULL ); ok( semaphore[0] && semaphore[1], "failed to create semaphore\n"); - r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); + r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); ok( r == WAIT_OBJECT_0, "should succeed\n"); - r = pSignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); + r = SignalObjectAndWait(semaphore[0], semaphore[1], 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); r = ReleaseSemaphore(semaphore[0],1,NULL); @@ -189,7 +180,7 @@ static void test_signalandwait(void) /* try a registry key */ file = CreateFileA("x", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); - r = pSignalObjectAndWait(file, file, 0, FALSE); + r = SignalObjectAndWait(file, file, 0, FALSE); ok( r == WAIT_FAILED, "should fail\n"); ok( ERROR_INVALID_HANDLE == GetLastError(), "should return invalid handle error\n"); CloseHandle(file); @@ -282,6 +273,16 @@ todo_wine ok(!hOpened, "OpenMutex succeeded\n"); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + SetLastError(0xdeadbeef); + hOpened = OpenMutexA(READ_CONTROL, FALSE, NULL); + ok(!hOpened, "OpenMutex succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + hOpened = OpenMutexW(READ_CONTROL, FALSE, NULL); + ok(!hOpened, "OpenMutex succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + SetLastError(0xdeadbeef); hOpened = CreateMutexA(NULL, FALSE, "WineTestMutex"); ok(hOpened != NULL, "CreateMutex failed with error %d\n", GetLastError()); @@ -535,6 +536,16 @@ static void test_event(void) ok( !handle2, "OpenEvent succeeded\n"); ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + SetLastError(0xdeadbeef); + handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, NULL ); + ok( !handle2, "OpenEvent succeeded\n"); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle2 = OpenEventW( EVENT_ALL_ACCESS, FALSE, NULL ); + ok( !handle2, "OpenEvent succeeded\n"); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + CloseHandle( handle ); /* resource notifications are events too */ @@ -604,6 +615,16 @@ static void test_semaphore(void) ok( !handle2, "OpenSemaphore succeeded\n"); ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + SetLastError(0xdeadbeef); + handle2 = OpenSemaphoreA( SEMAPHORE_ALL_ACCESS, FALSE, NULL ); + ok( !handle2, "OpenSemaphore succeeded\n"); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle2 = OpenSemaphoreW( SEMAPHORE_ALL_ACCESS, FALSE, NULL ); + ok( !handle2, "OpenSemaphore succeeded\n"); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + CloseHandle( handle ); } @@ -611,42 +632,44 @@ static void test_waitable_timer(void) { HANDLE handle, handle2; - if (!pCreateWaitableTimerA || !pOpenWaitableTimerA) - { - win_skip("{Create,Open}WaitableTimerA() is not available\n"); - return; - } - /* test case sensitivity */ SetLastError(0xdeadbeef); - handle = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer"); + handle = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer"); ok(handle != NULL, "CreateWaitableTimer failed with error %u\n", GetLastError()); ok(GetLastError() == 0, "wrong error %u\n", GetLastError()); SetLastError(0xdeadbeef); - handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer"); + handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": Test WaitableTimer"); ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError()); ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError()); CloseHandle( handle2 ); SetLastError(0xdeadbeef); - handle2 = pCreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER"); + handle2 = CreateWaitableTimerA(NULL, FALSE, __FILE__ ": TEST WAITABLETIMER"); ok( handle2 != NULL, "CreateWaitableTimer failed with error %d\n", GetLastError()); ok( GetLastError() == 0, "wrong error %u\n", GetLastError()); CloseHandle( handle2 ); SetLastError(0xdeadbeef); - handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer"); + handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": Test WaitableTimer"); ok( handle2 != NULL, "OpenWaitableTimer failed with error %d\n", GetLastError()); CloseHandle( handle2 ); SetLastError(0xdeadbeef); - handle2 = pOpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER"); + handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, __FILE__ ": TEST WAITABLETIMER"); ok( !handle2, "OpenWaitableTimer succeeded\n"); - ok( GetLastError() == ERROR_FILE_NOT_FOUND || - GetLastError() == ERROR_INVALID_NAME, /* win98 */ - "wrong error %u\n", GetLastError()); + ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle2 = OpenWaitableTimerA( TIMER_ALL_ACCESS, FALSE, NULL ); + ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError()); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + handle2 = OpenWaitableTimerW( TIMER_ALL_ACCESS, FALSE, NULL ); + ok( !handle2, "OpenWaitableTimer failed with error %d\n", GetLastError()); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError()); CloseHandle( handle ); } @@ -776,7 +799,7 @@ static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut) SetLastError(0xdeadbeef); /* Note, XP SP2 does *not* do any deadlock checking, so passing INVALID_HANDLE_VALUE here will just hang. */ - ret = pDeleteTimerQueueTimer(d->q, d->t, NULL); + ret = DeleteTimerQueueTimer(d->q, d->t, NULL); ok(!ret, "DeleteTimerQueueTimer\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n"); } @@ -790,7 +813,7 @@ static void CALLBACK timer_queue_cb3(PVOID p, BOOLEAN timedOut) { /* Basically kill the timer since it won't have time to run again. */ - BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 10000, 0); + BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 10000, 0); ok(ret, "ChangeTimerQueueTimer\n"); } } @@ -806,7 +829,7 @@ static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut) period of zero (run once), then ChangeTimerQueueTimer will fail if the timer is already flagged. Hence we really run only once. Otherwise we will run multiple times. */ - BOOL ret = pChangeTimerQueueTimer(d->q, d->t, 50, 50); + BOOL ret = ChangeTimerQueueTimer(d->q, d->t, 50, 50); ok(ret, "ChangeTimerQueueTimer\n"); ++d->num_calls; } @@ -838,15 +861,15 @@ static void CALLBACK timer_queue_cb6(PVOID p, BOOLEAN timedOut) /* The delete will pend while we are in this callback. */ SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueTimer(d->q, d->t, NULL); + ret = DeleteTimerQueueTimer(d->q, d->t, NULL); ok(!ret, "DeleteTimerQueueTimer\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer\n"); - ret = pCreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0); + ret = CreateTimerQueueTimer(&t, d->q, timer_queue_cb1, NULL, 100, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t != NULL, "CreateTimerQueueTimer\n"); - ret = pDeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueTimer(d->q, t, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueTimer\n"); /* Now we stay alive by hanging around in the callback. */ @@ -862,35 +885,27 @@ static void test_timer_queue(void) HANDLE e, et1, et2; BOOL ret, ret0; - if (!pChangeTimerQueueTimer || !pCreateTimerQueue || !pCreateTimerQueueTimer - || !pDeleteTimerQueueEx || !pDeleteTimerQueueTimer) - { - win_skip("TimerQueue API not present\n"); - return; - } - /* Test asynchronous deletion of the queue. */ - q = pCreateTimerQueue(); + q = CreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueEx(q, NULL); + ret = DeleteTimerQueueEx(q, NULL); ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n", GetLastError()); /* Test synchronous deletion of the queue and running timers. */ - q = pCreateTimerQueue(); + q = CreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); /* Not called. */ t0 = NULL; n0 = 0; - ret = pCreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0, - 300, 0); + ret = CreateTimerQueueTimer(&t0, q, timer_queue_cb1, &n0, 0, 300, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t0 != NULL, "CreateTimerQueueTimer\n"); - ret0 = pDeleteTimerQueueTimer(q, t0, NULL); + ret0 = DeleteTimerQueueTimer(q, t0, NULL); ok((!ret0 && GetLastError() == ERROR_IO_PENDING) || broken(ret0), /* Win 2000 & XP & 2003 */ "DeleteTimerQueueTimer ret=%d le=%u\n", ret0, GetLastError()); @@ -898,40 +913,35 @@ static void test_timer_queue(void) /* Called once. */ t1 = NULL; n1 = 0; - ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, - 0, 0); + ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 0, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t1 != NULL, "CreateTimerQueueTimer\n"); /* A slow one. */ t2 = NULL; n2 = 0; - ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, - 100, 0); + ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb1, &n2, 0, 100, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t2 != NULL, "CreateTimerQueueTimer\n"); /* A fast one. */ t3 = NULL; n3 = 0; - ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, - 10, 0); + ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb1, &n3, 0, 10, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t3 != NULL, "CreateTimerQueueTimer\n"); /* Start really late (it won't start). */ t4 = NULL; n4 = 0; - ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, - 10, 0); + ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb1, &n4, 10000, 10, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t4 != NULL, "CreateTimerQueueTimer\n"); /* Start soon, but delay so long it won't run again. */ t5 = NULL; n5 = 0; - ret = pCreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, - 10000, 0); + ret = CreateTimerQueueTimer(&t5, q, timer_queue_cb1, &n5, 0, 10000, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t5 != NULL, "CreateTimerQueueTimer\n"); @@ -939,14 +949,14 @@ static void test_timer_queue(void) Sleep(500); /* Test deleting a once-only timer. */ - ret = pDeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueTimer(q, t1, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueTimer\n"); /* A periodic timer. */ - ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueTimer\n"); - ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueEx\n"); todo_wine ok(n0 == 1 || broken(ret0 && n0 == 0), "Timer callback 0 expected 1 got %d\n", n0); @@ -965,32 +975,30 @@ static void test_timer_queue(void) return; } - q = pCreateTimerQueue(); + q = CreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); /* Run once and finish quickly (should be done when we delete it). */ t1 = NULL; - ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0); + ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb5, NULL, 0, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t1 != NULL, "CreateTimerQueueTimer\n"); /* Run once and finish slowly (shouldn't be done when we delete it). */ t2 = NULL; - ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, - 0, 0); + ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t2 != NULL, "CreateTimerQueueTimer\n"); /* Run once and finish quickly (should be done when we delete it). */ t3 = NULL; - ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0); + ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb5, NULL, 0, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t3 != NULL, "CreateTimerQueueTimer\n"); /* Run once and finish slowly (shouldn't be done when we delete it). */ t4 = NULL; - ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, - 0, 0); + ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb5, (PVOID) 1000, 0, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t4 != NULL, "CreateTimerQueueTimer\n"); @@ -1000,20 +1008,20 @@ static void test_timer_queue(void) /* DeleteTimerQueueTimer always returns PENDING with a NULL event, even if the timer is finished. */ SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueTimer(q, t1, NULL); + ret = DeleteTimerQueueTimer(q, t1, NULL); ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueTimer(q, t2, NULL); + ret = DeleteTimerQueueTimer(q, t2, NULL); ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueTimer(q, t3, et1); + ret = DeleteTimerQueueTimer(q, t3, et1); ok(ret, "DeleteTimerQueueTimer call was expected to fail\n"); ok(GetLastError() == 0xdeadbeef, "DeleteTimerQueueTimer, GetLastError: expected 0xdeadbeef, got %d\n", @@ -1022,7 +1030,7 @@ static void test_timer_queue(void) "Timer destruction event not triggered\n"); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueTimer(q, t4, et2); + ret = DeleteTimerQueueTimer(q, t4, et2); ok(!ret, "DeleteTimerQueueTimer call was expected to fail\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueTimer, GetLastError: expected ERROR_IO_PENDING, got %d\n", @@ -1031,7 +1039,7 @@ static void test_timer_queue(void) "Timer destruction event not triggered\n"); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueEx(q, e); + ret = DeleteTimerQueueEx(q, e); ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n", GetLastError()); @@ -1040,25 +1048,23 @@ static void test_timer_queue(void) CloseHandle(e); /* Test deleting/changing a timer in execution. */ - q = pCreateTimerQueue(); + q = CreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); /* Test changing a once-only timer before it fires (this is allowed, whereas after it fires you cannot). */ n1 = 0; - ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, - 0, 0); + ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 10000, 0, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t1 != NULL, "CreateTimerQueueTimer\n"); - ret = pChangeTimerQueueTimer(q, t1, 0, 0); + ret = ChangeTimerQueueTimer(q, t1, 0, 0); ok(ret, "ChangeTimerQueueTimer\n"); d2.t = t2 = NULL; d2.num_calls = 0; d2.max_calls = 3; d2.q = q; - ret = pCreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, - 10, 0); + ret = CreateTimerQueueTimer(&t2, q, timer_queue_cb2, &d2, 10, 10, 0); d2.t = t2; ok(ret, "CreateTimerQueueTimer\n"); ok(t2 != NULL, "CreateTimerQueueTimer\n"); @@ -1067,8 +1073,7 @@ static void test_timer_queue(void) d3.num_calls = 0; d3.max_calls = 4; d3.q = q; - ret = pCreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, - 10, 0); + ret = CreateTimerQueueTimer(&t3, q, timer_queue_cb3, &d3, 10, 10, 0); d3.t = t3; ok(ret, "CreateTimerQueueTimer\n"); ok(t3 != NULL, "CreateTimerQueueTimer\n"); @@ -1076,15 +1081,14 @@ static void test_timer_queue(void) d4.t = t4 = NULL; d4.num_calls = 0; d4.q = q; - ret = pCreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, - 0, 0); + ret = CreateTimerQueueTimer(&t4, q, timer_queue_cb4, &d4, 10, 0, 0); d4.t = t4; ok(ret, "CreateTimerQueueTimer\n"); ok(t4 != NULL, "CreateTimerQueueTimer\n"); Sleep(500); - ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueEx(q, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueEx\n"); ok(n1 == 1, "ChangeTimerQueueTimer\n"); ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n"); @@ -1092,15 +1096,14 @@ static void test_timer_queue(void) ok(d4.num_calls == 1, "Timer flagged for deletion incorrectly\n"); /* Test an obscure bug that was in the original implementation. */ - q = pCreateTimerQueue(); + q = CreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); /* All the work is done in the callback. */ d1.t = t1 = NULL; d1.num_calls = 0; d1.q = q; - ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100, - 100, WT_EXECUTELONGFUNCTION); + ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb6, &d1, 100, 100, WT_EXECUTELONGFUNCTION); d1.t = t1; ok(ret, "CreateTimerQueueTimer\n"); ok(t1 != NULL, "CreateTimerQueueTimer\n"); @@ -1108,7 +1111,7 @@ static void test_timer_queue(void) Sleep(750); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueEx(q, NULL); + ret = DeleteTimerQueueEx(q, NULL); ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n", GetLastError()); @@ -1117,57 +1120,54 @@ static void test_timer_queue(void) /* Test functions on the default timer queue. */ t1 = NULL; n1 = 0; - ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000, - 1000, 0); + ret = CreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000, 1000, 0); ok(ret, "CreateTimerQueueTimer, default queue\n"); ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n"); - ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000); + ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000); ok(ret, "ChangeTimerQueueTimer, default queue\n"); - ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueTimer, default queue\n"); /* Try mixing default and non-default queues. Apparently this works. */ - q = pCreateTimerQueue(); + q = CreateTimerQueue(); ok(q != NULL, "CreateTimerQueue\n"); t1 = NULL; n1 = 0; - ret = pCreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000, - 1000, 0); + ret = CreateTimerQueueTimer(&t1, q, timer_queue_cb1, &n1, 1000, 1000, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t1 != NULL, "CreateTimerQueueTimer\n"); t2 = NULL; n2 = 0; - ret = pCreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000, - 1000, 0); + ret = CreateTimerQueueTimer(&t2, NULL, timer_queue_cb1, &n2, 1000, 1000, 0); ok(ret, "CreateTimerQueueTimer\n"); ok(t2 != NULL, "CreateTimerQueueTimer\n"); - ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000); + ret = ChangeTimerQueueTimer(NULL, t1, 2000, 2000); ok(ret, "ChangeTimerQueueTimer\n"); - ret = pChangeTimerQueueTimer(q, t2, 2000, 2000); + ret = ChangeTimerQueueTimer(q, t2, 2000, 2000); ok(ret, "ChangeTimerQueueTimer\n"); - ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueTimer\n"); - ret = pDeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE); + ret = DeleteTimerQueueTimer(q, t2, INVALID_HANDLE_VALUE); ok(ret, "DeleteTimerQueueTimer\n"); /* Try to delete the default queue? In any case: not allowed. */ SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueEx(NULL, NULL); + ret = DeleteTimerQueueEx(NULL, NULL); ok(!ret, "DeleteTimerQueueEx call was expected to fail\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, "DeleteTimerQueueEx, GetLastError: expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pDeleteTimerQueueEx(q, NULL); + ret = DeleteTimerQueueEx(q, NULL); ok(ret /* vista */ || GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx, GetLastError: expected ERROR_IO_PENDING, got %d\n", GetLastError()); @@ -2645,15 +2645,6 @@ START_TEST(sync) HMODULE hdll = GetModuleHandleA("kernel32.dll"); HMODULE hntdll = GetModuleHandleA("ntdll.dll"); - pChangeTimerQueueTimer = (void*)GetProcAddress(hdll, "ChangeTimerQueueTimer"); - pCreateTimerQueue = (void*)GetProcAddress(hdll, "CreateTimerQueue"); - pCreateTimerQueueTimer = (void*)GetProcAddress(hdll, "CreateTimerQueueTimer"); - pCreateWaitableTimerA = (void*)GetProcAddress(hdll, "CreateWaitableTimerA"); - pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx"); - pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer"); - pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA"); - pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification"); - pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification"); pInitOnceInitialize = (void *)GetProcAddress(hdll, "InitOnceInitialize"); pInitOnceExecuteOnce = (void *)GetProcAddress(hdll, "InitOnceExecuteOnce"); pInitOnceBeginInitialize = (void *)GetProcAddress(hdll, "InitOnceBeginInitialize"); diff --git a/modules/rostests/winetests/kernel32/testlist.c b/modules/rostests/winetests/kernel32/testlist.c index 8e47dcc2bd9..769baa6b241 100755 --- a/modules/rostests/winetests/kernel32/testlist.c +++ b/modules/rostests/winetests/kernel32/testlist.c @@ -9,7 +9,6 @@ extern void func_change(void); extern void func_codepage(void); extern void func_comm(void); extern void func_console(void); -extern void func_cpu(void); extern void func_debugger(void); extern void func_directory(void); extern void func_drive(void); diff --git a/modules/rostests/winetests/kernel32/thread.c b/modules/rostests/winetests/kernel32/thread.c index 9e9e968c463..b0bee53b1c5 100755 --- a/modules/rostests/winetests/kernel32/thread.c +++ b/modules/rostests/winetests/kernel32/thread.c @@ -18,7 +18,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +/* Define _WIN32_WINNT to get SetThreadIdealProcessor on Windows */ +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0600 +#endif + +#include +#include +#include + +/* the tests intentionally pass invalid pointers and need an exception handler */ +#define WINE_NO_INLINE_STRING + +#include +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include +#include "wine/test.h" /* THREAD_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ #define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff) @@ -1380,10 +1400,12 @@ static DWORD WINAPI LS_ThreadProc(LPVOID p) ok(LS_index0 != LS_index1, "%s failed\n", LS_AllocFuncName); /* Both slots should be initialized to NULL */ + SetLastError(0xdeadbeef); val = LS_GetValueFunc(LS_index0); ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName); ok(val == NULL, "Slot not initialized correctly\n"); + SetLastError(0xdeadbeef); val = LS_GetValueFunc(LS_index1); ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName); ok(val == NULL, "Slot not initialized correctly\n"); @@ -1392,10 +1414,12 @@ static DWORD WINAPI LS_ThreadProc(LPVOID p) if (sync_threads_and_run_one(0, id)) { + SetLastError(0xdeadbeef); val = LS_GetValueFunc(LS_index0); ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName); ok(val == NULL, "Slot not initialized correctly\n"); + SetLastError(0xdeadbeef); val = LS_GetValueFunc(LS_index1); ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName); ok(val == NULL, "Slot not initialized correctly\n"); @@ -1406,10 +1430,12 @@ static DWORD WINAPI LS_ThreadProc(LPVOID p) ret = LS_SetValueFunc(LS_index1, (LPVOID) 2); ok(ret, "%s failed\n", LS_SetValueFuncName); + SetLastError(0xdeadbeef); val = LS_GetValueFunc(LS_index0); ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName); ok(val == (LPVOID) 1, "Slot not initialized correctly\n"); + SetLastError(0xdeadbeef); val = LS_GetValueFunc(LS_index1); ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName); ok(val == (LPVOID) 2, "Slot not initialized correctly\n"); @@ -1702,6 +1728,7 @@ static WORD get_thread_fpu_cw(void) res = CloseHandle(ctx.finished); ok(!!res, "Failed to close event handle, last error %#x.\n", GetLastError()); + CloseHandle(thread); return ctx.cw; } diff --git a/modules/rostests/winetests/kernel32/time.c b/modules/rostests/winetests/kernel32/time.c index e37434fc4cd..e6e779c703c 100755 --- a/modules/rostests/winetests/kernel32/time.c +++ b/modules/rostests/winetests/kernel32/time.c @@ -19,7 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include "wine/test.h" +#include "winbase.h" +#include "winnls.h" +#include "winternl.h" static BOOL (WINAPI *pTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); static BOOL (WINAPI *pSystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); diff --git a/modules/rostests/winetests/kernel32/timer.c b/modules/rostests/winetests/kernel32/timer.c index b8d0892ff89..be4c9e9f2df 100755 --- a/modules/rostests/winetests/kernel32/timer.c +++ b/modules/rostests/winetests/kernel32/timer.c @@ -18,7 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0501 +#endif + +#include "wine/test.h" +#include "winbase.h" + static void test_timer(void) { diff --git a/modules/rostests/winetests/kernel32/toolhelp.c b/modules/rostests/winetests/kernel32/toolhelp.c index b90c3caa6b6..c40dbc4f8fe 100644 --- a/modules/rostests/winetests/kernel32/toolhelp.c +++ b/modules/rostests/winetests/kernel32/toolhelp.c @@ -18,7 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "tlhelp32.h" +#include "wine/test.h" +#include "winuser.h" static char selfname[MAX_PATH]; diff --git a/modules/rostests/winetests/kernel32/version.c b/modules/rostests/winetests/kernel32/version.c index 8891c9d14bc..39f869b993d 100644 --- a/modules/rostests/winetests/kernel32/version.c +++ b/modules/rostests/winetests/kernel32/version.c @@ -18,11 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +/* Needed for PRODUCT_* defines and GetProductInfo() */ +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0600 +#endif + +#include "wine/test.h" +#include "winbase.h" +#include "winternl.h" static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *); -static BOOL (WINAPI * pVerifyVersionInfoA)(LPOSVERSIONINFOEXA, DWORD, DWORDLONG); -static ULONGLONG (WINAPI * pVerSetConditionMask)(ULONGLONG, DWORD, BYTE); static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *); #define GET_PROC(func) \ @@ -35,8 +40,6 @@ static void init_function_pointers(void) hmod = GetModuleHandleA("kernel32.dll"); GET_PROC(GetProductInfo); - GET_PROC(VerifyVersionInfoA); - GET_PROC(VerSetConditionMask); hmod = GetModuleHandleA("ntdll.dll"); @@ -82,7 +85,7 @@ static void test_GetProductInfo(void) res = pGetProductInfo(entry[0], entry[1], entry[2], entry[3], &product); if (entry[0] >= 6) - ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_PROFESSIONAL_WMC), + ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_ENTERPRISE_S_N_EVALUATION), "got %d and 0x%x (expected TRUE and a valid PRODUCT_* value)\n", res, product); else ok(!res && !product && (GetLastError() == 0xdeadbeef), @@ -148,9 +151,7 @@ static void test_GetVersionEx(void) SetLastError(0xdeadbeef); infoExA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); ret = GetVersionExA((OSVERSIONINFOA *)&infoExA); - ok(ret || - broken(ret == 0), /* win95 */ - "Expected GetVersionExA to succeed\n"); + ok(ret, "GetVersionExA failed.\n"); if (!infoExA.wServicePackMajor && !infoExA.wServicePackMinor) ok(!infoExA.szCSDVersion[0], "got '%s'\n", infoExA.szCSDVersion); @@ -158,537 +159,544 @@ static void test_GetVersionEx(void) static void test_VerifyVersionInfo(void) { - OSVERSIONINFOEXA info; - BOOL ret; - DWORD servicepack, error; - - if(!pVerifyVersionInfoA || !pVerSetConditionMask) + enum srcversion_mode { - win_skip("Needed functions not available\n"); - return; - } - - /* Before we start doing some tests we should check what the version of - * the ServicePack is. Tests on a box with no ServicePack will fail otherwise. - */ - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - servicepack = info.wServicePackMajor; - - /* Win8.1+ returns Win8 version in GetVersionEx when there's no app manifest targeting 8.1 */ - if (info.dwMajorVersion == 6 && info.dwMinorVersion == 2) + SRCVERSION_ZERO = 0, + SRCVERSION_CURRENT = 1, + SRCVERSION_INC_MINOR = 2, + SRCVERSION_INC_SP_MINOR = 3, + SRCVERSION_INC_SP_MAJOR = 4, + SRCVERSION_DEC_SP_MAJOR = 5, + SRCVERSION_DEC_MAJOR = 6, + SRCVERSION_INC_BUILD = 7, + SRCVERSION_REQUIRES_SP = 0x1000, + }; + + struct verify_version_test { - RTL_OSVERSIONINFOEXW rtlinfo; - rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); - ok(SUCCEEDED(pRtlGetVersion(&rtlinfo)), "RtlGetVersion failed\n"); + DWORD verifymask; /* Type mask for VerifyVersionInfo() */ + DWORD srcinfo; /* The way current version info is modified. */ + DWORD err; /* Error code on failure, 0 on success. */ + + DWORD typemask1; + DWORD condition1; + DWORD typemask2; + DWORD condition2; + DWORD typemask3; + DWORD condition3; + DWORD typemask4; + DWORD condition4; + + BOOL todo; + } verify_version_tests[] = + { + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + 0, - if (rtlinfo.dwMajorVersion != 6 || rtlinfo.dwMinorVersion != 2) + VER_MAJORVERSION, VER_EQUAL, + VER_MINORVERSION, VER_LESS, + }, { - win_skip("GetVersionEx and VerifyVersionInfo are faking values\n"); - return; - } - } + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + ERROR_OLD_WIN_VERSION, - memset(&info, 0, sizeof(info)); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_CURRENT, + 0, - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION, - pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_CURRENT, + 0, - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_BUILDNUMBER | VER_MAJORVERSION | - VER_MINORVERSION/* | VER_PLATFORMID | VER_SERVICEPACKMAJOR | - VER_SERVICEPACKMINOR | VER_SUITENAME | VER_PRODUCT_TYPE */, - pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - /* tests special handling of VER_SUITENAME */ - - ret = pVerifyVersionInfoA(&info, VER_SUITENAME, - pVerSetConditionMask(0, VER_SUITENAME, VER_AND)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_AND, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + 0, - ret = pVerifyVersionInfoA(&info, VER_SUITENAME, - pVerSetConditionMask(0, VER_SUITENAME, VER_OR)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_LESS_EQUAL, + VER_MINORVERSION, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + ERROR_OLD_WIN_VERSION, - /* test handling of version numbers */ - - /* v3.10 is always less than v4.x even - * if the minor version is tested */ - info.dwMajorVersion = 3; - info.dwMinorVersion = 10; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL), - VER_MAJORVERSION, VER_GREATER_EQUAL)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_AND, + VER_MINORVERSION, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + ERROR_OLD_WIN_VERSION, - info.dwMinorVersion = 0; - info.wServicePackMajor = 10; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL), - VER_MAJORVERSION, VER_GREATER_EQUAL)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_OR, + VER_MINORVERSION, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + ERROR_OLD_WIN_VERSION, - info.wServicePackMajor = 0; - info.wServicePackMinor = 10; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL), - VER_MAJORVERSION, VER_GREATER_EQUAL)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some wink2 */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MAJORVERSION, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - if (servicepack == 0) - { - skip("There is no ServicePack on this system\n"); - } - else - { - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_EQUAL, + }, + { + VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - } + VER_SERVICEPACKMAJOR, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_SERVICEPACKMAJOR, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + 0, + + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + ERROR_OLD_WIN_VERSION, + + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + 0, + + VER_MAJORVERSION, VER_EQUAL, + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + ERROR_OLD_WIN_VERSION, + + VER_MAJORVERSION, VER_EQUAL, + VER_MINORVERSION, VER_GREATER_EQUAL, + VER_SERVICEPACKMAJOR, VER_EQUAL, + VER_SERVICEPACKMINOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS_EQUAL)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_LESS_EQUAL, + VER_SERVICEPACKMAJOR, VER_GREATER, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MAJORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - /* test the failure hierarchy for the four version fields */ + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MAJORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMinorVersion++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MAJORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + 0, + + VER_MAJORVERSION, VER_EQUAL, + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMajorVersion++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_MAJOR, + 0, - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_CURRENT, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwBuildNumber++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, + + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, + + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_GREATER_EQUAL, + VER_SERVICEPACKMAJOR, VER_LESS_EQUAL, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_SERVICEPACKMAJOR, VER_AND, + }, + { + VER_MAJORVERSION | VER_MINORVERSION, + SRCVERSION_ZERO, + 0, - /* systematically test behaviour of condition mask (tests sorted by condition mask value) */ + VER_MAJORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, + SRCVERSION_ZERO, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMinorVersion++; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_MINORVERSION, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_GREATER_EQUAL, + }, + { + VER_SUITENAME, + SRCVERSION_ZERO, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMinorVersion++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_SUITENAME, VER_AND, + }, + { + VER_SUITENAME, + SRCVERSION_ZERO, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_SUITENAME, VER_OR, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MINOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_AND)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMinorVersion++; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_LESS_EQUAL), VER_MINORVERSION, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MINORVERSION, VER_LESS, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMinorVersion++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_AND), VER_MINORVERSION, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MINORVERSION, VER_LESS_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMinorVersion++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_OR), VER_MINORVERSION, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MINORVERSION, VER_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_SP_MAJOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_MINOR, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - if (servicepack) - { - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMajorVersion++; - info.wServicePackMajor--; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_LESS), VER_SERVICEPACKMAJOR, VER_EQUAL)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - } + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_CURRENT, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - ret = pVerifyVersionInfoA(&info, VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_SERVICEPACKMAJOR, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_BUILD, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_SERVICEPACKMAJOR, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_INC_BUILD, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL), - VER_SERVICEPACKMAJOR, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL), - VER_SERVICEPACKMAJOR, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + VER_MINORVERSION, VER_GREATER, + }, + { + VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + 0, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), - VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MINORVERSION, VER_GREATER_EQUAL, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMinor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_EQUAL), VER_SERVICEPACKMINOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - if (servicepack) - { - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_MAJORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_GREATER, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + 0, + + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_EQUAL, + VER_SERVICEPACKMAJOR, VER_GREATER, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + 0, + + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_LESS_EQUAL, + VER_SERVICEPACKMAJOR, VER_GREATER, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + 0, + + VER_MAJORVERSION, VER_GREATER_EQUAL, + VER_MINORVERSION, VER_AND, + VER_SERVICEPACKMAJOR, VER_GREATER, + }, + { + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + SRCVERSION_DEC_SP_MAJOR | SRCVERSION_REQUIRES_SP, + ERROR_OLD_WIN_VERSION, - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_LESS_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + VER_SERVICEPACKMAJOR, VER_GREATER, + VER_SERVICEPACKMINOR, VER_EQUAL, + }, + }; - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_AND), VER_SERVICEPACKMAJOR, VER_GREATER)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - } + OSVERSIONINFOEXA info; + DWORD servicepack; + unsigned int i; + BOOL ret; + /* Before we start doing some tests we should check what the version of + * the ServicePack is. Tests on a box with no ServicePack will fail otherwise. + */ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_LESS_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + servicepack = info.wServicePackMajor; + if (servicepack == 0) + skip("There is no ServicePack on this system. Some tests will be skipped.\n"); - if (servicepack) + /* Win8.1+ returns Win8 version in GetVersionEx when there's no app manifest targeting 8.1 */ + if (info.dwMajorVersion == 6 && info.dwMinorVersion == 2) { - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor--; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_SERVICEPACKMAJOR, VER_GREATER), VER_SERVICEPACKMINOR, VER_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + RTL_OSVERSIONINFOEXW rtlinfo; + rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); + ok(!pRtlGetVersion(&rtlinfo), "RtlGetVersion failed\n"); + + if (rtlinfo.dwMajorVersion != 6 || rtlinfo.dwMinorVersion != 2) + { + win_skip("GetVersionEx and VerifyVersionInfo are faking values\n"); + return; + } } - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + for (i = 0; i < sizeof(verify_version_tests)/sizeof(verify_version_tests[0]); i++) + { + struct verify_version_test *test = &verify_version_tests[i]; + DWORD srcinfo = test->srcinfo; + ULONGLONG mask; - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + if (servicepack == 0 && srcinfo & SRCVERSION_REQUIRES_SP) + continue; + srcinfo &= ~SRCVERSION_REQUIRES_SP; - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + info.dwOSVersionInfoSize = sizeof(info); + GetVersionExA((OSVERSIONINFOA *)&info); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + switch (srcinfo) + { + case SRCVERSION_ZERO: + memset(&info, 0, sizeof(info)); + break; + case SRCVERSION_INC_MINOR: + info.dwMinorVersion++; + break; + case SRCVERSION_INC_SP_MINOR: + info.wServicePackMinor++; + break; + case SRCVERSION_INC_SP_MAJOR: + info.wServicePackMajor++; + break; + case SRCVERSION_DEC_SP_MAJOR: + info.wServicePackMajor--; + break; + case SRCVERSION_DEC_MAJOR: + info.dwMajorVersion--; + break; + case SRCVERSION_INC_BUILD: + info.dwBuildNumber++; + break; + default: + ; + } - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), - VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + mask = VerSetConditionMask(0, test->typemask1, test->condition1); + if (test->typemask2) + mask = VerSetConditionMask(mask, test->typemask2, test->condition2); + if (test->typemask3) + mask = VerSetConditionMask(mask, test->typemask3, test->condition3); + if (test->typemask4) + mask = VerSetConditionMask(mask, test->typemask4, test->condition4); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); + SetLastError(0xdeadbeef); + ret = VerifyVersionInfoA(&info, test->verifymask, mask); + todo_wine_if(test->todo) + { + ok(test->err ? !ret : ret, "%u: unexpected return value %d.\n", i, ret); + if (!ret) + ok(GetLastError() == test->err, "%u: unexpected error code %d, expected %d.\n", i, GetLastError(), test->err); + } + } - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.dwMajorVersion--; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); + /* test handling of version numbers */ + /* v3.10 is always less than v4.x even + * if the minor version is tested */ + info.dwMajorVersion = 3; + info.dwMinorVersion = 10; + ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL), + VER_MAJORVERSION, VER_GREATER_EQUAL)); ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); + info.dwMinorVersion = 0; + info.wServicePackMajor = 10; + ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL), + VER_MAJORVERSION, VER_GREATER_EQUAL)); ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - info.wServicePackMajor++; - SetLastError(0xdeadbeef); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_LESS_EQUAL)); - error = GetLastError(); - ok(!ret, "VerifyVersionInfoA succeeded\n"); - ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */, - "VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error); - - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((OSVERSIONINFOA *)&info); - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_AND)); + info.wServicePackMajor = 0; + info.wServicePackMinor = 10; + ret = VerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL), + VER_MAJORVERSION, VER_GREATER_EQUAL)); ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); /* test bad dwOSVersionInfoSize */ info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); GetVersionExA((OSVERSIONINFOA *)&info); info.dwOSVersionInfoSize = 0; - ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL)); - ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError()); + ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL)); + ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); } START_TEST(version) diff --git a/modules/rostests/winetests/kernel32/volume.c b/modules/rostests/winetests/kernel32/volume.c index f0a0d3be05f..a7be321a04a 100644 --- a/modules/rostests/winetests/kernel32/volume.c +++ b/modules/rostests/winetests/kernel32/volume.c @@ -18,9 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - -#include +#include "wine/test.h" +#include "winbase.h" +#include "winioctl.h" +#include +#include "wine/ddk/ntddcdvd.h" #include struct COMPLETE_DVD_LAYER_DESCRIPTOR @@ -258,7 +260,7 @@ static void test_GetVolumeNameForVolumeMountPointW(void) } ret = pGetVolumeNameForVolumeMountPointW(path, volume, 0); - ok(ret == FALSE, "GetVolumeNameForVolumeMountPointA succeeded\n"); + ok(ret == FALSE, "GetVolumeNameForVolumeMountPointW succeeded\n"); ok(GetLastError() == ERROR_FILENAME_EXCED_RANGE || GetLastError() == ERROR_INVALID_PARAMETER, /* Vista */ "wrong error, last=%d\n", GetLastError()); -- 2.17.1