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