ReactOS 0.4.15-dev-7942-gd23573b
fxioqueueapi.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxIoQueueApi.cpp
8
9Abstract:
10
11 This module implements the FxIoQueue object C interfaces
12
13Author:
14
15
16
17
18Revision History:
19
20
21--*/
22
23#include "ioprivshared.hpp"
24#include "fxpkgio.hpp"
25#include "fxioqueue.hpp"
26
27extern "C" {
28// #include "FxIoQueueApi.tmh"
29}
30
31//
32// C Accessor methods
33//
34// These are the "public" API's used by driver writers for both
35// C and C++. In the C++ case, a "wrapper" class is placed around these
36// methods. This is to avoid exposing any internal details of our
37// driver frameworks implementation class, which would cause
38// binary coupling with the device driver.
39//
40// (thus causing drivers to rebuild for even small changes to this C++ object)
41//
42
43//
44// extern all functions
45//
46extern "C" {
47
48
53WDFEXPORT(WdfIoQueueCreate)(
54 __in
56 __in
57 WDFDEVICE Device,
58 __in
63 WDFQUEUE* Queue
64 )
65
66/*++
67
68Routine Description:
69
70 Creates an IoQueue object and returns its handle to the caller.
71
72 The newly created IoQueue object is associated with the IoPackage
73 instance for the device.
74
75 The IoQueue object is automatically dereferenced when its
76 associated device is removed. This driver does not normally have
77 to manually manage IoQueue object reference counts.
78
79 An IoQueue object is created in the WdfIoQueuePause state, and is
80 configured for WdfIoQueueDispatchSynchronous;
81
82Arguments:
83
84 Device - Handle to the Device the I/O Package registered with
85 at EvtDeviceFileCreate time.
86
87 Config - WDF_IO_QUEUE_CONFIG structure
88
89 pQueue - Pointer to location to store the returned IoQueue handle.
90
91Return Value:
92
93 NTSTATUS
94
95--*/
96
97{
98 DDI_ENTRY();
99
105
106 //
107 // Validate the I/O Package handle, and get the FxPkgIo*
108 //
110 Device,
112 (PVOID*)&pDevice,
114
115 pPkgIo = NULL;
116 pQueue = NULL;
117
119
125 return status;
126 }
127
128 // Validate Config structure
129 if (Config->Size != sizeof(WDF_IO_QUEUE_CONFIG) &&
130 Config->Size != sizeof(WDF_IO_QUEUE_CONFIG_V1_9) &&
131 Config->Size != sizeof(WDF_IO_QUEUE_CONFIG_V1_7)) {
133
135 "WDF_IO_QUEUE_CONFIG Size 0x%x, "
136 "expected for v1.7 size 0x%x or v1.9 size 0x%x or "
137 "current version size 0x%x, %!STATUS!",
138 Config->Size, sizeof(WDF_IO_QUEUE_CONFIG_V1_7),
140 sizeof(WDF_IO_QUEUE_CONFIG), status);
141 return status;
142 }
143
144 //
145 // If the queue is not a default queue then the out parameter is not optional
146 //
147 if(!Config->DefaultQueue && Queue == NULL) {
149
152 "Parameter to receive WDFQUEUE handle is not optional "
153 "for non default queue %!STATUS!", status);
154
155 return status;
156 }
157
158 //pPkgIo = (FxPkgIo*)pDevice->m_PkgIo;
160
161 //
162 // If the queue is a default queue, then we restrict the creation to happen
163 // a) before the device is started for pnp devices (FDO or PDO)
164 // b) before the call to WdfControlDeviceFinishInitializing for controldevices.
165 // This is done to prevent some unknown race conditions and reduce
166 // the test matrix.
167 //
168 if(Config->DefaultQueue) {
169
170 if(pDevice->IsLegacy()) {
171 //
172 // This is a controldevice. Make sure the create is called after the device
173 // is initialized and ready to accept I/O.
174 //
178 "Default queue can only be created before WdfControlDeviceFinishInitializing"
179 "on the WDFDEVICE %p is called %!STATUS!",
180 Device,
183 }
184
185 } else {
186 //
187 // This is either FDO or PDO. Make sure it's not started yet.
188 //
193 "Default queue can only be created before the WDFDEVICE 0x%p "
194 "is started, %!STATUS!", Device, status);
195 return status;
196 }
197 }
198 }
199
200 //
201 // Create the Queue for the I/O package
202 //
206 &pQueue);
207 if (!NT_SUCCESS(status)) {
209 "Queue Creation failed "
210 "for WDFDEVICE 0x%p, %!STATUS!", Device, status);
211 return status;
212 }
213
214 if(Config->DefaultQueue) {
215
216 //
217 // Make this a default queue. The default queue receives any
218 // I/O requests that have not been otherwise forwarded to another
219 // queue by WdfDeviceConfigureRequestDispatching .
220 //
221
223 pDevice,
224 pQueue
225 );
226
227 if (!NT_SUCCESS(status)) {
229 "Create failed "
230 "for FxPkgIo 0x%p, WDFDEVICE 0x%p",pPkgIo, Device);
231 //
232 // Delete the queue *without* invoking driver defined callbacks
233 //
235
236 return status;
237 }
238 }
239
241 "Created WDFQUEUE 0x%p", pQueue->GetObjectHandle());
242
243 if(Queue != NULL) {
244 *Queue = (WDFQUEUE)pQueue->GetObjectHandle();
245 }
246
248}
249
250
254WDFEXPORT(WdfIoQueueGetState)(
255 __in
257 __in
258 WDFQUEUE Queue,
263 )
264
265/*++
266
267Routine Description:
268
269 Return the Queues status
270
271Arguments:
272
273 Queue - Handle to Queue object
274
275 pQueueCount - Count of requests in the Queue not presented
276 to the driver.
277
278 pDriverCount - Count of requests the driver is operating
279 on that are associated with this queue.
280
281Returns:
282
283 WDF_IO_QUEUE_STATE
284
285--*/
286
287{
288 DDI_ENTRY();
289
291
293 Queue,
295 (PVOID*)&pQueue);
296
298}
299
301WDFDEVICE
303WDFEXPORT(WdfIoQueueGetDevice)(
304 __in
306 __in
307 WDFQUEUE Queue
308 )
309
310/*++
311
312Routine Description:
313 Returns the device handle that the queue is associated with
314
315Arguments:
316 Queue - Handle to queue object
317
318Return Value:
319 WDFDEVICE handle
320
321--*/
322
323{
324 DDI_ENTRY();
325
327
329 Queue,
331 (PVOID*) &pQueue);
332
333 return (WDFDEVICE) pQueue->GetDevice()->GetHandle();
334}
335
336
338VOID
340WDFEXPORT(WdfIoQueueStart)(
341 __in
343 __in
344 WDFQUEUE Queue
345 )
346
347/*++
348
349Routine Description:
350
351 Set the Queues state to start accepting and dispatching new requests.
352
353Arguments:
354
355 Queue - Handle to Queue object
356
357 A Queue may not go into a specific state right away, since it may have to
358 wait for requests to be completed or cancelled. This is reflected
359 in the status returned by WdfIoQueueGetState.
360
361 See the Queue event API's for asynchronous notification of
362 specific status states.
363
364Returns:
365
366 NTSTATUS
367--*/
368
369{
370 DDI_ENTRY();
371
373
375 Queue,
377 (PVOID*)&pQueue);
378
380
381 return;
382}
383
385VOID
387WDFEXPORT(WdfIoQueueStop)(
388 __in
390 __in
391 WDFQUEUE Queue,
398 )
399
400/*++
401
402Routine Description:
403
404 Set the Queue state to accept and queue (not dispatch) incoming new requests.
405
406Arguments:
407
408 Queue - Handle to Queue object
409
410 A Queue may not go into a specific state right away, since it may have to
411 wait for requests to be completed or cancelled. This is reflected
412 in the status returned by WdfIoQueueGetState.
413
414 See the Queue event API's for asynchronous notification of
415 specific status states.
416
417Returns:
418
419--*/
420
421{
422 DDI_ENTRY();
423
426
428 Queue,
430 (PVOID*)&pQueue);
431
433 if (!NT_SUCCESS(status)) {
435 return;
436 }
437
438 return;
439}
440
442VOID
444WDFEXPORT(WdfIoQueueStopSynchronously)(
445 __in
447 __in
448 WDFQUEUE Queue
449 )
450
451/*++
452
453Routine Description:
454
455 Set the Queue state to accept and queue (not dispatch) incoming new requests and wait
456 for 1) all the dispatch callbacks to return and 2) all the driver-owned request to complete.
457
458Arguments:
459
460 Queue - Handle to Queue object
461
462Returns:
463
464 NTSTATUS
465--*/
466
467{
468 DDI_ENTRY();
469
473
475 Queue,
477 (PVOID*)&pQueue,
479
481 if (!NT_SUCCESS(status)) {
482 return;
483 }
484
486
487 if (!NT_SUCCESS(status)) {
489 return;
490 }
491}
492
494VOID
496WDFEXPORT(WdfIoQueueStopAndPurge)(
497 __in
499 __in
500 WDFQUEUE Queue,
501 __drv_when(Context != 0, __in)
507 )
508
509/*++
510
511Routine Description:
512
513 This function does the following:
514 - sets the queue state to accept and queues (not dispatch) incoming new requests.
515 - cancels all current (at the time this function is called) queued requests.
516 - invokes, if present, the cancel callback of cancellable driver requests.
517 - Asynchronously if complete callback is specified, it waits until
518 1) all the dispatch callbacks to return and
519 2) all the driver-owned request to complete.
520
521Arguments:
522
523 Queue - Handle to Queue object
524
525 A Queue may not go into a specific state right away, since it may have to
526 wait for requests to be completed or cancelled. This is reflected
527 in the status returned by WdfIoQueueGetState.
528
529 See the Queue event API's for asynchronous notification of
530 specific status states.
531
532Returns:
533
534--*/
535
536{
537 DDI_ENTRY();
538
541
543 Queue,
545 (PVOID*)&queue);
546
548 if (!NT_SUCCESS(status)) {
549 queue->FatalError(status);
550 return;
551 }
552
553 return;
554}
555
557VOID
559WDFEXPORT(WdfIoQueueStopAndPurgeSynchronously)(
560 __in
562 __in
563 WDFQUEUE Queue
564 )
565
566/*++
567
568Routine Description:
569
570 This function does the following:
571 - sets the queue state to accept and queues (not dispatch) incoming new requests.
572 - cancels all current (at the time this function is called) queued requests.
573 - invokes, if present, the cancel callback of cancellable driver requests.
574 - before returning it waits until
575 1) all the dispatch callbacks to return and
576 2) all the driver-owned request to complete.
577
578Arguments:
579
580 Queue - Handle to Queue object
581
582Returns:
583
584 NTSTATUS
585--*/
586
587{
588 DDI_ENTRY();
589
593
595 Queue,
597 (PVOID*)&queue,
599
601 if (!NT_SUCCESS(status)) {
602 return;
603 }
604
605 status = queue->QueueIdleSynchronously(TRUE);
606
607 if (!NT_SUCCESS(status)) {
608 queue->FatalError(status);
609 return;
610 }
611}
612
617WDFEXPORT(WdfIoQueueRetrieveNextRequest)(
618 __in
620 __in
621 WDFQUEUE Queue,
622 __out
623 WDFREQUEST *OutRequest
624 )
625
626/*++
627
628WdfIoQueueRetrieveNextRequest:
629
630Routine Description:
631
632 Returns a request from the head of the queue.
633
634 On successful return the driver owns the request, and must
635 eventually call WdfRequestComplete.
636
637 The driver does not need to release any extra reference counts,
638 other than calling WdfRequestComplete.
639
640
641Arguments:
642
643 Queue - Queue handle
644
645 pOutRequest - Pointer to location to return new request handle
646
647Returns:
648
649
650 STATUS_NO_MORE_ENTRIES - The queue is empty
651
652 STATUS_SUCCESS - A request was returned in pOutRequest
653
654--*/
655
656{
657 DDI_ENTRY();
658
662
664 Queue,
666 (PVOID*)&pQueue);
667
669
671
673 *OutRequest = (WDFREQUEST)pOutputRequest->GetObjectHandle();
674 } else {
675 *OutRequest = NULL;
677 }
678
679 return status;
680}
681
686WDFEXPORT(WdfIoQueueRetrieveRequestByFileObject)(
687 __in
689 __in
690 WDFQUEUE Queue,
691 __in
692 WDFFILEOBJECT FileObject,
693 __out
694 WDFREQUEST *OutRequest
695 )
696
697/*++
698
699WdfIoQueueRetrieveNextRequest:
700
701Routine Description:
702
703 Returns a request from the queue that matches the fileobject.
704
705 Requests are dequeued in a first in, first out manner.
706
707 If there are no requests that match the selection criteria,
708 STATUS_NO_MORE_ENTRIES is returned.
709
710 On successful return the driver owns the request, and must
711 eventually call WdfRequestComplete.
712
713 The driver does not need to release any extra reference counts,
714 other than calling WdfRequestComplete.
715
716Arguments:
717
718 Queue - Queue handle
719
720 FileObject - FileObject to match in the request
721
722 pOutRequest - Pointer to location to return new request handle
723
724Returns:
725
726
727 STATUS_NO_MORE_ENTRIES - The queue is empty, or no more requests
728 match the selection criteria of TagRequest
729 and FileObject specified above.
730
731 STATUS_SUCCESS - A request context was returned in
732 pOutRequest
733
734--*/
735
736{
737 DDI_ENTRY();
738
745
747 Queue,
749 (PVOID*)&pQueue,
751
753
757 (PVOID*)&pFO);
758
759 // Get the real WDM fileobject
761
763
764 if (NT_SUCCESS(status)) {
765
766 // Copy out the handle to the new request
767 *OutRequest = (WDFREQUEST)pOutputRequest->GetObjectHandle();
768 } else {
769 *OutRequest = NULL;
771 }
772
773 return status;
774}
775
780WDFEXPORT(WdfIoQueueRetrieveFoundRequest)(
781 __in
783 __in
784 WDFQUEUE Queue,
785 __in
786 WDFREQUEST TagRequest,
787 __out
788 WDFREQUEST * OutRequest
789 )
790
791/*++
792
793WdfIoQueueRetrieveNextRequest:
794
795Routine Description:
796
797 Returns a request from the queue.
798
799 Requests are dequeued in a first in, first out manner.
800
801 The queue is searched for specific peeked
802 request, and if it is not found, STATUS_NOT_FOUND is
803 returned. A TagRequest value is returned
804 from WdfIoQueueFindRequest().
805
806 If there are no requests that match the selection criteria,
807 STATUS_NO_MORE_ENTRIES is returned.
808
809 On successful return the driver owns the request, and must
810 eventually call WdfRequestComplete.
811
812 The driver does not need to release any extra reference counts,
813 other than calling WdfRequestComplete.
814
815Arguments:
816
817 Queue - Queue handle
818
819 TagRequest - Request to look for in queue
820
821 pOutRequest - Pointer to location to return new request handle
822
823Returns:
824
825 STATUS_NOT_FOUND - TagContext was specified, but not
826 found in the queue. This could be
827 because the request was cancelled,
828 or is part of an active queue and
829 the request was passed to the driver
830 or forwarded to another queue.
831
832 STATUS_NO_MORE_ENTRIES - The queue is empty, or no more requests
833 match the selection criteria of TagRequest
834 specified above.
835
836 STATUS_SUCCESS - A request context was returned in
837 pOutRequest
838
839--*/
840
841{
842 DDI_ENTRY();
843
849
851 Queue,
853 (PVOID*)&pQueue,
855
857
861 (PVOID*)&pTagRequest);
862
864
865 if (NT_SUCCESS(status)) {
866 // Copy out the handle to the new request
867 *OutRequest = (WDFREQUEST)pOutputRequest->GetObjectHandle();
868 } else {
869 *OutRequest = NULL;
870 }
871
872 return status;
873}
874
879WDFEXPORT(WdfIoQueueFindRequest)(
880 __in
882 __in
883 WDFQUEUE Queue,
885 WDFREQUEST TagRequest,
887 WDFFILEOBJECT FileObject,
890 __out
891 WDFREQUEST * OutRequest
892 )
893
894/*++
895
896WdfIoQueueFindRequest:
897
898Routine Description:
899
900 PeekRequest allows a caller to enumerate through requests in
901 a queue, optionally only returning requests that match a specified
902 FileObject.
903
904 The first call specifies TagContext == NULL, and the first request
905 in the queue that matches the FileObject is returned.
906
907 Subsequent requests specify the previous request value as the
908 TagContext, and searching will continue at the request that follows.
909
910 If the queue is empty, there are no requests after TagContext, or no
911 requests match the FileObject, NULL is returned.
912
913 If FileObject == NULL, this matches any FileObject in a request.
914
915 If a WDF_REQUEST_PARAMETERS structure is supplied, the information
916 from the request is returned to allow the driver to further examine
917 the request to decide whether to service it.
918
919 If a TagRequest is specified, and it is not found, the return
920 status STATUS_NOT_FOUND means that the queue should
921 be re-scanned. This is because the TagRequest was cancelled from
922 the queue, or if the queue was active, delivered to the driver.
923 There may still be un-examined requests on the queue that match
924 the drivers search criteria, but the search marker has been lost.
925
926 Re-scanning the queue starting with TagRequest == NULL and
927 continuing until STATUS_NO_MORE_ENTRIES is returned will ensure
928 all requests have been examined.
929
930 Enumerating an active queue with this API could result in the
931 driver frequently having to re-scan.
932
933 If a successful return of a Request object handle occurs, the driver
934 *must* call WdfObjectDereference when done with it, otherwise an
935 object leak will result.
936
937 Returned request objects are not owned by the driver, and may not be
938 used by I/O or completed. The only valid operations are
939 WdfRequestGetParameters, passing it as the TagRequest parameter to
940 WdfIoQueueFindRequest, WdfIoQueueRetrieveFoundRequest, or calling
941 WdfObjectDereference. All other actions are undefined.
942
943 The request could be cancelled without a EvtIoCancel callback while the
944 driver has the handle. The request then becomes invalid, and
945 WdfObjectDereference must be called to release its resources.
946
947 The caller should not use any buffer pointers in the returned parameters
948 structure until it successfully receives ownership of the request by
949 calling WdfIoQueueRetrieveFoundRequest with the request tag. This is because
950 the I/O can be cancelled and completed at any time without the driver
951 being notified until it has received ownership, thus invalidating
952 the buffer pointers and releasing the memory, even if the request
953 object itself it still valid due to the reference.
954
955 The driver should hold the reference on the object until after
956 a call to WdfIoQueueFindRequest using it as the TagRequest
957 parameter, or WdfIoQueueRetrieveFoundtRequest. Otherwise, a race could
958 result in which the object is cancelled, its memory re-used for
959 a new request, and then an attempt to use it as a tag would result
960 in a different state than intended. The driver verifier will
961 catch this, but it is a rare race.
962
963 Calling this API on an operating Queue can lead to confusing results. This
964 is because the request could be presented to EvtIoDefault, causing it to be
965 invalid as a TagRequest in calls to WdfIoQueueFindRequest, and
966 WdfIoQueueRetrieveFoundRequest. The extra reference taken on the object by its return
967 from this call must still be released by WdfObjectDereference.
968
969 The intention of the API is to only hold onto the TagRequest long enough
970 for the driver to make a decision whether to service the request, or
971 to continue searching for requests.
972
973Arguments:
974
975 Queue - Queue handle
976
977 TagRequest - If !NULL, request to begin search at
978
979 FileObject - If !NULL, FileObject to match in the request
980
981 Parameters - If !NULL, pointer to buffer to return the requests
982 parameters to aid in selection.
983
984 pOutRequest - Pointer to location to return request handle
985
986Returns:
987
988 STATUS_NOT_FOUND - TagContext was specified, but not
989 found in the queue. This could be
990 because the request was cancelled,
991 or is part of an active queue and
992 the request was passed to the driver
993 or forwarded to another queue.
994
995 STATUS_NO_MORE_ENTRIES - The queue is empty, or no more requests
996 match the selection criteria of TagRequest
997 and FileObject specified above.
998
999 STATUS_SUCCESS - A request context was returned in
1000 pOutRequest
1001
1002--*/
1003
1004{
1005 DDI_ENTRY();
1006
1014
1016 Queue,
1018 (PVOID*)&pQueue,
1020
1022
1023 //
1024 // Validate tag request handle if supplied
1025 //
1028 TagRequest,
1030 (PVOID*)&pTagRequest);
1031 }
1032
1033 //
1034 // If present, validate the FileObject object handle,
1035 // and get its FxFileObject*
1036 //
1039 FileObject,
1041 (PVOID*)&pFO);
1042 //
1043 // Get the real WDM fileobject
1044 //
1046 }
1047
1048 //
1049 // If a parameters buffer is supplied, validate its length
1050 //
1051 if ((Parameters != NULL) && (Parameters->Size < sizeof(WDF_REQUEST_PARAMETERS))) {
1054 "Invalid WDF_REQUEST_PARAMETERS size %d %!STATUS!",
1055 Parameters->Size, status);
1056 return status;
1057 }
1058
1059
1061 pWdmFO,
1062 Parameters,
1064
1065 if (NT_SUCCESS(status)) {
1066 //
1067 // Copy out the handle to the new request
1068 //
1069 *OutRequest = (WDFREQUEST)pOutputRequest->GetObjectHandle();
1070 } else {
1071 *OutRequest = NULL;
1072 }
1073
1074 return status;
1075}
1076
1078VOID
1079STDCALL
1080WDFEXPORT(WdfIoQueueDrain)(
1081 __in
1083 __in
1084 WDFQUEUE Queue,
1085 __drv_when(Context != 0, __in)
1091 )
1092
1093/*++
1094
1095 Set the Queue to reject new requests, with newly arriving
1096 requests being completed with STATUS_CANCELLED.
1097
1098 If the optional DrainComplete callback is specified, the
1099 callback will be invoked with the supplied context when
1100 there are no requests owned by the driver and no request pending in the
1101 queue.
1102
1103 Only one callback registration for WdfIoQueueIdle, WdfIoQueuePurge,
1104 or WdfIoQueueDrain may be outstanding at a time.
1105
1106--*/
1107
1108{
1109 DDI_ENTRY();
1110
1113
1115 Queue,
1117 (PVOID*)&pQueue);
1118
1120
1121 if (!NT_SUCCESS(status)) {
1123 return;
1124 }
1125
1126 return;
1127}
1128
1130VOID
1131STDCALL
1132WDFEXPORT(WdfIoQueueDrainSynchronously)(
1133 __in
1135 __in
1136 WDFQUEUE Queue
1137 )
1138
1139/*++
1140
1141 Set the Queue to fail new request with STATUS_CANCELLED,
1142 dispatches pending requests, and waits for the all the pending and
1143 inflight requests to complete before returning.
1144
1145 Should be called at PASSIVE_LEVEL.
1146
1147--*/
1148
1149{
1150 DDI_ENTRY();
1151
1155
1157 Queue,
1159 (PVOID*)&pQueue,
1161
1163 if (!NT_SUCCESS(status)) {
1164 return;
1165 }
1166
1168
1169 if (!NT_SUCCESS(status)) {
1171 return;
1172 }
1173}
1174
1176VOID
1177STDCALL
1178WDFEXPORT(WdfIoQueuePurgeSynchronously)(
1179 __in
1181 __in
1182 WDFQUEUE Queue
1183 )
1184
1185/*++
1186
1187 Sets the queue state to fail incoming requests,
1188 cancels all the pending requests, cancels in-flights requests
1189 (if they are marked cancelable), and waits for all the requests
1190 to complete before returning.
1191
1192 Should be called at PASSIVE_LEVEL.
1193
1194--*/
1195
1196{
1197 DDI_ENTRY();
1198
1202
1204 Queue,
1206 (PVOID*)&pQueue,
1208
1210 if (!NT_SUCCESS(status)) {
1211 return;
1212 }
1213
1215
1216 if (!NT_SUCCESS(status)) {
1218 return;
1219 }
1220
1221 return;
1222}
1223
1225VOID
1226STDCALL
1227WDFEXPORT(WdfIoQueuePurge)(
1228 __in
1230 __in
1231 WDFQUEUE Queue,
1232 __drv_when(Context != 0, __in)
1238 )
1239
1240/*++
1241
1242 Set the Queue to reject new requests, with newly arriving
1243 requests being completed with STATUS_CANCELLED.
1244
1245 A Queue may not purge immediately, since the device driver
1246 could be operating on non-cancelable requests.
1247
1248
1249 If the optional PurgeComplete callback is specified, the
1250 callback will be invoked with the supplied context when
1251 the Queue is in the WDF_IO_QUEUE_PURGED state.
1252 (Reject new requests, no current requests in Queue or device driver)
1253
1254 Only one callback registration for WdfIoQueueIdle, WdfIoQueuePurge,
1255 or WdfIoQueueDrain may be outstanding at a time.
1256
1257--*/
1258
1259{
1260 DDI_ENTRY();
1261
1264
1266 Queue,
1268 (PVOID*)&pQueue);
1269
1271 TRUE,
1272 TRUE,
1274 Context
1275 );
1276
1277 if (!NT_SUCCESS(status)) {
1279 return;
1280 }
1281
1282 return;
1283}
1284
1285
1289STDCALL
1290WDFEXPORT(WdfIoQueueReadyNotify)(
1291 __in
1293 __in
1294 WDFQUEUE Queue,
1295 __in_opt
1297 __in_opt
1299 )
1300
1301/*++
1302
1303 This API notifies the device driver when the Queue
1304 has one or more requests that can be processed by
1305 the device driver.
1306
1307 This event registration continues until cancelled with
1308 by calling with NULL for QueueReady.
1309
1310 One event is generated for each transition from
1311 not ready, to ready. An event is not generated for each
1312 new request, only request arrival on an empty Queue.
1313
1314--*/
1315
1316{
1317 DDI_ENTRY();
1318
1321
1323 Queue,
1325 (PVOID*)&pQueue);
1326
1328 QueueReady,
1329 Context
1330 );
1331
1332 return status;
1333}
1334
1338STDCALL
1339WDFEXPORT(WdfIoQueueAssignForwardProgressPolicy)(
1340 __in
1342 __in
1343 WDFQUEUE Queue,
1344 __in
1346 )
1347
1348/*++
1349
1350 This DDI is used by the driver to configure a queue to have forward
1351 progress.
1352--*/
1353{
1354 DDI_ENTRY();
1355
1359
1361 Queue,
1363 (PVOID*)&pQueue,
1365
1368 if (!NT_SUCCESS(status)) {
1369 return status;
1370 }
1371
1373 //
1374 // Queue is already configured for forward progress
1375 //
1378 "Queue is already configured for forward progress %!STATUS!",
1379 status);
1381 return status;
1382 }
1383
1384 //
1385 // Validate Config structure
1386 //
1390 "WDF_IO_QUEUE_FORWARD_PROGRESS_POLICY Size 0x%x, "
1391 "expected 0x%x, %!STATUS!",
1393 return status;
1394 }
1395
1396 //
1397 // Validate policy settings
1398 //
1399 switch (ForwardProgressPolicy->ForwardProgressReservedPolicy) {
1401 if (ForwardProgressPolicy->ForwardProgressReservePolicySettings.Policy.ExaminePolicy.EvtIoWdmIrpForForwardProgress == NULL) {
1404 "Examine callback can't be null for WdfIoForwardProgressReservedPolicyUseExamine "
1405 " %!STATUS!",
1406 status);
1407
1408 return status;
1409 }
1410 break;
1411
1412 default:
1413 break;
1414
1415 }
1416
1417 //
1418 // Validate number of forward progress requests
1419 //
1420 if (ForwardProgressPolicy->TotalForwardProgressRequests == 0) {
1423 "Need to have more than 0 reserved Requests %!STATUS!",
1424 status);
1425
1426 return status;
1427 }
1428
1431 );
1432
1433 return status;
1434}
1435
1436
1437
1438} // extern "C"
LONG NTSTATUS
Definition: precomp.h:26
ULONG __inline GetDeviceObjectFlags(VOID)
Definition: fxdevice.hpp:192
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
__inline BOOLEAN IsLegacy(VOID)
Definition: fxdevice.hpp:1209
FxPkgIo * m_PkgIo
Definition: fxdevice.hpp:669
__inline WDF_DEVICE_PNP_STATE GetDevicePnpState()
Definition: fxdevice.hpp:1149
__inline MdFileObject GetWdmFileObject(VOID)
DECLSPEC_NORETURN VOID FatalError(__in NTSTATUS Status)
Definition: fxioqueue.cpp:6339
_Must_inspect_result_ NTSTATUS QueueIdle(__in BOOLEAN CancelQueueRequests, __in_opt PFN_WDF_IO_QUEUE_STATE IdleComplete, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:3584
_Must_inspect_result_ NTSTATUS QueueDrainSynchronously(VOID)
Definition: fxioqueue.cpp:4177
__inline BOOLEAN IsForwardProgressQueue(VOID)
Definition: fxioqueue.hpp:1264
_Must_inspect_result_ NTSTATUS ReadyNotify(__in PFN_WDF_IO_QUEUE_STATE QueueReady, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:3455
_Must_inspect_result_ NTSTATUS QueueIdleSynchronously(__in BOOLEAN CancelRequests)
Definition: fxioqueue.cpp:3838
_Must_inspect_result_ NTSTATUS AssignForwardProgressPolicy(__in PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY Policy)
__inline CfxDevice * GetDevice(VOID)
Definition: fxioqueue.hpp:773
VOID QueueStart(VOID)
Definition: fxioqueue.cpp:3552
_Must_inspect_result_ NTSTATUS GetRequest(__in_opt MdFileObject FileObject, __in_opt FxRequest *TagRequest, __deref_out FxRequest **pOutRequest)
Definition: fxioqueue.cpp:962
_Must_inspect_result_ NTSTATUS PeekRequest(__in_opt FxRequest *TagRequest, __in_opt MdFileObject FileObject, __out_opt PWDF_REQUEST_PARAMETERS Parameters, __deref_out FxRequest **pOutRequest)
Definition: fxioqueue.cpp:1197
WDF_IO_QUEUE_STATE GetState(__out_opt PULONG pQueueCount, __out_opt PULONG pDriverCount)
Definition: fxioqueue.cpp:760
_Must_inspect_result_ NTSTATUS QueuePurge(__in BOOLEAN CancelQueueRequests, __in BOOLEAN CancelDriverRequests, __in_opt PFN_WDF_IO_QUEUE_STATE PurgeComplete, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:3894
_Must_inspect_result_ NTSTATUS QueuePurgeSynchronously(VOID)
Definition: fxioqueue.cpp:4107
_Must_inspect_result_ NTSTATUS QueueDrain(__in_opt PFN_WDF_IO_QUEUE_STATE DrainComplete, __in_opt WDFCONTEXT Context)
Definition: fxioqueue.cpp:4158
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
_Must_inspect_result_ NTSTATUS CreateQueue(__in PWDF_IO_QUEUE_CONFIG Config, __in PWDF_OBJECT_ATTRIBUTES QueueAttributes, __in_opt FxDriver *Caller, __deref_out FxIoQueue **ppQueue)
Definition: fxpkgio.cpp:981
_Must_inspect_result_ NTSTATUS InitializeDefaultQueue(__in CfxDevice *Device, __inout FxIoQueue *Queue)
Definition: fxpkgio.cpp:489
Definition: _queue.h:67
#define __out_opt
Definition: dbghelp.h:65
#define __inout_opt
Definition: dbghelp.h:53
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGPNP
Definition: dbgtrace.h:67
#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
#define __drv_when(cond, annotes)
Definition: driverspecs.h:335
#define __drv_maxIRQL(irql)
Definition: driverspecs.h:291
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FxVerifierDbgBreakPoint(pFxDriverGlobals)
DriverGlobals
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
#define DDI_ENTRY()
Definition: fxglobalskm.h:56
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIO, "Created WDFQUEUE 0x%p", pQueue->GetObjectHandle())
_Must_inspect_result_ __in WDFQUEUE __in WDFREQUEST TagRequest
_Must_inspect_result_ __in WDFQUEUE __in WDFFILEOBJECT FileObject
_Must_inspect_result_ __in WDFQUEUE __in_opt WDFREQUEST __in_opt WDFFILEOBJECT __inout_opt PWDF_REQUEST_PARAMETERS Parameters
_Must_inspect_result_ __in WDFQUEUE __out WDFREQUEST * OutRequest
FxRequest * pTagRequest
__in WDFQUEUE __out_opt PULONG __out_opt PULONG DriverCount
FxIoQueue * pQueue
CfxDevice * pDevice
__in WDFQUEUE __out_opt PULONG QueueCount
FxIoQueue * queue
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Queue, FX_TYPE_QUEUE,(PVOID *)&pQueue)
return STATUS_SUCCESS
_Must_inspect_result_ __in WDFDEVICE __in PWDF_IO_QUEUE_CONFIG Config
FxRequest * pOutputRequest
_Must_inspect_result_ __in WDFDEVICE Device
PFX_DRIVER_GLOBALS fxDriverGlobals
NTSTATUS status
FxFileObject * pFO
MdFileObject pWdmFO
_Must_inspect_result_ __in WDFQUEUE __in_opt PFN_WDF_IO_QUEUE_STATE QueueReady
__in WDFQUEUE __in_opt PFN_WDF_IO_QUEUE_STATE __in_opt WDFCONTEXT Context
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE,(PVOID *)&pDevice, &pFxDriverGlobals)
_Must_inspect_result_ __in WDFDEVICE __in PWDF_IO_QUEUE_CONFIG __in_opt PWDF_OBJECT_ATTRIBUTES QueueAttributes
_Must_inspect_result_ __in WDFDEVICE __in PWDF_IO_QUEUE_CONFIG __in_opt PWDF_OBJECT_ATTRIBUTES __out_opt WDFQUEUE * Queue
FxPkgIo * pPkgIo
_Must_inspect_result_ __in WDFQUEUE __in PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY ForwardProgressPolicy
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define WDFEXPORT(a)
Definition: fxmacros.hpp:157
#define FxPointerNotNull(FxDriverGlobals, Ptr)
Definition: fxmacros.hpp:253
@ FX_TYPE_FILEOBJECT
Definition: fxtypes.h:71
@ FX_TYPE_DEVICE
Definition: fxtypes.h:47
@ FX_TYPE_QUEUE
Definition: fxtypes.h:48
@ FX_TYPE_REQUEST
Definition: fxtypes.h:53
@ FX_VALIDATE_OPTION_SYNCHRONIZATION_SCOPE_ALLOWED
@ FX_VALIDATE_OPTION_EXECUTION_LEVEL_ALLOWED
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ps.c:97
uint32_t * PULONG
Definition: typedefs.h:59
#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 STDCALL
Definition: wdf.h:45
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
@ WdfDevStatePnpInit
Definition: wdfdevice.h:69
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
@ WdfIoForwardProgressReservedPolicyUseExamine
Definition: wdfio.h:468
_Must_inspect_result_ _In_ WDFQUEUE _Out_ WDFREQUEST * OutRequest
Definition: wdfio.h:800
EVT_WDF_IO_QUEUE_STATE * PFN_WDF_IO_QUEUE_STATE
Definition: wdfio.h:380
_In_ WDFQUEUE _In_opt_ PFN_WDF_IO_QUEUE_STATE PurgeComplete
Definition: wdfio.h:1030
_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_ WDFQUEUE _In_ PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY ForwardProgressPolicy
Definition: wdfio.h:1103
_In_ WDFQUEUE _In_opt_ PFN_WDF_IO_QUEUE_STATE StopComplete
Definition: wdfio.h:712
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_IO_QUEUE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES QueueAttributes
Definition: wdfio.h:617
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ PFN_WDF_IO_QUEUE_STATE QueueReady
Definition: wdfio.h:1067
enum _WDF_IO_QUEUE_STATE WDF_IO_QUEUE_STATE
_In_ WDFQUEUE _In_opt_ PFN_WDF_IO_QUEUE_STATE StopAndPurgeComplete
Definition: wdfio.h:1133
_In_ WDFQUEUE _In_opt_ PFN_WDF_IO_QUEUE_STATE DrainComplete
Definition: wdfio.h:968