- Sync up Mm interface with WinLdr branch (introduce the concept of a memory type...
[reactos.git] / reactos / include / ddk / stdunk.h
1 /*
2 ReactOS Kernel-Mode COM
3 IUnknown implementations
4
5 LICENSE
6 Please see COPYING in the top-level directory for license information.
7
8 AUTHORS
9 Andrew Greenwood
10 */
11
12 #ifndef STDUNK_H
13 #define STDUNK_H
14
15 #define STDUNK_TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
16
17 #include <punknown.h>
18
19 /* ===============================================================
20 INonDelegatingUnknown interface
21 */
22
23 DECLARE_INTERFACE(INonDelegatingUnknown)
24 {
25 STDMETHOD_(NTSTATUS, NonDelegatingQueryInterface)( THIS_
26 IN REFIID,
27 OUT PVOID*) PURE;
28
29 STDMETHOD_(ULONG, NonDelegatingAddRef)( THIS ) PURE;
30 STDMETHOD_(ULONG, NonDelegatingRelease)( THIS ) PURE;
31 };
32
33 typedef INonDelegatingUnknown *PNONDELEGATINGUNKNOWN;
34
35
36 /* ===============================================================
37 CUnknown declaration / definition
38
39 There are 2 variants for this, and I'm not sure if the C
40 version is correct.
41 */
42
43 #ifdef __cplusplus
44
45 class CUnknown : public INonDelegatingUnknown
46 {
47 private :
48 LONG m_ref_count;
49 PUNKNOWN m_outer_unknown;
50
51 public :
52 /* CUnknown */
53 CUnknown(PUNKNOWN pUnknownOuter);
54 virtual ~CUnknown();
55
56 PUNKNOWN GetOuterUnknown()
57 { return m_outer_unknown; }
58
59 /* INonDelegatingUnknown */
60 STDMETHODIMP_(ULONG) NonDelegatingAddRef();
61 STDMETHODIMP_(ULONG) NonDelegatingRelease();
62
63 STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface(
64 REFIID rIID,
65 PVOID* ppVoid);
66 };
67
68 #define DECLARE_STD_UNKNOWN() \
69 STDMETHODIMP_(NTSTATUS) NonDelegatingQueryInterface( \
70 REFIID iid, \
71 PVOID* ppvObject); \
72 \
73 STDMETHODIMP_(NTSTATUS) QueryInterface( \
74 REFIID riid, \
75 void** ppv) \
76 { \
77 return GetOuterUnknown()->QueryInterface(riid, ppv); \
78 } \
79 \
80 STDMETHODIMP_(ULONG) AddRef() \
81 { \
82 return GetOuterUnknown()->AddRef(); \
83 } \
84 \
85 STDMETHODIMP_(ULONG) Release() \
86 { \
87 return GetOuterUnknown()->Release(); \
88 }
89
90 #define DEFINE_STD_CONSTRUCTOR(classname) \
91 classname(PUNKNOWN outer_unknown) \
92 : CUnknown(outer_unknown) \
93 { }
94
95 #else /* Not C++ - this is probably very buggy... */
96
97 STDMETHODCALLTYPE
98 NTSTATUS
99 Unknown_QueryInterface(
100 IUnknown* this,
101 IN REFIID refiid,
102 OUT PVOID* output);
103
104 STDMETHODCALLTYPE
105 ULONG
106 Unknown_AddRef(
107 IUnknown* unknown_this);
108
109 STDMETHODCALLTYPE
110 ULONG
111 Unknown_Release(
112 IUnknown* unknown_this);
113
114 typedef struct CUnknown
115 {
116 union
117 {
118 IUnknown IUnknown;
119 INonDelegatingUnknown INonDelegatingUnknown;
120 };
121
122 LONG m_ref_count;
123 PUNKNOWN m_outer_unknown;
124 } CUnknown;
125
126 #endif /* __cplusplus */
127
128
129
130 #ifdef __cplusplus
131
132
133 /* ===============================================================
134 Construction helpers
135 */
136
137 #define QICAST(typename) \
138 PVOID( (typename) (this) )
139
140 #define QICASTUNKNOWN(typename) \
141 PVOID( PUNKNOWN( (typename) (this) ) )
142
143 #define STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, base) \
144 classname *new_ptr = new(pool_type, tag) classname(outer_unknown); \
145 \
146 if ( ! new_ptr ) \
147 return STATUS_INSUFFICIENT_RESOURCES; \
148 \
149 *unknown = PUNKNOWN((base)(new_ptr)); \
150 (*unknown)->AddRef(); \
151 return STATUS_SUCCESS
152
153 #define STD_CREATE_BODY_WITH_TAG(classname, unknown, outer_unknown, pool_type, tag, base) \
154 STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, tag, PUNKNOWN)
155
156 #define STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, base) \
157 STD_CREATE_BODY_WITH_TAG_(classname, unknown, outer_unknown, pool_type, STDUNK_TAG('r','C','c','P'), base)
158
159 #define STD_CREATE_BODY(classname, unknown, outer_unknown, pool_type) \
160 STD_CREATE_BODY_(classname, unknown, outer_unknown, pool_type, PUNKNOWN)
161
162
163 /* ===============================================================
164 Custom "new" and "delete" C++ operators
165 */
166
167 #ifndef ALLOCATION_OPERATORS_DEFINED
168 #define ALLOCATION_OPERATORS_DEFINED
169
170 inline PVOID
171 KCOM_New(
172 size_t size,
173 POOL_TYPE pool_type,
174 ULONG tag)
175 {
176 PVOID result;
177
178 result = ExAllocatePoolWithTag(pool_type, size, tag);
179
180 if ( result )
181 RtlZeroMemory(result, size);
182
183 return result;
184 }
185
186 inline PVOID
187 operator new (
188 size_t size,
189 POOL_TYPE pool_type)
190 {
191 return KCOM_New(size, pool_type, STDUNK_TAG ('w','N','c','P'));
192 }
193
194 inline PVOID
195 operator new (
196 size_t size,
197 POOL_TYPE pool_type,
198 ULONG tag)
199 {
200 return KCOM_New(size, pool_type, tag);
201 }
202
203 inline void __cdecl
204 operator delete(
205 PVOID ptr)
206 {
207 ExFreePool(ptr);
208 }
209
210 #endif /* ALLOCATION_OPERATORS_DEFINED */
211
212
213 #else /* Being compiled with C */
214
215
216 #endif /* __cplusplus */
217
218 #endif /* include guard */