ReactOS 0.4.16-dev-1946-g52006dd
fxusbpipe.cpp
Go to the documentation of this file.
1//
2// Copyright (C) Microsoft. All rights reserved.
3//
4#include "fxusbpch.hpp"
5
6extern "C" {
7#if defined(EVENT_TRACING)
8#include "FxUsbPipe.tmh"
9#endif
10}
11
12#include "fxglobals.h"
13//
14// NOTE: There are 3 different paths Requests could be sent to the lower driver
15// 1) In case of reposting a successfully completed Request use the Dpc which calls SendIo.
16// 2) For a failed completion use a workitem which works if the IoTarget is in Started state.
17// 3) On moving to the start state the Repeater requests are inserted into the
18// Iotargets Pended Queue directly.
19//
20// The function ResubmitRepeater calls SubmitLocked. If the action we get back
21// from SubmitLocked is "SubmitSend", (SubmitQueued is treated as failure because
22// of WDF_REQUEST_SEND_INTERNAL_OPTION_FAIL_ON_PEND flag) we are guaranteed to
23// call IoCallDriver in the workitem or the DPC and hence the completion routine
24// being called.
25// This is very important because we increment the m_IoCount in SubmitLocked and
26// decrement in the completion routine. So if there was a code path where
27// SubmitLocked was called and IoCallDriver(hence the completion routine) wasn't,
28// the IoTarget could stop responding in Dispose.
29//
30
31
34 __in UCHAR NumReaders
35 ) :
36 m_NumReaders(NumReaders),
37 m_NumFailedReaders(0)
38{
45
47 m_Pipe = Pipe;
48
50
52}
53
55{
56 LONG i;
57
59
60 //
61 // It is impoortant to delete the requests before the lookaside because the
62 // requests may have outstanding references on memory objects allocated by
63 // the lookaside. The lookaside will not be truly deleted until the oustanding
64 // memory object allocations are also freed.
65 //
66 for (i = 0; i < m_NumReaders; i++) {
67 if (reader[i].Request != NULL) {
69
70 reader[i].Request->DeleteObject();
71 reader[i].Request = NULL;
72 }
73
74#if (FX_CORE_MODE == FX_CORE_USER_MODE)
75 reader[i].ReadCompletedEvent.Uninitialize();
76 reader[i].m_ReadWorkItem.Free();
77#endif
78 }
79
80 if (m_Lookaside != NULL) {
82 }
83
84 if (m_WorkItem != NULL) {
87 }
88}
89
93 )
94{
95 BOOLEAN queued;
97
98 queued = FALSE;
100
102 //
103 // No item queued, queue it up now.
104 //
107 "WDFUSBPIPE %p continuous reader queueing work item to recover "
108 "from failed allocation", m_Pipe->GetHandle());
109
112 queued = TRUE;
113 }
114 else {
116 "Could not Queue workitem");
117 }
118 }
119
120 //
121 // We only want to queue the work item while the target is in the
122 // started state. If it is not started, then we are no longer sending
123 // i/o and we should not queue the work item to try to restart.
124 //
125 if (FALSE == queued) {
128 "WDFUSBPIPE %p continuous reader not queueing work item,"
129 "WorkItemQueued = %d, target state %!WDF_IO_TARGET_STATE!",
131 }
132
133 return queued;
134}
135
136ULONG
138 __in FxUsbPipeRepeatReader* Repeater,
140 )
141{
145 KIRQL irql;
146
147 action = 0;
150
151 //
152 // Reformat and allocate any new needed buffers
153 //
154 status = FormatRepeater(Repeater);
155
156 m_Pipe->Lock(&irql);
157
158 //
159 // Do not re-submit repeaters if there is a queued/running work-item to
160 // reset pipe. Work-item will restart this repeater later.
161 // This check needs to be done after the FormatRepeater() call above to
162 // prevent a race condition where we are not detecting when the repeater
163 // is cancelled.
164 //
165 if (m_WorkItemQueued) {
166 //
167 // Return an error and no action flags to let the caller know that
168 // this request was not sent.
169 //
171
174 "WDFUSBPIPE %p is being reset, continuous reader %p FxRequest %p"
175 " PIRP %p is deferred for later.",
176 m_Pipe->GetHandle(), Repeater, Repeater->Request,
177 Repeater->RequestIrp);
178 }
179 else if (NT_SUCCESS(status)) {
180 //
181 // Get ready to re-submit the repeater.
182 //
184 Repeater->Request,
185 NULL,
187 );
188
189 if (action & SubmitSend) {
190 //
191 // Clear the event only if we are going to send the request
192 //
193 Repeater->ReadCompletedEvent.Clear();
194 }
195 else if (action & SubmitQueued) {
196 //
197 // Request got canceled asynchronously. The other thread is now
198 // responsible for calling its completion callback.
199 //
201 }
202 else {
203 //
204 // Submit failed (which is expected when we are changing the target
205 // state or when the request is canceled). It should always be an
206 // error.
207 //
208 status = Repeater->Request->GetFxIrp()->GetStatus();
210 }
211 }
212 else {
213 //
214 // Could not allocate a new buffer
215 //
216 Repeater->Request->GetFxIrp()->SetStatus(status);
217
220 "WDFUSBPIPE %p continuous reader, format failed, %!STATUS!, "
221 "repeater %p", m_Pipe->GetHandle(), status, Repeater);
222
226
228 //
229 // Queue a work item to clear problem.
230 //
231 QueueWorkItemLocked(Repeater);
232 }
233 else {
236 "WDFUSBPIPE %p continuous reader, buffer alloc failed, but "
237 "there are %d readers left out of a max of %d",
240
241 //
242 // There are still other pending readers, just use those for
243 // now.
244 //
245 DO_NOTHING();
246 }
247 }
248 else {
251 "WDFUSBPIPE %p continuous reader, buffer alloc failed, but not "
252 "in started state", m_Pipe->GetHandle());
253 }
254 }
255
257
258 *Status = status;
259
260 return action;
261}
262
263VOID
265 __in WDFREQUEST Request,
266 __in WDFIOTARGET Target,
269 )
270{
271 FxUsbPipeRepeatReader* pRepeater;
273 FxUsbPipe* pPipe;
276 BOOLEAN readCompletedEventSet;
277
280
281 readCompletedEventSet = FALSE;
282 action = 0;
283 pRepeater = (FxUsbPipeRepeatReader*) Context;
284 pThis = (FxUsbPipeContinuousReader*) pRepeater->Parent;
285 pPipe = pThis->m_Pipe;
286
287 status = pRepeater->Request->GetFxIrp()->GetStatus();
288
289 if (NT_SUCCESS(status)) {
291
292 params = pRepeater->Request->GetContext()->
293 m_CompletionParams.Parameters.Usb.Completion;
294
295 pThis->m_ReadCompleteCallback((WDFUSBPIPE) Target,
296 params->Parameters.PipeRead.Buffer,
297 params->Parameters.PipeRead.Length,
298 pThis->m_ReadCompleteContext);
299
300 //
301 // This will release the reference on the read memory and allocate a new
302 // one
303 //
304 action = pThis->ResubmitRepeater(pRepeater, &status);
305 }
306 else if (status != STATUS_CANCELLED) {
307 KIRQL irql;
308
311 "WDFUSBPIPE %p continuous reader FxRequest %p PIRP %p returned with "
312 "%!STATUS!", pPipe->GetHandle(), pRepeater->Request ,
313 pRepeater->RequestIrp, status);
314
315
316 pPipe->Lock(&irql);
317
318 pRepeater->ReadCompletedEvent.Set();
319 readCompletedEventSet = TRUE;
320
321 //
322 // Queue a work item to clear problem.
323 //
324 pThis->QueueWorkItemLocked(pRepeater);
325
326 pPipe->Unlock(irql);
327
329 }
330 else {
331 //
332 // I/O was cancelled, which means internally it was cancelled so don't
333 // do anything.
334 //
337 "WDFUSBPIPE %p continuous reader %p FxRequest %p PIRP %p canceled",
338 pPipe->GetHandle(), pRepeater, pRepeater->Request , pRepeater->RequestIrp);
339
340 DO_NOTHING();
341 }
342
343 if (action & SubmitSend) {
344
345 //
346 // We don't want to recurse on the same stack and overflow it.
347 // This is especially true if the device is pushing a lot of data and
348 // usb is completing everything within its dpc as soon as we send the
349 // read down. Eventually on a chk build, we will be nailed for running
350 // in one DPC for too long.
351 //
352 // As a slower alternative, we could queue a work item and resubmit the
353 // read from there.
354 //
355
356#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
358 result = KeInsertQueueDpc(&pRepeater->Dpc, NULL, NULL);
359
360 //
361 // The DPC should never be currently queued when we try to queue it.
362 //
363 ASSERT(result != FALSE);
364#else
365 pRepeater->m_ReadWorkItem.Enqueue((PMX_WORKITEM_ROUTINE)_ReadWorkItem, pRepeater);
366#endif
367 UNREFERENCED_PARAMETER(status); //for fre build
368
369 }
370 else if (action & SubmitQueued) {
371 //
372 // I/O got canceled asynchronously; the other thread is now
373 // responsible for re-invoking this completion routine.
374 //
376
379 "WDFUSBPIPE %p continuous reader %p FxRequest %p PIRP %p got"
380 " asynchronously canceled",
381 pPipe->GetHandle(), pRepeater, pRepeater->Request ,
382 pRepeater->RequestIrp);
383
384 DO_NOTHING();
385 }
386 else if (FALSE == readCompletedEventSet) {
388 //
389 // We are not sending the request and it is not queued so signal that
390 // it is done.
391 //
392 pRepeater->ReadCompletedEvent.Set();
393 }
394}
395
396VOID
398 __in FxUsbPipeRepeatReader* FailedRepeater
399 )
400{
402 NTSTATUS status, failedStatus;
403 USBD_STATUS usbdStatus;
404 LONG i;
405 KIRQL irql;
408 PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;
410
412
413 //
414 // Get failed info.
415 //
416 failedStatus = FailedRepeater->Request->GetStatus();
417
418 //
419 // Context is allocated at config time and gets reused so context
420 // will never be NULL.
421 //
422 context = FailedRepeater->Request->GetContext();
423 usbCompletionParams = context->m_CompletionParams.Parameters.Usb.Completion;
424
425 //
426 // In case FormatRepeater fails to allocate memory usbCompletionParams
427 // pointer is not set.
428 //
429 // usbCompletionParams are part of the context and
430 // not really allocated at the time of every Format but
431 // the pointer gets cleared by request->Reuse and gets set again by
432 // context->SetUsbType.
433 //
434 // In FormatRepeater, context->SetUsbType is skipped
435 // if a memory failure occurs before this step.
436 //
437 // Hence retrieve usbdStatus only when usbCompletionParams is set.
438 //
439 if (usbCompletionParams) {
440 usbdStatus = usbCompletionParams->UsbdStatus;
441 }
442 else {
443 //
444 // Set usbdStatus to success as we didn't receive a failure from
445 // USB stack.
446 //
447 // This path is reached during memory allocation failure. In such
448 // case failedStatus would already be set appropriately. (usbdStatus
449 // and failedStatus are passed to m_ReadersFailedCallback below.)
450 //
451 usbdStatus = STATUS_SUCCESS;
452 }
453
454 //
455 // No read requests should be in progress when the framework calls the
456 // EvtUsbTargetPipeReadersFailed callback function. This is part of the
457 // contract so that the Driver doesn't need to bother with the
458 // Completion calllback while taking corrective action.
459 //
462
464 //
465 // Save the current thread object pointer. This value is
466 // used for not deadlocking when misbehaved drivers (< v1.9) call
467 // WdfIoTargetStop from EvtUsbTargetPipeReadersFailed callback
468 //
471
473 (WDFUSBPIPE) m_Pipe->GetHandle(),
474 failedStatus,
475 usbdStatus
476 );
477
479 }
480 else {
481 //
482 // By default, we restart the readers
483 //
484 restart = TRUE;
485 }
486
487 if (restart) {
488 status = pDevice->IsConnected();
489
490 if (NT_SUCCESS(status)) {
491
492 //
493 // for v1.9 or higher use the error recovery procedure prescribed
494 // by the USB team.
495 //
497
498 if (pDevice->IsEnabled()) {
499 //
500 // Reset the pipe if port status is enabled
501 //
502 m_Pipe->Reset();
503 }
504 else {
505 //
506 // Reset the device if port status is disabled
507 //
508 status = pDevice->Reset();
509 }
510 }
511 else {
512 //
513 // Reset the device if port status is disabled
514 //
515 status = pDevice->Reset();
516 }
517 }
518 else {
519 //
520 // if port status is disconnected we would get back
521 // a !NT_SUCCESS. This would mean that we would not
522 // send the readers again and treat it like a failed reader.
523 //
524 DO_NOTHING();
525 }
526
527 }
528 else {
529 //
530 // By setting status to !NT_SUCCESS, we will not send the readers
531 // again and treat it like a failed reader.
532 //
534 }
535
536 //
537 // Work item is no longer queued. We set this before resubmitting the
538 // repeaters so that if they all complete and fail, we will requeue the
539 // work item.
540 //
541 m_Pipe->Lock(&irql);
544
545 if (NT_SUCCESS(status)) {
547
548 //
549 // Reset the count to zero. This is safe since we stopped all the
550 // readers at the beginning of this function.
551 //
553
554 //
555 // restart the readers
556 //
557 for (i = 0; i < m_NumReaders; i++) {
558 FxUsbPipeRepeatReader* pRepeater;
559
560 pRepeater = &m_Readers[i];
561
562 action = ResubmitRepeater(pRepeater, &status);
563
564 if (action & SubmitSend) {
565 //
566 // Ignore the return value because once we have sent the
567 // request, we want all processing to be done in the
568 // completion routine.
569 //
571 }
572 }
573 }
574}
575
576VOID
579 )
580/*
581 Only one work-item can be in-progress at any given time and
582 only one additional work-item can be queued at any given time.
583 This logic and m_WorkItemQueued makes this happen.
584*/
585{
586 FxUsbPipeRepeatReader* pFailedRepeater;
588 FxUsbPipe* pPipe;
589 KIRQL irql;
590 BOOLEAN rerun, inprogress;
591
592 pFailedRepeater = (FxUsbPipeRepeatReader*) Context;
593 pThis = (FxUsbPipeContinuousReader*) pFailedRepeater->Parent;
594 pPipe = pThis->m_Pipe;
595
596 //
597 // Check if a work item is already in progress.
598 //
599 pPipe->Lock(&irql);
601 //
602 // Yes, just let the other thread re-run this logic.
603 //
604 inprogress = TRUE;
605
608
611 }
612 else {
613 //
614 // No, it not running.
615 //
616 inprogress = FALSE;
617
620 }
621 pPipe->Unlock(irql);
622
623 if (inprogress) {
624 return;
625 }
626
627 //
628 // OK, this thread is responsible for running the work item logic.
629 //
630 do {
631 //
632 // Cleanup and restart the repeters.
633 //
634 pThis->FxUsbPipeRequestWorkItemHandler(pFailedRepeater);
635
636 //
637 // Check if callback needs to be re-run.
638 //
639 pPipe->Lock(&irql);
641 //
642 // Yes, a new work item was requested while it was already running.
643 //
644 rerun = TRUE;
645
646 pThis->m_WorkItemFlags &= ~FX_USB_WORKITEM_RERUN;
647
649 pFailedRepeater = (FxUsbPipeRepeatReader*)pThis->m_WorkItemRerunContext;
651
652 ASSERT(pThis == (FxUsbPipeContinuousReader*)pFailedRepeater->Parent);
653 }
654 else {
655 //
656 // No, all done.
657 //
658 rerun = FALSE;
659
661 pThis->m_WorkItemFlags &= ~FX_USB_WORKITEM_IN_PROGRESS;
662
664 }
665 pPipe->Unlock(irql);
666
667 }
668 while (rerun);
669}
670
671PVOID
672FxUsbPipeContinuousReader::operator new(
673 __in size_t Size,
674 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
675 __range(1, NUM_PENDING_READS_MAX) ULONG NumReaders
676 )
677{
678 ASSERT(NumReaders >= 1);
679
680 return FxPoolAllocate(
681 FxDriverGlobals,
683 Size + (NumReaders-1) * sizeof(FxUsbPipeRepeatReader)
684 );
685}
686
691 )
692{
695 FxUsbPipeTransferContext* pContext;
699
700 pRequest = Repeater->Request;
701 //
702 // The repeater owns the request memory. If there is a memory on the
703 // context, delete it now. the memory will still be referencable since
704 // it will still have a reference against it until FormatTransferRequest is
705 // called or the request is freed and the context releases its references
706 //
708
710
712
713 //
714 // pMemory will be deleted when either
715 // a) The request completes
716 // or
717 // b) The continuous reader is destroyed and we delete the lookaside. since
718 // the lookaside is the parent object for pMemory, pMemory will be disposed
719 // of when the parent is Disposed
720 //
722 if (!NT_SUCCESS(status)) {
723 FxRequestContext* pContext;
724
725 pContext = pRequest->GetContext();
726 if (pContext != NULL ) {
727 pContext->m_RequestMemory = NULL;
728 }
729
731 }
732
734
735 buf.SetMemory(pMemory, &m_Offsets);
736
738 pRequest,
739 &buf,
741 );
742
743 if (!NT_SUCCESS(status)) {
744 //
745 // In the case of failure, the context in the request will delete the
746 // memory. If there is no context, delete the memory here.
747 //
748 if (pRequest->GetContext() == NULL) {
749 //
750 // Use DeleteFromFailedCreate because the driver never saw the
751 // buffer, so they shouldn't be told about it going away.
752 //
754 }
755
756 return status;
757 }
758
761 pContext->m_UsbParameters.Parameters.PipeRead.Buffer = (WDFMEMORY)
763
765 return status;
766}
767
768
769VOID
771 VOID
772 )
773{
774 LONG i;
775
776 Mx::MxEnterCriticalRegion();
777
778 for (i = 0; i < m_NumReaders; i++) {
781 m_Readers[i].ReadCompletedEvent.GetSelfPointer(),
782 "waiting for continuous reader to finish, WDFUSBPIPE",
783 m_Pipe->GetHandle(),
786
787 }
788
789 Mx::MxLeaveCriticalRegion();
790 //
791 // Checking for IO Count <= 1 is not a good idea here because there could be always other IO
792 // besides that from the continous reader going on the Read Pipe.
793 //
794}
795
797 __in FX_URB_TYPE FxUrbType
798 ) :
800{
804
805 if (FxUrbType == FxUrbTypeLegacy) {
807 }
808 else {
809 m_Urb = NULL;
810 }
811
812}
813
815 VOID
816 )
817{
818 if (m_Urb && (m_Urb != &m_UrbLegacy)) {
820 }
821 m_Urb = NULL;
823}
824
828 __in USBD_HANDLE USBDHandle
829 )
830{
832
833 if (m_Urb) {
835 goto Done;
836 }
837
839
840 if (!NT_SUCCESS(status)) {
841 goto Done;
842 }
843
845
846Done:
847 return status;
848}
849
850VOID
852 VOID
853 )
854{
855 if (m_Urb && (m_Urb != &m_UrbLegacy)){
857 m_Urb = NULL;
859 }
860}
861
862VOID
865 )
866{
867#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
868 //
869 // Check now because Init will NULL out the field
870 //
871 if (m_PartialMdl != NULL) {
872 if (m_UnlockPages) {
875 }
876
877 FxMdlFree(Request->GetDriverGlobals(), m_PartialMdl);
879 }
880#endif
882}
883
884VOID
887 )
888{
890
891 //
892 // If both are at the same offset, we don't have to compare type for
893 // Read or Write
894 //
896 Parameters.PipeRead.Length) ==
898 Parameters.PipeWrite.Length));
899
902}
903
904VOID
906 __in USBD_PIPE_HANDLE PipeHandle,
907 __in ULONG TransferFlags
908 )
909{
910 m_Urb->TransferFlags = TransferFlags;
911 m_Urb->PipeHandle = PipeHandle;
912}
913
916 VOID
917 )
918{
919 return m_Urb->Hdr.Status;
920}
921
923 VOID
924 ) :
926 m_pUrb(NULL)
927{
928}
929
932 VOID
933 )
934{
935 return m_pUrb == NULL ? 0 : m_pUrb->UrbHeader.Status;
936}
937
938VOID
941 )
942{
943 ULONG dummy;
944
946
947 //
948 // make sure it is framework managed memory or raw PVOID
949 //
950 ASSERT(Buffer->DataType == FxRequestBufferMemory ||
951 Buffer->DataType == FxRequestBufferBuffer);
952
953 Buffer->AssignValues((PVOID*) &m_pUrb, NULL, &dummy);
954}
955
956VOID
959 )
960{
961 m_pUrb = NULL;
963}
964
965
967 __in FX_URB_TYPE FxUrbType
968 ) :
970{
972
973 if (FxUrbType == FxUrbTypeLegacy) {
975 }
976 else {
977 m_Urb = NULL;
978 }
979}
980
982 VOID
983 )
984{
985 if (m_Urb && (m_Urb != &m_UrbLegacy)) {
987 }
988 m_Urb = NULL;
990}
991
995 __in USBD_HANDLE USBDHandle
996 )
997{
999
1000 if (m_Urb) {
1002 goto Done;
1003 }
1004
1006
1007 if (!NT_SUCCESS(status)) {
1008 goto Done;
1009 }
1010
1012
1013Done:
1014 return status;
1015}
1016
1017VOID
1019 VOID
1020 )
1021{
1022 if (m_Urb && (m_Urb != &m_UrbLegacy)){
1024 m_Urb = NULL;
1026 }
1027}
1028
1029VOID
1032 __in USBD_PIPE_HANDLE PipeHandle,
1034 )
1035{
1036 RtlZeroMemory(m_Urb, sizeof(*m_Urb));
1037 m_Urb->Hdr.Length = sizeof(*m_Urb);
1038 m_Urb->Hdr.Function = Function;
1039 m_Urb->PipeHandle = PipeHandle;
1040
1042}
1043
1046 VOID
1047 )
1048{
1049 return m_Urb->Hdr.Status;
1050}
1051
1053 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1055 ) :
1057 m_UsbDevice(UsbDevice)
1058{
1061#if (FX_CORE_MODE == FX_CORE_USER_MODE)
1063#endif
1065 m_Reader = NULL;
1068 m_USBDHandle = UsbDevice->m_USBDHandle;
1069 m_UrbType = UsbDevice->m_UrbType;
1070
1072}
1073
1074VOID
1079 )
1080{
1083
1084 if (m_UsbInterface != NULL) {
1085 m_UsbInterface->RELEASE(this);
1087 }
1088
1090 m_UsbInterface->ADDREF(this);
1091}
1092
1094{
1095 if (m_UsbInterface != NULL) {
1097 m_UsbInterface->RELEASE(this);
1098 }
1099
1101}
1102
1103BOOLEAN
1105{
1106 BOOLEAN callCleanup;
1107
1108 //
1109 // Call base class: callbacks, terminates I/Os, etc.
1110 //
1111 callCleanup = FxIoTarget::Dispose(); // __super call
1112
1113 //
1114 // Don't need the reader anymore. The reader is deleted after calling the
1115 // parent class Dispose() to preserve the existing deletion order (it was
1116 // deleted in the Pipe's dtor() before this change).
1117 //
1118 if (m_Reader != NULL)
1119 {
1120 delete m_Reader;
1121
1122 //
1123 // By doing this assignment we prevent misbehaved drivers
1124 // from crashing the system when they call WdfIoTargetStop from their
1125 // usb pipe's destroy callback.
1126 //
1127 m_Reader = NULL;
1128 }
1129
1130 return callCleanup;
1131}
1132
1136 __in PLIST_ENTRY RequestListHead,
1138 )
1139{
1141 LONG i;
1142
1143 if (m_Reader != NULL) {
1146
1147 for (i = 0; i < m_Reader->m_NumReaders; i++) {
1149
1151
1152 UNREFERENCED_PARAMETER(pRequest); //for fre build
1155 }
1156 }
1157 }
1158
1159 status = FxIoTarget::GotoStartState(RequestListHead, Lock);
1160
1161 if (m_Reader == NULL || !NT_SUCCESS(status)) {
1162 return status;
1163 }
1164
1165 //
1166 // Add the repeater requests to the list head so that they are sent by the
1167 // caller of this function when this function returns IFF they have not yet
1168 // been queued. (They can be queued on a start -> start transition.)
1169 //
1171 for (i = 0; i < m_Reader->m_NumReaders; i++) {
1172 //
1173 // This will clear ReadCompletedEvent as well
1174 //
1176
1177 if (!NT_SUCCESS(status)) {
1178 return status;
1179 }
1180 }
1181
1182 //
1183 // Reset the number of failed readers in case we had failure in a
1184 // previously started state.
1185 //
1187
1188 for (i = 0; i < m_Reader->m_NumReaders; i++) {
1190
1192 pRequest->SetTarget(this);
1193 pRequest->ADDREF(this);
1194
1195 //
1196 // NOTE: This is an elusive backdoor to send the Request down
1197 // since it is inserted directly into the IoTargets pended list.
1198 // The IoTarget is not started so we add the request to the
1199 // pended list so that it is processed when the IoTarget starts.
1200 //
1202 InsertTailList(RequestListHead, &pRequest->m_ListEntry);
1203
1204 //
1205 // Clear the event only when we know it will be submitted to the
1206 // target. It will be set when the request is submitted to the
1207 // target and the submit fails or if it is cancelled.
1208 //
1210 }
1211
1213 }
1214
1215 return status;
1216}
1217
1218VOID
1221 __in PSINGLE_LIST_ENTRY SentRequestListHead,
1223 __in BOOLEAN LockSelf
1224 )
1225{
1226 KIRQL irql;
1228
1231
1232 if (LockSelf) {
1233 Lock(&irql);
1234 }
1235
1236 if (m_Reader != NULL) {
1237 //
1238 // If we are a continuous reader, always cancel the sent io so that we
1239 // can resubmit it later on a restart.
1240 //
1243 "WDFUSBPIPE %p converting stop action %!WDF_IO_TARGET_SENT_IO_ACTION!"
1244 " to %!WDF_IO_TARGET_SENT_IO_ACTION!", GetHandle(), Action,
1246
1248 }
1249
1250 FxIoTarget::GotoStopState(Action, SentRequestListHead, Wait, FALSE); // __super call
1251
1252 if (m_Reader != NULL) {
1253 //
1254 // The continuous reader requests are no longer enqueued. Remember that
1255 // state, so when we restart, we resend them.
1256 //
1258
1259 //
1260 // Log a message when misbehaved drivers call WdfIoTargetStop
1261 // from EvtUsbTargetPipeReadersFailed callback.
1262 //
1266 "WDFUSBPIPE %p is stopped from EvtUsbTargetPipeReadersFailed"
1267 " callback", GetHandle());
1268
1271 }
1272 }
1273
1274 //
1275 // Do not deadlock when misbehaved drivers (< v1.9) call
1276 // WdfIoTargetStop from EvtUsbTargetPipeReadersFailed callback.
1277 //
1280 //
1281 // Make sure work item is done. It is possible for the upper class
1282 // to return wait = false if the list of sent requests is empty. We
1283 // still want to wait anyway for making sure work item is not about
1284 // to run or it is running.
1285 //
1286 *Wait = TRUE;
1287 }
1288 }
1289
1290 if (LockSelf) {
1291 Unlock(irql);
1292 }
1293}
1294
1295VOID
1298 __in PLIST_ENTRY PendedRequestListHead,
1299 __in PSINGLE_LIST_ENTRY SentRequestListHead,
1301 __in BOOLEAN LockSelf
1302 )
1303{
1304 KIRQL irql;
1306
1309
1310 if (LockSelf) {
1311 Lock(&irql);
1312 }
1313
1314 if (m_Reader != NULL) {
1315 //
1316 // If we are a continuous reader, always wait for the sent io, so that we
1317 // can resubmit it later on a restart.
1318 //
1321 "WDFUSBPIPE %p converting purge action %!WDF_IO_TARGET_PURGE_IO_ACTION!"
1322 " to %!WDF_IO_TARGET_PURGE_IO_ACTION!", GetHandle(), Action,
1324
1326 }
1327
1328 FxIoTarget::GotoPurgeState(Action, // __super call
1329 PendedRequestListHead,
1330 SentRequestListHead,
1331 Wait,
1332 FALSE);
1333
1334 if (m_Reader != NULL) {
1335 //
1336 // The continuous reader requests are no longer enqueued. Remember that
1337 // state, so when we restart, we resend them.
1338 //
1340
1341 //
1342 // Log a message when misbehaved drivers call WdfIoTargetPurge
1343 // from EvtUsbTargetPipeReadersFailed callback.
1344 //
1348 "WDFUSBPIPE %p is purged from EvtUsbTargetPipeReadersFailed"
1349 " callback", GetHandle());
1350
1352 }
1353
1354 //
1355 // Make sure work item is done. It is possible for the upper class
1356 // to return wait = false if the list of sent requests is empty. We
1357 // still want to wait anyway for making sure work item is not about
1358 // to run or it is running.
1359 //
1360 *Wait = TRUE;
1361 }
1362
1363 if (LockSelf) {
1364 Unlock(irql);
1365 }
1366}
1367
1368VOID
1370 __in WDF_IO_TARGET_STATE NewState,
1371 __in PLIST_ENTRY PendedRequestListHead,
1372 __in PSINGLE_LIST_ENTRY SentRequestListHead,
1373 __in BOOLEAN LockSelf,
1375 )
1376{
1377 KIRQL irql;
1378
1380
1381 if (LockSelf) {
1382 Lock(&irql);
1383 }
1384
1387 //
1388 // Driver forgot to stop the pipe on D0Exit.
1389 //
1392 "WDFUSBPIPE %p was not stopped in EvtDeviceD0Exit callback",
1393 GetHandle());
1394
1395 if (GetDriverGlobals()->IsVerificationEnabled(1,9,OkForDownLevel)) {
1397 }
1398 }
1399
1400 FxIoTarget::GotoRemoveState(NewState, // __super call
1401 PendedRequestListHead,
1402 SentRequestListHead,
1403 FALSE,
1404 Wait);
1405 if (m_Reader != NULL) {
1406 //
1407 // Make sure work item is done. It is possible for the upper class to
1408 // return wait = false if the list of sent requests is empty. We still
1409 // want to wait anyway for making sure work item is not about to run or
1410 // it is running.
1411 //
1412 *Wait = TRUE;
1413 }
1414
1415 if (LockSelf) {
1416 Unlock(irql);
1417 }
1418}
1419
1420VOID
1422 VOID
1423 )
1424{
1425 if (m_Reader != NULL) {
1428 "WDFUSBPIPE %p, waiting for continuous reader work item to complete",
1429 GetHandle());
1430
1431 //
1432 // First, wait for the work item to complete if it is running.
1433 //
1434 // NOTE: We don't wait for the DPC to complete because
1435 // they are flushed in FxUsbDevice::Dispose
1436 //
1438
1441 "WDFUSBPIPE %p, cancelling for continuous reader (max of %d)",
1443
1444 //
1445 // Now that the work item is not running, make sure all the readers are
1446 // truly canceled and *NOT* in the pended queue. In between the call to
1447 // GotoStopState and here, the work item could have run and retried to
1448 // send the I/O.
1449 //
1451 }
1452
1455 "WDFUSBPIPE %p, waiting for all i/o to complete", GetHandle());
1456
1457 //
1458 // Finally, let the parent class wait for all I/O to complete
1459 //
1460 FxIoTarget::WaitForSentIoToComplete(); // __super call
1461}
1462
1467 __in size_t TotalBufferLength
1468 )
1469{
1472 UCHAR numReaders;
1473
1474 pReader = NULL;
1475
1476 if (m_Reader != NULL) {
1478
1481 "Continuous reader already initialized on WDFUSBPIPE %p %!STATUS!",
1482 GetHandle(), status);
1483
1484 return status;
1485 }
1486
1487 numReaders = Config->NumPendingReads;
1488
1489 if (numReaders == 0) {
1490 numReaders = NUM_PENDING_READS_DEFAULT;
1491 }
1492 else if (numReaders > NUM_PENDING_READS_MAX) {
1493 numReaders = NUM_PENDING_READS_MAX;
1494 }
1495
1496 pReader = new(GetDriverGlobals(), numReaders)
1497 FxUsbPipeContinuousReader(this, numReaders);
1498
1499 if (pReader == NULL) {
1501 }
1502
1503 //
1504 // Allocate all of the structurs and objects required
1505 //
1506 status = pReader->Config(Config, TotalBufferLength);
1507
1508 if (!NT_SUCCESS(status)) {
1509 delete pReader;
1510 return status;
1511 }
1512
1513 pReader->m_ReadCompleteCallback = Config->EvtUsbTargetPipeReadComplete;
1514 pReader->m_ReadCompleteContext = Config->EvtUsbTargetPipeReadCompleteContext;
1515
1516 pReader->m_ReadersFailedCallback = Config->EvtUsbTargetPipeReadersFailed;
1517
1519 pReader,
1520 NULL) == NULL) {
1521 //
1522 // We set the field, do nothing.
1523 //
1524 DO_NOTHING();
1525 }
1526 else {
1527 //
1528 // Some other thread came in and set the field, free our allocation.
1529 //
1530 delete pReader;
1531 }
1532
1533 return STATUS_SUCCESS;
1534}
1535
1539 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1540 __in WDFUSBPIPE Pipe,
1541 __in WDFREQUEST Request,
1542 __in_opt WDFMEMORY TransferMemory,
1543 __in_opt PWDFMEMORY_OFFSET TransferOffsets,
1545 )
1546{
1552
1553 FxObjectHandleGetPtrAndGlobals(FxDriverGlobals,
1554 Pipe,
1556 (PVOID*) &pUsbPipe,
1557 &FxDriverGlobals);
1558
1559 FxObjectHandleGetPtr(FxDriverGlobals,
1560 Request,
1562 (PVOID*) &pRequest);
1563
1564 //
1565 // We allow zero length transfers (which are indicated by TransferMemory == NULL)
1566 //
1567 if (TransferMemory != NULL) {
1568 FxObjectHandleGetPtr(FxDriverGlobals,
1571 (PVOID*) &pMemory);
1572
1573 status = pMemory->ValidateMemoryOffsets(TransferOffsets);
1574 if (!NT_SUCCESS(status)) {
1575 goto Done;
1576 }
1577
1578 buf.SetMemory(pMemory, TransferOffsets);
1579 }
1580 else {
1581 pMemory = NULL;
1582 }
1583
1585
1586 if (NT_SUCCESS(status)) {
1587 FxUsbPipeTransferContext* pContext;
1588
1590
1591 //
1592 // By assuming the fields are at the same offset, we can use simpler
1593 // logic (w/out comparisons for type) to set them.
1594 //
1595 WDFCASSERT(
1598 );
1599
1600 WDFCASSERT(
1603 );
1604
1606 pContext->m_UsbParameters.Parameters.PipeWrite.Length = buf.GetBufferLength();
1607
1608 pContext->m_UsbParameters.Parameters.PipeWrite.Offset =
1609 (TransferOffsets != NULL) ? TransferOffsets->BufferOffset
1610 : 0;
1611 pContext->SetUsbType(
1614 );
1615 }
1616
1617Done:
1619 "WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p, %!STATUS!",
1621
1622 return status;
1623}
1624
1628 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1629 __in WDFUSBPIPE Pipe,
1630 __in_opt WDFREQUEST Request,
1635 )
1636{
1640
1641 FxObjectHandleGetPtrAndGlobals(FxDriverGlobals,
1642 Pipe,
1644 (PVOID*) &pUsbPipe,
1645 &FxDriverGlobals);
1646
1648
1649 FxSyncRequest request(FxDriverGlobals, &context, Request);
1650
1651 //
1652 // FxSyncRequest always succeesds for KM but can fail for UM.
1653 //
1654 status = request.Initialize();
1655 if (!NT_SUCCESS(status)) {
1657 "Failed to initialize FxSyncRequest");
1658 return status;
1659 }
1660
1661 if (BytesTransferred != NULL) {
1662 *BytesTransferred = 0;
1663 }
1664
1665 status = FxVerifierCheckIrqlLevel(FxDriverGlobals, PASSIVE_LEVEL);
1666 if (!NT_SUCCESS(status)) {
1667 return status;
1668 }
1669
1671 if (!NT_SUCCESS(status)) {
1672 return status;
1673 }
1674
1675 //
1676 // We allow zero length writes (which are indicated by MemoryDescriptor == NULL)
1677 //
1678 if (MemoryDescriptor != NULL) {
1679 status = buf.ValidateMemoryDescriptor(FxDriverGlobals, MemoryDescriptor);
1680 if (!NT_SUCCESS(status)) {
1681 return status;
1682 }
1683 }
1684
1686
1687 if (NT_SUCCESS(status)) {
1689 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
1690 "WDFUSBPIPE %p, WDFREQUEST %p being submitted",
1691 Pipe, request.m_TrueRequest->GetTraceObjectHandle());
1692
1693 status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions);
1694
1695 //
1696 // Even on error we want to set this value. USBD should be clearing
1697 // it if the transfer fails.
1698 //
1699 if (BytesTransferred != NULL) {
1700 *BytesTransferred = context.GetUrbTransferLength();
1701 }
1702 }
1703
1705 "WDFUSBPIPE %p, %!STATUS!", Pipe, status);
1706
1707 return status;
1708}
1709
1714 )
1715{
1716 FxUsbPipeRequestContext* pContext;
1718 FX_URB_TYPE urbType;
1719
1720 status = Request->ValidateTarget(this);
1721 if (!NT_SUCCESS(status)) {
1723 "Pipe %p, Request %p, setting target failed, "
1724 "status %!STATUS!", this, Request, status);
1725
1726 return status;
1727 }
1728
1729 if (Request->HasContextType(FX_RCT_USB_PIPE_REQUEST)) {
1730 pContext = (FxUsbPipeRequestContext*) Request->GetContext();
1731 }
1732 else {
1733
1735 pContext = new(GetDriverGlobals()) FxUsbPipeRequestContext(urbType);
1736 if (pContext == NULL) {
1738 }
1739
1740#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1741 if (urbType == FxUrbTypeUsbdAllocated) {
1742 status = pContext->AllocateUrb(m_USBDHandle);
1743 if (!NT_SUCCESS(status)) {
1744 delete pContext;
1745 return status;
1746 }
1747 //
1748 // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
1749 // important to release those resorces before the devnode is removed. Those
1750 // resoruces are removed at the time Request is disposed.
1751 //
1752 Request->EnableContextDisposeNotification();
1753 }
1754#endif
1755
1756 Request->SetContext(pContext);
1757 }
1758
1759#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1763
1764 if (pContext->m_Urb == &pContext->m_UrbLegacy) {
1765 urbType = FxUrbTypeLegacy;
1766 }
1767 else {
1768 urbType = FxUrbTypeUsbdAllocated;
1769 }
1770
1771 FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
1772#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
1775 m_PipeInformationUm.PipeId,
1778#endif
1779
1780 return STATUS_SUCCESS;
1781}
1782
1787 )
1788{
1789 FxUsbPipeRequestContext* pContext;
1791 FX_URB_TYPE urbType;
1792
1793 status = Request->ValidateTarget(this);
1794 if (!NT_SUCCESS(status)) {
1796 "Pipe %p, Request %p, setting target failed, "
1797 "status %!STATUS!", this, Request, status);
1798
1799 return status;
1800 }
1801
1802 if (Request->HasContextType(FX_RCT_USB_PIPE_REQUEST)) {
1803 pContext = (FxUsbPipeRequestContext*) Request->GetContext();
1804 }
1805 else {
1807 pContext = new(GetDriverGlobals()) FxUsbPipeRequestContext(urbType);
1808 if (pContext == NULL) {
1810 }
1811
1812#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1813 if (urbType == FxUrbTypeUsbdAllocated) {
1814 status = pContext->AllocateUrb(m_USBDHandle);
1815 if (!NT_SUCCESS(status)) {
1816 delete pContext;
1817 return status;
1818 }
1819 //
1820 // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
1821 // important to release those resorces before the devnode is removed. Those
1822 // resoruces are removed at the time Request is disposed.
1823 //
1824 Request->EnableContextDisposeNotification();
1825 }
1826#endif
1827
1828 Request->SetContext(pContext);
1829 }
1830
1831#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1832 //
1833 // URB_FUNCTION_RESET_PIPE and URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
1834 // are the same value
1835 //
1839
1840 if (pContext->m_Urb == &pContext->m_UrbLegacy) {
1841 urbType = FxUrbTypeLegacy;
1842 }
1843 else {
1844 urbType = FxUrbTypeUsbdAllocated;
1845 }
1846
1847 FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
1848#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
1851 m_PipeInformationUm.PipeId,
1854#endif
1855
1856 return STATUS_SUCCESS;
1857}
1858
1861 VOID
1862 )
1863{
1865
1866 FxSyncRequest request(GetDriverGlobals(), &context);
1868
1869 //
1870 // FxSyncRequest always succeesds for KM but can fail for UM.
1871 //
1872 status = request.Initialize();
1873 if (!NT_SUCCESS(status)) {
1875 "Failed to initialize FxSyncRequest");
1876 return status;
1877 }
1878
1879 status = FormatResetRequest(request.m_TrueRequest);
1880 if (NT_SUCCESS(status)) {
1881 if (m_Reader != NULL) {
1882 //
1883 // This assumes that no other I/O besides reader I/O is going on.
1884 //
1886 }
1887 else {
1888 CancelSentIo();
1889 }
1891 }
1892 return status;
1893}
1894
unsigned char BOOLEAN
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxiotarget.cpp:306
VOID CancelSentIo(VOID)
virtual VOID GotoStopState(__in WDF_IO_TARGET_SENT_IO_ACTION Action, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxiotarget.cpp:617
_Must_inspect_result_ NTSTATUS SubmitSync(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL, __out_opt PULONG Action=NULL)
ULONG SubmitLocked(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options, __in ULONG Flags)
LIST_ENTRY m_SentIoListHead
Definition: fxiotarget.hpp:868
_Must_inspect_result_ NTSTATUS SubmitSyncRequestIgnoreTargetState(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS RequestOptions)
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
virtual BOOLEAN Dispose(VOID)
Definition: fxiotarget.cpp:154
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
virtual VOID GotoPurgeState(__in WDF_IO_TARGET_PURGE_IO_ACTION Action, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxiotarget.cpp:790
__inline MdDeviceObject GetTargetDevice(VOID)
Definition: fxiotarget.hpp:272
virtual VOID GotoRemoveState(__in WDF_IO_TARGET_STATE NewState, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __in BOOLEAN Lock, __out PBOOLEAN Wait)
Definition: fxiotarget.cpp:964
__inline VOID IncrementIoCount(VOID)
Definition: fxiotarget.hpp:767
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
NTSTATUS CallDriver(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:36
virtual _Must_inspect_result_ NTSTATUS Allocate(__out FxMemoryObject **PPMemory)=0
virtual size_t GetBufferSize(VOID)
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
virtual VOID DeleteObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
SINGLE_LIST_ENTRY m_DrainSingleEntry
__inline FxIrp * GetSubmitFxIrp(VOID)
BOOLEAN Cancel(VOID)
LIST_ENTRY m_ListEntry
__inline FxRequestContext * GetContext(VOID)
__inline VOID SetCompletionRoutine(__in_opt PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine=NULL, __in_opt WDFCONTEXT CompletionContext=NULL)
VOID __inline SetTarget(__in FxIoTarget *Target)
FxIrp * GetFxIrp(VOID)
Definition: fxrequest.hpp:957
_Must_inspect_result_ NTSTATUS Reuse(__in PWDF_REQUEST_REUSE_PARAMS ReuseParams)
Definition: fxrequest.cpp:2136
__inline BOOLEAN Enqueue(__in PFN_WDF_SYSTEMWORKITEM CallbackFunc, __in PVOID Parameter)
IWudfFile * m_pHostTargetFile
FX_URB_TYPE GetFxUrbTypeForRequest(__in FxRequestBase *Request)
VOID RemoveDeletedPipe(__in FxUsbPipe *Pipe)
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
FxUsbDevice * m_UsbDevice
Definition: fxusbpipe.hpp:698
VOID GotoPurgeState(__in WDF_IO_TARGET_PURGE_IO_ACTION Action, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxusbpipe.cpp:1296
virtual VOID GotoStopState(__in WDF_IO_TARGET_SENT_IO_ACTION Action, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxusbpipe.cpp:1219
BOOLEAN m_CheckPacketSize
Definition: fxusbpipe.hpp:732
_Must_inspect_result_ NTSTATUS FormatTransferRequest(__in FxRequestBase *Request, __in FxRequestBuffer *Buffer, __in ULONG TransferFlags=0)
virtual VOID GotoRemoveState(__in WDF_IO_TARGET_STATE NewState, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __in BOOLEAN Lock, __out PBOOLEAN Wait)
Definition: fxusbpipe.cpp:1369
_Must_inspect_result_ NTSTATUS FormatResetRequest(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:1785
USBD_PIPE_INFORMATION m_PipeInformation
Definition: fxusbpipe.hpp:714
FxUsbPipeContinuousReader * m_Reader
Definition: fxusbpipe.hpp:709
_Must_inspect_result_ NTSTATUS FormatAbortRequest(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:1712
FX_URB_TYPE m_UrbType
Definition: fxusbpipe.hpp:743
VOID InitPipe(__in PUSBD_PIPE_INFORMATION PipeInfo, __in UCHAR InterfaceNumber, __in FxUsbInterface *UsbInterface)
Definition: fxusbpipe.cpp:1075
friend FxUsbPipeContinuousReader
Definition: fxusbpipe.hpp:413
UCHAR m_InterfaceNumber
Definition: fxusbpipe.hpp:726
FxUsbInterface * m_UsbInterface
Definition: fxusbpipe.hpp:700
WINUSB_PIPE_INFORMATION m_PipeInformationUm
Definition: fxusbpipe.hpp:720
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxusbpipe.cpp:1421
WDFUSBPIPE GetHandle(VOID)
Definition: fxusbpipe.hpp:504
static _Must_inspect_result_ NTSTATUS _SendTransfer(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFUSBPIPE Pipe, __in_opt WDFREQUEST Request, __in_opt PWDF_REQUEST_SEND_OPTIONS RequestOptions, __in_opt PWDF_MEMORY_DESCRIPTOR MemoryDescriptor, __out_opt PULONG BytesTransferred, __in ULONG Flags)
Definition: fxusbpipe.cpp:1627
virtual BOOLEAN Dispose(VOID)
Definition: fxusbpipe.cpp:1104
static _Must_inspect_result_ NTSTATUS _FormatTransfer(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in WDFUSBPIPE Pipe, __in WDFREQUEST Request, __in_opt WDFMEMORY TransferMemory, __in_opt PWDFMEMORY_OFFSET TransferOffsets, __in ULONG Flags)
Definition: fxusbpipe.cpp:1538
NTSTATUS Reset(VOID)
Definition: fxusbpipe.cpp:1860
FxUsbPipe(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxUsbDevice *UsbDevice)
Definition: fxusbpipe.cpp:1052
USBD_HANDLE m_USBDHandle
Definition: fxusbpipe.hpp:737
LIST_ENTRY m_ListEntry
Definition: fxusbpipe.hpp:687
_Must_inspect_result_ NTSTATUS InitContinuousReader(__in PWDF_USB_CONTINUOUS_READER_CONFIG Config, __in size_t TotalBufferLength)
Definition: fxusbpipe.cpp:1465
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxusbpipe.cpp:1135
_Must_inspect_result_ NTSTATUS ValidateMemoryOffsets(__in_opt PWDFMEMORY_OFFSET Offsets)
Definition: ifxmemory.hpp:105
virtual PVOID GetBuffer(VOID)=0
__inline VOID Clear()
Definition: mxeventkm.h:102
__inline VOID Set()
Definition: mxeventkm.h:91
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
#define TRACINGIO
Definition: dbgtrace.h:66
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
action
Definition: namespace.c:707
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE,(PVOID *)&pDevice, &pFxDriverGlobals)
PFX_DRIVER_GLOBALS pFxDriverGlobals
PFX_DRIVER_GLOBALS fxDriverGlobals
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxRequest * pRequest
@ OkForDownLevel
Definition: fxglobals.h:80
@ WaitSignalBreakUnderVerifier
Definition: fxglobals.h:84
@ SubmitSend
Definition: fxiotarget.hpp:202
@ SubmitQueued
Definition: fxiotarget.hpp:203
FxMemoryObject * pMemory
VOID __inline FxMdlFree(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PMDL Mdl)
Definition: fxmdl.h:60
@ ObjectDoNotLock
Definition: fxobject.hpp:128
#define WDF_REQUEST_SEND_INTERNAL_OPTION_FAIL_ON_PEND
@ FxRequestBufferMemory
@ FxRequestBufferBuffer
@ FX_RCT_USB_PIPE_REQUEST
@ FX_RCT_USB_URB_REQUEST
@ FX_RCT_USB_PIPE_XFER
NTSTATUS __inline FxValidateRequestOptions(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ PWDF_REQUEST_SEND_OPTIONS Options, _In_opt_ FxRequestBase *Request=NULL)
@ FX_TYPE_IO_TARGET_USB_PIPE
Definition: fxtypes.h:103
@ IFX_TYPE_MEMORY
Definition: fxtypes.h:55
@ FX_TYPE_REQUEST
Definition: fxtypes.h:53
@ FxUrbTypeLegacy
Definition: fxusbdevice.hpp:27
@ FxUrbTypeUsbdAllocated
Definition: fxusbdevice.hpp:28
enum _FX_URB_TYPE FX_URB_TYPE
#define NUM_PENDING_READS_MAX
Definition: fxusbpipe.hpp:222
#define FX_USB_WORKITEM_IN_PROGRESS
Definition: fxusbpipe.hpp:227
#define FX_USB_WORKITEM_RERUN
Definition: fxusbpipe.hpp:228
#define NUM_PENDING_READS_DEFAULT
Definition: fxusbpipe.hpp:221
FxUsbPipe * pUsbPipe
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
Status
Definition: gdiplustypes.h:25
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
#define ASSERT(a)
Definition: mode.c:44
#define DO_NOTHING()
Definition: mxgeneral.h:32
IO_WORKITEM_ROUTINE * PMX_WORKITEM_ROUTINE
Definition: mxworkitemkm.h:26
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define __checkReturn
Definition: sal_old.h:113
#define STATUS_SUCCESS
Definition: shellext.h:65
#define __range(lb, ub)
Definition: specstrings.h:331
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
WDF_REQUEST_COMPLETION_PARAMS m_CompletionParams
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
IFxMemory * m_RequestMemory
static EVT_SYSTEMWORKITEM _FxUsbPipeRequestWorkItemThunk
Definition: fxusbpipe.hpp:319
PFN_WDF_USB_READERS_FAILED m_ReadersFailedCallback
Definition: fxusbpipe.hpp:335
BOOLEAN QueueWorkItemLocked(__in FxUsbPipeRepeatReader *Repeater)
Definition: fxusbpipe.cpp:91
ULONG ResubmitRepeater(__in FxUsbPipeRepeatReader *Repeater, __out NTSTATUS *Status)
Definition: fxusbpipe.cpp:137
FxUsbPipeRepeatReader m_Readers[1]
Definition: fxusbpipe.hpp:406
MdDeviceObject m_TargetDevice
Definition: fxusbpipe.hpp:350
FxLookasideList * m_Lookaside
Definition: fxusbpipe.hpp:345
volatile POINTER_ALIGNMENT MxThread m_WorkItemThread
Definition: fxusbpipe.hpp:372
static MX_WORKITEM_ROUTINE _ReadWorkItem
Definition: fxusbpipe.hpp:310
_Must_inspect_result_ NTSTATUS FormatRepeater(__in FxUsbPipeRepeatReader *Repeater)
Definition: fxusbpipe.cpp:689
VOID DeleteMemory(__in FxRequestBase *Request)
Definition: fxusbpipe.hpp:276
FxSystemWorkItem * m_WorkItem
Definition: fxusbpipe.hpp:360
PFN_WDF_USB_READER_COMPLETION_ROUTINE m_ReadCompleteCallback
Definition: fxusbpipe.hpp:325
WDFCONTEXT m_ReadCompleteContext
Definition: fxusbpipe.hpp:330
static EVT_WDF_REQUEST_COMPLETION_ROUTINE _FxUsbPipeRequestComplete
Definition: fxusbpipe.hpp:315
WDFMEMORY_OFFSET m_Offsets
Definition: fxusbpipe.hpp:355
_Must_inspect_result_ NTSTATUS Config(__in PWDF_USB_CONTINUOUS_READER_CONFIG Config, __in size_t TotalBufferLength)
Definition: fxusbpipekm.cpp:92
FxUsbPipeContinuousReader(__in FxUsbPipe *Pipe, __in UCHAR NumReaders)
Definition: fxusbpipe.cpp:32
__inline VOID FxUsbPipeRequestWorkItemHandler(__in FxUsbPipeRepeatReader *FailedRepeater)
Definition: fxusbpipe.cpp:397
FxUsbPipeContinuousReader * Parent
Definition: fxusbpipe.hpp:194
USBD_STATUS GetUsbdStatus(VOID)
Definition: fxusbpipe.cpp:1045
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:994
USBD_HANDLE m_USBDHandle
Definition: fxusbpipe.hpp:167
_URB_PIPE_REQUEST m_UrbLegacy
Definition: fxusbpipe.hpp:170
_URB_PIPE_REQUEST * m_Urb
Definition: fxusbpipe.hpp:175
VOID SetInfo(__in WDF_USB_REQUEST_TYPE Type, __in USBD_PIPE_HANDLE PipeHandle, __in USHORT Function)
Definition: fxusbpipe.cpp:1030
FxUsbPipeRequestContext(__in FX_URB_TYPE FxUrbType)
Definition: fxusbpipe.cpp:966
virtual VOID Dispose(VOID)
Definition: fxusbpipe.cpp:1018
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:863
virtual VOID CopyParameters(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:885
virtual VOID Dispose(VOID)
Definition: fxusbpipe.cpp:851
USBD_STATUS GetUsbdStatus(VOID)
Definition: fxusbpipe.cpp:915
_URB_BULK_OR_INTERRUPT_TRANSFER m_UrbLegacy
Definition: fxusbpipe.hpp:86
_URB_BULK_OR_INTERRUPT_TRANSFER * m_Urb
Definition: fxusbpipe.hpp:91
ULONG GetUrbTransferLength(VOID)
Definition: fxusbpipe.hpp:71
FxUsbPipeTransferContext(__in FX_URB_TYPE UrbType)
Definition: fxusbpipe.cpp:796
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:827
VOID SetUrbInfo(__in USBD_PIPE_HANDLE PipeHandle, __in ULONG TransferFlags)
Definition: fxusbpipe.cpp:905
USBD_HANDLE m_USBDHandle
Definition: fxusbpipe.hpp:83
VOID SetUsbType(__in WDF_USB_REQUEST_TYPE Type)
WDF_USB_REQUEST_COMPLETION_PARAMS m_UsbParameters
virtual VOID CopyParameters(__in FxRequestBase *Request)
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
Definition: fxusbpipe.cpp:939
FxUsbUrbContext(VOID)
Definition: fxusbpipe.cpp:922
USBD_STATUS GetUsbdStatus(VOID)
Definition: fxusbpipe.cpp:931
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:957
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
ULONG FxVerifierDbgWaitForSignalTimeoutInSec
Definition: fxglobals.h:527
_Must_inspect_result_ BOOLEAN IsVerificationEnabled(__in ULONG Major, __in ULONG Minor, __in FxVerifierDownlevelOption DownLevel)
Definition: fxglobals.h:286
VOID WaitForSignal(__in MxEvent *Event, __in PCSTR ReasonForWaiting, __in PVOID Handle, __in ULONG WarningTimeoutInSec, __in ULONG WaitSignalFlags)
Definition: globals.cpp:1703
Definition: typedefs.h:120
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641
struct _UMURB_PIPE_REQUEST UmUrbPipeRequest
Definition: umusb.h:186
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:499
struct _URB_HEADER Hdr
Definition: usb.h:498
struct _URB_HEADER Hdr
Definition: usb.h:315
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:316
Definition: usb.h:529
struct _URB_HEADER UrbHeader
Definition: usb.h:531
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:264
union _WDF_USB_REQUEST_COMPLETION_PARAMS::@4014 Parameters
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@4014::@4018 PipeWrite
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@4014::@4019 PipeRead
Definition: http.c:7252
Definition: reader.h:84
Definition: tftpd.h:86
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define UMURB_FUNCTION_ABORT_PIPE
Definition: umusb.h:10
#define UMURB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
Definition: umusb.h:38
#define URB_FUNCTION_ABORT_PIPE
Definition: usb.h:88
#define URB_FUNCTION_RESET_PIPE
Definition: usb.h:151
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:154
LONG USBD_STATUS
Definition: usb.h:165
NTSTATUS USBD_UrbAllocate(_In_ USBD_HANDLE USBDHandle, _Outptr_result_bytebuffer_(sizeof(URB)) PURB *Urb)
Definition: usbdex.c:59
VOID USBD_UrbFree(_In_ USBD_HANDLE USBDHandle, _In_ PURB Urb)
Definition: usbdex.c:83
_Must_inspect_result_ _In_ PDEVICE_OBJECT _In_ ULONG _In_ ULONG _Out_ USBD_HANDLE * USBDHandle
Definition: usbdlib.h:278
_In_ PVOID _In_ LONG InterfaceNumber
Definition: usbdlib.h:169
VOID FxFormatUsbRequest(__in FxRequestBase *Request, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __drv_when(FxUrbType==FxUrbTypeUsbdAllocated, __in) __drv_when(FxUrbType !=FxUrbTypeUsbdAllocated, __in_opt) USBD_HANDLE UsbdHandle)
Definition: usbutil.cpp:31
VOID FxUsbUmFormatRequest(__in FxRequestBase *Request, __in_xcount(Urb->Length) PUMURB_HEADER Urb, __in IWudfFile *HostFile, __in BOOLEAN Reuse)
Definition: usbutil.cpp:488
#define WDFCASSERT(c)
Definition: wdfassert.h:93
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
enum _WDF_IO_TARGET_PURGE_IO_ACTION WDF_IO_TARGET_PURGE_IO_ACTION
@ WdfIoTargetCancelSentIo
Definition: wdfiotarget.h:71
enum _WDF_IO_TARGET_SENT_IO_ACTION WDF_IO_TARGET_SENT_IO_ACTION
@ WdfIoTargetStarted
Definition: wdfiotarget.h:53
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
@ WdfIoTargetPurgeIoAndWait
Definition: wdfiotarget.h:78
WDF_EXTERN_C_START enum _WDF_IO_TARGET_STATE WDF_IO_TARGET_STATE
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS RequestOptions
Definition: wdfiotarget.h:867
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_opt_ PWDF_USB_PIPE_INFORMATION PipeInfo
Definition: wdfusb.h:2543
_In_ WDFUSBINTERFACE UsbInterface
Definition: wdfusb.h:2276
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFUSBDEVICE * UsbDevice
Definition: wdfusb.h:906
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR MemoryDescriptor
Definition: wdfusb.h:1339
@ WdfUsbRequestTypePipeReset
Definition: wdfusb.h:95
@ WdfUsbRequestTypePipeWrite
Definition: wdfusb.h:92
@ WdfUsbRequestTypePipeRead
Definition: wdfusb.h:93
@ WdfUsbRequestTypePipeAbort
Definition: wdfusb.h:94
enum _WDF_USB_REQUEST_TYPE WDF_USB_REQUEST_TYPE
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ WDFREQUEST _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ WDFMEMORY TransferMemory
Definition: wdfusb.h:1384
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR _Out_opt_ PULONG BytesTransferred
Definition: wdfusb.h:1342
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
unsigned char UCHAR
Definition: xmlstorage.h:181