1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxRequestOutputBuffer.cpp 8 9 Abstract: 10 11 This module implements class representing the output buffer in an FxRequest 12 13 Author: 14 15 16 17 Environment: 18 19 Both kernel and user mode 20 21 Revision History: 22 23 24 25 26 --*/ 27 28 #include "coreprivshared.hpp" 29 30 // Tracing support 31 extern "C" { 32 // #include "FxRequestOutputBuffer.tmh" 33 } 34 35 PVOID 36 FxRequestOutputBuffer::GetBuffer( 37 VOID 38 ) 39 /*++ 40 41 Routine Description: 42 Returns the output buffer that has been cached away by the call to SetBuffer() 43 44 Arguments: 45 None 46 47 Return Value: 48 Valid memory or NULL on error 49 50 --*/ 51 { 52 FxIrp* irp = GetRequest()->GetFxIrp(); 53 54 ASSERT(irp->GetMajorFunction() == IRP_MJ_DEVICE_CONTROL || 55 irp->GetMajorFunction() == IRP_MJ_INTERNAL_DEVICE_CONTROL); 56 57 switch (irp->GetParameterIoctlCodeBufferMethod()) { 58 case METHOD_BUFFERED: 59 // 60 // For buffered ioctls, input and output buffer pointers are same. 61 // 62 return m_Buffer; 63 64 case METHOD_IN_DIRECT: 65 case METHOD_OUT_DIRECT: 66 // 67 // FxRequest::GetDeviceControlOutputMemoryObject has already called 68 // MmGetSystemAddressForMdlSafe and returned success, so we know that 69 // we can safely call MmGetSystemAddressForMdlSafe again to get a 70 // valid VA pointer. 71 // 72 return Mx::MxGetSystemAddressForMdlSafe(m_Mdl, NormalPagePriority); 73 74 case METHOD_NEITHER: 75 return m_Buffer; 76 77 default: 78 ASSERT(FALSE); 79 return NULL; 80 } 81 } 82 83 size_t 84 FxRequestOutputBuffer::GetBufferSize( 85 VOID 86 ) 87 /*++ 88 89 Routine Description: 90 Returns the size of the buffer returned by GetBuffer() 91 92 Arguments: 93 None 94 95 Return Value: 96 Buffer length or 0 on error 97 98 --*/ 99 { 100 FxIrp* irp = GetRequest()->GetFxIrp(); 101 102 ASSERT(irp->GetMajorFunction() == IRP_MJ_DEVICE_CONTROL || 103 irp->GetMajorFunction() == IRP_MJ_INTERNAL_DEVICE_CONTROL); 104 105 return irp->GetParameterIoctlOutputBufferLength(); 106 } 107 108 _Must_inspect_result_ 109 PMDL 110 FxRequestOutputBuffer::GetMdl( 111 VOID 112 ) 113 /*++ 114 115 Routine Description: 116 Returns the PMDL from the irp if one exists, otherwise NULL 117 118 Arguments: 119 None 120 121 Return Value: 122 a valid PMDL or NULL (not an error condition) 123 124 --*/ 125 { 126 FxIrp* irp = GetRequest()->GetFxIrp(); 127 128 ASSERT(irp->GetMajorFunction() == IRP_MJ_DEVICE_CONTROL || 129 irp->GetMajorFunction() == IRP_MJ_INTERNAL_DEVICE_CONTROL); 130 131 switch (irp->GetParameterIoctlCodeBufferMethod()) { 132 case METHOD_IN_DIRECT: 133 case METHOD_OUT_DIRECT: 134 return m_Mdl; 135 136 default: 137 return NULL; 138 } 139 } 140 141 WDFMEMORY 142 FxRequestOutputBuffer::GetHandle( 143 VOID 144 ) 145 /*++ 146 147 Routine Description: 148 Returns the handle that will represent this object to the driver writer. 149 150 Arguments: 151 None 152 153 Return Value: 154 Valid WDF handle 155 156 --*/ 157 { 158 return GetRequest()->GetMemoryHandle( 159 FIELD_OFFSET(FxRequest, m_OutputBufferOffset)); 160 } 161 162 USHORT 163 FxRequestOutputBuffer::GetFlags( 164 VOID 165 ) 166 /*++ 167 168 Routine Description: 169 Returns the flags associated with this buffer. This currently only includes 170 whether the buffer is read only or not 171 172 Arguments: 173 None 174 175 Return Value: 176 flags from IFxMemoryFlags 177 178 --*/ 179 { 180 FxIrp* irp = GetRequest()->GetFxIrp(); 181 182 ASSERT(irp->GetMajorFunction() == IRP_MJ_DEVICE_CONTROL || 183 irp->GetMajorFunction() == IRP_MJ_INTERNAL_DEVICE_CONTROL); 184 185 switch (irp->GetParameterIoctlCodeBufferMethod()) { 186 case METHOD_IN_DIRECT: 187 return IFxMemoryFlagReadOnly; 188 189 case METHOD_BUFFERED: 190 case METHOD_OUT_DIRECT: 191 case METHOD_NEITHER: // since it is neither, we can't tell, so leave it as 0 192 default: 193 return 0; 194 } 195 } 196 197 PFX_DRIVER_GLOBALS 198 FxRequestOutputBuffer::GetDriverGlobals( 199 VOID 200 ) 201 /*++ 202 203 Routine Description: 204 Returns the driver globals 205 206 Arguments: 207 none 208 209 Return Value: 210 Driver globals pointer 211 212 --*/ 213 { 214 return GetRequest()->GetDriverGlobals(); 215 } 216 217 ULONG 218 FxRequestOutputBuffer::AddRef( 219 __in PVOID Tag, 220 __in LONG Line, 221 __in_opt PSTR File 222 ) 223 /*++ 224 225 Routine Description: 226 Adds an irp reference to the owning FxRequest. This object does not maintain 227 its own reference count. A request cannot be completed with outstanding 228 irp references. 229 230 Arguments: 231 Tag - the tag to use to track the reference 232 233 Line - The line number of the caller 234 235 File - the file name of the caller 236 237 Return Value: 238 current reference count 239 240 --*/ 241 { 242 UNREFERENCED_PARAMETER(Tag); 243 UNREFERENCED_PARAMETER(Line); 244 UNREFERENCED_PARAMETER(File); 245 246 GetRequest()->AddIrpReference(); 247 248 return 2; 249 } 250 251 ULONG 252 FxRequestOutputBuffer::Release( 253 __in PVOID Tag, 254 __in LONG Line, 255 __in_opt PSTR File 256 ) 257 /*++ 258 259 Routine Description: 260 Removes an irp reference to the owning FxRequest. This object does not maintain 261 its own reference count. A request cannot be completed with outstanding 262 irp references. 263 264 Arguments: 265 Tag - the tag to use to track the release 266 267 Line - The line number of the caller 268 269 File - the file name of the caller 270 271 Return Value: 272 current reference count 273 274 --*/ 275 { 276 UNREFERENCED_PARAMETER(Tag); 277 UNREFERENCED_PARAMETER(Line); 278 UNREFERENCED_PARAMETER(File); 279 280 GetRequest()->ReleaseIrpReference(); 281 282 return 1; 283 } 284 285 FxRequest* 286 FxRequestOutputBuffer::GetRequest( 287 VOID 288 ) 289 /*++ 290 291 Routine Description: 292 Return the owning FxRequest based on this object's address 293 294 Arguments: 295 None 296 297 Return Value: 298 owning FxRequest 299 300 --*/ 301 { 302 return CONTAINING_RECORD(this, FxRequest, m_OutputBuffer); 303 } 304 305 VOID 306 FxRequestOutputBuffer::Delete( 307 VOID 308 ) 309 /*++ 310 311 Routine Description: 312 Attempt to delete this interface. Since this is an embedded object, it 313 cannot be deleted. Since this function is only called internally, the 314 internal caller knows if the IFxMemory is deletable because the internal 315 caller allocated the IFxMemory to begin with. 316 317 Arguments: 318 None 319 320 Return Value: 321 None 322 323 --*/ 324 { 325 // this function should never be called 326 ASSERT(FALSE); 327 } 328