ReactOS 0.4.15-dev-8339-g4028de8
clntirp.c
Go to the documentation of this file.
1/*++
2
3Copyright (C) Microsoft Corporation, 1991 - 1999
4
5Module Name:
6
7 clntirp.c
8
9Abstract:
10
11 Client IRP queuing routines for CLASSPNP
12
13Environment:
14
15 kernel mode only
16
17Notes:
18
19
20Revision History:
21
22--*/
23
24#include "classp.h"
25#include "debug.h"
26
27
28#ifdef DEBUG_USE_WPP
29#include "clntirp.tmh"
30#endif
31
32VOID
35 );
36
37VOID
40 );
41
42KDEFERRED_ROUTINE ClasspIdleTimerDpc;
43
44VOID
47 BOOLEAN PostToDpc
48 );
49
50
51PIRP
54 );
55
56
57/*++
58
59EnqueueDeferredClientIrp
60
61Routine Description:
62
63 Insert the deferred irp into the list.
64
65 Note: we currently do not support Cancel for storage irps.
66
67Arguments:
68
69 Fdo - Pointer to the device object
70 Irp - Pointer to the I/O request packet
71
72Return Value:
73
74 None
75
76--*/
77VOID
80 PIRP Irp
81 )
82{
83 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
84 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
85 KIRQL oldIrql;
86
87
88 KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
89 InsertTailList(&fdoData->DeferredClientIrpList, &Irp->Tail.Overlay.ListEntry);
90
91
92 KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
93}
94
95/*++
96
97DequeueDeferredClientIrp
98
99Routine Description:
100
101 Remove the deferred irp from the list.
102
103Arguments:
104
105 Fdo - Pointer to the device object
106
107Return Value:
108
109 Pointer to removed IRP
110
111--*/
112PIRP
115 )
116{
117 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
118 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
119 PIRP irp;
120
121 //
122 // The DeferredClientIrpList is almost always empty.
123 // We don't want to grab the spinlock every time we check it (which is on every xfer completion)
124 // so check once first before we grab the spinlock.
125 //
126 if (IsListEmpty(&fdoData->DeferredClientIrpList)){
127 irp = NULL;
128 }
129 else {
130 PLIST_ENTRY listEntry;
131 KIRQL oldIrql;
132
133 KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
134 if (IsListEmpty(&fdoData->DeferredClientIrpList)){
135 listEntry = NULL;
136 }
137 else {
138 listEntry = RemoveHeadList(&fdoData->DeferredClientIrpList);
139 }
140 KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
141
142 if (listEntry == NULL) {
143 irp = NULL;
144 }
145 else {
146 irp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
147 NT_ASSERT(irp->Type == IO_TYPE_IRP);
148
149
150 InitializeListHead(&irp->Tail.Overlay.ListEntry);
151 }
152 }
153
154 return irp;
155}
156
157/*++
158
159ClasspInitializeIdleTimer
160
161Routine Description:
162
163 Initialize the idle timer for the given device.
164
165Arguments:
166
167 FdoExtension - Pointer to the device extension
168
169Return Value:
170
171 None
172
173--*/
174VOID
177 )
178{
179 PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
180 ULONG idleInterval = CLASS_IDLE_INTERVAL;
181 ULONG idlePrioritySupported = TRUE;
182 ULONG activeIdleIoMax = 1;
183
184 ClassGetDeviceParameter(FdoExtension,
187 &idlePrioritySupported);
188
189
190 if (idlePrioritySupported == FALSE) {
191 //
192 // User has set the registry to disable idle priority for this disk.
193 // No need to initialize any further.
194 // Always ensure that none of the other fields used for idle priority
195 // io are ever used without checking if it is supported.
196 //
197 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspInitializeIdleTimer: Idle priority not supported for disk %p\n", FdoExtension));
198 fdoData->IdlePrioritySupported = FALSE;
199 fdoData->IdleIoCount = 0;
200 fdoData->ActiveIoCount = 0;
201 return;
202 }
203
204 ClassGetDeviceParameter(FdoExtension,
207 &idleInterval);
208
209 if ((idleInterval < CLASS_IDLE_INTERVAL_MIN) || (idleInterval > USHORT_MAX)) {
210 //
211 // If the interval is too low or too high, reset it to the default value.
212 //
213 idleInterval = CLASS_IDLE_INTERVAL;
214 }
215
216 fdoData->IdlePrioritySupported = TRUE;
218 KeInitializeTimer(&fdoData->IdleTimer);
221 fdoData->IdleTimerStarted = FALSE;
223 fdoData->IdleInterval = (USHORT)(idleInterval);
224 fdoData->IdleIoCount = 0;
225 fdoData->ActiveIoCount = 0;
226 fdoData->ActiveIdleIoCount = 0;
227
228 ClassGetDeviceParameter(FdoExtension,
231 &activeIdleIoMax);
232
233 activeIdleIoMax = max(activeIdleIoMax, 1);
234 activeIdleIoMax = min(activeIdleIoMax, USHORT_MAX);
235
236 fdoData->IdleActiveIoMax = (USHORT)activeIdleIoMax;
237
238 return;
239}
240
241/*++
242
243ClasspStartIdleTimer
244
245Routine Description:
246
247 Start the idle timer if not already running. Reset the
248 timer counters before starting the timer. Use the IdleInterval
249 in the private fdo data to setup the timer.
250
251Arguments:
252
253 FdoData - Pointer to the private fdo data
254
255Return Value:
256
257 None
258
259--*/
260VOID
263 )
264{
265 LARGE_INTEGER dueTime;
266 LONG mstotimer;
267 LONG timerStarted;
268
269 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspStartIdleTimer: Start idle timer\n"));
270
271 timerStarted = InterlockedCompareExchange(&FdoData->IdleTimerStarted, 1, 0);
272
273 if (!timerStarted) {
274
275 //
276 // Reset the anti-starvation start time.
277 //
278 FdoData->AntiStarvationStartTime = ClasspGetCurrentTime();
279
280 //
281 // convert milliseconds to a relative 100ns
282 //
283 mstotimer = (-10) * 1000;
284
285 //
286 // multiply the period
287 //
288 dueTime.QuadPart = Int32x32To64(FdoData->IdleInterval, mstotimer);
289
290 KeSetTimerEx(&FdoData->IdleTimer,
291 dueTime,
292 FdoData->IdleInterval,
293 &FdoData->IdleDpc);
294 }
295 return;
296}
297
298/*++
299
300ClasspStopIdleTimer
301
302Routine Description:
303
304 Stop the idle timer if running. Also reset the timer counters.
305
306Arguments:
307
308 FdoData - Pointer to the private fdo data
309
310Return Value:
311
312 None
313
314--*/
315VOID
318 )
319{
320 LONG timerStarted;
321
322 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspStopIdleTimer: Stop idle timer\n"));
323
324 timerStarted = InterlockedCompareExchange(&FdoData->IdleTimerStarted, 0, 1);
325
326 if (timerStarted) {
327 (VOID)KeCancelTimer(&FdoData->IdleTimer);
328 }
329 return;
330}
331
332/*++
333
334ClasspGetIdleTime
335
336Routine Description:
337
338 This routine returns how long it has been since the last non-idle request
339 completed by checking the actual time.
340
341Arguments:
342
343 FdoData - Pointer to the private fdo data
344
345Return Value:
346
347 The idle interval in ms.
348
349--*/
353 IN LARGE_INTEGER CurrentTime
354 )
355{
356 ULONGLONG idleTime;
358
359 //
360 // Get the time difference between current time and last I/O
361 // complete time.
362 //
363
364 status = RtlULongLongSub((ULONGLONG)CurrentTime.QuadPart,
365 (ULONGLONG)FdoData->LastNonIdleIoTime.QuadPart,
366 &idleTime);
367
368 if (NT_SUCCESS(status)) {
369 //
370 // Convert the time to milliseconds.
371 //
372 idleTime = ClasspTimeDiffToMs(idleTime);
373 } else {
374 //
375 // Failed to get time difference, assume enough time passed.
376 //
377 idleTime = FdoData->IdleInterval;
378 }
379
380 return idleTime;
381}
382
383/*++
384
385ClasspIdleDurationSufficient
386
387Routine Description:
388
389 This routine computes whether enough idle duration has elapsed since the
390 completion of the last non-idle request.
391
392Arguments:
393
394 FdoData - Pointer to the private fdo data
395
396 CurrentTimeIn - If CurrentTimeIn is non-NULL
397 - contents are set to NULL if the time is not updated.
398 - time is updated otherwise
399
400Return Value:
401
402 TRUE if sufficient idle duration has elapsed to issue the next idle request.
403
404--*/
405LOGICAL
408 OUT LARGE_INTEGER** CurrentTimeIn
409 )
410{
411 ULONGLONG idleInterval;
412 LARGE_INTEGER CurrentTime;
413
414 //
415 // If there are any outstanding non-idle requests, then there has been no
416 // idle time.
417 //
418 if (FdoData->ActiveIoCount > 0) {
419 if (CurrentTimeIn != NULL) {
420 *CurrentTimeIn = NULL;
421 }
422 return FALSE;
423 }
424
425 //
426 // Check whether an idle request should be issued now or on the next timer
427 // expiration.
428 //
429
430 CurrentTime = ClasspGetCurrentTime();
431 idleInterval = ClasspGetIdleTime(FdoData, CurrentTime);
432
433 if (CurrentTimeIn != NULL) {
434 **CurrentTimeIn = CurrentTime;
435 }
436
437 if (idleInterval >= FdoData->IdleInterval) {
438 return TRUE;
439 }
440
441 return FALSE;
442}
443
444/*++
445
446ClasspIdleTimerDpc
447
448Routine Description:
449
450 Timer dpc function. This function will be called once every
451 IdleInterval. An idle request will be queued if sufficient idle time
452 has elapsed since the last non-idle request.
453
454Arguments:
455
456 Dpc - Pointer to DPC object
457 Context - Pointer to the fdo device extension
458 SystemArgument1 - Not used
459 SystemArgument2 - Not used
460
461Return Value:
462
463 None
464
465--*/
466VOID
467NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
469 IN PKDPC Dpc,
473 )
474{
477 ULONGLONG idleTime;
479 LARGE_INTEGER currentTime;
480 LARGE_INTEGER* pCurrentTime;
481
485
486 if (fdoExtension == NULL) {
487 NT_ASSERT(fdoExtension != NULL);
488 return;
489 }
490
491 fdoData = fdoExtension->PrivateFdoData;
492
493 if (fdoData->ActiveIoCount <= 0) {
494
495 //
496 // If there are max active idle requests, do not issue another one here.
497 //
498 if (fdoData->ActiveIdleIoCount >= fdoData->IdleActiveIoMax) {
499 return;
500 }
501
502 //
503 // Check whether enough idle time has passed since the last non-idle
504 // request has completed.
505 //
506
507 pCurrentTime = &currentTime;
508 if (ClasspIdleDurationSufficient(fdoData, &pCurrentTime)) {
509 //
510 // We are going to issue an idle request so reset the anti-starvation
511 // timer counter.
512 // If we are here (Idle duration is sufficient), pCurrentTime is
513 // expected to be set.
514 //
515 NT_ASSERT(pCurrentTime != NULL);
516 fdoData->AntiStarvationStartTime = *pCurrentTime;
517 ClasspServiceIdleRequest(fdoExtension, FALSE);
518 }
519 return;
520 }
521
522 //
523 // Get the time difference between current time and last I/O
524 // complete time.
525 //
526
527 currentTime = ClasspGetCurrentTime();
528 status = RtlULongLongSub((ULONGLONG)currentTime.QuadPart,
530 &idleTime);
531
532 if (NT_SUCCESS(status)) {
533 //
534 // Convert the time to milliseconds.
535 //
536 idleTime = ClasspTimeDiffToMs(idleTime);
537 } else {
538 //
539 // Failed to get time difference, assume enough time passed.
540 //
541 idleTime = fdoData->StarvationDuration;
542 }
543
544 //
545 // If the timer is running then there must be at least one idle priority I/O pending
546 //
547 if (idleTime >= fdoData->StarvationDuration) {
548 fdoData->AntiStarvationStartTime = currentTime;
549 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspIdleTimerDpc: Starvation timer. Send one idle request\n"));
550 ClasspServiceIdleRequest(fdoExtension, FALSE);
551 }
552 return;
553}
554
555/*++
556
557ClasspEnqueueIdleRequest
558
559Routine Description:
560
561 This function will insert the idle request into the list.
562 If the inserted reqeust is the first request then it will
563 start the timer.
564
565Arguments:
566
567 DeviceObject - Pointer to device object
568 Irp - Pointer to the idle I/O request packet
569
570Return Value:
571
572 NT status code.
573
574--*/
578 PIRP Irp
579 )
580{
581 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
582 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
583 KIRQL oldIrql;
584 BOOLEAN issueRequest = TRUE;
585 LARGE_INTEGER currentTime;
586 LARGE_INTEGER* pCurrentTime;
587
588 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspEnqueueIdleRequest: Queue idle request %p\n", Irp));
589
591
592 //
593 // Reset issueRequest if the idle duration is not sufficient.
594 //
595 pCurrentTime = &currentTime;
596 if (ClasspIdleDurationSufficient(fdoData, &pCurrentTime) == FALSE) {
597 issueRequest = FALSE;
598 }
599
600 //
601 // If there are already max active idle requests in the port driver, then
602 // queue this idle request.
603 //
604 if (fdoData->ActiveIdleIoCount >= fdoData->IdleActiveIoMax) {
605 issueRequest = FALSE;
606 }
607
608
609 KeAcquireSpinLock(&fdoData->IdleListLock, &oldIrql);
610 if (IsListEmpty(&fdoData->IdleIrpList)) {
611 NT_ASSERT(fdoData->IdleIoCount == 0);
612 }
613 InsertTailList(&fdoData->IdleIrpList, &Irp->Tail.Overlay.ListEntry);
614
615
616 fdoData->IdleIoCount++;
617 if (!fdoData->IdleTimerStarted) {
618 ClasspStartIdleTimer(fdoData);
619 }
620
621 if (fdoData->IdleIoCount != 1) {
622 issueRequest = FALSE;
623 }
624
625
626 KeReleaseSpinLock(&fdoData->IdleListLock, oldIrql);
627
628 if (issueRequest) {
629 ClasspServiceIdleRequest(fdoExtension, FALSE);
630 }
631
632 return STATUS_PENDING;
633}
634
635/*++
636
637ClasspDequeueIdleRequest
638
639Routine Description:
640
641 This function will remove the next idle request from the list.
642 If there are no requests in the queue, then it will return NULL.
643
644Arguments:
645
646 FdoExtension - Pointer to the functional device extension
647
648Return Value:
649
650 Pointer to removed IRP
651
652--*/
653PIRP
656 )
657{
658 PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
659 PLIST_ENTRY listEntry = NULL;
660 PIRP irp = NULL;
661 KIRQL oldIrql;
662
663 KeAcquireSpinLock(&fdoData->IdleListLock, &oldIrql);
664
665 if (fdoData->IdleIoCount > 0) {
666 listEntry = RemoveHeadList(&fdoData->IdleIrpList);
667 //
668 // Make sure we actaully removed a request from the list
669 //
670 NT_ASSERT(listEntry != &fdoData->IdleIrpList);
671 //
672 // Decrement the idle I/O count.
673 //
674 fdoData->IdleIoCount--;
675 //
676 // Stop the timer on last request
677 //
678 if (fdoData->IdleIoCount == 0) {
679 ClasspStopIdleTimer(fdoData);
680 }
681 irp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
682 NT_ASSERT(irp->Type == IO_TYPE_IRP);
683
684
685 InitializeListHead(&irp->Tail.Overlay.ListEntry);
686 }
687
688 KeReleaseSpinLock(&fdoData->IdleListLock, oldIrql);
689
690
691 return irp;
692}
693
694/*++
695
696ClasspCompleteIdleRequest
697
698Routine Description:
699
700 This function will be called every time an idle request is completed.
701 This will call ClasspServiceIdleRequest to process any other pending idle requests.
702
703Arguments:
704
705 FdoExtension - Pointer to the device extension
706
707Return Value:
708
709 None
710
711--*/
712VOID
715 )
716{
717 PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
718
719 //
720 // Issue the next idle request if there are any left in the queue, there are
721 // no non-idle requests outstanding, there are less than max idle requests
722 // outstanding, and it has been long enough since the completion of the last
723 // non-idle request.
724 //
725 if ((fdoData->IdleIoCount > 0) &&
726 (fdoData->ActiveIdleIoCount < fdoData->IdleActiveIoMax) &&
727 (fdoData->ActiveIoCount <= 0) &&
729 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspCompleteIdleRequest: Service next idle reqeusts\n"));
731 }
732
733 return;
734}
735
736/*++
737
738ClasspServiceIdleRequest
739
740Routine Description:
741
742 Remove the next pending idle request from the queue and process it.
743 If a request was removed then it will be processed otherwise it will
744 just return.
745
746Arguments:
747
748 FdoExtension - Pointer to the device extension
749 PostToDpc - Flag to pass to ServiceTransferRequest to indicate if request must be posted to a DPC
750
751Return Value:
752
753 None
754
755--*/
756VOID
759 BOOLEAN PostToDpc
760 )
761{
762 PIRP irp;
763
765 if (irp != NULL) {
766 ServiceTransferRequest(FdoExtension->DeviceObject, irp, PostToDpc);
767 }
768 return;
769}
770
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define CLASSP_REG_SUBKEY_NAME
Definition: cdromp.h:120
PLIST_ENTRY ListEntry()
Definition: fxirpum.cpp:535
#define CLASSP_REG_IDLE_ACTIVE_MAX
Definition: classp.h:120
FORCEINLINE ULONGLONG ClasspTimeDiffToMs(ULONGLONG TimeDiff)
Definition: classp.h:1297
FORCEINLINE LARGE_INTEGER ClasspGetCurrentTime(VOID)
Definition: classp.h:1280
#define CLASSP_REG_IDLE_INTERVAL_NAME
Definition: classp.h:119
#define CLASS_IDLE_INTERVAL
Definition: classp.h:1199
#define CLASS_STARVATION_INTERVAL
Definition: classp.h:1200
#define CLASS_IDLE_INTERVAL_MIN
Definition: classp.h:1198
#define CLASSP_REG_IDLE_PRIORITY_SUPPORTED
Definition: classp.h:121
VOID ClasspStartIdleTimer(IN PCLASS_PRIVATE_FDO_DATA FdoData)
Definition: clntirp.c:261
PIRP DequeueDeferredClientIrp(PDEVICE_OBJECT Fdo)
Definition: clntirp.c:113
PIRP ClasspDequeueIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:654
VOID ClasspStopIdleTimer(PCLASS_PRIVATE_FDO_DATA FdoData)
Definition: clntirp.c:316
VOID ClasspInitializeIdleTimer(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:175
VOID ClasspServiceIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN PostToDpc)
Definition: clntirp.c:757
ULONGLONG ClasspGetIdleTime(IN PCLASS_PRIVATE_FDO_DATA FdoData, IN LARGE_INTEGER CurrentTime)
Definition: clntirp.c:351
VOID EnqueueDeferredClientIrp(PDEVICE_OBJECT Fdo, PIRP Irp)
Definition: clntirp.c:78
VOID ClasspCompleteIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:713
KDEFERRED_ROUTINE ClasspIdleTimerDpc
Definition: clntirp.c:42
NTSTATUS ClasspEnqueueIdleRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: clntirp.c:576
LOGICAL ClasspIdleDurationSufficient(IN PCLASS_PRIVATE_FDO_DATA FdoData, OUT LARGE_INTEGER **CurrentTimeIn)
Definition: clntirp.c:406
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
Definition: class.c:3341
@ FdoExtension
Definition: precomp.h:48
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
FxIrp * irp
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define USHORT_MAX
Definition: intsafe.h:147
IoMarkIrpPending(Irp)
#define min(a, b)
Definition: monoChain.cc:55
#define Int32x32To64(a, b)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_PENDING
Definition: ntstatus.h:82
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
LARGE_INTEGER AntiStarvationStartTime
Definition: classp.h:930
LIST_ENTRY IdleIrpList
Definition: classp.h:882
BOOLEAN IdlePrioritySupported
Definition: classp.h:808
KSPIN_LOCK IdleListLock
Definition: classp.h:877
LIST_ENTRY DeferredClientIrpList
Definition: classp.h:777
USHORT StarvationDuration
Definition: classp.h:915
KSPIN_LOCK SpinLock
Definition: classp.h:795
Definition: ketypes.h:699
Definition: typedefs.h:120
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
#define IO_TYPE_IRP
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
#define NT_ASSERT
Definition: rtlfuncs.h:3310