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