Author: tfaber Date: Wed Jul 13 20:08:05 2011 New Revision: 52673
URL: http://svn.reactos.org/svn/reactos?rev=52673&view=rev Log: [KMTESTS/EX] - add a test for hard-error handling - add test for interlocked functions (part 1)
Added: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExHardError.c (with props) branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExInterlocked.c (with props) Modified: branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c
Modified: branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/CM... ============================================================================== --- branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt [iso-8859-1] (original) +++ branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt [iso-8859-1] Wed Jul 13 20:08:05 2011 @@ -14,6 +14,8 @@ kmtest_drv/testlist.c
example/Example.c + ntos_ex/ExHardError.c + ntos_ex/ExInterlocked.c ntos_ex/ExPools.c ntos_ex/ExResource.c ntos_ex/ExTimer.c
Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/km... ============================================================================== --- branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild [iso-8859-1] (original) +++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild [iso-8859-1] Wed Jul 13 20:08:05 2011 @@ -13,6 +13,8 @@ <file>Example.c</file> </directory> <directory name="ntos_ex"> + <file>ExHardError.c</file> + <file>ExInterlocked.c</file> <file>ExPools.c</file> <file>ExResource.c</file> <file>ExTimer.c</file>
Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/km... ============================================================================== --- branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c [iso-8859-1] (original) +++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c [iso-8859-1] Wed Jul 13 20:08:05 2011 @@ -9,6 +9,9 @@ #include <kmt_test.h>
KMT_TESTFUNC Test_Example; +KMT_TESTFUNC Test_ExHardError; +KMT_TESTFUNC Test_ExHardErrorInteractive; +KMT_TESTFUNC Test_ExInterlocked; KMT_TESTFUNC Test_ExPools; KMT_TESTFUNC Test_ExResource; KMT_TESTFUNC Test_ExTimer; @@ -25,6 +28,9 @@ const KMT_TEST TestList[] = { { "Example", Test_Example }, + { "ExHardError", Test_ExHardError }, + { "-ExHardErrorInteractive", Test_ExHardErrorInteractive }, + { "ExInterlocked", Test_ExInterlocked }, { "ExPools", Test_ExPools }, { "ExResource", Test_ExResource }, { "ExTimer", Test_ExTimer },
Added: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExHardError.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/nt... ============================================================================== --- branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExHardError.c (added) +++ branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExHardError.c [iso-8859-1] Wed Jul 13 20:08:05 2011 @@ -1,0 +1,253 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Kernel-Mode Test Suite Hard error message test + * PROGRAMMER: Thomas Faber thfabba@gmx.de + */ + +#include <ntddk.h> +#include <ntifs.h> +#include <ndk/exfuncs.h> +#include <pseh/pseh2.h> + +#include <kmt_test.h> + +/* TODO: don't require user interaction, test Io* routines, + * test NTSTATUS values with special handling */ + +/* TODO: this belongs in ndk/exfuncs.h?! */ +NTSTATUS +NTAPI +ExRaiseHardError(IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response); + +/* TODO: this belongs in HARDERROR_RESPONSE_OPTION in ndk/extypes.h */ +#define OptionBalloonNotification 7 +#define OptionCancelTryAgainContinue 8 + +static +VOID +SetParameters( + OUT PULONG_PTR Parameters, + IN INT Count, + ...) +{ + INT i; + va_list Arguments; + va_start(Arguments, Count); + for (i = 0; i < Count; ++i) + Parameters[i] = va_arg(Arguments, ULONG_PTR); + va_end(Arguments); +} + +#define NoResponse 27 + +#define CheckHardError(ErrStatus, UnicodeStringMask, ResponseOption, \ + ExpectedStatus, ExpectedResponse, \ + NumberOfParameters, ...) do \ +{ \ + SetParameters(HardErrorParameters, NumberOfParameters, __VA_ARGS__);\ + Response = NoResponse; \ + _SEH2_TRY { \ + Status = ExRaiseHardError(ErrStatus, \ + NumberOfParameters, \ + UnicodeStringMask, \ + HardErrorParameters, \ + ResponseOption, \ + &Response); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, ExpectedStatus); \ + ok_eq_ulong(Response, (ULONG)ExpectedResponse); \ +} while (0) + +#define CheckInformationalHardError(ErrStatus, String, Thread, \ + ExpectedStatus, ExpectedRet) do \ +{ \ + Status = STATUS_SUCCESS; \ + Ret = !ExpectedRet; \ + _SEH2_TRY { \ + Ret = IoRaiseInformationalHardError(ErrStatus, \ + String, \ + Thread); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, ExpectedStatus); \ + ok_eq_bool(Ret, ExpectedRet); \ +} while (0) + +static +VOID +TestHardError( + BOOLEAN InteractivePart1, + BOOLEAN InteractivePart2, + BOOLEAN InteractivePart3, + BOOLEAN InteractivePart4) +{ + NTSTATUS Status; + ULONG Response; + WCHAR StringBuffer1[] = L"Parameter1+Garbage"; + CHAR StringBuffer1Ansi[] = "Parameter1+Garbage"; + WCHAR StringBuffer2[] = L"Parameter2+Garbage"; + UNICODE_STRING String1 = RTL_CONSTANT_STRING(StringBuffer1); + ANSI_STRING String1Ansi = RTL_CONSTANT_STRING(StringBuffer1Ansi); + UNICODE_STRING String2 = RTL_CONSTANT_STRING(StringBuffer2); + ULONG_PTR HardErrorParameters[6]; + BOOLEAN Ret; + + String1.Length = sizeof L"Parameter1" - sizeof UNICODE_NULL; + String1Ansi.Length = sizeof "Parameter1" - sizeof ANSI_NULL; + String2.Length = sizeof L"Parameter2" - sizeof UNICODE_NULL; + + if (InteractivePart1) + { + CheckHardError(0x40000000, 0, OptionOk, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a box :| + CheckHardError(0x40000001, 0, OptionOk, STATUS_SUCCESS, ResponseOk, 4, 1, 2, 3, 4); // outputs a box :| + CheckHardError(0x40000002, 0, OptionOk, STATUS_SUCCESS, ResponseOk, 5, 1, 2, 3, 4, 5); // outputs a box :| + } + CheckHardError(0x40000003, 0, OptionOk, STATUS_SUCCESS, ResponseNotHandled, 6, 1, 2, 3, 4, 5, 6); + + CheckHardError(0x40000004, 0, OptionShutdownSystem, STATUS_PRIVILEGE_NOT_HELD, ResponseNotHandled, 0, 0); + CheckHardError(0x40000005, 0, OptionBalloonNotification, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a balloon notification + CheckHardError(0x4000000f, 0, OptionBalloonNotification, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a balloon notification + if (InteractivePart1) + { + CheckHardError(0x40000006, 0, OptionAbortRetryIgnore, STATUS_SUCCESS, ResponseAbort, 0, 0); // outputs a box :| + CheckHardError(0x40000006, 0, OptionAbortRetryIgnore, STATUS_SUCCESS, ResponseRetry, 0, 0); // outputs a box :| + CheckHardError(0x40000006, 0, OptionAbortRetryIgnore, STATUS_SUCCESS, ResponseIgnore, 0, 0); // outputs a box :| + CheckHardError(0x40000008, 0, OptionCancelTryAgainContinue, STATUS_SUCCESS, ResponseCancel, 0, 0); // outputs a box :| + CheckHardError(0x40000008, 0, OptionCancelTryAgainContinue, STATUS_SUCCESS, ResponseTryAgain, 0, 0); // outputs a box :| + CheckHardError(0x40000008, 0, OptionCancelTryAgainContinue, STATUS_SUCCESS, ResponseContinue, 0, 0); // outputs a box :| + CheckHardError(0x40000010, 0, OptionOkCancel, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a box :| + CheckHardError(0x40000010, 0, OptionOkCancel, STATUS_SUCCESS, ResponseCancel, 0, 0); // outputs a box :| + CheckHardError(0x40000011, 0, OptionRetryCancel, STATUS_SUCCESS, ResponseRetry, 0, 0); // outputs a box :| + CheckHardError(0x40000011, 0, OptionRetryCancel, STATUS_SUCCESS, ResponseCancel, 0, 0); // outputs a box :| + CheckHardError(0x40000012, 0, OptionYesNo, STATUS_SUCCESS, ResponseYes, 0, 0); // outputs a box :| + CheckHardError(0x40000012, 0, OptionYesNo, STATUS_SUCCESS, ResponseNo, 0, 0); // outputs a box :| + CheckHardError(0x40000013, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 0, 0); // outputs a box :| + CheckHardError(0x40000013, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 0, 0); // outputs a box :| + CheckHardError(0x40000013, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, 0); // outputs a box :| + } + CheckHardError(0x40000009, 0, 9, STATUS_SUCCESS, ResponseNotHandled, 0, 0); + CheckHardError(0x4000000a, 0, 10, STATUS_SUCCESS, ResponseNotHandled, 0, 0); + CheckHardError(0x4000000b, 0, 11, STATUS_SUCCESS, ResponseNotHandled, 0, 0); + CheckHardError(0x4000000c, 0, 12, STATUS_SUCCESS, ResponseNotHandled, 0, 0); + CheckHardError(0x4000000d, 0, MAXULONG / 2 + 1, STATUS_SUCCESS, ResponseNotHandled, 0, 0); + CheckHardError(0x4000000d, 0, MAXULONG, STATUS_SUCCESS, ResponseNotHandled, 0, 0); + + if (InteractivePart2) + { + /* try a message with one parameter */ + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 1, &String1); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, &String1); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, &String1); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, &String1); // outputs a box :| + /* give too many parameters */ + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 2, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 4, &String1, &String2, 0, 0); // outputs a box :| + /* try with stuff that's not a UNICODE_STRING */ + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 1, &String1Ansi); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 1, L"Parameter1"); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 1, "Parameter1"); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, 1234); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, &String1Ansi); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, L"Parameter1"); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, "Parameter1"); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, 1234); // outputs a box :| + CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, NULL); // outputs a box :| + } + if (InteractivePart3) + { + /* try a message with one parameter */ + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, &String1); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, &String1); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 0, &String1); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 0, &String1); // outputs a box :| + /* give too many parameters */ + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 2, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseOk, 3, &String1, &String2, 0); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseOk, 4, &String1, &String2, 0, 0); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 3, OptionBalloonNotification, STATUS_SUCCESS, ResponseOk, 4, &String1, &String2, 0, 0); // outputs a balloon notification + /* try with stuff that's not a UNICODE_STRING */ + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, &String1Ansi); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, L"Parameter1"); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, "Parameter1"); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, 1234); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, &String1Ansi); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, L"Parameter1"); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, "Parameter1"); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, 1234); // outputs a box :| + CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, NULL); // outputs a box :| + } + if (InteractivePart4) + { + /* try a message with one parameter */ + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 1, &String1); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, &String1); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, &String1); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, &String1); // outputs a box :| + /* give too many parameters */ + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 2, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 2, &String1, &String2); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 4, &String1, &String2, 0, 0); // outputs a box :| + /* try with stuff that's not a UNICODE_STRING */ + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 1, &String1Ansi); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 1, L"Parameter1"); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 1, "Parameter1"); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, 1234); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, &String1Ansi); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, L"Parameter1"); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, "Parameter1"); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, 1234); // outputs a box :| + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, NULL); // outputs a box :| + } + + CheckInformationalHardError(STATUS_WAIT_0, NULL, NULL, STATUS_SUCCESS, TRUE); // outputs a balloon notification + CheckInformationalHardError(STATUS_DLL_NOT_FOUND, &String1, NULL, STATUS_SUCCESS, TRUE); // outputs a balloon notification + CheckInformationalHardError(STATUS_DLL_NOT_FOUND, NULL, NULL, STATUS_SUCCESS, TRUE); // outputs a balloon notification + CheckInformationalHardError(STATUS_SERVICE_NOTIFICATION, &String1, NULL, STATUS_SUCCESS, FALSE); + + ok_bool_true(IoSetThreadHardErrorMode(TRUE), "IoSetThreadHardErrorMode returned"); + ok_bool_true(IoSetThreadHardErrorMode(FALSE), "IoSetThreadHardErrorMode returned"); + ok_bool_false(IoSetThreadHardErrorMode(FALSE), "IoSetThreadHardErrorMode returned"); + CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseReturnToCaller, 0, 0); + CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL); + CheckInformationalHardError(STATUS_WAIT_0, NULL, NULL, STATUS_SUCCESS, FALSE); + CheckInformationalHardError(STATUS_DLL_NOT_FOUND, &String1, NULL, STATUS_SUCCESS, FALSE); + CheckInformationalHardError(STATUS_DLL_NOT_FOUND, NULL, NULL, STATUS_SUCCESS, FALSE); + CheckInformationalHardError(STATUS_SERVICE_NOTIFICATION, &String1, NULL, STATUS_SUCCESS, FALSE); + ok_bool_false(IoSetThreadHardErrorMode(TRUE), "IoSetThreadHardErrorMode returned"); +} + +START_TEST(ExHardError) +{ + TestHardError(FALSE, FALSE, FALSE, FALSE); +} + +/* Here's how to do the interactive test: + * - First there will be a few messages random messages. If there's + * multiple options available, the same box will appear multiple times -- + * click the buttons in order from left to right + * - After that, you must verify the error parameters. You should always + * see Parameter1 or Parameter2 for strings, and 0x12345678 for numbers. + * if there's a message saying an exception occured during processing, + * click cancel. If there's a bad parameter (Parameter1+, Parameter1+Garbage + * or an empty string for example), click no. Otherwise click yes. */ +START_TEST(ExHardErrorInteractive) +{ + TestHardError(TRUE, TRUE, TRUE, TRUE); +}
Propchange: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExHardError.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExInterlocked.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/nt... ============================================================================== --- branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExInterlocked.c (added) +++ branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExInterlocked.c [iso-8859-1] Wed Jul 13 20:08:05 2011 @@ -1,0 +1,289 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Kernel-Mode Test Suite Interlocked function test + * PROGRAMMER: Thomas Faber thfabba@gmx.de + */ + +/* missing prototypes >:| */ +#ifndef _MSC_VER +typedef long long __int64; +#endif +struct _KSPIN_LOCK; +__declspec(dllimport) long __fastcall InterlockedCompareExchange(volatile long *, long, long); +__declspec(dllimport) __int64 __fastcall ExInterlockedCompareExchange64(volatile __int64 *, __int64 *, __int64 *, void *); +__declspec(dllimport) __int64 __fastcall ExfInterlockedCompareExchange64(volatile __int64 *, __int64 *, __int64 *); +__declspec(dllimport) long __fastcall InterlockedExchange(volatile long *, long); +__declspec(dllimport) unsigned long __stdcall ExInterlockedExchangeUlong(unsigned long *, unsigned long, void *); +__declspec(dllimport) long __fastcall InterlockedExchangeAdd(volatile long *, long); +__declspec(dllimport) unsigned long __stdcall ExInterlockedAddUlong(unsigned long *, unsigned long, void *); +__declspec(dllimport) unsigned long __stdcall Exi386InterlockedExchangeUlong(unsigned long *, unsigned long); +__declspec(dllimport) long __fastcall InterlockedIncrement(long *); +__declspec(dllimport) long __fastcall InterlockedDecrement(long *); +__declspec(dllimport) int __stdcall ExInterlockedIncrementLong(long *, void *); +__declspec(dllimport) int __stdcall ExInterlockedDecrementLong(long *, void *); +__declspec(dllimport) int __stdcall Exi386InterlockedIncrementLong(long *); +__declspec(dllimport) int __stdcall Exi386InterlockedDecrementLong(long *); + +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WS03SP1 +#include <ntddk.h> +#include <pseh/pseh2.h> + +#include <kmt_test.h> + +/* TODO: There are quite some changes needed for other architectures! + ExInterlockedAddLargeInteger, ExInterlockedAddUlong are the only two + functions actually exported by my win7/x64 kernel! */ + +/* TODO: stress-testing */ + +static KSPIN_LOCK SpinLock; + +static +LARGE_INTEGER +Large( + ULONGLONG Value) +{ + LARGE_INTEGER Ret; + Ret.QuadPart = Value; + return Ret; +} + +#define CheckInterlockedCmpXchg(Function, Type, Print, Val, Cmp, Xchg, \ + ExpectedValue, ExpectedRet, ...) do \ +{ \ + Type Ret##Type = 0; \ + Type Value##Type = Val; \ + Status = STATUS_SUCCESS; \ + _SEH2_TRY { \ + Ret##Type = Function(&Value##Type, Xchg, Cmp, ##__VA_ARGS__); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_print(Ret##Type, ExpectedRet, Print); \ + ok_eq_print(Value##Type, ExpectedValue, Print); \ +} while (0) + +#define CheckInterlockedCmpXchgI(Function, Type, Print, Val, Cmp, Xchg, \ + ExpectedValue, ExpectedRet, ...) do \ +{ \ + Type Ret##Type = 0; \ + Type Value##Type = Val; \ + Type Compare##Type = Cmp; \ + Type Exchange##Type = Xchg; \ + Status = STATUS_SUCCESS; \ + _SEH2_TRY { \ + Ret##Type = Function(&Value##Type, &Exchange##Type, \ + &Compare##Type, ##__VA_ARGS__); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_print(Ret##Type, ExpectedRet, Print); \ + ok_eq_print(Value##Type, ExpectedValue, Print); \ + ok_eq_print(Exchange##Type, Xchg, Print); \ + ok_eq_print(Compare##Type, Cmp, Print); \ +} while(0) + +#define CheckInterlockedOp(Function, Type, Print, Val, Op, \ + ExpectedValue, ExpectedRet, ...) do \ +{ \ + Type Ret##Type = 0; \ + Type Value##Type = Val; \ + Status = STATUS_SUCCESS; \ + _SEH2_TRY { \ + Ret##Type = Function(&Value##Type, Op, ##__VA_ARGS__); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_print(Ret##Type, ExpectedRet, Print); \ + ok_eq_print(Value##Type, ExpectedValue, Print); \ +} while (0) + +#define CheckInterlockedOpNoArg(Function, Type, Print, Val, \ + ExpectedValue, ExpectedRet, ...) do \ +{ \ + Type Ret##Type = 0; \ + Type Value##Type = Val; \ + Status = STATUS_SUCCESS; \ + _SEH2_TRY { \ + Ret##Type = Function(&Value##Type, ##__VA_ARGS__); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_print(Ret##Type, ExpectedRet, Print); \ + ok_eq_print(Value##Type, ExpectedValue, Print); \ +} while (0) + +#define CheckInterlockedOpLarge(Function, Type, Print, Val, Op, \ + ExpectedValue, ExpectedRet, ...) do \ +{ \ + Type Ret##Type = Large(0); \ + Type Value##Type = Val; \ + Status = STATUS_SUCCESS; \ + _SEH2_TRY { \ + Ret##Type = Function(&Value##Type, Op, ##__VA_ARGS__); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_print(Ret##Type.QuadPart, ExpectedRet, Print); \ + ok_eq_print(Value##Type.QuadPart, ExpectedValue, Print); \ +} while (0) + +#define CheckInterlockedOpLargeNoRet(Function, Type, Print, Val, Op, \ + ExpectedValue, ...) do \ +{ \ + Type Value##Type = Val; \ + Status = STATUS_SUCCESS; \ + _SEH2_TRY { \ + Function(&Value##Type, Op, ##__VA_ARGS__); \ + } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { \ + Status = _SEH2_GetExceptionCode(); \ + } _SEH2_END; \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_print(Value##Type.QuadPart, ExpectedValue, Print); \ +} while (0) + +/* TODO: missing in wdm.h! */ +#define InterlockedCompareExchangeAcquire InterlockedCompareExchange +#define InterlockedCompareExchangeRelease InterlockedCompareExchange +#define InterlockedIncrementAcquire InterlockedIncrement +#define InterlockedIncrementRelease InterlockedIncrement +#define InterlockedDecrementAcquire InterlockedDecrement +#define InterlockedDecrementRelease InterlockedDecrement + +static +VOID +TestInterlockedFunctional(VOID) +{ + NTSTATUS Status; + PKSPIN_LOCK pSpinLock = &SpinLock; + + /* on x86, most of these are supported intrinsicly and don't need a spinlock! */ +#if defined _M_IX86 || defined _M_AMD64 + pSpinLock = NULL; +#endif + + /* CompareExchange */ + /* macro version */ + CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 6, 8, 5L, 5L); + CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 5, 9, 9L, 5L); + /* exported function */ +#undef InterlockedCompareExchange + CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 6, 8, 5L, 5L); + CheckInterlockedCmpXchg(InterlockedCompareExchange, LONG, "%ld", 5, 5, 9, 9L, 5L); + /* these only exist as macros on x86 */ + CheckInterlockedCmpXchg(InterlockedCompareExchangeAcquire, LONG, "%ld", 16, 9, 12, 16L, 16L); + CheckInterlockedCmpXchg(InterlockedCompareExchangeAcquire, LONG, "%ld", 16, 16, 4, 4L, 16L); + CheckInterlockedCmpXchg(InterlockedCompareExchangeRelease, LONG, "%ld", 27, 123, 38, 27L, 27L); + CheckInterlockedCmpXchg(InterlockedCompareExchangeRelease, LONG, "%ld", 27, 27, 39, 39L, 27L); + /* only exists as a macro */ + CheckInterlockedCmpXchg(InterlockedCompareExchangePointer, PVOID, "%p", (PVOID)117, (PVOID)711, (PVOID)12, (PVOID)117, (PVOID)117); + CheckInterlockedCmpXchg(InterlockedCompareExchangePointer, PVOID, "%p", (PVOID)117, (PVOID)117, (PVOID)228, (PVOID)228, (PVOID)117); + /* macro version */ + CheckInterlockedCmpXchgI(ExInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL, pSpinLock); + CheckInterlockedCmpXchgI(ExInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL, pSpinLock); + /* exported function */ + CheckInterlockedCmpXchgI((ExInterlockedCompareExchange64), LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL, pSpinLock); + CheckInterlockedCmpXchgI((ExInterlockedCompareExchange64), LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL, pSpinLock); + /* fastcall version */ + CheckInterlockedCmpXchgI(ExfInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 4LL, 20LL, 17LL, 17LL); + CheckInterlockedCmpXchgI(ExfInterlockedCompareExchange64, LONGLONG, "%I64d", 17, 17LL, 21LL, 21LL, 17LL); + + /* Exchange */ + CheckInterlockedOp(InterlockedExchange, LONG, "%ld", 5, 8, 8L, 5L); +#undef InterlockedExchange + CheckInterlockedOp(InterlockedExchange, LONG, "%ld", 5, 8, 8L, 5L); + CheckInterlockedOp(InterlockedExchangePointer, PVOID, "%p", (PVOID)700, (PVOID)93, (PVOID)93, (PVOID)700); + CheckInterlockedOp(ExInterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU, pSpinLock); + CheckInterlockedOp((ExInterlockedExchangeUlong), ULONG, "%lu", 212, 121, 121LU, 212LU, pSpinLock); +#ifdef _M_IX86 + CheckInterlockedOp(Exi386InterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU); + CheckInterlockedOp(Exfi386InterlockedExchangeUlong, ULONG, "%lu", 212, 121, 121LU, 212LU); +#endif + + /* ExchangeAdd */ + /* TODO: ExInterlockedExchangeAddLargeInteger? */ + CheckInterlockedOp(InterlockedExchangeAdd, LONG, "%ld", 312, 7, 319L, 312L); +#undef InterlockedExchangeAdd + CheckInterlockedOp(InterlockedExchangeAdd, LONG, "%ld", 312, 7, 319L, 312L); + + /* Add */ + /* these DO need a valid spinlock even on x86 */ + CheckInterlockedOpLarge(ExInterlockedAddLargeInteger, LARGE_INTEGER, "%I64d", Large(23), Large(7), 30LL, 23LL, &SpinLock); + CheckInterlockedOpLargeNoRet(ExInterlockedAddLargeStatistic, LARGE_INTEGER, "%I64d", Large(15), 17LL, 32LL); + CheckInterlockedOp(ExInterlockedAddUlong, ULONG, "%lu", 239, 44, 283LU, 239LU, &SpinLock); +#undef ExInterlockedAddUlong + CheckInterlockedOp(ExInterlockedAddUlong, ULONG, "%lu", 239, 44, 283LU, 239LU, &SpinLock); + + /* Increment */ + CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", 2341L, 2342L, 2342L); + CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)MINLONG); +#undef InterlockedIncrement + CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", 2341L, 2342L, 2342L); + CheckInterlockedOpNoArg(InterlockedIncrement, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)MINLONG); + CheckInterlockedOpNoArg(InterlockedIncrementAcquire, LONG, "%ld", 2341L, 2342L, 2342L); + CheckInterlockedOpNoArg(InterlockedIncrementRelease, LONG, "%ld", 2341L, 2342L, 2342L); + CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", -2L, -1L, (LONG)ResultNegative, pSpinLock); + CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", -1L, 0L, (LONG)ResultZero, pSpinLock); + CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", 0L, 1L, (LONG)ResultPositive, pSpinLock); + CheckInterlockedOpNoArg(ExInterlockedIncrementLong, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)ResultNegative, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", -2L, -1L, (LONG)ResultNegative, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", -1L, 0L, (LONG)ResultZero, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", 0L, 1L, (LONG)ResultPositive, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedIncrementLong), LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)ResultNegative, pSpinLock); +#ifdef _M_IX86 + CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", -2L, -1L, (LONG)ResultNegative); + CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", -1L, 0L, (LONG)ResultZero); + CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", 0L, 1L, (LONG)ResultPositive); + CheckInterlockedOpNoArg(Exi386InterlockedIncrementLong, LONG, "%ld", (LONG)MAXLONG, (LONG)MINLONG, (LONG)ResultNegative); +#endif + + /* Decrement */ + CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", 1745L, 1744L, 1744L); + CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)MAXLONG); +#undef InterlockedDecrement + CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", 1745L, 1744L, 1744L); + CheckInterlockedOpNoArg(InterlockedDecrement, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)MAXLONG); + CheckInterlockedOpNoArg(InterlockedDecrementAcquire, LONG, "%ld", 1745L, 1744L, 1744L); + CheckInterlockedOpNoArg(InterlockedDecrementRelease, LONG, "%ld", 1745L, 1744L, 1744L); + CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive, pSpinLock); + CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 0L, -1L, (LONG)ResultNegative, pSpinLock); + CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 1L, 0L, (LONG)ResultZero, pSpinLock); + CheckInterlockedOpNoArg(ExInterlockedDecrementLong, LONG, "%ld", 2L, 1L, (LONG)ResultPositive, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 0L, -1L, (LONG)ResultNegative, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 1L, 0L, (LONG)ResultZero, pSpinLock); + CheckInterlockedOpNoArg((ExInterlockedDecrementLong), LONG, "%ld", 2L, 1L, (LONG)ResultPositive, pSpinLock); +#ifdef _M_IX86 + CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", (LONG)MINLONG, (LONG)MAXLONG, (LONG)ResultPositive); + CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 0L, -1L, (LONG)ResultNegative); + CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 1L, 0L, (LONG)ResultZero); + CheckInterlockedOpNoArg(Exi386InterlockedDecrementLong, LONG, "%ld", 2L, 1L, (LONG)ResultPositive); +#endif + + /* And, Or, Xor */ + CheckInterlockedOp(InterlockedAnd, LONG, "0x%lx", 0x1234L, 0x1111L, 0x1010L, 0x1234L); + CheckInterlockedOp(InterlockedOr, LONG, "0x%lx", 0x1234L, 0x1111L, 0x1335L, 0x1234L); + CheckInterlockedOp(InterlockedXor, LONG, "0x%lx", 0x1234L, 0x1111L, 0x0325L, 0x1234L); +#ifdef _WIN64 + CheckInterlockedOp(InterlockedXor64, LONGLONG, "0x%I64x", 0x200001234LL, 0x100001111LL, 0x300000325LL, 0x200001234LL); +#endif +} + +START_TEST(ExInterlocked) +{ + KIRQL Irql; + KeInitializeSpinLock(&SpinLock); + + /* functional testing */ + TestInterlockedFunctional(); + KeRaiseIrql(HIGH_LEVEL, &Irql); + TestInterlockedFunctional(); + KeLowerIrql(Irql); +}
Propchange: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ex/ExInterlocked.c ------------------------------------------------------------------------------ svn:eol-style = native