1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxCommonBufferAPI.cpp 8 9 Abstract: 10 11 Base for WDF CommonBuffer APIs 12 13 Environment: 14 15 Kernel mode only. 16 17 Notes: 18 19 20 Revision History: 21 22 --*/ 23 24 #include "fxdmapch.hpp" 25 26 extern "C" { 27 // #include "FxCommonBufferAPI.tmh" 28 } 29 30 // 31 // Extern "C" the entire file 32 // 33 extern "C" { 34 35 _Must_inspect_result_ 36 __drv_maxIRQL(PASSIVE_LEVEL) 37 NTSTATUS 38 STDCALL 39 WDFEXPORT(WdfCommonBufferCreate)( 40 __in 41 PWDF_DRIVER_GLOBALS DriverGlobals, 42 __in 43 WDFDMAENABLER DmaEnabler, 44 __in 45 __drv_when(Length == 0, __drv_reportError(Length cannot be zero)) 46 size_t Length, 47 __in_opt 48 WDF_OBJECT_ATTRIBUTES * Attributes, 49 __out 50 WDFCOMMONBUFFER * CommonBufferHandle 51 ) 52 { 53 FxCommonBuffer * pComBuf; 54 FxDmaEnabler * pDmaEnabler; 55 NTSTATUS status; 56 WDFOBJECT handle; 57 PFX_DRIVER_GLOBALS pFxDriverGlobals; 58 59 // 60 // Get validate DmaEnabler handle 61 // 62 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 63 DmaEnabler, 64 FX_TYPE_DMA_ENABLER, 65 (PVOID *) &pDmaEnabler, 66 &pFxDriverGlobals); 67 68 FxPointerNotNull(pFxDriverGlobals, CommonBufferHandle); 69 70 *CommonBufferHandle = NULL; 71 72 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 73 if (!NT_SUCCESS(status)) { 74 return status; 75 } 76 77 // 78 // Basic parameter validation 79 // 80 if (Length == 0) { 81 status = STATUS_INVALID_PARAMETER; 82 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, 83 "Length is 0, %!STATUS!", status); 84 return status; 85 } 86 87 status = FxValidateObjectAttributes(pFxDriverGlobals, 88 Attributes, 89 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED 90 ); 91 if (!NT_SUCCESS(status)) { 92 return status; 93 } 94 95 // 96 // Create a new CommonBuffer object 97 // 98 pComBuf = new(pFxDriverGlobals, Attributes) 99 FxCommonBuffer(pFxDriverGlobals, pDmaEnabler); 100 101 if (pComBuf == NULL) { 102 status = STATUS_INSUFFICIENT_RESOURCES; 103 104 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, 105 "Could not allocate memory for a WDFCOMMONBUFFER, " 106 "%!STATUS!", status); 107 return status; 108 } 109 110 // 111 // Assign this FxCommonBuffer to its parent FxDmaEnabler object. 112 // 113 status = pComBuf->Commit(Attributes, (WDFOBJECT*)&handle, pDmaEnabler); 114 115 if (NT_SUCCESS(status)) { 116 // 117 // Ok: now allocate a CommonBuffer via this DmaEnabler 118 // 119 status = pComBuf->AllocateCommonBuffer( Length ); 120 } 121 122 if (NT_SUCCESS(status)) { 123 // 124 // Only return a valid handle on success. 125 // 126 *CommonBufferHandle = (WDFCOMMONBUFFER) handle; 127 } 128 else { 129 pComBuf->DeleteFromFailedCreate(); 130 } 131 132 return status; 133 } 134 135 _Must_inspect_result_ 136 __drv_maxIRQL(PASSIVE_LEVEL) 137 NTSTATUS 138 STDCALL 139 WDFEXPORT(WdfCommonBufferCreateWithConfig)( 140 __in 141 PWDF_DRIVER_GLOBALS DriverGlobals, 142 __in 143 WDFDMAENABLER DmaEnabler, 144 __in 145 __drv_when(Length == 0, __drv_reportError(Length cannot be zero)) 146 size_t Length, 147 __in 148 PWDF_COMMON_BUFFER_CONFIG Config, 149 __in_opt 150 WDF_OBJECT_ATTRIBUTES * Attributes, 151 __out 152 WDFCOMMONBUFFER * CommonBufferHandle 153 ) 154 { 155 FxCommonBuffer * pComBuf; 156 FxDmaEnabler * pDmaEnabler; 157 NTSTATUS status; 158 WDFOBJECT handle; 159 PFX_DRIVER_GLOBALS pFxDriverGlobals; 160 161 // 162 // Get validate DmaEnabler handle 163 // 164 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 165 DmaEnabler, 166 FX_TYPE_DMA_ENABLER, 167 (PVOID *) &pDmaEnabler, 168 &pFxDriverGlobals); 169 170 // 171 // Basic parameter validation 172 // 173 FxPointerNotNull(pFxDriverGlobals, Config); 174 175 if (Config->Size != sizeof(WDF_COMMON_BUFFER_CONFIG)) { 176 status = STATUS_INFO_LENGTH_MISMATCH; 177 178 DoTraceLevelMessage( 179 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, 180 "WDF_COMMON_BUFFER_CONFIG Size 0x%x, expected 0x%x, %!STATUS!", 181 Config->Size, sizeof(WDF_COMMON_BUFFER_CONFIG), status); 182 183 return status; 184 } 185 186 FxPointerNotNull(pFxDriverGlobals, CommonBufferHandle); 187 188 *CommonBufferHandle = NULL; 189 190 status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 191 if (!NT_SUCCESS(status)) { 192 return status; 193 } 194 195 if (Length == 0) { 196 status = STATUS_INVALID_PARAMETER; 197 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, 198 "Length is 0, %!STATUS!", status); 199 return status; 200 } 201 202 status = FxValidateObjectAttributes(pFxDriverGlobals, 203 Attributes, 204 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED 205 ); 206 if (!NT_SUCCESS(status)) { 207 return status; 208 } 209 210 pComBuf = new(pFxDriverGlobals, Attributes) 211 FxCommonBuffer(pFxDriverGlobals, pDmaEnabler); 212 213 if (pComBuf == NULL) { 214 status = STATUS_INSUFFICIENT_RESOURCES; 215 216 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDMA, 217 "Could not allocate memory for a WDFCOMMONBUFFER, " 218 "%!STATUS!", status); 219 return status; 220 } 221 222 // 223 // Assign this FxCommonBuffer to its parent FxDmaEnabler object. 224 // 225 status = pComBuf->Commit(Attributes, (WDFOBJECT*)&handle, pDmaEnabler); 226 227 if (NT_SUCCESS(status)) { 228 // 229 // Set the alignment value before calling AllocateCommonBuffer. 230 // 231 pComBuf->SetAlignment(Config->AlignmentRequirement); 232 status = pComBuf->AllocateCommonBuffer( Length ); 233 } 234 235 if (NT_SUCCESS(status)) { 236 // 237 // Only return a valid handle on success. 238 // 239 *CommonBufferHandle = (WDFCOMMONBUFFER) handle; 240 } 241 else { 242 pComBuf->DeleteFromFailedCreate(); 243 } 244 245 return status; 246 } 247 248 __drv_maxIRQL(DISPATCH_LEVEL) 249 PVOID 250 STDCALL 251 WDFEXPORT(WdfCommonBufferGetAlignedVirtualAddress)( 252 __in 253 PWDF_DRIVER_GLOBALS DriverGlobals, 254 __in 255 WDFCOMMONBUFFER CommonBuffer 256 ) 257 { 258 FxCommonBuffer * pComBuf; 259 260 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 261 CommonBuffer, 262 FX_TYPE_COMMON_BUFFER, 263 (PVOID *) &pComBuf); 264 265 return pComBuf->GetAlignedVirtualAddress(); 266 } 267 268 __drv_maxIRQL(DISPATCH_LEVEL) 269 PHYSICAL_ADDRESS 270 STDCALL 271 WDFEXPORT(WdfCommonBufferGetAlignedLogicalAddress)( 272 __in 273 PWDF_DRIVER_GLOBALS DriverGlobals, 274 __in 275 WDFCOMMONBUFFER CommonBuffer 276 ) 277 { 278 FxCommonBuffer * pComBuf; 279 280 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 281 CommonBuffer, 282 FX_TYPE_COMMON_BUFFER, 283 (PVOID *) &pComBuf); 284 285 return pComBuf->GetAlignedLogicalAddress(); 286 } 287 288 __drv_maxIRQL(DISPATCH_LEVEL) 289 size_t 290 STDCALL 291 WDFEXPORT(WdfCommonBufferGetLength)( 292 __in 293 PWDF_DRIVER_GLOBALS DriverGlobals, 294 __in 295 WDFCOMMONBUFFER CommonBuffer 296 ) 297 { 298 FxCommonBuffer * pComBuf; 299 300 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 301 CommonBuffer, 302 FX_TYPE_COMMON_BUFFER, 303 (PVOID *) &pComBuf); 304 305 return pComBuf->GetLength(); 306 } 307 308 } // extern "C" 309