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