mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 18:24:02 +00:00
863 lines
23 KiB
C++
863 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"
|