1 /* 2 * PROJECT: ReactOS kernel-mode tests 3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Kernel-Mode Test Suite Executive Regressions KM-Test 5 * PROGRAMMER: Aleksey Bragin <aleksey@reactos.org> 6 */ 7 8 #include <kmt_test.h> 9 10 #define NDEBUG 11 #include <debug.h> 12 13 static 14 VOID 15 NTAPI 16 TestTimerApcRoutine(IN PVOID TimerContext, 17 IN ULONG TimerLowValue, 18 IN LONG TimerHighValue) 19 20 { 21 ULONG *ApcCount = (ULONG *)TimerContext; 22 DPRINT("Timer Apc called!\n"); 23 (*ApcCount)++; 24 } 25 26 START_TEST(ExTimer) 27 { 28 UNICODE_STRING TimerName; 29 OBJECT_ATTRIBUTES ObjectAttributes; 30 HANDLE TimerHandle; 31 HANDLE HandleOpened; 32 LARGE_INTEGER DueTime; 33 BOOLEAN PreviousState, CurrentState; 34 NTSTATUS Status; 35 ULONG ApcCount; 36 37 // Create the timer 38 RtlInitUnicodeString(&TimerName, L"\\TestTimer"); 39 InitializeObjectAttributes(&ObjectAttributes, &TimerName, 0, NULL, NULL); 40 Status = ZwCreateTimer(&TimerHandle, TIMER_ALL_ACCESS, 41 &ObjectAttributes, NotificationTimer); 42 ok(Status == STATUS_SUCCESS, "ZwCreateTimer failed with Status=0x%08lX", Status); 43 44 // Open the timer 45 Status = ZwOpenTimer(&HandleOpened, TIMER_ALL_ACCESS, &ObjectAttributes); 46 ok(Status == STATUS_SUCCESS, "ZwOpenTimer failed with Status=0x%08lX", Status); 47 48 // Set the timer, to some rather high value so it doesn't expire 49 DPRINT("Set timer 1\n"); 50 DueTime.LowPart = -10000; 51 DueTime.HighPart = -10; 52 PreviousState = TRUE; 53 Status = ZwSetTimer(HandleOpened, &DueTime, NULL, NULL, FALSE, 0L, &PreviousState); 54 ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status); 55 ok(PreviousState == FALSE, "Incorrect PreviousState returned when setting the timer"); 56 57 // Cancel the timer 58 CurrentState = TRUE; 59 Status = ZwCancelTimer(HandleOpened, &CurrentState); 60 ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status); 61 ok(CurrentState == FALSE, "Incorrect CurrentState returned when canceling the timer"); 62 63 // Set the timer to some small value, because we'll wait for it to expire 64 DPRINT("Set timer 2\n"); 65 DueTime.LowPart = -100; 66 DueTime.HighPart = -1; 67 PreviousState = TRUE; 68 Status = ZwSetTimer(HandleOpened, &DueTime, NULL, NULL, FALSE, 0L, &PreviousState); 69 ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status); 70 ok(PreviousState == FALSE, "Incorrect PreviousState returned when setting the timer"); 71 72 // Wait until it expires 73 DPRINT("Wait till timer expires\n"); 74 Status = ZwWaitForSingleObject(HandleOpened, FALSE, NULL); 75 ok(Status == STATUS_SUCCESS, "ZwWaitForSingleObject failed with Status=0x%08lX", Status); 76 77 // And cancel it 78 DPRINT("Cancel it\n"); 79 CurrentState = FALSE; 80 Status = ZwCancelTimer(HandleOpened, &CurrentState); 81 ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status); 82 ok(CurrentState == TRUE, "Incorrect CurrentState returned when setting the timer"); 83 84 // Test it with APC: Set, Cancel, check if APC has been called 85 DPRINT("Set timer with Apc (3)\n"); 86 ApcCount = 0; 87 DueTime.LowPart = -10000; 88 DueTime.HighPart = -10; 89 PreviousState = FALSE; 90 Status = ZwSetTimer(HandleOpened, &DueTime, 91 (PTIMER_APC_ROUTINE)TestTimerApcRoutine, &ApcCount, FALSE, 92 0L, &PreviousState); 93 94 ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status); 95 ok(PreviousState == TRUE, "Incorrect PreviousState returned when setting the timer"); 96 97 DPRINT("Cancel it\n"); 98 CurrentState = TRUE; 99 Status = ZwCancelTimer(HandleOpened, &CurrentState); 100 ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status); 101 ok(CurrentState == FALSE, "Incorrect CurrentState returned when cancelling the timer"); 102 ok(ApcCount == 0, "Incorrect count of TimerApcRoutine calls: %ld, should be 0\n", ApcCount); 103 104 // Test setting the timer two times in a row, APC routine must not be called 105 DPRINT("Set timer with Apc (4)\n"); 106 ApcCount = 0; 107 DueTime.LowPart = -10000; 108 DueTime.HighPart = -10; 109 PreviousState = TRUE; 110 Status = ZwSetTimer(HandleOpened, &DueTime, 111 (PTIMER_APC_ROUTINE)TestTimerApcRoutine, &ApcCount, FALSE, 112 0L, &PreviousState); 113 ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status); 114 ok(PreviousState == FALSE, "Incorrect PreviousState returned when setting the timer"); 115 116 // Set small due time, since we have to wait for timer to finish 117 DPRINT("Set timer with Apc (5)\n"); 118 DueTime.LowPart = -10; 119 DueTime.HighPart = -1; 120 PreviousState = TRUE; 121 Status = ZwSetTimer(HandleOpened, &DueTime, 122 (PTIMER_APC_ROUTINE)TestTimerApcRoutine, &ApcCount, FALSE, 123 0L, &PreviousState); 124 ok(Status == STATUS_SUCCESS, "ZwSetTimer failed with Status=0x%08lX", Status); 125 ok(PreviousState == FALSE, "Incorrect PreviousState returned when setting the timer"); 126 127 // Now wait till it's finished, and then check APC call 128 DPRINT("Wait for it\n"); 129 Status = ZwWaitForSingleObject(HandleOpened, FALSE, NULL); 130 ok(Status == STATUS_SUCCESS, "ZwWaitForSingleObject failed with Status=0x%08lX", Status); 131 132 CurrentState = FALSE; 133 Status = ZwCancelTimer(HandleOpened, &CurrentState); 134 ok(Status == STATUS_SUCCESS, "ZwCancelTimer failed with Status=0x%08lX", Status); 135 ok(CurrentState == TRUE, "Incorrect CurrentState returned when cancelling the timer"); 136 ok(ApcCount == 1, "Incorrect count of TimerApcRoutine calls: %ld, should be 1\n", ApcCount); 137 138 // Cleanup... 139 Status = ZwClose(HandleOpened); 140 ok(Status == STATUS_SUCCESS, "ZwClose failed with Status=0x%08lX", Status); 141 142 Status = ZwClose(TimerHandle); 143 ok(Status == STATUS_SUCCESS, "ZwClose failed with Status=0x%08lX", Status); 144 } 145