Create a branch for audio work
[reactos.git] / 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 }CBaseUnknownImpl;
33
34
35
36 NTSTATUS
37 NTAPI
38 INonDelegatedUnknown_fnQueryInterface(
39 INonDelegatedUnknown * iface,
40 IN REFIID refiid,
41 OUT PVOID* Output)
42 {
43 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, 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 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtbl);
60
61 return InterlockedIncrement(&This->m_RefCount);
62 }
63
64 ULONG
65 NTAPI
66 INonDelegatedUnknown_fnRelease(
67 INonDelegatedUnknown * iface)
68 {
69 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, 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 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, 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 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, 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 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, 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 KS_DECL_CXX(CBaseUnknownImpl *) CBaseUnknown_ConstructorWithGUID(KS_THIS(CBaseUnknownImpl), const GUID *lpGUID, IUnknown * OuterUnknown)
125 {
126
127 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
128 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
129
130 /* class uses class id */
131 This->m_UsingClassId = TRUE;
132
133 /* copy guid */
134 RtlMoveMemory(&This->m_ClassId, lpGUID, sizeof(GUID));
135
136 /* set refcount to zero */
137 This->m_RefCount = 0;
138
139 if (OuterUnknown)
140 {
141 /* use outer unknown */
142 This->m_UnknownOuter = OuterUnknown;
143 }
144 else
145 {
146 /* use unknown from INonDelegatedUnknown */
147 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
148 }
149
150 /* return result */
151 return This;
152 }
153
154 KS_DECL_CXX(CBaseUnknownImpl *) CBaseUnknown_Constructor(KS_THIS(CBaseUnknownImpl), IUnknown * OuterUnknown)
155 {
156
157 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
158 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
159
160 /* class uses class id */
161 This->m_UsingClassId = FALSE;
162
163 /* set refcount to zero */
164 This->m_RefCount = 0;
165
166 if (OuterUnknown)
167 {
168 /* use outer unknown */
169 This->m_UnknownOuter = OuterUnknown;
170 }
171 else
172 {
173 /* use unknown from INonDelegatedUnknown */
174 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
175 }
176
177 /* return result */
178 return This;
179 }
180
181 KS_DECL_CXX(VOID) CBaseUnknown_Destructor(KS_THIS(CBaseUnknownImpl), IUnknown * OuterUnknown)
182 {
183 /* restore vtbl's */
184 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
185 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
186
187
188 if (OuterUnknown)
189 {
190 /* use outer unknown */
191 This->m_UnknownOuter = OuterUnknown;
192 }
193 else
194 {
195 /* use unknown from INonDelegatedUnknown */
196 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
197 }
198 }
199
200 KS_DECL_CXX(VOID) CBaseUnknown_DefaultDestructor(KS_THIS(CBaseUnknownImpl))
201 {
202 /* restore vtbl's */
203 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
204 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
205 }
206