// feeds.cpp : Implementation of CnntpadmApp and DLL registration. #include "stdafx.h" #include "nntpcmn.h" #include "feeds.h" #include "oleutil.h" #include "nntptype.h" #include "nntpapi.h" #include // Must define THIS_FILE_* macros to use NntpCreateException() #define THIS_FILE_HELP_CONTEXT 0 #define THIS_FILE_PROG_ID _T("Nntpadm.Feeds.1") #define THIS_FILE_IID IID_INntpAdminFeeds ///////////////////////////////////////////////////////////////////////////// // Defaults: #define DEFAULT_FEED_ID 0 #define DEFAULT_FEED_SERVER _T("") #define DEFAULT_PULL_NEWS_DATE 0 #define DEFAULT_START_TIME 0 #define DEFAULT_FEED_INTERVAL 15 #define DEFAULT_AUTO_CREATE TRUE #define DEFAULT_ENABLED TRUE #define DEFAULT_MAX_CONNECTIONS_ATTEMPTS 10 #define DEFAULT_SECURITY_TYPE 0 #define DEFAULT_AUTH_TYPE AUTH_PROTOCOL_NONE #define DEFAULT_ACCOUNT_NAME _T("") #define DEFAULT_PASSWORD _T("") #define DEFAULT_ALLOW_CONTROL_MESSAGES TRUE #define DEFAULT_UUCP_NAME _T("") #define DEFAULT_NEWSGROUPS _T("\0") #define DEFAULT_DISTRIBUTION _T("world\0") ///////////////////////////////////////////////////////////////////////////// // // // Use a macro to define all the default methods // DECLARE_METHOD_IMPLEMENTATION_FOR_STANDARD_EXTENSION_INTERFACES(NntpAdminFeeds, CNntpAdminFeeds, IID_INntpAdminFeeds) STDMETHODIMP CNntpOneWayFeed::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_INntpOneWayFeed, }; for (int i=0;iQueryInterface ( IID_INntpOneWayFeed, (void **) ppFeed ); return hr; } return E_FAIL; } STDMETHODIMP CNntpFeed::get_OutboundFeed ( INntpOneWayFeed ** ppFeed ) { HRESULT hr = NOERROR; *ppFeed = NULL; if ( m_pOutbound ) { hr = m_pOutbound->QueryInterface ( IID_INntpOneWayFeed, (void **) ppFeed ); return hr; } return E_FAIL; } STDMETHODIMP CNntpFeed::put_InboundFeed ( INntpOneWayFeed * pFeed ) { HRESULT hr = NOERROR; // !!!magnush - Do some feed type checking here. m_pInbound.Release (); m_pInbound = pFeed; return NOERROR; } STDMETHODIMP CNntpFeed::put_OutboundFeed ( INntpOneWayFeed * pFeed ) { HRESULT hr = NOERROR; // !!!magnush - Do some feed type checking here. m_pOutbound.Release (); m_pOutbound = pFeed; return hr; } STDMETHODIMP CNntpFeed::get_InboundFeedDispatch ( IDispatch ** ppDispatch ) { HRESULT hr; CComPtr pInbound; hr = get_InboundFeed ( &pInbound ); BAIL_ON_FAILURE(hr); hr = pInbound->QueryInterface ( IID_IDispatch, (void **) ppDispatch ); BAIL_ON_FAILURE(hr); Exit: return hr; } STDMETHODIMP CNntpFeed::put_InboundFeedDispatch ( IDispatch * pDispatch ) { HRESULT hr; CComPtr pInbound; hr = pDispatch->QueryInterface ( IID_INntpOneWayFeed, (void **) &pInbound ); BAIL_ON_FAILURE(hr); hr = put_InboundFeed ( pInbound ); BAIL_ON_FAILURE(hr); Exit: return hr; } STDMETHODIMP CNntpFeed::get_OutboundFeedDispatch ( IDispatch ** ppDispatch ) { HRESULT hr; CComPtr pOutbound; hr = get_OutboundFeed ( &pOutbound ); BAIL_ON_FAILURE(hr); hr = pOutbound->QueryInterface ( IID_IDispatch, (void **) ppDispatch ); BAIL_ON_FAILURE(hr); Exit: return hr; } STDMETHODIMP CNntpFeed::put_OutboundFeedDispatch ( IDispatch * pDispatch ) { HRESULT hr; CComPtr pOutbound; hr = pDispatch->QueryInterface ( IID_INntpOneWayFeed, (void **) &pOutbound ); BAIL_ON_FAILURE(hr); hr = put_OutboundFeed ( pOutbound ); BAIL_ON_FAILURE(hr); Exit: return hr; } HRESULT CNntpFeed::FromFeedPair ( CFeedPair * pFeedPair ) { HRESULT hr = NOERROR; m_pInbound.Release (); m_pOutbound.Release (); m_strRemoteServer = pFeedPair->m_strRemoteServer; m_type = pFeedPair->m_type; if ( pFeedPair->m_pInbound ) { hr = pFeedPair->m_pInbound->ToINntpOneWayFeed ( &m_pInbound ); BAIL_ON_FAILURE(hr); } if ( pFeedPair->m_pOutbound ) { hr = pFeedPair->m_pOutbound->ToINntpOneWayFeed ( &m_pOutbound ); BAIL_ON_FAILURE(hr); } Exit: return hr; } ///////////////////////////////////////////////////////////////////////////// // STDMETHODIMP CNntpAdminFeeds::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_INntpAdminFeeds, }; for (int i=0;im_dwPairFeedId; pFeedPair = m_listFeeds.Find ( dwPairID ); if ( pFeedPair ) { // We found a matching pair, so add it: hr = pFeedPair->AddFeed ( pFeed ); if ( hr == E_FAIL ) { // Something went wrong - Try to add the feed by itself. pFeedPair = NULL; hr = NOERROR; } if ( FAILED(hr) ) { goto Exit; } } if ( pFeedPair == NULL ) { // We need to create a new feed pair: hr = CFeedPair::CreateFeedPair ( &pFeedPair, pFeedInfo[i].ServerName, FeedTypeToEnum ( pFeedInfo[i].FeedType ) ); if ( FAILED(hr) ) { goto Exit; } // Add the current feed to the new pair: hr = pFeedPair->AddFeed ( pFeed ); if ( FAILED(hr) ) { goto Exit; } // Add the new pair to the pair list: m_listFeeds.Add ( pFeedPair ); } } // !!!magnush - Stop memory leaks here. m_fEnumerated = TRUE; Exit: if ( FAILED(hr) ) { m_listFeeds.Empty(); } if ( pFeedInfo ) { ::NetApiBufferFree ( pFeedInfo ); } TRACE_HRESULT(hr); TraceFunctLeave (); return hr; } STDMETHODIMP CNntpAdminFeeds::Item ( long lIndex, INntpFeed ** ppFeed ) { TraceFunctEnter ( "CNntpAdminFeeds::Item" ); HRESULT hr = NOERROR; CFeedPair * pFeedPair; // Did we enumerate first? if ( !m_fEnumerated ) { hr = NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_ENUMERATE ); TraceFunctLeave (); return hr; } pFeedPair = m_listFeeds.Item ( lIndex ); if ( !pFeedPair ) { hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX ); goto Exit; } hr = pFeedPair->ToINntpFeed ( ppFeed ); if ( FAILED(hr) ) { goto Exit; } Exit: TRACE_HRESULT(hr); TraceFunctLeave (); return hr; } STDMETHODIMP CNntpAdminFeeds::FindID ( long lID, long * plIndex ) { TraceFunctEnter ( "CNntpAdminFeeds::FindID" ); HRESULT hr = NOERROR; CFeedPair * pFeedPair; *plIndex = -1; pFeedPair = m_listFeeds.Find ( (DWORD) lID ); if ( pFeedPair ) { *plIndex = (long) m_listFeeds.GetPairIndex ( pFeedPair ); } TraceFunctLeave (); return hr; } HRESULT CNntpAdminFeeds::ReturnFeedPair ( CFeedPair * pFeedPair, INntpFeed * pFeed ) { HRESULT hr; CComPtr pInbound; CComPtr pOutbound; CComPtr pNewFeedPair; hr = pFeedPair->ToINntpFeed ( &pNewFeedPair ); BAIL_ON_FAILURE(hr); pNewFeedPair->get_InboundFeed ( &pInbound ); pNewFeedPair->get_OutboundFeed ( &pOutbound ); pFeed->put_InboundFeed ( pInbound ); pFeed->put_OutboundFeed ( pOutbound ); Exit: return hr; } STDMETHODIMP CNntpAdminFeeds::Add ( INntpFeed * pFeed ) { TraceFunctEnter ( "CNntpAdminFeeds::Add" ); HRESULT hr = NOERROR; CFeedPair * pFeedPair = NULL; CComBSTR strRemoteServer; CComBSTR strServer; NNTP_FEED_SERVER_TYPE type; CMetabaseKey *pMK = NULL; IMSAdminBase *pMeta = NULL; hr = pFeed->get_RemoteServer ( &strRemoteServer ); BAIL_ON_FAILURE(hr); hr = get_Server(&strServer); BAIL_ON_FAILURE(hr); hr = CreateMetabaseObject( strServer, &pMeta ); _ASSERT( SUCCEEDED( hr ) ); BAIL_ON_FAILURE(hr); pMK = new CMetabaseKey(pMeta); if (!pMK) BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); hr = pFeed->get_FeedType ( &type ); BAIL_ON_FAILURE(hr); hr = CFeedPair::CreateFeedPair ( &pFeedPair, strRemoteServer, type ); BAIL_ON_FAILURE(hr); hr = pFeedPair->FromINntpFeed ( pFeed ); BAIL_ON_FAILURE(hr); hr = pFeedPair->AddToServer ( m_iadsImpl.QueryComputer(), m_iadsImpl.QueryInstance(), pMK ); BAIL_ON_FAILURE(hr); m_listFeeds.Add ( pFeedPair ); // Return the new feeds (and their IDs) to the caller: hr = ReturnFeedPair ( pFeedPair, pFeed ); BAIL_ON_FAILURE(hr); Exit: if ( FAILED(hr) ) { delete pFeedPair; } if (pMK) delete pMK; if (pMeta) pMeta->Release(); TRACE_HRESULT(hr); TraceFunctLeave (); return hr; } STDMETHODIMP CNntpAdminFeeds::Set ( long lIndex, INntpFeed * pFeed ) { TraceFunctEnter ( "CNntpAdminFeeds::Set" ); HRESULT hr = NOERROR; CFeedPair * pFeedPair; CComPtr pNewFeedPair; CComPtr pInbound; CComPtr pOutbound; CComBSTR strServer; CMetabaseKey *pMK = NULL; IMSAdminBase *pMeta = NULL; hr = get_Server ( &strServer ); BAIL_ON_FAILURE(hr); hr = CreateMetabaseObject( strServer, &pMeta ); _ASSERT( SUCCEEDED( hr ) ); BAIL_ON_FAILURE(hr); pMK = new CMetabaseKey(pMeta); if (!pMK) BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); pFeedPair = m_listFeeds.Item ( lIndex ); if ( !pFeedPair ) { hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX ); goto Exit; } hr = pFeedPair->SetToServer ( m_iadsImpl.QueryComputer(), m_iadsImpl.QueryInstance(), pFeed, pMK ); BAIL_ON_FAILURE(hr); // Return the new feeds (and their IDs) to the caller: hr = ReturnFeedPair ( pFeedPair, pFeed ); BAIL_ON_FAILURE(hr); Exit: if (pMK) delete pMK; if (pMeta) pMeta->Release(); TRACE_HRESULT(hr); TraceFunctLeave (); return hr; } STDMETHODIMP CNntpAdminFeeds::Remove ( long lIndex ) { TraceFunctEnter ( "CNntpAdminFeeds::Remove" ); HRESULT hr = NOERROR; CFeedPair * pFeedPair; CComBSTR strServer; CMetabaseKey *pMK = NULL; IMSAdminBase *pMeta = NULL; pFeedPair = m_listFeeds.Item ( lIndex ); if ( !pFeedPair ) { hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX ); goto Exit; } hr = get_Server ( &strServer ); BAIL_ON_FAILURE(hr); hr = CreateMetabaseObject( strServer, &pMeta ); _ASSERT( SUCCEEDED( hr ) ); BAIL_ON_FAILURE(hr); pMK = new CMetabaseKey(pMeta); if (!pMK) BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY); hr = pFeedPair->RemoveFromServer ( m_iadsImpl.QueryComputer(), m_iadsImpl.QueryInstance(), pMK ); if ( FAILED(hr) ) { goto Exit; } m_listFeeds.Remove ( pFeedPair ); Exit: if (pMK) delete pMK; if (pMeta) pMeta->Release(); TRACE_HRESULT(hr); TraceFunctLeave (); return hr; } STDMETHODIMP CNntpAdminFeeds::ItemDispatch ( long index, IDispatch ** ppDispatch ) { HRESULT hr; CComPtr pFeed; hr = Item ( index, &pFeed ); BAIL_ON_FAILURE ( hr ); hr = pFeed->QueryInterface ( IID_IDispatch, (void **) ppDispatch ); BAIL_ON_FAILURE ( hr ); Exit: return hr; } STDMETHODIMP CNntpAdminFeeds::AddDispatch ( IDispatch * pFeed ) { HRESULT hr; CComPtr pINntpFeed; hr = pFeed->QueryInterface ( IID_INntpFeed, (void **) &pINntpFeed ); BAIL_ON_FAILURE(hr); hr = Add ( pINntpFeed ); BAIL_ON_FAILURE(hr); Exit: return hr; } STDMETHODIMP CNntpAdminFeeds::SetDispatch ( long lIndex, IDispatch * pFeed ) { HRESULT hr; CComPtr pINntpFeed; hr = pFeed->QueryInterface ( IID_INntpFeed, (void **) &pINntpFeed ); BAIL_ON_FAILURE(hr); hr = Set ( lIndex, pINntpFeed ); BAIL_ON_FAILURE(hr); Exit: return hr; }