1 2 /*++ 3 4 Copyright (c) Microsoft Corporation 5 6 Module Name: 7 8 FxSyncRequest.hpp 9 10 Abstract: 11 12 FxSyncRequest is meant to be a completely stack based structure. This 13 allows synchronous functions to not have to allocate an FxRequest for 14 something that only lives for the lifetime of the function call. 15 Additionally, this object can substitute a WDFREQUEST for itself when making 16 synchronous calls. This allows the driver writer to pass a WDFREQUEST to a 17 synchronous DDI and be able to cancel it on another thread later. 18 19 To overcome the initial reference count that is associated upon request, the 20 destructor releases the initial reference and SelfDestruct does nothing 21 because there is no memory to free. 22 23 FxSyncRequest derives from FxRequestBase as protected so that it cannot be 24 used as a FxRequestBase directly. Instead, m_TrueRequest should be used. 25 m_TrueRequest is either this object itself or the WDFREQUEST, as set by 26 SetRequestHandle. 27 28 Author: 29 30 31 32 Environment: 33 34 kernel mode only 35 36 Revision History: 37 38 --*/ 39 40 #ifndef _FXSYNCREQUEST_H_ 41 #define _FXSYNCREQUEST_H_ 42 43 class DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) FxSyncRequest : protected FxRequestBase { 44 45 public: 46 // Create a sync request that allocates its own PIRP 47 FxSyncRequest( 48 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 49 __in_opt FxRequestContext* Context, 50 __in_opt WDFREQUEST Request = NULL 51 ); 52 53 ~FxSyncRequest(); 54 55 // 56 // FxObject overrides 57 // 58 VOID 59 SelfDestruct( 60 VOID 61 ); 62 63 protected: 64 PVOID 65 operator new( 66 __in size_t Size 67 ) 68 { 69 UNREFERENCED_PARAMETER(Size); 70 71 ASSERTMSG("FxSyncRequest::operator new called, should only be" 72 " declared on the stack\n", FALSE); 73 74 return (PVOID)1; 75 } 76 77 public: 78 79 NTSTATUS 80 Initialize( 81 VOID 82 ) 83 { 84 NTSTATUS status = STATUS_SUCCESS; 85 86 #if (FX_CORE_MODE == FX_CORE_USER_MODE) 87 // 88 // FxCrEvent initialization can fail in UMDF so check for status. 89 // 90 status = m_DestroyedEvent.Initialize(); 91 if (!NT_SUCCESS(status)) { 92 return status; 93 } 94 #else 95 UNREFERENCED_PARAMETER(status); 96 DO_NOTHING(); 97 #endif 98 return STATUS_SUCCESS; 99 } 100 101 // 102 // Since this object can be sitting on a list which is access by another 103 // thread and that thread will expect lifetime semantics from AddRef and 104 // Release, we need to hold up destruction of the object until all 105 // references are released. This event will be set when the last reference 106 // is dropped. 107 // 108 FxCREvent m_DestroyedEvent; 109 110 // 111 // By default, this will point to this object. If AssignRequestHandle is 112 // called, it will point to the underlying object for that handle. Since 113 // this object derives from FxRequestBase as protected, this field is how 114 // the object is used as an FxRequestBase* pointer. 115 // 116 FxRequestBase* m_TrueRequest; 117 118 BOOLEAN m_ClearContextOnDestroy; 119 }; 120 121 #endif // _FXSYNCREQUEST_H_ 122