xref: /reactos/drivers/ksfilter/ks/unknown.c (revision 8a978a17)
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 "precomp.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 
209