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