//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000 - 2001 // // File: H N A P I . H // // Contents: OEM API // // Notes: // // Author: billi 21 Nov 2000 // //---------------------------------------------------------------------------- #pragma once #define HNET_OEM_API_ENTER try { #define HNET_OEM_API_LEAVE } catch (...) { return DISP_E_EXCEPTION; } #include class HNet_Oem_SEH_Exception { private: unsigned int m_uSECode; public: HNet_Oem_SEH_Exception(unsigned int uSECode) : m_uSECode(uSECode) {} HNet_Oem_SEH_Exception() {} ~HNet_Oem_SEH_Exception() {} unsigned int getSeHNumber() { return m_uSECode; } }; void __cdecl hnet_oem_trans_func( unsigned int uSECode, EXCEPTION_POINTERS* pExp ); void EnableOEMExceptionHandling(); void DisableOEMExceptionHandling(); #ifndef IID_PPV_ARG #define IID_PPV_ARG(Type, Expr) \ __uuidof(Type), reinterpret_cast(static_cast((Expr))) #endif #ifndef ReleaseObj #define ReleaseObj(obj) (( obj ) ? (obj)->Release() : 0) #endif BOOLEAN IsSecureContext(); BOOLEAN IsNotifyApproved(); HRESULT InitializeOemApi( HINSTANCE hInstance ); HRESULT ReleaseOemApi(); HRESULT _ObtainIcsSettingsObj( IHNetIcsSettings** ppIcsSettings ); // structs typedef struct tagICSPortMapping { OLECHAR *pszwName; UCHAR ucIPProtocol; USHORT usExternalPort; USHORT usInternalPort; DWORD dwOptions; OLECHAR *pszwTargetName; OLECHAR *pszwTargetIPAddress; VARIANT_BOOL bEnabled; } ICS_PORTMAPPING, *LPICS_PORTMAPPING; typedef struct tagICS_RESPONSE_RANGE { UCHAR ucIPProtocol; USHORT usStartPort; USHORT usEndPort; } ICS_RESPONSE_RANGE, *LPICS_RESPONSE_RANGE; typedef struct tagICS_APPLICATION_DEFINITION { VARIANT_BOOL bEnabled; OLECHAR *pszwName; UCHAR ucIPProtocol; USHORT usOutgoingPort; DWORD dwOptions; USHORT uscResponses; ICS_RESPONSE_RANGE lpResponse[1]; } ICS_APPLICATION_DEFINITION, *LPICS_APPLICATION_DEFINITION; class ATL_NO_VTABLE CNetConnectionProps : public CComObjectRootEx, public IDispatchImpl { private: INetConnection* m_pNetConnection; public: BEGIN_COM_MAP(CNetConnectionProps) COM_INTERFACE_ENTRY(INetConnectionProps) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() CNetConnectionProps() { m_pNetConnection = NULL; } ~CNetConnectionProps() { ReleaseObj (m_pNetConnection); } HRESULT Initialize (INetConnection * pNC) { _ASSERT (pNC); if (!pNC) return E_POINTER; ReleaseObj (m_pNetConnection); m_pNetConnection = pNC; m_pNetConnection->AddRef(); return S_OK; } // INetConnectionProps STDMETHODIMP get_Guid (BSTR * pbstrGuid) { HNET_OEM_API_ENTER if (!pbstrGuid) return E_POINTER; *pbstrGuid = NULL; _ASSERT (m_pNetConnection); if (!m_pNetConnection) return E_UNEXPECTED; NETCON_PROPERTIES * pNCP = NULL; HRESULT hr = m_pNetConnection->GetProperties (&pNCP); if (pNCP) { LPOLESTR lpo = NULL; hr = StringFromCLSID (pNCP->guidId, &lpo); if (lpo) { *pbstrGuid = SysAllocString (lpo); if (!*pbstrGuid) hr = E_OUTOFMEMORY; CoTaskMemFree (lpo); } NcFreeNetconProperties (pNCP); } return hr; HNET_OEM_API_LEAVE } STDMETHODIMP get_Name (BSTR * pbstrName) { HNET_OEM_API_ENTER if (!pbstrName) return E_POINTER; *pbstrName = NULL; _ASSERT (m_pNetConnection); if (!m_pNetConnection) return E_UNEXPECTED; NETCON_PROPERTIES * pNCP = NULL; HRESULT hr = m_pNetConnection->GetProperties (&pNCP); if (pNCP) { *pbstrName = SysAllocString (pNCP->pszwName); if (!*pbstrName) hr = E_OUTOFMEMORY; NcFreeNetconProperties (pNCP); } return hr; HNET_OEM_API_LEAVE } STDMETHODIMP get_DeviceName(BSTR * pbstrDeviceName) { HNET_OEM_API_ENTER if (!pbstrDeviceName) return E_POINTER; *pbstrDeviceName = NULL; _ASSERT (m_pNetConnection); if (!m_pNetConnection) return E_UNEXPECTED; NETCON_PROPERTIES * pNCP = NULL; HRESULT hr = m_pNetConnection->GetProperties (&pNCP); if (pNCP) { *pbstrDeviceName = SysAllocString (pNCP->pszwDeviceName); if (!*pbstrDeviceName) hr = E_OUTOFMEMORY; NcFreeNetconProperties (pNCP); } return hr; HNET_OEM_API_LEAVE } STDMETHODIMP get_Status (NETCON_STATUS * pStatus) { HNET_OEM_API_ENTER if (!pStatus) return E_POINTER; // *pStatus = NULL; _ASSERT (m_pNetConnection); if (!m_pNetConnection) return E_UNEXPECTED; NETCON_PROPERTIES * pNCP = NULL; HRESULT hr = m_pNetConnection->GetProperties (&pNCP); if (pNCP) { *pStatus = pNCP->Status; NcFreeNetconProperties (pNCP); } return hr; HNET_OEM_API_LEAVE } STDMETHODIMP get_MediaType (NETCON_MEDIATYPE * pMediaType) { HNET_OEM_API_ENTER if (!pMediaType) return E_POINTER; *pMediaType = NCM_NONE; _ASSERT (m_pNetConnection); if (!m_pNetConnection) return E_UNEXPECTED; NETCON_PROPERTIES * pNCP = NULL; HRESULT hr = m_pNetConnection->GetProperties (&pNCP); if (pNCP) { *pMediaType = pNCP->MediaType; NcFreeNetconProperties (pNCP); } return hr; HNET_OEM_API_LEAVE } STDMETHODIMP get_Characteristics (DWORD * pdwFlags) { HNET_OEM_API_ENTER if (!pdwFlags) return E_POINTER; *pdwFlags = NCCF_NONE; _ASSERT (m_pNetConnection); if (!m_pNetConnection) return E_UNEXPECTED; NETCON_PROPERTIES * pNCP = NULL; HRESULT hr = m_pNetConnection->GetProperties (&pNCP); if (pNCP) { *pdwFlags = pNCP->dwCharacter; NcFreeNetconProperties (pNCP); } return hr; HNET_OEM_API_LEAVE } }; class ATL_NO_VTABLE CNetSharingConfiguration : public CComObjectRootEx, public IDispatchImpl { private: IHNetConnection* m_pHNetConnection; IHNetProtocolSettings* m_pSettings; CRITICAL_SECTION m_csSharingConfiguration; // private method called from 2 wrappers below (get_SharingEnabled, get_SharingEnabledType) STDMETHODIMP GetSharingEnabled (BOOLEAN* pbEnabled, SHARINGCONNECTIONTYPE* pType); // this was necessary because oleautomation allows only one retval type public: BEGIN_COM_MAP(CNetSharingConfiguration) COM_INTERFACE_ENTRY(INetSharingConfiguration) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() CNetSharingConfiguration() { m_pHNetConnection = NULL; m_pSettings = NULL; InitializeCriticalSection(&m_csSharingConfiguration); } ~CNetSharingConfiguration() { DeleteCriticalSection(&m_csSharingConfiguration); } HRESULT Initialize( INetConnection *pNetConnection ); HRESULT FinalRelease() { ReleaseObj(m_pHNetConnection); ReleaseObj(m_pSettings); return S_OK; } STDMETHODIMP get_SharingEnabled (VARIANT_BOOL* pbEnabled); STDMETHODIMP get_SharingConnectionType(SHARINGCONNECTIONTYPE* pType); STDMETHODIMP DisableSharing(); STDMETHODIMP EnableSharing( SHARINGCONNECTIONTYPE Type ); STDMETHODIMP get_InternetFirewallEnabled( VARIANT_BOOL *pbEnabled ); STDMETHODIMP DisableInternetFirewall(); STDMETHODIMP EnableInternetFirewall(); // Return an IEnumSharingPortMapping interface used to enumerate all of // the contained INetSharingPortMapping objects. // STDMETHODIMP get_EnumPortMappings( SHARINGCONNECTION_ENUM_FLAGS Flags, INetSharingPortMappingCollection** ppColl); STDMETHODIMP AddPortMapping( OLECHAR* pszwName, UCHAR ucIPProtocol, USHORT usExternalPort, USHORT usInternalPort, DWORD dwOptions, OLECHAR* pszwTargetNameOrIPAddress, ICS_TARGETTYPE eTargetType, INetSharingPortMapping** ppMapping ); STDMETHODIMP RemovePortMapping( INetSharingPortMapping* pMapping ); }; class ATL_NO_VTABLE CNetSharingManager : public CComObjectRootEx, public CComCoClass, public IDispatchImpl { private: IHNetIcsSettings* m_pIcsSettings; public: BEGIN_COM_MAP(CNetSharingManager) COM_INTERFACE_ENTRY(INetSharingManager) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() DECLARE_REGISTRY_RESOURCEID(IDR_SHAREMGR) DECLARE_PROTECT_FINAL_CONSTRUCT() CNetSharingManager() { m_pIcsSettings = NULL; } HRESULT FinalConstruct() { return _ObtainIcsSettingsObj( &m_pIcsSettings ); } HRESULT FinalRelease() { ReleaseObj( m_pIcsSettings ); return S_OK; } STDMETHODIMP get_SharingInstalled( VARIANT_BOOL *pbInstalled ); // Return an IEnumNetEveryConnection interface used to enumerate all of // the contained INetConnections // STDMETHODIMP get_EnumEveryConnection( INetSharingEveryConnectionCollection** ppColl); // Return an IEnumNetPublicConnection interface used to enumerate all of // the contained INetConnections configured as a public adapter // STDMETHODIMP get_EnumPublicConnections( SHARINGCONNECTION_ENUM_FLAGS Flags, INetSharingPublicConnectionCollection** ppColl); // Return an IEnumNetPrivateConnection interface used to enumerate all of // the contained INetConnections configured as a private adapter // STDMETHODIMP get_EnumPrivateConnections( SHARINGCONNECTION_ENUM_FLAGS Flags, INetSharingPrivateConnectionCollection** ppColl); STDMETHODIMP get_INetSharingConfigurationForINetConnection( INetConnection* pNetConnection, INetSharingConfiguration** ppNetSharingConfiguration ); STDMETHODIMP get_NetConnectionProps( INetConnection * pNetConnection, INetConnectionProps **ppProps) { HNET_OEM_API_ENTER if (!ppProps) return E_POINTER; else *ppProps = NULL; if (!pNetConnection) return E_INVALIDARG; CComObject* pNCP = NULL; HRESULT hr = CComObject::CreateInstance(&pNCP); if (pNCP) { pNCP->AddRef(); hr = pNCP->Initialize (pNetConnection); if (hr == S_OK) hr = pNCP->QueryInterface ( __uuidof(INetConnectionProps), (void**)ppProps); pNCP->Release(); } return hr; HNET_OEM_API_LEAVE } }; template< class IMapping, class IProtocol > class TNetMapping : public CComObjectRootEx, public IMapping { private: IProtocol* m_pIProtocol; CRITICAL_SECTION m_csDefinition; protected: IProtocol* _IProtocol() { return m_pIProtocol; } IProtocol* _IProtocol( IProtocol* _pIProtocol ) { if ( m_pIProtocol ) ReleaseObj(m_pIProtocol); m_pIProtocol = _pIProtocol; if ( m_pIProtocol ) m_pIProtocol->AddRef(); return m_pIProtocol; } CRITICAL_SECTION* _CriticalSection() { return &m_csDefinition; } public: typedef TNetMapping _ThisClass; BEGIN_COM_MAP(_ThisClass) COM_INTERFACE_ENTRY(IMapping) END_COM_MAP() public: TNetMapping() { m_pIProtocol = NULL; InitializeCriticalSection(&m_csDefinition); } ~TNetMapping() { DeleteCriticalSection(&m_csDefinition); } HRESULT FinalRelease() { ReleaseObj( m_pIProtocol ); return S_OK; } HRESULT Initialize( IProtocol* pItem) { EnterCriticalSection(&m_csDefinition); _IProtocol( pItem ); LeaveCriticalSection(&m_csDefinition); return S_OK; } STDMETHOD(Disable)(void) { HRESULT hr; if ( !IsNotifyApproved() ) { hr = E_ACCESSDENIED; } else if ( NULL == m_pIProtocol ) { hr = E_UNEXPECTED; } else { hr = m_pIProtocol->SetEnabled( FALSE ); } return hr; } STDMETHOD(Enable)(void) { HRESULT hr; if ( !IsNotifyApproved() ) { hr = E_ACCESSDENIED; } else if ( NULL == m_pIProtocol ) { hr = E_UNEXPECTED; } else { hr = m_pIProtocol->SetEnabled( TRUE ); } return hr; } }; class ATL_NO_VTABLE CNetSharingPortMapping : public IDispatchImpl, &IID_INetSharingPortMapping, &LIBID_NETCONLib> { public: typedef TNetMapping _ThisOtherClass; BEGIN_COM_MAP(CNetSharingPortMapping) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_CHAIN(_ThisOtherClass) END_COM_MAP() STDMETHODIMP get_Properties (/*[out, retval]*/ INetSharingPortMappingProps ** ppNSPMP); STDMETHODIMP Delete(); }; template< class EnumInterface, class ItemInterface, class EnumWrapped, class ItemWrapped > class TNetApiEnum : public CComObjectRootEx, public EnumInterface, public IEnumVARIANT { protected: typedef TNetApiEnum _ThisClass; friend class TNetApiEnum; SHARINGCONNECTION_ENUM_FLAGS m_fEnumFlags; EnumWrapped* m_pEnum; CRITICAL_SECTION m_csEnum; public: TNetApiEnum () { m_fEnumFlags = ICSSC_DEFAULT; m_pEnum = NULL; InitializeCriticalSection(&m_csEnum); } ~TNetApiEnum () { DeleteCriticalSection(&m_csEnum); } BEGIN_COM_MAP(_ThisClass) COM_INTERFACE_ENTRY(EnumInterface) COM_INTERFACE_ENTRY(IEnumVARIANT) END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT Initialize( EnumWrapped* pEnum, SHARINGCONNECTION_ENUM_FLAGS Flags ) { EnterCriticalSection(&m_csEnum); ReleaseObj( m_pEnum ); m_fEnumFlags = Flags; m_pEnum = pEnum; m_pEnum->AddRef(); LeaveCriticalSection(&m_csEnum); return S_OK; } HRESULT FinalRelease () { ReleaseObj( m_pEnum ); return S_OK; } virtual HRESULT GetItemInterfaceFromItemWrapped( ItemWrapped* pItem, ItemInterface** ppIface ) { HRESULT hr; if ( NULL == ppIface ) { hr = E_POINTER; } else if ( NULL == pItem ) { hr = E_INVALIDARG; } else { *ppIface = NULL; hr = E_NOTIMPL; } return hr; } private: STDMETHOD (Next) ( ULONG celt, ItemInterface** rgelt, ULONG* pceltFetched) { HRESULT hr = S_OK; ULONG ulFetched = 0; ItemInterface **ppNet = rgelt; ItemWrapped **ItemArray; // Validate parameters. if ( !rgelt || ((1 < celt) && !pceltFetched) ) { hr = E_POINTER; } else if ( 0 == celt ) { hr = E_INVALIDARG; } if ( SUCCEEDED(hr) ) { ZeroMemory(rgelt, sizeof(ItemInterface*) * celt); if ( pceltFetched ) *pceltFetched = 0; ulFetched = 0; if ( NULL == m_pEnum ) { hr = S_FALSE; } else { ItemArray = new ItemWrapped * [ sizeof(ItemWrapped) * celt ]; if ( ItemArray ) { ZeroMemory( ItemArray, sizeof(ItemWrapped) * celt ); } else { hr = E_OUTOFMEMORY; } } } if ( SUCCEEDED(hr) && m_pEnum ) { ItemWrapped **ppItem; ULONG ulBatchFetched, i; hr = m_pEnum->Next( celt, ItemArray, &ulBatchFetched ); ppItem = ItemArray; ppNet = rgelt; for( i=0, ulFetched=0; ( ( i < ulBatchFetched ) && ( S_OK == hr ) ); i++, ppItem++ ) { hr = GetItemInterfaceFromItemWrapped( *ppItem, ppNet ); if ( SUCCEEDED(hr) ) { ppNet++; ulFetched++; } ReleaseObj( *ppItem ); } delete [] ItemArray; } if ( ulFetched > 0 ) { hr = ( ulFetched == celt ) ? S_OK : S_FALSE; if ( pceltFetched ) *pceltFetched = ulFetched; } return hr; } public: STDMETHOD (Next) (ULONG celt, VARIANT * rgVar, ULONG * pceltFetched) { // this Next calls the private Next to wrap up ItemInterfaces in VARIANTs HNET_OEM_API_ENTER if (!rgVar || ((1 < celt) && !pceltFetched)) return E_POINTER; else if (0 == celt) return E_INVALIDARG; HRESULT hr = S_OK; // alloc array of ItemInterface* and call private Next ItemInterface ** rgelt = (ItemInterface**)malloc (celt*sizeof(ItemInterface*)); if (!rgelt) hr = E_OUTOFMEMORY; else { hr = Next (celt, rgelt, pceltFetched); if (hr == S_OK) { // if error or S_FALSE, don't copy data ULONG ulElements; if (pceltFetched) ulElements = *pceltFetched; else ulElements = 1; for (ULONG ul=0; ulQueryInterface (__uuidof(IDispatch), (void**)&V_DISPATCH (&rgVar[ul])))) V_VT (&rgVar[ul]) = VT_DISPATCH; else if (S_OK == (hr = rgelt[ul]->QueryInterface (__uuidof(IUnknown), (void**)&V_UNKNOWN (&rgVar[ul])))) V_VT (&rgVar[ul]) = VT_UNKNOWN; else break; } for (ULONG ul=0; ulRelease(); } free (rgelt); } return hr; HNET_OEM_API_LEAVE } STDMETHOD (Skip) ( ULONG celt) { return ( (m_pEnum) ? m_pEnum->Skip(celt) : S_OK ); } STDMETHOD (Reset) () { return ( (m_pEnum) ? m_pEnum->Reset() : S_OK ); } public: STDMETHOD (Clone) ( EnumInterface** ppEnum) { HNET_OEM_API_ENTER HRESULT hr = S_OK; CComObject<_ThisClass>* pNewEnum; EnumWrapped* pClonedEnum; if ( NULL == ppEnum ) { hr = E_POINTER; } else { // Attempt to clone the embedded enumeration. pClonedEnum = NULL; hr = m_pEnum->Clone(&pClonedEnum); } if ( SUCCEEDED(hr) ) { // Create an initialized a new instance of ourselves hr = CComObject<_ThisClass>::CreateInstance(&pNewEnum); if ( SUCCEEDED(hr) ) { pNewEnum->AddRef(); hr = pNewEnum->Initialize( pClonedEnum, m_fEnumFlags ); if ( SUCCEEDED(hr) ) { hr = pNewEnum->QueryInterface( IID_PPV_ARG(EnumInterface, ppEnum) ); } pNewEnum->Release(); } // Release the cloned enum. New enum object will have // AddReffed it... pClonedEnum->Release(); } return hr; HNET_OEM_API_LEAVE } public: STDMETHOD (Clone) (IEnumVARIANT ** ppEnum) { HNET_OEM_API_ENTER EnumInterface* pEnum = NULL; HRESULT hr = Clone (&pEnum); if (pEnum) { hr = pEnum->QueryInterface (__uuidof(IEnumVARIANT), (void**)ppEnum); pEnum->Release(); } return hr; HNET_OEM_API_LEAVE } }; template<> HRESULT TNetApiEnum ::GetItemInterfaceFromItemWrapped( INetConnection* pItem, INetConnection** ppIface ) { HRESULT hr; if ( NULL == ppIface ) { hr = E_POINTER; } else if ( NULL == pItem ) { hr = E_INVALIDARG; } else { hr = pItem->QueryInterface( IID_PPV_ARG( INetConnection, ppIface ) ); } return hr; } class ATL_NO_VTABLE CSharingManagerEnumEveryConnection : public TNetApiEnum { public: BEGIN_COM_MAP(CSharingManagerEnumEveryConnection) COM_INTERFACE_ENTRY(IEnumNetSharingEveryConnection) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; template<> HRESULT TNetApiEnum ::GetItemInterfaceFromItemWrapped( IHNetIcsPublicConnection* pItem, INetConnection** ppIface ) { HRESULT hr; if ( NULL == ppIface ) { hr = E_POINTER; } else if ( NULL == pItem ) { hr = E_INVALIDARG; } else { IHNetConnection* pHNet; *ppIface = NULL; hr = pItem->QueryInterface( IID_PPV_ARG( IHNetConnection, &pHNet ) ); if ( SUCCEEDED(hr) ) { hr = pHNet->GetINetConnection( ppIface ); ReleaseObj( pHNet ); } } return hr; } class ATL_NO_VTABLE CSharingManagerEnumPublicConnection : public TNetApiEnum { public: BEGIN_COM_MAP(CSharingManagerEnumPublicConnection) COM_INTERFACE_ENTRY(IEnumNetSharingPublicConnection) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; template<> HRESULT TNetApiEnum ::GetItemInterfaceFromItemWrapped( IHNetIcsPrivateConnection* pItem, INetConnection** ppIface ) { HRESULT hr; if ( NULL == ppIface ) { hr = E_POINTER; } else if ( NULL == pItem ) { hr = E_INVALIDARG; } else { IHNetConnection* pHNet; *ppIface = NULL; hr = pItem->QueryInterface( IID_PPV_ARG( IHNetConnection, &pHNet ) ); if ( SUCCEEDED(hr) ) { hr = pHNet->GetINetConnection( ppIface ); ReleaseObj( pHNet ); } } return hr; } class ATL_NO_VTABLE CSharingManagerEnumPrivateConnection : public TNetApiEnum { public: BEGIN_COM_MAP(CSharingManagerEnumPrivateConnection) COM_INTERFACE_ENTRY(IEnumNetSharingPrivateConnection) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; template<> HRESULT TNetApiEnum ::GetItemInterfaceFromItemWrapped( IHNetPortMappingBinding* pItem, INetSharingPortMapping** ppIface ) { HRESULT hr; hr = ( NULL == ppIface ) ? E_POINTER : S_OK; if ( SUCCEEDED(hr) ) { *ppIface = NULL; if ( NULL == pItem ) { hr = E_INVALIDARG; } } if ( SUCCEEDED(hr) ) { CComObject* pMap; hr = CComObject::CreateInstance(&pMap); if ( SUCCEEDED(hr) ) { pMap->AddRef(); hr = pMap->Initialize( pItem ); if ( SUCCEEDED(hr) ) { hr = pMap->QueryInterface( IID_PPV_ARG( INetSharingPortMapping, ppIface ) ); } ReleaseObj(pMap); } } return hr; } class ATL_NO_VTABLE CSharingManagerEnumPortMapping : public TNetApiEnum { public: BEGIN_COM_MAP(CSharingManagerEnumPortMapping) COM_INTERFACE_ENTRY(IEnumNetSharingPortMapping) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; // collections template class TNetCollection : public CComObjectRootEx, public IEnumBase { private: IEnumerator * m_pE; public: typedef TNetCollection _ThisClass; BEGIN_COM_MAP(_ThisClass) COM_INTERFACE_ENTRY(IEnumBase) END_COM_MAP() public: TNetCollection() { m_pE = NULL; } ~TNetCollection() { ReleaseObj(m_pE); } HRESULT Initialize (IEnumerator * pE) { _ASSERT ( pE != NULL); _ASSERT(m_pE == NULL); m_pE = pE; m_pE->AddRef(); return S_OK; } STDMETHOD(get__NewEnum)(IUnknown** ppVal) { HNET_OEM_API_ENTER if (!ppVal) return E_POINTER; if (!m_pE) return E_UNEXPECTED; return m_pE->QueryInterface (__uuidof(IUnknown), (void**)ppVal); HNET_OEM_API_LEAVE } STDMETHOD(get_Count)(long *pVal) { HNET_OEM_API_ENTER if (!pVal) return E_POINTER; if (!m_pE) return E_UNEXPECTED; CComPtr spE; HRESULT hr = m_pE->Clone (&spE); if (spE) { long lCount = 0; spE->Reset(); while (1) { CComVariant cvar; HRESULT hr2 = spE->Next (1, &cvar, NULL); if (hr2 == S_OK) lCount++; else break; } *pVal = lCount; } return hr; HNET_OEM_API_LEAVE } }; class ATL_NO_VTABLE CNetSharingEveryConnectionCollection : public IDispatchImpl, &IID_INetSharingEveryConnectionCollection, &LIBID_NETCONLib> { public: BEGIN_COM_MAP(CNetSharingEveryConnectionCollection) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; class ATL_NO_VTABLE CNetSharingPublicConnectionCollection : public IDispatchImpl, &IID_INetSharingPublicConnectionCollection, &LIBID_NETCONLib> { public: BEGIN_COM_MAP(CNetSharingPublicConnectionCollection) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; class ATL_NO_VTABLE CNetSharingPrivateConnectionCollection : public IDispatchImpl, &IID_INetSharingPrivateConnectionCollection, &LIBID_NETCONLib> { public: BEGIN_COM_MAP(CNetSharingPrivateConnectionCollection) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; class ATL_NO_VTABLE CNetSharingPortMappingCollection : public IDispatchImpl, &IID_INetSharingPortMappingCollection, &LIBID_NETCONLib> { public: BEGIN_COM_MAP(CNetSharingPortMappingCollection) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY_CHAIN(_ThisClass) END_COM_MAP() }; // props class ATL_NO_VTABLE CNetSharingPortMappingProps : public CComObjectRootEx, public IDispatchImpl { private: ICS_PORTMAPPING m_IPM; // not alloc'd public: BEGIN_COM_MAP(CNetSharingPortMappingProps) COM_INTERFACE_ENTRY(INetSharingPortMappingProps) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() public: CNetSharingPortMappingProps() { ZeroMemory (&m_IPM, sizeof(ICS_PORTMAPPING)); } ~CNetSharingPortMappingProps() { FreeData (&m_IPM); } public: // CNetSharingPortMappingProps ICS_PORTMAPPING * GetVolatileRawData (void) { return &m_IPM; } HRESULT SetRawData (ICS_PORTMAPPING * pIPM) { _ASSERT (pIPM); if (!pIPM) return E_POINTER; ICS_PORTMAPPING IPM = {0}; HRESULT hr = DupData (pIPM, &IPM); if (hr == S_OK) { FreeData (&m_IPM); m_IPM = IPM; // struct copy } return S_OK; } static OLECHAR * DupString (OLECHAR * in) { OLECHAR * po = NULL; if (in) { po = (OLECHAR*)malloc ((wcslen (in) + 1)*sizeof(OLECHAR)); if (po) wcscpy(po, in); } else { // one of pszwTargetName or pszwTargetIPAddress may be blank! so... po = (OLECHAR*)malloc (1*sizeof(OLECHAR)); if (po) *po = 0; // ...alloc an emptry string } return po; } static HRESULT DupData (ICS_PORTMAPPING * in, ICS_PORTMAPPING * out) { if (!in) return E_POINTER; out->ucIPProtocol = in->ucIPProtocol; out->usExternalPort = in->usExternalPort; out->usInternalPort = in->usInternalPort; out->dwOptions = in->dwOptions; out->bEnabled = in->bEnabled; out->pszwName = DupString (in->pszwName); out->pszwTargetName = DupString (in->pszwTargetName); out->pszwTargetIPAddress = DupString (in->pszwTargetIPAddress); if (!out->pszwName || !out->pszwTargetName || !out->pszwTargetIPAddress) { FreeData (out); return E_OUTOFMEMORY; } return S_OK; } static void FreeData (ICS_PORTMAPPING * pIPM) { if (pIPM) { if (pIPM->pszwName) free (pIPM->pszwName); if (pIPM->pszwTargetName) free (pIPM->pszwTargetName); if (pIPM->pszwTargetIPAddress) free (pIPM->pszwTargetIPAddress); } } public: // INetSharingPortMappingProps STDMETHODIMP get_Name (/*[out, retval]*/ BSTR * pbstrName); STDMETHODIMP get_IPProtocol (/*[out, retval]*/ UCHAR * pucIPProt); STDMETHODIMP get_ExternalPort (/*[out, retval]*/ long * pusPort); STDMETHODIMP get_InternalPort (/*[out, retval]*/ long * pusPort); STDMETHODIMP get_Options (/*[out, retval]*/ long * pdwOptions); STDMETHODIMP get_TargetName (/*[out, retval]*/ BSTR * pbstrTargetName); STDMETHODIMP get_TargetIPAddress(/*[out, retval]*/ BSTR * pbstrTargetIPAddress); STDMETHODIMP get_Enabled (/*[out, retval]*/ VARIANT_BOOL * pbool); };