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_
__drv_maxIRQL(PASSIVE_LEVEL)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_
__drv_maxIRQL(PASSIVE_LEVEL)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
__drv_maxIRQL(DISPATCH_LEVEL)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
__drv_maxIRQL(DISPATCH_LEVEL)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
__drv_maxIRQL(DISPATCH_LEVEL)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