reactos/dll/directx/ksproxy/node.cpp

160 lines
3.9 KiB
C++

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
* FILE: dll/directx/ksproxy/node.cpp
* PURPOSE: Control Node
*
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
*/
#include "precomp.h"
class CKsNode : public IKsControl
{
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;
}
//IKsControl
HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
CKsNode(IUnknown * pUnkOuter, HANDLE Handle) : m_Ref(0), m_pUnkOuter(pUnkOuter), m_Handle(Handle){};
virtual ~CKsNode()
{
CloseHandle(m_Handle);
};
protected:
LONG m_Ref;
IUnknown * m_pUnkOuter;
HANDLE m_Handle;
};
HRESULT
STDMETHODCALLTYPE
CKsNode::QueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
if (IsEqualGUID(refiid, IID_IUnknown) ||
IsEqualGUID(refiid, IID_IKsControl))
{
*Output = PVOID(this);
reinterpret_cast<IUnknown*>(*Output)->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
//-------------------------------------------------------------------
// IKsControl
//
HRESULT
STDMETHODCALLTYPE
CKsNode::KsProperty(
PKSPROPERTY Property,
ULONG PropertyLength,
LPVOID PropertyData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_Handle != 0);
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
}
HRESULT
STDMETHODCALLTYPE
CKsNode::KsMethod(
PKSMETHOD Method,
ULONG MethodLength,
LPVOID MethodData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_Handle != 0);
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
}
HRESULT
STDMETHODCALLTYPE
CKsNode::KsEvent(
PKSEVENT Event,
ULONG EventLength,
LPVOID EventData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_Handle != 0);
if (EventLength)
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
else
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
}
HRESULT
WINAPI
CKsNode_Constructor(
IUnknown * pUnkOuter,
HANDLE ParentHandle,
ULONG NodeId,
ACCESS_MASK DesiredAccess,
REFIID riid,
LPVOID * ppv)
{
HRESULT hr;
HANDLE handle;
KSNODE_CREATE NodeCreate;
#ifdef KSPROXY_TRACE
OutputDebugStringW(L"CKsNode_Constructor\n");
#endif
//setup request
NodeCreate.CreateFlags = 0;
NodeCreate.Node = NodeId;
hr = KsCreateTopologyNode(ParentHandle, &NodeCreate, DesiredAccess, &handle);
if (hr != NOERROR)
{
OutputDebugString("CKsNode_Constructor failed to open device\n");
return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, hr);
}
CKsNode * quality = new CKsNode(pUnkOuter, handle);
if (!quality)
{
// free clock handle
CloseHandle(handle);
return E_OUTOFMEMORY;
}
if (FAILED(quality->QueryInterface(riid, ppv)))
{
/* not supported */
delete quality;
return E_NOINTERFACE;
}
return NOERROR;
}