Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS BDA Proxy * FILE: dll/directx/bdaplgin/pincontrol.cpp * PURPOSE: ClassFactory interface * * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) */
#include "precomp.h"
#ifndef _MSC_VERconst GUID KSPROPSETID_BdaPinControl = {0x0ded49d5, 0xa8b7, 0x4d5d, {0x97, 0xa1, 0x12, 0xb0, 0xc1, 0x95, 0x87, 0x4d}};const GUID IID_IBDA_PinControl = {0x0DED49D5, 0xA8B7, 0x4d5d, {0x97, 0xA1, 0x12, 0xB0, 0xC1, 0x95, 0x87, 0x4D}};const GUID IID_IPin = {0x56a86891, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};#endif
class CBDAPinControl : public IBDA_PinControl{public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
STDMETHODIMP_(ULONG) AddRef() { InterlockedIncrement(&m_Ref); return m_Ref; } STDMETHODIMP_(ULONG) Release() { InterlockedDecrement(&m_Ref); if (!m_Ref) { delete this; return 0; } return m_Ref; } // IBDA_PinControl methods HRESULT STDMETHODCALLTYPE GetPinID(ULONG *pulPinID); HRESULT STDMETHODCALLTYPE GetPinType(ULONG *pulPinType); HRESULT STDMETHODCALLTYPE RegistrationContext(ULONG *pulRegistrationCtx);
CBDAPinControl(HANDLE hFile, IBDA_NetworkProvider * pProvider, IPin * pConnectedPin, ULONG RegistrationCtx) : m_Ref(0), m_Handle(hFile), m_pProvider(pProvider), m_pConnectedPin(pConnectedPin), m_RegistrationCtx(RegistrationCtx){}; virtual ~CBDAPinControl() { //m_pConnectedPin->Release(); //m_pProvider->Release(); };
protected: LONG m_Ref; HANDLE m_Handle; IBDA_NetworkProvider * m_pProvider; IPin * m_pConnectedPin; ULONG m_RegistrationCtx;};
HRESULTSTDMETHODCALLTYPECBDAPinControl::QueryInterface( IN REFIID refiid, OUT PVOID* Output){ *Output = NULL; if (IsEqualGUID(refiid, IID_IUnknown)) { *Output = PVOID(this); reinterpret_cast<IUnknown*>(*Output)->AddRef(); return NOERROR; } if (IsEqualGUID(refiid, IID_IBDA_PinControl)) { *Output = (IBDA_PinControl*)(this); reinterpret_cast<IBDA_PinControl*>(*Output)->AddRef(); return NOERROR; }DebugBreak(); return E_NOINTERFACE;}//-------------------------------------------------------------------// IBDA_PinControl methods//HRESULTSTDMETHODCALLTYPECBDAPinControl::GetPinID(ULONG *pulPinID){ KSPROPERTY Property; ULONG BytesReturned; HRESULT hr;
// setup request Property.Set = KSPROPSETID_BdaPinControl; Property.Id = KSPROPERTY_BDA_PIN_ID; Property.Flags = KSPROPERTY_TYPE_GET;
// perform request hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), pulPinID, sizeof(ULONG), &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDAPinControl::GetPinID: hr %lx pulPinID %lu BytesReturned %lx\n", hr, *pulPinID, BytesReturned); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDAPinControl::GetPinType(ULONG *pulPinType){ KSPROPERTY Property; ULONG BytesReturned; HRESULT hr;
// setup request Property.Set = KSPROPSETID_BdaPinControl; Property.Id = KSPROPERTY_BDA_PIN_TYPE; Property.Flags = KSPROPERTY_TYPE_GET;
// perform request hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), pulPinType, sizeof(ULONG), &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDAPinControl::GetPinType: hr %lx pulPinType %lu BytesReturned %lx\n", hr, *pulPinType, BytesReturned); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDAPinControl::RegistrationContext(ULONG *pulRegistrationCtx){#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDAPinControl::RegistrationContext\n");#endif
if (!pulRegistrationCtx) { // invalid argument return E_POINTER; }
if (m_RegistrationCtx) { // is registered *pulRegistrationCtx = m_RegistrationCtx; return NOERROR; }
//pin not registered return E_FAIL;}
//-------------------------------------------------------------------HRESULTGetNetworkProviderFromGraph( IFilterGraph * pGraph, IBDA_NetworkProvider ** pOutNetworkProvider){ IEnumFilters *pEnumFilters = NULL; IBaseFilter * ppFilter[1]; IBDA_NetworkProvider * pNetworkProvider = NULL; HRESULT hr;
// get IEnumFilters interface hr = pGraph->EnumFilters(&pEnumFilters);
if (FAILED(hr)) { //clean up *pOutNetworkProvider = NULL; return hr; }
while(pEnumFilters->Next(1, ppFilter, NULL) == S_OK) { // check if that filter supports the IBDA_NetworkProvider interface hr = ppFilter[0]->QueryInterface(IID_IBDA_NetworkProvider, (void**)&pNetworkProvider);
// release IBaseFilter ppFilter[0]->Release();
if (SUCCEEDED(hr)) break; }
// release IEnumFilters interface pEnumFilters->Release();
//store result *pOutNetworkProvider = pNetworkProvider;
if (pNetworkProvider) return S_OK; else return E_FAIL;}
HRESULTCBDAPinControl_RealConstructor( HANDLE hPin, IBDA_NetworkProvider *pNetworkProvider, IPin * pConnectedPin, ULONG RegistrationCtx, IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv){ CBDAPinControl * handler = new CBDAPinControl(hPin, pNetworkProvider, pConnectedPin, RegistrationCtx);
#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDAPinControl_fnConstructor\n");#endif
if (!handler) return E_OUTOFMEMORY;
if (FAILED(handler->QueryInterface(riid, ppv))) { /* not supported */ delete handler; return E_NOINTERFACE; }
return NOERROR;}
HRESULTWINAPICBDAPinControl_fnConstructor( IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv){ IPin * pConnectedPin = NULL; IBDA_NetworkProvider * pNetworkProvider = NULL; HANDLE hFile = INVALID_HANDLE_VALUE; HRESULT hr; IKsObject * pObject = NULL; IPin * pPin = NULL; IUnknown * pUnknown = NULL; PIN_INFO PinInfo; FILTER_INFO FilterInfo; ULONG RegistrationCtx = 0;
if (!pUnkOuter) return E_POINTER;
OutputDebugStringW(L"CBDAPinControl_fnConstructor\n"); //DebugBreak();
// query for IKsObject interface hr = pUnkOuter->QueryInterface(IID_IKsObject, (void**)&pObject);
if (FAILED(hr)) return hr;
// query for IPin interface hr = pObject->QueryInterface(IID_IPin, (void**)&pPin);
if (FAILED(hr)) { //clean up pObject->Release(); return hr; }
// get pin info hr = pPin->QueryPinInfo(&PinInfo);
if (FAILED(hr)) { //clean up pObject->Release(); pPin->Release(); return hr; }
if (!PinInfo.pFilter) { //clean up pObject->Release(); pPin->Release(); return hr; }
// sanity checks assert(PinInfo.pFilter != NULL);
// query filter info hr = PinInfo.pFilter->QueryFilterInfo(&FilterInfo);
// sanity check assert(FilterInfo.pGraph != NULL);
// get network provider interface hr = GetNetworkProviderFromGraph(FilterInfo.pGraph, &pNetworkProvider);
if (SUCCEEDED(hr)) { if (PinInfo.dir == PINDIR_OUTPUT) { // get connected pin handle hr = pPin->ConnectedTo(&pConnectedPin); if (SUCCEEDED(hr)) { // get file handle hFile = pObject->KsGetObjectHandle(); if (hFile) { hr = CBDAPinControl_RealConstructor(hFile, pNetworkProvider, pConnectedPin, 0, pUnkOuter, riid, ppv); if (SUCCEEDED(hr)) { // set to null to prevent releasing pNetworkProvider = NULL; pConnectedPin = NULL; } } else { // expected file handle hr = E_UNEXPECTED; } } } else { // get IUnknown from base filter hr = PinInfo.pFilter->QueryInterface(IID_IUnknown, (void**)&pUnknown); if (SUCCEEDED(hr)) { // register device filter OutputDebugStringW(L"CBDAPinControl_fnConstructor registering device filter with network provider\n"); hr = pNetworkProvider->RegisterDeviceFilter(pUnknown, &RegistrationCtx); if (SUCCEEDED(hr)) { // get file handle hFile = pObject->KsGetObjectHandle(); if (hFile) { hr = CBDAPinControl_RealConstructor(hFile, pNetworkProvider, NULL, RegistrationCtx, pUnkOuter, riid, ppv); if (SUCCEEDED(hr)) { // set to null to prevent releasing pNetworkProvider = NULL; } } else { // expected file handle hr = E_UNEXPECTED; } } else { WCHAR Buffer[100]; swprintf(Buffer, L"CBDAPinControl_fnConstructor failed to register filter with %lx\n", hr); OutputDebugStringW(Buffer); } } } }
// release IFilterGraph interface FilterInfo.pGraph->Release();
// release IBaseFilter interface PinInfo.pFilter->Release();
// release IPin pPin->Release();
// release IKsObject pObject->Release();
if (pNetworkProvider) { // release network provider pNetworkProvider->Release(); }
if (pConnectedPin) { // release connected pin pConnectedPin->Release(); }
if (pUnknown) { // release filter pUnknown->Release(); }
return hr;}