1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxUsbPipeAPI.cpp
8
9 Abstract:
10
11
12 Author:
13
14 Environment:
15
16 Both kernel and user mode
17
18 Revision History:
19
20 --*/
21
22 #include "fxusbpch.hpp"
23
24 extern "C" {
25 #include "FxUsbPipeAPI.tmh"
26 }
27
28 //
29 // extern "C" the whole file since we are exporting the APIs by name
30 //
31 extern "C" {
32
__drv_maxIRQL(DISPATCH_LEVEL)33 __drv_maxIRQL(DISPATCH_LEVEL)
34 VOID
35 WDFAPI
36 WDFEXPORT(WdfUsbTargetPipeGetInformation)(
37 __in
38 PWDF_DRIVER_GLOBALS DriverGlobals,
39 __in
40 WDFUSBPIPE Pipe,
41 __out
42 PWDF_USB_PIPE_INFORMATION PipeInformation
43 )
44 {
45 DDI_ENTRY();
46
47 PFX_DRIVER_GLOBALS pFxDriverGlobals;
48 FxUsbPipe* pUsbPipe;
49
50 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
51 Pipe,
52 FX_TYPE_IO_TARGET_USB_PIPE,
53 (PVOID*) &pUsbPipe,
54 &pFxDriverGlobals);
55
56 FxPointerNotNull(pFxDriverGlobals, PipeInformation);
57
58 pUsbPipe->GetInformation(PipeInformation);
59 }
60
__drv_maxIRQL(DISPATCH_LEVEL)61 __drv_maxIRQL(DISPATCH_LEVEL)
62 BOOLEAN
63 WDFAPI
64 WDFEXPORT(WdfUsbTargetPipeIsInEndpoint)(
65 __in
66 PWDF_DRIVER_GLOBALS DriverGlobals,
67 __in
68 WDFUSBPIPE Pipe
69 )
70 {
71 DDI_ENTRY();
72
73 FxUsbPipe* pUsbPipe;
74
75 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
76 Pipe,
77 FX_TYPE_IO_TARGET_USB_PIPE,
78 (PVOID*) &pUsbPipe);
79
80 return pUsbPipe->IsInEndpoint();
81 }
82
__drv_maxIRQL(DISPATCH_LEVEL)83 __drv_maxIRQL(DISPATCH_LEVEL)
84 BOOLEAN
85 WDFAPI
86 WDFEXPORT(WdfUsbTargetPipeIsOutEndpoint)(
87 __in
88 PWDF_DRIVER_GLOBALS DriverGlobals,
89 __in
90 WDFUSBPIPE Pipe
91 )
92 {
93 DDI_ENTRY();
94
95 FxUsbPipe* pUsbPipe;
96
97 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
98 Pipe,
99 FX_TYPE_IO_TARGET_USB_PIPE,
100 (PVOID*) &pUsbPipe);
101
102 return pUsbPipe->IsOutEndpoint();
103 }
104
__drv_maxIRQL(DISPATCH_LEVEL)105 __drv_maxIRQL(DISPATCH_LEVEL)
106 WDF_USB_PIPE_TYPE
107 WDFAPI
108 WDFEXPORT(WdfUsbTargetPipeGetType)(
109 __in
110 PWDF_DRIVER_GLOBALS DriverGlobals,
111 __in
112 WDFUSBPIPE Pipe
113 )
114 {
115 DDI_ENTRY();
116
117 FxUsbPipe* pUsbPipe;
118
119 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
120 Pipe,
121 FX_TYPE_IO_TARGET_USB_PIPE,
122 (PVOID*) &pUsbPipe);
123
124 return pUsbPipe->GetType();
125 }
126
__drv_maxIRQL(DISPATCH_LEVEL)127 __drv_maxIRQL(DISPATCH_LEVEL)
128 VOID
129 WDFAPI
130 WDFEXPORT(WdfUsbTargetPipeSetNoMaximumPacketSizeCheck)(
131 __in
132 PWDF_DRIVER_GLOBALS DriverGlobals,
133 __in
134 WDFUSBPIPE Pipe
135 )
136 {
137 DDI_ENTRY();
138
139 PFX_DRIVER_GLOBALS pFxDriverGlobals;
140 FxUsbPipe* pUsbPipe;
141
142 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
143 Pipe,
144 FX_TYPE_IO_TARGET_USB_PIPE,
145 (PVOID*) &pUsbPipe,
146 &pFxDriverGlobals);
147
148 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
149 "WDFUSBPIPE %p", Pipe);
150
151 pUsbPipe->SetNoCheckPacketSize();
152 }
153
154 _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)155 __drv_maxIRQL(PASSIVE_LEVEL)
156 NTSTATUS
157 WDFAPI
158 WDFEXPORT(WdfUsbTargetPipeWriteSynchronously)(
159 __in
160 PWDF_DRIVER_GLOBALS DriverGlobals,
161 __in
162 WDFUSBPIPE Pipe,
163 __in_opt
164 WDFREQUEST Request,
165 __in_opt
166 PWDF_REQUEST_SEND_OPTIONS RequestOptions,
167 __in_opt
168 PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
169 __out_opt
170 PULONG BytesWritten
171 )
172 {
173 DDI_ENTRY();
174
175 DoTraceLevelMessage(
176 GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
177 "WDFUSBPIPE %p", Pipe);
178
179 return FxUsbPipe::_SendTransfer(GetFxDriverGlobals(DriverGlobals),
180 Pipe,
181 Request,
182 RequestOptions,
183 MemoryDescriptor,
184 BytesWritten,
185 0);
186 }
187
188 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)189 __drv_maxIRQL(DISPATCH_LEVEL)
190 NTSTATUS
191 WDFAPI
192 WDFEXPORT(WdfUsbTargetPipeFormatRequestForWrite)(
193 __in
194 PWDF_DRIVER_GLOBALS DriverGlobals,
195 __in
196 WDFUSBPIPE Pipe,
197 __in
198 WDFREQUEST Request,
199 __in_opt
200 WDFMEMORY WriteMemory,
201 __in_opt
202 PWDFMEMORY_OFFSET WriteOffsets
203 )
204 {
205 DDI_ENTRY();
206
207 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
208 "WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p",
209 Pipe, Request, WriteMemory);
210
211 return FxUsbPipe::_FormatTransfer(GetFxDriverGlobals(DriverGlobals),
212 Pipe,
213 Request,
214 WriteMemory,
215 WriteOffsets,
216 0);
217 }
218
219 _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)220 __drv_maxIRQL(PASSIVE_LEVEL)
221 NTSTATUS
222 WDFAPI
223 WDFEXPORT(WdfUsbTargetPipeReadSynchronously)(
224 __in
225 PWDF_DRIVER_GLOBALS DriverGlobals,
226 __in
227 WDFUSBPIPE Pipe,
228 __in_opt
229 WDFREQUEST Request,
230 __in_opt
231 PWDF_REQUEST_SEND_OPTIONS RequestOptions,
232 __in_opt
233 PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
234 __out_opt
235 PULONG BytesRead
236 )
237 {
238 DDI_ENTRY();
239
240 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
241 "WDFUSBPIPE %p", Pipe);
242
243 return FxUsbPipe::_SendTransfer(
244 GetFxDriverGlobals(DriverGlobals),
245 Pipe,
246 Request,
247 RequestOptions,
248 MemoryDescriptor,
249 BytesRead,
250 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK
251 );
252 }
253
254 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)255 __drv_maxIRQL(DISPATCH_LEVEL)
256 NTSTATUS
257 WDFAPI
258 WDFEXPORT(WdfUsbTargetPipeFormatRequestForRead)(
259 __in
260 PWDF_DRIVER_GLOBALS DriverGlobals,
261 __in
262 WDFUSBPIPE Pipe,
263 __in
264 WDFREQUEST Request,
265 __in_opt
266 WDFMEMORY ReadMemory,
267 __in_opt
268 PWDFMEMORY_OFFSET ReadOffsets
269 )
270 {
271 DDI_ENTRY();
272
273 DoTraceLevelMessage(
274 GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
275 "WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p",
276 Pipe, Request, ReadMemory);
277
278 return FxUsbPipe::_FormatTransfer(
279 GetFxDriverGlobals(DriverGlobals),
280 Pipe,
281 Request,
282 ReadMemory,
283 ReadOffsets,
284 USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK
285 );
286 }
287
288 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)289 __drv_maxIRQL(DISPATCH_LEVEL)
290 NTSTATUS
291 WDFAPI
292 WDFEXPORT(WdfUsbTargetPipeConfigContinuousReader)(
293 __in
294 PWDF_DRIVER_GLOBALS DriverGlobals,
295 __in
296 WDFUSBPIPE Pipe,
297 __in
298 PWDF_USB_CONTINUOUS_READER_CONFIG Config
299 )
300 {
301 DDI_ENTRY();
302
303 PFX_DRIVER_GLOBALS pFxDriverGlobals;
304 FxUsbPipe* pUsbPipe;
305 NTSTATUS status;
306 size_t total;
307
308 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
309 Pipe,
310 FX_TYPE_IO_TARGET_USB_PIPE,
311 (PVOID*) &pUsbPipe,
312 &pFxDriverGlobals);
313
314 FxPointerNotNull(pFxDriverGlobals, Config);
315
316 if (Config->Size != sizeof(WDF_USB_CONTINUOUS_READER_CONFIG)) {
317 status = STATUS_INFO_LENGTH_MISMATCH;
318
319 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
320 "Config %p incorrect size %d, expected %d %!STATUS!",
321 Config, Config->Size, sizeof(WDF_USB_CONTINUOUS_READER_CONFIG),
322 status);
323
324 return status;
325 }
326
327 if (Config->EvtUsbTargetPipeReadComplete == NULL) {
328 status = STATUS_INVALID_PARAMETER;
329 DoTraceLevelMessage(
330 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
331 "NULL EvtUsbTargetPipeReadComplete not allowed %!STATUS!", status);
332 return status;
333 }
334
335 if (Config->TransferLength == 0) {
336 status = STATUS_INVALID_PARAMETER;
337 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
338 "TransferLength of 0 not allowed %!STATUS!", status);
339 return status;
340 }
341
342 status = RtlSizeTAdd(Config->HeaderLength,
343 Config->TransferLength,
344 &total);
345
346 if (!NT_SUCCESS(status)) {
347 DoTraceLevelMessage(
348 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
349 "HeaderLength + TransferLength overflow %!STATUS!", status);
350 return status;
351 }
352
353 status = RtlSizeTAdd(total,
354 Config->TrailerLength,
355 &total);
356
357 if (!NT_SUCCESS(status)) {
358 DoTraceLevelMessage(
359 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
360 "HeaderLength + TransferLength + TrailerLength overflow %!STATUS!",
361 status);
362 return status;
363 }
364
365 //
366 // Internally WDF will assign a parent to the memory, so do not allow the driver
367 // to do so.
368 //
369 status = FxValidateObjectAttributes(pFxDriverGlobals,
370 Config->BufferAttributes,
371 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
372 if (!NT_SUCCESS(status)) {
373 return status;
374 }
375
376 //
377 // Only bulk or interrrupt is allowed for a continous reader
378 //
379 if ((pUsbPipe->IsType(WdfUsbPipeTypeBulk) ||
380 pUsbPipe->IsType(WdfUsbPipeTypeInterrupt)) == FALSE) {
381 status = STATUS_INVALID_DEVICE_REQUEST;
382
383 DoTraceLevelMessage(
384 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
385 "WDFUSBPIPE %p type %!WDF_USB_PIPE_TYPE!, only bulk or interrupt "
386 "pipes can be configured for continous readers, %!STATUS!",
387 Pipe, pUsbPipe->GetType(), status);
388
389 return status;
390 }
391
392 if (pUsbPipe->IsOutEndpoint()) {
393 status = STATUS_INVALID_DEVICE_REQUEST;
394
395 DoTraceLevelMessage(
396 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
397 "WDFUSBPIPE %p, wrong direction for continuous reader, %!STATUS!",
398 Pipe, status);
399
400 return status;
401 }
402
403 status = pUsbPipe->ValidateTransferLength(Config->TransferLength);
404 if (!NT_SUCCESS(status)) {
405 DoTraceLevelMessage(
406 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
407 "TransferLength %I64d not a valid transer length (not integral of max "
408 "packet size %d) %!STATUS!", Config->TransferLength,
409 pUsbPipe->GetMaxPacketSize(), status);
410 return status;
411 }
412
413 status = pUsbPipe->InitContinuousReader(Config, total);
414
415 return status;
416 }
417
418 _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)419 __drv_maxIRQL(PASSIVE_LEVEL)
420 NTSTATUS
421 WDFAPI
422 WDFEXPORT(WdfUsbTargetPipeAbortSynchronously)(
423 __in
424 PWDF_DRIVER_GLOBALS DriverGlobals,
425 __in
426 WDFUSBPIPE Pipe,
427 __in_opt
428 WDFREQUEST Request,
429 __in_opt
430 PWDF_REQUEST_SEND_OPTIONS RequestOptions
431 )
432 {
433 DDI_ENTRY();
434
435 PFX_DRIVER_GLOBALS pFxDriverGlobals;
436 FxUsbPipe* pUsbPipe;
437 NTSTATUS status;
438
439 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
440 Pipe,
441 FX_TYPE_IO_TARGET_USB_PIPE,
442 (PVOID*) &pUsbPipe,
443 &pFxDriverGlobals);
444
445 FxUsbPipeRequestContext context(FxUrbTypeLegacy);
446
447 FxSyncRequest request(pFxDriverGlobals, &context, Request);
448
449 //
450 // FxSyncRequest always succeesds for KM but can fail for UM.
451 //
452 status = request.Initialize();
453 if (!NT_SUCCESS(status)) {
454 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
455 "Failed to initialize FxSyncRequest");
456 return status;
457 }
458
459 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
460 "Pipe %p", Pipe);
461
462 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
463 if (!NT_SUCCESS(status)) {
464 return status;
465 }
466
467 status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
468 if (!NT_SUCCESS(status)) {
469 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
470 "Invalid request options");
471 return status;
472 }
473
474 status = pUsbPipe->FormatAbortRequest(request.m_TrueRequest);
475 if (NT_SUCCESS(status)) {
476 DoTraceLevelMessage(
477 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
478 "WDFUSBPIPE %p, WDFREQUEST %p being submitted",
479 Pipe, request.m_TrueRequest->GetTraceObjectHandle());
480
481 status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions);
482 }
483
484 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
485 "WDFUSBPIPE %p, %!STATUS!", Pipe, status);
486
487 return status;
488 }
489
490 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)491 __drv_maxIRQL(DISPATCH_LEVEL)
492 NTSTATUS
493 WDFAPI
494 WDFEXPORT(WdfUsbTargetPipeFormatRequestForAbort)(
495 __in
496 PWDF_DRIVER_GLOBALS DriverGlobals,
497 __in
498 WDFUSBPIPE Pipe,
499 __in
500 WDFREQUEST Request
501 )
502 {
503 DDI_ENTRY();
504
505 PFX_DRIVER_GLOBALS pFxDriverGlobals;
506 FxRequest* pRequest;
507 FxUsbPipe* pUsbPipe;
508 NTSTATUS status;
509
510 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
511 Pipe,
512 FX_TYPE_IO_TARGET_USB_PIPE,
513 (PVOID*) &pUsbPipe,
514 &pFxDriverGlobals);
515
516 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
517 "Pipe %p, Request %p", Pipe, Request);
518
519 FxObjectHandleGetPtr(pFxDriverGlobals,
520 Request,
521 FX_TYPE_REQUEST,
522 (PVOID*) &pRequest);
523
524 status = pUsbPipe->FormatAbortRequest(pRequest);
525
526 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
527 "Pipe %p, Request %p, status %!STATUS!",
528 Pipe, Request, status);
529
530 return status;
531 }
532
533 _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)534 __drv_maxIRQL(PASSIVE_LEVEL)
535 NTSTATUS
536 WDFAPI
537 WDFEXPORT(WdfUsbTargetPipeResetSynchronously)(
538 __in
539 PWDF_DRIVER_GLOBALS DriverGlobals,
540 __in
541 WDFUSBPIPE Pipe,
542 __in_opt
543 WDFREQUEST Request,
544 __in_opt
545 PWDF_REQUEST_SEND_OPTIONS RequestOptions
546 )
547 {
548 DDI_ENTRY();
549
550 PFX_DRIVER_GLOBALS pFxDriverGlobals;
551 FxUsbPipe* pUsbPipe;
552 NTSTATUS status;
553
554 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
555 Pipe,
556 FX_TYPE_IO_TARGET_USB_PIPE,
557 (PVOID*) &pUsbPipe,
558 &pFxDriverGlobals);
559
560 FxUsbPipeRequestContext context(FxUrbTypeLegacy);
561
562 FxSyncRequest request(pFxDriverGlobals, &context, Request);
563
564 //
565 // FxSyncRequest always succeesds for KM but can fail for UM.
566 //
567 status = request.Initialize();
568 if (!NT_SUCCESS(status)) {
569 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
570 "Failed to initialize FxSyncRequest");
571 return status;
572 }
573
574 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
575 "WDFUSBPIPE %p reset", Pipe);
576
577 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
578 if (!NT_SUCCESS(status)) {
579 return status;
580 }
581
582 status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
583 if (!NT_SUCCESS(status)) {
584 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
585 "Invalid request options");
586 return status;
587 }
588
589 status = pUsbPipe->FormatResetRequest(request.m_TrueRequest);
590
591 if (NT_SUCCESS(status)) {
592 DoTraceLevelMessage(
593 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
594 "WDFUSBPIPE %p, WDFREQUEST %p being submitted",
595 Pipe, request.m_TrueRequest->GetTraceObjectHandle());
596
597 pUsbPipe->CancelSentIo();
598
599 //
600 // Even if the previous state of the target was stopped let this IO go through by
601 // ignoring target state.
602 //
603 status = pUsbPipe->SubmitSyncRequestIgnoreTargetState(request.m_TrueRequest, RequestOptions);
604 }
605
606 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
607 "WDFUSBPIPE %p reset, %!STATUS!", Pipe, status);
608
609 return status;
610 }
611
612 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)613 __drv_maxIRQL(DISPATCH_LEVEL)
614 NTSTATUS
615 WDFAPI
616 WDFEXPORT(WdfUsbTargetPipeFormatRequestForReset)(
617 __in
618 PWDF_DRIVER_GLOBALS DriverGlobals,
619 __in
620 WDFUSBPIPE Pipe,
621 __in
622 WDFREQUEST Request
623 )
624 {
625 DDI_ENTRY();
626
627 PFX_DRIVER_GLOBALS pFxDriverGlobals;
628 FxRequest* pRequest;
629 FxUsbPipe* pUsbPipe;
630 NTSTATUS status;
631
632 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
633 Pipe,
634 FX_TYPE_IO_TARGET_USB_PIPE,
635 (PVOID*) &pUsbPipe,
636 &pFxDriverGlobals);
637
638 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
639 "Pipe %p, Request %p", Pipe, Request);
640
641 FxObjectHandleGetPtr(pFxDriverGlobals,
642 Request,
643 FX_TYPE_REQUEST,
644 (PVOID*) &pRequest);
645
646 status = pUsbPipe->FormatResetRequest(pRequest);
647
648 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
649 "Pipe %p, Request %p = 0x%x",
650 Pipe, Request, status);
651
652 return status;
653 }
654
655 _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)656 __drv_maxIRQL(PASSIVE_LEVEL)
657 NTSTATUS
658 WDFAPI
659 WDFEXPORT(WdfUsbTargetPipeSendUrbSynchronously)(
660 __in
661 PWDF_DRIVER_GLOBALS DriverGlobals,
662 __in
663 WDFUSBPIPE Pipe,
664 __in_opt
665 WDFREQUEST Request,
666 __in_opt
667 PWDF_REQUEST_SEND_OPTIONS RequestOptions,
668 __in_xcount("union bug in SAL")
669 PURB Urb
670 )
671 {
672 DDI_ENTRY();
673
674 FxRequestBuffer buf;
675 PFX_DRIVER_GLOBALS pFxDriverGlobals;
676 FxUsbPipe* pUsbPipe;
677 NTSTATUS status;
678
679 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
680 Pipe,
681 FX_TYPE_IO_TARGET_USB_PIPE,
682 (PVOID*) &pUsbPipe,
683 &pFxDriverGlobals);
684
685 FxUsbUrbContext context;
686 FxSyncRequest request(pFxDriverGlobals, &context, Request);
687
688 //
689 // FxSyncRequest always succeesds for KM but can fail for UM.
690 //
691 status = request.Initialize();
692 if (!NT_SUCCESS(status)) {
693 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
694 "Failed to initialize FxSyncRequest");
695 return status;
696 }
697
698 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
699 "WDFUSBPIPE %p, Urb %p", Pipe, Urb);
700
701 FxPointerNotNull(pFxDriverGlobals, Urb);
702
703 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
704 if (!NT_SUCCESS(status)) {
705 return status;
706 }
707
708 status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
709 if (!NT_SUCCESS(status)) {
710 return status;
711 }
712
713 buf.SetBuffer(Urb, 0);
714
715 status = FxFormatUrbRequest(pFxDriverGlobals,
716 pUsbPipe,
717 request.m_TrueRequest,
718 &buf,
719 pUsbPipe->GetUrbType(),
720 pUsbPipe->GetUSBDHandle());
721
722 if (NT_SUCCESS(status)) {
723 DoTraceLevelMessage(
724 pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
725 "WDFUSBPIPE %p, WDFREQUEST %p being submitted",
726 Pipe, request.m_TrueRequest->GetTraceObjectHandle());
727
728 status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions);
729 }
730
731 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
732 "WDFUSBPIPE %p, Urb %p, %!STATUS!",
733 Pipe, Urb, status);
734
735 return status;
736 }
737
738 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)739 __drv_maxIRQL(DISPATCH_LEVEL)
740 NTSTATUS
741 WDFAPI
742 WDFEXPORT(WdfUsbTargetPipeFormatRequestForUrb)(
743 __in
744 PWDF_DRIVER_GLOBALS DriverGlobals,
745 __in
746 WDFUSBPIPE Pipe,
747 __in
748 WDFREQUEST Request,
749 __in
750 WDFMEMORY UrbMemory,
751 __in_opt
752 PWDFMEMORY_OFFSET UrbOffsets
753 )
754 {
755 DDI_ENTRY();
756
757 PFX_DRIVER_GLOBALS pFxDriverGlobals;
758 IFxMemory* pMemory;
759 FxUsbPipe* pUsbPipe;
760 FxRequest* pRequest;
761 FxRequestBuffer buf;
762 NTSTATUS status;
763 size_t bufferSize;
764
765 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
766 Pipe,
767 FX_TYPE_IO_TARGET_USB_PIPE,
768 (PVOID*) &pUsbPipe,
769 &pFxDriverGlobals);
770
771 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
772 "Pipe %p, Request %p, Memory %p",
773 Pipe, Request, UrbMemory);
774
775 FxObjectHandleGetPtr(pFxDriverGlobals,
776 UrbMemory,
777 IFX_TYPE_MEMORY,
778 (PVOID*) &pMemory);
779
780 FxObjectHandleGetPtr(pFxDriverGlobals,
781 Request,
782 FX_TYPE_REQUEST,
783 (PVOID*) &pRequest);
784
785 status = pMemory->ValidateMemoryOffsets(UrbOffsets);
786 if (!NT_SUCCESS(status)) {
787 return status;
788 }
789
790 bufferSize = pMemory->GetBufferSize();
791 if (UrbOffsets != NULL && UrbOffsets->BufferOffset > 0) {
792 bufferSize -= UrbOffsets->BufferOffset;
793 }
794
795 if (bufferSize < sizeof(_URB_HEADER)) {
796 status = STATUS_INVALID_PARAMETER;
797 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
798 "UrbMemory %p buffer size, %I64d, smaller then "
799 "_URB_HEADER, %!STATUS!", UrbMemory,
800 pMemory->GetBufferSize(), status);
801 return status;
802 }
803
804 buf.SetMemory(pMemory, UrbOffsets);
805
806 status = FxFormatUrbRequest(pFxDriverGlobals,
807 pUsbPipe,
808 pRequest,
809 &buf,
810 pUsbPipe->GetUrbType(),
811 pUsbPipe->GetUSBDHandle());
812
813 if (NT_SUCCESS(status)) {
814 FxUsbUrbContext* pContext;
815 pContext = (FxUsbUrbContext*) pRequest->GetContext();
816
817 pContext->SetUsbType(WdfUsbRequestTypePipeUrb);
818 pContext->m_UsbParameters.Parameters.PipeUrb.Buffer = UrbMemory;
819 }
820
821 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
822 "Pipe %p, Request %p, Memory %p, status %!STATUS!",
823 Pipe, Request, UrbMemory, status);
824
825 return status;
826 }
827
__drv_maxIRQL(DISPATCH_LEVEL)828 __drv_maxIRQL(DISPATCH_LEVEL)
829 USBD_PIPE_HANDLE
830 WDFAPI
831 WDFEXPORT(WdfUsbTargetPipeWdmGetPipeHandle)(
832 __in
833 PWDF_DRIVER_GLOBALS DriverGlobals,
834 __in
835 WDFUSBPIPE UsbPipe
836 )
837 /*++
838
839 Routine Description:
840 Returns the underlying WDM USBD pipe handle
841
842 Arguments:
843 UsbPipe - the WDF pipe whose WDM handle will be returned
844
845 Return Value:
846 valid handle value or NULL on error
847
848 --*/
849 {
850 DDI_ENTRY();
851
852 FxUsbPipe* pUsbPipe;
853
854 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
855 UsbPipe,
856 FX_TYPE_IO_TARGET_USB_PIPE,
857 (PVOID*) &pUsbPipe);
858
859 return pUsbPipe->WdmGetPipeHandle();
860 }
861
862 } // extern "C"
863