2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS BDA Proxy
4 * FILE: dll/directx/bdaplgin/classfactory.cpp
5 * PURPOSE: ClassFactory interface
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
12 const GUID IID_IKsObject
= {0x423c13a2, 0x2070, 0x11d0, {0x9e, 0xf7, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
15 const GUID CLSID_DVBTNetworkProvider
= {0x216c62df, 0x6d7f, 0x4e9a, {0x85, 0x71, 0x5, 0xf1, 0x4e, 0xdb, 0x76, 0x6a}};
17 const GUID KSPROPSETID_BdaTopology
= {0xa14ee835, 0x0a23, 0x11d3, {0x9c, 0xc7, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
18 const GUID KSMETHODSETID_BdaDeviceConfiguration
= {0x71985f45, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
19 const GUID KSMETHODSETID_BdaChangeSync
= {0xfd0a5af3, 0xb41d, 0x11d2, {0x9c, 0x95, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}};
20 const GUID IID_IBaseFilter
= {0x56a86895, 0x0ad4, 0x11ce, {0xb0,0x3a, 0x00,0x20,0xaf,0x0b,0xa7,0x70}};
21 const GUID IID_IAsyncReader
= {0x56A868AA, 0x0AD4, 0x11CE, {0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
22 const GUID IID_IAMOpenProgress
= {0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D}};
23 const GUID IID_IBDA_Topology
= {0x79B56888, 0x7FEA, 0x4690, {0xB4, 0x5D, 0x38, 0xFD, 0x3C, 0x78, 0x49, 0xBE}};
24 const GUID IID_IBDA_NetworkProvider
= {0xfd501041, 0x8ebe, 0x11ce, {0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa2}};
25 const GUID IID_IBDA_DeviceControl
= {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
27 const GUID IID_IDistributorNotify
= {0x56a868af, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
31 class CBDADeviceControl
: public IBDA_DeviceControl
,
35 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
37 STDMETHODIMP_(ULONG
) AddRef()
39 InterlockedIncrement(&m_Ref
);
42 STDMETHODIMP_(ULONG
) Release()
44 InterlockedDecrement(&m_Ref
);
53 // IBDA_DeviceControl methods
54 HRESULT STDMETHODCALLTYPE
StartChanges( void);
55 HRESULT STDMETHODCALLTYPE
CheckChanges( void);
56 HRESULT STDMETHODCALLTYPE
CommitChanges( void);
57 HRESULT STDMETHODCALLTYPE
GetChangeState(ULONG
*pState
);
59 // IBDA_Topology methods
60 HRESULT STDMETHODCALLTYPE
GetNodeTypes(ULONG
*pulcNodeTypes
, ULONG ulcNodeTypesMax
, ULONG
* rgulNodeTypes
);
61 HRESULT STDMETHODCALLTYPE
GetNodeDescriptors(ULONG
*ulcNodeDescriptors
, ULONG ulcNodeDescriptorsMax
, BDANODE_DESCRIPTOR
* rgNodeDescriptors
);
62 HRESULT STDMETHODCALLTYPE
GetNodeInterfaces(ULONG ulNodeType
, ULONG
*pulcInterfaces
, ULONG ulcInterfacesMax
, GUID
* rgguidInterfaces
);
63 HRESULT STDMETHODCALLTYPE
GetPinTypes(ULONG
*pulcPinTypes
, ULONG ulcPinTypesMax
, ULONG
*rgulPinTypes
);
64 HRESULT STDMETHODCALLTYPE
GetTemplateConnections(ULONG
*pulcConnections
, ULONG ulcConnectionsMax
, BDA_TEMPLATE_CONNECTION
* rgConnections
);
65 HRESULT STDMETHODCALLTYPE
CreatePin(ULONG ulPinType
, ULONG
*pulPinId
);
66 HRESULT STDMETHODCALLTYPE
DeletePin(ULONG ulPinId
);
67 HRESULT STDMETHODCALLTYPE
SetMediaType(ULONG ulPinId
, AM_MEDIA_TYPE
*pMediaType
);
68 HRESULT STDMETHODCALLTYPE
SetMedium(ULONG ulPinId
, REGPINMEDIUM
*pMedium
);
69 HRESULT STDMETHODCALLTYPE
CreateTopology(ULONG ulInputPinId
, ULONG ulOutputPinId
);
70 HRESULT STDMETHODCALLTYPE
GetControlNode(ULONG ulInputPinId
, ULONG ulOutputPinId
, ULONG ulNodeType
, IUnknown
**ppControlNode
);
72 CBDADeviceControl(IUnknown
* pUnkOuter
, IBaseFilter
*pFilter
, HANDLE hFile
) : m_Ref(0), m_pUnkOuter(pUnkOuter
), m_Handle(hFile
), m_pFilter(pFilter
){};
73 virtual ~CBDADeviceControl(){};
77 IUnknown
* m_pUnkOuter
;
79 IBaseFilter
* m_pFilter
;
84 CBDADeviceControl::QueryInterface(
90 if (IsEqualGUID(refiid
, IID_IUnknown
))
92 *Output
= PVOID(this);
93 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
96 if (IsEqualGUID(refiid
, IID_IBDA_DeviceControl
))
98 *Output
= (IBDA_DeviceControl
*)(this);
99 reinterpret_cast<IBDA_DeviceControl
*>(*Output
)->AddRef();
103 if (IsEqualGUID(refiid
, IID_IBDA_Topology
))
105 *Output
= (IBDA_Topology
*)(this);
106 reinterpret_cast<IBDA_Topology
*>(*Output
)->AddRef();
110 return E_NOINTERFACE
;
114 //-------------------------------------------------------------------
115 // IBDA_DeviceControl methods
119 CBDADeviceControl::StartChanges( void)
126 Method
.Set
= KSMETHODSETID_BdaChangeSync
;
127 Method
.Id
= KSMETHOD_BDA_START_CHANGES
;
128 Method
.Flags
= KSMETHOD_TYPE_NONE
;
130 /* execute request */
131 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_METHOD
, (PVOID
)&Method
, sizeof(KSMETHOD
), NULL
, 0, &BytesReturned
);
133 #ifdef BDAPLGIN_TRACE
135 swprintf(Buffer
, L
"CBDADeviceControl::StartChanges: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
136 OutputDebugStringW(Buffer
);
145 CBDADeviceControl::CheckChanges( void)
152 Method
.Set
= KSMETHODSETID_BdaChangeSync
;
153 Method
.Id
= KSMETHOD_BDA_CHECK_CHANGES
;
154 Method
.Flags
= KSMETHOD_TYPE_NONE
;
156 /* execute request */
157 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_METHOD
, (PVOID
)&Method
, sizeof(KSMETHOD
), NULL
, 0, &BytesReturned
);
159 #ifdef BDAPLGIN_TRACE
161 swprintf(Buffer
, L
"CBDADeviceControl::CheckChanges: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
162 OutputDebugStringW(Buffer
);
171 CBDADeviceControl::CommitChanges( void)
178 Method
.Set
= KSMETHODSETID_BdaChangeSync
;
179 Method
.Id
= KSMETHOD_BDA_COMMIT_CHANGES
;
180 Method
.Flags
= KSMETHOD_TYPE_NONE
;
182 /* execute request */
183 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_METHOD
, (PVOID
)&Method
, sizeof(KSMETHOD
), NULL
, 0, &BytesReturned
);
185 #ifdef BDAPLGIN_TRACE
187 swprintf(Buffer
, L
"CBDADeviceControl::CommitChanges: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
188 OutputDebugStringW(Buffer
);
196 CBDADeviceControl::GetChangeState(ULONG
*pState
)
200 *pState
= BDA_CHANGES_COMPLETE
;
209 //-------------------------------------------------------------------
210 // IBDA_Topology methods
214 CBDADeviceControl::GetNodeTypes(ULONG
*pulcNodeTypes
, ULONG ulcNodeTypesMax
, ULONG
* rgulNodeTypes
)
221 Property
.Set
= KSPROPSETID_BdaTopology
;
222 Property
.Id
= KSPROPERTY_BDA_NODE_TYPES
;
223 Property
.Flags
= KSPROPERTY_TYPE_GET
;
226 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), rgulNodeTypes
, sizeof(ULONG
) * ulcNodeTypesMax
, &BytesReturned
);
228 *pulcNodeTypes
= (BytesReturned
/ sizeof(ULONG
));
230 #ifdef BDAPLGIN_TRACE
232 swprintf(Buffer
, L
"CBDADeviceControl::GetNodeTypes: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
233 OutputDebugStringW(Buffer
);
237 for(ULONG Index
= 0; Index
< *pulcNodeTypes
; Index
++)
239 swprintf(Buffer
, L
"CBDADeviceControl::GetPinTypes: Index %lu Value %lx\n", Index
, rgulNodeTypes
[Index
]);
240 OutputDebugStringW(Buffer
);
250 CBDADeviceControl::GetNodeDescriptors(ULONG
*ulcNodeDescriptors
, ULONG ulcNodeDescriptorsMax
, BDANODE_DESCRIPTOR
* rgNodeDescriptors
)
258 Property
.Set
= KSPROPSETID_BdaTopology
;
259 Property
.Id
= KSPROPERTY_BDA_NODE_DESCRIPTORS
;
260 Property
.Flags
= KSPROPERTY_TYPE_GET
;
263 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), rgNodeDescriptors
, sizeof(BDANODE_DESCRIPTOR
) * ulcNodeDescriptorsMax
, &BytesReturned
);
265 *ulcNodeDescriptors
= (BytesReturned
/ sizeof(BDANODE_DESCRIPTOR
));
267 #ifdef BDAPLGIN_TRACE
269 swprintf(Buffer
, L
"CBDADeviceControl::GetNodeDescriptors: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
270 OutputDebugStringW(Buffer
);
275 for(ULONG Index
= 0; Index
< min(*ulcNodeDescriptors
, ulcNodeDescriptorsMax
); Index
++)
277 LPOLESTR pGUIDFunction
, pGUIDName
;
279 StringFromCLSID(rgNodeDescriptors
[Index
].guidFunction
, &pGUIDFunction
);
280 StringFromCLSID(rgNodeDescriptors
[Index
].guidName
, &pGUIDName
);
282 swprintf(Buffer
, L
"CBDADeviceControl::GetPinTypes: Index %lu Value %lx\nFunction %s\n Name %s\n-----\n", Index
, rgNodeDescriptors
[Index
].ulBdaNodeType
, pGUIDFunction
, pGUIDName
);
283 OutputDebugStringW(Buffer
);
294 CBDADeviceControl::GetNodeInterfaces(ULONG ulNodeType
, ULONG
*pulcInterfaces
, ULONG ulcInterfacesMax
, GUID
* rgguidInterfaces
)
302 Property
.Property
.Set
= KSPROPSETID_BdaTopology
;
303 Property
.Property
.Id
= KSPROPERTY_BDA_NODE_PROPERTIES
;
304 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
305 Property
.NodeId
= ulNodeType
;
306 Property
.Reserved
= 0;
309 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_NODE
), rgguidInterfaces
, sizeof(GUID
) * ulcInterfacesMax
, &BytesReturned
);
311 *pulcInterfaces
= (BytesReturned
/ sizeof(GUID
));
313 #ifdef BDAPLGIN_TRACE
315 swprintf(Buffer
, L
"CBDADeviceControl::GetNodeInterfaces: hr %lx, BytesReturned %lu ulNodeType %lu\n", hr
, BytesReturned
, ulNodeType
);
316 OutputDebugStringW(Buffer
);
320 for(ULONG Index
= 0; Index
< min(*pulcInterfaces
, ulcInterfacesMax
); Index
++)
324 StringFromCLSID(rgguidInterfaces
[Index
], &pstr
);
326 swprintf(Buffer
, L
"CBDADeviceControl::GetNodeInterfaces: Index %lu Name %s\n", Index
, pstr
);
327 OutputDebugStringW(Buffer
);
337 CBDADeviceControl::GetPinTypes(ULONG
*pulcPinTypes
, ULONG ulcPinTypesMax
, ULONG
*rgulPinTypes
)
344 Property
.Set
= KSPROPSETID_BdaTopology
;
345 Property
.Id
= KSPROPERTY_BDA_PIN_TYPES
;
346 Property
.Flags
= KSPROPERTY_TYPE_GET
;
349 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), rgulPinTypes
, sizeof(ULONG
) * ulcPinTypesMax
, &BytesReturned
);
351 *pulcPinTypes
= (BytesReturned
/ sizeof(ULONG
));
353 #ifdef BDAPLGIN_TRACE
355 swprintf(Buffer
, L
"CBDADeviceControl::GetPinTypes: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
356 OutputDebugStringW(Buffer
);
360 for(ULONG Index
= 0; Index
< *pulcPinTypes
; Index
++)
362 swprintf(Buffer
, L
"CBDADeviceControl::GetPinTypes: Index %lu Value %lx\n", Index
, rgulPinTypes
[Index
]);
363 OutputDebugStringW(Buffer
);
373 CBDADeviceControl::GetTemplateConnections(ULONG
*pulcConnections
, ULONG ulcConnectionsMax
, BDA_TEMPLATE_CONNECTION
* rgConnections
)
375 #ifdef BDAPLGIN_TRACE
376 OutputDebugStringW(L
"CBDADeviceControl::GetTemplateConnections: NotImplemented\n");
384 CBDADeviceControl::CreatePin(ULONG ulPinType
, ULONG
*pulPinId
)
386 #ifdef BDAPLGIN_TRACE
387 OutputDebugStringW(L
"CBDADeviceControl::CreatePin: NotImplemented\n");
395 CBDADeviceControl::DeletePin(ULONG ulPinId
)
397 #ifdef BDAPLGIN_TRACE
398 OutputDebugStringW(L
"CBDADeviceControl::DeletePin: NotImplemented\n");
406 CBDADeviceControl::SetMediaType(ULONG ulPinId
, AM_MEDIA_TYPE
*pMediaType
)
408 #ifdef BDAPLGIN_TRACE
409 OutputDebugStringW(L
"CBDADeviceControl::SetMediaType: NotImplemented\n");
417 CBDADeviceControl::SetMedium(ULONG ulPinId
, REGPINMEDIUM
*pMedium
)
419 #ifdef BDAPLGIN_TRACE
420 OutputDebugStringW(L
"CBDADeviceControl::SetMedium: NotImplemented\n");
428 CBDADeviceControl::CreateTopology(ULONG ulInputPinId
, ULONG ulOutputPinId
)
430 KSM_BDA_PIN_PAIR Method
;
432 ULONG BytesReturned
= 0;
434 Method
.Method
.Flags
= KSMETHOD_TYPE_NONE
;
435 Method
.Method
.Id
= KSMETHOD_BDA_CREATE_TOPOLOGY
;
436 Method
.Method
.Set
= KSMETHODSETID_BdaDeviceConfiguration
;
437 Method
.InputPinId
= ulInputPinId
;
438 Method
.OutputPinId
= ulOutputPinId
;
440 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_METHOD
, (PVOID
)&Method
, sizeof(KSM_BDA_PIN_PAIR
), NULL
, 0, &BytesReturned
);
442 #ifdef BDAPLGIN_TRACE
444 swprintf(Buffer
, L
"CBDADeviceControl::CreateTopology: hr %lx, BytesReturned %lu\n", hr
, BytesReturned
);
445 OutputDebugStringW(Buffer
);
453 CBDADeviceControl::GetControlNode(ULONG ulInputPinId
, ULONG ulOutputPinId
, ULONG ulNodeType
, IUnknown
**ppControlNode
)
458 KSP_BDA_NODE_PIN Property
;
461 Property
.Property
.Set
= KSPROPSETID_BdaTopology
;
462 Property
.Property
.Id
= KSPROPERTY_BDA_CONTROLLING_PIN_ID
;
463 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
464 Property
.ulInputPinId
= ulInputPinId
;
465 Property
.ulOutputPinId
= ulOutputPinId
;
466 Property
.ulNodeType
= ulNodeType
;
469 // WinXP SP3 expects minimum sizeof(KSP_BDA_NODE_PIN) + sizeof(ULONG)
470 // seems a driver to be a driver bug
472 hr
= KsSynchronousDeviceControl(m_Handle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_BDA_NODE_PIN
) + sizeof(ULONG
), &PinId
, sizeof(ULONG
), &BytesReturned
);
474 #ifdef BDAPLGIN_TRACE
476 swprintf(Buffer
, L
"CBDADeviceControl::GetControlNode: hr %lx, BytesReturned %lu PinId %lu ulInputPinId %lu ulOutputPinId %lu ulNodeType %lu\n", hr
, BytesReturned
, PinId
, ulInputPinId
, ulOutputPinId
, ulNodeType
);
477 OutputDebugStringW(Buffer
);
483 hr
= CControlNode_fnConstructor(m_pFilter
, ulNodeType
, PinId
, IID_IUnknown
, (LPVOID
*)ppControlNode
);
485 #ifdef BDAPLGIN_TRACE
486 swprintf(Buffer
, L
"CBDADeviceControl::GetControlNode: hr %lx\n", hr
);
487 OutputDebugStringW(Buffer
);
495 CBDADeviceControl_fnConstructor(
496 IUnknown
* pUnkOuter
,
501 IKsObject
*pObject
= NULL
;
502 IBaseFilter
*pFilter
= NULL
;
505 #ifdef BDAPLGIN_TRACE
506 OutputDebugStringW(L
"CBDADeviceControl_fnConstructor\n");
514 // query for IKsObject
515 hr
= pUnkOuter
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
518 return E_NOINTERFACE
;
521 assert(hr
== NOERROR
);
523 // query for IBaseFilter interface support
524 hr
= pUnkOuter
->QueryInterface(IID_IBaseFilter
, (void**)&pFilter
);
530 return E_NOINTERFACE
;
533 // another sanity check
534 assert(pObject
!= NULL
);
537 hFile
= pObject
->KsGetObjectHandle();
539 // one more sanity check
540 assert(hFile
!= NULL
&& hFile
!= INVALID_HANDLE_VALUE
);
542 // release IKsObject interface
548 // construct device control
549 CBDADeviceControl
* handler
= new CBDADeviceControl(pUnkOuter
, pFilter
, hFile
);
552 return E_OUTOFMEMORY
;
554 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
558 return E_NOINTERFACE
;