DLL de plug-in de unidade de extensão de exemplo
Importante
O conteúdo e o código de exemplo neste tópico estão desatualizados e atualmente sem suporte. Ele pode não funcionar com a cadeia de ferramentas de desenvolvimento de driver atual.
Este tópico contém um código de exemplo para uma DLL de plug-in de Unidade de Extensão que expõe uma API COM sobre um conjunto de propriedades KS.
O exemplo define uma classe chamada CExtension, que deriva de CNodeControl. A implementação da classe CNodeControl também é fornecida posteriormente. CNodeControl deriva da interface IKsNodeControl fornecida pela Microsoft, que é definida em Vidcap.h.
Vidcap.ax usa IKsNodeControl para informar o plug-in da ID do nó de extensão e fornecer uma instância do IKsControl. Especificamente, o plug-in recebe essas informações por meio de chamadas para CExtension::p ut_NodeId e CExtension::p ut_KsControl. Você pode encontrar possíveis implementações desses métodos posteriormente neste tópico para a classe pai CNodeControl.
Vidcap.h aparece no SDK do DirectX de verão de 2004 até o SDK do DirectX de fevereiro de 2005. Ao instalar esses pacotes, você deve instalar os Extras para obter o Vidcap.h.
No Windows Vista e versões posteriores, o Vidcap.h é incluído como parte do SDK do Microsoft Windows.
Inclua o seguinte código no arquivo de cabeçalho de classe, arbitrariamente chamado 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)
Implemente os dois métodos virtuais de IKsNodeControl em CNodeControl. Esses métodos são herdados por instâncias da classe CExtension .
O código a seguir está em um arquivo de origem arbitrariamente chamado 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;
}
Inclua também implementações dos métodos de CExtension no mesmo arquivo 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;
}