Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS BDA Proxy * FILE: dll/directx/bdaplgin/devicecontrol.cpp * PURPOSE: ClassFactory interface * * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) */
#include "precomp.h"
const GUID IID_IKsObject = {0x423c13a2, 0x2070, 0x11d0, {0x9e, 0xf7, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
#ifndef _MSC_VERconst GUID CLSID_DVBTNetworkProvider = {0x216c62df, 0x6d7f, 0x4e9a, {0x85, 0x71, 0x5, 0xf1, 0x4e, 0xdb, 0x76, 0x6a}};
const GUID KSPROPSETID_BdaTopology = {0xa14ee835, 0x0a23, 0x11d3, {0x9c, 0xc7, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};const GUID KSMETHODSETID_BdaDeviceConfiguration = {0x71985f45, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};const GUID KSMETHODSETID_BdaChangeSync = {0xfd0a5af3, 0xb41d, 0x11d2, {0x9c, 0x95, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};const GUID IID_IBaseFilter = {0x56a86895, 0x0ad4, 0x11ce, {0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70}};const GUID IID_IAsyncReader = {0x56A868AA, 0x0AD4, 0x11CE, {0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};const GUID IID_IAMOpenProgress = {0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D}};const GUID IID_IBDA_Topology = {0x79B56888, 0x7FEA, 0x4690, {0xB4, 0x5D, 0x38, 0xFD, 0x3C, 0x78, 0x49, 0xBE}};const GUID IID_IBDA_NetworkProvider = {0xfd501041, 0x8ebe, 0x11ce, {0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa2}};const GUID IID_IBDA_DeviceControl = {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
const GUID IID_IDistributorNotify = {0x56a868af, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
#endif
class CBDADeviceControl : public IBDA_DeviceControl, public IBDA_Topology{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_DeviceControl methods HRESULT STDMETHODCALLTYPE StartChanges( void); HRESULT STDMETHODCALLTYPE CheckChanges( void); HRESULT STDMETHODCALLTYPE CommitChanges( void); HRESULT STDMETHODCALLTYPE GetChangeState(ULONG *pState);
// IBDA_Topology methods HRESULT STDMETHODCALLTYPE GetNodeTypes(ULONG *pulcNodeTypes, ULONG ulcNodeTypesMax, ULONG * rgulNodeTypes); HRESULT STDMETHODCALLTYPE GetNodeDescriptors(ULONG *ulcNodeDescriptors, ULONG ulcNodeDescriptorsMax, BDANODE_DESCRIPTOR * rgNodeDescriptors); HRESULT STDMETHODCALLTYPE GetNodeInterfaces(ULONG ulNodeType, ULONG *pulcInterfaces, ULONG ulcInterfacesMax, GUID * rgguidInterfaces); HRESULT STDMETHODCALLTYPE GetPinTypes(ULONG *pulcPinTypes, ULONG ulcPinTypesMax, ULONG *rgulPinTypes); HRESULT STDMETHODCALLTYPE GetTemplateConnections(ULONG *pulcConnections, ULONG ulcConnectionsMax, BDA_TEMPLATE_CONNECTION * rgConnections); HRESULT STDMETHODCALLTYPE CreatePin(ULONG ulPinType, ULONG *pulPinId); HRESULT STDMETHODCALLTYPE DeletePin(ULONG ulPinId); HRESULT STDMETHODCALLTYPE SetMediaType(ULONG ulPinId, AM_MEDIA_TYPE *pMediaType); HRESULT STDMETHODCALLTYPE SetMedium(ULONG ulPinId, REGPINMEDIUM *pMedium); HRESULT STDMETHODCALLTYPE CreateTopology(ULONG ulInputPinId, ULONG ulOutputPinId); HRESULT STDMETHODCALLTYPE GetControlNode(ULONG ulInputPinId, ULONG ulOutputPinId, ULONG ulNodeType, IUnknown **ppControlNode);
CBDADeviceControl(IUnknown * pUnkOuter, IBaseFilter *pFilter, HANDLE hFile) : m_Ref(0), m_pUnkOuter(pUnkOuter), m_Handle(hFile), m_pFilter(pFilter){}; virtual ~CBDADeviceControl(){};
protected: LONG m_Ref; IUnknown * m_pUnkOuter; HANDLE m_Handle; IBaseFilter * m_pFilter;};
HRESULTSTDMETHODCALLTYPECBDADeviceControl::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_DeviceControl)) { *Output = (IBDA_DeviceControl*)(this); reinterpret_cast<IBDA_DeviceControl*>(*Output)->AddRef(); return NOERROR; }
if (IsEqualGUID(refiid, IID_IBDA_Topology)) { *Output = (IBDA_Topology*)(this); reinterpret_cast<IBDA_Topology*>(*Output)->AddRef(); return NOERROR; }
return E_NOINTERFACE;}
//-------------------------------------------------------------------// IBDA_DeviceControl methods//HRESULTSTDMETHODCALLTYPECBDADeviceControl::StartChanges( void){ KSMETHOD Method; HRESULT hr; ULONG BytesReturned;
/* setup request */ Method.Set = KSMETHODSETID_BdaChangeSync; Method.Id = KSMETHOD_BDA_START_CHANGES; Method.Flags = KSMETHOD_TYPE_NONE;
/* execute request */ hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)&Method, sizeof(KSMETHOD), NULL, 0, &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::StartChanges: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::CheckChanges( void){ KSMETHOD Method; HRESULT hr; ULONG BytesReturned;
/* setup request */ Method.Set = KSMETHODSETID_BdaChangeSync; Method.Id = KSMETHOD_BDA_CHECK_CHANGES; Method.Flags = KSMETHOD_TYPE_NONE;
/* execute request */ hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)&Method, sizeof(KSMETHOD), NULL, 0, &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::CheckChanges: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::CommitChanges( void){ KSMETHOD Method; HRESULT hr; ULONG BytesReturned;
/* setup request */ Method.Set = KSMETHODSETID_BdaChangeSync; Method.Id = KSMETHOD_BDA_COMMIT_CHANGES; Method.Flags = KSMETHOD_TYPE_NONE;
/* execute request */ hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)&Method, sizeof(KSMETHOD), NULL, 0, &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::CommitChanges: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetChangeState(ULONG *pState){ if (pState) { *pState = BDA_CHANGES_COMPLETE; return S_OK; } else { return E_POINTER; }}
//-------------------------------------------------------------------// IBDA_Topology methods//HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetNodeTypes(ULONG *pulcNodeTypes, ULONG ulcNodeTypesMax, ULONG * rgulNodeTypes){ KSPROPERTY Property; HRESULT hr; ULONG BytesReturned;
// setup request Property.Set = KSPROPSETID_BdaTopology; Property.Id = KSPROPERTY_BDA_NODE_TYPES; Property.Flags = KSPROPERTY_TYPE_GET;
// perform request hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), rgulNodeTypes, sizeof(ULONG) * ulcNodeTypesMax, &BytesReturned);
*pulcNodeTypes = (BytesReturned / sizeof(ULONG));
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::GetNodeTypes: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);
if (SUCCEEDED(hr)) { for(ULONG Index = 0; Index < *pulcNodeTypes; Index++) { swprintf(Buffer, L"CBDADeviceControl::GetPinTypes: Index %lu Value %lx\n", Index, rgulNodeTypes[Index]); OutputDebugStringW(Buffer); } }#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetNodeDescriptors(ULONG *ulcNodeDescriptors, ULONG ulcNodeDescriptorsMax, BDANODE_DESCRIPTOR * rgNodeDescriptors){ KSPROPERTY Property; HRESULT hr; ULONG BytesReturned;
// setup request Property.Set = KSPROPSETID_BdaTopology; Property.Id = KSPROPERTY_BDA_NODE_DESCRIPTORS; Property.Flags = KSPROPERTY_TYPE_GET;
// perform request hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), rgNodeDescriptors, sizeof(BDANODE_DESCRIPTOR) * ulcNodeDescriptorsMax, &BytesReturned);
*ulcNodeDescriptors = (BytesReturned / sizeof(BDANODE_DESCRIPTOR));
#ifdef BDAPLGIN_TRACE WCHAR Buffer[1000]; swprintf(Buffer, L"CBDADeviceControl::GetNodeDescriptors: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);
if (SUCCEEDED(hr)) { for(ULONG Index = 0; Index < min(*ulcNodeDescriptors, ulcNodeDescriptorsMax); Index++) { LPOLESTR pGUIDFunction, pGUIDName;
StringFromCLSID(rgNodeDescriptors[Index].guidFunction, &pGUIDFunction); StringFromCLSID(rgNodeDescriptors[Index].guidName, &pGUIDName);
swprintf(Buffer, L"CBDADeviceControl::GetPinTypes: Index %lu Value %lx\nFunction %s\n Name %s\n-----\n", Index, rgNodeDescriptors[Index].ulBdaNodeType, pGUIDFunction, pGUIDName); OutputDebugStringW(Buffer); } }#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetNodeInterfaces(ULONG ulNodeType, ULONG *pulcInterfaces, ULONG ulcInterfacesMax, GUID * rgguidInterfaces){ KSP_NODE Property; HRESULT hr; ULONG BytesReturned;
// setup request Property.Property.Set = KSPROPSETID_BdaTopology; Property.Property.Id = KSPROPERTY_BDA_NODE_PROPERTIES; Property.Property.Flags = KSPROPERTY_TYPE_GET; Property.NodeId = ulNodeType; Property.Reserved = 0;
// perform request hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_NODE), rgguidInterfaces, sizeof(GUID) * ulcInterfacesMax, &BytesReturned);
*pulcInterfaces = (BytesReturned / sizeof(GUID));
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::GetNodeInterfaces: hr %lx, BytesReturned %lu ulNodeType %lu\n", hr, BytesReturned, ulNodeType); OutputDebugStringW(Buffer);
if (SUCCEEDED(hr)) { for(ULONG Index = 0; Index < min(*pulcInterfaces, ulcInterfacesMax); Index++) { LPOLESTR pstr;
StringFromCLSID(rgguidInterfaces[Index], &pstr);
swprintf(Buffer, L"CBDADeviceControl::GetNodeInterfaces: Index %lu Name %s\n", Index, pstr); OutputDebugStringW(Buffer); } }#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetPinTypes(ULONG *pulcPinTypes, ULONG ulcPinTypesMax, ULONG *rgulPinTypes){ KSPROPERTY Property; HRESULT hr; ULONG BytesReturned;
// setup request Property.Set = KSPROPSETID_BdaTopology; Property.Id = KSPROPERTY_BDA_PIN_TYPES; Property.Flags = KSPROPERTY_TYPE_GET;
// perform request hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), rgulPinTypes, sizeof(ULONG) * ulcPinTypesMax, &BytesReturned);
*pulcPinTypes = (BytesReturned / sizeof(ULONG));
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::GetPinTypes: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);
if (SUCCEEDED(hr)) { for(ULONG Index = 0; Index < *pulcPinTypes; Index++) { swprintf(Buffer, L"CBDADeviceControl::GetPinTypes: Index %lu Value %lx\n", Index, rgulPinTypes[Index]); OutputDebugStringW(Buffer); } }#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetTemplateConnections(ULONG *pulcConnections, ULONG ulcConnectionsMax, BDA_TEMPLATE_CONNECTION * rgConnections){#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDADeviceControl::GetTemplateConnections: NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::CreatePin(ULONG ulPinType, ULONG *pulPinId){#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDADeviceControl::CreatePin: NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::DeletePin(ULONG ulPinId){#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDADeviceControl::DeletePin: NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::SetMediaType(ULONG ulPinId, AM_MEDIA_TYPE *pMediaType){#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDADeviceControl::SetMediaType: NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::SetMedium(ULONG ulPinId, REGPINMEDIUM *pMedium){#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDADeviceControl::SetMedium: NotImplemented\n");#endif
return E_NOTIMPL;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::CreateTopology(ULONG ulInputPinId, ULONG ulOutputPinId){ KSM_BDA_PIN_PAIR Method; HRESULT hr; ULONG BytesReturned = 0;
Method.Method.Flags = KSMETHOD_TYPE_NONE; Method.Method.Id = KSMETHOD_BDA_CREATE_TOPOLOGY; Method.Method.Set = KSMETHODSETID_BdaDeviceConfiguration; Method.InputPinId = ulInputPinId; Method.OutputPinId = ulOutputPinId;
hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)&Method, sizeof(KSM_BDA_PIN_PAIR), NULL, 0, &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[100]; swprintf(Buffer, L"CBDADeviceControl::CreateTopology: hr %lx, BytesReturned %lu\n", hr, BytesReturned); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTSTDMETHODCALLTYPECBDADeviceControl::GetControlNode(ULONG ulInputPinId, ULONG ulOutputPinId, ULONG ulNodeType, IUnknown **ppControlNode){ HRESULT hr; ULONG PinId = 0; ULONG BytesReturned; KSP_BDA_NODE_PIN Property;
//setup request Property.Property.Set = KSPROPSETID_BdaTopology; Property.Property.Id = KSPROPERTY_BDA_CONTROLLING_PIN_ID; Property.Property.Flags = KSPROPERTY_TYPE_GET; Property.ulInputPinId = ulInputPinId; Property.ulOutputPinId = ulOutputPinId; Property.ulNodeType = ulNodeType;
// perform request // WinXP SP3 expects minimum sizeof(KSP_BDA_NODE_PIN) + sizeof(ULONG) // seems a driver to be a driver bug
hr = KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_BDA_NODE_PIN) + sizeof(ULONG), &PinId, sizeof(ULONG), &BytesReturned);
#ifdef BDAPLGIN_TRACE WCHAR Buffer[200]; swprintf(Buffer, L"CBDADeviceControl::GetControlNode: hr %lx, BytesReturned %lu PinId %lu ulInputPinId %lu ulOutputPinId %lu ulNodeType %lu\n", hr, BytesReturned, PinId, ulInputPinId, ulOutputPinId, ulNodeType); OutputDebugStringW(Buffer);#endif
if (FAILED(hr)) return hr;
hr = CControlNode_fnConstructor(m_pFilter, ulNodeType, PinId, IID_IUnknown, (LPVOID*)ppControlNode);
#ifdef BDAPLGIN_TRACE swprintf(Buffer, L"CBDADeviceControl::GetControlNode: hr %lx\n", hr); OutputDebugStringW(Buffer);#endif
return hr;}
HRESULTWINAPICBDADeviceControl_fnConstructor( IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv){ HRESULT hr; IKsObject *pObject = NULL; IBaseFilter *pFilter = NULL; HANDLE hFile;
#ifdef BDAPLGIN_TRACE OutputDebugStringW(L"CBDADeviceControl_fnConstructor\n");#endif
//DebugBreak();
// sanity check assert(pUnkOuter);
// query for IKsObject hr = pUnkOuter->QueryInterface(IID_IKsObject, (void**)&pObject);
if (FAILED(hr)) return E_NOINTERFACE;
// sanity check assert(hr == NOERROR);
// query for IBaseFilter interface support hr = pUnkOuter->QueryInterface(IID_IBaseFilter, (void**)&pFilter);
if (FAILED(hr)) { // release pObject->Release(); return E_NOINTERFACE; }
// another sanity check assert(pObject != NULL);
// get file handle hFile = pObject->KsGetObjectHandle();
// one more sanity check assert(hFile != NULL && hFile != INVALID_HANDLE_VALUE);
// release IKsObject interface pObject->Release();
// release filter pFilter->Release();
// construct device control CBDADeviceControl * handler = new CBDADeviceControl(pUnkOuter, pFilter, hFile);
if (!handler) return E_OUTOFMEMORY;
if (FAILED(handler->QueryInterface(riid, ppv))) { /* not supported */ delete handler; return E_NOINTERFACE; }
return NOERROR;}