Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

205 lines
5.4 KiB

// 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_