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