206 lines
5.4 KiB
C++
206 lines
5.4 KiB
C++
// DPrtMapC.h : Declaration of the CDynamicPortMappingCollection
|
|
|
|
#ifndef __DYNAMICPORTMAPPINGCOLLECTION_H_
|
|
#define __DYNAMICPORTMAPPINGCOLLECTION_H_
|
|
|
|
#include "dportmap.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDynamicPortMappingCollection
|
|
class ATL_NO_VTABLE CDynamicPortMappingCollection :
|
|
public CComObjectRootEx<CComSingleThreadModel>,
|
|
// public CComCoClass<CDynamicPortMappingCollection, &CLSID_DynamicPortMappingCollection>,
|
|
public IDispatchImpl<IDynamicPortMappingCollection, &IID_IDynamicPortMappingCollection, &LIBID_NATUPNPLib>
|
|
{
|
|
private:
|
|
CComPtr<IUPnPService> m_spUPS;
|
|
|
|
public:
|
|
CDynamicPortMappingCollection()
|
|
{
|
|
}
|
|
|
|
//DECLARE_REGISTRY_RESOURCEID(IDR_DYNAMICPORTMAPPINGCOLLECTION)
|
|
|
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
|
|
|
BEGIN_COM_MAP(CDynamicPortMappingCollection)
|
|
COM_INTERFACE_ENTRY(IDynamicPortMappingCollection)
|
|
COM_INTERFACE_ENTRY(IDispatch)
|
|
END_COM_MAP()
|
|
|
|
// IDynamicPortMappingCollection
|
|
public:
|
|
STDMETHOD(Add)(/*[in]*/ BSTR bstrRemoteHost, /*[in]*/ long lExternalPort, /*[in]*/ BSTR bstrProtocol, /*[in]*/ long lInternalPort, /*[in]*/ BSTR bstrInternalClient, /*[in]*/ VARIANT_BOOL bEnabled, /*[in]*/ BSTR bstrDescription, /*[in]*/ long lLeaseDuration, /*[retval][out]*/ IDynamicPortMapping **ppDPM);
|
|
STDMETHOD(Remove)(/*[in]*/ BSTR bstrRemoteHost, /*[in]*/ long lExternalPort, /*[in]*/ BSTR bstrProtocol);
|
|
STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal);
|
|
STDMETHOD(get__NewEnum)(/*[out, retval]*/ IUnknown* *pVal);
|
|
STDMETHOD(get_Item)(/*[in]*/ BSTR bstrRemoteHost, /*[in]*/ long lExternalPort, /*[in]*/ BSTR bstrProtocol, /*[out, retval]*/ IDynamicPortMapping ** ppDPM);
|
|
|
|
// CDynamicPortMappingCollection
|
|
public:
|
|
HRESULT Initialize (IUPnPService * pUPS);
|
|
};
|
|
|
|
// quickie enumerator
|
|
class CEnumDynamicPortMappingCollection : public IEnumVARIANT
|
|
{
|
|
private:
|
|
CComPtr<IUPnPService> m_spUPS;
|
|
long m_index, m_refs;
|
|
|
|
CEnumDynamicPortMappingCollection ()
|
|
{
|
|
m_refs = 0;
|
|
m_index = 0;
|
|
}
|
|
HRESULT Init (IUPnPService * pUPS, long lIndex)
|
|
{
|
|
m_index = lIndex;
|
|
m_spUPS = pUPS;
|
|
return S_OK;
|
|
}
|
|
|
|
public:
|
|
static IEnumVARIANT * CreateInstance (IUPnPService * pUPS, long lIndex = 0)
|
|
{
|
|
CEnumDynamicPortMappingCollection * pCEV = new CEnumDynamicPortMappingCollection ();
|
|
if (!pCEV)
|
|
return NULL;
|
|
HRESULT hr = pCEV->Init (pUPS, lIndex);
|
|
if (FAILED(hr)) {
|
|
delete pCEV;
|
|
return NULL;
|
|
}
|
|
|
|
IEnumVARIANT * pIEV = NULL;
|
|
pCEV->AddRef();
|
|
pCEV->QueryInterface (IID_IEnumVARIANT, (void**)&pIEV);
|
|
pCEV->Release();
|
|
return pIEV;
|
|
}
|
|
|
|
// IUnknown
|
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppvObject)
|
|
{
|
|
NAT_API_ENTER
|
|
|
|
if (ppvObject)
|
|
*ppvObject = NULL;
|
|
else
|
|
return E_POINTER;
|
|
|
|
HRESULT hr = S_OK;
|
|
if ((riid == IID_IUnknown) ||
|
|
(riid == IID_IEnumVARIANT) ){
|
|
AddRef();
|
|
*ppvObject = (void *)this;
|
|
} else
|
|
hr = E_NOINTERFACE;
|
|
return hr;
|
|
|
|
NAT_API_LEAVE
|
|
}
|
|
virtual ULONG STDMETHODCALLTYPE AddRef ()
|
|
{
|
|
return InterlockedIncrement ((PLONG)&m_refs);
|
|
}
|
|
virtual ULONG STDMETHODCALLTYPE Release ()
|
|
{
|
|
ULONG l = InterlockedDecrement ((PLONG)&m_refs);
|
|
if (l == 0)
|
|
delete this;
|
|
return l;
|
|
}
|
|
|
|
// IEnumVARIANT
|
|
virtual HRESULT STDMETHODCALLTYPE Next (/*[in]*/ ULONG celt, /*[out, size_is(celt), length_is(*pCeltFetched)]*/ VARIANT * rgVar, /*[out]*/ ULONG * pCeltFetched)
|
|
{
|
|
NAT_API_ENTER
|
|
|
|
// clear stuff being passed in (just in case)
|
|
if (pCeltFetched) *pCeltFetched = 0;
|
|
for (ULONG i=0; i<celt; i++)
|
|
VariantInit (&rgVar[i]);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
// get the next celt elements
|
|
for (i=0; i<celt; i++) {
|
|
|
|
// ask service for more....
|
|
CComPtr<IDynamicPortMapping> spDPM = NULL;
|
|
hr = CDynamicPortMapping::CreateInstance (m_spUPS, (long)m_index+i, &spDPM);
|
|
if (!spDPM)
|
|
break;
|
|
|
|
// can't fail
|
|
V_VT (&rgVar[i]) = VT_DISPATCH;
|
|
spDPM->QueryInterface (__uuidof(IDispatch),
|
|
(void**)&V_DISPATCH (&rgVar[i]));
|
|
}
|
|
if (hr == HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND))
|
|
hr = S_OK; // no more; will return S_FALSE below
|
|
|
|
if (FAILED(hr)) {
|
|
// on error clear variant array....
|
|
for (ULONG j=0; j<i; j++)
|
|
VariantClear (&rgVar[j]);
|
|
return hr;
|
|
}
|
|
|
|
// now update index
|
|
m_index += i;
|
|
|
|
// fill out how many we're returning
|
|
if (pCeltFetched)
|
|
*pCeltFetched = i;
|
|
return i < celt ? S_FALSE : S_OK;
|
|
|
|
NAT_API_LEAVE
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Skip (/*[in]*/ ULONG celt)
|
|
{
|
|
NAT_API_ENTER
|
|
|
|
if (celt + m_index > GetTotal())
|
|
return S_FALSE;
|
|
m_index += celt;
|
|
return S_OK;
|
|
|
|
NAT_API_LEAVE
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Reset ()
|
|
{
|
|
NAT_API_ENTER
|
|
|
|
m_index = 0;
|
|
return S_OK;
|
|
|
|
NAT_API_LEAVE
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Clone (/*[out]*/ IEnumVARIANT ** ppEnum)
|
|
{
|
|
NAT_API_ENTER
|
|
|
|
if (!(*ppEnum = CreateInstance (m_spUPS, m_index)))
|
|
return E_OUTOFMEMORY;
|
|
return S_OK;
|
|
|
|
NAT_API_LEAVE
|
|
}
|
|
|
|
private:
|
|
ULONG GetTotal()
|
|
{
|
|
ULONG ul = 0;
|
|
GetNumberOfEntries (m_spUPS, &ul);
|
|
return ul;
|
|
}
|
|
};
|
|
|
|
#endif //__DYNAMICPORTMAPPINGCOLLECTION_H_
|