Пример подключаемого модуля расширения DLL
Важно!
Содержимое и пример кода в этом разделе устарели и в настоящее время не поддерживаются. Она может не работать с текущей цепочкой инструментов разработки драйверов.
В этом разделе содержится пример кода для подключаемого модуля расширения DLL, который предоставляет COM API поверх набора свойств KS.
В примере определяется класс CExtension, производный от CNodeControl. Реализация класса CNodeControl также предоставляется позже. CNodeControl является производным от предоставленного корпорацией Майкрософт интерфейса IKsNodeControl , который определен в Vidcap.h.
Vidcap.ax использует IKsNodeControl для информирования подключаемого модуля идентификатора узла расширения и предоставления ему экземпляра IKsControl. В частности, подключаемый модуль получает эти сведения через вызовы CExtension::p ut_NodeId и CExtension::p ut_KsControl. Возможные реализации этих методов можно найти далее в этом разделе для родительского класса CNodeControl.
Vidcap.h отображается в пакете SDK DirectX за лето 2004 г., а также в пакете SDK Для DirectX за февраль 2005 г. При установке этих пакетов необходимо установить дополнительные компоненты, чтобы получить Vidcap.h.
В Windows Vista и более поздних выпусках Vidcap.h входит в состав Microsoft Windows SDK.
Включите следующий код в файл заголовка класса с произвольным именем Xuproxy.h:
#include <ks.h>
#include <ksproxy.h>
#include <C:\Program Files\Microsoft DirectX 9.0 SDK (February 2005)\Extras\DirectShow\Include\vidcap.h>
#include <C:\Program Files\Microsoft DirectX 9.0 SDK (February 2005)\Extras\DirectShow\Include\ksmedia.h>
DEFINE_GUID(CLSID_ExtensionUnit, 0xzzzzzzzz, 0xzzzz, 0xzzzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz);
class CNodeControl :
public IKsNodeControl
{
public:
STDMETHOD(put_NodeId) (DWORD dwNodeId);
STDMETHOD(put_KsControl) (PVOID pKsControl);
DWORD m_dwNodeId;
CComPtr<IKsControl> m_pKsControl;
};
class CExtension :
public IExtensionUnit,
public CComObjectRootEx<CComObjectThreadModel>,
public CComCoClass<CExtension, &CLSID_ExtensionUnit>,
public CNodeControl
{
public:
CExtension();
STDMETHOD(FinalConstruct)();
BEGIN_COM_MAP(CExtension)
COM_INTERFACE_ENTRY(IKsNodeControl)
COM_INTERFACE_ENTRY(IExtensionUnit)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_NO_REGISTRY()
DECLARE_ONLY_AGGREGATABLE(CExtension)
// IExtensionUnit
public:
STDMETHOD (get_Info)(
ULONG ulSize,
BYTE pInfo[]);
STDMETHOD (get_InfoSize)(
ULONG *pulSize);
STDMETHOD (get_PropertySize)(
ULONG PropertyId,
ULONG *pulSize);
STDMETHOD (get_Property)(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[]);
STDMETHOD (put_Property)(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[]);
STDMETHOD (get_PropertyRange)(
ULONG PropertyId,
ULONG ulSize,
BYTE pMin[],
BYTE pMax[],
BYTE pSteppingDelta[],
BYTE pDefault[]);
};
#define STATIC_PROPSETID_VIDCAP_EXTENSION_UNIT \
0xXXXXXXXX,0xXXXX,0xXXXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
DEFINE_GUIDSTRUCT("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", \
PROPSETID_VIDCAP_EXTENSION_UNIT);
#define PROPSETID_VIDCAP_EXTENSION_UNIT \
DEFINE_GUIDNAMED(PROPSETID_VIDCAP_EXTENSION_UNIT)
Реализуйте два виртуальных метода из IKsNodeControl в CNodeControl. Затем эти методы наследуются экземплярами класса CExtension .
Следующий код находится в исходном файле с произвольным именем Xuproxy.cpp:
STDMETHODIMP
CNodeControl::put_NodeId(
DWORD dwNodeId)
{
m_dwNodeId = dwNodeId;
return S_OK;
}
STDMETHODIMP
CNodeControl::put_KsControl(
PVOID pKsControl)
{
HRESULT hr = S_OK;
IKsControl *pIKsControl;
if (!pKsControl) return E_POINTER;
pIKsControl = (IKsControl *) pKsControl;
if (m_pKsControl) m_pKsControl.Release();
hr = pIKsControl->QueryInterface(__uuidof(IKsControl),
(void **) &m_pKsControl);
return hr;
}
Также включите реализации методов CExtension в том же файле Xuproxy.cpp :
CExtension::CExtension()
{
m_pKsControl = NULL;
}
STDMETHODIMP
CExtension::FinalConstruct()
{
if (m_pOuterUnknown == NULL ) return E_FAIL;
return S_OK;
}
STDMETHODIMP
CExtension::get_InfoSize(
ULONG *pulSize)
{
HRESULT hr = S_OK;
ULONG ulBytesReturned;
KSP_NODE ExtensionProp;
if (!pulSize) return E_POINTER;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = KSPROPERTY_EXTENSION_UNIT_INFO;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
NULL,
0,
&ulBytesReturned);
if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA))
{
*pulSize = ulBytesReturned;
hr = S_OK;
}
return hr;
}
STDMETHODIMP
CExtension::get_Info(
ULONG ulSize,
BYTE pInfo[])
{
HRESULT hr = S_OK;
KSP_NODE ExtensionProp;
ULONG ulBytesReturned;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = KSPROPERTY_EXTENSION_UNIT_INFO;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
(PVOID) pInfo,
ulSize,
&ulBytesReturned);
return hr;
}
STDMETHODIMP
CExtension::get_PropertySize(
ULONG PropertyId,
ULONG *pulSize)
{
HRESULT hr = S_OK;
ULONG ulBytesReturned;
KSP_NODE ExtensionProp;
if (!pulSize) return E_POINTER;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = PropertyId;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
NULL,
0,
&ulBytesReturned);
if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA))
{
*pulSize = ulBytesReturned;
hr = S_OK;
}
return hr;
}
STDMETHODIMP
CExtension::get_Property(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[])
{
HRESULT hr = S_OK;
KSP_NODE ExtensionProp;
ULONG ulBytesReturned;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = PropertyId;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
(PVOID) pValue,
ulSize,
&ulBytesReturned);
return hr;
}
STDMETHODIMP
CExtension::put_Property(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[])
{
HRESULT hr = S_OK;
KSP_NODE ExtensionProp;
ULONG ulBytesReturned;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = PropertyId;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_SET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
(PVOID) pValue,
ulSize,
&ulBytesReturned);
return hr;
}
STDMETHODIMP
CExtension::get_PropertyRange(
ULONG PropertyId,
ULONG ulSize,
BYTE pMin[ ],
BYTE pMax[ ],
BYTE pSteppingDelta[ ],
BYTE pDefault[ ])
{
// IHV may add code here, current stub just returns S_OK
HRESULT hr = S_OK;
return hr;
}
CExtension::CExtension()
{
m_pKsControl = NULL;
}
STDMETHODIMP
CExtension::FinalConstruct()
{
if (m_pOuterUnknown == NULL) return E_FAIL;
return S_OK;
}