ReactOS 0.4.15-dev-7953-g1f49173
fxrequest.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxRequest.cpp
8
9Abstract:
10
11 This module implements FxRequest object
12
13Author:
14
15
16
17Environment:
18
19 Both kernel and user mode
20
21Revision History:
22
23
24--*/
25
26#include "coreprivshared.hpp"
27
28// Tracing support
29extern "C" {
30// #include "FxRequest.tmh"
31}
32
34 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
38 __in USHORT ObjectSize
39 ) :
40 FxRequestBase(FxDriverGlobals,
41 ObjectSize,
42 Irp,
43 Ownership,
44 Caller)
45{
49
51
55
61}
62
63#if DBG
64FxRequest::~FxRequest(
65 VOID
66 )
67{
70}
71#endif // DBG
72
80 )
81/*++
82
83Routine Description:
84
85 Creates an FxRequest object and returns its pointer to the caller.
86
87Arguments:
88
89 Device - Pointer to FxDevice object request will be associated with
90
91 RequestAttributes - Specifies the object's attributes for the request.
92
93 Irp - Pointer to Irp
94
95 Request - Pointer to location to store the returned FxRequest pointer
96
97Return Value:
98
99 NTSTATUS
100
101--*/
102{
105
106 *Request = NULL;
107
108 //
109 // Allocate the new FxRequest object in the per driver tracking pool
110 //
112
113 if (pRequest == NULL) {
115 Device->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGREQUEST,
116 "Memory allocation failed %!STATUS!",
119 }
120
121 //
122 // For forward progress the IRP can be NULL.
123 //
124 if (Irp != NULL) {
125 pRequest->AssignMemoryBuffers(Device->GetIoTypeForReadWriteBufferAccess());
126 }
127
128 //
129 // Improve I/O perf by not parenting it to device. However, if verifier is
130 // turned on, the request is parented to the device to help track reference
131 // leaks.
132 //
133 if (Device->GetDriverGlobals()->FxRequestParentOptimizationOn) {
135 NULL,
136 NULL,
137 FALSE);
138 }
139 else {
141 NULL,
142 Device,
143 FALSE);
144 }
145
146 if (NT_SUCCESS(status)) {
147 *Request = pRequest;
148 }
149 else {
151 Device->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGREQUEST,
152 "Could not commit FxRequest %!STATUS!", status);
154 }
155
156 return status;
157}
158
162 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
166 __in FxRequestIrpOwnership Ownership,
169 )
170{
171 WDFOBJECT hRequest;
174
175 *Request = NULL;
176
178 if (!NT_SUCCESS(status)) {
179 return status;
180 }
181
182 pRequest = new (FxDriverGlobals, RequestAttributes)
183 FxRequest(FxDriverGlobals,
184 Irp,
185 Ownership,
186 Caller,
187 sizeof(FxRequest));
188
189 if (pRequest != NULL) {
190 if (Target != NULL) {
192 }
193
194 if (NT_SUCCESS(status)) {
196 }
197
198 if (NT_SUCCESS(status)) {
199 *Request = pRequest;
200 }
201 else {
203 "Handle create failed %!STATUS!", status);
204
205 if (Irp != NULL) {
206 //
207 // Clear the irp out of the request so that the destructor does
208 // not free it. Since we are returning failure, the caller does
209 // not expect the PIRP passed in to be freed.
210 //
212 }
213
215 }
216 }
217 else {
219 }
220
222 "Irp %p Ownership %!FxRequestIrpOwnership! FxRequest %p, status %!STATUS!",
223 Irp, Ownership, *Request, status);
224
225 return status;
226}
227
231 )
232/*++
233
234Routine Description:
235
236 Set the IRP's IoStatus.Information field.
237
238 NOTE: If the caller calls Complete(status, information), as opposed
239 to Complete(status), the value will get overwritten.
240
241Arguments:
242
243 Information - Information value to set
244
245Returns:
246
247 NTSTATUS
248
249--*/
250{
252
254
257 KIRQL irql;
258
259 Lock(&irql);
260
261 status = VerifyRequestIsNotCompleted(pFxDriverGlobals);
262 if (NT_SUCCESS(status)) {
264 }
265
266 Unlock(irql);
267
268 return status;
269 }
270 else {
272 return STATUS_SUCCESS;
273 }
274}
275
278 VOID
279 )
280/*++
281
282Routine Description:
283
284 Get the IRP's IoStatus.Information field.
285
286
287Arguments:
288
289 None
290
291Returns:
292
293 ULONG_PTR
294
295--*/
296{
298
300
301 // Verifier
304 KIRQL irql;
306
307 Lock(&irql);
308
309 status = VerifyRequestIsNotCompleted(pFxDriverGlobals);
310 if (!NT_SUCCESS(status)) {
311 info = NULL;
312 }
313 else {
315 }
316
317 Unlock(irql);
318
319 return info;
320 }
321 else {
322 return m_Irp.GetInformation();
323 }
324}
325
328 VOID
329 )
330/*++
331
332Routine Description:
333 Get the Irp->RequestorMode value.
334
335Arguments:
336 None
337
338Returns:
339 KPROCESSOR_MODE
340
341--*/
342{
344
346
349 KIRQL irql;
351
352 Lock(&irql);
353
354 status = VerifyRequestIsNotCompleted(pFxDriverGlobals);
355 if (!NT_SUCCESS(status)) {
356 mode = UserMode;
357 } else {
359 }
360
361 Unlock(irql);
362
363 return mode;
364 }
365 else {
366 return m_Irp.GetRequestorMode();
367 }
368}
369
370
371VOID
372FX_VF_METHOD(FxRequest, VerifyCompleteInternal)(
373 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
375 )
376{
377 UNREFERENCED_PARAMETER(FxDriverGlobals);
381
383
384 Lock(&irql);
385
386 if (GetDriverGlobals()->FxVerifierIO ) {
387 (VOID) VerifyRequestIsNotCompleted(GetDriverGlobals());
388 } else {
390 }
391
392
393 if ((m_VerifierFlags & FXREQUEST_FLAG_DRIVER_CANCELABLE) &&
394 (m_VerifierFlags & FXREQUEST_FLAG_CANCELLED) == 0x0) {
395
396 //
397 // We could trace each sentence separate, but that takes up valuable
398 // room in the IFR. Instead, trace the entire "paragraph" as one
399 // message so that we have more room in the IFR.
400 //
402 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGREQUEST,
403 "Completing Cancelable WDFREQUEST %p. "
404
405 "This results in a race condition in the device driver that can "
406 "cause double completions. "
407
408 "Call WdfRequestUnmarkCancelable before WdfRequestComplete. "
409
410 "If WdfRequestUnmarkCancelable returns STATUS_CANCELLED, "
411 "do not complete the request until the EvtIoCancel handler is called. "
412
413 "The straightforward way to ensure this is to complete a canceled "
414 "request from the EvIoCancel callback.",
415
416 GetHandle()
417 );
418
419 FxVerifierDbgBreakPoint(GetDriverGlobals());
420
421 }
422
424 length = 0;
425
426 switch (m_Irp.GetMajorFunction()) {
427 case IRP_MJ_READ:
428 length = m_Irp.GetParameterReadLength();
430 break;
431
432 case IRP_MJ_WRITE:
433 length = m_Irp.GetParameterWriteLength();
435 break;
436
438 if (m_Irp.GetRequestorMode() == UserMode) {
439 length = m_Irp.GetParameterIoctlOutputBufferLength();
440
441 if (length > 0) {
443 }
444 else {
445 //
446 // For an output length == 0, a driver can indicate the number
447 // of bytes used of the input buffer.
448 //
449 DO_NOTHING();
450 }
451 }
452 else {
453 //
454 // If the IOCTL came from kernel mode, the same reasoning applies
455 // here as for an internal IOCTL...we don't know deterministically
456 // how to find the output buffer length.
457 //
458 DO_NOTHING();
459 }
460 break;
461
463 //
464 // Because the current stack location can use any part of the union
465 // (like Parameters.Others instead of Parameters.DeviceIoControl), we
466 // cannot deterministically figure out the output buffer length for
467 // internal IOCTLs.
468 //
469 // || || Fall through || ||
470 // \/ \/ \/ \/
471 default:
472 DO_NOTHING();
473 }
474
475 //
476 // We shouldn't validate the information field if the status is warning
477 // because it's valid for a driver to fill partial data in the buffer
478 // and ask for large buffer size.
479 //
482 m_Irp.GetInformation() > length) {
483
485
487 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGREQUEST,
488 "WDFREQUEST %p, MJ 0x%x, Information 0x%I64x is greater then "
489 "buffer length 0x%x", GetHandle(), m_Irp.GetMajorFunction(),
490 m_Irp.GetInformation(), length);
491
492 data.Request = GetHandle();
493 data.Irp = reinterpret_cast<PIRP>(m_Irp.GetIrp());
494 data.OutputBufferLength = length;
495 data.Information = m_Irp.GetInformation();
496 data.MajorFunction = m_Irp.GetMajorFunction();
497
499 GetDriverGlobals(),
502 (ULONG_PTR) &data
503 );
504
505 // will not get here
506 }
507
508 // Set IRP to NULL when NT IRP is completed
510
512}
513
517 )
518
519/*++
520
521Routine Description:
522
523 Internal worker to complete the current request object.
524
525 This is called with the FxRequest object lock held, and
526 state validation as far as IRP completion already done.
527
528 Callers must use Complete(Status), or Complete(Status,Information)
529
530 It returns with the FxRequest object locked *released*
531
532Arguments:
533
534 Status - Status to complete the request with
535
536Returns:
537
538 NTSTATUS
539
540--*/
541
542{
544 MdIrp pIrp;
547 CfxDevice* pRefedDevice;
548
550 queue = NULL;
551 //
552 // Store off the irp into a local variable
553 //
554 pIrp = m_Irp.GetIrp();
555
556 //
557 // Lock is no longer required, since it's only used
558 // by verifier for already completed requests. This is a
559 // serious driver error anyway
560 //
561
562
563 VerifyCompleteInternal(pFxDriverGlobals, Status);
564
566 //
567 // No lock needed in non-verifier case since this is only
568 // used to detect double completions with verifier on
569 //
572 }
573
574
575
576
577
578
579#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
580
581
582
583
584
585
586
587 ULONG flagsMasked = m_Irp.GetFlags() & IRP_INPUT_OPERATION;
592 (flagsMasked != 0)) {
593
596 "Driver that handled WDFREQUEST 0x%p is requesting data to "
597 " be written back to the UserBuffer by returing a non zero value "
598 " in the Irp 0x%p Information field even though the OutputBufferLength "
599 " is zero", GetObjectHandle(), pIrp);
600
601 //
602 // We will assert only if the Information field is not zero to warn
603 // the developer that it's a bad thing to do. However, we do avoid
604 // corruption of UserBuffer on completion by clearing the flag
605 // erroneously set by the I/O manager.
606 //
607 if (m_Irp.GetInformation() != 0L) {
609 }
610
611 //
612 // Clear the flag to prevent the I/O manager from coping the
613 // data back from the SystemBuffer to Irp->UserBuffer
614 //
616 }
617#endif
618
619 //
620 // If the status code is one of the framework facility codes,
621 // map it to a standard NTSTATUS
622 //
623
624
625 if ((Status & 0x0FFF0000) == (FACILITY_DRIVER_FRAMEWORK << 16)) {
628 "Converting WDF NTSTATUS value 0x%x...", Status);
629
630 switch (Status) {
632 case STATUS_WDF_BUSY:
634 break;
635
638 break;
639
642 break;
643
644 default:
647 "Unknown WDF NTSTATUS 0x%x", Status);
649 break;
650 }
651
653 "... to %!STATUS!", Status);
654 }
655
656 if (IsAllocatedFromIo() == FALSE && IsCanComplete() == FALSE) {
658 }
659
660 //
661 // It is invalid to complete any requests on an IRPQUEUE
662 //
663 ASSERTMSG("WDFREQUEST is part of a WDFQUEUE, it could be Cancellable\n",
664 (m_IrpQueue == NULL));
665
668
669 //
670 // Some I/O request cleanup. Do not do this for driver created requests.
671 //
672 if (IsAllocatedFromIo()) {
673 //
674 // Set the completion state to none
675 //
677
678 if (IsReserved() == FALSE) {
679 //
680 // Don't set the Queue to NULL for reserved requests.
681 //
682 m_IoQueue = NULL;
683 }
684 }
685
686 //
687 // IMPORTANT: the context must free its references before the request is
688 // completed. Any of these references could be on a memory interface that is
689 // an embedded interface in this object. If this reference
690 // is left outstanding when we check m_IrpReferenceCount below, we would
691 // bugcheck (and the driver writer would be unaware of why things are going
692 // wrong).
693 //
694 // Also, if the driver is freeing the referenced mmemory interface in its
695 // cleanup routine, we don't want an oustanding reference against it.
696 //
697 if (m_RequestContext != NULL) {
698 //
699 // m_RequestContext will be freed when the FxRequest's desctructor runs
700 //
702 }
703
704 //
705 // If the request is not presented to the driver then clear the
706 // cleanup & destroy callbacks before calling PerformEarlyDispose.
707 //
708 if (m_Presented == FALSE) {
710 }
711
712 if (IsReserved() == FALSE && IsAllocatedFromIo()) {
713 //
714 // Fire the driver supplied Cleanup callback if set
715 //
716 // This will allow the driver to release any IRP specific resources such
717 // as MDLs before we complete the IRP back to the OS, and release the
718 // process/thread reference.
719 //
720 // This is also the callback used to tell the driver the WDM IRP is going
721 // away if it has used the WDM "escape" API's to either get the IRP, or
722 // any resources it references.
723 //
724
725 //
726 // If a cleanup callback has been registered, we call it
727 // just before completing the IRP to WDM, which can cause any
728 // associated buffers, MDLs, or memory interfaces to be invalidated.
729 //
730 if (EarlyDispose() == FALSE) {
731 VerifierBreakpoint_RequestEarlyDisposeDeferred(GetDriverGlobals());
732 }
733
734 //
735 // Now that the entire tree is disposed, we want to destroy all of the
736 // children. This will not put this object in the destroyed state. For
737 // m_IrpReferenceCount to go to zero, we need to destroy the child WDFMEMORYs
738 // that were created when we probed and locked the buffers.
739 //
741 }
742 else {
743 //
744 // We don't call cleanup callback for Reserved Requests.
745 // The driver can perform any cleanp it wants before completing the Request
746 // or before reusing the Reserved Request in its Dispatch callback.
747
748
749
750
751
752
753 DO_NOTHING();
754 }
755
756 //
757 // If this is non-zero, indicates a reference count problem on any
758 // WDFMEMORY objects returned to the device driver from this WDFREQUEST.
759 //
760 if (m_IrpReferenceCount != 0) {
761 //
762 // NOTE: you cannot call GetBuffer or GetMdl
765 "WDFREQUEST 0x%p, PIRP 0x%p, Major Function 0x%x, completed with "
766 "outstanding references on WDFMEMORY 0x%p or 0x%p retrieved from "
767 "this request",
775 );
776
781 "WDFMEMORY 0x%p, buffer %p, PMDL %p, length %I64d bytes",
784 }
785
790 "IOCTL output WDFMEMORY 0x%p, buffer %p, PMDL %p, length %I64d bytes",
793 }
794
799 }
800
801 FxIrp irp(pIrp);
802
803 //
804 // Complete the NT IRP through the frameworks FxIrp
805 //
807
809
810 //
811 // For driver created requests we need to use two phase
812 // completion (pre and post) to detach the request from the queue before the
813 // IRP is completed, and then allow a new request to be dispatched.
814 // Note that the IRP is actually completed when the reference on this object
815 // goes to 1 (See FxRequest::Release() for more info).
816 //
817 if (IsAllocatedFromIo() == FALSE) {
818 //
819 // Do not touch the request after this call.
820 // Do not clear the request's IRP field before making this call.
821 //
823 }
824 else {
825 //
826 // We only clear the irp from this object after PerformEarlyDispose has been
827 // called. m_SystemBuffer and m_OutputBuffer use m_Irp to return their
828 // buffers and their WDFMEMORY handles should be valid in the cleanup routine
829 // for the WDFREQUEST. We also keep m_Irp valid until after the
830 // m_IrpReferenceCount check, so we can trace out the buffers in case of
831 // error.
832 //
834
836 //
837 // If this is the last handle to be closed on the device, then the call
838 // to CreateCompleted can cause the device to be deleted if the create
839 // has failed. We add a reference so that we make sure we have a device
840 // to free the request memory back to.
841 //
842 pRefedDevice = GetDevice();
843 pRefedDevice->ADDREF(&irp);
844
845 pRefedDevice->m_PkgGeneral->CreateCompleted(&irp);
846 }
847 else {
848 pRefedDevice = NULL;
849 }
850
851 //
852 // WDM IRP is completed.
853 //
855
856 if (IsReserved() == FALSE) {
858 }
859 else {
861 }
862
863 if (pRefedDevice != NULL) {
864 pRefedDevice->RELEASE(&irp);
865 pRefedDevice = NULL;
866 }
867 }
868
869 return Status;
870}
871
872
873VOID
877 )
878{
879 //
880 // Fire frameworks internal callback event if one is set
881 // (FxIoQueue or IoTarget's internal use)
882 //
884 //
885 // NOTE: This occurs after the IRP has already been released,
886 // and is only used for notification that the request
887 // has completed.
888 //
890 GetDevice()->m_PkgIo->RequestCompletedCallback(this);
891 }
892 else {
893 ASSERT(Queue != NULL);
894 Queue->RequestCompletedCallback(this);
895 //FxIoQueueToMx::RequestCompletedCallback(Queue, this);
896 }
897
898 //
899 // DeleteObject will dereference the object reference taken when the callback
900 // was registered
901 //
903 }
904 else {
905 //
906 // Caller still wants the FxRequest class to be valid on return,
907 // but must call DeleteObject in order to ensure the object is
908 // no longer assigned any child objects, etc.
909 //
911 DeleteObject();
912 }
913}
914
915VOID
919 )
920{
921 //
922 // Fire frameworks internal callback event if one is set
923 // (FxIoQueue or IoTarget's internal use)
924 //
926 //
927 // NOTE: This occurs after the IRP has already been released,
928 // and is only used for notification that the request
929 // has completed.
930 //
932 GetDevice()->m_PkgIo->RequestCompletedCallback(this);
933 }
934 else {
936 Queue->RequestCompletedCallback(this);
937 }
938 }
939 else {
940 //
941 // Caller still wants the FxRequest class to be valid on return,
942 // but must call DeleteObject in order to ensure the object is
943 // no longer assigned any child objects, etc.
944 //
946 }
947
949}
950
951//
952// Handles pre-process completion for driver-created-requests queued by the driver.
953//
954VOID
958 )
959{
962 //
963 // Fire frameworks internal callback (pre) event if one is set.
964 //
966 //
967 // NOTE: This occurs before the IRP has already been released,
968 // and is only used to notify the queue to remove this request from this queue's
969 // internal lists. A second notification (lPostProcessCompletionForAllocatedDriver)
970 // is made after the IRP is completed.
971 //
972 Queue->PreRequestCompletedCallback(this);
973 }
974 else if (Queue != NULL){
975 //
976 // On return from PostProcessCompletionForDriverRequest, caller (framework)
977 // will try to release the last ref. Increase the ref count so request stays alive until
978 // driver invokes WdfObjectDelete on this request.
979 //
981 }
982
983 //
984 // Let the system know that it is OK to complete this request.
985 //
987}
988
989//
990// Handles post-process completion for driver-created-requests queued by the driver.
991// On return the driver can delete the request with WdfObjectDelete.
992// NOTE: request may be already gone/reused. Do not dereference this or access any of its
993// members... its pointer is only used for logging.
994//
995VOID
999 )
1000{
1001 //
1002 // NOTE: Do not touch the request object here. The request object may already be
1003 // re-used or deleted.
1004 //
1005
1008 //
1009 // Fire frameworks internal callback (post) event if one is set.
1010 //
1012 //
1013 // NOTE: This occurs after the IRP has already been released, and is only used
1014 // to notify the queue to update its internal state and if appropriate, send
1015 // another request.
1016 //
1017 Queue->PostRequestCompletedCallback(this);
1018 }
1019}
1020
1021VOID
1023 VOID
1024 )
1025/*++
1026
1027Routine Description:
1028
1029 This routine is called to free a reserved request or in case of Fxpkgio
1030 a non-reserved request.
1031
1032--*/
1033{
1034 //
1035 // Restore any fields if necessary
1036 //
1037 if (m_RequestContext != NULL) {
1038 //
1039 // m_RequestContext will be freed when the FxRequest's destructor runs
1040 //
1042 }
1043
1044 //
1045 // If the request is not presented to the driver then clear the
1046 // cleanup & destroy callbacks before calling PerformEarlyDispose.
1047 //
1048 if (m_Presented == FALSE) {
1050 }
1051
1052 DeleteObject();
1053}
1054
1055VOID
1056FX_VF_METHOD(FxRequest, VerifyPreProcessSendAndForget) (
1057 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
1058 )
1059{
1061
1062 if (m_CompletionRoutine.m_Completion != NULL) {
1064 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
1065 "WDFREQUEST %p cannot send and forget will not execute completion "
1066 "routine %p",
1067 GetHandle(), m_CompletionRoutine.m_Completion);
1068
1069 FxVerifierDbgBreakPoint(FxDriverGlobals);
1070
1071
1072
1073
1074
1075
1076
1077
1078 }
1079
1080 //
1081 // You cannot fire and forget a create irp if we created a WDFFILEOBJECT
1082 // for it since you must post process the status of the create because
1083 // the create can fail in the driver to which we are sending the irp.
1084 //
1085 if ((m_Irp.GetMajorFunction() == IRP_MJ_CREATE)
1086 &&
1087 (FxFileObjectClassNormalize(GetDevice()->GetFileObjectClass()) !=
1089
1091 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
1092 "WDFREQUEST %p cannot send and forget a create request which "
1093 "has a WDFFILEOBJECT created for it, it must have a completion "
1094 "routine and be post processsed", GetHandle());
1095
1096 FxVerifierDbgBreakPoint(FxDriverGlobals);
1097 }
1098}
1099
1100VOID
1102 VOID
1103 )
1104{
1105 VerifyPreProcessSendAndForget(GetDriverGlobals());
1106
1107 //
1108 // To be sent and forgotten, the irp must have been presented
1109 //
1111
1112 //
1113 // To be sent and forgotten, the irp must not have a formatted IO context.
1114 //
1115 ASSERT(HasContext() == FALSE);
1116
1117 //
1118 // If the driver writer setup the next stack location using the current
1119 // stack location or did a manual IO_STACK_LOCATION copy, we do not want to
1120 // skip the current stack location that their format is used by the target
1121 // driver.
1122 //
1125 }
1126
1127 if (IsReserved() == FALSE) {
1128
1129 //
1130 // If a cleanup callback has been registered, we call it
1131 // just before sending the IRP on its way. The contract is that the cleanup
1132 // routine for a WDFREQUEST is called while the PIRP is still valid.
1133 //
1134 if (EarlyDispose() == FALSE) {
1135 VerifierBreakpoint_RequestEarlyDisposeDeferred(GetDriverGlobals());
1136 }
1137
1138 //
1139 // Now that the entire tree is disposed, we want to destroy all of the
1140 // children. This will not put this object in the destroyed state. For
1141 // m_IrpReferenceCount to go to zero, we need to destroy the child WDFMEMORYs
1142 // that were created when we probed and locked the buffers.
1143 //
1145 }
1146}
1147
1148VOID
1150 VOID
1151 )
1152{
1155
1156 m_Irp.SetIrp(NULL);
1157
1158 //
1159 // Capture the m_IoQueue value before making any other calls.
1160 // Note: m_IoQueue could be NULL if the request is freed before it's queued.
1161 //
1162 pQueue = m_IoQueue;
1163
1165
1168
1169 //
1170 // Technically we did not complete the irp, but a send and forget is
1171 // functionally the same. We no longer own the irp.
1172 //
1173 if (IsReserved() == FALSE) {
1175 }
1176 else {
1177 //
1178 // Release checks m_Completed flag to decide whether to return
1179 // the request to reserved pool.
1180 //
1181 m_Completed = TRUE;
1183 }
1184}
1185
1188 VOID
1189 )
1190{
1193
1195
1197 KIRQL irql;
1198
1199 Lock(&irql);
1200
1201
1202
1203
1204
1205
1206
1207
1209
1210 Unlock(irql);
1211
1212 return status;
1213 }
1214 else {
1215 return m_Irp.GetStatus();
1216 }
1217}
1218
1223 )
1224{
1226
1228
1229 //
1230 // No lock needed. Only reason this may be invalid is due
1231 // to previous completion, which is a serious driver bug
1232 // that will result in a crash anyway.
1233 //
1234
1236 KIRQL irql;
1238
1239 Lock(&irql);
1240
1241 status = VerifyRequestIsCurrentStackValid(pFxDriverGlobals);
1242 if (NT_SUCCESS(status)) {
1243 status = VerifyRequestIsNotCompleted(pFxDriverGlobals);
1244 }
1245
1246 Unlock(irql);
1247
1248 if (!NT_SUCCESS(status)) {
1249 return status;
1250 }
1251 }
1252
1253 ASSERT(Parameters->Size >= sizeof(WDF_REQUEST_PARAMETERS));
1254
1255 // How much we copied
1256 Parameters->Size = sizeof(WDF_REQUEST_PARAMETERS);
1257
1258
1259 // Copy parameters
1261 Parameters->MinorFunction = m_Irp.GetMinorFunction();
1262
1263 // Copy the Parameters structure which we are a subset of
1265
1267 //
1268 // If verifier is on, and the operation is an IRP_MJ_DEVICE_CONTROL
1269 // with METHOD_NEITHER, then set Type3InputBuffer to zero since
1270 // this should not be used to pass parameters in the normal path
1271 //
1274 Parameters->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
1275 }
1276 }
1277
1278 return STATUS_SUCCESS;
1279}
1280
1281
1287 __out size_t* Length
1288 )
1289{
1290 PMDL pMdl;
1292 ULONG length;
1293 KIRQL irql;
1294 BOOLEAN mapMdl;
1296
1298 length = 0x0;
1299 mapMdl = FALSE;
1302
1303
1304 //
1305 // Verifier
1306 //
1307 if (GetDriverGlobals()->FxVerifierIO) {
1308 status = VerifyRequestIsNotCompleted(GetDriverGlobals());
1309 if (!NT_SUCCESS(status)) {
1310 goto Done;
1311 }
1313 &&
1316 &&
1317 GetDevice()->GetIoType() == WdfDeviceIoNeither) {
1319
1322 "Attempt to get UserMode Buffer Pointer for WDFDEVICE 0x%p, "
1323 "WDFREQUEST 0x%p, %!STATUS!",
1325
1328 "Driver must use buffered or direct I/O for this call, or use "
1329 "WdfDeviceInitSetIoInCallerContextCallback to probe and lock "
1330 "user mode memory");
1331
1333 }
1334 }
1335
1337 Lock(&irql);
1338 }
1339
1340 //
1341 // We must dig into the IRP to get the buffer, length, and readonly status
1342 //
1343
1344 switch (majorFunction) {
1348
1349 if (length == 0) {
1351
1354 "WDFREQUEST %p InputBufferLength length is zero, %!STATUS!",
1356
1357 goto Done;
1358 }
1359
1361 //
1362 // Internal device controls are kernel mode to kernel mode, and deal
1363 // with direct unmapped pointers.
1364 //
1365 // In addition, a normal device control with
1366 // RequestorMode == KernelMode is also treated as kernel mode
1367 // to kernel mode since the I/O Manager will not generate requests
1368 // with this setting from a user mode request.
1369 //
1370 if ((m_Irp.GetRequestorMode() == KernelMode) ||
1372 DO_NOTHING();
1373 }
1374 else {
1376
1379 "Attempt to get UserMode Buffer Pointer for METHOD_NEITHER "
1380 "DeviceControl 0x%x, WDFDEVICE 0x%p, WDFREQUEST 0x%p, "
1381 "%!STATUS!",
1384
1387 "Driver must use METHOD_BUFFERED or METHOD_xx_DIRECT I/O for "
1388 "this call, or use WdfDeviceInitSetIoInCallerContextCallback to "
1389 "probe and lock user mode memory %!STATUS!",
1391
1392 goto Done;
1393 }
1394 }
1395 break;
1396
1397 case IRP_MJ_READ:
1399
1400 if (GetDevice()->GetIoTypeForReadWriteBufferAccess() == WdfDeviceIoDirect) {
1402 mapMdl = TRUE;
1403 }
1404 break;
1405
1406 case IRP_MJ_WRITE:
1408
1409 if (GetDevice()->GetIoTypeForReadWriteBufferAccess() == WdfDeviceIoDirect) {
1411 mapMdl = TRUE;
1412 }
1413 break;
1414
1415 default:
1418 "Unrecognized Major Function 0x%x on WDFDEVICE 0x%p WDFREQUEST 0x%p",
1420
1422
1424 goto Done;
1425 }
1426
1427 if (length == 0) {
1429
1432 "WDFREQUEST 0x%p length is zero, %!STATUS!",
1433 GetHandle(), status);
1434
1435 goto Done;
1436 }
1437
1438 //
1439 // See if we need to map
1440 //
1441 if (mapMdl && (m_RequestBaseFlags & FxRequestBaseSystemMdlMapped) == 0x00) {
1442 pMdl = m_Irp.GetMdl();
1443
1444 if (pMdl == NULL) {
1445 //
1446 // Zero length transfer
1447 //
1449
1452 "WDFREQUEST 0x%p, direct io device, PMDL is NULL, "
1453 "%!STATUS!", GetHandle(), status);
1454
1455 ASSERT(length == 0);
1456 }
1457 else {
1458 PVOID pVA;
1459
1460 //
1461 // PagePriority may need to be a property, and/or parameter to
1462 // this call
1463 //
1464 //
1465 // Upon success, MmGetSystemAddressForMdlSafe stores the mapped
1466 // VA pointer in the pMdl and upon subsequent calls to
1467 // MmGetSystemAddressForMdlSafe, no mapping is done, just
1468 // the stored VA is returned. FxRequestSystemBuffer relies
1469 // on this behavior and, more importantly, relies on this function
1470 // to do the initial mapping so that FxRequestSystemBuffer::GetBuffer()
1471 // will not return a NULL pointer.
1472 //
1474
1475 if (pVA == NULL) {
1477
1480 "WDFREQUEST 0x%p could not get a system address for PMDL "
1481 "0x%p, %!STATUS!", GetHandle(), pMdl, status);
1482 }
1483 else {
1484 //
1485 // System will automatically release the mapping PTE's when
1486 // the MDL is released by the I/O request
1487 //
1488
1489
1490
1491
1492
1494
1496 }
1497 }
1498 }
1499
1500Done:
1502 Unlock(irql);
1503 }
1504
1505 if (NT_SUCCESS(status)) {
1507
1508 if (mapMdl) {
1511 }
1512 else {
1514 }
1515
1516 *Length = length;
1517 }
1518
1519 return status;
1520}
1521
1527 __out size_t* Length
1528 )
1529/*++
1530
1531Routine Description:
1532
1533 Return the IRP_MJ_DEVICE_CONTROL OutputBuffer.
1534
1535 The memory buffer is valid in any thread/process context,
1536 and may be accessed at IRQL > PASSIVE_LEVEL.
1537
1538 The memory buffer is automatically released when the request
1539 is completed.
1540
1541 The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
1542 or for any request other than IRP_MJ_DEVICE_CONTROL.
1543
1544 The Memory buffer is as follows for each buffering mode:
1545
1546 METHOD_BUFFERED:
1547
1548 Irp->UserBuffer // This is actually a system address
1549
1550 METHOD_IN_DIRECT:
1551
1552 MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
1553
1554 METHOD_OUT_DIRECT:
1555
1556 MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
1557
1558 METHOD_NEITHER:
1559
1560 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
1561 to access the request in the calling threads address space before
1562 it is placed into any I/O Queues.
1563
1564 The buffer is only valid until the request is completed.
1565
1566Arguments:
1567
1568 MemoryObject - Pointer location to return the memory object interface.
1569
1570 Buffer - Pointer location to return buffer ptr
1571
1572 Length - Pointer location to return buffer length.
1573
1574Returns:
1575
1576 NTSTATUS
1577
1578--*/
1579{
1580 size_t length;
1582 KIRQL irql;
1583 BOOLEAN mapMdl;
1585
1588
1590 length = 0;
1592 mapMdl = FALSE;
1593
1594 //
1595 // Verifier
1596 //
1597 if (GetDriverGlobals()->FxVerifierIO ) {
1598 status = VerifyRequestIsNotCompleted(GetDriverGlobals());
1599 if (!NT_SUCCESS(status)) {
1600 return status;
1601 }
1602 }
1603
1605 Lock(&irql);
1606 }
1607
1608 //
1609 // See if we already have a validated buffer
1610 //
1611 //if (m_RequestBaseFlags & FxRequestBaseOutputBufferValid) {
1612 // status = STATUS_SUCCESS;
1613 //}
1614
1616
1619
1621
1622 if (length == 0) {
1624
1627 "WDFREQUEST 0x%p IOCTL output buffer length is zero, %!STATUS!",
1628 GetHandle(), status);
1629
1630 goto Done;
1631 }
1632
1634 //
1635 // InputBuffer is in SystemBuffer
1636 // OutputBuffer is in MdlAddress with read access
1637 //
1638 case METHOD_IN_DIRECT:
1639 // || || fall || ||
1640 // \/ \/ through \/ \/
1641
1642 //
1643 // InputBuffer is in SystemBuffer
1644 // OutputBuffer is in MdlAddress with read access
1645 //
1646 case METHOD_OUT_DIRECT:
1647 mapMdl = TRUE;
1648 break;
1649
1650 case METHOD_NEITHER:
1651 //
1652 // Internal device controls are kernel mode to kernel mode, and deal
1653 // with direct unmapped pointers.
1654 //
1655 // In addition, a normal device control with
1656 // RequestorMode == KernelMode is also treated as kernel mode
1657 // to kernel mode since the I/O Manager will not generate requests
1658 // with this setting from a user mode request.
1659 //
1660 if ((m_Irp.GetRequestorMode() == KernelMode) ||
1662 DO_NOTHING();
1663 }
1664 else {
1666
1669 "Attempt to get UserMode Buffer Pointer for "
1670 "METHOD_NEITHER DeviceControl 0x%x, WDFDEVICE 0x%p, "
1671 "WDFREQUEST 0x%p, %!STATUS!",
1674
1677 "Driver must use METHOD_BUFFERED or METHOD_xx_DIRECT "
1678 "I/O for this call, or use "
1679 "WdfDeviceInitSetIoInCallerContextCallback to probe and "
1680 "lock user mode memory");
1681 }
1682 break;
1683 }
1684
1685 if (mapMdl && (m_RequestBaseFlags & FxRequestBaseOutputMdlMapped) == 0x0) {
1686 PMDL pMdl;
1687 PVOID pVA;
1688
1689
1690 pMdl = m_Irp.GetMdl();
1691
1692 if (pMdl == NULL) {
1693 //
1694 // Zero length transfer
1695 //
1697
1700 "WDFREQUEST 0x%p, METHOD_IN_DIRECT IOCTL PMDL is NULL, "
1701 "%!STATUS!", GetHandle(), status);
1702
1703 ASSERT(
1705 );
1706 }
1707 else {
1708 //
1709 // PagePriority may need to be a property, and/or parameter to
1710 // this call
1711 //
1712 //
1713 // Upon success, MmGetSystemAddressForMdlSafe stores the mapped
1714 // VA pointer in the pMdl and upon subsequent calls to
1715 // MmGetSystemAddressForMdlSafe, no mapping is done, just
1716 // the stored VA is returned. FxRequestOutputBuffer relies
1717 // on this behavior and, more importantly, relies on this function
1718 // to do the initial mapping so that FxRequestOutputBuffer::GetBuffer()
1719 // will not return a NULL pointer.
1720 //
1722
1723 if (pVA == NULL) {
1725
1728 "WDFREQUEST 0x%p could not get a system address for PMDL"
1729 "0x%p, %!STATUS!", GetHandle(), pMdl, status);
1730 }
1731 else {
1732 m_OutputBuffer.SetMdl(pMdl);
1735 }
1736 }
1737 }
1738
1739Done:
1741 Unlock(irql);
1742 }
1743
1744 if (NT_SUCCESS(status)) {
1746 if (mapMdl) {
1749 }
1750 else {
1752 }
1753 *Length = length;
1754 }
1755
1756 return status;
1757}
1758
1762 )
1763{
1764 FxRequestCompletionState oldState;
1765
1766 //
1767 // The flag by itself should never be specified
1768 //
1770
1771 //
1772 // No need to lock. Only the "owner" can set the completion
1773 // callback function, and this is when under the general
1774 // FxIoQueue lock.
1775 //
1776
1777 // Request is already completed, awaiting final dereference
1778 if (m_Completed) {
1781 "WDFREQUEST 0x%p has already been completed",
1782 GetHandle());
1784 }
1785 else {
1786 ASSERT(m_Irp.GetIrp() != NULL);
1787
1789
1790 m_CompletionState = (BYTE) NewState;
1791
1792 if (NewState == FxRequestCompletionStateNone &&
1793 oldState != FxRequestCompletionStateNone) {
1794 //
1795 // Cancelling a callback, so release the callback reference
1796 //
1798 }
1799 else if (NewState != FxRequestCompletionStateNone &&
1800 oldState == FxRequestCompletionStateNone) {
1801 //
1802 // Adding a callback requires a reference
1803 //
1805 }
1806 else {
1807 //
1808 // else we leave the current reference alone
1809 //
1810 DO_NOTHING();
1811 }
1812 }
1813
1814 return oldState;
1815}
1816
1819FX_VF_METHOD(FxRequest, VerifyInsertIrpQueue) (
1820 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
1822 )
1823{
1825
1827
1828 //
1829 // Check to make sure we are not already in an Irp queue
1830 //
1831 if (m_IrpQueue != NULL) {
1833
1835 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
1836 "Already in FxIrpQueue 0x%p WDFREQUEST 0x%p %!STATUS!",
1838
1839 FxVerifierDbgBreakPoint(FxDriverGlobals);
1840
1841 goto Done;
1842 }
1843
1844 //
1845 // If request is completed, fail.
1846 // This is because the driver can complete the request
1847 // right away in another thread while returning STATUS_PENDING
1848 // from EvtIoDefault
1849 //
1850 status = VerifyRequestIsNotCompleted(FxDriverGlobals);
1851
1852Done:
1853 return status;
1854}
1855
1860 __out_opt ULONG* pRequestCount
1861 )
1862{
1865
1867
1868 // No locking required since only one accessor till inserted on queue
1869
1870 status = VerifyInsertIrpQueue(pFxDriverGlobals, IrpQueue);
1871 if (!NT_SUCCESS(status)) {
1872 return status;
1873 }
1874
1875 //
1876 // If a request is on an IrpQueue, it must be referenced
1877 //
1878
1879
1880
1881
1882
1883
1885
1888
1890
1891 status = IrpQueue->InsertTailRequest(m_Irp.GetIrp(),
1892 &m_CsqContext,
1893 pRequestCount);
1894
1895 //
1896 // If this insert failed, we must release the extra reference we took
1897 //
1898 if (!NT_SUCCESS(status)) {
1901 }
1902
1903 return status;
1904}
1905
1910 __out_opt ULONG* pRequestCount
1911 )
1912{
1915
1917
1918 // No locking required since only one accessor till inserted on queue
1919
1920 status = VerifyInsertIrpQueue(pFxDriverGlobals, IrpQueue);
1921 if (!NT_SUCCESS(status)) {
1922 return status;
1923 }
1924
1925 //
1926 // If a request is on an IrpQueue, it must be referenced
1927 //
1928
1929
1930
1931
1932
1933
1935
1938
1940
1941 status = IrpQueue->InsertHeadRequest(m_Irp.GetIrp(),
1942 &m_CsqContext,
1943 pRequestCount);
1944
1945 //
1946 // If this insert failed, we must release the extra reference we took
1947 //
1948 if (!NT_SUCCESS(status)) {
1951 }
1952
1953 return status;
1954}
1955
1956//
1957// Remove request from its IRP queue
1958//
1963 )
1964{
1966 MdIrp pIrp;
1967
1969
1970 //
1971 // Cancel Safe Queues allow this request
1972 // removal to be race free even if the
1973 // request has been cancelled already.
1974 //
1975 // It signals this by returning NULL for
1976 // the Irp.
1977 //
1978 pIrp = IrpQueue->RemoveRequest(&m_CsqContext);
1979
1980 if (pIrp == NULL) {
1981
1982 //
1983 // Cancel routine removed it from the cancel
1984 // safe queue.
1985 //
1986 // The cancel handler will remove this reference
1987 // in FxIoQueue::_IrpCancelForDriver /
1988 // FxIrpQueue::_WdmCancelRoutineInternal
1989 //
1990
1991 return STATUS_CANCELLED;
1992 }
1993 else {
1994
1995 //
1996 // We retrieved the Irp from the cancel safe queue
1997 // without it having been cancelled first.
1998 //
1999 // It is no longer cancelable
2000 //
2002 if (m_IrpQueue == NULL) {
2005 "WDFREQUEST 0x%p not on IrpQueue",
2006 GetHandle());
2007
2009 }
2010 }
2011
2013
2015
2016 return STATUS_SUCCESS;
2017 }
2018}
2019
2020//
2021// Function to return the next FxRequest from an FxIrpQueue
2022//
2024FxRequest*
2027 )
2028{
2029 MdIrp pIrp;
2032
2033 pIrp = IrpQueue->GetNextRequest(&pCsqContext);
2034
2035 if (pIrp == NULL) {
2036 return NULL;
2037 }
2038
2039 // Irp is not cancellable now
2041
2042 // Must tell the request it's off the queue
2044
2045 // Remove reference placed when on IrpQueue
2046 pRequest->RELEASE(FXREQUEST_QUEUE_TAG);
2047
2048 return pRequest;
2049}
2050
2051//
2052// Function to return an FxRequest from an FxIrpQueue based
2053// on optional context and/or file object.
2054//
2061 __deref_out FxRequest** ppOutRequest
2062 )
2063{
2066 PMdIoCsqIrpContext TagCsqContext;
2067
2068 if( TagRequest != NULL ) {
2069 TagCsqContext = TagRequest->GetCsqContext();
2070 }
2071 else {
2072 TagCsqContext = NULL;
2073 }
2074
2075 Status = IrpQueue->GetNextRequest( TagCsqContext, FileObject, &pRequest );
2076 if( !NT_SUCCESS(Status) ) {
2077 return Status;
2078 }
2079
2080 // Irp is not cancellable now
2081
2082 // Must tell the request its off the queue
2084
2085 // Remove reference placed when on IrpQueue
2086 pRequest->RELEASE(FXREQUEST_QUEUE_TAG);
2087
2088 *ppOutRequest = pRequest;
2089
2090 return STATUS_SUCCESS;
2091}
2092
2093//
2094// Allow peeking at requests in the IrpQueue
2095//
2103 __deref_out FxRequest** ppOutRequest
2104 )
2105{
2107
2108 PMdIoCsqIrpContext TagContext = NULL;
2109
2110 //
2111 // IrpQueue::PeekRequest works with CSQ_CONTEXT
2112 // structures since this is the only value that
2113 // is valid across cancellation.
2114 //
2115 if( TagRequest != NULL ) {
2116 TagContext = TagRequest->GetCsqContext();
2117 }
2118
2119 Status = IrpQueue->PeekRequest(
2120 TagContext,
2121 FileObject,
2122 ppOutRequest
2123 );
2124 if(NT_SUCCESS(Status)) {
2125
2126 if( Parameters != NULL ) {
2127 Status = (*ppOutRequest)->GetParameters(Parameters);
2128 }
2129 }
2130
2131 return Status;
2132}
2133
2138 )
2139{
2140 FxIrp currentIrp;
2142
2143 //
2144 // Make sure request is not pended in IoTarget.
2145 //
2147 SHORT flags;
2148 KIRQL irql;
2149
2150 Lock(&irql);
2155 "Driver is trying to reuse WDFREQUEST 0x%p while it is still "
2156 "active on WDFIOTARGET 0x%p. ",
2159 }
2160 Unlock(irql);
2161 }
2162
2163 //
2164 // For drivers 1.9 and above (for maintaining backwards compatibility)
2165 // deregister previously registered completion routine.
2166 //
2169 }
2170
2171 currentIrp.SetIrp(m_Irp.GetIrp());
2172
2173 if (currentIrp.GetIrp() != NULL) {
2174 //
2175 // Release all outstanding references and restore original fields in
2176 // the PIRP
2177 //
2178 if (m_RequestContext != NULL) {
2180 }
2181
2183 //
2184 // An irp presented by io queue can only reset a limited state
2185 //
2187 //
2188 // Not allowed to set a new irp
2189 //
2191 }
2192
2193#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
2194 currentIrp.SetStatus(ReuseParams->Status);
2195 currentIrp.SetCancel(FALSE);
2196#else
2197 //
2198 // For UMDF, host sets cancel flag to false as part of Reuse(), so no
2199 // need to have a separate call for UMDF (that's why host irp doesn't
2200 // expose any interface to set this independently).
2201
2202
2203
2204
2205 //
2206 currentIrp.Reuse(ReuseParams->Status);
2207#endif
2209 m_Canceled = FALSE;
2210
2211 return STATUS_SUCCESS;
2212 }
2214 //
2215 // Release outstanding reference on a must complete driver request.
2216 //
2217 if (m_CanComplete && m_Completed == FALSE) {
2218 ASSERT(GetRefCnt() >= 2);
2219
2222 }
2223
2225 }
2226 }
2227 }
2228 else {
2229 //
2230 // We should not have a m_RequestContext with anything to ReleaseAndRestore
2231 // because there is no IRP to have anything formatted off of.
2232 //
2233 DO_NOTHING();
2234 }
2235
2236 //
2237 // This cannot be a request on a queue
2238 //
2240 m_IoQueue == NULL);
2241
2243 currentIrp.SetIrp((MdIrp)ReuseParams->NewIrp);
2244
2245 //
2246 // If we are replacing an internal irp, we must free it later.
2247 //
2249 MdIrp pOldIrp;
2250
2252 pOldIrp = m_Irp.SetIrp(currentIrp.GetIrp());
2253
2254 if (pOldIrp != NULL) {
2255 FxIrp oldIrp(pOldIrp);
2256 oldIrp.FreeIrp();
2257 }
2258 }
2259 else {
2260 (void) m_Irp.SetIrp(currentIrp.GetIrp());
2261 }
2262
2264 }
2265
2266 //
2267 // Only reinitialize an internal irp. If the irp is external, then its
2268 // still valid.
2269 //
2270 if (m_IrpAllocation == REQUEST_ALLOCATED_INTERNAL && currentIrp.GetIrp() != NULL) {
2273 currentIrp.Reuse(ReuseParams->Status);
2274
2275 //
2276 // For UMDF, host sets cancel flag to false as part of Reuse(), so no
2277 // need to have a separate call for UMDF (that's why host irp doesn't
2278 // expose any interface to set this independently).
2279
2280
2281
2282
2283 //
2284#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
2285 currentIrp.SetCancel(FALSE);
2286#endif
2287 }
2288
2289 //
2290 // If necessary, reinit the request to support WdfRequestComplete.
2291 //
2294
2295 //
2296 // WDF guarantees a successful return code when the driver calls Reuse() from its
2297 // completion routine with valid input.
2298 //
2299
2300 //
2301 // This feature can only be used from WDF v1.11 and above.
2302 //
2307 "WDFREQUEST %p doesn't belong to any queue, %!STATUS!",
2310 return status;
2311 }
2312
2313 //
2314 // 'must_complete' flag requires an IRP.
2315 //
2316 if (currentIrp.GetIrp() == NULL) {
2320 "Driver is trying to reuse WDFREQUEST 0x%p without "
2321 "specifying an IRP with "
2322 "WDF_REQUEST_REUSE_MUST_COMPLETE flag, %!STATUS!",
2325 return status;
2326 }
2327
2328 //
2329 // Do not support internal IRPs.
2330 //
2335 "Driver is trying to reuse WDFREQUEST 0x%p holding an"
2336 "internal allocated IRP with "
2337 "WDF_REQUEST_REUSE_MUST_COMPLETE flag, %!STATUS!",
2340 return status;
2341 }
2342
2343 //
2344 // Ref count must be 1.
2345 //
2346 if (GetRefCnt() != 1) {
2350 "Driver is trying to reuse WDFREQUEST 0x%p with "
2351 "WDF_REQUEST_REUSE_MUST_COMPLETE flag while request is "
2352 "being referenced, reference count:%d, %!STATUS!",
2355 return status;
2356 }
2357
2358 //
2359 // Make sure current IRP stack location is valid.
2360 //
2361 if (currentIrp.IsCurrentIrpStackLocationValid() == FALSE) {
2365 "IRP %p of WDFREQUEST %p doesn't have a valid"
2366 " stack location, %!STATUS!",
2367 currentIrp.GetIrp(), GetHandle(), status);
2369 return status;
2370 }
2371
2372 //
2373 // This ref is removed when:
2374 // (a) the request is completed or
2375 // (b) the request is reused and old request/IRP was never sent and completed.
2376 //
2378
2379 //
2380 // Note: strange why ClearFieldsForReuse() is not used all the time... just in case,
2381 // keeping old logic for compatibility.
2382 //
2385
2388 }
2389 }
2390 else {
2393 m_Canceled = FALSE;
2394
2397 }
2398 }
2399
2400 return STATUS_SUCCESS;
2401}
2402
2403//
2404// Return the FxFileObject if associated with this request
2405//
2410 )
2411{
2413 FxFileObject* pFileObject;
2416
2417 pFileObject = NULL;
2419
2420 pDevice = GetDevice();
2421
2423 KIRQL irql;
2424 *FileObject = NULL;
2425
2426 Lock(&irql);
2427 status = VerifyRequestIsNotCompleted(pFxDriverGlobals);
2428
2429 Unlock(irql);
2430 if (!NT_SUCCESS(status)) {
2431 return status;
2432 }
2433
2434 }
2435
2436 if (NULL == m_Irp.GetFileObject() && IsAllocatedDriver()) {
2438 //
2439 // This is a 'must_complete' driver created request.
2440 //
2441 *FileObject = NULL;
2442 return STATUS_SUCCESS;
2443 }
2444
2446 pDevice,
2449 &pFileObject
2450 );
2451
2452 if (NT_SUCCESS(status) && pFileObject != NULL) {
2453 *FileObject = pFileObject;
2454 return STATUS_SUCCESS;
2455 }
2456 else if (NT_SUCCESS(status) &&
2458 //
2459 // Driver told us that it is ok for the file object to be NULL.
2460 //
2461 *FileObject = NULL;
2462 return STATUS_SUCCESS;
2463 }
2464 else {
2466 }
2467}
2468
2469VOID
2471 VOID
2472 )
2473/*++
2474
2475Routine Description:
2476
2477 Adds a reference to the IRP contained in the request.
2478
2479 This is used to check that FxRequest::Complete is not
2480 called with outstanding references to any IRP related
2481 fields such as memory buffers.
2482
2483Arguments:
2484
2485 None
2486
2487Return Value:
2488
2489 None
2490
2491--*/
2492{
2495
2497 KIRQL irql;
2498
2499 Lock(&irql);
2500
2501 (VOID)VerifyRequestIsNotCompleted(pFxDriverGlobals);
2502
2503 Unlock(irql);
2504 }
2505
2507
2508 return;
2509}
2510
2511VOID
2513 VOID
2514 )
2515/*++
2516
2517Routine Description:
2518
2519 Release a reference to the IRP contained in the request.
2520
2521Arguments:
2522
2523 None
2524
2525Return Value:
2526
2527 None
2528
2529--*/
2530{
2531 LONG count;
2532
2534
2535 if( count < 0 ) {
2537 "Attempt to release an IRP reference without adding "
2538 "one first WDFREQUEST 0x%p",GetHandle());
2540 }
2541
2542 return;
2543}
2544
2547FX_VF_METHOD(FxRequest, VerifyProbeAndLock) (
2548 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2549 )
2550{
2552
2554
2555 MdEThread thread = m_Irp.GetThread();
2556
2557 //
2558 // Some kernel mode drivers issue I/O without setting this
2559 //
2560 if (thread != NULL) {
2561 //
2562 // Currently DDK level headers don't let us reach into a threads
2563 // parent process, so we can't do the process level check, just
2564 // a thread level check.
2565 //
2566 if (m_Irp.GetRequestorMode() == UserMode && thread != Mx::GetCurrentEThread()) {
2568
2569 // Error, wrong process context...
2571 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2572 "Attempt to access user mode memory from the wrong process "
2573 "Irp->Tail.Overlay.Thread 0x%p, PsGetCurrentThread 0x%p, "
2574 "%!STATUS!", thread, Mx::GetCurrentEThread(), status);
2575
2576 return status;
2577 }
2578 }
2579 else {
2580 // Irp->Thread should be issued for all user mode requests
2581 ASSERT(m_Irp.GetRequestorMode() == KernelMode);
2582 }
2583
2584 return status;
2585}
2586
2589FX_VF_METHOD(FxRequest, VerifyStopAcknowledge) (
2590 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
2592 )
2593{
2595 KIRQL irql;
2596
2598
2599 Lock(&irql);
2600
2601 //
2602 // Make sure the driver is calling this function in the context
2603 // of EvtIoStop callback.
2604 //
2605 status = VerifyRequestIsInEvtIoStopContext(FxDriverGlobals);
2607 goto Done;
2608 }
2609
2611
2612 // Make sure the driver owns the request
2613
2614 status = VerifyRequestIsDriverOwned(FxDriverGlobals);
2615 if (!NT_SUCCESS(status)) {
2616 goto Done;
2617 }
2618
2619 //
2620 // Can't re-enqueue a cancelable request
2621 //
2622 status = VerifyRequestIsNotCancelable(FxDriverGlobals);
2623 if (!NT_SUCCESS(status)) {
2624 goto Done;
2625 }
2626 }
2627
2628Done:
2629 Unlock(irql);
2630 return status;
2631}
2632
2633VOID
2636 )
2637/*++
2638
2639Routine Description:
2640
2641 This routine saves the acknowledgement in the request object
2642 which will be looked at and processed later by the queue
2643 dispatch event loop
2644
2645Arguments:
2646
2647 Requeue - if TRUE, put the request back into the head
2648 of queue from which it was delivered to the driver.
2649Return Value:
2650
2651 None
2652
2653--*/
2654{
2656
2657 PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals();
2658
2659 status = VerifyStopAcknowledge(FxDriverGlobals, Requeue);
2660 if(!NT_SUCCESS(status)) {
2661 return;
2662 }
2663
2664 if (Requeue) {
2666 }
2667 else {
2669 }
2670
2671 return;
2672}
2673
2674ULONG
2677 __in PVOID Tag,
2678 __in LONG Line,
2680 )
2681{
2682 if (Offset != 0x0) {
2686 return 2;
2687 }
2688 else {
2689 return FxObject::AddRef(Tag, Line, File);
2690 }
2691}
2692
2693ULONG
2696 __in PVOID Tag,
2697 __in LONG Line,
2699 )
2700{
2701 if (Offset != 0x0) {
2705 return 1;
2706 }
2707 else {
2708 return FxObject::Release(Tag, Line, File);
2709 }
2710}
2711
2716 )
2717{
2718 switch (Params->Type) {
2719 case FX_TYPE_REQUEST:
2720 *Params->Object = (FxRequest*) this;
2721 break;
2722
2723 case IFX_TYPE_MEMORY:
2725 *Params->Object = (IFxMemory*) &m_SystemBuffer;
2726 break;
2727 }
2728 else if (Params->Offset == FIELD_OFFSET(FxRequest, m_OutputBufferOffset)) {
2729 *Params->Object = (IFxMemory*) &m_OutputBuffer;
2730 break;
2731 }
2732
2733 // || || Fall || ||
2734 // \/ \/ through \/ \/
2735 default:
2736 return FxRequestBase::QueryInterface(Params); // __super call
2737 }
2738
2739 return STATUS_SUCCESS;
2740}
2741
2742VOID
2743FX_VF_METHOD(FxRequest, VerifierBreakpoint_RequestEarlyDisposeDeferred) (
2744 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2745 )
2746{
2748
2749 //
2750 // For backwards compatibility break only if WDF is v1.11 or above, or if
2751 // the developer/client enabled these tests on down-level drivers.
2752 //
2753 if (FxDriverGlobals->IsVerificationEnabled(1, 11, OkForDownLevel)) {
2755 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2756 "WDFREQUEST %p deferred the dispose operation. This normally "
2757 "indicates that at least one of its children asked for passive "
2758 "level disposal. This is not supported.", GetHandle());
2759
2760 FxVerifierDbgBreakPoint(FxDriverGlobals);
2761 }
2762}
2763
2767 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2768 )
2769{
2771
2773
2774 if ((m_VerifierFlags & FXREQUEST_FLAG_DRIVER_OWNED) == 0) {
2776
2778 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2779 "WDFREQUEST 0x%p is not owned by the driver, %!STATUS!",
2780 GetHandle(), status);
2781
2782 //
2783 // See if it's a tag request, since this could be a common mistake
2784 //
2785 if (m_VerifierFlags & FXREQUEST_FLAG_TAG_REQUEST) {
2787 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2788 "WDFREQUEST 0x%p has been "
2789 "used as a TagRequest in WdfIoQueueFindRequest. "
2790 "A TagRequest cannot be used until it is retrieved "
2791 "by WdfIoQueueRetrieveFoundRequest",
2792 GetHandle());
2793 }
2794
2795 FxVerifierDbgBreakPoint(FxDriverGlobals);
2796 }
2797 else {
2799 }
2800
2801 return status;
2802}
2803
2806FX_VF_METHOD(FxRequest, VerifyRequestIsCancelable)(
2807 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2808 )
2809{
2811
2813
2814 if ((m_VerifierFlags & FXREQUEST_FLAG_DRIVER_CANCELABLE) == 0) {
2816
2818 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2819 "WDFREQUEST 0x%p is not cancelable, %!STATUS!",
2820 GetHandle(), status);
2821
2822 FxVerifierDbgBreakPoint(FxDriverGlobals);
2823 }
2824 else {
2826 }
2827
2828 return status;
2829}
2830
2833FX_VF_METHOD(FxRequest, VerifyRequestIsNotCancelable)(
2834 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2835 )
2836{
2838
2840
2841 if (m_VerifierFlags & FXREQUEST_FLAG_DRIVER_CANCELABLE) {
2843
2845 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2846 "WDFREQUEST 0x%p should be unmarked cancelable by calling "
2847 "WdfRequestUnmarkCancelable, %!STATUS!",
2848 GetHandle(), status);
2849
2850 FxVerifierDbgBreakPoint(FxDriverGlobals);
2851 }
2852 else {
2854 }
2855
2856 return status;
2857}
2858
2861FX_VF_METHOD(FxRequest, VerifyRequestIsInCallerContext)(
2862 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2863 )
2864{
2866
2868
2869 if ((m_VerifierFlags & FXREQUEST_FLAG_DRIVER_INPROCESS_CONTEXT) == 0) {
2871
2873 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2874 "This call is valid only in EvtIoInCallerContext callback, "
2875 "WDFREQUEST 0x%p, %!STATUS!", GetHandle(), status);
2876
2877 FxVerifierDbgBreakPoint(FxDriverGlobals);
2878 }
2879 else {
2881 }
2882
2883 return status;
2884}
2885
2888FX_VF_METHOD(FxRequest, VerifyRequestIsInEvtIoStopContext)(
2889 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2890 )
2891{
2893
2895
2896 if ((m_VerifierFlags & FXREQUEST_FLAG_DRIVER_IN_EVTIOSTOP_CONTEXT) == 0) {
2898
2900 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO,
2901 "This call is valid only in EvtIoStop callback, "
2902 "WDFREQUEST 0x%p, %!STATUS!", GetHandle(), status);
2903
2904 FxVerifierDbgBreakPoint(FxDriverGlobals);
2905 }
2906 else {
2908 }
2909
2910 return status;
2911}
2912
2915FX_VF_METHOD(FxRequest, VerifyRequestIsNotCompleted)(
2916 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2917 )
2918{
2920
2922
2923 if (m_Completed) {
2925
2927 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST,
2928 "WDFREQUEST 0x%p is already completed, %!STATUS!",
2929 GetHandle(), status);
2930
2931 FxVerifierDbgBreakPoint(FxDriverGlobals);
2932 }
2933 else {
2935 }
2936
2937 return status;
2938}
2939
2942FX_VF_METHOD(FxRequest, VerifyRequestIsTagRequest) (
2943 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2944 )
2945{
2947
2949
2950 //
2951 // A request that has been marked as a tag request can be retrieved
2952 // by the driver by calling WdfIoQueueRetrieveNextRequest instead of
2953 // WdfIoQueueRetrieveFoundRequest. Some drivers use multiple threads
2954 // to scan the queue, not the best design but allowed. This means that
2955 // it is possible for one thread to remove and complete a request that is
2956 // used as a tag by another thread.
2957 //
2958 if (FALSE == m_Completed && (0x0 == (m_VerifierFlags &
2960
2963 "Request 0x%p is not returned by WdfIoQueueFindRequest, "
2964 "%!STATUS!", GetHandle(), status);
2965 FxVerifierDbgBreakPoint(FxDriverGlobals);
2966 }
2967 else {
2969 }
2970
2971 return status;
2972}
2973
2976FX_VF_METHOD(FxRequest, VerifyRequestIsAllocatedFromIo)(
2977 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
2978 )
2979{
2981
2983
2984 if (IsAllocatedFromIo() == FALSE) {
2987 "Request 0x%p was not allocated for an incoming IRP, "
2988 "%!STATUS!", GetHandle(), status);
2989 FxVerifierDbgBreakPoint(FxDriverGlobals);
2990
2991 } else {
2993 }
2994
2995 return status;
2996}
2997
3000FX_VF_METHOD(FxRequest, VerifyRequestIsCurrentStackValid)(
3001 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
3002 )
3003{
3005 MdIrp irp;
3006
3008
3009 //
3010 //Make sure there is an IRP.
3011 //
3012 irp = GetFxIrp()->GetIrp();
3013 if (NULL == irp) {
3016 "WDFREQUEST %p doesn't have an IRP, %!STATUS!",
3017 GetHandle(), status);
3018 FxVerifierDbgBreakPoint(FxDriverGlobals);
3019 goto Done;
3020 }
3021
3022 //
3023 // Validate the IRP's stack location values.
3024 //
3025 if (m_Irp.IsCurrentIrpStackLocationValid() == FALSE) {
3028 "IRP %p of WDFREQUEST %p doesn't have a valid"
3029 " stack location, %!STATUS!",
3030 irp, GetHandle(), status);
3031 FxVerifierDbgBreakPoint(FxDriverGlobals);
3032 goto Done;
3033 }
3034
3036
3037Done:
3038 return status;
3039}
3040
3043FX_VF_METHOD(FxRequest, VerifyRequestCanBeCompleted)(
3044 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
3045 )
3046{
3048
3050
3051 if (GetDriverGlobals()->IsVersionGreaterThanOrEqualTo(1,11) == FALSE) {
3052 status = VerifyRequestIsAllocatedFromIo(FxDriverGlobals);
3053 goto Done;
3054 }
3055
3056 //
3057 // Validate the IRP's stack location.
3058 //
3059 status = VerifyRequestIsCurrentStackValid(FxDriverGlobals);
3060 if (!NT_SUCCESS(status)) {
3061 goto Done;
3062 }
3063
3064 //
3065 // Note: There is no guarantees that the request has a completion routine in the current
3066 // IRP stack location; thus we cannot check for it.
3067 //
3068
3069 //
3070 // Make sure this request can be completed.
3071 //
3072 if (IsCanComplete() == FALSE) {
3075 "IRP %p of WDFREQUEST %p cannot be completed, "
3076 "%!STATUS!",
3077 GetFxIrp()->GetIrp(), GetHandle(), status);
3078 FxVerifierDbgBreakPoint(FxDriverGlobals);
3079 goto Done;
3080 }
3081
3083
3084Done:
3085 return status;
3086}
3087
3088ULONG
3090 __in PVOID Tag,
3091 __in LONG Line,
3093 )
3094{
3095 ULONG retValue;
3096 BOOLEAN reservedRequest;
3097 BOOLEAN allocFromIo;
3098 BOOLEAN canComplete;
3099
3100 //
3101 // This may be the last ref, copy flags before calling Release().
3102 //
3103 reservedRequest = IsReserved();
3104 allocFromIo = IsAllocatedFromIo();
3105 canComplete = IsCanComplete();
3106
3107 retValue = FxRequestBase::Release(Tag, Line, File); // __super call
3108
3109 if (reservedRequest && retValue == 1 && m_Completed) {
3110 //
3111 // Reserved requests should have an associated queue all the time.
3112 //
3114 }
3115 else if (allocFromIo == FALSE && canComplete && retValue == 1 && m_Completed) {
3116
3119
3120 //
3121 // Make a local copy before request is gone.
3122 //
3124 queue = m_IoQueue;
3125
3127 m_IoQueue = NULL;
3128
3129 //
3130 // We are now ready to complete this driver created request.
3131 //
3132 FxIrp irp(m_Irp.GetIrp());
3133
3134 m_Irp.SetIrp(NULL);
3135
3137
3139 }
3140
3141 return retValue;
3142}
3143
3146 __in MdIrp Irp
3147 ) : FxRequest(Device->GetDriverGlobals(),
3148 Irp,
3152{
3153 SetDeviceBase(Device->GetDeviceBase());
3154}
3155
3156PVOID
3157FxRequestFromLookaside::operator new(
3158 __in size_t Size,
3161 )
3162{
3164
3165 //
3166 // Allocate out of a device specific lookaside list
3167 //
3168 return Device->AllocateRequestMemory(Attributes);
3169}
3170
3171VOID
3173 VOID
3174 )
3175{
3178
3179 //
3180 // Store off the device in case the destructor chain sets it to NULL.
3181 //
3182 pDevice = GetDevice();
3183 ASSERT(pDevice != NULL);
3184
3185 //
3186 // Destroy the object
3187 //
3188 // FxRequestFromLookaside::~FxRequestFromLookaside(); __REACTOS__
3189
3191
3192 #if FX_VERBOSE_TRACE
3194 "Free FxRequest* %p memory", this);
3195 #endif
3196
3197 //
3198 // Remove the request from the list of outstanding requests against this
3199 // driver.
3200 //
3203 }
3204 else {
3206 }
3207}
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE thread
Definition: service.c:33
Definition: bufpool.h:45
Definition: File.h:16
FxPkgGeneral * m_PkgGeneral
Definition: fxdevice.hpp:671
__inline WDF_FILEOBJECT_CLASS GetFileObjectClass(VOID)
Definition: fxdevice.hpp:1123
VOID FreeRequestMemory(__in FxRequest *Request)
Definition: fxdevice.cpp:1728
static _Must_inspect_result_ NTSTATUS _GetFileObjectFromWdm(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject, __deref_out_opt FxFileObject **ppFxFileObject)
VOID ReturnReservedRequest(__in FxRequest *ReservedRequest)
Definition: fxirp.hpp:28
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
ULONG GetParameterWriteLength(VOID)
Definition: fxirpum.cpp:1601
VOID CompleteRequest(__in_opt CCHAR PriorityBoost=IO_NO_INCREMENT)
Definition: fxirpum.cpp:24
ULONG GetParameterIoctlCodeBufferMethod(VOID)
Definition: fxirpum.cpp:1490
ULONG GetParameterIoctlCode(VOID)
Definition: fxirpum.cpp:1474
KPROCESSOR_MODE GetRequestorMode(VOID)
Definition: fxirpum.cpp:329
VOID SetCancel(__in BOOLEAN Cancel)
Definition: fxirpum.cpp:1294
ULONG GetParameterIoctlOutputBufferLength(VOID)
Definition: fxirpum.cpp:1504
PMDL GetMdl()
Definition: fxirpum.cpp:625
MdFileObject GetFileObject(VOID)
Definition: fxirpum.cpp:1460
VOID SkipCurrentIrpStackLocation(VOID)
Definition: fxirpum.cpp:400
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
VOID FreeIrp(VOID)
Definition: fxirpum.cpp:1648
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
VOID CopyParameters(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: fxirpum.cpp:1691
VOID SetInformation(__in ULONG_PTR Information)
Definition: fxirpum.cpp:504
BOOLEAN IsCurrentIrpStackLocationValid(VOID)
Definition: fxirpum.cpp:1761
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
UCHAR GetMinorFunction(VOID)
Definition: fxirpum.cpp:297
ULONG GetParameterIoctlInputBufferLength(VOID)
Definition: fxirpum.cpp:1518
ULONG GetFlags(VOID)
Definition: fxirpum.cpp:1281
ULONG_PTR GetInformation()
Definition: fxirpum.cpp:513
VOID SetFlags(__in ULONG Flags)
Definition: fxirpum.cpp:1266
ULONG GetParameterReadLength(VOID)
Definition: fxirpum.cpp:1589
VOID Reuse(__in NTSTATUS Status=STATUS_SUCCESS)
Definition: fxirpum.cpp:661
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID __inline DestroyChildren(VOID)
Definition: fxobject.hpp:464
ULONG __inline AddRef(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:826
VOID DeleteEarlyDisposedObject(VOID)
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
VOID ClearEvtCallbacks(VOID)
Definition: fxobject.cpp:360
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
BOOLEAN EarlyDispose(VOID)
virtual ULONG Release(__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxobject.hpp:853
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
static PFX_POOL_HEADER _CleanupPointer(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
Definition: fxobject.hpp:1273
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
VOID CreateCompleted(__in FxIrp *Irp)
MdIrp SetSubmitIrp(__in_opt MdIrp NewIrp, __in BOOLEAN FreeIrp=TRUE)
WDFOBJECT_OFFSET_ALIGNED m_OutputBufferOffset
BOOLEAN m_CanComplete
BOOLEAN __inline IsCanComplete(VOID)
__inline VOID SetVerifierFlags(__in SHORT Flags)
__inline PVOID GetTraceObjectHandle(VOID)
__inline BOOLEAN HasContext(VOID)
FxIrpQueue * m_IrpQueue
UCHAR m_RequestBaseStaticFlags
FxRequestContext * m_RequestContext
__inline VOID ClearVerifierFlags(__in SHORT Flags)
UCHAR m_RequestBaseFlags
SHORT GetVerifierFlagsLocked(VOID)
__inline FxIoTarget * GetTarget(VOID)
_Must_inspect_result_ NTSTATUS ValidateTarget(__in FxIoTarget *Target)
BOOLEAN __inline IsAllocatedDriver(VOID)
__inline BOOLEAN IsCancelRoutineSet(VOID)
BOOLEAN m_NextStackLocationFormatted
BOOLEAN __inline IsAllocatedFromIo(VOID)
__inline VOID SetCompletionRoutine(__in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine=NULL, __in_opt WDFCONTEXT CompletionContext=NULL)
MdIoCsqIrpContext m_CsqContext
WDFOBJECT_OFFSET_ALIGNED m_SystemBufferOffset
CCHAR __inline GetPriorityBoost(VOID)
FxRequestFromLookaside(__in CfxDevice *Device, __in MdIrp Irp)
Definition: fxrequest.cpp:3144
_Must_inspect_result_ NTSTATUS GetMemoryObject(__deref_out IFxMemory **Memory, __out PVOID *Buffer, __out size_t *Length)
Definition: fxrequest.cpp:1284
VOID StopAcknowledge(__in BOOLEAN Requeue)
Definition: fxrequest.cpp:2634
FxIoQueue * m_IoQueue
Definition: fxrequest.hpp:411
NTSTATUS CompleteInternal(__in NTSTATUS Status)
Definition: fxrequest.cpp:515
FxIoQueue * m_ForwardProgressQueue
Definition: fxrequest.hpp:434
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in_opt MdIrp Irp, __in_opt FxIoTarget *Target, __in FxRequestIrpOwnership Ownership, __in FxRequestConstructorCaller Caller, __deref_out FxRequest **Request)
Definition: fxrequest.cpp:161
_Must_inspect_result_ NTSTATUS InsertHeadIrpQueue(__in FxIrpQueue *IrpQueue, __out_opt ULONG *pRequestCount)
Definition: fxrequest.cpp:1908
_Must_inspect_result_ NTSTATUS GetParameters(__out PWDF_REQUEST_PARAMETERS Parameters)
Definition: fxrequest.cpp:1221
VOID PreProcessSendAndForget(VOID)
Definition: fxrequest.cpp:1101
static _Must_inspect_result_ FxRequest * GetNextRequest(__in FxIrpQueue *IrpQueue)
Definition: fxrequest.cpp:2025
static __inline FxRequest * RetrieveFromCsqContext(__in PMdIoCsqIrpContext pCsqContext)
Definition: fxrequest.hpp:1163
FxRequest(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in MdIrp Irp, __in FxRequestIrpOwnership Ownership, __in FxRequestConstructorCaller Caller, __in USHORT ObjectSize)
Definition: fxrequest.cpp:33
FxRequestCompletionState SetCompletionState(__in FxRequestCompletionState NewState)
Definition: fxrequest.cpp:1760
virtual ULONG ReleaseOverride(__in WDFOBJECT_OFFSET Offset, __in PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxrequest.cpp:2694
_Must_inspect_result_ NTSTATUS InsertTailIrpQueue(__in FxIrpQueue *IrpQueue, __out_opt ULONG *pRequestCount)
Definition: fxrequest.cpp:1858
VOID PostProcessCompletionForReserved(__in FxRequestCompletionState State, __in FxIoQueue *Queue)
Definition: fxrequest.cpp:916
KPROCESSOR_MODE GetRequestorMode(VOID)
Definition: fxrequest.cpp:327
NTSTATUS SetInformation(__in ULONG_PTR Information)
Definition: fxrequest.cpp:229
__inline VOID ClearFieldsForReuse(VOID)
Definition: fxrequest.hpp:1294
ULONG_PTR GetInformation(VOID)
Definition: fxrequest.cpp:277
__inline VOID MarkRemovedFromIrpQueue(VOID)
Definition: fxrequest.hpp:1100
FxRequestOutputBuffer m_OutputBuffer
Definition: fxrequest.hpp:415
BOOLEAN m_ForwardRequestToParent
Definition: fxrequest.hpp:461
__inline BOOLEAN IsRequestForwardedToParent(VOID)
Definition: fxrequest.hpp:1316
VOID PostProcessCompletionForDriverRequest(__in FxRequestCompletionState State, __in FxIoQueue *Queue)
Definition: fxrequest.cpp:996
_Must_inspect_result_ NTSTATUS GetDeviceControlOutputMemoryObject(__deref_out IFxMemory **MemoryObject, __out PVOID *Buffer, __out size_t *Length)
Definition: fxrequest.cpp:1524
LIST_ENTRY m_ForwardProgressList
Definition: fxrequest.hpp:427
BOOLEAN m_Presented
Definition: fxrequest.hpp:445
static _Must_inspect_result_ NTSTATUS _CreateForPackage(__in CfxDevice *Device, __in PWDF_OBJECT_ATTRIBUTES RequestAttributes, __in MdIrp Irp, __deref_out FxRequest **Request)
Definition: fxrequest.cpp:75
LIST_ENTRY m_OwnerListEntry
Definition: fxrequest.hpp:420
VOID AssignMemoryBuffers(__in WDF_DEVICE_IO_TYPE IoType)
Definition: fxrequest.hpp:1372
VOID ReleaseIrpReference(VOID)
Definition: fxrequest.cpp:2512
LIST_ENTRY m_OwnerListEntry2
Definition: fxrequest.hpp:422
virtual ULONG Release(__in PVOID Tag, __in LONG Line, __in_opt PSTR File)
Definition: fxrequest.cpp:3089
VOID PostProcessCompletion(__in FxRequestCompletionState State, __in FxIoQueue *Queue)
Definition: fxrequest.cpp:874
BOOLEAN m_Reserved
Definition: fxrequest.hpp:455
_Must_inspect_result_ NTSTATUS GetFileObject(__deref_out_opt FxFileObject **pFileObject)
Definition: fxrequest.cpp:2408
FxRequestSystemBuffer m_SystemBuffer
Definition: fxrequest.hpp:413
__inline BOOLEAN IsReserved()
Definition: fxrequest.hpp:609
VOID FreeRequest(VOID)
Definition: fxrequest.cpp:1022
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxrequest.cpp:2714
static _Must_inspect_result_ NTSTATUS PeekRequest(__in FxIrpQueue *IrpQueue, __in_opt FxRequest *TagRequest, __in_opt MdFileObject FileObject, __out_opt PWDF_REQUEST_PARAMETERS Parameters, __deref_out FxRequest **ppOutRequest)
Definition: fxrequest.cpp:2098
BYTE m_PowerStopState
Definition: fxrequest.hpp:450
virtual ULONG AddRefOverride(__in WDFOBJECT_OFFSET Offset, __in PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
Definition: fxrequest.cpp:2675
_Must_inspect_result_ NTSTATUS Reuse(__in PWDF_REQUEST_REUSE_PARAMS ReuseParams)
Definition: fxrequest.cpp:2136
_Must_inspect_result_ NTSTATUS RemoveFromIrpQueue(__in FxIrpQueue *IrpQueue)
Definition: fxrequest.cpp:1961
VOID PreProcessCompletionForDriverRequest(__in FxRequestCompletionState State, __in FxIoQueue *Queue)
Definition: fxrequest.cpp:955
NTSTATUS GetStatus(VOID)
Definition: fxrequest.cpp:1187
VOID PostProcessSendAndForget(VOID)
Definition: fxrequest.cpp:1149
PVOID m_InternalContext
Definition: fxrequest.hpp:439
VOID AddIrpReference(VOID)
Definition: fxrequest.cpp:2470
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
static __inline MdEThread GetCurrentEThread()
Definition: mxgeneralkm.h:69
static __inline PVOID MxGetSystemAddressForMdlSafe(__inout PMDL Mdl, __in ULONG Priority)
Definition: mxgeneralkm.h:366
Definition: _queue.h:67
_In_ PIRP Irp
Definition: csq.h:116
LIST_ENTRY IrpQueue
Definition: csqrtns.c:49
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __deref_out
Definition: dbghelp.h:26
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define __deref_out_opt
Definition: dbghelp.h:29
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGREQUEST
Definition: dbgtrace.h:65
#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:32
KIRQL irql
Definition: wave.h:1
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KMDF_ONLY_CODE_PATH_ASSERT()
Definition: fx.hpp:55
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
return pList GetDevice()
PFX_DRIVER_GLOBALS pFxDriverGlobals
return pObject GetObjectHandle()
BOOLEAN __inline FxIsFileObjectOptional(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:112
WDF_FILEOBJECT_CLASS __inline FxFileObjectClassNormalize(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:103
pKey SetDeviceBase(pDevice)
FxIoQueue * pQueue
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxRequest * pRequest
@ OkForDownLevel
Definition: fxglobals.h:80
_Must_inspect_result_ NTSTATUS _In_ FxRequest * TagRequest
Definition: fxioqueue.cpp:885
VOID Request VerifyRequestIsDriverOwned(FxDriverGlobals)
__in MdIrp __in PMdIoCsqIrpContext pCsqContext
Definition: fxirpqueue.hpp:75
#define FX_VF_METHOD(classname, fnName)
Definition: fxmacros.hpp:43
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define RELEASE(_tag)
Definition: fxobject.hpp:50
USHORT WDFOBJECT_OFFSET
Definition: fxobject.hpp:80
pKey DeleteObject()
_Must_inspect_result_ NTSTATUS _In_ BOOLEAN Requeue
Definition: fxrequest.cpp:2593
KIRQL irql
Definition: fxrequest.cpp:379
BOOLEAN validateLength
Definition: fxrequest.cpp:380
PAGED_CODE_LOCKED()
_Must_inspect_result_ NTSTATUS _In_ FxIrpQueue * IrpQueue
Definition: fxrequest.cpp:1823
m_Completed
Definition: fxrequest.cpp:509
status
Definition: fxrequest.cpp:1850
VOID _In_ NTSTATUS Status
Definition: fxrequest.cpp:376
ULONG length
Definition: fxrequest.cpp:378
#define FXREQUEST_STATE_TAG
Definition: fxrequest.hpp:42
#define FXREQUEST_COMPLETE_TAG
Definition: fxrequest.hpp:52
#define FXREQUEST_FWDPRG_TAG
Definition: fxrequest.hpp:63
#define FXREQUEST_DCRC_TAG
Definition: fxrequest.hpp:69
@ FxRequestPowerStopAcknowledged
Definition: fxrequest.hpp:388
@ FxRequestPowerStopAcknowledgedWithRequeue
Definition: fxrequest.hpp:391
@ FxRequestPowerStopUnknown
Definition: fxrequest.hpp:385
#define FXREQUEST_QUEUE_TAG
Definition: fxrequest.hpp:47
FxIrp * pIrp
UCHAR majorFunction
FxIrp * irp
pRequest GetFxIrp() -> GetIoIrp() ->SetUserModeDriverInitiatedIo(IsUserModeDriverInitiated)
@ REQUEST_ALLOCATED_FROM_IO
@ REQUEST_ALLOCATED_DRIVER
@ REQUEST_ALLOCATED_INTERNAL
FxRequestConstructorCaller
@ FxRequestConstructorCallerIsDriver
@ FxRequestConstructorCallerIsFx
#define WDF_REQUEST_REUSE_MUST_COMPLETE
@ FxRequestBaseStaticSystemBufferValid
@ FxRequestBaseStaticOutputBufferValid
@ FxRequestBaseOutputMdlMapped
@ FxRequestBaseSystemMdlMapped
@ FXREQUEST_FLAG_DRIVER_INPROCESS_CONTEXT
@ FXREQUEST_FLAG_TAG_REQUEST
@ FXREQUEST_FLAG_CANCELLED
@ FXREQUEST_FLAG_DRIVER_CANCELABLE
@ FXREQUEST_FLAG_DRIVER_IN_EVTIOSTOP_CONTEXT
@ FXREQUEST_FLAG_SENT_TO_TARGET
@ FXREQUEST_FLAG_DRIVER_OWNED
FxRequestCompletionState
@ FxRequestCompletionStateIoPkgFlag
@ FxRequestCompletionStateQueue
@ FxRequestCompletionStateNone
FxRequestIrpOwnership
@ FxRequestDoesNotOwnIrp
@ IFX_TYPE_MEMORY
Definition: fxtypes.h:55
@ FX_TYPE_REQUEST
Definition: fxtypes.h:53
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum mode
Definition: glext.h:6217
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define ASSERT(a)
Definition: mode.c:44
@ NormalPagePriority
Definition: imports.h:56
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define _In_
Definition: ms_sal.h:308
#define DO_NOTHING()
Definition: mxgeneral.h:32
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define METHOD_NEITHER
Definition: nt_native.h:597
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ Unlock
Definition: ntsecapi.h:294
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define L(x)
Definition: ntvdm.h:50
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
__inline VOID SetMdl(__in PMDL Mdl)
Definition: fxrequest.hpp:344
virtual _Must_inspect_result_ PMDL GetMdl(VOID)
virtual PVOID GetBuffer(VOID)
virtual size_t GetBufferSize(VOID)
virtual WDFMEMORY GetHandle(VOID)
virtual size_t GetBufferSize(VOID)
virtual _Must_inspect_result_ PVOID GetBuffer(VOID)
__inline VOID SetMdl(PMDL Mdl)
Definition: fxrequest.hpp:198
virtual WDFMEMORY GetHandle(VOID)
virtual _Must_inspect_result_ PMDL GetMdl(VOID)
Definition: ncftp.h:79
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
BOOLEAN FxVerifierIO
Definition: fxglobals.h:446
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
char * PSTR
Definition: typedefs.h:51
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
@ WDF_REQUEST_FATAL_ERROR
Definition: wdfbugcodes.h:63
@ WDF_VERIFIER_FATAL_ERROR
Definition: wdfbugcodes.h:60
@ WDF_REQUEST_FATAL_ERROR_INFORMATION_LENGTH_MISMATCH
Definition: wdfbugcodes.h:79
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_In_ PWDFDEVICE_INIT _In_ PWDF_OBJECT_ATTRIBUTES RequestAttributes
Definition: wdfdevice.h:3431
enum _WDF_REQUEST_TYPE WDF_REQUEST_TYPE
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
@ WdfFileObjectNotRequired
Definition: wdfdevice.h:460
@ WdfDeviceIoNeither
Definition: wdfdevice.h:451
@ WdfDeviceIoDirect
Definition: wdfdevice.h:453
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_In_ WDFREQUEST _In_ PWDF_REQUEST_REUSE_PARAMS ReuseParams
Definition: wdfrequest.h:554
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
_Must_inspect_result_ _In_ WDFREQUEST _In_ size_t _Out_ WDFMEMORY * MemoryObject
Definition: wdfrequest.h:1473
@ WDF_REQUEST_REUSE_SET_NEW_IRP
Definition: wdfrequest.h:93
_In_ WDFREQUEST _In_ BOOLEAN Requeue
Definition: wdfrequest.h:1654
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
struct _WDF_REQUEST_PARAMETERS WDF_REQUEST_PARAMETERS
#define STATUS_WDF_REQUEST_INVALID_STATE
Definition: wdfstatus.h:162
#define STATUS_WDF_TOO_FRAGMENTED
Definition: wdfstatus.h:180
#define FACILITY_DRIVER_FRAMEWORK
Definition: wdfstatus.h:32
#define STATUS_WDF_PAUSED
Definition: wdfstatus.h:117
#define STATUS_WDF_INTERNAL_ERROR
Definition: wdfstatus.h:108
#define STATUS_WDF_BUSY
Definition: wdfstatus.h:126
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define IRP_INPUT_OPERATION
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193