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/CMakeLists.txt?rev=52673&r1=52672&r2=52673&view=diff
==============================================================================
--- 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/kmtest_drv.rbuild?rev=52673&r1=52672&r2=52673&view=diff
==============================================================================
--- 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/kmtest_drv/testlist.c?rev=52673&r1=52672&r2=52673&view=diff
==============================================================================
--- 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/ntos_ex/ExHardError.c?rev=52673&view=auto
==============================================================================
--- 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 <[email protected]>
+ */
+
+#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/ntos_ex/ExInterlocked.c?rev=52673&view=auto
==============================================================================
--- 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 <[email protected]>
+ */
+
+/* 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


Reply via email to