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/C…
==============================================================================
--- 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/k…
==============================================================================
--- 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/k…
==============================================================================
--- 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/n…
==============================================================================
--- 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(a)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/n…
==============================================================================
--- 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(a)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