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

  1. // DPrtMapC.h : Declaration of the CDynamicPortMappingCollection
  2. #ifndef __DYNAMICPORTMAPPINGCOLLECTION_H_
  3. #define __DYNAMICPORTMAPPINGCOLLECTION_H_
  4. #include "dportmap.h"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CDynamicPortMappingCollection
  7. class ATL_NO_VTABLE CDynamicPortMappingCollection :
  8. public CComObjectRootEx<CComSingleThreadModel>,
  9. // public CComCoClass<CDynamicPortMappingCollection, &CLSID_DynamicPortMappingCollection>,
  10. public IDispatchImpl<IDynamicPortMappingCollection, &IID_IDynamicPortMappingCollection, &LIBID_NATUPNPLib>
  11. {
  12. private:
  13. CComPtr<IUPnPService> m_spUPS;
  14. public:
  15. CDynamicPortMappingCollection()
  16. {
  17. }
  18. //DECLARE_REGISTRY_RESOURCEID(IDR_DYNAMICPORTMAPPINGCOLLECTION)
  19. DECLARE_PROTECT_FINAL_CONSTRUCT()
  20. BEGIN_COM_MAP(CDynamicPortMappingCollection)
  21. COM_INTERFACE_ENTRY(IDynamicPortMappingCollection)
  22. COM_INTERFACE_ENTRY(IDispatch)
  23. END_COM_MAP()
  24. // IDynamicPortMappingCollection
  25. public:
  26. 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);
  27. STDMETHOD(Remove)(/*[in]*/ BSTR bstrRemoteHost, /*[in]*/ long lExternalPort, /*[in]*/ BSTR bstrProtocol);
  28. STDMETHOD(get_Count)(/*[out, retval]*/ long *pVal);
  29. STDMETHOD(get__NewEnum)(/*[out, retval]*/ IUnknown* *pVal);
  30. STDMETHOD(get_Item)(/*[in]*/ BSTR bstrRemoteHost, /*[in]*/ long lExternalPort, /*[in]*/ BSTR bstrProtocol, /*[out, retval]*/ IDynamicPortMapping ** ppDPM);
  31. // CDynamicPortMappingCollection
  32. public:
  33. HRESULT Initialize (IUPnPService * pUPS);
  34. };
  35. // quickie enumerator
  36. class CEnumDynamicPortMappingCollection : public IEnumVARIANT
  37. {
  38. private:
  39. CComPtr<IUPnPService> m_spUPS;
  40. long m_index, m_refs;
  41. CEnumDynamicPortMappingCollection ()
  42. {
  43. m_refs = 0;
  44. m_index = 0;
  45. }
  46. HRESULT Init (IUPnPService * pUPS, long lIndex)
  47. {
  48. m_index = lIndex;
  49. m_spUPS = pUPS;
  50. return S_OK;
  51. }
  52. public:
  53. static IEnumVARIANT * CreateInstance (IUPnPService * pUPS, long lIndex = 0)
  54. {
  55. CEnumDynamicPortMappingCollection * pCEV = new CEnumDynamicPortMappingCollection ();
  56. if (!pCEV)
  57. return NULL;
  58. HRESULT hr = pCEV->Init (pUPS, lIndex);
  59. if (FAILED(hr)) {
  60. delete pCEV;
  61. return NULL;
  62. }
  63. IEnumVARIANT * pIEV = NULL;
  64. pCEV->AddRef();
  65. pCEV->QueryInterface (IID_IEnumVARIANT, (void**)&pIEV);
  66. pCEV->Release();
  67. return pIEV;
  68. }
  69. // IUnknown
  70. virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppvObject)
  71. {
  72. NAT_API_ENTER
  73. if (ppvObject)
  74. *ppvObject = NULL;
  75. else
  76. return E_POINTER;
  77. HRESULT hr = S_OK;
  78. if ((riid == IID_IUnknown) ||
  79. (riid == IID_IEnumVARIANT) ){
  80. AddRef();
  81. *ppvObject = (void *)this;
  82. } else
  83. hr = E_NOINTERFACE;
  84. return hr;
  85. NAT_API_LEAVE
  86. }
  87. virtual ULONG STDMETHODCALLTYPE AddRef ()
  88. {
  89. return InterlockedIncrement ((PLONG)&m_refs);
  90. }
  91. virtual ULONG STDMETHODCALLTYPE Release ()
  92. {
  93. ULONG l = InterlockedDecrement ((PLONG)&m_refs);
  94. if (l == 0)
  95. delete this;
  96. return l;
  97. }
  98. // IEnumVARIANT
  99. virtual HRESULT STDMETHODCALLTYPE Next (/*[in]*/ ULONG celt, /*[out, size_is(celt), length_is(*pCeltFetched)]*/ VARIANT * rgVar, /*[out]*/ ULONG * pCeltFetched)
  100. {
  101. NAT_API_ENTER
  102. // clear stuff being passed in (just in case)
  103. if (pCeltFetched) *pCeltFetched = 0;
  104. for (ULONG i=0; i<celt; i++)
  105. VariantInit (&rgVar[i]);
  106. HRESULT hr = S_OK;
  107. // get the next celt elements
  108. for (i=0; i<celt; i++) {
  109. // ask service for more....
  110. CComPtr<IDynamicPortMapping> spDPM = NULL;
  111. hr = CDynamicPortMapping::CreateInstance (m_spUPS, (long)m_index+i, &spDPM);
  112. if (!spDPM)
  113. break;
  114. // can't fail
  115. V_VT (&rgVar[i]) = VT_DISPATCH;
  116. spDPM->QueryInterface (__uuidof(IDispatch),
  117. (void**)&V_DISPATCH (&rgVar[i]));
  118. }
  119. if (hr == HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND))
  120. hr = S_OK; // no more; will return S_FALSE below
  121. if (FAILED(hr)) {
  122. // on error clear variant array....
  123. for (ULONG j=0; j<i; j++)
  124. VariantClear (&rgVar[j]);
  125. return hr;
  126. }
  127. // now update index
  128. m_index += i;
  129. // fill out how many we're returning
  130. if (pCeltFetched)
  131. *pCeltFetched = i;
  132. return i < celt ? S_FALSE : S_OK;
  133. NAT_API_LEAVE
  134. }
  135. virtual HRESULT STDMETHODCALLTYPE Skip (/*[in]*/ ULONG celt)
  136. {
  137. NAT_API_ENTER
  138. if (celt + m_index > GetTotal())
  139. return S_FALSE;
  140. m_index += celt;
  141. return S_OK;
  142. NAT_API_LEAVE
  143. }
  144. virtual HRESULT STDMETHODCALLTYPE Reset ()
  145. {
  146. NAT_API_ENTER
  147. m_index = 0;
  148. return S_OK;
  149. NAT_API_LEAVE
  150. }
  151. virtual HRESULT STDMETHODCALLTYPE Clone (/*[out]*/ IEnumVARIANT ** ppEnum)
  152. {
  153. NAT_API_ENTER
  154. if (!(*ppEnum = CreateInstance (m_spUPS, m_index)))
  155. return E_OUTOFMEMORY;
  156. return S_OK;
  157. NAT_API_LEAVE
  158. }
  159. private:
  160. ULONG GetTotal()
  161. {
  162. ULONG ul = 0;
  163. GetNumberOfEntries (m_spUPS, &ul);
  164. return ul;
  165. }
  166. };
  167. #endif //__DYNAMICPORTMAPPINGCOLLECTION_H_