ReactOS  0.4.14-dev-376-gaedba84
KeDpc.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS kernel-mode tests
3  * LICENSE: GPLv2+ - See COPYING in the top level directory
4  * PURPOSE: Kernel-Mode Test Suite Deferred Procedure Call test
5  * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 //#define NDEBUG
11 #include <debug.h>
12 
13 /* TODO: DPC importance */
14 
15 static volatile LONG DpcCount;
16 static volatile UCHAR DpcImportance;
17 
18 static KDEFERRED_ROUTINE DpcHandler;
19 
20 static
21 VOID
22 NTAPI
24  IN PRKDPC Dpc,
28 {
29  PKPRCB Prcb = KeGetCurrentPrcb();
30 
31  ok_irql(DISPATCH_LEVEL);
33  ok(DeferredContext == Dpc, "DeferredContext = %p, Dpc = %p, expected equal\n", DeferredContext, Dpc);
36 
37  /* KDPC object contents */
38  ok_eq_uint(Dpc->Type, DpcObject);
39  ok_eq_uint(Dpc->Importance, DpcImportance);
40  ok_eq_uint(Dpc->Number, 0);
41  ok(Dpc->DpcListEntry.Blink != NULL, "\n");
42  ok(Dpc->DpcListEntry.Blink != &Dpc->DpcListEntry, "\n");
43  if (!skip(Dpc->DpcListEntry.Blink != NULL, "DpcListEntry.Blink == NULL\n"))
44  ok_eq_pointer(Dpc->DpcListEntry.Flink, Dpc->DpcListEntry.Blink->Flink);
45 
46  ok(Dpc->DpcListEntry.Flink != NULL, "\n");
47  ok(Dpc->DpcListEntry.Flink != &Dpc->DpcListEntry, "\n");
48  if (!skip(Dpc->DpcListEntry.Flink != NULL, "DpcListEntry.Flink == NULL\n"))
49  ok_eq_pointer(Dpc->DpcListEntry.Blink, Dpc->DpcListEntry.Flink->Blink);
50 
51  ok_eq_pointer(Dpc->DeferredRoutine, DpcHandler);
52  ok_eq_pointer(Dpc->DeferredContext, DeferredContext);
53  ok_eq_pointer(Dpc->SystemArgument1, SystemArgument1);
54  ok_eq_pointer(Dpc->SystemArgument2, SystemArgument2);
55  ok_eq_pointer(Dpc->DpcData, NULL);
56 
57  ok_eq_uint(Prcb->DpcRoutineActive, 1);
58  /* this DPC is not in the list anymore, but it was at the head! */
59  ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Flink, Dpc->DpcListEntry.Flink);
60  ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Blink, Dpc->DpcListEntry.Blink);
61 }
62 
63 START_TEST(KeDpc)
64 {
66  KDPC Dpc;
67  KIRQL Irql, Irql2, Irql3;
68  LONG ExpectedDpcCount = 0;
69  BOOLEAN Ret;
70  int i;
71 
72  DpcCount = 0;
74 
75 #define ok_dpccount() ok(DpcCount == ExpectedDpcCount, "DpcCount = %ld, expected %ld\n", DpcCount, ExpectedDpcCount);
76  trace("Dpc = %p\n", &Dpc);
77  memset(&Dpc, 0x55, sizeof Dpc);
79  /* check the Dpc object's fields */
80  ok_eq_uint(Dpc.Type, DpcObject);
81  ok_eq_uint(Dpc.Importance, DpcImportance);
82  ok_eq_uint(Dpc.Number, 0);
83  ok_eq_pointer(Dpc.DpcListEntry.Flink, (LIST_ENTRY *)0x5555555555555555LL);
84  ok_eq_pointer(Dpc.DpcListEntry.Blink, (LIST_ENTRY *)0x5555555555555555LL);
85  ok_eq_pointer(Dpc.DeferredRoutine, DpcHandler);
86  ok_eq_pointer(Dpc.DeferredContext, &Dpc);
87  ok_eq_pointer(Dpc.SystemArgument1, (PVOID)0x5555555555555555LL);
88  ok_eq_pointer(Dpc.SystemArgument2, (PVOID)0x5555555555555555LL);
89  ok_eq_pointer(Dpc.DpcData, NULL);
90 
91  /* simply run the Dpc a few times */
92  for (i = 0; i < 5; ++i)
93  {
94  ok_dpccount();
95  Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xabc123, (PVOID)0x5678);
96  ok_bool_true(Ret, "KeInsertQueueDpc returned");
97  ++ExpectedDpcCount;
98  ok_dpccount();
99  }
100 
101  /* insert into queue at high irql
102  * -> should only run when lowered to APC_LEVEL,
103  * inserting a second time should fail
104  */
106  for (i = 0; i < 5; ++i)
107  {
108  KeRaiseIrql(DISPATCH_LEVEL, &Irql2);
109  ok_dpccount();
110  Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xabc123, (PVOID)0x5678);
111  ok_bool_true(Ret, "KeInsertQueueDpc returned");
112  Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xdef, (PVOID)0x123);
113  ok_bool_false(Ret, "KeInsertQueueDpc returned");
114  ok_dpccount();
115  KeRaiseIrql(HIGH_LEVEL, &Irql3);
116  ok_dpccount();
117  KeLowerIrql(Irql3);
118  ok_dpccount();
119  KeLowerIrql(Irql2);
120  ++ExpectedDpcCount;
121  ok_dpccount();
122  }
123  KeLowerIrql(Irql);
124 
125  /* now test removing from the queue */
127  for (i = 0; i < 5; ++i)
128  {
129  KeRaiseIrql(DISPATCH_LEVEL, &Irql2);
130  ok_dpccount();
131  Ret = KeRemoveQueueDpc(&Dpc);
132  ok_bool_false(Ret, "KeRemoveQueueDpc returned");
133  Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xabc123, (PVOID)0x5678);
134  ok_bool_true(Ret, "KeInsertQueueDpc returned");
135  ok_dpccount();
136  KeRaiseIrql(HIGH_LEVEL, &Irql3);
137  ok_dpccount();
138  KeLowerIrql(Irql3);
139  ok_dpccount();
140  Ret = KeRemoveQueueDpc(&Dpc);
141  ok_bool_true(Ret, "KeRemoveQueueDpc returned");
142  KeLowerIrql(Irql2);
143  ok_dpccount();
144  }
145  KeLowerIrql(Irql);
146 
147  /* parameter checks */
149  _SEH2_TRY {
153  } _SEH2_END;
155 
156  if (!skip(Status == STATUS_SUCCESS, "KeInitializeDpc failed\n"))
157  {
159  Ret = KeInsertQueueDpc(&Dpc, NULL, NULL);
160  ok_bool_true(Ret, "KeInsertQueueDpc returned");
161  Ret = KeRemoveQueueDpc(&Dpc);
162  ok_bool_true(Ret, "KeRemoveQueueDpc returned");
163  KeLowerIrql(Irql);
164  }
165 
167  _SEH2_TRY {
171  } _SEH2_END;
173 
174  /* These result in IRQL_NOT_LESS_OR_EQUAL on 2k3 -- IRQLs 0x1f and 0xff (?)
175  Ret = KeInsertQueueDpc(NULL, NULL, NULL);
176  Ret = KeRemoveQueueDpc(NULL);*/
177 
178  ok_dpccount();
179  ok_irql(PASSIVE_LEVEL);
180  trace("Final Dpc count: %ld, expected %ld\n", DpcCount, ExpectedDpcCount);
181 }
#define IN
Definition: typedefs.h:38
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
START_TEST(KeDpc)
Definition: KeDpc.c:63
#define DPC_NORMAL
KDPC_DATA DpcData[2]
Definition: ketypes.h:676
#define ok_eq_pointer(value, expected)
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
static volatile UCHAR DpcImportance
Definition: KeDpc.c:16
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:877
static KDEFERRED_ROUTINE DpcHandler
Definition: KeDpc.c:18
_Out_ PKIRQL Irql
Definition: csq.h:179
_SEH2_TRY
Definition: create.c:4250
static volatile LONG DpcCount
Definition: KeDpc.c:15
#define ok_bool_false(value, desc)
Definition: kmt_test.h:257
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
#define ok_dpccount()
#define trace
Definition: atltest.h:70
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR DpcRoutineActive
Definition: ketypes.h:688
Definition: ketypes.h:687
Definition: typedefs.h:117
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
_SEH2_END
Definition: create.c:4424
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ok_eq_hex(value, expected)
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define memset(x, y, z)
Definition: compat.h:39
#define APC_LEVEL
Definition: env_spec_w32.h:695
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675