1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxIoTargetUm.cpp 8 9 Abstract: 10 11 This module implements the IO Target APIs 12 13 Author: 14 15 Environment: 16 17 kernel mode only 18 19 Revision History: 20 21 --*/ 22 23 24 #include "..\..\FxTargetsShared.hpp" 25 26 extern "C" { 27 #if defined(EVENT_TRACING) 28 #include "FxIoTargetUm.tmh" 29 #endif 30 } 31 32 _Must_inspect_result_ 33 NTSTATUS 34 FxIoTarget::InitModeSpecific( 35 __in CfxDeviceBase* Device 36 ) 37 { 38 NTSTATUS status; 39 40 // 41 // FxCREvent can fail in UMDF so it is initialized outside of constuctor 42 // for UMDF. It always succeeds for KMDF so it gets initialized in 43 // event's constructor. 44 // 45 46 status = m_SentIoEvent.Initialize(SynchronizationEvent, FALSE); 47 if (!NT_SUCCESS(status)) { 48 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, 49 TRACINGIOTARGET, 50 "Could not initialize m_SentIoEvent event for " 51 "WFIOTARGET %p, %!STATUS!", 52 GetObjectHandle(), status); 53 return status; 54 } 55 56 status = m_DisposeEventUm.Initialize(); 57 if (!NT_SUCCESS(status)) { 58 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, 59 TRACINGIOTARGET, 60 "Could not initialize m_DisposeEventUm event for " 61 "WFIOTARGET %p, %!STATUS!", 62 GetObjectHandle(), status); 63 return status; 64 } 65 66 return STATUS_SUCCESS; 67 } 68 69 _Must_inspect_result_ 70 NTSTATUS 71 FxIoTarget::FormatIoRequest( 72 __inout FxRequestBase* Request, 73 __in UCHAR MajorCode, 74 __in FxRequestBuffer* IoBuffer, 75 __in_opt PLONGLONG DeviceOffset, 76 __in_opt FxFileObject* FileObject 77 ) 78 { 79 FxIoContext* pContext; 80 NTSTATUS status; 81 ULONG ioLength; 82 FxIrp* irp; 83 PVOID buffer; 84 85 UNREFERENCED_PARAMETER(FileObject); 86 87 ASSERT(MajorCode == IRP_MJ_WRITE || MajorCode == IRP_MJ_READ); 88 89 status = Request->ValidateTarget(this); 90 if (!NT_SUCCESS(status)) { 91 return status; 92 } 93 94 if (Request->HasContextType(FX_RCT_IO)) { 95 pContext = (FxIoContext*) Request->GetContext(); 96 } 97 else { 98 pContext = new(GetDriverGlobals()) FxIoContext(); 99 if (pContext == NULL) { 100 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 101 "could not allocate context for request"); 102 103 return STATUS_INSUFFICIENT_RESOURCES; 104 } 105 106 // 107 // Since we can error out and return, remember the allocation before 108 // we do anything so we can free it later. 109 // 110 Request->SetContext(pContext); 111 } 112 113 // 114 // Save away any references to IFxMemory pointers that are passed 115 // 116 pContext->StoreAndReferenceMemory(IoBuffer); 117 118 // 119 // Setup irp stack 120 // 121 irp = Request->GetSubmitFxIrp(); 122 irp->ClearNextStackLocation(); 123 124 // 125 // copy File object and flags 126 // 127 CopyFileObjectAndFlags(Request); 128 129 irp->SetMajorFunction(MajorCode); 130 pContext->m_MajorFunction = MajorCode; 131 132 ioLength = IoBuffer->GetBufferLength(); 133 134 status = IoBuffer->GetBuffer(&buffer); 135 if (!NT_SUCCESS(status)) { 136 DoTraceLevelMessage( 137 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 138 "Could not retrieve i/o buffer, %!STATUS!", 139 status); 140 goto exit; 141 } 142 143 // 144 // Since we don't support buffer transformations (buffered->Direct->Neither) 145 // we are analogous to "Neither" method in KMDF 146 // in which case we just set the Irp buffer to the buffer that is passed in 147 // 148 if (IRP_MJ_READ == MajorCode) { 149 pContext->SwapIrpBuffer(Request, 150 0, 151 NULL, 152 ioLength, 153 buffer); 154 155 irp->GetIoIrp()->SetReadParametersForNextStackLocation( 156 ioLength, 157 DeviceOffset, 158 0 159 ); 160 } 161 else if (IRP_MJ_WRITE == MajorCode) { 162 pContext->SwapIrpBuffer(Request, 163 ioLength, 164 buffer, 165 0, 166 NULL); 167 irp->GetIoIrp()->SetWriteParametersForNextStackLocation( 168 ioLength, 169 DeviceOffset, 170 0 171 ); 172 } 173 /* 174 else if (WdfRequestQueryInformation == RequestType) 175 { 176 pContext->SwapIrpBuffer(pRequest, 177 0, 178 NULL, 179 ioLength, 180 buffer); 181 } 182 else if (WdfRequestSetInformation == RequestType) 183 { 184 pContext->SwapIrpBuffer(pRequest, 185 ioLength, 186 buffer, 187 0, 188 NULL); 189 } 190 */ 191 else { 192 pContext->SwapIrpBuffer(Request, 0, NULL, 0, NULL); 193 } 194 195 exit: 196 197 if (NT_SUCCESS(status)) { 198 Request->VerifierSetFormatted(); 199 } 200 else { 201 Request->ContextReleaseAndRestore(); 202 } 203 204 return status; 205 } 206 207 _Must_inspect_result_ 208 NTSTATUS 209 FxIoTarget::FormatIoctlRequest( 210 __in FxRequestBase* Request, 211 __in ULONG Ioctl, 212 __in BOOLEAN Internal, 213 __in FxRequestBuffer* InputBuffer, 214 __in FxRequestBuffer* OutputBuffer, 215 __in_opt FxFileObject* FileObject 216 ) 217 { 218 FxIoContext* pContext; 219 NTSTATUS status; 220 ULONG inLength, outLength; 221 FxIrp* irp; 222 PVOID inputBuffer; 223 PVOID outputBuffer; 224 225 UNREFERENCED_PARAMETER(FileObject); 226 227 irp = Request->GetSubmitFxIrp(); 228 229 status = Request->ValidateTarget(this); 230 if (!NT_SUCCESS(status)) { 231 return status; 232 } 233 234 if (Request->HasContextType(FX_RCT_IO)) { 235 pContext = (FxIoContext*) Request->GetContext(); 236 } 237 else { 238 pContext = new(GetDriverGlobals()) FxIoContext(); 239 if (pContext == NULL) { 240 DoTraceLevelMessage( 241 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 242 "Could not allocate context for request"); 243 244 return STATUS_INSUFFICIENT_RESOURCES; 245 } 246 247 Request->SetContext(pContext); 248 } 249 250 inLength = InputBuffer->GetBufferLength(); 251 outLength = OutputBuffer->GetBufferLength(); 252 253 // 254 // Capture irp buffers in context and set driver-provided buffers in the irp 255 // 256 status = InputBuffer->GetBuffer(&inputBuffer); 257 if (!NT_SUCCESS(status)) { 258 DoTraceLevelMessage( 259 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 260 "Could not retrieve input buffer, %!STATUS!", 261 status); 262 goto exit; 263 } 264 265 status = OutputBuffer->GetBuffer(&outputBuffer); 266 if (!NT_SUCCESS(status)) { 267 DoTraceLevelMessage( 268 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, 269 "Could not retrieve output buffer, %!STATUS!", 270 status); 271 goto exit; 272 } 273 274 // 275 // Save away any references to IFxMemory pointers that are passed 276 // 277 pContext->StoreAndReferenceMemory(InputBuffer); 278 pContext->StoreAndReferenceOtherMemory(OutputBuffer); 279 pContext->m_MajorFunction = IRP_MJ_DEVICE_CONTROL; 280 281 // 282 // Format next stack location 283 // 284 irp->ClearNextStackLocation(); 285 irp->SetMajorFunction(IRP_MJ_DEVICE_CONTROL); 286 287 // 288 // copy File object and flags 289 // 290 CopyFileObjectAndFlags(Request); 291 292 irp->GetIoIrp()->SetDeviceIoControlParametersForNextStackLocation( 293 Ioctl, 294 inLength, 295 outLength 296 ); 297 298 pContext->SwapIrpBuffer(Request, 299 InputBuffer->GetBufferLength(), 300 inputBuffer, 301 OutputBuffer->GetBufferLength(), 302 outputBuffer); 303 exit: 304 305 if (NT_SUCCESS(status)) { 306 Request->VerifierSetFormatted(); 307 } 308 else { 309 Request->ContextReleaseAndRestore(); 310 } 311 312 return status;; 313 } 314 315 316