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