- Implement CBaseUnknown class functions in C!
[reactos.git] / reactos / drivers / ksfilter / ks / unknown.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/topoology.c
5 * PURPOSE: KS CBaseUnknown functions
6 * PROGRAMMER: Johannes Anderwald
7 * KJK::Hyperion
8 */
9
10
11 #include "priv.h"
12
13 #ifdef _X86_
14 #define KS_DECL_CXX(RET_) extern RET_ __fastcall
15 #define KS_THIS(CLASS_) CLASS_ * This, void * dummy_
16 #else
17 #define KS_DECL_CXX(RET_) extern RET_ __cdecl
18 #define KS_THIS(CLASS_) CLASS_ * This
19 #endif
20
21 typedef struct
22 {
23 INonDelegatedUnknownVtbl *lpVtbl;
24 IIndirectedUnknownVtbl *lpVtblIndirectedUnknown;
25
26 LONG m_RefCount;
27
28 BOOLEAN m_UsingClassId;
29 CLSID m_ClassId;
30 IUnknown* m_UnknownOuter;
31
32 }IBaseUnknownImpl;
33
34
35
36 NTSTATUS
37 NTAPI
38 INonDelegatedUnknown_fnQueryInterface(
39 INonDelegatedUnknown * iface,
40 IN REFIID refiid,
41 OUT PVOID* Output)
42 {
43 IBaseUnknownImpl * This = (IBaseUnknownImpl*)CONTAINING_RECORD(iface, IBaseUnknownImpl, lpVtbl);
44
45 if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
46 {
47 *Output = &This->lpVtbl;
48 _InterlockedIncrement(&This->m_RefCount);
49 return STATUS_SUCCESS;
50 }
51 return STATUS_NOINTERFACE;
52 }
53
54 ULONG
55 NTAPI
56 INonDelegatedUnknown_fnAddRef(
57 INonDelegatedUnknown * iface)
58 {
59 IBaseUnknownImpl * This = (IBaseUnknownImpl*)CONTAINING_RECORD(iface, IBaseUnknownImpl, lpVtbl);
60
61 return InterlockedIncrement(&This->m_RefCount);
62 }
63
64 ULONG
65 NTAPI
66 INonDelegatedUnknown_fnRelease(
67 INonDelegatedUnknown * iface)
68 {
69 IBaseUnknownImpl * This = (IBaseUnknownImpl*)CONTAINING_RECORD(iface, IBaseUnknownImpl, lpVtbl);
70
71 InterlockedDecrement(&This->m_RefCount);
72
73 /* Return new reference count */
74 return This->m_RefCount;
75 }
76
77 static INonDelegatedUnknownVtbl vt_INonDelegatedUnknownVtbl =
78 {
79 INonDelegatedUnknown_fnQueryInterface,
80 INonDelegatedUnknown_fnAddRef,
81 INonDelegatedUnknown_fnRelease
82 };
83
84 NTSTATUS
85 NTAPI
86 IIndirectedUnknown_fnQueryInterface(
87 IIndirectedUnknown * iface,
88 IN REFIID refiid,
89 OUT PVOID* Output)
90 {
91 IBaseUnknownImpl * This = (IBaseUnknownImpl*)CONTAINING_RECORD(iface, IBaseUnknownImpl, lpVtblIndirectedUnknown);
92
93 return This->m_UnknownOuter->lpVtbl->QueryInterface(This->m_UnknownOuter, refiid, Output);
94 }
95
96 ULONG
97 NTAPI
98 IIndirectedUnknown_fnAddRef(
99 IIndirectedUnknown * iface)
100 {
101 IBaseUnknownImpl * This = (IBaseUnknownImpl*)CONTAINING_RECORD(iface, IBaseUnknownImpl, lpVtblIndirectedUnknown);
102
103 return This->m_UnknownOuter->lpVtbl->AddRef(This->m_UnknownOuter);
104 }
105
106 ULONG
107 NTAPI
108 IIndirectedUnknown_fnRelease(
109 IIndirectedUnknown * iface)
110 {
111 IBaseUnknownImpl * This = (IBaseUnknownImpl*)CONTAINING_RECORD(iface, IBaseUnknownImpl, lpVtblIndirectedUnknown);
112
113 return This->m_UnknownOuter->lpVtbl->Release(This->m_UnknownOuter);
114 }
115
116 static IIndirectedUnknownVtbl vt_IIndirectedUnknownVtbl =
117 {
118 IIndirectedUnknown_fnQueryInterface,
119 IIndirectedUnknown_fnAddRef,
120 IIndirectedUnknown_fnRelease
121 };
122
123
124 // On x86, the function is named @__CBaseUnknown_ConstructorWithGUID@16
125 // On non-x86, the function is named __CBaseUnknown_ConstructorWithGUID
126 KS_DECL_CXX(IBaseUnknownImpl *) CBaseUnknown_ConstructorWithGUID(KS_THIS(IBaseUnknownImpl), const GUID *lpGUID, IUnknown * OuterUnknown)
127 {
128
129 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
130 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
131
132 /* class uses class id */
133 This->m_UsingClassId = TRUE;
134
135 /* copy guid */
136 RtlMoveMemory(&This->m_ClassId, lpGUID, sizeof(GUID));
137
138 /* set refcount to zero */
139 This->m_RefCount = 0;
140
141 if (OuterUnknown)
142 {
143 /* use outer unknown */
144 This->m_UnknownOuter = OuterUnknown;
145 }
146 else
147 {
148 /* use unknown from INonDelegatedUnknown */
149 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
150 }
151
152 /* return result */
153 return This;
154 }
155
156 // On x86, the function is named @__CBaseUnknown_Constructor@12
157 // On non-x86, the function is named ___CBaseUnknown_Constructor
158 KS_DECL_CXX(IBaseUnknownImpl *) CBaseUnknown_Constructor(KS_THIS(IBaseUnknownImpl), IUnknown * OuterUnknown)
159 {
160
161 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
162 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
163
164 /* class uses class id */
165 This->m_UsingClassId = FALSE;
166
167 /* set refcount to zero */
168 This->m_RefCount = 0;
169
170 if (OuterUnknown)
171 {
172 /* use outer unknown */
173 This->m_UnknownOuter = OuterUnknown;
174 }
175 else
176 {
177 /* use unknown from INonDelegatedUnknown */
178 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
179 }
180
181 /* return result */
182 return This;
183 }
184
185 // On x86, the function is named @__CBaseUnknown_Destructor@12
186 // On non-x86, the function is named __CBaseUnknown_Destructor
187 KS_DECL_CXX(IBaseUnknownImpl *) CBaseUnknown_Destructor(KS_THIS(IBaseUnknownImpl), IUnknown * OuterUnknown)
188 {
189 /* restore vtbl's */
190 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
191 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
192
193
194 if (OuterUnknown)
195 {
196 /* use outer unknown */
197 This->m_UnknownOuter = OuterUnknown;
198 }
199 else
200 {
201 /* use unknown from INonDelegatedUnknown */
202 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
203 }
204
205 /* return result */
206 return This;
207 }
208
209 KS_DECL_CXX(IBaseUnknownImpl *) CBaseUnknown_DefaultDestructor(KS_THIS(IBaseUnknownImpl))
210 {
211 /* restore vtbl's */
212 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
213 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
214
215
216 /* return result */
217 return This;
218 }
219