reactos/sdk/lib/drivers/wdf/shared/targets/usb/fxusbpipeapi.cpp
Victor Perevertkin 8a978a179f
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9

Licensed under MIT
2020-11-03 00:06:26 +03:00

862 lines
23 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxUsbPipeAPI.cpp
Abstract:
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "fxusbpch.hpp"
extern "C" {
#include "FxUsbPipeAPI.tmh"
}
//
// extern "C" the whole file since we are exporting the APIs by name
//
extern "C" {
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
WDFAPI
WDFEXPORT(WdfUsbTargetPipeGetInformation)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__out
PWDF_USB_PIPE_INFORMATION PipeInformation
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbPipe* pUsbPipe;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, PipeInformation);
pUsbPipe->GetInformation(PipeInformation);
}
__drv_maxIRQL(DISPATCH_LEVEL)
BOOLEAN
WDFAPI
WDFEXPORT(WdfUsbTargetPipeIsInEndpoint)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe
)
{
DDI_ENTRY();
FxUsbPipe* pUsbPipe;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe);
return pUsbPipe->IsInEndpoint();
}
__drv_maxIRQL(DISPATCH_LEVEL)
BOOLEAN
WDFAPI
WDFEXPORT(WdfUsbTargetPipeIsOutEndpoint)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe
)
{
DDI_ENTRY();
FxUsbPipe* pUsbPipe;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe);
return pUsbPipe->IsOutEndpoint();
}
__drv_maxIRQL(DISPATCH_LEVEL)
WDF_USB_PIPE_TYPE
WDFAPI
WDFEXPORT(WdfUsbTargetPipeGetType)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe
)
{
DDI_ENTRY();
FxUsbPipe* pUsbPipe;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe);
return pUsbPipe->GetType();
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
WDFAPI
WDFEXPORT(WdfUsbTargetPipeSetNoMaximumPacketSizeCheck)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbPipe* pUsbPipe;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p", Pipe);
pUsbPipe->SetNoCheckPacketSize();
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeWriteSynchronously)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in_opt
WDFREQUEST Request,
__in_opt
PWDF_REQUEST_SEND_OPTIONS RequestOptions,
__in_opt
PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
__out_opt
PULONG BytesWritten
)
{
DDI_ENTRY();
DoTraceLevelMessage(
GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p", Pipe);
return FxUsbPipe::_SendTransfer(GetFxDriverGlobals(DriverGlobals),
Pipe,
Request,
RequestOptions,
MemoryDescriptor,
BytesWritten,
0);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeFormatRequestForWrite)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in
WDFREQUEST Request,
__in_opt
WDFMEMORY WriteMemory,
__in_opt
PWDFMEMORY_OFFSET WriteOffsets
)
{
DDI_ENTRY();
DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p",
Pipe, Request, WriteMemory);
return FxUsbPipe::_FormatTransfer(GetFxDriverGlobals(DriverGlobals),
Pipe,
Request,
WriteMemory,
WriteOffsets,
0);
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeReadSynchronously)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in_opt
WDFREQUEST Request,
__in_opt
PWDF_REQUEST_SEND_OPTIONS RequestOptions,
__in_opt
PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
__out_opt
PULONG BytesRead
)
{
DDI_ENTRY();
DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p", Pipe);
return FxUsbPipe::_SendTransfer(
GetFxDriverGlobals(DriverGlobals),
Pipe,
Request,
RequestOptions,
MemoryDescriptor,
BytesRead,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK
);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeFormatRequestForRead)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in
WDFREQUEST Request,
__in_opt
WDFMEMORY ReadMemory,
__in_opt
PWDFMEMORY_OFFSET ReadOffsets
)
{
DDI_ENTRY();
DoTraceLevelMessage(
GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, WDFREQUEST %p, WDFMEMORY %p",
Pipe, Request, ReadMemory);
return FxUsbPipe::_FormatTransfer(
GetFxDriverGlobals(DriverGlobals),
Pipe,
Request,
ReadMemory,
ReadOffsets,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK
);
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeConfigContinuousReader)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in
PWDF_USB_CONTINUOUS_READER_CONFIG Config
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbPipe* pUsbPipe;
NTSTATUS status;
size_t total;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Config);
if (Config->Size != sizeof(WDF_USB_CONTINUOUS_READER_CONFIG)) {
status = STATUS_INFO_LENGTH_MISMATCH;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Config %p incorrect size %d, expected %d %!STATUS!",
Config, Config->Size, sizeof(WDF_USB_CONTINUOUS_READER_CONFIG),
status);
return status;
}
if (Config->EvtUsbTargetPipeReadComplete == NULL) {
status = STATUS_INVALID_PARAMETER;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"NULL EvtUsbTargetPipeReadComplete not allowed %!STATUS!", status);
return status;
}
if (Config->TransferLength == 0) {
status = STATUS_INVALID_PARAMETER;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"TransferLength of 0 not allowed %!STATUS!", status);
return status;
}
status = RtlSizeTAdd(Config->HeaderLength,
Config->TransferLength,
&total);
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"HeaderLength + TransferLength overflow %!STATUS!", status);
return status;
}
status = RtlSizeTAdd(total,
Config->TrailerLength,
&total);
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"HeaderLength + TransferLength + TrailerLength overflow %!STATUS!",
status);
return status;
}
//
// Internally WDF will assign a parent to the memory, so do not allow the driver
// to do so.
//
status = FxValidateObjectAttributes(pFxDriverGlobals,
Config->BufferAttributes,
FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Only bulk or interrrupt is allowed for a continous reader
//
if ((pUsbPipe->IsType(WdfUsbPipeTypeBulk) ||
pUsbPipe->IsType(WdfUsbPipeTypeInterrupt)) == FALSE) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"WDFUSBPIPE %p type %!WDF_USB_PIPE_TYPE!, only bulk or interrupt "
"pipes can be configured for continous readers, %!STATUS!",
Pipe, pUsbPipe->GetType(), status);
return status;
}
if (pUsbPipe->IsOutEndpoint()) {
status = STATUS_INVALID_DEVICE_REQUEST;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"WDFUSBPIPE %p, wrong direction for continuous reader, %!STATUS!",
Pipe, status);
return status;
}
status = pUsbPipe->ValidateTransferLength(Config->TransferLength);
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"TransferLength %I64d not a valid transer length (not integral of max "
"packet size %d) %!STATUS!", Config->TransferLength,
pUsbPipe->GetMaxPacketSize(), status);
return status;
}
status = pUsbPipe->InitContinuousReader(Config, total);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeAbortSynchronously)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in_opt
WDFREQUEST Request,
__in_opt
PWDF_REQUEST_SEND_OPTIONS RequestOptions
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbPipe* pUsbPipe;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
FxUsbPipeRequestContext context(FxUrbTypeLegacy);
FxSyncRequest request(pFxDriverGlobals, &context, Request);
//
// FxSyncRequest always succeesds for KM but can fail for UM.
//
status = request.Initialize();
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Failed to initialize FxSyncRequest");
return status;
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p", Pipe);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Invalid request options");
return status;
}
status = pUsbPipe->FormatAbortRequest(request.m_TrueRequest);
if (NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, WDFREQUEST %p being submitted",
Pipe, request.m_TrueRequest->GetTraceObjectHandle());
status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions);
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, %!STATUS!", Pipe, status);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeFormatRequestForAbort)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in
WDFREQUEST Request
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxRequest* pRequest;
FxUsbPipe* pUsbPipe;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p, Request %p", Pipe, Request);
FxObjectHandleGetPtr(pFxDriverGlobals,
Request,
FX_TYPE_REQUEST,
(PVOID*) &pRequest);
status = pUsbPipe->FormatAbortRequest(pRequest);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p, Request %p, status %!STATUS!",
Pipe, Request, status);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeResetSynchronously)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in_opt
WDFREQUEST Request,
__in_opt
PWDF_REQUEST_SEND_OPTIONS RequestOptions
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbPipe* pUsbPipe;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
FxUsbPipeRequestContext context(FxUrbTypeLegacy);
FxSyncRequest request(pFxDriverGlobals, &context, Request);
//
// FxSyncRequest always succeesds for KM but can fail for UM.
//
status = request.Initialize();
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Failed to initialize FxSyncRequest");
return status;
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p reset", Pipe);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Invalid request options");
return status;
}
status = pUsbPipe->FormatResetRequest(request.m_TrueRequest);
if (NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, WDFREQUEST %p being submitted",
Pipe, request.m_TrueRequest->GetTraceObjectHandle());
pUsbPipe->CancelSentIo();
//
// Even if the previous state of the target was stopped let this IO go through by
// ignoring target state.
//
status = pUsbPipe->SubmitSyncRequestIgnoreTargetState(request.m_TrueRequest, RequestOptions);
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p reset, %!STATUS!", Pipe, status);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeFormatRequestForReset)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in
WDFREQUEST Request
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxRequest* pRequest;
FxUsbPipe* pUsbPipe;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p, Request %p", Pipe, Request);
FxObjectHandleGetPtr(pFxDriverGlobals,
Request,
FX_TYPE_REQUEST,
(PVOID*) &pRequest);
status = pUsbPipe->FormatResetRequest(pRequest);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p, Request %p = 0x%x",
Pipe, Request, status);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeSendUrbSynchronously)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in_opt
WDFREQUEST Request,
__in_opt
PWDF_REQUEST_SEND_OPTIONS RequestOptions,
__in_xcount("union bug in SAL")
PURB Urb
)
{
DDI_ENTRY();
FxRequestBuffer buf;
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbPipe* pUsbPipe;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
FxUsbUrbContext context;
FxSyncRequest request(pFxDriverGlobals, &context, Request);
//
// FxSyncRequest always succeesds for KM but can fail for UM.
//
status = request.Initialize();
if (!NT_SUCCESS(status)) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Failed to initialize FxSyncRequest");
return status;
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, Urb %p", Pipe, Urb);
FxPointerNotNull(pFxDriverGlobals, Urb);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
if (!NT_SUCCESS(status)) {
return status;
}
buf.SetBuffer(Urb, 0);
status = FxFormatUrbRequest(pFxDriverGlobals,
pUsbPipe,
request.m_TrueRequest,
&buf,
pUsbPipe->GetUrbType(),
pUsbPipe->GetUSBDHandle());
if (NT_SUCCESS(status)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, WDFREQUEST %p being submitted",
Pipe, request.m_TrueRequest->GetTraceObjectHandle());
status = pUsbPipe->SubmitSync(request.m_TrueRequest, RequestOptions);
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"WDFUSBPIPE %p, Urb %p, %!STATUS!",
Pipe, Urb, status);
return status;
}
_Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbTargetPipeFormatRequestForUrb)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE Pipe,
__in
WDFREQUEST Request,
__in
WDFMEMORY UrbMemory,
__in_opt
PWDFMEMORY_OFFSET UrbOffsets
)
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
IFxMemory* pMemory;
FxUsbPipe* pUsbPipe;
FxRequest* pRequest;
FxRequestBuffer buf;
NTSTATUS status;
size_t bufferSize;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
Pipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe,
&pFxDriverGlobals);
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p, Request %p, Memory %p",
Pipe, Request, UrbMemory);
FxObjectHandleGetPtr(pFxDriverGlobals,
UrbMemory,
IFX_TYPE_MEMORY,
(PVOID*) &pMemory);
FxObjectHandleGetPtr(pFxDriverGlobals,
Request,
FX_TYPE_REQUEST,
(PVOID*) &pRequest);
status = pMemory->ValidateMemoryOffsets(UrbOffsets);
if (!NT_SUCCESS(status)) {
return status;
}
bufferSize = pMemory->GetBufferSize();
if (UrbOffsets != NULL && UrbOffsets->BufferOffset > 0) {
bufferSize -= UrbOffsets->BufferOffset;
}
if (bufferSize < sizeof(_URB_HEADER)) {
status = STATUS_INVALID_PARAMETER;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"UrbMemory %p buffer size, %I64d, smaller then "
"_URB_HEADER, %!STATUS!", UrbMemory,
pMemory->GetBufferSize(), status);
return status;
}
buf.SetMemory(pMemory, UrbOffsets);
status = FxFormatUrbRequest(pFxDriverGlobals,
pUsbPipe,
pRequest,
&buf,
pUsbPipe->GetUrbType(),
pUsbPipe->GetUSBDHandle());
if (NT_SUCCESS(status)) {
FxUsbUrbContext* pContext;
pContext = (FxUsbUrbContext*) pRequest->GetContext();
pContext->SetUsbType(WdfUsbRequestTypePipeUrb);
pContext->m_UsbParameters.Parameters.PipeUrb.Buffer = UrbMemory;
}
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
"Pipe %p, Request %p, Memory %p, status %!STATUS!",
Pipe, Request, UrbMemory, status);
return status;
}
__drv_maxIRQL(DISPATCH_LEVEL)
USBD_PIPE_HANDLE
WDFAPI
WDFEXPORT(WdfUsbTargetPipeWdmGetPipeHandle)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBPIPE UsbPipe
)
/*++
Routine Description:
Returns the underlying WDM USBD pipe handle
Arguments:
UsbPipe - the WDF pipe whose WDM handle will be returned
Return Value:
valid handle value or NULL on error
--*/
{
DDI_ENTRY();
FxUsbPipe* pUsbPipe;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
UsbPipe,
FX_TYPE_IO_TARGET_USB_PIPE,
(PVOID*) &pUsbPipe);
return pUsbPipe->WdmGetPipeHandle();
}
} // extern "C"