mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
[SDK][WDFLDR] Add kmdf loader driver [SDK][WDF] Add kmdf drver init static library [SDK][WDF] Modify kmdf driver for working with wdfldr driver [SDK][CDROM] Cdrom driver dynamically linking with kmdf [SDK][WDF] Add kmdfdriver module type [SDK][WDF][USBDEX][NTOSKRNL_VISTA] Fully enable KMDF [KMDF][WDFLDR][WDF01000] Fix Windows 10 Compatibility WDFLDR and WDF01000 [WDF01000] NO_KERNEL_LIST_ENTRY_CHECKS for wdf01000 3rd party code This PR is an accumulation of three peoples work, with the goal of the trying to get WDF to work like it should. This has been tested in combination with some extra NT6+ ntoskrnl against multiple drivers. --------- Co-authored-by: Max Korostil <[email protected]> Co-authored-by: Victor Perevertkin <[email protected]> Co-authored-by: Adam Słaboń <[email protected]> Co-authored-by: Hermès BÉLUSCA - MAÏTO <[email protected]>
882 lines
24 KiB
C++
882 lines
24 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" {
|
|
#if defined(EVENT_TRACING)
|
|
#include "FxUsbPipeAPI.tmh"
|
|
#endif
|
|
}
|
|
|
|
//
|
|
// extern "C" the whole file since we are exporting the APIs by name
|
|
//
|
|
extern "C" {
|
|
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
VOID
|
|
WDFAPI
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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
|
|
NTAPI
|
|
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"
|