1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy 4 * FILE: dll/directx/ksproxy/node.cpp 5 * PURPOSE: Control Node 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 #include "precomp.h" 10 11 class CKsNode : public IKsControl 12 { 13 public: 14 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 15 16 STDMETHODIMP_(ULONG) AddRef() 17 { 18 InterlockedIncrement(&m_Ref); 19 return m_Ref; 20 } 21 STDMETHODIMP_(ULONG) Release() 22 { 23 InterlockedDecrement(&m_Ref); 24 25 if (!m_Ref) 26 { 27 delete this; 28 return 0; 29 } 30 return m_Ref; 31 } 32 33 //IKsControl 34 HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned); 35 HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned); 36 HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned); 37 38 CKsNode(IUnknown * pUnkOuter, HANDLE Handle) : m_Ref(0), m_pUnkOuter(pUnkOuter), m_Handle(Handle){}; 39 virtual ~CKsNode() 40 { 41 CloseHandle(m_Handle); 42 }; 43 44 protected: 45 LONG m_Ref; 46 IUnknown * m_pUnkOuter; 47 HANDLE m_Handle; 48 }; 49 50 HRESULT 51 STDMETHODCALLTYPE 52 CKsNode::QueryInterface( 53 IN REFIID refiid, 54 OUT PVOID* Output) 55 { 56 if (IsEqualGUID(refiid, IID_IUnknown) || 57 IsEqualGUID(refiid, IID_IKsControl)) 58 { 59 *Output = PVOID(this); 60 reinterpret_cast<IUnknown*>(*Output)->AddRef(); 61 return NOERROR; 62 } 63 64 return E_NOINTERFACE; 65 } 66 67 //------------------------------------------------------------------- 68 // IKsControl 69 // 70 HRESULT 71 STDMETHODCALLTYPE 72 CKsNode::KsProperty( 73 PKSPROPERTY Property, 74 ULONG PropertyLength, 75 LPVOID PropertyData, 76 ULONG DataLength, 77 ULONG* BytesReturned) 78 { 79 assert(m_Handle != 0); 80 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned); 81 } 82 83 HRESULT 84 STDMETHODCALLTYPE 85 CKsNode::KsMethod( 86 PKSMETHOD Method, 87 ULONG MethodLength, 88 LPVOID MethodData, 89 ULONG DataLength, 90 ULONG* BytesReturned) 91 { 92 assert(m_Handle != 0); 93 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned); 94 } 95 96 HRESULT 97 STDMETHODCALLTYPE 98 CKsNode::KsEvent( 99 PKSEVENT Event, 100 ULONG EventLength, 101 LPVOID EventData, 102 ULONG DataLength, 103 ULONG* BytesReturned) 104 { 105 assert(m_Handle != 0); 106 107 if (EventLength) 108 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned); 109 else 110 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned); 111 } 112 113 HRESULT 114 WINAPI 115 CKsNode_Constructor( 116 IUnknown * pUnkOuter, 117 HANDLE ParentHandle, 118 ULONG NodeId, 119 ACCESS_MASK DesiredAccess, 120 REFIID riid, 121 LPVOID * ppv) 122 { 123 HRESULT hr; 124 HANDLE handle; 125 KSNODE_CREATE NodeCreate; 126 127 #ifdef KSPROXY_TRACE 128 OutputDebugStringW(L"CKsNode_Constructor\n"); 129 #endif 130 131 //setup request 132 NodeCreate.CreateFlags = 0; 133 NodeCreate.Node = NodeId; 134 135 hr = KsCreateTopologyNode(ParentHandle, &NodeCreate, DesiredAccess, &handle); 136 if (hr != NOERROR) 137 { 138 OutputDebugString("CKsNode_Constructor failed to open device\n"); 139 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, hr); 140 } 141 142 CKsNode * quality = new CKsNode(pUnkOuter, handle); 143 144 if (!quality) 145 { 146 // free clock handle 147 CloseHandle(handle); 148 return E_OUTOFMEMORY; 149 } 150 151 if (FAILED(quality->QueryInterface(riid, ppv))) 152 { 153 /* not supported */ 154 delete quality; 155 return E_NOINTERFACE; 156 } 157 158 return NOERROR; 159 } 160