mirror of
https://github.com/reactos/reactos.git
synced 2025-03-10 10:14:44 +00:00
316 lines
8 KiB
C++
316 lines
8 KiB
C++
![]() |
/*++
|
||
|
|
||
|
Copyright (c) Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
FxIoTargetUm.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements the IO Target APIs
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
kernel mode only
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "..\..\FxTargetsShared.hpp"
|
||
|
|
||
|
extern "C" {
|
||
|
#if defined(EVENT_TRACING)
|
||
|
#include "FxIoTargetUm.tmh"
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
_Must_inspect_result_
|
||
|
NTSTATUS
|
||
|
FxIoTarget::InitModeSpecific(
|
||
|
__in CfxDeviceBase* Device
|
||
|
)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
|
||
|
//
|
||
|
// FxCREvent can fail in UMDF so it is initialized outside of constuctor
|
||
|
// for UMDF. It always succeeds for KMDF so it gets initialized in
|
||
|
// event's constructor.
|
||
|
//
|
||
|
|
||
|
status = m_SentIoEvent.Initialize(SynchronizationEvent, FALSE);
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR,
|
||
|
TRACINGIOTARGET,
|
||
|
"Could not initialize m_SentIoEvent event for "
|
||
|
"WFIOTARGET %p, %!STATUS!",
|
||
|
GetObjectHandle(), status);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
status = m_DisposeEventUm.Initialize();
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR,
|
||
|
TRACINGIOTARGET,
|
||
|
"Could not initialize m_DisposeEventUm event for "
|
||
|
"WFIOTARGET %p, %!STATUS!",
|
||
|
GetObjectHandle(), status);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
_Must_inspect_result_
|
||
|
NTSTATUS
|
||
|
FxIoTarget::FormatIoRequest(
|
||
|
__inout FxRequestBase* Request,
|
||
|
__in UCHAR MajorCode,
|
||
|
__in FxRequestBuffer* IoBuffer,
|
||
|
__in_opt PLONGLONG DeviceOffset,
|
||
|
__in_opt FxFileObject* FileObject
|
||
|
)
|
||
|
{
|
||
|
FxIoContext* pContext;
|
||
|
NTSTATUS status;
|
||
|
ULONG ioLength;
|
||
|
FxIrp* irp;
|
||
|
PVOID buffer;
|
||
|
|
||
|
UNREFERENCED_PARAMETER(FileObject);
|
||
|
|
||
|
ASSERT(MajorCode == IRP_MJ_WRITE || MajorCode == IRP_MJ_READ);
|
||
|
|
||
|
status = Request->ValidateTarget(this);
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
if (Request->HasContextType(FX_RCT_IO)) {
|
||
|
pContext = (FxIoContext*) Request->GetContext();
|
||
|
}
|
||
|
else {
|
||
|
pContext = new(GetDriverGlobals()) FxIoContext();
|
||
|
if (pContext == NULL) {
|
||
|
DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
||
|
"could not allocate context for request");
|
||
|
|
||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Since we can error out and return, remember the allocation before
|
||
|
// we do anything so we can free it later.
|
||
|
//
|
||
|
Request->SetContext(pContext);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save away any references to IFxMemory pointers that are passed
|
||
|
//
|
||
|
pContext->StoreAndReferenceMemory(IoBuffer);
|
||
|
|
||
|
//
|
||
|
// Setup irp stack
|
||
|
//
|
||
|
irp = Request->GetSubmitFxIrp();
|
||
|
irp->ClearNextStackLocation();
|
||
|
|
||
|
//
|
||
|
// copy File object and flags
|
||
|
//
|
||
|
CopyFileObjectAndFlags(Request);
|
||
|
|
||
|
irp->SetMajorFunction(MajorCode);
|
||
|
pContext->m_MajorFunction = MajorCode;
|
||
|
|
||
|
ioLength = IoBuffer->GetBufferLength();
|
||
|
|
||
|
status = IoBuffer->GetBuffer(&buffer);
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
DoTraceLevelMessage(
|
||
|
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
||
|
"Could not retrieve i/o buffer, %!STATUS!",
|
||
|
status);
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Since we don't support buffer transformations (buffered->Direct->Neither)
|
||
|
// we are analogous to "Neither" method in KMDF
|
||
|
// in which case we just set the Irp buffer to the buffer that is passed in
|
||
|
//
|
||
|
if (IRP_MJ_READ == MajorCode) {
|
||
|
pContext->SwapIrpBuffer(Request,
|
||
|
0,
|
||
|
NULL,
|
||
|
ioLength,
|
||
|
buffer);
|
||
|
|
||
|
irp->GetIoIrp()->SetReadParametersForNextStackLocation(
|
||
|
ioLength,
|
||
|
DeviceOffset,
|
||
|
0
|
||
|
);
|
||
|
}
|
||
|
else if (IRP_MJ_WRITE == MajorCode) {
|
||
|
pContext->SwapIrpBuffer(Request,
|
||
|
ioLength,
|
||
|
buffer,
|
||
|
0,
|
||
|
NULL);
|
||
|
irp->GetIoIrp()->SetWriteParametersForNextStackLocation(
|
||
|
ioLength,
|
||
|
DeviceOffset,
|
||
|
0
|
||
|
);
|
||
|
}
|
||
|
/*
|
||
|
else if (WdfRequestQueryInformation == RequestType)
|
||
|
{
|
||
|
pContext->SwapIrpBuffer(pRequest,
|
||
|
0,
|
||
|
NULL,
|
||
|
ioLength,
|
||
|
buffer);
|
||
|
}
|
||
|
else if (WdfRequestSetInformation == RequestType)
|
||
|
{
|
||
|
pContext->SwapIrpBuffer(pRequest,
|
||
|
ioLength,
|
||
|
buffer,
|
||
|
0,
|
||
|
NULL);
|
||
|
}
|
||
|
*/
|
||
|
else {
|
||
|
pContext->SwapIrpBuffer(Request, 0, NULL, 0, NULL);
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
Request->VerifierSetFormatted();
|
||
|
}
|
||
|
else {
|
||
|
Request->ContextReleaseAndRestore();
|
||
|
}
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
_Must_inspect_result_
|
||
|
NTSTATUS
|
||
|
FxIoTarget::FormatIoctlRequest(
|
||
|
__in FxRequestBase* Request,
|
||
|
__in ULONG Ioctl,
|
||
|
__in BOOLEAN Internal,
|
||
|
__in FxRequestBuffer* InputBuffer,
|
||
|
__in FxRequestBuffer* OutputBuffer,
|
||
|
__in_opt FxFileObject* FileObject
|
||
|
)
|
||
|
{
|
||
|
FxIoContext* pContext;
|
||
|
NTSTATUS status;
|
||
|
ULONG inLength, outLength;
|
||
|
FxIrp* irp;
|
||
|
PVOID inputBuffer;
|
||
|
PVOID outputBuffer;
|
||
|
|
||
|
UNREFERENCED_PARAMETER(FileObject);
|
||
|
|
||
|
irp = Request->GetSubmitFxIrp();
|
||
|
|
||
|
status = Request->ValidateTarget(this);
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
if (Request->HasContextType(FX_RCT_IO)) {
|
||
|
pContext = (FxIoContext*) Request->GetContext();
|
||
|
}
|
||
|
else {
|
||
|
pContext = new(GetDriverGlobals()) FxIoContext();
|
||
|
if (pContext == NULL) {
|
||
|
DoTraceLevelMessage(
|
||
|
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
||
|
"Could not allocate context for request");
|
||
|
|
||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||
|
}
|
||
|
|
||
|
Request->SetContext(pContext);
|
||
|
}
|
||
|
|
||
|
inLength = InputBuffer->GetBufferLength();
|
||
|
outLength = OutputBuffer->GetBufferLength();
|
||
|
|
||
|
//
|
||
|
// Capture irp buffers in context and set driver-provided buffers in the irp
|
||
|
//
|
||
|
status = InputBuffer->GetBuffer(&inputBuffer);
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
DoTraceLevelMessage(
|
||
|
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
||
|
"Could not retrieve input buffer, %!STATUS!",
|
||
|
status);
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
status = OutputBuffer->GetBuffer(&outputBuffer);
|
||
|
if (!NT_SUCCESS(status)) {
|
||
|
DoTraceLevelMessage(
|
||
|
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
||
|
"Could not retrieve output buffer, %!STATUS!",
|
||
|
status);
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save away any references to IFxMemory pointers that are passed
|
||
|
//
|
||
|
pContext->StoreAndReferenceMemory(InputBuffer);
|
||
|
pContext->StoreAndReferenceOtherMemory(OutputBuffer);
|
||
|
pContext->m_MajorFunction = IRP_MJ_DEVICE_CONTROL;
|
||
|
|
||
|
//
|
||
|
// Format next stack location
|
||
|
//
|
||
|
irp->ClearNextStackLocation();
|
||
|
irp->SetMajorFunction(IRP_MJ_DEVICE_CONTROL);
|
||
|
|
||
|
//
|
||
|
// copy File object and flags
|
||
|
//
|
||
|
CopyFileObjectAndFlags(Request);
|
||
|
|
||
|
irp->GetIoIrp()->SetDeviceIoControlParametersForNextStackLocation(
|
||
|
Ioctl,
|
||
|
inLength,
|
||
|
outLength
|
||
|
);
|
||
|
|
||
|
pContext->SwapIrpBuffer(Request,
|
||
|
InputBuffer->GetBufferLength(),
|
||
|
inputBuffer,
|
||
|
OutputBuffer->GetBufferLength(),
|
||
|
outputBuffer);
|
||
|
exit:
|
||
|
|
||
|
if (NT_SUCCESS(status)) {
|
||
|
Request->VerifierSetFormatted();
|
||
|
}
|
||
|
else {
|
||
|
Request->ContextReleaseAndRestore();
|
||
|
}
|
||
|
|
||
|
return status;;
|
||
|
}
|
||
|
|
||
|
|