ReactOS 0.4.15-dev-8227-g32d615f
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#include "FxUsbPipe.tmh"
8}
9
10#include "Fxglobals.h"
11//
12// NOTE: There are 3 different paths Requests could be sent to the lower driver
13// 1) In case of reposting a successfully completed Request use the Dpc which calls SendIo.
14// 2) For a failed completion use a workitem which works if the IoTarget is in Started state.
15// 3) On moving to the start state the Repeater requests are inserted into the
16// Iotargets Pended Queue directly.
17//
18// The function ResubmitRepeater calls SubmitLocked. If the action we get back
19// from SubmitLocked is "SubmitSend", (SubmitQueued is treated as failure because
20// of WDF_REQUEST_SEND_INTERNAL_OPTION_FAIL_ON_PEND flag) we are guaranteed to
21// call IoCallDriver in the workitem or the DPC and hence the completion routine
22// being called.
23// This is very important because we increment the m_IoCount in SubmitLocked and
24// decrement in the completion routine. So if there was a code path where
25// SubmitLocked was called and IoCallDriver(hence the completion routine) wasn't,
26// the IoTarget could stop responding in Dispose.
27//
28
29
32 __in UCHAR NumReaders
33 ) :
34 m_NumReaders(NumReaders),
35 m_NumFailedReaders(0)
36{
43
45 m_Pipe = Pipe;
46
48
50}
51
53{
54 LONG i;
55
57
58 //
59 // It is impoortant to delete the requests before the lookaside because the
60 // requests may have outstanding references on memory objects allocated by
61 // the lookaside. The lookaside will not be truly deleted until the oustanding
62 // memory object allocations are also freed.
63 //
64 for (i = 0; i < m_NumReaders; i++) {
65 if (reader[i].Request != NULL) {
67
68 reader[i].Request->DeleteObject();
69 reader[i].Request = NULL;
70 }
71
72#if (FX_CORE_MODE == FX_CORE_USER_MODE)
73 reader[i].ReadCompletedEvent.Uninitialize();
74 reader[i].m_ReadWorkItem.Free();
75#endif
76 }
77
78 if (m_Lookaside != NULL) {
80 }
81
82 if (m_WorkItem != NULL) {
85 }
86}
87
91 )
92{
93 BOOLEAN queued;
95
96 queued = FALSE;
98
100 //
101 // No item queued, queue it up now.
102 //
105 "WDFUSBPIPE %p continuous reader queueing work item to recover "
106 "from failed allocation", m_Pipe->GetHandle());
107
110 queued = TRUE;
111 }
112 else {
114 "Could not Queue workitem");
115 }
116 }
117
118 //
119 // We only want to queue the work item while the target is in the
120 // started state. If it is not started, then we are no longer sending
121 // i/o and we should not queue the work item to try to restart.
122 //
123 if (FALSE == queued) {
126 "WDFUSBPIPE %p continuous reader not queueing work item,"
127 "WorkItemQueued = %d, target state %!WDF_IO_TARGET_STATE!",
129 }
130
131 return queued;
132}
133
134ULONG
136 __in FxUsbPipeRepeatReader* Repeater,
138 )
139{
143 KIRQL irql;
144
145 action = 0;
148
149 //
150 // Reformat and allocate any new needed buffers
151 //
152 status = FormatRepeater(Repeater);
153
154 m_Pipe->Lock(&irql);
155
156 //
157 // Do not re-submit repeaters if there is a queued/running work-item to
158 // reset pipe. Work-item will restart this repeater later.
159 // This check needs to be done after the FormatRepeater() call above to
160 // prevent a race condition where we are not detecting when the repeater
161 // is cancelled.
162 //
163 if (m_WorkItemQueued) {
164 //
165 // Return an error and no action flags to let the caller know that
166 // this request was not sent.
167 //
169
172 "WDFUSBPIPE %p is being reset, continuous reader %p FxRequest %p"
173 " PIRP %p is deferred for later.",
174 m_Pipe->GetHandle(), Repeater, Repeater->Request,
175 Repeater->RequestIrp);
176 }
177 else if (NT_SUCCESS(status)) {
178 //
179 // Get ready to re-submit the repeater.
180 //
182 Repeater->Request,
183 NULL,
185 );
186
187 if (action & SubmitSend) {
188 //
189 // Clear the event only if we are going to send the request
190 //
191 Repeater->ReadCompletedEvent.Clear();
192 }
193 else if (action & SubmitQueued) {
194 //
195 // Request got canceled asynchronously. The other thread is now
196 // responsible for calling its completion callback.
197 //
199 }
200 else {
201 //
202 // Submit failed (which is expected when we are changing the target
203 // state or when the request is canceled). It should always be an
204 // error.
205 //
206 status = Repeater->Request->GetFxIrp()->GetStatus();
208 }
209 }
210 else {
211 //
212 // Could not allocate a new buffer
213 //
214 Repeater->Request->GetFxIrp()->SetStatus(status);
215
218 "WDFUSBPIPE %p continuous reader, format failed, %!STATUS!, "
219 "repeater %p", m_Pipe->GetHandle(), status, Repeater);
220
224
226 //
227 // Queue a work item to clear problem.
228 //
229 QueueWorkItemLocked(Repeater);
230 }
231 else {
234 "WDFUSBPIPE %p continuous reader, buffer alloc failed, but "
235 "there are %d readers left out of a max of %d",
238
239 //
240 // There are still other pending readers, just use those for
241 // now.
242 //
243 DO_NOTHING();
244 }
245 }
246 else {
249 "WDFUSBPIPE %p continuous reader, buffer alloc failed, but not "
250 "in started state", m_Pipe->GetHandle());
251 }
252 }
253
255
256 *Status = status;
257
258 return action;
259}
260
261VOID
263 __in WDFREQUEST Request,
264 __in WDFIOTARGET Target,
267 )
268{
269 FxUsbPipeRepeatReader* pRepeater;
271 FxUsbPipe* pPipe;
274 BOOLEAN readCompletedEventSet;
275
278
279 readCompletedEventSet = FALSE;
280 action = 0;
281 pRepeater = (FxUsbPipeRepeatReader*) Context;
282 pThis = (FxUsbPipeContinuousReader*) pRepeater->Parent;
283 pPipe = pThis->m_Pipe;
284
285 status = pRepeater->Request->GetFxIrp()->GetStatus();
286
287 if (NT_SUCCESS(status)) {
289
290 params = pRepeater->Request->GetContext()->
291 m_CompletionParams.Parameters.Usb.Completion;
292
293 pThis->m_ReadCompleteCallback((WDFUSBPIPE) Target,
294 params->Parameters.PipeRead.Buffer,
295 params->Parameters.PipeRead.Length,
296 pThis->m_ReadCompleteContext);
297
298 //
299 // This will release the reference on the read memory and allocate a new
300 // one
301 //
302 action = pThis->ResubmitRepeater(pRepeater, &status);
303 }
304 else if (status != STATUS_CANCELLED) {
305 KIRQL irql;
306
309 "WDFUSBPIPE %p continuous reader FxRequest %p PIRP %p returned with "
310 "%!STATUS!", pPipe->GetHandle(), pRepeater->Request ,
311 pRepeater->RequestIrp, status);
312
313
314 pPipe->Lock(&irql);
315
316 pRepeater->ReadCompletedEvent.Set();
317 readCompletedEventSet = TRUE;
318
319 //
320 // Queue a work item to clear problem.
321 //
322 pThis->QueueWorkItemLocked(pRepeater);
323
324 pPipe->Unlock(irql);
325
327 }
328 else {
329 //
330 // I/O was cancelled, which means internally it was cancelled so don't
331 // do anything.
332 //
335 "WDFUSBPIPE %p continuous reader %p FxRequest %p PIRP %p canceled",
336 pPipe->GetHandle(), pRepeater, pRepeater->Request , pRepeater->RequestIrp);
337
338 DO_NOTHING();
339 }
340
341 if (action & SubmitSend) {
342
343 //
344 // We don't want to recurse on the same stack and overflow it.
345 // This is especially true if the device is pushing a lot of data and
346 // usb is completing everything within its dpc as soon as we send the
347 // read down. Eventually on a chk build, we will be nailed for running
348 // in one DPC for too long.
349 //
350 // As a slower alternative, we could queue a work item and resubmit the
351 // read from there.
352 //
353
354#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
356 result = KeInsertQueueDpc(&pRepeater->Dpc, NULL, NULL);
357
358 //
359 // The DPC should never be currently queued when we try to queue it.
360 //
361 ASSERT(result != FALSE);
362#else
363 pRepeater->m_ReadWorkItem.Enqueue((PMX_WORKITEM_ROUTINE)_ReadWorkItem, pRepeater);
364#endif
365 UNREFERENCED_PARAMETER(status); //for fre build
366
367 }
368 else if (action & SubmitQueued) {
369 //
370 // I/O got canceled asynchronously; the other thread is now
371 // responsible for re-invoking this completion routine.
372 //
374
377 "WDFUSBPIPE %p continuous reader %p FxRequest %p PIRP %p got"
378 " asynchronously canceled",
379 pPipe->GetHandle(), pRepeater, pRepeater->Request ,
380 pRepeater->RequestIrp);
381
382 DO_NOTHING();
383 }
384 else if (FALSE == readCompletedEventSet) {
386 //
387 // We are not sending the request and it is not queued so signal that
388 // it is done.
389 //
390 pRepeater->ReadCompletedEvent.Set();
391 }
392}
393
394VOID
396 __in FxUsbPipeRepeatReader* FailedRepeater
397 )
398{
400 NTSTATUS status, failedStatus;
401 USBD_STATUS usbdStatus;
402 LONG i;
403 KIRQL irql;
406 PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;
408
410
411 //
412 // Get failed info.
413 //
414 failedStatus = FailedRepeater->Request->GetStatus();
415
416 //
417 // Context is allocated at config time and gets reused so context
418 // will never be NULL.
419 //
420 context = FailedRepeater->Request->GetContext();
421 usbCompletionParams = context->m_CompletionParams.Parameters.Usb.Completion;
422
423 //
424 // In case FormatRepeater fails to allocate memory usbCompletionParams
425 // pointer is not set.
426 //
427 // usbCompletionParams are part of the context and
428 // not really allocated at the time of every Format but
429 // the pointer gets cleared by request->Reuse and gets set again by
430 // context->SetUsbType.
431 //
432 // In FormatRepeater, context->SetUsbType is skipped
433 // if a memory failure occurs before this step.
434 //
435 // Hence retrieve usbdStatus only when usbCompletionParams is set.
436 //
437 if (usbCompletionParams) {
438 usbdStatus = usbCompletionParams->UsbdStatus;
439 }
440 else {
441 //
442 // Set usbdStatus to success as we didn't receive a failure from
443 // USB stack.
444 //
445 // This path is reached during memory allocation failure. In such
446 // case failedStatus would already be set appropriately. (usbdStatus
447 // and failedStatus are passed to m_ReadersFailedCallback below.)
448 //
449 usbdStatus = STATUS_SUCCESS;
450 }
451
452 //
453 // No read requests should be in progress when the framework calls the
454 // EvtUsbTargetPipeReadersFailed callback function. This is part of the
455 // contract so that the Driver doesn't need to bother with the
456 // Completion calllback while taking corrective action.
457 //
460
462 //
463 // Save the current thread object pointer. This value is
464 // used for not deadlocking when misbehaved drivers (< v1.9) call
465 // WdfIoTargetStop from EvtUsbTargetPipeReadersFailed callback
466 //
469
471 (WDFUSBPIPE) m_Pipe->GetHandle(),
472 failedStatus,
473 usbdStatus
474 );
475
477 }
478 else {
479 //
480 // By default, we restart the readers
481 //
482 restart = TRUE;
483 }
484
485 if (restart) {
486 status = pDevice->IsConnected();
487
488 if (NT_SUCCESS(status)) {
489
490 //
491 // for v1.9 or higher use the error recovery procedure prescribed
492 // by the USB team.
493 //
495
496 if (pDevice->IsEnabled()) {
497 //
498 // Reset the pipe if port status is enabled
499 //
500 m_Pipe->Reset();
501 }
502 else {
503 //
504 // Reset the device if port status is disabled
505 //
506 status = pDevice->Reset();
507 }
508 }
509 else {
510 //
511 // Reset the device if port status is disabled
512 //
513 status = pDevice->Reset();
514 }
515 }
516 else {
517 //
518 // if port status is disconnected we would get back
519 // a !NT_SUCCESS. This would mean that we would not
520 // send the readers again and treat it like a failed reader.
521 //
522 DO_NOTHING();
523 }
524
525 }
526 else {
527 //
528 // By setting status to !NT_SUCCESS, we will not send the readers
529 // again and treat it like a failed reader.
530 //
532 }
533
534 //
535 // Work item is no longer queued. We set this before resubmitting the
536 // repeaters so that if they all complete and fail, we will requeue the
537 // work item.
538 //
539 m_Pipe->Lock(&irql);
542
543 if (NT_SUCCESS(status)) {
545
546 //
547 // Reset the count to zero. This is safe since we stopped all the
548 // readers at the beginning of this function.
549 //
551
552 //
553 // restart the readers
554 //
555 for (i = 0; i < m_NumReaders; i++) {
556 FxUsbPipeRepeatReader* pRepeater;
557
558 pRepeater = &m_Readers[i];
559
560 action = ResubmitRepeater(pRepeater, &status);
561
562 if (action & SubmitSend) {
563 //
564 // Ignore the return value because once we have sent the
565 // request, we want all processing to be done in the
566 // completion routine.
567 //
569 }
570 }
571 }
572}
573
574VOID
577 )
578/*
579 Only one work-item can be in-progress at any given time and
580 only one additional work-item can be queued at any given time.
581 This logic and m_WorkItemQueued makes this happen.
582*/
583{
584 FxUsbPipeRepeatReader* pFailedRepeater;
586 FxUsbPipe* pPipe;
587 KIRQL irql;
588 BOOLEAN rerun, inprogress;
589
590 pFailedRepeater = (FxUsbPipeRepeatReader*) Context;
591 pThis = (FxUsbPipeContinuousReader*) pFailedRepeater->Parent;
592 pPipe = pThis->m_Pipe;
593
594 //
595 // Check if a work item is already in progress.
596 //
597 pPipe->Lock(&irql);
599 //
600 // Yes, just let the other thread re-run this logic.
601 //
602 inprogress = TRUE;
603
606
609 }
610 else {
611 //
612 // No, it not running.
613 //
614 inprogress = FALSE;
615
618 }
619 pPipe->Unlock(irql);
620
621 if (inprogress) {
622 return;
623 }
624
625 //
626 // OK, this thread is responsible for running the work item logic.
627 //
628 do {
629 //
630 // Cleanup and restart the repeters.
631 //
632 pThis->FxUsbPipeRequestWorkItemHandler(pFailedRepeater);
633
634 //
635 // Check if callback needs to be re-run.
636 //
637 pPipe->Lock(&irql);
639 //
640 // Yes, a new work item was requested while it was already running.
641 //
642 rerun = TRUE;
643
644 pThis->m_WorkItemFlags &= ~FX_USB_WORKITEM_RERUN;
645
647 pFailedRepeater = (FxUsbPipeRepeatReader*)pThis->m_WorkItemRerunContext;
649
650 ASSERT(pThis == (FxUsbPipeContinuousReader*)pFailedRepeater->Parent);
651 }
652 else {
653 //
654 // No, all done.
655 //
656 rerun = FALSE;
657
659 pThis->m_WorkItemFlags &= ~FX_USB_WORKITEM_IN_PROGRESS;
660
662 }
663 pPipe->Unlock(irql);
664
665 }
666 while (rerun);
667}
668
669PVOID
670FxUsbPipeContinuousReader::operator new(
671 __in size_t Size,
672 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
673 __range(1, NUM_PENDING_READS_MAX) ULONG NumReaders
674 )
675{
676 ASSERT(NumReaders >= 1);
677
678 return FxPoolAllocate(
679 FxDriverGlobals,
681 Size + (NumReaders-1) * sizeof(FxUsbPipeRepeatReader)
682 );
683}
684
689 )
690{
693 FxUsbPipeTransferContext* pContext;
697
698 pRequest = Repeater->Request;
699 //
700 // The repeater owns the request memory. If there is a memory on the
701 // context, delete it now. the memory will still be referencable since
702 // it will still have a reference against it until FormatTransferRequest is
703 // called or the request is freed and the context releases its references
704 //
706
708
710
711 //
712 // pMemory will be deleted when either
713 // a) The request completes
714 // or
715 // b) The continuous reader is destroyed and we delete the lookaside. since
716 // the lookaside is the parent object for pMemory, pMemory will be disposed
717 // of when the parent is Disposed
718 //
720 if (!NT_SUCCESS(status)) {
721 FxRequestContext* pContext;
722
723 pContext = pRequest->GetContext();
724 if (pContext != NULL ) {
725 pContext->m_RequestMemory = NULL;
726 }
727
729 }
730
732
733 buf.SetMemory(pMemory, &m_Offsets);
734
736 pRequest,
737 &buf,
739 );
740
741 if (!NT_SUCCESS(status)) {
742 //
743 // In the case of failure, the context in the request will delete the
744 // memory. If there is no context, delete the memory here.
745 //
746 if (pRequest->GetContext() == NULL) {
747 //
748 // Use DeleteFromFailedCreate because the driver never saw the
749 // buffer, so they shouldn't be told about it going away.
750 //
752 }
753
754 return status;
755 }
756
759 pContext->m_UsbParameters.Parameters.PipeRead.Buffer = (WDFMEMORY)
761
763 return status;
764}
765
766
767VOID
769 VOID
770 )
771{
772 LONG i;
773
774 Mx::MxEnterCriticalRegion();
775
776 for (i = 0; i < m_NumReaders; i++) {
779 m_Readers[i].ReadCompletedEvent.GetSelfPointer(),
780 "waiting for continuous reader to finish, WDFUSBPIPE",
781 m_Pipe->GetHandle(),
784
785 }
786
787 Mx::MxLeaveCriticalRegion();
788 //
789 // Checking for IO Count <= 1 is not a good idea here because there could be always other IO
790 // besides that from the continous reader going on the Read Pipe.
791 //
792}
793
795 __in FX_URB_TYPE FxUrbType
796 ) :
798{
802
803 if (FxUrbType == FxUrbTypeLegacy) {
805 }
806 else {
807 m_Urb = NULL;
808 }
809
810}
811
813 VOID
814 )
815{
816 if (m_Urb && (m_Urb != &m_UrbLegacy)) {
818 }
819 m_Urb = NULL;
821}
822
826 __in USBD_HANDLE USBDHandle
827 )
828{
830
831 if (m_Urb) {
833 goto Done;
834 }
835
836 status = USBD_UrbAllocate(USBDHandle, (PURB*)&m_Urb);
837
838 if (!NT_SUCCESS(status)) {
839 goto Done;
840 }
841
842 m_USBDHandle = USBDHandle;
843
844Done:
845 return status;
846}
847
848VOID
850 VOID
851 )
852{
853 if (m_Urb && (m_Urb != &m_UrbLegacy)){
855 m_Urb = NULL;
857 }
858}
859
860VOID
863 )
864{
865#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
866 //
867 // Check now because Init will NULL out the field
868 //
869 if (m_PartialMdl != NULL) {
870 if (m_UnlockPages) {
873 }
874
875 FxMdlFree(Request->GetDriverGlobals(), m_PartialMdl);
877 }
878#endif
880}
881
882VOID
885 )
886{
888
889 //
890 // If both are at the same offset, we don't have to compare type for
891 // Read or Write
892 //
894 Parameters.PipeRead.Length) ==
896 Parameters.PipeWrite.Length));
897
900}
901
902VOID
905 __in ULONG TransferFlags
906 )
907{
908 m_Urb->TransferFlags = TransferFlags;
910}
911
914 VOID
915 )
916{
917 return m_Urb->Hdr.Status;
918}
919
921 VOID
922 ) :
924 m_pUrb(NULL)
925{
926}
927
930 VOID
931 )
932{
933 return m_pUrb == NULL ? 0 : m_pUrb->UrbHeader.Status;
934}
935
936VOID
939 )
940{
941 ULONG dummy;
942
944
945 //
946 // make sure it is framework managed memory or raw PVOID
947 //
948 ASSERT(Buffer->DataType == FxRequestBufferMemory ||
949 Buffer->DataType == FxRequestBufferBuffer);
950
951 Buffer->AssignValues((PVOID*) &m_pUrb, NULL, &dummy);
952}
953
954VOID
957 )
958{
959 m_pUrb = NULL;
961}
962
963
965 __in FX_URB_TYPE FxUrbType
966 ) :
968{
970
971 if (FxUrbType == FxUrbTypeLegacy) {
973 }
974 else {
975 m_Urb = NULL;
976 }
977}
978
980 VOID
981 )
982{
983 if (m_Urb && (m_Urb != &m_UrbLegacy)) {
985 }
986 m_Urb = NULL;
988}
989
993 __in USBD_HANDLE USBDHandle
994 )
995{
997
998 if (m_Urb) {
1000 goto Done;
1001 }
1002
1003 status = USBD_UrbAllocate(USBDHandle, (PURB*)&m_Urb);
1004
1005 if (!NT_SUCCESS(status)) {
1006 goto Done;
1007 }
1008
1009 m_USBDHandle = USBDHandle;
1010
1011Done:
1012 return status;
1013}
1014
1015VOID
1017 VOID
1018 )
1019{
1020 if (m_Urb && (m_Urb != &m_UrbLegacy)){
1022 m_Urb = NULL;
1024 }
1025}
1026
1027VOID
1032 )
1033{
1034 RtlZeroMemory(m_Urb, sizeof(*m_Urb));
1035 m_Urb->Hdr.Length = sizeof(*m_Urb);
1036 m_Urb->Hdr.Function = Function;
1038
1040}
1041
1044 VOID
1045 )
1046{
1047 return m_Urb->Hdr.Status;
1048}
1049
1051 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1053 ) :
1055 m_UsbDevice(UsbDevice)
1056{
1059#if (FX_CORE_MODE == FX_CORE_USER_MODE)
1061#endif
1063 m_Reader = NULL;
1066 m_USBDHandle = UsbDevice->m_USBDHandle;
1067 m_UrbType = UsbDevice->m_UrbType;
1068
1070}
1071
1072VOID
1077 )
1078{
1081
1082 if (m_UsbInterface != NULL) {
1083 m_UsbInterface->RELEASE(this);
1085 }
1086
1088 m_UsbInterface->ADDREF(this);
1089}
1090
1092{
1093 if (m_UsbInterface != NULL) {
1095 m_UsbInterface->RELEASE(this);
1096 }
1097
1099}
1100
1101BOOLEAN
1103{
1104 BOOLEAN callCleanup;
1105
1106 //
1107 // Call base class: callbacks, terminates I/Os, etc.
1108 //
1109 callCleanup = FxIoTarget::Dispose(); // __super call
1110
1111 //
1112 // Don't need the reader anymore. The reader is deleted after calling the
1113 // parent class Dispose() to preserve the existing deletion order (it was
1114 // deleted in the Pipe's dtor() before this change).
1115 //
1116 if (m_Reader != NULL)
1117 {
1118 delete m_Reader;
1119
1120 //
1121 // By doing this assignment we prevent misbehaved drivers
1122 // from crashing the system when they call WdfIoTargetStop from their
1123 // usb pipe's destroy callback.
1124 //
1125 m_Reader = NULL;
1126 }
1127
1128 return callCleanup;
1129}
1130
1134 __in PLIST_ENTRY RequestListHead,
1136 )
1137{
1139 LONG i;
1140
1141 if (m_Reader != NULL) {
1144
1145 for (i = 0; i < m_Reader->m_NumReaders; i++) {
1147
1149
1150 UNREFERENCED_PARAMETER(pRequest); //for fre build
1153 }
1154 }
1155 }
1156
1157 status = FxIoTarget::GotoStartState(RequestListHead, Lock);
1158
1159 if (m_Reader == NULL || !NT_SUCCESS(status)) {
1160 return status;
1161 }
1162
1163 //
1164 // Add the repeater requests to the list head so that they are sent by the
1165 // caller of this function when this function returns IFF they have not yet
1166 // been queued. (They can be queued on a start -> start transition.)
1167 //
1169 for (i = 0; i < m_Reader->m_NumReaders; i++) {
1170 //
1171 // This will clear ReadCompletedEvent as well
1172 //
1174
1175 if (!NT_SUCCESS(status)) {
1176 return status;
1177 }
1178 }
1179
1180 //
1181 // Reset the number of failed readers in case we had failure in a
1182 // previously started state.
1183 //
1185
1186 for (i = 0; i < m_Reader->m_NumReaders; i++) {
1188
1190 pRequest->SetTarget(this);
1191 pRequest->ADDREF(this);
1192
1193 //
1194 // NOTE: This is an elusive backdoor to send the Request down
1195 // since it is inserted directly into the IoTargets pended list.
1196 // The IoTarget is not started so we add the request to the
1197 // pended list so that it is processed when the IoTarget starts.
1198 //
1200 InsertTailList(RequestListHead, &pRequest->m_ListEntry);
1201
1202 //
1203 // Clear the event only when we know it will be submitted to the
1204 // target. It will be set when the request is submitted to the
1205 // target and the submit fails or if it is cancelled.
1206 //
1208 }
1209
1211 }
1212
1213 return status;
1214}
1215
1216VOID
1219 __in PSINGLE_LIST_ENTRY SentRequestListHead,
1221 __in BOOLEAN LockSelf
1222 )
1223{
1224 KIRQL irql;
1226
1229
1230 if (LockSelf) {
1231 Lock(&irql);
1232 }
1233
1234 if (m_Reader != NULL) {
1235 //
1236 // If we are a continuous reader, always cancel the sent io so that we
1237 // can resubmit it later on a restart.
1238 //
1241 "WDFUSBPIPE %p converting stop action %!WDF_IO_TARGET_SENT_IO_ACTION!"
1242 " to %!WDF_IO_TARGET_SENT_IO_ACTION!", GetHandle(), Action,
1244
1246 }
1247
1248 FxIoTarget::GotoStopState(Action, SentRequestListHead, Wait, FALSE); // __super call
1249
1250 if (m_Reader != NULL) {
1251 //
1252 // The continuous reader requests are no longer enqueued. Remember that
1253 // state, so when we restart, we resend them.
1254 //
1256
1257 //
1258 // Log a message when misbehaved drivers call WdfIoTargetStop
1259 // from EvtUsbTargetPipeReadersFailed callback.
1260 //
1264 "WDFUSBPIPE %p is stopped from EvtUsbTargetPipeReadersFailed"
1265 " callback", GetHandle());
1266
1269 }
1270 }
1271
1272 //
1273 // Do not deadlock when misbehaved drivers (< v1.9) call
1274 // WdfIoTargetStop from EvtUsbTargetPipeReadersFailed callback.
1275 //
1278 //
1279 // Make sure work item is done. It is possible for the upper class
1280 // to return wait = false if the list of sent requests is empty. We
1281 // still want to wait anyway for making sure work item is not about
1282 // to run or it is running.
1283 //
1284 *Wait = TRUE;
1285 }
1286 }
1287
1288 if (LockSelf) {
1289 Unlock(irql);
1290 }
1291}
1292
1293VOID
1296 __in PLIST_ENTRY PendedRequestListHead,
1297 __in PSINGLE_LIST_ENTRY SentRequestListHead,
1299 __in BOOLEAN LockSelf
1300 )
1301{
1302 KIRQL irql;
1304
1307
1308 if (LockSelf) {
1309 Lock(&irql);
1310 }
1311
1312 if (m_Reader != NULL) {
1313 //
1314 // If we are a continuous reader, always wait for the sent io, so that we
1315 // can resubmit it later on a restart.
1316 //
1319 "WDFUSBPIPE %p converting purge action %!WDF_IO_TARGET_PURGE_IO_ACTION!"
1320 " to %!WDF_IO_TARGET_PURGE_IO_ACTION!", GetHandle(), Action,
1322
1324 }
1325
1326 FxIoTarget::GotoPurgeState(Action, // __super call
1327 PendedRequestListHead,
1328 SentRequestListHead,
1329 Wait,
1330 FALSE);
1331
1332 if (m_Reader != NULL) {
1333 //
1334 // The continuous reader requests are no longer enqueued. Remember that
1335 // state, so when we restart, we resend them.
1336 //
1338
1339 //
1340 // Log a message when misbehaved drivers call WdfIoTargetPurge
1341 // from EvtUsbTargetPipeReadersFailed callback.
1342 //
1346 "WDFUSBPIPE %p is purged from EvtUsbTargetPipeReadersFailed"
1347 " callback", GetHandle());
1348
1350 }
1351
1352 //
1353 // Make sure work item is done. It is possible for the upper class
1354 // to return wait = false if the list of sent requests is empty. We
1355 // still want to wait anyway for making sure work item is not about
1356 // to run or it is running.
1357 //
1358 *Wait = TRUE;
1359 }
1360
1361 if (LockSelf) {
1362 Unlock(irql);
1363 }
1364}
1365
1366VOID
1368 __in WDF_IO_TARGET_STATE NewState,
1369 __in PLIST_ENTRY PendedRequestListHead,
1370 __in PSINGLE_LIST_ENTRY SentRequestListHead,
1371 __in BOOLEAN LockSelf,
1373 )
1374{
1375 KIRQL irql;
1376
1378
1379 if (LockSelf) {
1380 Lock(&irql);
1381 }
1382
1385 //
1386 // Driver forgot to stop the pipe on D0Exit.
1387 //
1390 "WDFUSBPIPE %p was not stopped in EvtDeviceD0Exit callback",
1391 GetHandle());
1392
1393 if (GetDriverGlobals()->IsVerificationEnabled(1,9,OkForDownLevel)) {
1395 }
1396 }
1397
1398 FxIoTarget::GotoRemoveState(NewState, // __super call
1399 PendedRequestListHead,
1400 SentRequestListHead,
1401 FALSE,
1402 Wait);
1403 if (m_Reader != NULL) {
1404 //
1405 // Make sure work item is done. It is possible for the upper class to
1406 // return wait = false if the list of sent requests is empty. We still
1407 // want to wait anyway for making sure work item is not about to run or
1408 // it is running.
1409 //
1410 *Wait = TRUE;
1411 }
1412
1413 if (LockSelf) {
1414 Unlock(irql);
1415 }
1416}
1417
1418VOID
1420 VOID
1421 )
1422{
1423 if (m_Reader != NULL) {
1426 "WDFUSBPIPE %p, waiting for continuous reader work item to complete",
1427 GetHandle());
1428
1429 //
1430 // First, wait for the work item to complete if it is running.
1431 //
1432 // NOTE: We don't wait for the DPC to complete because
1433 // they are flushed in FxUsbDevice::Dispose
1434 //
1436
1439 "WDFUSBPIPE %p, cancelling for continuous reader (max of %d)",
1441
1442 //
1443 // Now that the work item is not running, make sure all the readers are
1444 // truly canceled and *NOT* in the pended queue. In between the call to
1445 // GotoStopState and here, the work item could have run and retried to
1446 // send the I/O.
1447 //
1449 }
1450
1453 "WDFUSBPIPE %p, waiting for all i/o to complete", GetHandle());
1454
1455 //
1456 // Finally, let the parent class wait for all I/O to complete
1457 //
1458 FxIoTarget::WaitForSentIoToComplete(); // __super call
1459}
1460
1465 __in size_t TotalBufferLength
1466 )
1467{
1470 UCHAR numReaders;
1471
1472 pReader = NULL;
1473
1474 if (m_Reader != NULL) {
1476
1479 "Continuous reader already initialized on WDFUSBPIPE %p %!STATUS!",
1480 GetHandle(), status);
1481
1482 return status;
1483 }
1484
1485 numReaders = Config->NumPendingReads;
1486
1487 if (numReaders == 0) {
1488 numReaders = NUM_PENDING_READS_DEFAULT;
1489 }
1490 else if (numReaders > NUM_PENDING_READS_MAX) {
1491 numReaders = NUM_PENDING_READS_MAX;
1492 }
1493
1494 pReader = new(GetDriverGlobals(), numReaders)
1495 FxUsbPipeContinuousReader(this, numReaders);
1496
1497 if (pReader == NULL) {
1499 }
1500
1501 //
1502 // Allocate all of the structurs and objects required
1503 //
1504 status = pReader->Config(Config, TotalBufferLength);
1505
1506 if (!NT_SUCCESS(status)) {
1507 delete pReader;
1508 return status;
1509 }
1510
1511 pReader->m_ReadCompleteCallback = Config->EvtUsbTargetPipeReadComplete;
1512 pReader->m_ReadCompleteContext = Config->EvtUsbTargetPipeReadCompleteContext;
1513
1514 pReader->m_ReadersFailedCallback = Config->EvtUsbTargetPipeReadersFailed;
1515
1517 pReader,
1518 NULL) == NULL) {
1519 //
1520 // We set the field, do nothing.
1521 //
1522 DO_NOTHING();
1523 }
1524 else {
1525 //
1526 // Some other thread came in and set the field, free our allocation.
1527 //
1528 delete pReader;
1529 }
1530
1531 return STATUS_SUCCESS;
1532}
1533
1537 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1538 __in WDFUSBPIPE Pipe,
1539 __in WDFREQUEST Request,
1540 __in_opt WDFMEMORY TransferMemory,
1541 __in_opt PWDFMEMORY_OFFSET TransferOffsets,
1543 )
1544{
1550
1551 FxObjectHandleGetPtrAndGlobals(FxDriverGlobals,
1552 Pipe,
1554 (PVOID*) &pUsbPipe,
1555 &FxDriverGlobals);
1556
1557 FxObjectHandleGetPtr(FxDriverGlobals,
1558 Request,
1560 (PVOID*) &pRequest);
1561
1562 //
1563 // We allow zero length transfers (which are indicated by TransferMemory == NULL)
1564 //
1565 if (TransferMemory != NULL) {
1566 FxObjectHandleGetPtr(FxDriverGlobals,
1569 (PVOID*) &pMemory);
1570
1571 status = pMemory->ValidateMemoryOffsets(TransferOffsets);
1572 if (!NT_SUCCESS(status)) {
1573 goto Done;
1574 }
1575
1576 buf.SetMemory(pMemory, TransferOffsets);
1577 }
1578 else {
1579 pMemory = NULL;
1580 }
1581
1583
1584 if (NT_SUCCESS(status)) {
1585 FxUsbPipeTransferContext* pContext;
1586
1588
1589 //
1590 // By assuming the fields are at the same offset, we can use simpler
1591 // logic (w/out comparisons for type) to set them.
1592 //
1593 WDFCASSERT(
1596 );
1597
1598 WDFCASSERT(
1601 );
1602
1604 pContext->m_UsbParameters.Parameters.PipeWrite.Length = buf.GetBufferLength();
1605
1606 pContext->m_UsbParameters.Parameters.PipeWrite.Offset =
1607 (TransferOffsets != NULL) ? TransferOffsets->BufferOffset
1608 : 0;
1609 pContext->SetUsbType(
1612 );
1613 }
1614
1615Done:
1617 "WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p, %!STATUS!",
1619
1620 return status;
1621}
1622
1626 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1627 __in WDFUSBPIPE Pipe,
1628 __in_opt WDFREQUEST Request,
1633 )
1634{
1638
1639 FxObjectHandleGetPtrAndGlobals(FxDriverGlobals,
1640 Pipe,
1642 (PVOID*) &pUsbPipe,
1643 &FxDriverGlobals);
1644
1646
1647 FxSyncRequest request(FxDriverGlobals, &context, Request);
1648
1649 //
1650 // FxSyncRequest always succeesds for KM but can fail for UM.
1651 //
1652 status = request.Initialize();
1653 if (!NT_SUCCESS(status)) {
1655 "Failed to initialize FxSyncRequest");
1656 return status;
1657 }
1658
1659 if (BytesTransferred != NULL) {
1660 *BytesTransferred = 0;
1661 }
1662
1663 status = FxVerifierCheckIrqlLevel(FxDriverGlobals, PASSIVE_LEVEL);
1664 if (!NT_SUCCESS(status)) {
1665 return status;
1666 }
1667
1669 if (!NT_SUCCESS(status)) {
1670 return status;
1671 }
1672
1673 //
1674 // We allow zero length writes (which are indicated by MemoryDescriptor == NULL)
1675 //
1676 if (MemoryDescriptor != NULL) {
1677 status = buf.ValidateMemoryDescriptor(FxDriverGlobals, MemoryDescriptor);
1678 if (!NT_SUCCESS(status)) {
1679 return status;
1680 }
1681 }
1682
1684
1685 if (NT_SUCCESS(status)) {
1687 FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
1688 "WDFUSBPIPE %p, WDFREQUEST %p being submitted",
1689 Pipe, request.m_TrueRequest->GetTraceObjectHandle());
1690
1691 status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions);
1692
1693 //
1694 // Even on error we want to set this value. USBD should be clearing
1695 // it if the transfer fails.
1696 //
1697 if (BytesTransferred != NULL) {
1698 *BytesTransferred = context.GetUrbTransferLength();
1699 }
1700 }
1701
1703 "WDFUSBPIPE %p, %!STATUS!", Pipe, status);
1704
1705 return status;
1706}
1707
1712 )
1713{
1714 FxUsbPipeRequestContext* pContext;
1716 FX_URB_TYPE urbType;
1717
1718 status = Request->ValidateTarget(this);
1719 if (!NT_SUCCESS(status)) {
1721 "Pipe %p, Request %p, setting target failed, "
1722 "status %!STATUS!", this, Request, status);
1723
1724 return status;
1725 }
1726
1727 if (Request->HasContextType(FX_RCT_USB_PIPE_REQUEST)) {
1728 pContext = (FxUsbPipeRequestContext*) Request->GetContext();
1729 }
1730 else {
1731
1733 pContext = new(GetDriverGlobals()) FxUsbPipeRequestContext(urbType);
1734 if (pContext == NULL) {
1736 }
1737
1738#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1739 if (urbType == FxUrbTypeUsbdAllocated) {
1740 status = pContext->AllocateUrb(m_USBDHandle);
1741 if (!NT_SUCCESS(status)) {
1742 delete pContext;
1743 return status;
1744 }
1745 //
1746 // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
1747 // important to release those resorces before the devnode is removed. Those
1748 // resoruces are removed at the time Request is disposed.
1749 //
1750 Request->EnableContextDisposeNotification();
1751 }
1752#endif
1753
1754 Request->SetContext(pContext);
1755 }
1756
1757#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1761
1762 if (pContext->m_Urb == &pContext->m_UrbLegacy) {
1763 urbType = FxUrbTypeLegacy;
1764 }
1765 else {
1766 urbType = FxUrbTypeUsbdAllocated;
1767 }
1768
1769 FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
1770#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
1773 m_PipeInformationUm.PipeId,
1776#endif
1777
1778 return STATUS_SUCCESS;
1779}
1780
1785 )
1786{
1787 FxUsbPipeRequestContext* pContext;
1789 FX_URB_TYPE urbType;
1790
1791 status = Request->ValidateTarget(this);
1792 if (!NT_SUCCESS(status)) {
1794 "Pipe %p, Request %p, setting target failed, "
1795 "status %!STATUS!", this, Request, status);
1796
1797 return status;
1798 }
1799
1800 if (Request->HasContextType(FX_RCT_USB_PIPE_REQUEST)) {
1801 pContext = (FxUsbPipeRequestContext*) Request->GetContext();
1802 }
1803 else {
1805 pContext = new(GetDriverGlobals()) FxUsbPipeRequestContext(urbType);
1806 if (pContext == NULL) {
1808 }
1809
1810#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1811 if (urbType == FxUrbTypeUsbdAllocated) {
1812 status = pContext->AllocateUrb(m_USBDHandle);
1813 if (!NT_SUCCESS(status)) {
1814 delete pContext;
1815 return status;
1816 }
1817 //
1818 // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
1819 // important to release those resorces before the devnode is removed. Those
1820 // resoruces are removed at the time Request is disposed.
1821 //
1822 Request->EnableContextDisposeNotification();
1823 }
1824#endif
1825
1826 Request->SetContext(pContext);
1827 }
1828
1829#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1830 //
1831 // URB_FUNCTION_RESET_PIPE and URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
1832 // are the same value
1833 //
1837
1838 if (pContext->m_Urb == &pContext->m_UrbLegacy) {
1839 urbType = FxUrbTypeLegacy;
1840 }
1841 else {
1842 urbType = FxUrbTypeUsbdAllocated;
1843 }
1844
1845 FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
1846#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
1849 m_PipeInformationUm.PipeId,
1852#endif
1853
1854 return STATUS_SUCCESS;
1855}
1856
1859 VOID
1860 )
1861{
1863
1864 FxSyncRequest request(GetDriverGlobals(), &context);
1866
1867 //
1868 // FxSyncRequest always succeesds for KM but can fail for UM.
1869 //
1870 status = request.Initialize();
1871 if (!NT_SUCCESS(status)) {
1873 "Failed to initialize FxSyncRequest");
1874 return status;
1875 }
1876
1877 status = FormatResetRequest(request.m_TrueRequest);
1878 if (NT_SUCCESS(status)) {
1879 if (m_Reader != NULL) {
1880 //
1881 // This assumes that no other I/O besides reader I/O is going on.
1882 //
1884 }
1885 else {
1886 CancelSentIo();
1887 }
1889 }
1890 return status;
1891}
1892
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:1294
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:1217
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:1367
_Must_inspect_result_ NTSTATUS FormatResetRequest(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:1783
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:1710
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:1073
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:1419
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:1625
virtual BOOLEAN Dispose(VOID)
Definition: fxusbpipe.cpp:1102
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:1536
NTSTATUS Reset(VOID)
Definition: fxusbpipe.cpp:1858
FxUsbPipe(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxUsbDevice *UsbDevice)
Definition: fxusbpipe.cpp:1050
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:1463
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxusbpipe.cpp:1133
_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 __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
static HANDLE PipeHandle
Definition: dhcpcsvc.c:22
#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
const WCHAR * action
Definition: action.c:7479
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
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:129
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
#define ASSERT(a)
Definition: mode.c:44
#define __checkReturn
Definition: ms_sal.h:2873
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define DO_NOTHING()
Definition: mxgeneral.h:32
IO_WORKITEM_ROUTINE * PMX_WORKITEM_ROUTINE
Definition: mxworkitemkm.h:26
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#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:89
ULONG ResubmitRepeater(__in FxUsbPipeRepeatReader *Repeater, __out NTSTATUS *Status)
Definition: fxusbpipe.cpp:135
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:687
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:88
FxUsbPipeContinuousReader(__in FxUsbPipe *Pipe, __in UCHAR NumReaders)
Definition: fxusbpipe.cpp:30
__inline VOID FxUsbPipeRequestWorkItemHandler(__in FxUsbPipeRepeatReader *FailedRepeater)
Definition: fxusbpipe.cpp:395
FxUsbPipeContinuousReader * Parent
Definition: fxusbpipe.hpp:194
USBD_STATUS GetUsbdStatus(VOID)
Definition: fxusbpipe.cpp:1043
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:992
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:1028
FxUsbPipeRequestContext(__in FX_URB_TYPE FxUrbType)
Definition: fxusbpipe.cpp:964
virtual VOID Dispose(VOID)
Definition: fxusbpipe.cpp:1016
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:861
virtual VOID CopyParameters(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:883
virtual VOID Dispose(VOID)
Definition: fxusbpipe.cpp:849
USBD_STATUS GetUsbdStatus(VOID)
Definition: fxusbpipe.cpp:913
_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:794
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbpipe.cpp:825
VOID SetUrbInfo(__in USBD_PIPE_HANDLE PipeHandle, __in ULONG TransferFlags)
Definition: fxusbpipe.cpp:903
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:937
FxUsbUrbContext(VOID)
Definition: fxusbpipe.cpp:920
USBD_STATUS GetUsbdStatus(VOID)
Definition: fxusbpipe.cpp:929
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
Definition: fxusbpipe.cpp:955
_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:1705
Definition: typedefs.h:120
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
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
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@3920::@3925 PipeRead
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@3920::@3924 PipeWrite
union _WDF_USB_REQUEST_COMPLETION_PARAMS::@3920 Parameters
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
_In_ PVOID _In_ LONG InterfaceNumber
Definition: usbdlib.h:169
NTSTATUS USBD_UrbAllocate(_In_ USBD_HANDLE USBDHandle, _Outptr_result_bytebuffer_(sizeof(URB)) PURB *Urb)
Definition: usbstubum.cpp:46
VOID USBD_UrbFree(_In_ USBD_HANDLE USBDHandle, _In_ PURB Urb)
Definition: usbstubum.cpp:33
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:29
VOID FxUsbUmFormatRequest(__in FxRequestBase *Request, __in_xcount(Urb->Length) PUMURB_HEADER Urb, __in IWudfFile *HostFile, __in BOOLEAN Reuse)
Definition: usbutil.cpp:486
#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:4533
_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