[KS]
[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 #include "priv.h"
11
12 #define NDEBUG
13 #include <debug.h>
14
15 #ifdef _X86_
16 #define KS_DECL_CXX(RET_) extern RET_ __fastcall
17 #define KS_THIS(CLASS_) CLASS_ * This, void * dummy_
18 #else
19 #define KS_DECL_CXX(RET_) extern RET_ __cdecl
20 #define KS_THIS(CLASS_) CLASS_ * This
21 #endif
22
23 typedef struct
24 {
25 INonDelegatedUnknownVtbl *lpVtbl;
26 IIndirectedUnknownVtbl *lpVtblIndirectedUnknown;
27
28 LONG m_RefCount;
29
30 BOOLEAN m_UsingClassId;
31 CLSID m_ClassId;
32 IUnknown* m_UnknownOuter;
33
34 }CBaseUnknownImpl;
35
36
37
38 NTSTATUS
39 NTAPI
40 INonDelegatedUnknown_fnQueryInterface(
41 INonDelegatedUnknown * iface,
42 IN REFIID refiid,
43 OUT PVOID* Output)
44 {
45 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtbl);
46
47 if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
48 {
49 *Output = &This->lpVtbl;
50 _InterlockedIncrement(&This->m_RefCount);
51 return STATUS_SUCCESS;
52 }
53 return STATUS_NOINTERFACE;
54 }
55
56 ULONG
57 NTAPI
58 INonDelegatedUnknown_fnAddRef(
59 INonDelegatedUnknown * iface)
60 {
61 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtbl);
62
63 return InterlockedIncrement(&This->m_RefCount);
64 }
65
66 ULONG
67 NTAPI
68 INonDelegatedUnknown_fnRelease(
69 INonDelegatedUnknown * iface)
70 {
71 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtbl);
72
73 InterlockedDecrement(&This->m_RefCount);
74
75 /* Return new reference count */
76 return This->m_RefCount;
77 }
78
79 static INonDelegatedUnknownVtbl vt_INonDelegatedUnknownVtbl =
80 {
81 INonDelegatedUnknown_fnQueryInterface,
82 INonDelegatedUnknown_fnAddRef,
83 INonDelegatedUnknown_fnRelease
84 };
85
86 NTSTATUS
87 NTAPI
88 IIndirectedUnknown_fnQueryInterface(
89 IIndirectedUnknown * iface,
90 IN REFIID refiid,
91 OUT PVOID* Output)
92 {
93 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtblIndirectedUnknown);
94
95 return This->m_UnknownOuter->lpVtbl->QueryInterface(This->m_UnknownOuter, refiid, Output);
96 }
97
98 ULONG
99 NTAPI
100 IIndirectedUnknown_fnAddRef(
101 IIndirectedUnknown * iface)
102 {
103 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtblIndirectedUnknown);
104
105 return This->m_UnknownOuter->lpVtbl->AddRef(This->m_UnknownOuter);
106 }
107
108 ULONG
109 NTAPI
110 IIndirectedUnknown_fnRelease(
111 IIndirectedUnknown * iface)
112 {
113 CBaseUnknownImpl * This = (CBaseUnknownImpl*)CONTAINING_RECORD(iface, CBaseUnknownImpl, lpVtblIndirectedUnknown);
114
115 return This->m_UnknownOuter->lpVtbl->Release(This->m_UnknownOuter);
116 }
117
118 static IIndirectedUnknownVtbl vt_IIndirectedUnknownVtbl =
119 {
120 IIndirectedUnknown_fnQueryInterface,
121 IIndirectedUnknown_fnAddRef,
122 IIndirectedUnknown_fnRelease
123 };
124
125
126 KS_DECL_CXX(CBaseUnknownImpl *) CBaseUnknown_ConstructorWithGUID(KS_THIS(CBaseUnknownImpl), 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 KS_DECL_CXX(CBaseUnknownImpl *) CBaseUnknown_Constructor(KS_THIS(CBaseUnknownImpl), IUnknown * OuterUnknown)
157 {
158
159 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
160 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
161
162 /* class uses class id */
163 This->m_UsingClassId = FALSE;
164
165 /* set refcount to zero */
166 This->m_RefCount = 0;
167
168 if (OuterUnknown)
169 {
170 /* use outer unknown */
171 This->m_UnknownOuter = OuterUnknown;
172 }
173 else
174 {
175 /* use unknown from INonDelegatedUnknown */
176 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
177 }
178
179 /* return result */
180 return This;
181 }
182
183 KS_DECL_CXX(VOID) CBaseUnknown_Destructor(KS_THIS(CBaseUnknownImpl), IUnknown * OuterUnknown)
184 {
185 /* restore vtbl's */
186 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
187 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
188
189
190 if (OuterUnknown)
191 {
192 /* use outer unknown */
193 This->m_UnknownOuter = OuterUnknown;
194 }
195 else
196 {
197 /* use unknown from INonDelegatedUnknown */
198 This->m_UnknownOuter = (PUNKNOWN)&This->lpVtbl;
199 }
200 }
201
202 KS_DECL_CXX(VOID) CBaseUnknown_DefaultDestructor(KS_THIS(CBaseUnknownImpl))
203 {
204 /* restore vtbl's */
205 This->lpVtbl = &vt_INonDelegatedUnknownVtbl;
206 This->lpVtblIndirectedUnknown = &vt_IIndirectedUnknownVtbl;
207 }
208