ReactOS 0.4.16-dev-320-g3bd9ddc
fxfileobject.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxFileObject.hpp
8
9Abstract:
10
11 This module implements a frameworks managed FileObject
12
13Author:
14
15
16
17Environment:
18
19 Both kernel and user mode
20
21Revision History:
22
23
24--*/
25
26#include "coreprivshared.hpp"
27
28// Tracing support
29extern "C" {
30// #include "FxFileObject.tmh"
31}
32
33//
34// Public constructors
35//
36
37
39 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
40 __in MdFileObject pWdmFileObject,
42 ) :
44{
45 m_FileObject.SetFileObject(pWdmFileObject);
48
49#if (FX_CORE_MODE == FX_CORE_USER_MODE)
52#endif
53
54 //
55 // Cannot be deleted by the device driver
56 //
58}
59
61{
62#if (FX_CORE_MODE == FX_CORE_USER_MODE)
64#endif
65}
66
67//
68// Create the WDFFILEOBJECT and associate it with the WDM PFILE_OBJECT.
69//
75 __in WDF_FILEOBJECT_CLASS FileObjectClass,
76 __in_opt PWDF_OBJECT_ATTRIBUTES pObjectAttributes,
77 __in_opt MdFileObject pWdmFileObject,
78 __deref_out_opt FxFileObject** pFileObject
79 )
80{
83 KIRQL irql;
85
86 PFX_DRIVER_GLOBALS FxDriverGlobals = pDevice->GetDriverGlobals();
87
88 //
89 // Create does require a WDM file obj based on the normalized file obj
90 // class value.
91 //
93
94 //
95 // No FileObject support
96 //
98 if( pFileObject != NULL ) *pFileObject = NULL;
99 return STATUS_SUCCESS;
100 }
101
102 //
103 // If fileobject support was specified, and a NULL
104 // WDM PFILE_OBJECT is supplied, then it's an error
105 //
106 if( pWdmFileObject == NULL ) {
107
108 //
109 // Seems like some filter driver above us sending a create without fileobject.
110 // We support this only if the FileObjectClass class is set to
111 // WdfFileObjectWdfCannotUseFsContexts and device is created to be
112 // exclusive.
113 //
115 pDevice->IsExclusive() ) {
116
117 DO_NOTHING();
118
119 } else {
121 "WdfFileObjectWdfCanUseFsContexts is specified, but the Create "
122 "IRP %p doesn't have a fileObject\n",
123 Irp);
126 }
127
128 }
129
130 // Allocate a new FxFileObject with context
131 pfo = new(pDevice->GetDriverGlobals(), pObjectAttributes)
132 FxFileObject(pDevice->GetDriverGlobals(), pWdmFileObject, pDevice);
133
134 if( pfo == NULL ) {
136 }
137
138 pfo->Initialize(Irp);
139
140 // Assign FxDevice as the parent for the file object
141 Status = pfo->Commit(pObjectAttributes, NULL, pDevice);
142 if( !NT_SUCCESS(Status) ) {
143 pfo->DeleteFromFailedCreate();
144 return Status;
145 }
146
147 //
148 // Place it on the list of FxFileObject's for this FxDevice
149 //
150 pDevice->Lock(&irql);
153
154 //
155 // Set file object context in mode-specific manner
156 //
157 pfo->SetFileObjectContext(pWdmFileObject,
159 Irp,
160 pDevice);
161
162 // FxFileObject* to caller
163 if( pFileObject != NULL ) {
164 *pFileObject = pfo;
165 }
166
167 return STATUS_SUCCESS;
168}
169
170//
171// Destroy (dereference) the WDFFILEOBJECT related to the
172// WDM PFILE_OBJECT according to its FileObjectClass.
173//
174VOID
177 __in WDF_FILEOBJECT_CLASS FileObjectClass,
178 __in_opt MdFileObject pWdmFileObject
179 )
180{
182 PFX_DRIVER_GLOBALS FxDriverGlobals = pDevice->GetDriverGlobals();
184
185 //
186 // Close does require a WDM file obj based on the normalized file obj
187 // class value.
188 //
190
192 return;
193 }
194
195 //
196 // Driver has specified file object support, and we
197 // allocated one at Create, so they must pass one
198 // to close, otherwise it's an error and we will leak
199 // the file object.
200 //
201 MxFileObject wdmFileObject(pWdmFileObject);
202 if( pWdmFileObject == NULL &&
204
205 //
206 // It's likely that IRP_MJ_CREATE had NULL for the Wdm FileObject as well.
207 //
208 // If a driver passes != NULL for Wdm FileObject to create, and NULL to
209 // this routine, a WDF FxFileObject object leak will occur, which will
210 // be reported at driver unload.
211 //
213 "PFILE_OBJECT in close IRP is NULL, *Possible Leak of FxFileObject*\n");
214
216
217 return;
218 }
220 pfo = (FxFileObject*)wdmFileObject.GetFsContext();
221 wdmFileObject.SetFsContext(NULL);
222
223 }
225 pfo = (FxFileObject*)wdmFileObject.GetFsContext2();
226 wdmFileObject.SetFsContext2(NULL);
227 }
228 else {
230 //
231 // We must find the associated FxFileObject from the list
232 // on the device
233 //
235 pDevice,
237 pWdmFileObject,
238 &pfo
239 );
240
241 //
242 // We should find it, unless a different one was passed to IRP_MJ_CLOSE
243 // than to IRP_MJ_CREATE, which is an error.
244 //
245 if (NT_SUCCESS(status) == FALSE || pfo == NULL) {
247 "Could not find WDFFILEOBJECT for PFILE_OBJECT 0x%p",
248 pWdmFileObject);
249
251 "Did a different PFILE_OBJECT get passed to "
252 "IRP_MJ_CLOSE than did to IRP_MJ_CREATE?");
254 }
255 }
256
257 if( pfo != NULL ) {
258 KIRQL irql;
259
260 //
261 // Remove it from the list of FxFileObjects on the FxDevice
262 //
263 pDevice->Lock(&irql);
264 RemoveEntryList(&pfo->m_Link);
266
267 // Delete the file object
268 pfo->DeleteObject();
269 }
270
271 return;
272}
273
274//
275// Return the FxFileObject* for the given WDM PFILE_OBJECT
276//
281 __in WDF_FILEOBJECT_CLASS FileObjectClass,
282 __in_opt MdFileObject pWdmFileObject,
283 __deref_out_opt FxFileObject** ppFxFileObject
284 )
285{
287 PFX_DRIVER_GLOBALS FxDriverGlobals = pDevice->GetDriverGlobals();
289
290 //
291 // Normalize file object class value.
292 //
294
295 //
296 // No FileObject support
297 //
299 *ppFxFileObject = NULL;
300 return STATUS_SUCCESS;
301 }
302
303 if( pWdmFileObject == NULL ) {
304
305 //
306 // Warn if an I/O request has NULL for the WDM PFILE_OBJECT
307 //
308 if ( pDevice->IsExclusive() &&
310 //
311 // We allow a NULL file object iff the device is exclusive and
312 // we have to look up the WDFFILEOBJECT by PFILE_OBJECT value
313 //
314 DO_NOTHING();
315 }
316 else if ( FxIsFileObjectOptional(FileObjectClass) ) {
317 //
318 // Driver told us that it's able to handle this case.
319 //
320 *ppFxFileObject = NULL;
321 return STATUS_SUCCESS;
322 }
323 else {
325 "NULL passed for PFILE_OBJECT when FileObject "
326 "support is requested in an I/O request");
328
329 return STATUS_UNSUCCESSFUL;
330 }
331 }
332
333 //
334 // Depending on the drivers configuration, we can quickly
335 // get the FxFileObject* from FxContext, or FxContext2.
336 //
337 // Some drivers can not touch either of the FxContext(s), and
338 // in that case we must resort to a list or hashtable.
339 //
340 MxFileObject wdmFileObject(pWdmFileObject);
342 pfo = (FxFileObject*)wdmFileObject.GetFsContext();
343 }
345 pfo = (FxFileObject*)wdmFileObject.GetFsContext2();
346 }
347 else {
350 KIRQL irql;
351
352 //
353 // Must look it up from the FxDevice->m_FileObjectListHead.
354 //
355 pfo = NULL;
356
357 pDevice->Lock(&irql);
358
360
361 if(pWdmFileObject == NULL) {
362 //
363 // If the pWdmFileObject is NULL then we will pass the first entry
364 // in the list because the device must be exclusive and there
365 // can be only one fileobject in the list.
366 //
368
370 pfo = f;
371
372 } else {
373
374 while( next != &pDevice->m_FileObjectListHead ) {
376
377 if( f->m_FileObject.GetFileObject()== pWdmFileObject ) {
378 pfo = f;
379 break;
380 }
381
382 next = next->Flink;
383 }
384 }
385
386
387
388
389
390
391
392
393
394
395 if(pfo == NULL
396 && pDevice->IsExclusive()
399
402 pfo = f;
403
405 "The PFILE_OBJECT 0x%p in this request (cleanup/close) "
406 "is different from the one specified in "
407 "create request 0x%p.This is bad!", pWdmFileObject,
408 ((f != NULL) ? f->m_FileObject.GetFileObject(): NULL));
410 "Since this is a serial port device, framework is "
411 "using a workaround to allow this");
412 }
413
415 }
416
417 //
418 // This can happen if a different PFILE_OBJECT is passed to an I/O
419 // request than was presented to IRP_MJ_CREATE
420 //
421 if (pfo == NULL && FxIsFileObjectOptional(FileObjectClass) == FALSE) {
422
424 "Could not locate WDFFILEOBJECT for "
425 "PFILE_OBJECT 0x%p",pWdmFileObject);
426
428 "Did a different PFILE_OBJECT get passed to the "
429 "request than was to IRP_MJ_CREATE?");
430
431
432
433
434
435
436
437
438
439
440 if (FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,9)) {
442 }
443 }
444
445 //
446 // We don't do an extra reference count since the file objects
447 // lifetime is controlled by the IoMgr. When the IRP_MJ_CLOSE
448 // occurs, the reference is released after the optional
449 // driver event callback.
450 //
451
452 *ppFxFileObject = pfo;
453
454 return STATUS_SUCCESS;
455}
456
457VOID
459 VOID
460 )
461{
462 KIRQL irql;
463
464 //
465 // Remove it from the list of FxFileObjects on the FxDevice
466 //
467 m_Device->Lock(&irql);
470
471 // Delete the file object
473}
474
479 )
480/*++
481
482Routine Description:
483 This routine is used to return the pointer to the Object itself.
484
485Arguments:
486 Params - query interface parameters.
487
488Return Value:
489 NTSTATUS
490
491--*/
492
493{
494 switch (Params->Type) {
496 *Params->Object = (FxFileObject*) this;
497 break;
498
500 *Params->Object = (IFxHasCallbacks*) this;
501 break;
502
503 default:
504 return FxNonPagedObject::QueryInterface(Params); // __super call
505 }
506
507 return STATUS_SUCCESS;
508}
509
510VOID
512 __in WDF_EXECUTION_LEVEL* ExecutionLevel,
513 __in WDF_SYNCHRONIZATION_SCOPE* SynchronizationScope
514 )
515/*++
516
517Routine Description:
518 This routine implements the GetConstraints IfxCallback. The caller gets the
519 ExecutionLevel and the SynchronizationScope of the FileObject. The FileObject's
520 SynchronizationScope and ExecutionLevel is strored in the FxPkgGeneral object.
521
522Arguments:
523 ExecutionLevel - (opt) receives the execution level.
524
525 SynchronizationScope - (opt) receives the synchronization scope.
526
527Return Value:
528 None
529
530--*/
531
532{
533 //
534 // Get it from FxPkgGeneral which has the File attributes passed to it at device Creation time.
535 //
536 return GetDevice()->m_PkgGeneral->GetConstraintsHelper(ExecutionLevel, SynchronizationScope);
537}
538
543 )
544/*++
545
546Routine Description:
547 This routine implements the GetCallbackLockPtr IfxCallback. The caller gets the
548 LockObject to be used before calling the driver callbacks.
549
550Arguments:
551 LockObject - receives the lock object.
552
553Return Value:
554 FxCallbackLock *
555
556--*/
557
558{
559 //
560 // Get it from FxPkgGeneral which has the File attributes passed to it at device Creation time.
561 //
562 return GetDevice()->m_PkgGeneral->GetCallbackLockPtrHelper(LockObject);
563}
564
565
LONG NTSTATUS
Definition: precomp.h:26
__inline MxDeviceObject * GetMxDeviceObject(VOID)
Definition: fxdevice.hpp:183
__inline BOOLEAN IsExclusive(VOID)
Definition: fxdevice.hpp:1218
LIST_ENTRY m_FileObjectListHead
Definition: fxdevice.hpp:643
static _Must_inspect_result_ NTSTATUS _CreateFileObject(__in FxDevice *pDevice, __in MdIrp Irp, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt PWDF_OBJECT_ATTRIBUTES pObjectAttributes, __in_opt MdFileObject pWdmFileObject, __deref_out_opt FxFileObject **ppFxFileObject)
LIST_ENTRY m_Link
VOID GetConstraints(__in WDF_EXECUTION_LEVEL *ExecutionLevel, __in WDF_SYNCHRONIZATION_SCOPE *SynchronizationScope)
virtual ~FxFileObject()
VOID DeleteFileObjectFromFailedCreate(VOID)
UNICODE_STRING m_FileName
static _Must_inspect_result_ NTSTATUS _GetFileObjectFromWdm(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject, __deref_out_opt FxFileObject **ppFxFileObject)
static VOID _DestroyFileObject(__in FxDevice *pDevice, __in WDF_FILEOBJECT_CLASS FileObjectClass, __in_opt MdFileObject pWdmFileObject)
PVOID m_PkgContext
MxFileObject m_FileObject
_Must_inspect_result_ FxCallbackLock * GetCallbackLockPtr(__deref_out_opt FxObject **LockObject)
FxFileObject(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in MdFileObject pWdmFileObject, __in FxDevice *Device)
FxFileObject * m_RelatedFileObject
_Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
DEVICE_TYPE GetDeviceType(VOID)
PVOID GetFsContext(VOID)
VOID SetFsContext2(_In_ PVOID Value)
__inline VOID SetFileObject(_In_ MdFileObject FileObject)
Definition: mxfileobject.h:36
VOID SetFsContext(_In_ PVOID Value)
PVOID GetFsContext2(VOID)
_In_ PIRP Irp
Definition: csq.h:116
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __deref_out_opt
Definition: dbghelp.h:29
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
KIRQL irql
Definition: wave.h:1
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
return pList GetDevice()
WDF_FILEOBJECT_CLASS normalizedFileClass
BOOLEAN __inline FxIsFileObjectOptional(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:112
WDF_FILEOBJECT_CLASS __inline FxFileObjectClassNormalize(__in WDF_FILEOBJECT_CLASS FileObjectClass)
Definition: fxdevice.hpp:103
FxVerifierDbgBreakPoint(pFxDriverGlobals)
@ FX_TYPE_FILEOBJECT
Definition: fxtypes.h:71
@ FX_TYPE_IHASCALLBACKS
Definition: fxtypes.h:114
Status
Definition: gdiplustypes.h:25
GLfloat f
Definition: glext.h:7540
#define f
Definition: ke_i.h:83
#define ASSERT(a)
Definition: mode.c:44
#define FILE_DEVICE_SERIAL_PORT
Definition: serial.c:44
#define DO_NOTHING()
Definition: mxgeneral.h:32
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
#define _Must_inspect_result_
Definition: no_sal2.h:62
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
static unsigned __int64 next
Definition: rand_nt.c:6
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ps.c:97
#define LockObject(Object)
Definition: titypes.h:34
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
enum _WDF_FILEOBJECT_CLASS WDF_FILEOBJECT_CLASS
@ WdfFileObjectWdfCanUseFsContext
Definition: wdfdevice.h:461
@ WdfFileObjectNotRequired
Definition: wdfdevice.h:460
@ WdfFileObjectWdfCanUseFsContext2
Definition: wdfdevice.h:462
@ WdfFileObjectWdfCannotUseFsContexts
Definition: wdfdevice.h:463
WDF_EXTERN_C_START enum _WDF_EXECUTION_LEVEL WDF_EXECUTION_LEVEL
enum _WDF_SYNCHRONIZATION_SCOPE WDF_SYNCHRONIZATION_SCOPE
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
_In_opt_ FONTOBJ * pfo
Definition: winddi.h:3603
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define SAFE_RELEASE(p)