mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 08:08:38 +00:00
9393fc320e
Excluded: 3rd-party code (incl. wine) and most of the win32ss.
562 lines
16 KiB
C++
562 lines
16 KiB
C++
/*
|
|
* 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_VER
|
|
const 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;
|
|
};
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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
|
|
//
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::GetChangeState(ULONG *pState)
|
|
{
|
|
if (pState)
|
|
{
|
|
*pState = BDA_CHANGES_COMPLETE;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// IBDA_Topology methods
|
|
//
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::GetTemplateConnections(ULONG *pulcConnections, ULONG ulcConnectionsMax, BDA_TEMPLATE_CONNECTION * rgConnections)
|
|
{
|
|
#ifdef BDAPLGIN_TRACE
|
|
OutputDebugStringW(L"CBDADeviceControl::GetTemplateConnections: NotImplemented\n");
|
|
#endif
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::CreatePin(ULONG ulPinType, ULONG *pulPinId)
|
|
{
|
|
#ifdef BDAPLGIN_TRACE
|
|
OutputDebugStringW(L"CBDADeviceControl::CreatePin: NotImplemented\n");
|
|
#endif
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::DeletePin(ULONG ulPinId)
|
|
{
|
|
#ifdef BDAPLGIN_TRACE
|
|
OutputDebugStringW(L"CBDADeviceControl::DeletePin: NotImplemented\n");
|
|
#endif
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::SetMediaType(ULONG ulPinId, AM_MEDIA_TYPE *pMediaType)
|
|
{
|
|
#ifdef BDAPLGIN_TRACE
|
|
OutputDebugStringW(L"CBDADeviceControl::SetMediaType: NotImplemented\n");
|
|
#endif
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::SetMedium(ULONG ulPinId, REGPINMEDIUM *pMedium)
|
|
{
|
|
#ifdef BDAPLGIN_TRACE
|
|
OutputDebugStringW(L"CBDADeviceControl::SetMedium: NotImplemented\n");
|
|
#endif
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CBDADeviceControl::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;
|
|
}
|
|
|
|
HRESULT
|
|
WINAPI
|
|
CBDADeviceControl_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;
|
|
}
|