ReactOS  0.4.15-dev-2534-geba00d1
fxrequestapi.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxRequestApi.cpp
8 
9 Abstract:
10 
11  This module implements FxRequest object
12 
13 Author:
14 
15 
16 
17 
18 
19 Environment:
20 
21  Both kernel and user mode
22 
23 Revision History:
24 
25 
26 --*/
27 #include "coreprivshared.hpp"
28 
29 // Tracing support
30 extern "C" {
31 // #include "FxRequestApi.tmh"
32 
33 //
34 // Verifiers
35 //
36 // Do not supply Argument names
38 NTSTATUS,
41  );
42 
43 // Do not supply Argument names
45 NTSTATUS,
48  );
49 
50 //Do not supply argument names
52 NTSTATUS,
55  );
56 
57 //Do not supply argument names
59 NTSTATUS,
62  );
63 
67 STDCALL
68 WDFEXPORT(WdfRequestCreate)(
69  __in
71  __in_opt
73  __in_opt
74  WDFIOTARGET Target,
75  __out
76  WDFREQUEST* Request
77  )
78 
79 /*++
80 
81 Routine Description:
82  Creates a WDFREQUEST handle that is suitable to be submitted to the provided
83  target
84 
85 Arguments:
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 
96 Return 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 
144  *Request = pRequest->GetHandle();
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 
159 NTSTATUS
160 STDCALL
161 WDFEXPORT(WdfRequestCreateFromIrp)(
162  __in
164  __in_opt
166  __in
167  MdIrp Irp,
168  __in
170  __out
171  WDFREQUEST* Request
172  )
173 
174 /*++
175 
176 Routine Description:
177  Creates a request handle that uses an external IRP instead of an internally
178  allocated irp.
179 
180 Arguments:
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 
193 Return 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)) {
232  *Request = pRequest->GetHandle();
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 
259 NTSTATUS
260 STDCALL
261 WDFEXPORT(WdfRequestReuse)(
262  __in
264  __in
265  WDFREQUEST Request,
266  __in
268  )
269 /*++
270 
271 Routine 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 
279 Arguments:
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 
285 Return 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!",
305  ReuseParams->Size, sizeof(WDF_REQUEST_REUSE_PARAMS),
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 
326  return pRequest->Reuse(ReuseParams);
327 }
328 
331 NTSTATUS
332 STDCALL
333 WDFEXPORT(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 
361 NTSTATUS
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 
379  pRequest->Unlock(irql);
380  return status;
381 }
382 
384 VOID
385 WDFAPI
386 STDCALL
387 WDFEXPORT(WdfRequestComplete)(
388  __in
390  __in
391  WDFREQUEST Request,
392  __in
394  )
395 
396 /*++
397 
398 Routine Description:
399 
400  Complete the request with supplied status.
401 
402  Any default reference counts implied by handle are invalid after
403  completion.
404 
405 Arguments:
406 
407  Request - Handle to the Request object
408 
409  RequestStatus - Wdm Status to complete the request with
410 
411 Returns:
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 
445 VOID
446 WDFAPI
447 STDCALL
448 WDFEXPORT(WdfRequestCompleteWithPriorityBoost)(
449  __in
451  __in
452  WDFREQUEST Request,
453  __in
455  __in
457  )
458 
459 /*++
460 
461 Routine Description:
462 
463  Complete the request with supplied status.
464 
465  Any default reference counts implied by handle are invalid after
466  completion.
467 
468 Arguments:
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 
477 Returns:
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 
514 VOID
515 WDFAPI
516 STDCALL
517 WDFEXPORT(WdfRequestCompleteWithInformation)(
518  __in
520  __in
521  WDFREQUEST Request,
522  __in
524  __in
526  )
527 
528 /*++
529 
530 Routine 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 
537 Arguments:
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 
545 Returns:
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 
582 VOID
583 WDFAPI
584 STDCALL
585 WDFEXPORT(WdfRequestSetInformation)(
586  __in
588  __in
589  WDFREQUEST Request,
590  __in
592  )
593 
594 /*++
595 
596 Routine Description:
597 
598  Set the transfer information for the request.
599 
600  This sets the NT Irp->Status.Information field.
601 
602 Arguments:
603 
604  Request - Handle to the Request object
605 
606  Information - Value to be set
607 
608 Returns:
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 
639 ULONG_PTR
640 WDFAPI
641 STDCALL
642 WDFEXPORT(WdfRequestGetInformation)(
643  __in
645  __in
646  WDFREQUEST Request
647  )
648 
649 /*++
650 
651 Routine Description:
652 
653  Get the transfer information for the reuqest.
654 
655 
656 Arguments:
657 
658  Request - Handle to the Request object
659 
660 
661 Returns:
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 
678  return pRequest->GetInformation();
679 }
680 
683 NTSTATUS
684 WDFAPI
685 STDCALL
686 WDFEXPORT(WdfRequestRetrieveInputMemory)(
687  __in
689  __in
690  WDFREQUEST Request,
691  __out
692  WDFMEMORY *Memory
693  )
694 /*++
695 
696 Routine 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 
732 Arguments:
733 
734  Request - Handle to the Request object
735 
736  Memory - Pointer location to return WDFMEMORY handle
737 
738 Returns:
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)) {
787  *Memory = pMemory->GetHandle();
788  }
789 
790  return status;
791 }
792 
795 NTSTATUS
796 WDFAPI
797 STDCALL
798 WDFEXPORT(WdfRequestRetrieveOutputMemory)(
799  __in
801  __in
802  WDFREQUEST Request,
803  __out
804  WDFMEMORY *Memory
805  )
806 
807 /*++
808 
809 Routine 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 
845 Arguments:
846 
847  Request - Handle to the Request object
848 
849  Memory - Pointer location to return WDFMEMORY handle
850 
851 Returns:
852 
853  NTSTATUS
854 
855 --*/
856 
857 {
862  PVOID pBuffer;
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)) {
910  *Memory = pMemory->GetHandle();
911  }
912 
913  return status;
914 }
915 
918 NTSTATUS
919 WDFAPI
920 STDCALL
921 WDFEXPORT(WdfRequestRetrieveInputBuffer)(
922  __in
924  __in
925  WDFREQUEST Request,
926  __in
927  size_t RequiredLength,
929  PVOID* Buffer,
930  __out_opt
931  size_t* Length
932  )
933 /*++
934 
935 Routine 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 
972 Arguments:
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 
982 Returns:
983 
984  NTSTATUS
985 
986 --*/
987 {
992  PVOID pBuffer;
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,
1004  &pFxDriverGlobals);
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 
1062 NTSTATUS
1063 WDFAPI
1064 STDCALL
1065 WDFEXPORT(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 
1079 Routine 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 
1116 Arguments:
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 
1126 Returns:
1127 
1128  NTSTATUS
1129 
1130 --*/
1131 {
1133  NTSTATUS status;
1135  IFxMemory* pMemory;
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,
1149  &pFxDriverGlobals);
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 
1216 NTSTATUS
1217 WDFAPI
1218 STDCALL
1219 WDFEXPORT(WdfRequestRetrieveUnsafeUserInputBuffer)(
1220  __in
1222  __in
1223  WDFREQUEST Request,
1224  __in
1225  size_t RequiredLength,
1227  PVOID* InputBuffer,
1228  __out_opt
1229  size_t* Length
1230  )
1231 /*++
1232 
1233 Routine 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 
1256 Arguments:
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 
1268 Returns:
1269 
1270  NTSTATUS
1271 
1272 --*/
1273 {
1275  NTSTATUS status;
1279 
1280  //
1281  // Validate the request handle, and get the FxRequest*
1282  //
1284  Request,
1286  (PVOID*)&pRequest,
1287  &pFxDriverGlobals);
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 
1316  pRequest->Unlock(irql);
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 
1420 NTSTATUS
1421 WDFAPI
1422 STDCALL
1423 WDFEXPORT(WdfRequestRetrieveUnsafeUserOutputBuffer)(
1424  __in
1426  __in
1427  WDFREQUEST Request,
1428  __in
1429  size_t RequiredLength,
1432  __out_opt
1433  size_t* Length
1434  )
1435 /*++
1436 
1437 Routine 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 
1457 Arguments:
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 
1470 Returns:
1471 
1472  NTSTATUS
1473 
1474 --*/
1475 {
1477  NTSTATUS status;
1480  FxDevice* pDevice;
1481 
1482  //
1483  // Validate the request handle, and get the FxRequest*
1484  //
1486  Request,
1488  (PVOID*)&pRequest,
1489  &pFxDriverGlobals);
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 
1513  pRequest->Unlock(irql);
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 
1622 NTSTATUS
1623 WDFAPI
1624 STDCALL
1625 WDFEXPORT(WdfRequestRetrieveInputWdmMdl)(
1626  __in
1628  __in
1629  WDFREQUEST Request,
1630  __deref_out
1631  PMDL *Mdl
1632  )
1633 
1634 /*++
1635 
1636 Routine 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 
1668 Arguments:
1669 
1670  Request - Handle to the Request object
1671 
1672  Mdl - Pointer location to return MDL ptr
1673 
1674 Returns:
1675 
1676  NTSTATUS
1677 
1678 --*/
1679 
1682  NTSTATUS status;
1684 
1685  //
1686  // Validate the request handle, and get the FxRequest*
1687  //
1689  Request,
1691  (PVOID*)&pRequest,
1692  &pFxDriverGlobals);
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 
1715  status = pRequest->GetMdl(Mdl);
1716 
1717  return status;
1718 }
1719 
1722 NTSTATUS
1723 WDFAPI
1724 STDCALL
1725 WDFEXPORT(WdfRequestRetrieveOutputWdmMdl)(
1726  __in
1728  __in
1729  WDFREQUEST Request,
1730  __deref_out
1731  PMDL *Mdl
1732  )
1733 
1734 /*++
1735 
1736 Routine 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 
1768 Arguments:
1769 
1770  Request - Handle to the Request object
1771 
1772  Mdl - Pointer location to return MDL ptr
1773 
1774 Returns:
1775 
1776  NTSTATUS
1777 
1778 --*/
1779 
1780 {
1782  NTSTATUS status;
1785 
1786  //
1787  // Validate the request handle, and get the FxRequest*
1788  //
1790  Request,
1792  (PVOID*)&pRequest,
1793  &pFxDriverGlobals);
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, "
1812  "%!STATUS!",Request, STATUS_INVALID_DEVICE_REQUEST);
1813 
1815  }
1816 
1820  }
1821  else {
1822  status = pRequest->GetMdl(Mdl);
1823  }
1824 
1825  return status;
1826 }
1827 
1828 void
1830  VOID
1831  )
1832 /*++
1833 
1834 Routine 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 
1842 Arguments:
1843  None.
1844 
1845 Return 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 
1869 BOOLEAN
1870 STDCALL
1872  __in
1874  __in
1875  WDFREQUEST Request,
1876  __in
1877  WDFIOTARGET Target,
1878  __in_opt
1880  )
1881 /*++
1882 
1883 Routine 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 
1889 Arguments:
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 
1901 Return 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  --*/
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 
1934  FxObjectHandleGetPtr(WDFREQUEST_FXREQUEST(Request)->GetDriverGlobals(),
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  //
2074  WDFIOTARGET_FXIOTARGET(Target)->Submit(
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 
2124 NTSTATUS
2125 STDCALL
2126 WDFEXPORT(WdfRequestGetStatus)(
2127  __in
2129  __in
2130  WDFREQUEST Request
2131  )
2132 {
2134 
2136  Request,
2138  (PVOID*)&pRequest);
2139 
2140  return pRequest->GetStatus();
2141 }
2142 
2144 BOOLEAN
2145 WDFAPI
2146 STDCALL
2147 WDFEXPORT(WdfRequestCancelSentRequest)(
2148  __in
2150  __in
2151  WDFREQUEST Request
2152  )
2153 
2154 /*++
2155 
2156 Routine Description:
2157  Cancels a previously submitted request.
2158 
2159 Arguments:
2160  Request - The previously submitted request
2161 
2162 Return 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,
2181  &pFxDriverGlobals);
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 
2198 BOOLEAN
2199 STDCALL
2200 WDFEXPORT(WdfRequestIsFrom32BitProcess)(
2201  __in
2203  __in
2204  WDFREQUEST Request
2205  )
2206 /*++
2207 
2208 Routine 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 
2212 Arguments:
2213  Request - The request being queried
2214 
2215 Return Value:
2216  TRUE if the request came from a 32 bit process, FALSE otherwise.
2217 
2218  --*/
2219 
2220 {
2223  BOOLEAN result;
2224 
2226  Request,
2228  (PVOID*) &pRequest,
2229  &pFxDriverGlobals);
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 
2244 VOID
2245 STDCALL
2246 WDFEXPORT(WdfRequestFormatRequestUsingCurrentType)(
2247  __in
2249  __in
2250  WDFREQUEST Request
2251  )
2252 /*++
2253 
2254 Routine Description:
2255  Copies the current Irp stack location to the next one. This is the
2256  equivalent of IoCopyCurrentIrpStackLocationToNext.
2257 
2258 Arguments:
2259  Request - The request that will be formatted.
2260 
2261 Return 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,
2278  &pFxDriverGlobals);
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 
2314 VOID
2315 WDFAPI
2316 STDCALL
2317 WDFEXPORT(WdfRequestWdmFormatUsingStackLocation)(
2318  __in
2320  __in
2321  WDFREQUEST Request,
2322  __in
2324  )
2325 
2326 /*++
2327 
2328 Routine 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 
2334 Arguments:
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 
2340 Return Value:
2341  None.
2342 
2343  --*/
2344 
2349 
2350  //
2351  // Validate the request handle, and get the FxRequest*
2352  //
2354  Request,
2356  (PVOID*)&pRequest,
2357  &pFxDriverGlobals);
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 
2395 VOID
2396 WDFAPI
2397 STDCALL
2398 WDFEXPORT(WdfRequestSetCompletionRoutine)(
2399  __in
2401  __in
2402  WDFREQUEST Request,
2403  __in_opt
2405  __in_opt
2407  )
2411 
2412  //
2413  // Validate the request handle, and get the FxRequest*
2414  //
2416  Request,
2418  (PVOID*)&pRequest,
2419  &pFxDriverGlobals);
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 
2434 VOID
2435 WDFAPI
2436 STDCALL
2437 WDFEXPORT(WdfRequestGetParameters)(
2438  __in
2440  __in
2441  WDFREQUEST Request,
2442  __out
2444  )
2448 
2449  //
2450  // Validate the request handle, and get the FxRequest*
2451  //
2453  Request,
2455  (PVOID*)&pRequest,
2456  &pFxDriverGlobals);
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 
2484 VOID
2485 WDFAPI
2486 STDCALL
2487 WDFEXPORT(WdfRequestGetCompletionParams)(
2488  __in
2490  __in
2491  WDFREQUEST Request,
2492  __out
2494  )
2498 
2499  //
2500  // Validate the request handle, and get the FxRequest*
2501  //
2503  Request,
2505  (PVOID*)&pRequest,
2506  &pFxDriverGlobals);
2507 
2508 #if FX_VERBOSE_TRACE
2510  "Enter: WDFREQUEST %p, Params %p", Request, Params);
2511 #endif // FX_VERBOSE_TRACE
2512 
2514 
2515  if (Params->Size != sizeof(WDF_REQUEST_COMPLETION_PARAMS)) {
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 
2531 MdIrp
2532 WDFAPI
2533 STDCALL
2534 WDFEXPORT(WdfRequestWdmGetIrp)(
2535  __in
2537  __in
2538  WDFREQUEST Request
2539  )
2540 
2541 /*++
2542 
2543 Routine 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 
2551 Arguments:
2552 
2553  Request - Handle to the Request object
2554 
2555 Returns:
2556 
2557  PIRP
2558 
2559 --*/
2560 
2561 {
2563  NTSTATUS status;
2565  MdIrp irp;
2566 
2567  //
2568  // Validate the request handle, and get the FxRequest*
2569  //
2571  Request,
2573  (PVOID*)&pRequest,
2574  &pFxDriverGlobals);
2575 
2576 #if FX_VERBOSE_TRACE
2578  "Enter: WDFREQUEST 0x%p", Request);
2579 #endif // FX_VERBOSE_TRACE
2580 
2581  status = pRequest->GetIrp(&irp);
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 
2596 NTSTATUS
2597 WDFAPI
2598 STDCALL
2599 WDFEXPORT(WdfRequestAllocateTimer)(
2600  __in
2602  __in
2603  WDFREQUEST Request
2604  )
2605 /*++
2606 
2607 Routine 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 
2616 Arguments:
2617  Request - the request to allocate a timer for
2618 
2619 Return 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 
2635  return pRequest->CreateTimer();
2636 }
2637 
2639 WDFFILEOBJECT
2640 WDFAPI
2641 STDCALL
2642 WDFEXPORT(WdfRequestGetFileObject)(
2643  __in
2645  __in
2646  WDFREQUEST Request
2647  )
2648 
2649 /*++
2650 
2651 Routine Description:
2652 
2653  This routine returns the WDFFILEOBJECT associated with the given
2654  request.
2655 
2656 Arguments:
2657 
2658  Request - Handle to the Request object
2659 
2660 Returns:
2661 
2662  WDFFILEOBJECT handle.
2663 
2664 --*/
2665 
2666 {
2668  NTSTATUS status;
2671 
2672  //
2673  // Validate the request handle, and get the FxRequest*
2674  //
2676  Request,
2678  (PVOID*) &pRequest,
2679  &pFxDriverGlobals);
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);
2694  pRequest->Unlock(irql);
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 
2719 NTSTATUS
2720 WDFAPI
2721 STDCALL
2722 WDFEXPORT(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 
2737 Routine 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 
2748 Arguments:
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 
2758 Returns:
2759 
2760  NTSTATUS
2761 
2762 --*/
2763 
2766  NTSTATUS status;
2769 
2770  //
2771  // Validate the request handle, and get the FxRequest*
2772  //
2774  Request,
2776  (PVOID*)&pRequest,
2777  &pFxDriverGlobals);
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);
2799  pRequest->Unlock(irql);
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 
2821 NTSTATUS
2822 WDFAPI
2823 STDCALL
2824 WDFEXPORT(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 
2839 Routine 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 
2850 Arguments:
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 
2860 Returns:
2861 
2862  NTSTATUS
2863 
2864 --*/
2865 
2866 {
2868  NTSTATUS status;
2871 
2872  //
2873  // Validate the request handle, and get the FxRequest*
2874  //
2876  Request,
2878  (PVOID*)&pRequest,
2879  &pFxDriverGlobals);
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);
2900  pRequest->Unlock(irql);
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 
2921 WDFAPI
2922 STDCALL
2923 WDFEXPORT(WdfRequestGetRequestorMode)(
2924  __in
2926  __in
2927  WDFREQUEST Request
2928  )
2929 
2930 /*++
2931 
2932 Routine Description:
2933 
2934  Returns the RequestorMode information from the IRP.
2935 
2936 
2937 Arguments:
2938 
2939  Request - Handle to the Request object
2940 
2941 
2942 Returns:
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 
2959  return pRequest->GetRequestorMode();
2960 }
2961 
2963 WDFQUEUE
2964 WDFAPI
2965 STDCALL
2966 WDFEXPORT(WdfRequestGetIoQueue)(
2967  __in
2969  __in
2970  WDFREQUEST Request
2971  )
2972 
2973 /*++
2974 
2975 Routine Description:
2976 
2977  Returns the queue handle that currently owns the request.
2978 
2979 
2980 Arguments:
2981 
2982  Request - Handle to the Request object
2983 
2984 
2985 Returns:
2986 
2987  WDFQUEUE
2988 
2989 --*/
2990 
2991 {
2994 
2995  //
2996  // Validate the request handle, and get the FxRequest*
2997  //
2999  Request,
3001  (PVOID*)&pRequest,
3002  &pFxDriverGlobals);
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 
3050  return (WDFQUEUE) pRequest->GetCurrentQueue()->GetObjectHandle();
3051 }
3052 
3054 NTSTATUS
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 
3087 NTSTATUS
3088 STDCALL
3089 WDFEXPORT(WdfRequestForwardToIoQueue)(
3090  __in
3092  __in
3093  WDFREQUEST Request,
3094  __in
3095  WDFQUEUE DestinationQueue
3096  )
3097 
3098 /*++
3099 
3100 Routine 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 
3116 Arguments:
3117 
3118 
3119  Request - Request object to forward.
3120 
3121  DestinationQueue - Queue that is to receive the request.
3122 
3123 Returns:
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 
3139  NTSTATUS status;
3140 
3142 
3143  //
3144  // Validate destination queue handle
3145  //
3148  FX_TYPE_QUEUE,
3149  (PVOID*)&queue,
3150  &fxDriverGlobals);
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 
3181 Done:
3182  return status;
3183 }
3184 
3186 NTSTATUS
3190  )
3191 {
3192  NTSTATUS status;
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 
3226  if (irp->GetCurrentIrpStackLocationIndex() <= 1) {
3229  "IRP %p of WDFREQUEST %p doesn't enough stack "
3230  "locations, %!STATUS!",
3231  irp, request->GetHandle(), status);
3233  goto Done;
3234  }
3235 
3236 Done:
3237  return status;
3238 }
3239 
3242 NTSTATUS
3243 STDCALL
3244 WDFEXPORT(WdfRequestForwardToParentDeviceIoQueue)(
3245  __in
3247  __in
3248  WDFREQUEST Request,
3249  __in
3250  WDFQUEUE ParentDeviceQueue,
3251  __in
3253  )
3254 
3255 /*++
3256 
3257 Routine 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 
3269 Arguments:
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 
3279 Returns:
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 
3292  NTSTATUS status;
3293  FxRequest* request;
3294  FxIoQueue* queue;
3295 
3296  //
3297  // Validate destination queue handle
3298  //
3301  FX_TYPE_QUEUE,
3302  (PVOID*)&queue,
3303  &fxDriverGlobals);
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,
3351  ForwardOptions);
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 
3369 Done:
3370  return status;
3371 }
3372 
3375 NTSTATUS
3376 STDCALL
3377 WDFEXPORT(WdfRequestRequeue)(
3378  __in
3380  __in
3381  WDFREQUEST Request
3382  )
3383 
3384 /*++
3385 
3386 Routine Description:
3387 
3388  Requeue the request - only allowed if the queue is a manual queue.
3389 
3390 Arguments:
3391 
3392  Request - Request to requeue
3393 
3394 Returns:
3395 
3396  NTSTATUS
3397 
3398 --*/
3399 
3400 {
3403 
3404  //
3405  // Validate request object handle
3406  //
3408  Request,
3410  (PVOID*)&pRequest,
3411  &pFxDriverGlobals);
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 
3434 VOID
3435 STDCALL
3436 WDFEXPORT(WdfRequestMarkCancelable)(
3437  __in
3439  __in
3440  WDFREQUEST Request,
3441  __in
3443  )
3444 
3445 /*++
3446 
3447 Routine Description:
3448 
3449  Mark the specified request as cancelable
3450 
3451 Arguments:
3452 
3453  Request - Request to mark as cancelable.
3454 
3455  EvtRequestCancel - cancel routine to be invoked when the
3456  request is cancelled.
3457 
3458 Returns:
3459 
3460  None
3461 
3462 --*/
3463 
3467  NTSTATUS status;
3468 
3469  //
3470  // Validate request object handle
3471  //
3473  Request,
3475  (PVOID*)&pRequest,
3476  &pFxDriverGlobals);
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);
3497  UNREFERENCED_PARAMETER(status); //for fre build
3499 
3500 }
3501 
3504 NTSTATUS
3505 STDCALL
3506 WDFEXPORT(WdfRequestMarkCancelableEx)(
3507  __in
3509  __in
3510  WDFREQUEST Request,
3511  __in
3513  )
3514 
3515 /*++
3516 
3517 Routine 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 
3523 Arguments:
3524 
3525  Request - Request to mark as cancelable.
3526 
3527  EvtRequestCancel - cancel routine to be invoked when the
3528  request is cancelled.
3529 
3530 Returns:
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 {
3541  NTSTATUS status;
3542 
3543  //
3544  // Validate request object handle
3545  //
3547  Request,
3549  (PVOID*)&pRequest,
3550  &pFxDriverGlobals);
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 
3578 NTSTATUS
3579 STDCALL
3580 WDFEXPORT(WdfRequestUnmarkCancelable)(
3581  __in
3583  __in
3584  WDFREQUEST Request
3585  )
3586 
3587 /*++
3588 
3589 Routine Description:
3590 
3591  Unmark the specified request as cancelable
3592 
3593 Arguments:
3594 
3595  Request - Request to unmark as cancelable.
3596 
3597 Returns:
3598 
3599  NTSTATUS
3600 
3601 --*/
3602 
3603 {
3606 
3607  //
3608  // Validate request object handle
3609  //
3611  Request,
3613  (PVOID*)&pRequest,
3614  &pFxDriverGlobals);
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 
3636 NTSTATUS
3638  _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
3640  )
3641 {
3642  NTSTATUS status;
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 
3654  pRequest->Unlock(irql);
3655  return status;
3656 }
3657 
3660 BOOLEAN
3661 STDCALL
3662 WDFEXPORT(WdfRequestIsCanceled)(
3663  __in
3665  __in
3666  WDFREQUEST Request
3667  )
3668 
3669 /*++
3670 
3671 Routine 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 
3676 Arguments:
3677 
3678  Request - Request being checked.
3679 
3680 Returns:
3681 
3682  BOOLEAN
3683 
3684 --*/
3685 
3686 {
3689  NTSTATUS status;
3690 
3691  //
3692  // Validate request object handle
3693  //
3695  Request,
3697  (PVOID*)&pRequest,
3698  &pFxDriverGlobals);
3700  if (!NT_SUCCESS(status)) {
3701  return FALSE;
3702  }
3703 
3704  return pRequest->IsCancelled();
3705 }
3706 
3708 VOID
3709 STDCALL
3710 WDFEXPORT(WdfRequestStopAcknowledge)(
3711  __in
3713  __in
3714  WDFREQUEST Request,
3715  __in
3717  )
3718 
3719 /*++
3720 
3721 Routine 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 
3730 Arguments:
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 
3737 Returns:
3738 
3739  None
3740 
3741 --*/
3742 
3746 
3747  //
3748  // Validate request object handle
3749  //
3751  Request,
3753  (PVOID*)&pRequest,
3754  &pFxDriverGlobals);
3755 
3756 #if FX_VERBOSE_TRACE
3758  "Enter: WDFREQUEST 0x%p", Request);
3759 #endif // FX_VERBOSE_TRACE
3760 
3762 }
3763 
3764 
3766 BOOLEAN
3767 STDCALL
3768 WDFEXPORT(WdfRequestIsReserved)(
3769  __in
3771  __in
3772  WDFREQUEST Request
3773  )
3774 /*++
3775 
3776 Routine Description:
3777  This is used to determine if a Request is a reserved request. Reserved
3778  Requests are used for forward progress.
3779 
3780 Arguments:
3781 
3782  Request - Request being checked
3783 
3784 
3785 Returns:
3786 
3787  BOOLEAN
3788 
3789 --*/
3790 
3791 {
3794 
3795  //
3796  // Validate request object handle
3797  //
3799  Request,
3801  (PVOID*)&pRequest,
3802  &pFxDriverGlobals);
3803 
3804  return pRequest->IsReserved();
3805 }
3806 
3807 
3808 } // extern "C" the whole file
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyWdfRequestForwardToParentDeviceIoQueue(_In_ PFX_DRIVER_GLOBALS fxDriverGlobals, _In_ FxRequest *request)
__inline VOID SetCompletionRoutine(__in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine=NULL, __in_opt WDFCONTEXT CompletionContext=NULL)
_Must_inspect_result_ NTSTATUS CreateTimer(VOID)
_In_ WDFREQUEST _In_ PFN_WDF_REQUEST_CANCEL EvtRequestCancel
Definition: wdfrequest.h:727
__in WDFREQUEST __in PIO_STACK_LOCATION Stack
ULONG GetParameterReadLength(VOID)
Definition: fxirpum.cpp:1589
VOID StopAcknowledge(__in BOOLEAN Requeue)
Definition: fxrequest.cpp:2634
BOOLEAN Cancel(VOID)
#define _Must_inspect_result_
Definition: no_sal2.h:62
_Must_inspect_result_ __drv_maxIRQL(DISPATCH_LEVEL) NTSTATUS STDCALL WDFEXPORT(WdfRequestCreate)(__in PWDF_DRIVER_GLOBALS DriverGlobals
FxIoQueue * queue
void CheckUnionAssumptions(VOID)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in MdIrp __in BOOLEAN RequestFreesIrp
#define WDFIOTARGET_FXIOTARGET(handle)
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
_Must_inspect_result_ __in WDFREQUEST __in WDFIOTARGET __in_opt PWDF_REQUEST_SEND_OPTIONS Options
VOID CopyToNextIrpStackLocation(__in PIO_STACK_LOCATION Stack)
Definition: fxirpum.cpp:1216
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
__inline NTSTATUS Complete(__in NTSTATUS Status)
Definition: fxrequest.hpp:770
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
GLint x0
Definition: linetemp.h:95
GLuint64EXT * result
Definition: glext.h:11304
CCHAR GetCurrentIrpStackLocationIndex()
Definition: fxirpum.cpp:521
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:893
MdDeviceObject GetDeviceObject(VOID)
Definition: fxirpum.cpp:1352
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE _In_ PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions
Definition: wdfrequest.h:1731
__inline WDF_DEVICE_IO_TYPE GetIoType(VOID)
Definition: fxdevice.hpp:1084
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
EVT_WDF_REQUEST_CANCEL * PFN_WDF_REQUEST_CANCEL
Definition: wdfrequest.h:130
_In_ WDFREQUEST _In_ PWDF_REQUEST_REUSE_PARAMS ReuseParams
Definition: wdfrequest.h:551
_Must_inspect_result_ __in WDFREQUEST __in size_t __deref_out_bcount Length PVOID * Buffer
WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0)==sizeof(WDF_DRIVER_CONFIG_V1_1))
PVOID pBuffer
FxIoTarget * pTarget
#define FX_VF_FUNCTION(fnName)
Definition: fxmacros.hpp:47
_Must_inspect_result_ FxIoQueue * GetCurrentQueue(VOID)
Definition: fxrequest.hpp:728
LONG NTSTATUS
Definition: precomp.h:26
__inline VOID CopyCompletionParams(__in PWDF_REQUEST_COMPLETION_PARAMS Params)
Definition: fxrequest.hpp:534
static FxDevice * GetFxDevice(__in MdDeviceObject DeviceObject)
Definition: fxdeviceum.cpp:60
#define __deref_out_bcount(size)
Definition: sal.h:2755
_Must_inspect_result_ NTSTATUS GetParameters(__out PWDF_REQUEST_PARAMETERS Parameters)
Definition: fxrequest.cpp:1221
FxObjectHandleGetPtr(pFxDriverGlobals, IoTarget, FX_TYPE_IO_TARGET,(PVOID *)&pTarget)
_Must_inspect_result_ NTSTATUS GetFileObject(__deref_out_opt FxFileObject **pFileObject)
Definition: fxrequest.cpp:2408
__inline FxIrp * GetSubmitFxIrp(VOID)
Definition: fxirp.hpp:28
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
FxVerifierDbgBreakPoint(pFxDriverGlobals)
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
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
FxPointerNotNull(pFxDriverGlobals, Request)
KIRQL irql
Definition: wave.h:1
#define TRACINGAPIERROR
Definition: dbgtrace.h:60
_Must_inspect_result_ __in WDFREQUEST __in size_t __deref_out_bcount_opt Length PVOID * OutputBuffer
DriverGlobals
NTSTATUS GetStatus(VOID)
Definition: fxrequest.cpp:1187
_Must_inspect_result_ NTSTATUS GetDeviceControlOutputMdl(__out PMDL *pMdl)
_Must_inspect_result_ NTSTATUS GetMemoryObject(__deref_out IFxMemory **Memory, __out PVOID *Buffer, __out size_t *Length)
Definition: fxrequest.cpp:1284
FxIrp * pIrp
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyWdfRequestIsCanceled(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest *pRequest)
_Must_inspect_result_ NTSTATUS GetMdl(__out PMDL *pMdl)
Definition: fxrequestkm.cpp:80
virtual WDFMEMORY GetHandle(VOID)=0
__inline NTSTATUS CompleteWithInformation(__in NTSTATUS Status, __in ULONG_PTR Information)
Definition: fxrequest.hpp:810
_Must_inspect_result_ __in WDFREQUEST __out WDFMEMORY * Memory
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1044
#define TRACINGREQUEST
Definition: dbgtrace.h:65
VOID __inline FxObjectHandleGetGlobals(__in PFX_DRIVER_GLOBALS CallersGlobals, __in WDFOBJECT Handle, __out PFX_DRIVER_GLOBALS *ObjectGlobals)
Definition: fxhandle.h:453
size_t length
__in WDFREQUEST __in NTSTATUS RequestStatus
#define PGLOBALS_ACTION(globals)
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_Must_inspect_result_ NTSTATUS ProbeAndLockForWrite(__in PVOID Buffer, __in ULONG Length, __deref_out FxRequestMemory **pMemoryObject)
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS __inline FxValidateRequestOptions(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ PWDF_REQUEST_SEND_OPTIONS Options, _In_opt_ FxRequestBase *Request=NULL)
return pObject GetObjectHandle()
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
_Must_inspect_result_ __in WDFREQUEST __in WDFQUEUE ParentDeviceQueue
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in_opt WDFIOTARGET __out WDFREQUEST * Request
_Must_inspect_result_ __in WDFREQUEST __deref_out PMDL * Mdl
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Request, FX_TYPE_REQUEST,(PVOID *)&pRequest, &pFxDriverGlobals)
_Must_inspect_result_ __in WDFREQUEST __in size_t __out WDFMEMORY * MemoryObject
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES RequestAttributes
UCHAR KIRQL
Definition: env_spec_w32.h:591
FxRequest * request
NTSTATUS SetInformation(__in ULONG_PTR Information)
Definition: fxrequest.cpp:229
__in WDFREQUEST __out PWDF_REQUEST_PARAMETERS Parameters
#define __out_opt
Definition: dbghelp.h:65
#define METHOD_NEITHER
Definition: nt_native.h:597
#define FALSE
Definition: types.h:117
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1011
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
_Must_inspect_result_ __in WDFREQUEST __in WDFQUEUE DestinationQueue
ULONG GetParameterIoctlInputBufferLength(VOID)
Definition: fxirpum.cpp:1518
__inline BOOLEAN IsCancelled(VOID)
Definition: fxrequest.hpp:525
__in WDFREQUEST __in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE __in_opt WDFCONTEXT CompletionContext
#define WDFEXPORT(a)
Definition: fxmacros.hpp:157
#define WDFAPI
Definition: wdftypes.h:53
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in_opt WDFIOTARGET Target
_In_ PWDFDEVICE_INIT _In_ PWDF_OBJECT_ATTRIBUTES RequestAttributes
Definition: wdfdevice.h:3428
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define __out
Definition: dbghelp.h:62
_Must_inspect_result_ NTSTATUS ProbeAndLockForRead(__in PVOID Buffer, __in ULONG Length, __deref_out FxRequestMemory **pMemoryObject)
#define __deref_out_bcount_opt(size)
Definition: sal.h:2783
#define PAGED_CODE_LOCKED()
Definition: kefuncs.h:1429
Definition: _queue.h:59
unsigned char BOOLEAN
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
_Must_inspect_result_ __in WDFREQUEST __in WDFQUEUE __in PWDF_REQUEST_FORWARD_OPTIONS ForwardOptions
IWudfIrp * MdIrp
Definition: mxum.h:103
EVT_WDF_REQUEST_COMPLETION_ROUTINE * PFN_WDF_REQUEST_COMPLETION_ROUTINE
Definition: wdfrequest.h:313
Definition: bufpool.h:45
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:859
ULONG validFlags
_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
#define WDF_REQUEST_REUSE_VALID_FLAGS_V1_9
UNREFERENCED_PARAMETER(status)
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:949
IFxMemory * pMemory
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
__inline VOID VerifierSetFormatted(VOID)
#define STDCALL
Definition: wdf.h:45
KPROCESSOR_MODE GetRequestorMode(VOID)
Definition: fxrequest.cpp:327
__inline BOOLEAN IsReserved()
Definition: fxrequest.hpp:609
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:51
_Must_inspect_result_ __in_opt PWDF_OBJECT_ATTRIBUTES __in MdIrp Irp
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGREQUEST, "Error: This call is valid only on method-neither " "ioctl and write WDFREQUEST %p, %!STATUS!", Request, status)
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define GLOBALS_ACTION(globals)
_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_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
NTSTATUS status
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_Must_inspect_result_ __in WDFREQUEST __in size_t __deref_out_bcount_opt Length PVOID * InputBuffer
#define WDF_REQUEST_REUSE_VALID_FLAGS
_In_ WDFREQUEST _In_ BOOLEAN Requeue
Definition: wdfrequest.h:1651
FxDevice * pDevice
pFxDriverGlobals
unsigned char UCHAR
Definition: xmlstorage.h:181
_Must_inspect_result_ _In_ WDFREQUEST _In_ size_t _Out_ WDFMEMORY * MemoryObject
Definition: wdfrequest.h:1470
FxIrp * GetFxIrp(VOID)
Definition: fxrequest.hpp:957
BOOLEAN result
BOOLEAN Is32bitProcess(VOID)
Definition: fxirpum.cpp:1640
PVOID GetParameterIoctlType3InputBuffer(VOID)
Definition: fxirpum.cpp:1542
PVOID GetUserBuffer()
Definition: fxirpum.cpp:633
#define VOID
Definition: acefi.h:82
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_Must_inspect_result_ __in WDFREQUEST __in_bcount(Length) PVOID Buffer
ULONG GetParameterWriteLength(VOID)
Definition: fxirpum.cpp:1601
_Must_inspect_result_ NTSTATUS ValidateTarget(__in FxIoTarget *Target)
_Must_inspect_result_ FORCEINLINE BOOLEAN WdfRequestSend(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_opt_ PWDF_REQUEST_SEND_OPTIONS Options)
Definition: wdfrequest.h:677
FxPkgGeneral * m_PkgGeneral
Definition: fxdevice.hpp:671
_Must_inspect_result_ NTSTATUS Reuse(__in PWDF_REQUEST_REUSE_PARAMS ReuseParams)
Definition: fxrequest.cpp:2136
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ __in WDFREQUEST __in size_t __deref_out_bcount Length PVOID __out_opt size_t * Length
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:158
#define WDFREQUEST_FXREQUEST(handle)
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyWdfRequestForwardToIoQueue(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest *request)
__in WDFREQUEST __in NTSTATUS __in ULONG_PTR Information
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
PFX_DRIVER_GLOBALS cxDriverGlobals
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
ULONG GetParameterIoctlOutputBufferLength(VOID)
Definition: fxirpum.cpp:1504
__in WDFREQUEST __in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
PFX_DRIVER_GLOBALS fxDriverGlobals
FX_DECLARE_VF_FUNCTION_P1(NTSTATUS, VerifyRequestComplete, _In_ FxRequest *)
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:893
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE ParentDeviceQueue
Definition: wdfrequest.h:1731
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PIRP _In_ BOOLEAN RequestFreesIrp
Definition: wdfrequest.h:513
__inline WDFFILEOBJECT GetHandle(VOID)
ULONG GetParameterIoctlCodeBufferMethod(VOID)
Definition: fxirpum.cpp:1490
#define NULL
Definition: types.h:112
UCHAR majorFunction
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
Definition: tftpd.h:85
#define IRP_MJ_READ
Definition: rdpdr.c:46
__in WDFREQUEST __in NTSTATUS __in CCHAR PriorityBoost
ULONG_PTR GetInformation(VOID)
Definition: fxrequest.cpp:277
__in WDFREQUEST __in PFN_WDF_REQUEST_CANCEL EvtRequestCancel
#define __deref_out
Definition: dbghelp.h:26
_Must_inspect_result_ NTSTATUS Requeue(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:1933
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIOTARGET * IoTarget
Definition: wdfiotarget.h:363
_Must_inspect_result_ _In_ WDFREQUEST _In_ WDFQUEUE DestinationQueue
Definition: wdfrequest.h:1569
__inline CfxDevice * GetDevice(VOID)
Definition: fxrequest.hpp:600
_Must_inspect_result_ NTSTATUS GetDeviceControlOutputMemoryObject(__deref_out IFxMemory **MemoryObject, __out PVOID *Buffer, __out size_t *Length)
Definition: fxrequest.cpp:1524
__in WDFREQUEST __in BOOLEAN Requeue
BOOLEAN HasStack(_In_ UCHAR StackCount)
Definition: fxirpum.cpp:1745
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ASSERT(status==STATUS_SUCCESS)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACINGIO
Definition: dbgtrace.h:66
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
VOID CopyCurrentIrpStackLocationToNext(VOID)
Definition: fxirpum.cpp:209
UCHAR GetMajorFunction(VOID)
Definition: fxirpum.cpp:217
_Must_inspect_result_ NTSTATUS GetIrp(__deref_out MdIrp *ppIrp)
Definition: fxrequest.hpp:975
#define __in
Definition: dbghelp.h:35
FxFileObject * pFO
__in WDFREQUEST __out PWDF_REQUEST_COMPLETION_PARAMS Params
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxRequest * pRequest
BOOLEAN m_NextStackLocationFormatted
FxIrp * irp
__inline WDFREQUEST GetHandle(VOID)
__inline NTSTATUS CompleteWithPriority(__in NTSTATUS Status, __in CCHAR PriorityBoost)
Definition: fxrequest.hpp:825
_Must_inspect_result_ __in WDFREQUEST __in WDFIOTARGET IoTarget
return pFO GetHandle()
__in WDFREQUEST __in PWDF_REQUEST_REUSE_PARAMS ReuseParams
_Must_inspect_result_ __in WDFREQUEST __in size_t RequiredLength
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
__inline FxIoQueue * GetDeafultInternalCreateQueue()
_Must_inspect_result_ NTSTATUS FX_VF_FUNCTION() VerifyRequestComplete(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxRequest *pRequest)
Definition: ps.c:97