#include <ndk/ntndk.h>\r
#include "kmtest.h"\r
\r
-#define NDEBUG\r
+//#define NDEBUG\r
#include "debug.h"\r
\r
/* PRIVATE FUNCTIONS ***********************************************************/\r
\r
+VOID\r
+NTAPI\r
+TestTimerApcRoutine(IN PVOID TimerContext,\r
+ IN ULONG TimerLowValue,\r
+ IN LONG TimerHighValue)\r
+\r
+{\r
+ DPRINT("Timer Apc called!\n");\r
+ ULONG *ApcCount = (ULONG *)TimerContext;\r
+ (*ApcCount)++;\r
+}\r
+\r
+\r
VOID\r
ExTimerTest()\r
{\r
LARGE_INTEGER DueTime;\r
BOOLEAN PreviousState, CurrentState;\r
NTSTATUS Status;\r
+ ULONG ApcCount;\r
\r
StartTest();\r
\r
ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status);\r
ok(CurrentState == TRUE, "Incorrect CurrentState returned when setting the timer");\r
\r
- // TODO: Add tests for a timer with APC routines\r
+ // Test it with APC: Set, Cancel, check if APC has been called\r
+ ApcCount = 0;\r
+ DueTime.LowPart = -10000;\r
+ DueTime.HighPart = -10;\r
+ PreviousState = FALSE;\r
+ Status = ZwSetTimer(HandleOpened, &DueTime,\r
+ (PTIMER_APC_ROUTINE)TestTimerApcRoutine, &ApcCount, FALSE,\r
+ 0L, &PreviousState);\r
+\r
+ ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status);\r
+ ok(PreviousState == TRUE, "Incorrect PreviousState returned when setting the timer");\r
+\r
+ CurrentState = TRUE;\r
+ Status = ZwCancelTimer(HandleOpened, &CurrentState);\r
+ ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status);\r
+ ok(CurrentState == FALSE, "Incorrect CurrentState returned when cancelling the timer");\r
+ ok(ApcCount == 0, "Incorrect count of TimerApcRoutine calls: %ld, should be 0\n", ApcCount);\r
+\r
+ // Test setting the timer two times in a row, APC routine must not be called\r
+ ApcCount = 0;\r
+ DueTime.LowPart = -10000;\r
+ DueTime.HighPart = -10;\r
+ PreviousState = TRUE;\r
+ Status = ZwSetTimer(HandleOpened, &DueTime,\r
+ (PTIMER_APC_ROUTINE)TestTimerApcRoutine, &ApcCount, FALSE,\r
+ 0L, &PreviousState);\r
+ ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status);\r
+ ok(PreviousState == FALSE, "Incorrect PreviousState returned when setting the timer");\r
+\r
+ // Set small due time, since we have to wait for timer to finish\r
+ DueTime.LowPart = -10;\r
+ DueTime.HighPart = -1;\r
+ PreviousState = TRUE;\r
+ Status = ZwSetTimer(HandleOpened, &DueTime,\r
+ (PTIMER_APC_ROUTINE)TestTimerApcRoutine, &ApcCount, FALSE,\r
+ 0L, &PreviousState);\r
+ ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status);\r
+ ok(PreviousState == FALSE, "Incorrect PreviousState returned when setting the timer");\r
+\r
+ // Now wait till it's finished, and then check APC call\r
+ Status = ZwWaitForSingleObject(HandleOpened, FALSE, NULL);\r
+ ok(Status == STATUS_SUCCESS, "ZwWaitForSingleObject failed with Status=0x%08lX", Status);\r
+\r
+ CurrentState = FALSE;\r
+ Status = ZwCancelTimer(HandleOpened, &CurrentState);\r
+ ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status);\r
+ ok(CurrentState == TRUE, "Incorrect CurrentState returned when cancelling the timer");\r
+ ok(ApcCount == 1, "Incorrect count of TimerApcRoutine calls: %ld, should be 1\n", ApcCount);\r
\r
// Cleanup...\r
Status = ZwClose(HandleOpened);\r