mirror of
https://github.com/reactos/reactos.git
synced 2025-01-06 06:20:13 +00:00
[KMTESTS]
- add KeSpinLock test - KeIrql: also test the actual stdcall versions of KeRaiseIrql/KeLowerIrql - ExHardError: take advantage of r52847 svn path=/branches/GSoC_2011/KMTestSuite/; revision=52869
This commit is contained in:
parent
ca91b96107
commit
928b5489ef
5 changed files with 467 additions and 103 deletions
|
@ -28,6 +28,7 @@ list(APPEND KMTEST_DRV_SOURCE
|
||||||
ntos_ke/KeDpc.c
|
ntos_ke/KeDpc.c
|
||||||
ntos_ke/KeIrql.c
|
ntos_ke/KeIrql.c
|
||||||
ntos_ke/KeProcessor.c
|
ntos_ke/KeProcessor.c
|
||||||
|
ntos_ke/KeSpinLock.c
|
||||||
ntos_ob/ObCreate.c
|
ntos_ob/ObCreate.c
|
||||||
|
|
||||||
kmtest_drv/kmtest_drv.rc)
|
kmtest_drv/kmtest_drv.rc)
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<file>KeDpc.c</file>
|
<file>KeDpc.c</file>
|
||||||
<file>KeIrql.c</file>
|
<file>KeIrql.c</file>
|
||||||
<file>KeProcessor.c</file>
|
<file>KeProcessor.c</file>
|
||||||
|
<file>KeSpinLock.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="ntos_ob">
|
<directory name="ntos_ob">
|
||||||
<file>ObCreate.c</file>
|
<file>ObCreate.c</file>
|
||||||
|
|
|
@ -15,20 +15,6 @@
|
||||||
/* TODO: don't require user interaction, test Io* routines,
|
/* TODO: don't require user interaction, test Io* routines,
|
||||||
* test NTSTATUS values with special handling */
|
* 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
|
static
|
||||||
VOID
|
VOID
|
||||||
SetParameters(
|
SetParameters(
|
||||||
|
@ -107,125 +93,125 @@ TestHardError(
|
||||||
|
|
||||||
if (InteractivePart1)
|
if (InteractivePart1)
|
||||||
{
|
{
|
||||||
CheckHardError(0x40000000, 0, OptionOk, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a box :|
|
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(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(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(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(0x40000004, 0, OptionShutdownSystem, STATUS_PRIVILEGE_NOT_HELD, ResponseNotHandled, 0, 0);
|
||||||
CheckHardError(0x40000005, 0, OptionBalloonNotification, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a balloon notification
|
CheckHardError(0x40000005, 0, OptionOkNoWait, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a balloon notification
|
||||||
CheckHardError(0x4000000f, 0, OptionBalloonNotification, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a balloon notification
|
CheckHardError(0x4000000f, 0, OptionOkNoWait, STATUS_SUCCESS, ResponseOk, 0, 0); // outputs a balloon notification
|
||||||
if (InteractivePart1)
|
if (InteractivePart1)
|
||||||
{
|
{
|
||||||
CheckHardError(0x40000006, 0, OptionAbortRetryIgnore, STATUS_SUCCESS, ResponseAbort, 0, 0); // outputs a box :|
|
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, ResponseRetry, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000006, 0, OptionAbortRetryIgnore, STATUS_SUCCESS, ResponseIgnore, 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, OptionCancelTryContinue, STATUS_SUCCESS, ResponseCancel, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000008, 0, OptionCancelTryAgainContinue, STATUS_SUCCESS, ResponseTryAgain, 0, 0); // outputs a box :|
|
CheckHardError(0x40000008, 0, OptionCancelTryContinue, STATUS_SUCCESS, ResponseTryAgain, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000008, 0, OptionCancelTryAgainContinue, STATUS_SUCCESS, ResponseContinue, 0, 0); // outputs a box :|
|
CheckHardError(0x40000008, 0, OptionCancelTryContinue, 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, ResponseOk, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000010, 0, OptionOkCancel, STATUS_SUCCESS, ResponseCancel, 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, ResponseRetry, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000011, 0, OptionRetryCancel, STATUS_SUCCESS, ResponseCancel, 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, ResponseYes, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000012, 0, OptionYesNo, STATUS_SUCCESS, ResponseNo, 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, ResponseYes, 0, 0); // outputs a box :|
|
||||||
CheckHardError(0x40000013, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNo, 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(0x40000013, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, 0); // outputs a box :|
|
||||||
}
|
}
|
||||||
CheckHardError(0x40000009, 0, 9, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
CheckHardError(0x40000009, 0, 9, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
||||||
CheckHardError(0x4000000a, 0, 10, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
CheckHardError(0x4000000a, 0, 10, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
||||||
CheckHardError(0x4000000b, 0, 11, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
CheckHardError(0x4000000b, 0, 11, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
||||||
CheckHardError(0x4000000c, 0, 12, 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 / 2 + 1, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
||||||
CheckHardError(0x4000000d, 0, MAXULONG, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
CheckHardError(0x4000000d, 0, MAXULONG, STATUS_SUCCESS, ResponseNotHandled, 0, 0);
|
||||||
|
|
||||||
if (InteractivePart2)
|
if (InteractivePart2)
|
||||||
{
|
{
|
||||||
/* try a message with one parameter */
|
/* 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, 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, 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, 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 :|
|
CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, &String1); // outputs a box :|
|
||||||
/* give too many parameters */
|
/* 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, 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, 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, 2, &String1, &String2); // outputs a box :|
|
||||||
CheckHardError(STATUS_DLL_NOT_FOUND, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 4, &String1, &String2, 0, 0); // 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 */
|
/* 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, &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, 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_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, 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, 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, &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, 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, "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, 1234); // outputs a box :|
|
||||||
CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, NULL); // outputs a box :|
|
CheckHardError(STATUS_DLL_NOT_FOUND, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, NULL); // outputs a box :|
|
||||||
}
|
}
|
||||||
if (InteractivePart3)
|
if (InteractivePart3)
|
||||||
{
|
{
|
||||||
/* try a message with one parameter */
|
/* try a message with one parameter */
|
||||||
CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, &String1); // outputs a box :|
|
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, 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, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 0, &String1); // outputs a box :|
|
||||||
CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, 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 */
|
/* give too many parameters */
|
||||||
CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 2, &String1, &String2); // outputs a box :|
|
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, 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, 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, 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, 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
|
CheckHardError(STATUS_SERVICE_NOTIFICATION, 3, OptionOkNoWait, STATUS_SUCCESS, ResponseOk, 4, &String1, &String2, 0, 0); // outputs a balloon notification
|
||||||
/* try with stuff that's not a UNICODE_STRING */
|
/* 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, &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, 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_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, 1234); // outputs a box :|
|
||||||
CheckHardError(STATUS_SERVICE_NOTIFICATION, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL); // 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, &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, 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, "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, 1234); // outputs a box :|
|
||||||
CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, NULL); // outputs a box :|
|
CheckHardError(STATUS_SERVICE_NOTIFICATION, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseNotHandled, 1, NULL); // outputs a box :|
|
||||||
}
|
}
|
||||||
if (InteractivePart4)
|
if (InteractivePart4)
|
||||||
{
|
{
|
||||||
/* try a message with one parameter */
|
/* 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, 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, 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, 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 :|
|
CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 0, &String1); // outputs a box :|
|
||||||
/* give too many parameters */
|
/* 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, 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, 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, 2, &String1, &String2); // outputs a box :|
|
||||||
CheckHardError(STATUS_FATAL_APP_EXIT, 3, OptionYesNoCancel, STATUS_SUCCESS, ResponseYes, 4, &String1, &String2, 0, 0); // 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 */
|
/* 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, &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, 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_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, 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, 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, &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, 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, "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, 1234); // outputs a box :|
|
||||||
CheckHardError(STATUS_FATAL_APP_EXIT, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseCancel, 1, NULL); // 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_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, &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_DLL_NOT_FOUND, NULL, NULL, STATUS_SUCCESS, TRUE); // outputs a balloon notification
|
||||||
CheckInformationalHardError(STATUS_SERVICE_NOTIFICATION, &String1, NULL, STATUS_SUCCESS, FALSE);
|
CheckInformationalHardError(STATUS_SERVICE_NOTIFICATION, &String1, NULL, STATUS_SUCCESS, FALSE);
|
||||||
|
|
||||||
ok_bool_true(IoSetThreadHardErrorMode(TRUE), "IoSetThreadHardErrorMode returned");
|
ok_bool_true(IoSetThreadHardErrorMode(TRUE), "IoSetThreadHardErrorMode returned");
|
||||||
ok_bool_true(IoSetThreadHardErrorMode(FALSE), "IoSetThreadHardErrorMode returned");
|
ok_bool_true(IoSetThreadHardErrorMode(FALSE), "IoSetThreadHardErrorMode returned");
|
||||||
ok_bool_false(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, 0, OptionYesNoCancel, STATUS_SUCCESS, ResponseReturnToCaller, 0, 0);
|
||||||
CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL);
|
CheckHardError(STATUS_FATAL_APP_EXIT, 1, OptionYesNoCancel, STATUS_ACCESS_VIOLATION, NoResponse, 1, NULL);
|
||||||
CheckInformationalHardError(STATUS_WAIT_0, NULL, NULL, STATUS_SUCCESS, FALSE);
|
CheckInformationalHardError(STATUS_WAIT_0, NULL, NULL, STATUS_SUCCESS, FALSE);
|
||||||
CheckInformationalHardError(STATUS_DLL_NOT_FOUND, &String1, 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_DLL_NOT_FOUND, NULL, NULL, STATUS_SUCCESS, FALSE);
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
__declspec(dllimport) void __stdcall KeRaiseIrql(unsigned char, unsigned char *);
|
||||||
|
__declspec(dllimport) void __stdcall KeLowerIrql(unsigned char);
|
||||||
|
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#include <ntifs.h>
|
#include <ntifs.h>
|
||||||
#include <ndk/ntndk.h>
|
#include <ndk/ntndk.h>
|
||||||
|
@ -134,6 +137,14 @@ START_TEST(KeIrql)
|
||||||
KeLowerIrql(PASSIVE_LEVEL);
|
KeLowerIrql(PASSIVE_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* try the actual exports, not only the fastcall versions */
|
||||||
|
ok_irql(PASSIVE_LEVEL);
|
||||||
|
(KeRaiseIrql)(HIGH_LEVEL, &Irql);
|
||||||
|
ok_irql(HIGH_LEVEL);
|
||||||
|
ok_eq_uint(Irql, PASSIVE_LEVEL);
|
||||||
|
(KeLowerIrql)(Irql);
|
||||||
|
ok_irql(PASSIVE_LEVEL);
|
||||||
|
|
||||||
/* make sure we exit gracefully */
|
/* make sure we exit gracefully */
|
||||||
ok_irql(PASSIVE_LEVEL);
|
ok_irql(PASSIVE_LEVEL);
|
||||||
KeLowerIrql(PASSIVE_LEVEL);
|
KeLowerIrql(PASSIVE_LEVEL);
|
||||||
|
|
365
kmtests/ntos_ke/KeSpinLock.c
Normal file
365
kmtests/ntos_ke/KeSpinLock.c
Normal file
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS kernel-mode tests
|
||||||
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||||
|
* PURPOSE: Kernel-Mode Test Suite Spin lock test
|
||||||
|
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
__declspec(dllimport) void __stdcall KeAcquireSpinLock(unsigned long *, unsigned char *);
|
||||||
|
__declspec(dllimport) void __stdcall KeReleaseSpinLock(unsigned long *, unsigned char);
|
||||||
|
__declspec(dllimport) void __stdcall KeAcquireSpinLockAtDpcLevel(unsigned long *);
|
||||||
|
__declspec(dllimport) void __stdcall KeReleaseSpinLockFromDpcLevel(unsigned long *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this define makes KeInitializeSpinLock not use the inlined version */
|
||||||
|
#define WIN9X_COMPAT_SPINLOCK
|
||||||
|
#include <ntddk.h>
|
||||||
|
#include <ntifs.h>
|
||||||
|
#include <ndk/kefuncs.h>
|
||||||
|
#include <kmt_test.h>
|
||||||
|
#include <pseh/pseh2.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* TODO: these are documented for Vista+ */
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KeAcquireInStackQueuedSpinLockForDpc(
|
||||||
|
IN OUT PKSPIN_LOCK SpinLock,
|
||||||
|
OUT PKLOCK_QUEUE_HANDLE LockHandle);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KeReleaseInStackQueuedSpinLockForDpc(
|
||||||
|
IN PKLOCK_QUEUE_HANDLE LockHandle);
|
||||||
|
|
||||||
|
/* TODO: multiprocessor testing */
|
||||||
|
|
||||||
|
struct _CHECK_DATA;
|
||||||
|
typedef struct _CHECK_DATA CHECK_DATA, *PCHECK_DATA;
|
||||||
|
|
||||||
|
typedef VOID (*PACQUIRE_FUNCTION)(PKSPIN_LOCK, PCHECK_DATA);
|
||||||
|
typedef VOID (*PRELEASE_FUNCTION)(PKSPIN_LOCK, PCHECK_DATA);
|
||||||
|
typedef BOOLEAN (*PTRY_FUNCTION)(PKSPIN_LOCK, PCHECK_DATA);
|
||||||
|
|
||||||
|
struct _CHECK_DATA
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CheckQueueHandle,
|
||||||
|
CheckQueue,
|
||||||
|
CheckLock
|
||||||
|
} Check;
|
||||||
|
KIRQL IrqlWhenAcquired;
|
||||||
|
PACQUIRE_FUNCTION Acquire;
|
||||||
|
PRELEASE_FUNCTION Release;
|
||||||
|
PTRY_FUNCTION TryAcquire;
|
||||||
|
PACQUIRE_FUNCTION AcquireNoRaise;
|
||||||
|
PRELEASE_FUNCTION ReleaseNoLower;
|
||||||
|
PTRY_FUNCTION TryAcquireNoRaise;
|
||||||
|
KSPIN_LOCK_QUEUE_NUMBER QueueNumber;
|
||||||
|
BOOLEAN TryRetOnFailure;
|
||||||
|
KIRQL OriginalIrql;
|
||||||
|
BOOLEAN IsAcquired;
|
||||||
|
_ANONYMOUS_UNION union
|
||||||
|
{
|
||||||
|
KLOCK_QUEUE_HANDLE QueueHandle;
|
||||||
|
PKSPIN_LOCK_QUEUE Queue;
|
||||||
|
KIRQL Irql;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
PVOID UntouchedValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_ACQUIRE(LocalName, SetIsAcquired, DoCall) \
|
||||||
|
static VOID LocalName(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) \
|
||||||
|
{ \
|
||||||
|
ASSERT(!CheckData->IsAcquired); \
|
||||||
|
DoCall; \
|
||||||
|
if (SetIsAcquired) CheckData->IsAcquired = TRUE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_RELEASE(LocalName, SetIsAcquired, DoCall) \
|
||||||
|
static VOID LocalName(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) \
|
||||||
|
{ \
|
||||||
|
DoCall; \
|
||||||
|
if (SetIsAcquired) CheckData->IsAcquired = FALSE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireNormal, TRUE, KeAcquireSpinLock(SpinLock, &CheckData->Irql))
|
||||||
|
DEFINE_RELEASE(ReleaseNormal, TRUE, KeReleaseSpinLock(SpinLock, CheckData->Irql))
|
||||||
|
DEFINE_ACQUIRE(AcquireExp, TRUE, (KeAcquireSpinLock)(SpinLock, &CheckData->Irql))
|
||||||
|
DEFINE_RELEASE(ReleaseExp, TRUE, (KeReleaseSpinLock)(SpinLock, CheckData->Irql))
|
||||||
|
DEFINE_ACQUIRE(AcquireSynch, TRUE, CheckData->Irql = KeAcquireSpinLockRaiseToSynch(SpinLock))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireInStackQueued, TRUE, KeAcquireInStackQueuedSpinLock(SpinLock, &CheckData->QueueHandle))
|
||||||
|
DEFINE_ACQUIRE(AcquireInStackSynch, TRUE, KeAcquireInStackQueuedSpinLockRaiseToSynch(SpinLock, &CheckData->QueueHandle))
|
||||||
|
DEFINE_RELEASE(ReleaseInStackQueued, TRUE, KeReleaseInStackQueuedSpinLock(&CheckData->QueueHandle))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireQueued, TRUE, CheckData->Irql = KeAcquireQueuedSpinLock(CheckData->QueueNumber))
|
||||||
|
DEFINE_ACQUIRE(AcquireQueuedSynch, TRUE, CheckData->Irql = KeAcquireQueuedSpinLockRaiseToSynch(CheckData->QueueNumber))
|
||||||
|
DEFINE_RELEASE(ReleaseQueued, TRUE, KeReleaseQueuedSpinLock(CheckData->QueueNumber, CheckData->Irql))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireNoRaise, FALSE, KeAcquireSpinLockAtDpcLevel(SpinLock))
|
||||||
|
DEFINE_RELEASE(ReleaseNoLower, FALSE, KeReleaseSpinLockFromDpcLevel(SpinLock))
|
||||||
|
DEFINE_ACQUIRE(AcquireExpNoRaise, FALSE, (KeAcquireSpinLockAtDpcLevel)(SpinLock))
|
||||||
|
DEFINE_RELEASE(ReleaseExpNoLower, FALSE, (KeReleaseSpinLockFromDpcLevel)(SpinLock))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireInStackNoRaise, FALSE, KeAcquireInStackQueuedSpinLockAtDpcLevel(SpinLock, &CheckData->QueueHandle))
|
||||||
|
DEFINE_RELEASE(ReleaseInStackNoRaise, FALSE, KeReleaseInStackQueuedSpinLockFromDpcLevel(&CheckData->QueueHandle))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireForDpc, TRUE, CheckData->Irql = KeAcquireSpinLockForDpc(SpinLock))
|
||||||
|
DEFINE_RELEASE(ReleaseForDpc, TRUE, KeReleaseSpinLockForDpc(SpinLock, CheckData->Irql))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireInStackForDpc, FALSE, KeAcquireInStackQueuedSpinLockForDpc(SpinLock, &CheckData->QueueHandle))
|
||||||
|
DEFINE_RELEASE(ReleaseInStackForDpc, FALSE, KeReleaseInStackQueuedSpinLockForDpc(&CheckData->QueueHandle))
|
||||||
|
|
||||||
|
DEFINE_ACQUIRE(AcquireInt, FALSE, KiAcquireSpinLock(SpinLock))
|
||||||
|
DEFINE_RELEASE(ReleaseInt, FALSE, KiReleaseSpinLock(SpinLock))
|
||||||
|
|
||||||
|
BOOLEAN TryQueued(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) {
|
||||||
|
LOGICAL Ret = KeTryToAcquireQueuedSpinLock(CheckData->QueueNumber, &CheckData->Irql);
|
||||||
|
CheckData->IsAcquired = TRUE;
|
||||||
|
ASSERT(Ret == FALSE || Ret == TRUE);
|
||||||
|
return (BOOLEAN)Ret;
|
||||||
|
}
|
||||||
|
BOOLEAN TryQueuedSynch(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) {
|
||||||
|
BOOLEAN Ret = KeTryToAcquireQueuedSpinLockRaiseToSynch(CheckData->QueueNumber, &CheckData->Irql);
|
||||||
|
CheckData->IsAcquired = TRUE;
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
BOOLEAN TryNoRaise(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) {
|
||||||
|
BOOLEAN Ret = KeTryToAcquireSpinLockAtDpcLevel(SpinLock);
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CheckSpinLockLock(SpinLock, CheckData, Value) do \
|
||||||
|
{ \
|
||||||
|
PKTHREAD Thread = KeGetCurrentThread(); \
|
||||||
|
if (KmtIsMultiProcessorBuild) \
|
||||||
|
{ \
|
||||||
|
ok_eq_bool(Ret, (Value) == 0); \
|
||||||
|
if (SpinLock) \
|
||||||
|
ok_eq_pointer((PVOID)*(SpinLock), \
|
||||||
|
(Value) ? (PVOID)((ULONG_PTR)Thread | 1) : 0); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
ok_bool_true(Ret, "KeTestSpinLock returned"); \
|
||||||
|
if (SpinLock) \
|
||||||
|
ok_eq_pointer((PVOID)*(SpinLock), NULL); \
|
||||||
|
} \
|
||||||
|
ok_eq_uint((CheckData)->Irql, (CheckData)->OriginalIrql); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CheckSpinLockQueue(SpinLock, CheckData, Value) do \
|
||||||
|
{ \
|
||||||
|
ok_eq_pointer((CheckData)->Queue->Next, NULL); \
|
||||||
|
ok_eq_pointer((CheckData)->Queue->Lock, NULL); \
|
||||||
|
ok_eq_uint((CheckData)->Irql, (CheckData)->OriginalIrql); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CheckSpinLockQueueHandle(SpinLock, CheckData, Value) do \
|
||||||
|
{ \
|
||||||
|
if (KmtIsMultiProcessorBuild) \
|
||||||
|
{ \
|
||||||
|
ok_eq_bool(Ret, (Value) == 0); \
|
||||||
|
if (SpinLock) \
|
||||||
|
ok_eq_pointer((PVOID)*(SpinLock), \
|
||||||
|
(Value) ? &(CheckData)->QueueHandle : 0); \
|
||||||
|
ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Next, NULL); \
|
||||||
|
ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Lock, \
|
||||||
|
(PVOID)((ULONG_PTR)SpinLock | ((Value) ? 2 : 0))); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
ok_bool_true(Ret, "KeTestSpinLock returned"); \
|
||||||
|
if (SpinLock) \
|
||||||
|
ok_eq_pointer((PVOID)*(SpinLock), NULL); \
|
||||||
|
ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Next, (CheckData)->UntouchedValue); \
|
||||||
|
ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Lock, (CheckData)->UntouchedValue); \
|
||||||
|
} \
|
||||||
|
ok_eq_uint((CheckData)->QueueHandle.OldIrql, (CheckData)->OriginalIrql); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CheckSpinLock(SpinLock, CheckData, Value) do \
|
||||||
|
{ \
|
||||||
|
BOOLEAN Ret = SpinLock ? KeTestSpinLock(SpinLock) : TRUE; \
|
||||||
|
KIRQL ExpectedIrql = (CheckData)->OriginalIrql; \
|
||||||
|
\
|
||||||
|
switch ((CheckData)->Check) \
|
||||||
|
{ \
|
||||||
|
case CheckLock: \
|
||||||
|
CheckSpinLockLock(SpinLock, CheckData, Value); \
|
||||||
|
break; \
|
||||||
|
case CheckQueue: \
|
||||||
|
CheckSpinLockQueue(SpinLock, CheckData, Value); \
|
||||||
|
break; \
|
||||||
|
case CheckQueueHandle: \
|
||||||
|
CheckSpinLockQueueHandle(SpinLock, CheckData, Value); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if ((CheckData)->IsAcquired) \
|
||||||
|
ExpectedIrql = (CheckData)->IrqlWhenAcquired; \
|
||||||
|
ok_irql(ExpectedIrql); \
|
||||||
|
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); \
|
||||||
|
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
TestSpinLock(
|
||||||
|
PKSPIN_LOCK SpinLock,
|
||||||
|
PCHECK_DATA CheckData)
|
||||||
|
{
|
||||||
|
static INT Run = 0;
|
||||||
|
trace("Test SpinLock run %d\n", Run++);
|
||||||
|
|
||||||
|
ok_irql(CheckData->OriginalIrql);
|
||||||
|
|
||||||
|
if (SpinLock)
|
||||||
|
ok_eq_pointer((PVOID)*SpinLock, NULL);
|
||||||
|
CheckData->Acquire(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
CheckData->Release(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
|
||||||
|
if (CheckData->TryAcquire)
|
||||||
|
{
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
ok_bool_true(CheckData->TryAcquire(SpinLock, CheckData), "TryAcquire returned");
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
if (!KmtIsCheckedBuild)
|
||||||
|
{
|
||||||
|
/* SPINLOCK_ALREADY_OWNED on checked build */
|
||||||
|
ok_bool_true(CheckData->TryAcquire(SpinLock, CheckData), "TryAcquire returned");
|
||||||
|
/* even a failing acquire sets irql */
|
||||||
|
ok_eq_uint(CheckData->Irql, CheckData->IrqlWhenAcquired);
|
||||||
|
CheckData->Irql = CheckData->OriginalIrql;
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
}
|
||||||
|
CheckData->Release(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckData->AcquireNoRaise &&
|
||||||
|
(CheckData->OriginalIrql >= DISPATCH_LEVEL || !KmtIsCheckedBuild))
|
||||||
|
{
|
||||||
|
/* acquire/release without irql change */
|
||||||
|
CheckData->AcquireNoRaise(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
CheckData->ReleaseNoLower(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
|
||||||
|
/* acquire without raise, but normal release */
|
||||||
|
CheckData->AcquireNoRaise(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
CheckData->Release(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
|
||||||
|
/* acquire normally but release without lower */
|
||||||
|
CheckData->Acquire(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
CheckData->ReleaseNoLower(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
CheckData->IsAcquired = FALSE;
|
||||||
|
KmtSetIrql(CheckData->OriginalIrql);
|
||||||
|
|
||||||
|
if (CheckData->TryAcquireNoRaise)
|
||||||
|
{
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
ok_bool_true(CheckData->TryAcquireNoRaise(SpinLock, CheckData), "TryAcquireNoRaise returned");
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
if (!KmtIsCheckedBuild)
|
||||||
|
{
|
||||||
|
ok_bool_true(CheckData->TryAcquireNoRaise(SpinLock, CheckData), "TryAcquireNoRaise returned");
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 1);
|
||||||
|
}
|
||||||
|
CheckData->ReleaseNoLower(SpinLock, CheckData);
|
||||||
|
CheckSpinLock(SpinLock, CheckData, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ok_irql(CheckData->OriginalIrql);
|
||||||
|
/* make sure we survive this in case of error */
|
||||||
|
KmtSetIrql(CheckData->OriginalIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(KeSpinLock)
|
||||||
|
{
|
||||||
|
KSPIN_LOCK SpinLock = (KSPIN_LOCK)0x5555555555555555LL;
|
||||||
|
PKSPIN_LOCK pSpinLock = &SpinLock;
|
||||||
|
KIRQL Irql, SynchIrql = KmtIsMultiProcessorBuild ? IPI_LEVEL - 2 : DISPATCH_LEVEL;
|
||||||
|
KIRQL OriginalIrqls[] = { PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL, HIGH_LEVEL };
|
||||||
|
CHECK_DATA TestData[] =
|
||||||
|
{
|
||||||
|
{ CheckLock, DISPATCH_LEVEL, AcquireNormal, ReleaseNormal, NULL, AcquireNoRaise, ReleaseNoLower, TryNoRaise },
|
||||||
|
{ CheckLock, DISPATCH_LEVEL, AcquireExp, ReleaseExp, NULL, AcquireExpNoRaise, ReleaseExpNoLower, NULL },
|
||||||
|
/* TODO: this one is just weird!
|
||||||
|
{ CheckLock, DISPATCH_LEVEL, AcquireNormal, ReleaseNormal, NULL, AcquireForDpc, ReleaseForDpc, NULL },*/
|
||||||
|
{ CheckLock, DISPATCH_LEVEL, AcquireNormal, ReleaseNormal, NULL, AcquireInt, ReleaseInt, NULL },
|
||||||
|
{ CheckLock, SynchIrql, AcquireSynch, ReleaseNormal, NULL, NULL, NULL, NULL },
|
||||||
|
{ CheckQueueHandle, DISPATCH_LEVEL, AcquireInStackQueued, ReleaseInStackQueued, NULL, AcquireInStackNoRaise, ReleaseInStackNoRaise, NULL },
|
||||||
|
{ CheckQueueHandle, SynchIrql, AcquireInStackSynch, ReleaseInStackQueued, NULL, NULL, NULL, NULL },
|
||||||
|
{ CheckQueueHandle, DISPATCH_LEVEL, AcquireInStackQueued, ReleaseInStackQueued, NULL, AcquireInStackForDpc, ReleaseInStackForDpc, NULL },
|
||||||
|
{ CheckQueue, DISPATCH_LEVEL, AcquireQueued, ReleaseQueued, TryQueued, NULL, NULL, NULL, LockQueuePfnLock },
|
||||||
|
{ CheckQueue, SynchIrql, AcquireQueuedSynch, ReleaseQueued, TryQueuedSynch, NULL, NULL, NULL, LockQueuePfnLock },
|
||||||
|
};
|
||||||
|
int i, iIrql;
|
||||||
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
|
|
||||||
|
/* KeInitializeSpinLock */
|
||||||
|
memset(&SpinLock, 0x55, sizeof SpinLock);
|
||||||
|
KeInitializeSpinLock(&SpinLock);
|
||||||
|
ok_eq_pointer((PVOID)SpinLock, NULL);
|
||||||
|
|
||||||
|
/* KeTestSpinLock */
|
||||||
|
ok_bool_true(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
|
||||||
|
SpinLock = 1;
|
||||||
|
ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
|
||||||
|
SpinLock = 2;
|
||||||
|
ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
|
||||||
|
SpinLock = (ULONG_PTR)-1;
|
||||||
|
ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
|
||||||
|
SpinLock = (ULONG_PTR)1 << (sizeof(ULONG_PTR) * CHAR_BIT - 1);
|
||||||
|
ok_bool_false(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
|
||||||
|
SpinLock = 0;
|
||||||
|
ok_bool_true(KeTestSpinLock(&SpinLock), "KeTestSpinLock returned");
|
||||||
|
|
||||||
|
/* on UP none of the following functions actually looks at the spinlock! */
|
||||||
|
if (!KmtIsMultiProcessorBuild && !KmtIsCheckedBuild)
|
||||||
|
pSpinLock = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof TestData / sizeof TestData[0]; ++i)
|
||||||
|
{
|
||||||
|
memset(&SpinLock, 0x55, sizeof SpinLock);
|
||||||
|
KeInitializeSpinLock(&SpinLock);
|
||||||
|
if (TestData[i].Check == CheckQueueHandle)
|
||||||
|
memset(&TestData[i].QueueHandle, 0x55, sizeof TestData[i].QueueHandle);
|
||||||
|
if (TestData[i].Check == CheckQueue)
|
||||||
|
{
|
||||||
|
TestData[i].Queue = &Prcb->LockQueue[TestData[i].QueueNumber];
|
||||||
|
TestData[i].UntouchedValue = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TestData[i].UntouchedValue = (PVOID)0x5555555555555555LL;
|
||||||
|
|
||||||
|
for (iIrql = 0; iIrql < sizeof OriginalIrqls / sizeof OriginalIrqls[0]; ++iIrql)
|
||||||
|
{
|
||||||
|
if (KmtIsCheckedBuild && OriginalIrqls[iIrql] > DISPATCH_LEVEL)
|
||||||
|
continue;
|
||||||
|
KeRaiseIrql(OriginalIrqls[iIrql], &Irql);
|
||||||
|
TestData[i].OriginalIrql = OriginalIrqls[iIrql];
|
||||||
|
TestData[i].IsAcquired = FALSE;
|
||||||
|
TestSpinLock(pSpinLock, &TestData[i]);
|
||||||
|
KeLowerIrql(Irql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KmtSetIrql(PASSIVE_LEVEL);
|
||||||
|
}
|
Loading…
Reference in a new issue