1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxMemoryBufferPreallocatedApi.cpp
8 
9 Abstract:
10 
11     This modules implements the C API's for the FxMemoryBufferPreallocated.
12 
13 Author:
14 
15 
16 Environment:
17 
18     kernel mode only
19 
20 Revision History:
21 
22 --*/
23 
24 #include "coreprivshared.hpp"
25 #include "fxmemorybufferpreallocated.hpp"
26 
27 extern "C" {
28 // #include "FxMemoryBufferPreallocatedAPI.tmh"
29 }
30 
31 extern "C" {
32 
33 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)34 __drv_maxIRQL(DISPATCH_LEVEL)
35 WDFAPI
36 NTSTATUS
37 STDCALL
38 WDFEXPORT(WdfMemoryCreatePreallocated)(
39     __in
40     PWDF_DRIVER_GLOBALS DriverGlobals,
41     __in_opt
42     PWDF_OBJECT_ATTRIBUTES Attributes,
43     __in
44     PVOID Buffer,
45     __in
46     __drv_when(BufferSize == 0, __drv_reportError(BufferSize cannot be zero))
47     size_t BufferSize,
48     __out   //deref cud be null if unable to allocate memory
49     WDFMEMORY* PMemory
50     )/*++
51 
52 Routine Description:
53     External API provided to the client driver to create a WDFMEMORY object
54     whose associated buffers are supplied by the caller.  This API is provided
55     so that the caller does not need to allocate a new buffer every time she
56     wants to pass a WDFMEMORY object to an API which requires it.  It is up to
57     the client driver to free the Buffer and Context at the appropriate time.
58 
59 Arguments:
60     Attributes - Context to associate with the returned WDFMEMORY handle
61 
62     Buffer - Buffer to associate with the returned WDFMEMORY handle
63 
64     BufferSize - Size of Buffer in bytes
65 
66     PMemory  - Handle to be returned to the caller
67 
68 Return Value:
69     STATUS_INVALID_PARAMETER - if required parameters are incorrect
70 
71     STATUS_INSUFFICIENT_RESOURCES - if no resources are available
72 
73     STATUS_SUCCESS  - success
74 
75   --*/
76 {
77     DDI_ENTRY();
78 
79     PFX_DRIVER_GLOBALS pFxDriverGlobals;
80     FxMemoryBufferPreallocated *pBuffer;
81     WDFMEMORY hMemory;
82     NTSTATUS status;
83 
84     pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
85 
86     //
87     // Get the parent's globals if it is present
88     //
89     if (NT_SUCCESS(FxValidateObjectAttributesForParentHandle(pFxDriverGlobals,
90                                                              Attributes))) {
91         FxObject* pParent;
92 
93         FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals,
94                                        Attributes->ParentObject,
95                                        FX_TYPE_OBJECT,
96                                        (PVOID*)&pParent,
97                                        &pFxDriverGlobals);
98     }
99 
100     FxPointerNotNull(pFxDriverGlobals, Buffer);
101     FxPointerNotNull(pFxDriverGlobals, PMemory);
102 
103     *PMemory = NULL;
104 
105     if (BufferSize == 0) {
106         status = STATUS_INVALID_PARAMETER;
107         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
108                             "Zero BufferSize not allowed, %!STATUS!", status);
109         return status;
110     }
111 
112     status = FxValidateObjectAttributes(pFxDriverGlobals, Attributes);
113     if (!NT_SUCCESS(status)) {
114         return status;
115     }
116 
117     pBuffer = new(pFxDriverGlobals, Attributes)
118             FxMemoryBufferPreallocated(pFxDriverGlobals, Buffer, BufferSize);
119 
120     if (pBuffer == NULL) {
121         return STATUS_INSUFFICIENT_RESOURCES;
122     }
123 
124     status = pBuffer->Commit(Attributes, (WDFOBJECT*)&hMemory);
125 
126     if (NT_SUCCESS(status)) {
127         *PMemory = hMemory;
128     }
129     else {
130         pBuffer->DeleteFromFailedCreate();
131     }
132 
133     return status;
134 }
135 
136 _Must_inspect_result_
__drv_maxIRQL(DISPATCH_LEVEL)137 __drv_maxIRQL(DISPATCH_LEVEL)
138 WDFAPI
139 NTSTATUS
140 STDCALL
141 WDFEXPORT(WdfMemoryAssignBuffer)(
142     _In_
143     PWDF_DRIVER_GLOBALS DriverGlobals,
144     _In_
145     WDFMEMORY Memory,
146     _Pre_notnull_ _Pre_writable_byte_size_(BufferSize)
147     PVOID Buffer,
148     _In_
149     __drv_when(BufferSize == 0, __drv_reportError(BufferSize cannot be zero))
150     size_t BufferSize
151     )
152 {
153     DDI_ENTRY();
154 
155     PFX_DRIVER_GLOBALS pFxDriverGlobals;
156     NTSTATUS status;
157     FxMemoryBufferPreallocated* pMemory;
158 
159     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
160                                    Memory,
161                                    FX_TYPE_MEMORY_PREALLOCATED,
162                                    (PVOID*) &pMemory,
163                                    &pFxDriverGlobals);
164 
165     FxPointerNotNull(pFxDriverGlobals, Buffer);
166 
167     if (BufferSize == 0) {
168         status = STATUS_INVALID_PARAMETER;
169         DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
170                             "Zero BufferSize not allowed, %!STATUS!", status);
171         return status;
172     }
173 
174     pMemory->UpdateBuffer(Buffer, BufferSize);
175 
176     return STATUS_SUCCESS;
177 }
178 
179 } // extern "C"
180