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
DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)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