ReactOS 0.4.15-dev-7958-gcd0bb1a
fxrequestapi.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxRequestApi.cpp
8
9Abstract:
10
11 This module implements FxRequest object
12
13Author:
14
15
16
17
18
19Environment:
20
21 Both kernel and user mode
22
23Revision History:
24
25
26--*/
27#include "coreprivshared.hpp"
28
29// Tracing support
30extern "C" {
31// #include "FxRequestApi.tmh"
32
33//
34// Verifiers
35//
36// Do not supply Argument names
41 );
42
43// Do not supply Argument names
48 );
49
50//Do not supply argument names
55 );
56
57//Do not supply argument names
62 );
63
68WDFEXPORT(WdfRequestCreate)(
69 __in
74 WDFIOTARGET Target,
75 __out
76 WDFREQUEST* Request
77 )
78
79/*++
80
81Routine Description:
82 Creates a WDFREQUEST handle that is suitable to be submitted to the provided
83 target
84
85Arguments:
86 RequestAttributes - Attributes associated with the request. If NULL, the
87 size of the user context associated with the request will be
88 the default size specified in WdfDriverCreate.
89
90 Target - Target for which the request will be sent to. If NULL, then
91 WdfRequestChangeTarget must be called before the request is formatted
92 or sent to any target
93
94 Request - Pointer which will receive the newly created request
95
96Return Value:
97 NT_SUCCESS if successful, otherwise appropriate error code
98
99 --*/
100
101{
106
108
109 if (Target != NULL) {
111 Target,
113 (PVOID*)&pTarget,
115 }
116 else {
117 pTarget = NULL;
118
119 //
120 // For class extension support, get globals from parent object.
121 //
123 RequestAttributes->ParentObject != NULL) {
124
127 RequestAttributes->ParentObject,
129 }
130 }
131
133 *Request = NULL;
134
137 NULL,
138 pTarget,
141 &pRequest);
142
145
146#if FX_VERBOSE_TRACE
149 "Created WDFREQUEST %p, %!STATUS!",
150 *Request, status);
151#endif // FX_VERBOSE_TRACE
152 }
153
154 return status;
155}
156
161WDFEXPORT(WdfRequestCreateFromIrp)(
162 __in
166 __in
168 __in
170 __out
171 WDFREQUEST* Request
172 )
173
174/*++
175
176Routine Description:
177 Creates a request handle that uses an external IRP instead of an internally
178 allocated irp.
179
180Arguments:
181 RequestAttributes - Attributes associated with the request. If NULL, the
182 size of the user context associated with the request will be
183 the default size specified in WdfDriverCreate.
184
185 Irp - The IRP to use
186
187 RequestFreesIrp - If TRUE, when the request handle is destroyed, it will
188 free the IRP with IoFreeIrp. If FALSE, it is the responsibility of the
189 calller to free the IRP
190
191 Request - Pointer which will receive the newly created request
192
193Return Value:
194 NT_SUCCESS or appropriate error code
195
196 --*/
197
198{
202
204
205 //
206 // For class extension support, get globals from parent object.
207 //
208 if (RequestAttributes != NULL &&
209 RequestAttributes->ParentObject != NULL) {
210
213 RequestAttributes->ParentObject,
215 }
216
219
220 *Request = NULL;
221
224 Irp,
225 NULL,
229 &pRequest);
230
231 if (NT_SUCCESS(status)) {
233
234#if FX_VERBOSE_TRACE
237 "Irp %p RequestFreesIrp %d WDFREQUEST %p created",
239#endif // FX_VERBOSE_TRACE
240 }
241
242 return status;
243}
244
245
246#define WDF_REQUEST_REUSE_VALID_FLAGS_V1_9 \
247 (WDF_REQUEST_REUSE_SET_NEW_IRP)
248
249#define WDF_REQUEST_REUSE_VALID_FLAGS \
250 (WDF_REQUEST_REUSE_SET_NEW_IRP | WDF_REQUEST_REUSE_MUST_COMPLETE)
251
252
253
254
255
256
257
261WDFEXPORT(WdfRequestReuse)(
262 __in
264 __in
265 WDFREQUEST Request,
266 __in
268 )
269/*++
270
271Routine Description:
272 Clears out the internal state of the irp, which includes, but is not limited
273 to:
274 a) Any internal allocations for the previously formatted request
275 b) The completion routine and its context
276 c) The request's intended i/o target
277 d) All of the internal IRP's stack locations
278
279Arguments:
280 Request - The request to be reused.
281
282 ReuseParams - Parameters controlling the reuse of the request, see comments
283 for each field in the structure for usage
284
285Return Value:
286 NT_SUCCESS or appropriate error code
287
288 --*/
289 {
293
295 Request,
297 (PVOID*)&pRequest,
299
301
302 if (ReuseParams->Size != sizeof(WDF_REQUEST_REUSE_PARAMS)) {
304 "ReuseParams Size %d, expected %d %!STATUS!",
308 }
309
310 if (pFxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,11)) {
312 }
313 else {
315 }
316
317 if (ReuseParams->Flags & ~validFlags) {
319 "ReuseParams Flags 0x%x, valid mask 0x%x, %!STATUS!",
320 ReuseParams->Flags,
321 (ULONG) ~validFlags,
324 }
325
327}
328
333WDFEXPORT(WdfRequestChangeTarget)(
334 __in
336 __in
337 WDFREQUEST Request,
338 __in
339 WDFIOTARGET IoTarget
340 )
341{
345
347 Request,
349 (PVOID*)&pRequest,
351
353 IoTarget,
355 (PVOID*)&pTarget);
356
358}
359
363 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
365 )
366{
368 KIRQL irql;
369
371
372 pRequest->Lock(&irql);
373
374 status = pRequest->VerifyRequestIsDriverOwned(FxDriverGlobals);
375 if (NT_SUCCESS(status)) {
376 status = pRequest->VerifyRequestCanBeCompleted(FxDriverGlobals);
377 }
378
380 return status;
381}
382
384VOID
385WDFAPI
387WDFEXPORT(WdfRequestComplete)(
388 __in
390 __in
391 WDFREQUEST Request,
392 __in
394 )
395
396/*++
397
398Routine Description:
399
400 Complete the request with supplied status.
401
402 Any default reference counts implied by handle are invalid after
403 completion.
404
405Arguments:
406
407 Request - Handle to the Request object
408
409 RequestStatus - Wdm Status to complete the request with
410
411Returns:
412
413 None
414
415--*/
416{
419
420 //
421 // Validate the request handle, and get the FxRequest*
422 //
424 Request,
426 (PVOID*)&pRequest);
427#if FX_VERBOSE_TRACE
428 //
429 // Use object's globals, not the caller's
430 //
433 "Completing WDFREQUEST 0x%p, %!STATUS!",
435#endif
438 return;
439 }
440
442}
443
445VOID
446WDFAPI
448WDFEXPORT(WdfRequestCompleteWithPriorityBoost)(
449 __in
451 __in
452 WDFREQUEST Request,
453 __in
455 __in
457 )
458
459/*++
460
461Routine Description:
462
463 Complete the request with supplied status.
464
465 Any default reference counts implied by handle are invalid after
466 completion.
467
468Arguments:
469
470 Request - Handle to the Request object
471
472 RequestStatus - Wdm Status to complete the request with
473
474 PriorityBoost - A system-defined constant value by which to increment the
475 run-time priority of the original thread that requested the operation.
476
477Returns:
478
479 None
480
481--*/
482
483{
486
487 //
488 // Validate the request handle, and get the FxRequest*
489 //
491 Request,
493 (PVOID*)&pRequest);
494
495#if FX_VERBOSE_TRACE
496 //
497 // Use the object's globals, not the caller's
498 //
501 "Completing WDFREQUEST 0x%p, %!STATUS!",
503#endif
505 pRequest);
506 if (!NT_SUCCESS(status)) {
507 return;
508 }
509
511}
512
514VOID
515WDFAPI
517WDFEXPORT(WdfRequestCompleteWithInformation)(
518 __in
520 __in
521 WDFREQUEST Request,
522 __in
524 __in
526 )
527
528/*++
529
530Routine Description:
531
532 Complete the request with supplied status and information.
533
534 Any default reference counts implied by handle are invalid after
535 completion.
536
537Arguments:
538
539 Request - Handle to the Request object
540
541 RequestStatus - Wdm Status to complete the request with
542
543 Information - Information to complete request with
544
545Returns:
546
547 None
548
549--*/
550
551{
554
555 //
556 // Validate the request handle, and get the FxRequest*
557 //
559 Request,
561 (PVOID*)&pRequest);
562
563#if FX_VERBOSE_TRACE
564 //
565 // Use the object's globals, not the caller's
566 //
569 "Completing WDFREQUEST 0x%p, %!STATUS!",
571#endif
573 if (!NT_SUCCESS(status)) {
574 return;
575 }
576
577
579}
580
582VOID
583WDFAPI
585WDFEXPORT(WdfRequestSetInformation)(
586 __in
588 __in
589 WDFREQUEST Request,
590 __in
592 )
593
594/*++
595
596Routine Description:
597
598 Set the transfer information for the request.
599
600 This sets the NT Irp->Status.Information field.
601
602Arguments:
603
604 Request - Handle to the Request object
605
606 Information - Value to be set
607
608Returns:
609
610 None
611
612--*/
613
614{
616
617 //
618 // Validate the request handle, and get the FxRequest*
619 //
621 Request,
623 (PVOID*)&pRequest);
624
625#if FX_VERBOSE_TRACE
626 //
627 // Use the object's globals, not the caller's
628 //
631 "Enter: WDFREQUEST 0x%p, Information 0x%p",
633#endif // FX_VERBOSE_TRACE
634
636}
637
640WDFAPI
642WDFEXPORT(WdfRequestGetInformation)(
643 __in
645 __in
646 WDFREQUEST Request
647 )
648
649/*++
650
651Routine Description:
652
653 Get the transfer information for the reuqest.
654
655
656Arguments:
657
658 Request - Handle to the Request object
659
660
661Returns:
662
663 Returns Irp->IoStatus.Information value.
664
665--*/
666
667{
669
670 //
671 // Validate the request handle, and get the FxRequest*
672 //
674 Request,
676 (PVOID*)&pRequest);
677
679}
680
684WDFAPI
686WDFEXPORT(WdfRequestRetrieveInputMemory)(
687 __in
689 __in
690 WDFREQUEST Request,
691 __out
692 WDFMEMORY *Memory
693 )
694/*++
695
696Routine Description:
697
698 Return the WDFMEMORY buffer associated with the request.
699
700 The memory buffer is valid in any thread/process context,
701 and may be accessed at IRQL > PASSIVE_LEVEL.
702
703 The memory buffer is automatically released when the request
704 is completed.
705
706 The memory buffers access permissions are validated according
707 to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may
708 only be accessed according to the access semantics of the request.
709
710 The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
711 or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are
712 configured for the device object.
713
714 The Memory buffer is as follows for each buffering mode:
715
716 DO_BUFFERED_IO:
717
718 Irp->AssociatedIrp.SystemBuffer
719
720 DO_DIRECT_IO:
721
722 MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
723
724 NEITHER flag set:
725
726 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
727 to access the request in the calling threads address space before
728 it is placed into any I/O Queues.
729
730 The buffer is only valid until the request is completed.
731
732Arguments:
733
734 Request - Handle to the Request object
735
736 Memory - Pointer location to return WDFMEMORY handle
737
738Returns:
739
740 NTSTATUS
741
742--*/
743
744{
750 size_t length;
751
752 pMemory = NULL;
753
754 //
755 // Validate the request handle, and get the FxRequest*
756 //
758 Request,
760 (PVOID*)&pRequest,
762
764
765#if FX_VERBOSE_TRACE
767 "Enter: WDFREQUEST 0x%p", Request);
768#endif // FX_VERBOSE_TRACE
769
770 //
771 // This call is not valid on Read request.
772 //
775
778 "This call is not valid on the Read request, you should call"
779 " WdfRequestRetrieveOutputMemory to get the Memory for WDFREQUEST "
780 "0x%p, %!STATUS!", Request, status);
781
782 return status;
783 }
784
786 if (NT_SUCCESS(status)) {
788 }
789
790 return status;
791}
792
796WDFAPI
798WDFEXPORT(WdfRequestRetrieveOutputMemory)(
799 __in
801 __in
802 WDFREQUEST Request,
803 __out
804 WDFMEMORY *Memory
805 )
806
807/*++
808
809Routine Description:
810
811 Return the WDFMEMORY buffer associated with the request.
812
813 The memory buffer is valid in any thread/process context,
814 and may be accessed at IRQL > PASSIVE_LEVEL.
815
816 The memory buffer is automatically released when the request
817 is completed.
818
819 The memory buffers access permissions are validated according
820 to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may
821 only be accessed according to the access semantics of the request.
822
823 The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
824 or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are
825 configured for the device object.
826
827 The Memory buffer is as follows for each buffering mode:
828
829 DO_BUFFERED_IO:
830
831 Irp->AssociatedIrp.SystemBuffer
832
833 DO_DIRECT_IO:
834
835 MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
836
837 NEITHER flag set:
838
839 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
840 to access the request in the calling threads address space before
841 it is placed into any I/O Queues.
842
843 The buffer is only valid until the request is completed.
844
845Arguments:
846
847 Request - Handle to the Request object
848
849 Memory - Pointer location to return WDFMEMORY handle
850
851Returns:
852
853 NTSTATUS
854
855--*/
856
857{
863 size_t length;
865
866 pMemory = NULL;
867
868 //
869 // Validate the request handle, and get the FxRequest*
870 //
872 Request,
874 (PVOID*)&pRequest,
876
878
879#if FX_VERBOSE_TRACE
881 "Enter: WDFREQUEST 0x%p", Request);
882#endif // FX_VERBOSE_TRACE
883
884 //
885 // This call is not valid on Write request.
886 //
888
891
894 "This call is not valid on the Write request, you should call"
895 " WdfRequestRetrieveInputMemory to get the Memory for WDFREQUEST "
896 "0x%p, %!STATUS!", Request, status);
897
898 return status;
899 }
900
904 }
905 else {
907 }
908
909 if (NT_SUCCESS(status)) {
911 }
912
913 return status;
914}
915
919WDFAPI
921WDFEXPORT(WdfRequestRetrieveInputBuffer)(
922 __in
924 __in
925 WDFREQUEST Request,
926 __in
931 size_t* Length
932 )
933/*++
934
935Routine Description:
936
937 Return the memory buffer associated with the request along
938 with its maximum length.
939
940 The memory buffer is valid in any thread/process context,
941 and may be accessed at IRQL > PASSIVE_LEVEL.
942
943 The memory buffer is automatically released when the request
944 is completed.
945
946 The memory buffers access permissions are validated according
947 to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may
948 only be accessed according to the access semantics of the request.
949
950 The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
951 or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are
952 configured for the device object.
953
954 The Memory buffer is as follows for each buffering mode:
955
956 DO_BUFFERED_IO:
957
958 Irp->AssociatedIrp.SystemBuffer
959
960 DO_DIRECT_IO:
961
962 MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
963
964 NEITHER flag set:
965
966 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
967 to access the request in the calling threads address space before
968 it is placed into any I/O Queues.
969
970 The buffer is only valid until the request is completed.
971
972Arguments:
973
974 Request - Handle to the Request object
975
976 RequiredLength - This is the minimum size expected by the caller
977
978 Buffer - Pointer location to return buffer ptr
979
980 Length - actual size of the buffer. This is >= to RequiredLength
981
982Returns:
983
984 NTSTATUS
985
986--*/
987{
993 size_t length;
994
995 pMemory = NULL;
996
997 //
998 // Validate the request handle, and get the FxRequest*
999 //
1001 Request,
1003 (PVOID*)&pRequest,
1005
1006 //
1007 // Validate the pointers and set its content to NULL
1008 //
1010 *Buffer = NULL;
1011
1012 if (Length != NULL) {
1013 *Length = 0;
1014 }
1015
1016#if FX_VERBOSE_TRACE
1018 "Enter: WDFREQUEST 0x%p", Request);
1019#endif //FX_VERBOSE_TRACE
1020
1021 //
1022 // This call is not valid on Read request.
1023 //
1026
1029 "This call is not valid on the read request, you should call"
1030 " WdfRequestRetrieveOutputBuffer to get the buffer for WDFREQUEST "
1031 "0x%p, %!STATUS!", Request, status);
1032
1033 return status;
1034 }
1035
1037
1038 if (NT_SUCCESS(status)) {
1039 if (length < RequiredLength) {
1041
1044 "WDFREQUEST 0x%p buffer size %I64d is less than RequiredLength "
1045 "%I64d, %!STATUS!", Request, length, RequiredLength, status);
1046
1047 return status;
1048 }
1049
1050 *Buffer = pBuffer;
1051
1052 if (Length != NULL) {
1053 *Length = length;
1054 }
1055 }
1056
1057 return status;
1058}
1059
1063WDFAPI
1064STDCALL
1065WDFEXPORT(WdfRequestRetrieveOutputBuffer)(
1066 __in
1068 __in
1069 WDFREQUEST Request,
1070 __in
1071 size_t RequiredLength,
1073 PVOID* Buffer,
1074 __out_opt
1075 size_t* Length
1076 )
1077/*++
1078
1079Routine Description:
1080
1081 Return the memory buffer associated with the request along
1082 with its maximum length.
1083
1084 The memory buffer is valid in any thread/process context,
1085 and may be accessed at IRQL > PASSIVE_LEVEL.
1086
1087 The memory buffer is automatically released when the request
1088 is completed.
1089
1090 The memory buffers access permissions are validated according
1091 to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may
1092 only be accessed according to the access semantics of the request.
1093
1094 The memory buffer is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
1095 or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are
1096 configured for the device object.
1097
1098 The Memory buffer is as follows for each buffering mode:
1099
1100 DO_BUFFERED_IO:
1101
1102 Irp->AssociatedIrp.SystemBuffer
1103
1104 DO_DIRECT_IO:
1105
1106 MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority)
1107
1108 NEITHER flag set:
1109
1110 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
1111 to access the request in the calling threads address space before
1112 it is placed into any I/O Queues.
1113
1114 The buffer is only valid until the request is completed.
1115
1116Arguments:
1117
1118 Request - Handle to the Request object
1119
1120 RequiredLength - This is the minimum size expected by the caller
1121
1122 Buffer - Pointer location to return buffer ptr
1123
1124 Length - actual size of the buffer. This is >= to RequiredLength
1125
1126Returns:
1127
1128 NTSTATUS
1129
1130--*/
1131{
1136 PVOID pBuffer;
1137 size_t length;
1139
1140 pMemory = NULL;
1141
1142 //
1143 // Validate the request handle, and get the FxRequest*
1144 //
1146 Request,
1148 (PVOID*)&pRequest,
1150
1151 //
1152 // Validate the pointers and set its content to NULL
1153 //
1155 *Buffer = NULL;
1156
1157 if (Length != NULL) {
1158 *Length = 0;
1159 }
1160
1161#if FX_VERBOSE_TRACE
1163 "Enter: WDFREQUEST 0x%p", Request);
1164#endif //FX_VERBOSE_TRACE
1165
1166 //
1167 // This call is not valid on Write request.
1168 //
1170
1171 if (majorFunction == IRP_MJ_WRITE) {
1173
1176 "This call is not valid on write request, you should call"
1177 " WdfRequestRetrieveInputBuffer to get the buffer for WDFREQUEST "
1178 "0x%p, %!STATUS!", Request, status);
1179
1180 return status;
1181 }
1182
1186 &pMemory, &pBuffer, &length);
1187 }
1188 else {
1190 }
1191
1192 if (NT_SUCCESS(status)) {
1193 if (length < RequiredLength) {
1195
1198 "WDFREQUEST 0x%p buffer size %I64d is less than RequiredLength "
1199 "%I64d, %!STATUS!", Request, length, RequiredLength, status);
1200
1201 return status;
1202 }
1203
1204 *Buffer = pBuffer;
1205
1206 if (Length != NULL) {
1207 *Length = length;
1208 }
1209 }
1210
1211 return status;
1212}
1213
1217WDFAPI
1218STDCALL
1219WDFEXPORT(WdfRequestRetrieveUnsafeUserInputBuffer)(
1220 __in
1222 __in
1223 WDFREQUEST Request,
1224 __in
1225 size_t RequiredLength,
1228 __out_opt
1229 size_t* Length
1230 )
1231/*++
1232
1233Routine Description:
1234
1235 Returns input buffer of a method-neither request. This function can be
1236 called only in the context of EvtDeviceIoInProcessContextCallback at
1237 PASSIVE_LEVEL.
1238
1239 This call is valid on public IOCTL and Write request.
1240
1241 The returned buffer is valid only in the caller's process context. This
1242 call should be typically used in a toplevel or monolithic driver to
1243 guarantee the caller's context.
1244
1245
1246 The Memory buffer is as follows for each type of request:
1247
1248 For IOCTL, it will return irpStack->Parameters.DeviceIoControl.Type3InputBuffer
1249
1250 For Write, it will return Irp->UserBuffer.
1251
1252 For read and internal-device control and other type of request, this call
1253 will return an error.
1254
1255
1256Arguments:
1257
1258 Request - Handle to the Request object
1259
1260 RequiredLength - minimum length of the buffer expected by the caller.
1261 If it's not this call will return an error.
1262
1263
1264 InputBuffer - Pointer location to return buffer ptr
1265
1266 Length - actual size of the buffer. This is >= to RequiredLength
1267
1268Returns:
1269
1270 NTSTATUS
1271
1272--*/
1273{
1279
1280 //
1281 // Validate the request handle, and get the FxRequest*
1282 //
1284 Request,
1286 (PVOID*)&pRequest,
1288
1289#if FX_VERBOSE_TRACE
1291 "Enter: WDREQUEST 0x%p", Request);
1292#endif // FX_VERBOSE_TRACE
1293
1295 *InputBuffer = NULL;
1296
1297 if (Length != NULL) {
1298 *Length = 0;
1299 }
1300
1302 if (!NT_SUCCESS(status)) {
1303 return status;
1304 }
1305
1306 //
1307 // Make sure this function is called in the context of in-process callback
1308 //
1309 if (pFxDriverGlobals->FxVerifierOn) {
1310 KIRQL irql;
1311
1312 pRequest->Lock(&irql);
1313
1314 status = pRequest->VerifyRequestIsInCallerContext(pFxDriverGlobals);
1315
1317
1318 if (!NT_SUCCESS(status)) {
1319 return status;
1320 }
1321 }
1322
1324
1326
1327 //
1328 // This call is not valid on Read request.
1329 //
1331
1332 if (majorFunction == IRP_MJ_READ) {
1334
1337 "This call is not valid on read request, you should call"
1338 " WdfRequestRetrieveUnsafeUserOutputBuffer to get the buffer for "
1339 "WDFREQUEST 0x%p, %!STATUS!", Request, status);
1340
1341 return status;
1342 }
1343
1346
1349 "This call is not valid on internal-ioctl request, you should call"
1350 " safer WdfRequestRetrieveInputBuffer to get the buffer for "
1351 "WDFREQUEST 0x%p, %!STATUS!", Request, status);
1352
1353 return status;
1354 }
1355
1358
1361
1364 "WDFREQUEST %p buffer size %d is less than RequiredLength %I64d,"
1365 " %!STATUS!",
1368
1369 return status;
1370 }
1371
1373 if (Length != NULL) {
1375 }
1376
1377 return STATUS_SUCCESS;
1378
1379 }
1380 else if (majorFunction == IRP_MJ_WRITE &&
1382
1385
1388 "WDFREQUEST 0x%p buffer size %d is less than RequiredLength "
1389 "%I64d, %!STATUS!",
1391 status);
1392
1393 return status;
1394 }
1395
1397 if (Length != NULL) {
1399 }
1400
1401 return STATUS_SUCCESS;
1402
1403 } else {
1405
1407 "Error: This call is valid only on method-neither "
1408 "ioctl and write WDFREQUEST %p, %!STATUS!",
1409 Request, status);
1411
1412 return status;
1413 }
1414
1415 // NOTREACHED
1416}
1417
1421WDFAPI
1422STDCALL
1423WDFEXPORT(WdfRequestRetrieveUnsafeUserOutputBuffer)(
1424 __in
1426 __in
1427 WDFREQUEST Request,
1428 __in
1429 size_t RequiredLength,
1432 __out_opt
1433 size_t* Length
1434 )
1435/*++
1436
1437Routine Description:
1438
1439 Returns output buffer of a method-neither request. This function can be called only
1440 in the context of EvtDeviceIoInProcessContextCallback at PASSIVE_LEVEL.
1441
1442 This call is valid on public IOCTL and Read request.
1443
1444 The returned buffer is valid only in the caller's process context. This call should
1445 be typically used in a toplevel or monolithic driver to guarantee the caller's context.
1446
1447
1448 The Memory buffer is as follows for each type of request:
1449
1450 For IOCTL, it will return Irp->UserBuffer
1451
1452 For Read, it will return Irp->UserBuffer.
1453
1454 For Write and internal-device control and other type of request, this call will return an error.
1455
1456
1457Arguments:
1458
1459 Request - Handle to the Request object
1460
1461 RequiredLength - minimum length of the buffer expected by the caller. If it's not
1462 this call will return an error.
1463
1464
1465 OutputBuffer - Pointer location to return buffer ptr
1466
1467 Length - actual size of the buffer. This is >= to RequiredLength
1468
1469
1470Returns:
1471
1472 NTSTATUS
1473
1474--*/
1475{
1481
1482 //
1483 // Validate the request handle, and get the FxRequest*
1484 //
1486 Request,
1488 (PVOID*)&pRequest,
1490
1492 *OutputBuffer = NULL;
1493
1494 if (Length != NULL) {
1495 *Length = 0;
1496 }
1497
1499 if (!NT_SUCCESS(status)) {
1500 return status;
1501 }
1502
1503 //
1504 // Make sure this function is called in the context of in-process callback
1505 //
1506 if (pFxDriverGlobals->FxVerifierOn) {
1507 KIRQL irql;
1508
1509 pRequest->Lock(&irql);
1510
1511 status = pRequest->VerifyRequestIsInCallerContext(pFxDriverGlobals);
1512
1514
1515 if (!NT_SUCCESS(status)) {
1516 return status;
1517 }
1518 }
1519
1520#if FX_VERBOSE_TRACE
1522 "Enter: WDFREQUEST 0x%p", pRequest);
1523#endif // FX_VERBOSE_TRACE
1524
1525 FxIrp* irp = pRequest->GetFxIrp();
1527
1528 //
1529 // This call is not valid on Write request.
1530 //
1532
1533 if (majorFunction == IRP_MJ_WRITE) {
1535
1538 "This call is not valid on Write request, you should call"
1539 " WdfRequestRetrieveUnsafeUserInputBuffer to get the buffer for "
1540 "WDFREQUEST 0x%p, %!STATUS!", Request, status);
1541
1542 return status;
1543
1544 }
1545
1548
1551 "This call is not valid on an internal IOCTL request, you should call"
1552 " safer WdfRequestRetrieveOutputBuffer to get the buffer for "
1553 "WDFREQUEST 0x%p, %!STATUS!", Request, status);
1554
1555 return status;
1556 }
1557
1560
1563
1566 "WDFREQUEST 0x%p buffer size %d is less than RequiredLength "
1567 "%I64d, %!STATUS!",
1570
1571 return status;
1572 }
1573
1575
1576 if (Length != NULL) {
1578 }
1579
1580 return STATUS_SUCCESS;
1581
1582 } else if (majorFunction == IRP_MJ_READ &&
1584
1587
1590 "WDFREQUEST 0x%p buffer size %d is less than RequiredLength "
1591 "%I64d, %!STATUS!",
1593 status);
1594
1595 return status;
1596 }
1597
1599 if (Length != NULL) {
1601 }
1602
1603 return STATUS_SUCCESS;
1604
1605 } else {
1607
1610 "Error: This call is valid only on method-neither ioctl and read "
1611 "WDFREQUEST 0x%p, %!STATUS!", Request, status);
1612
1613 return status;
1614 }
1615
1616 // NOTREACHED
1617}
1618
1619
1623WDFAPI
1624STDCALL
1625WDFEXPORT(WdfRequestRetrieveInputWdmMdl)(
1626 __in
1628 __in
1629 WDFREQUEST Request,
1632 )
1633
1634/*++
1635
1636Routine Description:
1637
1638 Return the MDL associated with the request.
1639
1640 The MDL is automatically released when the request is completed.
1641
1642 The MDL's access permissions are validated according
1643 to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may
1644 only be accessed according to the access semantics of the request.
1645
1646 The MDL is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
1647 or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are
1648 configured for the device object.
1649
1650 The MDL is as follows for each buffering mode:
1651
1652 DO_BUFFERED_IO:
1653
1654 MmBuildMdlForNonPagedPool(IoAllocateMdl(Irp->AssociatedIrp.SystemBuffer, ... ))
1655
1656 DO_DIRECT_IO:
1657
1658 Irp->MdlAddress
1659
1660 NEITHER flag set:
1661
1662 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
1663 to access the request in the calling threads address space before
1664 it is placed into any I/O Queues.
1665
1666 The MDL is only valid until the request is completed.
1667
1668Arguments:
1669
1670 Request - Handle to the Request object
1671
1672 Mdl - Pointer location to return MDL ptr
1673
1674Returns:
1675
1676 NTSTATUS
1677
1678--*/
1679
1680{
1684
1685 //
1686 // Validate the request handle, and get the FxRequest*
1687 //
1689 Request,
1691 (PVOID*)&pRequest,
1693
1695 *Mdl = NULL;
1696
1697#if FX_VERBOSE_TRACE
1699 "Enter: WDFREQUEST 0x%p", Request);
1700#endif // FX_VERBOSE_TRACE
1701
1702 //
1703 // This call is not valid on Read request.
1704 //
1708 "This call is not valid on the Read request, you should call"
1709 " WdfRequestRetrieveOutputMdl to get the Mdl for WFDREQUEST 0x%p, "
1710 " %!STATUS!", Request, STATUS_INVALID_DEVICE_REQUEST);
1711
1713 }
1714
1716
1717 return status;
1718}
1719
1723WDFAPI
1724STDCALL
1725WDFEXPORT(WdfRequestRetrieveOutputWdmMdl)(
1726 __in
1728 __in
1729 WDFREQUEST Request,
1731 PMDL *Mdl
1732 )
1733
1734/*++
1735
1736Routine Description:
1737
1738 Return the MDL associated with the request.
1739
1740 The MDL is automatically released when the request is completed.
1741
1742 The MDL's access permissions are validated according
1743 to the command type (IRP_MJ_READ, IRP_MJ_WRITE), and may
1744 only be accessed according to the access semantics of the request.
1745
1746 The MDL is not valid for a METHOD_NEITHER IRP_MJ_DEVICE_CONTROL,
1747 or if neither of the DO_BUFFERED_IO or DO_DIRECT_IO flags are
1748 configured for the device object.
1749
1750 The MDL is as follows for each buffering mode:
1751
1752 DO_BUFFERED_IO:
1753
1754 MmBuildMdlForNonPagedPool(IoAllocateMdl(Irp->AssociatedIrp.SystemBuffer, ... ))
1755
1756 DO_DIRECT_IO:
1757
1758 Irp->MdlAddress
1759
1760 NEITHER flag set:
1761
1762 NULL. Must use WdfDeviceInitSetIoInCallerContextCallback in order
1763 to access the request in the calling threads address space before
1764 it is placed into any I/O Queues.
1765
1766 The MDL is only valid until the request is completed.
1767
1768Arguments:
1769
1770 Request - Handle to the Request object
1771
1772 Mdl - Pointer location to return MDL ptr
1773
1774Returns:
1775
1776 NTSTATUS
1777
1778--*/
1779
1780{
1785
1786 //
1787 // Validate the request handle, and get the FxRequest*
1788 //
1790 Request,
1792 (PVOID*)&pRequest,
1794
1796 *Mdl = NULL;
1797
1798#if FX_VERBOSE_TRACE
1800 "Enter: WDFREQUEST 0x%p", Request);
1801#endif // FX_VERBOSE_TRACE
1802
1803 //
1804 // This call is not valid on Write request.
1805 //
1807 if (majorFunction == IRP_MJ_WRITE) {
1810 "This call is not valid on the Write request, you should call"
1811 " WdfRequestRetrieveInputMemory to get the Memory for WDFREQUEST 0x%p, "
1813
1815 }
1816
1820 }
1821 else {
1823 }
1824
1825 return status;
1826}
1827
1828void
1830 VOID
1831 )
1832/*++
1833
1834Routine Description:
1835 Make sure our assumptions about using the passed in parameters as locals
1836 does not exceed the space allocated on the stack for the passed in variables,
1837 otherwise we could corrupt the stack.
1838
1839 *DO NOT REMOVE* this function even though no code calls it. Because it uses
1840 WDFCASSERT, if our assumptions were false, it would not compile.
1841
1842Arguments:
1843 None.
1844
1845Return Value:
1846 None
1847
1848 --*/
1849{
1850 // ActionUnion check
1851 WDFCASSERT(sizeof(ULONG) <= sizeof(PWDF_DRIVER_GLOBALS));
1852 // RequestUnion check
1853 WDFCASSERT(sizeof(FxRequest*) <= sizeof(WDFREQUEST));
1854 // TargetUnion check
1855 WDFCASSERT(sizeof(FxIoTarget*) <= sizeof(WDFIOTARGET));
1856}
1857
1858#define GLOBALS_ACTION(globals) ((ULONG)(ULONG_PTR)(globals))
1859#define PGLOBALS_ACTION(globals) ((PULONG)(PULONG_PTR)(globals))
1860
1861#define GLOBALS_DEVICE(globals) ((FxDevice*)(ULONG_PTR)(globals))
1862#define PGLOBALS_DEVICE(globals) ((FxDevice**)(PULONG_PTR)(globals))
1863
1864#define WDFREQUEST_FXREQUEST(handle) ((FxRequest*)(handle))
1865#define WDFIOTARGET_FXIOTARGET(handle) ((FxIoTarget*)(handle))
1866
1869BOOLEAN
1870STDCALL
1872 __in
1874 __in
1875 WDFREQUEST Request,
1876 __in
1877 WDFIOTARGET Target,
1878 __in_opt
1880 )
1881/*++
1882
1883Routine Description:
1884 Sends a previously created and formatted request to the target device
1885 object. The target device object will typically be the device object that
1886 this device is attached to. The submission can also be controlled by a set
1887 of options.
1888
1889Arguments:
1890 Request - The request to be submitted
1891
1892 Target - The target of the request
1893
1894 Options - Optional options applied to the sending of the request
1895
1896 In the aggressive attempt to conserve stack space, the passed in parameters
1897 are unionized with the locals this function would need. On an optimized
1898 build, the compiler may already do this, but we want to be extra aggressive
1899 and ensure that this type of stack reuse is done.
1900
1901Return Value:
1902 TRUE if the request was sent to the target, FALSE otherwise.
1903
1904 To retrieve the status of the request, call WdfRequestGetStatus.
1905 WdfRequestGetStatus should only be called if WdfRequestSend returns FALSE
1906 or if the caller specified that the request be synchronous in
1907 WDF_REQUEST_SEND_OPTIONS. Otherwise, the request is asynchronous and the status
1908 will be returned in the request's completion routine.
1909
1910 --*/
1911{
1912 //
1913 // Validate the request handle, and get the FxRequest*
1914 //
1916 Request,
1918 (PVOID*) &Request);
1919
1920 //
1921 // Request stack memory now holds an FxRequest pointer.
1922 // Request as a handle is no longer valid!
1923 //
1925 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
1927
1929
1931 return FALSE;
1932 }
1933
1935 Target,
1937 (PVOID*) &Target);
1938
1939 //
1940 // Target stack memory now hold an FxIoTarget pointer.
1941 // Target as a handle is no longer valid!
1942 //
1943 if (Options != NULL &&
1946
1948 //
1949 // This sets impersonation flags for UMDF. Noop for KMDF.
1950 //
1951 WDFREQUEST_FXREQUEST(Request)->SetImpersonationFlags(Options->Flags);
1952
1954 (void) WDFIOTARGET_FXIOTARGET(Target)->SubmitSync(
1956 Options,
1958 );
1959 }
1961 if (WDFREQUEST_FXREQUEST(Request)->IsAllocatedFromIo() == FALSE) {
1963 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
1965 "WDFREQUEST %p must be a WDFQUEUE presented request",
1967
1968 WDFREQUEST_FXREQUEST(Request)->SetStatus(
1970 );
1971
1973 }
1974 else if (WDFREQUEST_FXREQUEST(Request)->HasContext()) {
1975 //
1976 // Cannot send-and-forget a request with formatted IO context.
1977 //
1979 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
1981 "Cannot send-and-forget WDFREQUEST 0x%p with formatted IO"
1982 " context, %!STATUS!",
1985
1986 WDFREQUEST_FXREQUEST(Request)->SetStatus(
1988 );
1989
1991
1993 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals());
1994 }
1995 else {
1996 //
1997 // We split processing into pre and post processing to reduce
1998 // stack usage (by not making the call to IoCallDriver in a
1999 // deep function.
2000 //
2001
2002 //
2003 // This will skip the current stack location
2004 //
2005 WDFREQUEST_FXREQUEST(Request)->PreProcessSendAndForget();
2006
2007 //
2008 // This sets impersonation flags for UMDF. Noop for KMDF.
2009 //
2010 WDFREQUEST_FXREQUEST(Request)->SetImpersonationFlags(Options->Flags);
2011
2012 MdIrp submitIrp = WDFREQUEST_FXREQUEST(Request)->GetSubmitIrp();
2013
2014 WDFIOTARGET_FXIOTARGET(Target)->Send(submitIrp);
2015
2016 //
2017 // This will free the request memory and pop the queue
2018 //
2019 WDFREQUEST_FXREQUEST(Request)->PostProcessSendAndForget();
2020 return TRUE;
2021 }
2022 }
2023 }
2024 else if (WDFREQUEST_FXREQUEST(Request)->IsCompletionRoutineSet() == FALSE &&
2025 WDFREQUEST_FXREQUEST(Request)->IsAllocatedFromIo()) {
2026 //
2027 // Cannot send an asynchronous queue presented request without a
2028 // completion routine.
2029 //
2031 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
2033 "WDFREQUEST %p is a WDFQUEUE presented request with no"
2034 " completion routine, %!STATUS!",
2037
2038 WDFREQUEST_FXREQUEST(Request)->SetStatus(
2040 );
2041
2043
2045 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals());
2046 }
2047 else {
2048#if FX_VERBOSE_TRACE
2050 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
2052 "Enter: WDFIOTARGET %p, WDFREQUEST %p",
2055#endif // FX_VERBOSE_TRACE
2056
2057 //
2058 // This sets impersonation flags for UMDF. Noop for KMDF.
2059 //
2060 if (Options != NULL) {
2061 WDFREQUEST_FXREQUEST(Request)->SetImpersonationFlags(Options->Flags);
2062 }
2063
2064 //
2065 // Submit will return whether the request should be sent *right now*.
2066 // If SubmitSend is clear, then SubmitQueued must be checked. If set,
2067 // then the request was queued, otherwise, the request has failed.
2068 //
2069 // NOTE: by calling FxIoTarget::Submit instead of acquiring the lock
2070 // in this call frame, we don't have expend stack space for the KIRQL
2071 // storage
2072 //
2076 Options,
2077 (Options != NULL) ? Options->Flags : 0
2078 );
2079
2080 // DriverGlobals stack memory now hold a ULONG action value.
2081 // DriverGlobals as a pointer is no longer valid!
2082
2083#if FX_VERBOSE_TRACE
2085 WDFIOTARGET_FXIOTARGET(Target)->GetDriverGlobals(),
2087 "action 0x%x", GLOBALS_ACTION(DriverGlobals));
2088#endif // FX_VERBOSE_TRACE
2089
2091
2093
2095
2096#if FX_VERBOSE_TRACE
2098 WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
2100 "Sending FxRequest %p (WDFREQUEST %p), Irp %p",
2103 WDFREQUEST_FXREQUEST(Request)->GetSubmitIrp());
2104#endif // FX_VERBOSE_TRACE
2105
2106 MdIrp submitIrp = WDFREQUEST_FXREQUEST(Request)->GetSubmitIrp();
2107
2108 WDFIOTARGET_FXIOTARGET(Target)->Send(submitIrp);
2109 }
2111 //
2112 // To the caller, we saw and sent the request (and all the cancel
2113 // semantics of a sent request still work).
2114 //
2116 }
2117 }
2118
2120}
2121
2125STDCALL
2126WDFEXPORT(WdfRequestGetStatus)(
2127 __in
2129 __in
2130 WDFREQUEST Request
2131 )
2132{
2134
2136 Request,
2138 (PVOID*)&pRequest);
2139
2141}
2142
2144BOOLEAN
2145WDFAPI
2146STDCALL
2147WDFEXPORT(WdfRequestCancelSentRequest)(
2148 __in
2150 __in
2151 WDFREQUEST Request
2152 )
2153
2154/*++
2155
2156Routine Description:
2157 Cancels a previously submitted request.
2158
2159Arguments:
2160 Request - The previously submitted request
2161
2162Return Value:
2163 TRUE if the cancel was *attempted*. The caller must still synchronize with
2164 the request's completion routine since TRUE just means the owner of the
2165 request was successfully asked to cancel the request.
2166
2167 --*/
2168
2169{
2173
2174 //
2175 // Validate the request handle, and get the FxRequest*
2176 //
2178 Request,
2180 (PVOID*)&pRequest,
2182
2184 "Enter: WDFREQUEST %p to be cancelled", Request);
2185
2186 result = pRequest->Cancel();
2187
2188#if FX_VERBOSE_TRACE
2190 "Exit: WDFREQUEST %p, result %d", Request, result);
2191#endif // FX_VERBOSE_TRACE
2192
2193 return result;
2194}
2195
2198BOOLEAN
2199STDCALL
2200WDFEXPORT(WdfRequestIsFrom32BitProcess)(
2201 __in
2203 __in
2204 WDFREQUEST Request
2205 )
2206/*++
2207
2208Routine Description:
2209 Indicates to the caller if the I/O request originated in a 32 bit process
2210 or not. On 32 bit systems, this function always returns TRUE.
2211
2212Arguments:
2213 Request - The request being queried
2214
2215Return Value:
2216 TRUE if the request came from a 32 bit process, FALSE otherwise.
2217
2218 --*/
2219
2220{
2224
2226 Request,
2228 (PVOID*) &pRequest,
2230
2232
2233#if FX_VERBOSE_TRACE
2235 "Enter: WDFREQUEST %p is from 32 bit process = %d",
2236 Request, result);
2237#endif // FX_VERBOSE_TRACE
2238
2239 return result;
2240}
2241
2243
2244VOID
2245STDCALL
2246WDFEXPORT(WdfRequestFormatRequestUsingCurrentType)(
2247 __in
2249 __in
2250 WDFREQUEST Request
2251 )
2252/*++
2253
2254Routine Description:
2255 Copies the current Irp stack location to the next one. This is the
2256 equivalent of IoCopyCurrentIrpStackLocationToNext.
2257
2258Arguments:
2259 Request - The request that will be formatted.
2260
2261Return Value:
2262 None
2263
2264 --*/
2265
2266{
2269 FxIrp* irp;
2270
2271 //
2272 // Validate the request handle, and get the FxRequest*
2273 //
2275 Request,
2277 (PVOID*)&pRequest,
2279
2280#if FX_VERBOSE_TRACE
2282 "Enter: WDFREQUEST %p", Request);
2283#endif // FX_VERBOSE_TRACE
2284
2286
2287 if (irp->GetIrp() == NULL) {
2291 (ULONG_PTR) Request);
2292 return; // not reached
2293 }
2294
2295 //
2296 // 1 is the minimum for CurrentLocation. Since the next stack location is
2297 // CurrentLocation-1, the CurrentLocation must be at least 2.
2298 //
2299 if (irp->HasStack(2) == FALSE) {
2303 (ULONG_PTR) irp->GetIrp());
2304 return; // not reached
2305 }
2306
2309
2311}
2312
2314VOID
2315WDFAPI
2316STDCALL
2317WDFEXPORT(WdfRequestWdmFormatUsingStackLocation)(
2318 __in
2320 __in
2321 WDFREQUEST Request,
2322 __in
2324 )
2325
2326/*++
2327
2328Routine Description:
2329 Sets the next IRP stack location to the one provided by the caller. The
2330 Context and CompletionRoutine values will be ignored. If the caller wants
2331 to set a completion routine, WdfRequestSetCompletionRoutine should be used
2332 instead.
2333
2334Arguments:
2335 Request - The request to be formatted
2336
2337 Stack - A pointer to an IO_STACK_LOCATION structure that contains
2338 driver-supplied information
2339
2340Return Value:
2341 None.
2342
2343 --*/
2344
2345{
2349
2350 //
2351 // Validate the request handle, and get the FxRequest*
2352 //
2354 Request,
2356 (PVOID*)&pRequest,
2358
2360
2361#if FX_VERBOSE_TRACE
2363 "Enter: WDFREQUEST %p", Request);
2364#endif // FX_VERBOSE_TRACE
2365
2367
2368 if (pIrp == NULL) {
2372 (ULONG_PTR) Request);
2373 return; // not reached
2374 }
2375
2376 //
2377 // 1 is the minimum for CurrentLocation. Since the next stack location is
2378 // CurrentLocation-1, the CurrentLocation must be at least 2.
2379 //
2384 (ULONG_PTR) pIrp);
2385 return; // not reached
2386 }
2387
2390
2392}
2393
2395VOID
2396WDFAPI
2397STDCALL
2398WDFEXPORT(WdfRequestSetCompletionRoutine)(
2399 __in
2401 __in
2402 WDFREQUEST Request,
2403 __in_opt
2405 __in_opt
2407 )
2408{
2411
2412 //
2413 // Validate the request handle, and get the FxRequest*
2414 //
2416 Request,
2418 (PVOID*)&pRequest,
2420
2421#if FX_VERBOSE_TRACE
2424 "Enter: WDFREQUEST %p, Routine %p, Context %p",
2426#endif // FX_VERBOSE_TRACE
2427
2429
2430 return;
2431}
2432
2434VOID
2435WDFAPI
2436STDCALL
2437WDFEXPORT(WdfRequestGetParameters)(
2438 __in
2440 __in
2441 WDFREQUEST Request,
2442 __out
2444 )
2445{
2448
2449 //
2450 // Validate the request handle, and get the FxRequest*
2451 //
2453 Request,
2455 (PVOID*)&pRequest,
2457
2459
2460#if FX_VERBOSE_TRACE
2462 "Enter: Request %p, Parameters %p", Request, Parameters);
2463#endif // FX_VERBOSE_TRACE
2464
2465 if (Parameters->Size != sizeof(WDF_REQUEST_PARAMETERS)) {
2467 "Params size %d incorrect, expected %d",
2468 Parameters->Size, sizeof(WDF_REQUEST_PARAMETERS));
2469
2471
2472 return;
2473 }
2474
2475
2476
2477
2479
2480 return;
2481}
2482
2484VOID
2485WDFAPI
2486STDCALL
2487WDFEXPORT(WdfRequestGetCompletionParams)(
2488 __in
2490 __in
2491 WDFREQUEST Request,
2492 __out
2494 )
2495{
2498
2499 //
2500 // Validate the request handle, and get the FxRequest*
2501 //
2503 Request,
2505 (PVOID*)&pRequest,
2507
2508#if FX_VERBOSE_TRACE
2510 "Enter: WDFREQUEST %p, Params %p", Request, Params);
2511#endif // FX_VERBOSE_TRACE
2512
2514
2518 "Params Size 0x%x, expected 0x%x",
2519 Params->Size, sizeof(WDF_REQUEST_COMPLETION_PARAMS));
2521 return;
2522 }
2523
2525
2526 return;
2527
2528}
2529
2531MdIrp
2532WDFAPI
2533STDCALL
2534WDFEXPORT(WdfRequestWdmGetIrp)(
2535 __in
2537 __in
2538 WDFREQUEST Request
2539 )
2540
2541/*++
2542
2543Routine Description:
2544
2545 This routine returns the WDM IRP associated with the given
2546 request.
2547
2548 The WDM IRP is invalid once WdfRequestComplete is called, regardless
2549 of any reference counts on the WDFREQUEST object.
2550
2551Arguments:
2552
2553 Request - Handle to the Request object
2554
2555Returns:
2556
2557 PIRP
2558
2559--*/
2560
2561{
2565 MdIrp irp;
2566
2567 //
2568 // Validate the request handle, and get the FxRequest*
2569 //
2571 Request,
2573 (PVOID*)&pRequest,
2575
2576#if FX_VERBOSE_TRACE
2578 "Enter: WDFREQUEST 0x%p", Request);
2579#endif // FX_VERBOSE_TRACE
2580
2582
2583 if (!NT_SUCCESS(status)) {
2585 "WDFREQUEST is already completed 0x%p, %!STATUS!",
2586 Request, status);
2588 return NULL;
2589 }
2590
2591 return irp;
2592}
2593
2597WDFAPI
2598STDCALL
2599WDFEXPORT(WdfRequestAllocateTimer)(
2600 __in
2602 __in
2603 WDFREQUEST Request
2604 )
2605/*++
2606
2607Routine Description:
2608 Preallocates a timer to be associated with the passed in request object.
2609 By preallocating the timer, WdfSendRequest cannot fail with insufficient
2610 resources when attempting to allocate a timer when a timeout constraint has
2611 been passed in.
2612
2613 If the request already has a timer allocated for it, then the function will
2614 succeed.
2615
2616Arguments:
2617 Request - the request to allocate a timer for
2618
2619Return Value:
2620 NT_SUCCESS upon success, STATUS_INSUFFICIENT_RESOURCES upon failure
2621
2622 --*/
2623
2624{
2626
2627 //
2628 // Validate the request handle, and get the FxRequest*
2629 //
2631 Request,
2633 (PVOID*)&pRequest);
2634
2636}
2637
2639WDFFILEOBJECT
2640WDFAPI
2641STDCALL
2642WDFEXPORT(WdfRequestGetFileObject)(
2643 __in
2645 __in
2646 WDFREQUEST Request
2647 )
2648
2649/*++
2650
2651Routine Description:
2652
2653 This routine returns the WDFFILEOBJECT associated with the given
2654 request.
2655
2656Arguments:
2657
2658 Request - Handle to the Request object
2659
2660Returns:
2661
2662 WDFFILEOBJECT handle.
2663
2664--*/
2665
2666{
2671
2672 //
2673 // Validate the request handle, and get the FxRequest*
2674 //
2676 Request,
2678 (PVOID*) &pRequest,
2680
2681 pFO = NULL;
2682
2683#if FX_VERBOSE_TRACE
2685 "Enter: WDFREQUEST 0x%p", Request);
2686#endif // FX_VERBOSE_TRACE
2687
2689 1,9, OkForDownLevel)) {
2690 KIRQL irql;
2691
2692 pRequest->Lock(&irql);
2693 status = pRequest->VerifyRequestIsDriverOwned(pFxDriverGlobals);
2695 if (!NT_SUCCESS(status)) {
2696 return NULL;
2697 }
2698 }
2699
2701 if (!NT_SUCCESS(status)) {
2703 "GetFileobject failed with %!STATUS!", status);
2704 return NULL;
2705 }
2706 else if (NULL == pFO) {
2707 //
2708 // Success and NULL file object: driver during init told us that it
2709 // knows how to handle NULL file objects.
2710 //
2711 return NULL;
2712 }
2713
2714 return pFO->GetHandle();
2715}
2716
2720WDFAPI
2721STDCALL
2722WDFEXPORT(WdfRequestProbeAndLockUserBufferForRead)(
2723 __in
2725 __in
2726 WDFREQUEST Request,
2728 PVOID Buffer,
2729 __in
2730 size_t Length,
2731 __out
2732 WDFMEMORY* MemoryObject
2733 )
2734
2735/*++
2736
2737Routine Description:
2738
2739 This routine probes and locks the specified user mode address into
2740 an MDL, and associates it with the WDFREQUEST object.
2741
2742 The MDL, and its associated system buffer is represented by a WDFMEMORY
2743 object.
2744
2745 The WDFMEMORY object and the MDL is automatically released when the
2746 WDFREQUEST is completed by WdfRequestComplete.
2747
2748Arguments:
2749
2750 Request - Handle to the Request object
2751
2752 Buffer - Buffer to probe and lock into an MDL
2753
2754 Length - Length of buffer
2755
2756 MemoryObject - Location to return WDFMEMORY handle
2757
2758Returns:
2759
2760 NTSTATUS
2761
2762--*/
2763
2764{
2769
2770 //
2771 // Validate the request handle, and get the FxRequest*
2772 //
2774 Request,
2776 (PVOID*)&pRequest,
2778
2781 *MemoryObject = NULL;
2782
2784 if (!NT_SUCCESS(status)) {
2785 return status;
2786 }
2787
2788#if FX_VERBOSE_TRACE
2790 "Enter: WDFREQUEST 0x%p", Request);
2791#endif // FX_VERBOSE_TRACE
2792
2794 1,9, OkForDownLevel)) {
2795 KIRQL irql;
2796
2797 pRequest->Lock(&irql);
2798 status = pRequest->VerifyRequestIsDriverOwned(pFxDriverGlobals);
2800 if (!NT_SUCCESS(status)) {
2801 return status;
2802 }
2803 }
2804
2806
2807 if (!NT_SUCCESS(status)) {
2810 "ProbeAndLockForRead failed with %!STATUS!", status);
2811 return status;
2812 }
2813
2814 *MemoryObject = (WDFMEMORY) pMemory->GetObjectHandle();
2815
2816 return status;
2817}
2818
2822WDFAPI
2823STDCALL
2824WDFEXPORT(WdfRequestProbeAndLockUserBufferForWrite)(
2825 __in
2827 __in
2828 WDFREQUEST Request,
2830 PVOID Buffer,
2831 __in
2832 size_t Length,
2833 __out
2834 WDFMEMORY* MemoryObject
2835 )
2836
2837/*++
2838
2839Routine Description:
2840
2841 This routine probes and locks the specified user mode address into
2842 an MDL, and associates it with the WDFREQUEST object.
2843
2844 The MDL, and its associated system buffer is represented by a WDFMEMORY
2845 object.
2846
2847 The WDFMEMORY object and the MDL is automatically released when the
2848 WDFREQUEST is completed by WdfRequestComplete.
2849
2850Arguments:
2851
2852 Request - Handle to the Request object
2853
2854 Buffer - Buffer to probe and lock into an MDL
2855
2856 Length - Length of buffer
2857
2858 MemoryObject - Location to return WDFMEMORY handle
2859
2860Returns:
2861
2862 NTSTATUS
2863
2864--*/
2865
2866{
2871
2872 //
2873 // Validate the request handle, and get the FxRequest*
2874 //
2876 Request,
2878 (PVOID*)&pRequest,
2880
2883
2885 if (!NT_SUCCESS(status)) {
2886 return status;
2887 }
2888
2889#if FX_VERBOSE_TRACE
2891 "Enter: WDFREQUEST 0x%p", Request);
2892#endif // FX_VERBOSE_TRACE
2893
2895 1,9, OkForDownLevel)) {
2896 KIRQL irql;
2897
2898 pRequest->Lock(&irql);
2899 status = pRequest->VerifyRequestIsDriverOwned(pFxDriverGlobals);
2901 if (!NT_SUCCESS(status)) {
2902 return status;
2903 }
2904 }
2905
2907 if (!NT_SUCCESS(status)) {
2910 "ProbeAndLockForWrite failed with %!STATUS!", status);
2911 return status;
2912 }
2913
2914 *MemoryObject = (WDFMEMORY)pMemory->GetObjectHandle();
2915
2916 return status;
2917}
2918
2921WDFAPI
2922STDCALL
2923WDFEXPORT(WdfRequestGetRequestorMode)(
2924 __in
2926 __in
2927 WDFREQUEST Request
2928 )
2929
2930/*++
2931
2932Routine Description:
2933
2934 Returns the RequestorMode information from the IRP.
2935
2936
2937Arguments:
2938
2939 Request - Handle to the Request object
2940
2941
2942Returns:
2943
2944 KPROCESSOR_MODE is CCHAR
2945
2946--*/
2947
2948{
2950
2951 //
2952 // Validate the request handle, and get the FxRequest*
2953 //
2955 Request,
2957 (PVOID*)&pRequest);
2958
2960}
2961
2963WDFQUEUE
2964WDFAPI
2965STDCALL
2966WDFEXPORT(WdfRequestGetIoQueue)(
2967 __in
2969 __in
2970 WDFREQUEST Request
2971 )
2972
2973/*++
2974
2975Routine Description:
2976
2977 Returns the queue handle that currently owns the request.
2978
2979
2980Arguments:
2981
2982 Request - Handle to the Request object
2983
2984
2985Returns:
2986
2987 WDFQUEUE
2988
2989--*/
2990
2991{
2994
2995 //
2996 // Validate the request handle, and get the FxRequest*
2997 //
2999 Request,
3001 (PVOID*)&pRequest,
3003
3004#if FX_VERBOSE_TRACE
3006 "Enter: WDFREQUEST 0x%p", Request);
3007#endif // FX_VERBOSE_TRACE
3008
3010 //
3011 // For a driver-created request, the queue can be NULL. It is not
3012 // necessarily an error to call WdfRequestGetIoQueue on a driver-
3013 // created request, because the caller may not really know whether or
3014 // not the request is driver-created.
3015 //
3016 // For example, it is possible for a class extension to create a request
3017 // and pass it to the client driver, in which case the client driver
3018 // wouldn't really know whether or not it was driver-created. Or a
3019 // client driver is might be using a helper library for some of its
3020 // tasks and it might pass in a request object to the helper library. In
3021 // this case, the helper library wouldn't really know whether or not the
3022 // request was driver-created. Therefore, the log message below is at
3023 // verbose level and not at error or warning level.
3024 //
3028 "WDFREQUEST %p doesn't belong to any queue",
3029 Request);
3030 return NULL;
3031 }
3032
3034 //
3035 // If the queue for Create is the framework internal queue
3036 // return NULL.
3037 //
3038 FxPkgGeneral* devicePkgGeneral = pRequest->GetDevice()->m_PkgGeneral;
3039
3040 if (devicePkgGeneral->GetDeafultInternalCreateQueue() ==
3043 "Getting queue handle for Create request is "
3044 "not allowed for WDFREQUEST 0x%p", pRequest);
3046 return NULL;
3047 }
3048 }
3049
3051}
3052
3056 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
3058 )
3059{
3061
3063
3064 //
3065 // * Is request I/O allocated but without a queue? This should not happen.
3066 // * Is WDF driver v1.9 or below trying to use this feature? We don't allow it.
3067 //
3068 if (request->IsAllocatedDriver() == FALSE ||
3069 FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,11) == FALSE) {
3072 "WDFREQUEST %p doesn't belong to any queue, %!STATUS!",
3073 request->GetHandle(), status);
3074 FxVerifierDbgBreakPoint(FxDriverGlobals);
3075 return status;
3076 }
3077
3078 //
3079 // Make sure current IRP stack location is valid. See helper routine for error msgs.
3080 //
3081 status = request->VerifyRequestCanBeCompleted(FxDriverGlobals);
3082 return status;
3083}
3084
3088STDCALL
3089WDFEXPORT(WdfRequestForwardToIoQueue)(
3090 __in
3092 __in
3093 WDFREQUEST Request,
3094 __in
3096 )
3097
3098/*++
3099
3100Routine Description:
3101
3102 Forward a request presented on one queue to another driver
3103 managed queue.
3104
3105 A request may only be forwarded from a queues dispatch routine.
3106
3107 If the request is successfully forwarded to the DestinationQueue, it
3108 is no longer owned by the driver, but by the DestinationQueue.
3109
3110 Both the source queue and destination queue should be part of the
3111 same device.
3112
3113 The driver gets ownership of the request when it receives it
3114 from the DestinationQueue through EvtIo callback, or WdfIoQueueRetrieveNextRequest.
3115
3116Arguments:
3117
3118
3119 Request - Request object to forward.
3120
3121 DestinationQueue - Queue that is to receive the request.
3122
3123Returns:
3124
3125 STATUS_SUCCESS - Request was forwarded to Queue and driver no
3126 longer owns it.
3127
3128 !STATUS_SUCCESS - Request was not forwarded to the Queue, and
3129 the driver still owns the request and is responsible
3130 for either completing it, or eventually successfully
3131 forwarding it to a Queue.
3132--*/
3133
3134{
3140
3142
3143 //
3144 // Validate destination queue handle
3145 //
3149 (PVOID*)&queue,
3151
3152 //
3153 // Validate request object handle
3154 //
3156 Request,
3158 (PVOID*)&request);
3159
3160 //
3161 // If present, let the queue do the heavy lifting.
3162 //
3163 if (request->GetCurrentQueue() != NULL) {
3164 status = request->GetCurrentQueue()->ForwardRequest(queue, request);
3165 goto Done;
3166 }
3167
3168 //
3169 // Basic verification.
3170 //
3172 if (!NT_SUCCESS(status)) {
3173 goto Done;
3174 }
3175
3176 //
3177 // OK, queue this request.
3178 //
3179 status = queue->QueueDriverCreatedRequest(request, FALSE);
3180
3181Done:
3182 return status;
3183}
3184
3190 )
3191{
3193 FxIrp* irp;
3194
3196
3197 //
3198 // * Is request I/O allocated but without a queue? This should not happen.
3199 // * Is WDF driver v1.9 or below trying to use this feature? We don't allow it.
3200 //
3201 if (request->IsAllocatedDriver() == FALSE ||
3205 "WDFREQUEST %p doesn't belong to any queue, %!STATUS!",
3206 request->GetHandle(), status);
3208 goto Done;
3209 }
3210
3211 //
3212 // Make sure current IRP stack location is valid.
3213 //
3214 status = request->VerifyRequestCanBeCompleted(fxDriverGlobals);
3215 if (!NT_SUCCESS(status)) {
3216 goto Done;
3217 }
3218
3219 //
3220 // Make sure IRP has space for at least another stack location.
3221 //
3222 irp = request->GetFxIrp();
3223
3224 ASSERT(irp->GetIrp() != NULL);
3225
3229 "IRP %p of WDFREQUEST %p doesn't enough stack "
3230 "locations, %!STATUS!",
3231 irp, request->GetHandle(), status);
3233 goto Done;
3234 }
3235
3236Done:
3237 return status;
3238}
3239
3243STDCALL
3244WDFEXPORT(WdfRequestForwardToParentDeviceIoQueue)(
3245 __in
3247 __in
3248 WDFREQUEST Request,
3249 __in
3251 __in
3253 )
3254
3255/*++
3256
3257Routine Description:
3258
3259 Forward a request presented on one queue to parent Device queue.
3260
3261 A request may only be forwarded from a queues dispatch routine.
3262
3263 If the request is successfully forwarded to the ParentDeviceQueue, it
3264 is no longer owned by the driver, but by the ParentDeviceQueue.
3265
3266 The driver gets ownership of the request when it receives it
3267 from the DestinationQueue through EvtIo callback, or WdfIoQueueRetrieveNextRequest.
3268
3269Arguments:
3270
3271
3272 Request - Request object to forward.
3273
3274 ParentDeviceQueue - Queue that is to receive the request.
3275
3276 ForwardOptions - A pointer to a caller-allocated WDF_REQUEST_FORWARD_OPTIONS
3277 structure
3278
3279Returns:
3280
3281 STATUS_SUCCESS - Request was forwarded to Queue and driver no
3282 longer owns it.
3283
3284 !STATUS_SUCCESS - Request was not forwarded to the Queue, and
3285 the driver still owns the request and is responsible
3286 for either completing it, or eventually successfully
3287 forwarding it to a Queue.
3288--*/
3289
3290{
3295
3296 //
3297 // Validate destination queue handle
3298 //
3302 (PVOID*)&queue,
3304
3305 //
3306 // Validate request object handle
3307 //
3309 Request,
3311 (PVOID*)&request);
3313
3315 //
3316 // Size is wrong, bale out
3317 //
3320 "ForwardOptions %p Size incorrect, expected %d, "
3321 "got %d, %!STATUS!",
3323 ForwardOptions->Size,
3324 status);
3325
3326 goto Done;
3327 }
3328
3330 //
3331 // Invalid flag
3332 //
3335 "ForwardOptions %p Flags 0x%x invalid, "
3336 "valid mask is 0x%x, %!STATUS!",
3339 status);
3340
3341 goto Done;
3342 }
3343
3344 //
3345 // If present, let the queue do the heavy lifting.
3346 //
3347 if (request->GetCurrentQueue() != NULL) {
3348 status = request->GetCurrentQueue()->ForwardRequestToParent(
3349 queue,
3350 request,
3352 goto Done;
3353 }
3354
3355 //
3356 // Basic verification.
3357 //
3359 request);
3360 if (!NT_SUCCESS(status)) {
3361 goto Done;
3362 }
3363
3364 //
3365 // OK, queue this request.
3366 //
3367 status = queue->QueueDriverCreatedRequest(request, TRUE);
3368
3369Done:
3370 return status;
3371}
3372
3376STDCALL
3377WDFEXPORT(WdfRequestRequeue)(
3378 __in
3380 __in
3381 WDFREQUEST Request
3382 )
3383
3384/*++
3385
3386Routine Description:
3387
3388 Requeue the request - only allowed if the queue is a manual queue.
3389
3390Arguments:
3391
3392 Request - Request to requeue
3393
3394Returns:
3395
3396 NTSTATUS
3397
3398--*/
3399
3400{
3403
3404 //
3405 // Validate request object handle
3406 //
3408 Request,
3410 (PVOID*)&pRequest,
3412
3413#if FX_VERBOSE_TRACE
3415 "Enter: WDFREQUEST 0x%p", Request);
3416#endif // FX_VERBOSE_TRACE
3417
3418 //
3419 // GetCurrentQueue may return NULL if the request is driver created request
3420 // or the if the call is made in the context of InProcessContextCallback.
3421 //
3422 if (pRequest->GetCurrentQueue() == NULL) {
3424 "WDFREQUEST %p doesn't belong to any queue %!STATUS!",
3428 }
3429
3431}
3432
3434VOID
3435STDCALL
3436WDFEXPORT(WdfRequestMarkCancelable)(
3437 __in
3439 __in
3440 WDFREQUEST Request,
3441 __in
3443 )
3444
3445/*++
3446
3447Routine Description:
3448
3449 Mark the specified request as cancelable
3450
3451Arguments:
3452
3453 Request - Request to mark as cancelable.
3454
3455 EvtRequestCancel - cancel routine to be invoked when the
3456 request is cancelled.
3457
3458Returns:
3459
3460 None
3461
3462--*/
3463
3464{
3468
3469 //
3470 // Validate request object handle
3471 //
3473 Request,
3475 (PVOID*)&pRequest,
3477
3479
3480#if FX_VERBOSE_TRACE
3482 "Enter: WDFREQUEST 0x%p", Request);
3483#endif // FX_VERBOSE_TRACE
3484
3485 if (pRequest->GetCurrentQueue() == NULL) {
3487 "WDFREQUEST %p doesn't belong to any queue",
3488 Request);
3490 return;
3491 }
3492
3494 TRUE,
3496 FALSE);
3499
3500}
3501
3505STDCALL
3506WDFEXPORT(WdfRequestMarkCancelableEx)(
3507 __in
3509 __in
3510 WDFREQUEST Request,
3511 __in
3513 )
3514
3515/*++
3516
3517Routine Description:
3518
3519 Mark the specified request as cancelable. Do not call the specified cancel
3520 routine if IRP is already cancelled but instead return STATUS_CANCELLED.
3521 Caller is responsible for completing the request with STATUS_CANCELLED.
3522
3523Arguments:
3524
3525 Request - Request to mark as cancelable.
3526
3527 EvtRequestCancel - cancel routine to be invoked when the
3528 request is cancelled.
3529
3530Returns:
3531
3532 STATUS_SUCCESS - The request has been marked cancelable.
3533 STATUS_CANCELLED - The IRP is already cancelled.
3534 NTSTATUS - Other values are possible when verifier is enabled.
3535
3536--*/
3537
3538{
3542
3543 //
3544 // Validate request object handle
3545 //
3547 Request,
3549 (PVOID*)&pRequest,
3551
3553
3554#if FX_VERBOSE_TRACE
3556 "Enter: WDFREQUEST 0x%p", Request);
3557#endif // FX_VERBOSE_TRACE
3558
3559 if (pRequest->GetCurrentQueue() == NULL) {
3561 "WDFREQUEST %p doesn't belong to any queue %!STATUS!",
3565 }
3566
3568 TRUE,
3570 TRUE);
3571
3573 return status;
3574}
3575
3579STDCALL
3580WDFEXPORT(WdfRequestUnmarkCancelable)(
3581 __in
3583 __in
3584 WDFREQUEST Request
3585 )
3586
3587/*++
3588
3589Routine Description:
3590
3591 Unmark the specified request as cancelable
3592
3593Arguments:
3594
3595 Request - Request to unmark as cancelable.
3596
3597Returns:
3598
3599 NTSTATUS
3600
3601--*/
3602
3603{
3606
3607 //
3608 // Validate request object handle
3609 //
3611 Request,
3613 (PVOID*)&pRequest,
3615
3616#if FX_VERBOSE_TRACE
3618 "Enter: WDFREQUEST 0x%p", Request);
3619#endif // FX_VERBOSE_TRACE
3620
3621 if (pRequest->GetCurrentQueue() == NULL) {
3623 "WDFREQUEST %p doesn't belong to any queue %!STATUS!",
3627 }
3628
3630 FALSE,
3631 NULL,
3632 FALSE);
3633}
3634
3638 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
3640 )
3641{
3643 KIRQL irql;
3644
3646
3647 pRequest->Lock(&irql);
3648
3649 status = pRequest->VerifyRequestIsDriverOwned(FxDriverGlobals);
3650 if (NT_SUCCESS(status)) {
3651 status = pRequest->VerifyRequestIsNotCancelable(FxDriverGlobals);
3652 }
3653
3655 return status;
3656}
3657
3660BOOLEAN
3661STDCALL
3662WDFEXPORT(WdfRequestIsCanceled)(
3663 __in
3665 __in
3666 WDFREQUEST Request
3667 )
3668
3669/*++
3670
3671Routine Description:
3672
3673 Check to see if the request is cancelled by the I/O manager.
3674 This call is valid only on a driver owned non-cancelable request.
3675
3676Arguments:
3677
3678 Request - Request being checked.
3679
3680Returns:
3681
3682 BOOLEAN
3683
3684--*/
3685
3686{
3690
3691 //
3692 // Validate request object handle
3693 //
3695 Request,
3697 (PVOID*)&pRequest,
3700 if (!NT_SUCCESS(status)) {
3701 return FALSE;
3702 }
3703
3705}
3706
3708VOID
3709STDCALL
3710WDFEXPORT(WdfRequestStopAcknowledge)(
3711 __in
3713 __in
3714 WDFREQUEST Request,
3715 __in
3717 )
3718
3719/*++
3720
3721Routine Description:
3722
3723 The driver calls this to acknowledge that it is no longer
3724 attempting to perform I/O on the request which was provided in
3725 the EvtIoStop event callback notification.
3726
3727 The device driver must arrange to no longer touch any hardware
3728 resources before making this call.
3729
3730Arguments:
3731
3732 Request - Request being stopped
3733
3734 Requeue - True if the request is to be placed back on the front of the queue,
3735 and re-delivered to the device driver on resume.
3736
3737Returns:
3738
3739 None
3740
3741--*/
3742
3743{
3746
3747 //
3748 // Validate request object handle
3749 //
3751 Request,
3753 (PVOID*)&pRequest,
3755
3756#if FX_VERBOSE_TRACE
3758 "Enter: WDFREQUEST 0x%p", Request);
3759#endif // FX_VERBOSE_TRACE
3760
3762}
3763
3764
3766BOOLEAN
3767STDCALL
3768WDFEXPORT(WdfRequestIsReserved)(
3769 __in
3771 __in
3772 WDFREQUEST Request
3773 )
3774/*++
3775
3776Routine Description:
3777 This is used to determine if a Request is a reserved request. Reserved
3778 Requests are used for forward progress.
3779
3780Arguments:
3781
3782 Request - Request being checked
3783
3784
3785Returns:
3786
3787 BOOLEAN
3788
3789--*/
3790
3791{
3794
3795 //
3796 // Validate request object handle
3797 //
3799 Request,
3801 (PVOID*)&pRequest,
3803
3805}
3806
3807
3808} // extern "C" the whole file
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
__inline WDF_DEVICE_IO_TYPE GetIoType(VOID)
Definition: fxdevice.hpp:1084
static FxDevice * GetFxDevice(__in MdDeviceObject DeviceObject)
Definition: fxdeviceum.cpp:60
FxPkgGeneral * m_PkgGeneral
Definition: fxdevice.hpp:671
__inline WDFFILEOBJECT GetHandle(VOID)
_Must_inspect_result_ NTSTATUS RequestCancelable(__in FxRequest *pRequest, __in BOOLEAN Cancelable, __in_opt PFN_WDF_REQUEST_CANCEL EvtRequestCancel, __in BOOLEAN FailIfIrpIsCancelled)
Definition: fxioqueue.cpp:2093
_Must_inspect_result_ NTSTATUS Requeue(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:1933
Definition: fxirp.hpp:28
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
ULONG GetParameterWriteLength(VOID)
Definition: fxirpum.cpp:1601
MdDeviceObject GetDeviceObject(VOID)
Definition: fxirpum.cpp:1352
ULONG GetParameterIoctlCodeBufferMethod(VOID)
Definition: fxirpum.cpp:1490
CCHAR GetCurrentIrpStackLocationIndex()
Definition: fxirpum.cpp:521
ULONG GetParameterIoctlOutputBufferLength(VOID)
Definition: fxirpum.cpp:1504
BOOLEAN HasStack(_In_ UCHAR StackCount)
Definition: fxirpum.cpp:1745
VOID CopyToNextIrpStackLocation(__in PIO_STACK_LOCATION Stack)
Definition: fxirpum.cpp:1216
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
VOID CopyCurrentIrpStackLocationToNext(VOID)
Definition: fxirpum.cpp:209
ULONG GetParameterIoctlInputBufferLength(VOID)
Definition: fxirpum.cpp:1518
PVOID GetParameterIoctlType3InputBuffer(VOID)
Definition: fxirpum.cpp:1542
ULONG GetParameterReadLength(VOID)
Definition: fxirpum.cpp:1589
PVOID GetUserBuffer()
Definition: fxirpum.cpp:633
BOOLEAN Is32bitProcess(VOID)
Definition: fxirpum.cpp:1640
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
__inline FxIoQueue * GetDeafultInternalCreateQueue()
__inline FxIrp * GetSubmitFxIrp(VOID)
BOOLEAN Cancel(VOID)
_Must_inspect_result_ NTSTATUS CreateTimer(VOID)
__inline WDFREQUEST GetHandle(VOID)
_Must_inspect_result_ NTSTATUS ValidateTarget(__in FxIoTarget *Target)
BOOLEAN m_NextStackLocationFormatted
__inline VOID VerifierSetFormatted(VOID)
__inline VOID SetCompletionRoutine(__in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine=NULL, __in_opt WDFCONTEXT CompletionContext=NULL)
_Must_inspect_result_ NTSTATUS GetMemoryObject(__deref_out IFxMemory **Memory, __out PVOID *Buffer, __out size_t *Length)
Definition: fxrequest.cpp:1284
__inline NTSTATUS CompleteWithInformation(__in NTSTATUS Status, __in ULONG_PTR Information)
Definition: fxrequest.hpp:810
VOID StopAcknowledge(__in BOOLEAN Requeue)
Definition: fxrequest.cpp:2634
_Must_inspect_result_ FxIoQueue * GetCurrentQueue(VOID)
Definition: fxrequest.hpp:728
FxIrp * GetFxIrp(VOID)
Definition: fxrequest.hpp:957
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 GetParameters(__out PWDF_REQUEST_PARAMETERS Parameters)
Definition: fxrequest.cpp:1221
__inline CfxDevice * GetDevice(VOID)
Definition: fxrequest.hpp:600
_Must_inspect_result_ NTSTATUS GetDeviceControlOutputMdl(__out PMDL *pMdl)
__inline NTSTATUS CompleteWithPriority(__in NTSTATUS Status, __in CCHAR PriorityBoost)
Definition: fxrequest.hpp:825
KPROCESSOR_MODE GetRequestorMode(VOID)
Definition: fxrequest.cpp:327
_Must_inspect_result_ NTSTATUS ProbeAndLockForRead(__in PVOID Buffer, __in ULONG Length, __deref_out FxRequestMemory **pMemoryObject)
NTSTATUS SetInformation(__in ULONG_PTR Information)
Definition: fxrequest.cpp:229
__inline NTSTATUS Complete(__in NTSTATUS Status)
Definition: fxrequest.hpp:770
_Must_inspect_result_ NTSTATUS GetMdl(__out PMDL *pMdl)
Definition: fxrequestkm.cpp:80
ULONG_PTR GetInformation(VOID)
Definition: fxrequest.cpp:277
__inline VOID CopyCompletionParams(__in PWDF_REQUEST_COMPLETION_PARAMS Params)
Definition: fxrequest.hpp:534
__inline BOOLEAN IsCancelled(VOID)
Definition: fxrequest.hpp:525
_Must_inspect_result_ NTSTATUS ProbeAndLockForWrite(__in PVOID Buffer, __in ULONG Length, __deref_out FxRequestMemory **pMemoryObject)
_Must_inspect_result_ NTSTATUS GetDeviceControlOutputMemoryObject(__deref_out IFxMemory **MemoryObject, __out PVOID *Buffer, __out size_t *Length)
Definition: fxrequest.cpp:1524
_Must_inspect_result_ NTSTATUS GetIrp(__deref_out MdIrp *ppIrp)
Definition: fxrequest.hpp:975
_Must_inspect_result_ NTSTATUS GetFileObject(__deref_out_opt FxFileObject **pFileObject)
Definition: fxrequest.cpp:2408
__inline BOOLEAN IsReserved()
Definition: fxrequest.hpp:609
_Must_inspect_result_ NTSTATUS Reuse(__in PWDF_REQUEST_REUSE_PARAMS ReuseParams)
Definition: fxrequest.cpp:2136
NTSTATUS GetStatus(VOID)
Definition: fxrequest.cpp:1187
virtual WDFMEMORY GetHandle(VOID)=0
Definition: _queue.h:67
_In_ PIRP Irp
Definition: csq.h:116
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __in_bcount(x)
Definition: dbghelp.h:41
#define __deref_out
Definition: dbghelp.h:26
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGREQUEST
Definition: dbgtrace.h:65
#define TRACINGAPIERROR
Definition: dbgtrace.h:60
#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 __drv_maxIRQL(irql)
Definition: driverspecs.h:291
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
return pObject GetObjectHandle()
PFX_DRIVER_GLOBALS fxDriverGlobals
DriverGlobals
@ OkForDownLevel
Definition: fxglobals.h:80
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
VOID __inline FxObjectHandleGetGlobals(__in PFX_DRIVER_GLOBALS CallersGlobals, __in WDFOBJECT Handle, __out PFX_DRIVER_GLOBALS *ObjectGlobals)
Definition: fxhandle.h:453
@ SubmitSend
Definition: fxiotarget.hpp:202
@ SubmitSyncCallCompletion
Definition: fxiotarget.hpp:207
@ SubmitSent
Definition: fxiotarget.hpp:204
@ SubmitQueued
Definition: fxiotarget.hpp:203
#define FX_DECLARE_VF_FUNCTION_P1(rt, fnName, at1)
Definition: fxmacros.hpp:94
#define FX_VF_FUNCTION(fnName)
Definition: fxmacros.hpp:47
#define WDFEXPORT(a)
Definition: fxmacros.hpp:157
#define FxPointerNotNull(FxDriverGlobals, Ptr)
Definition: fxmacros.hpp:253
NTSTATUS status
#define WDFIOTARGET_FXIOTARGET(handle)
#define WDF_REQUEST_REUSE_VALID_FLAGS_V1_9
__in WDFREQUEST __in PIO_STACK_LOCATION Stack
ULONG validFlags
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in_opt WDFIOTARGET Target
FxIrp * pIrp
__in WDFREQUEST __in BOOLEAN Requeue
_Must_inspect_result_ __in WDFREQUEST __in size_t RequiredLength
FxIoTarget * pTarget
FxRequest * request
FxVerifierDbgBreakPoint(pFxDriverGlobals)
__in WDFREQUEST __in NTSTATUS __in ULONG_PTR Information
__in WDFREQUEST __in NTSTATUS __in CCHAR PriorityBoost
_Must_inspect_result_ __in WDFREQUEST __out WDFMEMORY * Memory
PFX_DRIVER_GLOBALS cxDriverGlobals
FxObjectHandleGetPtr(pFxDriverGlobals, IoTarget, FX_TYPE_IO_TARGET,(PVOID *)&pTarget)
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST,(PVOID *)&pRequest, &pFxDriverGlobals)
#define WDFREQUEST_FXREQUEST(handle)
__in WDFREQUEST __in PFN_WDF_REQUEST_CANCEL EvtRequestCancel
return pFO GetHandle()
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyRequestComplete(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest *pRequest)
__in WDFREQUEST __in NTSTATUS RequestStatus
_Must_inspect_result_ __in WDFREQUEST __in size_t __deref_out_bcount Length PVOID * Buffer
__in WDFREQUEST __out PWDF_REQUEST_PARAMETERS Parameters
IFxMemory * pMemory
#define GLOBALS_ACTION(globals)
__in WDFREQUEST __out PWDF_REQUEST_COMPLETION_PARAMS Params
FxDevice * pDevice
_Must_inspect_result_ __in WDFREQUEST __in WDFIOTARGET __in_opt PWDF_REQUEST_SEND_OPTIONS Options
_Must_inspect_result_ __in WDFREQUEST __in size_t __out WDFMEMORY * MemoryObject
#define WDF_REQUEST_REUSE_VALID_FLAGS
_Must_inspect_result_ __in WDFREQUEST __deref_out PMDL * Mdl
_Must_inspect_result_ __in WDFREQUEST __in WDFQUEUE ParentDeviceQueue
FxRequest * pRequest
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in MdIrp __in BOOLEAN RequestFreesIrp
_Must_inspect_result_ __in WDFREQUEST __in WDFQUEUE DestinationQueue
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES RequestAttributes
void CheckUnionAssumptions(VOID)
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyWdfRequestForwardToIoQueue(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest *request)
FxIoQueue * queue
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyWdfRequestIsCanceled(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest *pRequest)
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in MdIrp Irp
PVOID pBuffer
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyWdfRequestForwardToParentDeviceIoQueue(_In_ PFX_DRIVER_GLOBALS fxDriverGlobals, _In_ FxRequest *request)
__in WDFREQUEST __in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
UCHAR majorFunction
BOOLEAN result
FxFileObject * pFO
#define PGLOBALS_ACTION(globals)
_Must_inspect_result_ __in WDFREQUEST __in WDFQUEUE __in PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions
_Must_inspect_result_ __in WDFREQUEST __in size_t __deref_out_bcount Length PVOID __out_opt size_t * Length
FxIrp * irp
size_t length
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "Error: This call is valid only on method-neither " "ioctl and write WDFREQUEST %p, %!STATUS!", Request, status)
__in WDFREQUEST __in PWDF_REQUEST_REUSE_PARAMS ReuseParams
_Must_inspect_result_ __in WDFREQUEST __in WDFIOTARGET IoTarget
__in WDFREQUEST __in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE __in_opt WDFCONTEXT CompletionContext
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in_opt WDFIOTARGET __out WDFREQUEST * Request
pFxDriverGlobals
@ FxRequestConstructorCallerIsDriver
@ FxRequestDoesNotOwnIrp
@ FxRequestOwnsIrp
NTSTATUS __inline FxValidateRequestOptions(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ PWDF_REQUEST_SEND_OPTIONS Options, _In_opt_ FxRequestBase *Request=NULL)
@ FX_TYPE_QUEUE
Definition: fxtypes.h:48
@ FX_TYPE_IO_TARGET
Definition: fxtypes.h:100
@ FX_TYPE_REQUEST
Definition: fxtypes.h:53
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
#define ASSERT(a)
Definition: mode.c:44
#define __deref_out_bcount_opt(size)
Definition: ms_sal.h:2783
#define __deref_out_bcount(size)
Definition: ms_sal.h:2755
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define _In_
Definition: ms_sal.h:308
IWudfIrp * MdIrp
Definition: mxum.h:103
#define METHOD_NEITHER
Definition: nt_native.h:597
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#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_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
Definition: tftpd.h:86
Definition: ps.c:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define STDCALL
Definition: wdf.h:45
#define WDFCASSERT(c)
Definition: wdfassert.h:93
@ WDF_REQUEST_FATAL_ERROR
Definition: wdfbugcodes.h:63
@ WDF_REQUEST_FATAL_ERROR_NO_MORE_STACK_LOCATIONS
Definition: wdfbugcodes.h:76
@ WDF_REQUEST_FATAL_ERROR_NULL_IRP
Definition: wdfbugcodes.h:77
_In_ PWDFDEVICE_INIT _In_ PWDF_OBJECT_ATTRIBUTES RequestAttributes
Definition: wdfdevice.h:3431
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
@ WdfDeviceIoNeither
Definition: wdfdevice.h:451
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIOTARGET * IoTarget
Definition: wdfiotarget.h:368
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
_Must_inspect_result_ FORCEINLINE BOOLEAN WdfRequestSend(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_opt_ PWDF_REQUEST_SEND_OPTIONS Options)
Definition: wdfrequest.h:677
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1016
_In_ WDFREQUEST _In_ PWDF_REQUEST_REUSE_PARAMS ReuseParams
Definition: wdfrequest.h:554
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE _In_ PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions
Definition: wdfrequest.h:1736
@ WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET
Definition: wdfrequest.h:111
@ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
Definition: wdfrequest.h:109
_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
_In_ WDFREQUEST _In_ BOOLEAN Requeue
Definition: wdfrequest.h:1654
EVT_WDF_REQUEST_COMPLETION_ROUTINE * PFN_WDF_REQUEST_COMPLETION_ROUTINE
Definition: wdfrequest.h:313
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:898
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
@ WDF_REQUEST_FORWARD_OPTION_SEND_AND_FORGET
Definition: wdfrequest.h:431
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PIRP _In_ BOOLEAN RequestFreesIrp
Definition: wdfrequest.h:517
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
EVT_WDF_REQUEST_CANCEL * PFN_WDF_REQUEST_CANCEL
Definition: wdfrequest.h:130
_In_ WDFREQUEST _In_ PFN_WDF_REQUEST_CANCEL EvtRequestCancel
Definition: wdfrequest.h:730
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE DestinationQueue
Definition: wdfrequest.h:1572
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE ParentDeviceQueue
Definition: wdfrequest.h:1733
#define WDFAPI
Definition: wdftypes.h:53
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define PAGED_CODE_LOCKED()
Definition: kefuncs.h:1417
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
unsigned char UCHAR
Definition: xmlstorage.h:181