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.

963 lines
22 KiB

  1. // feeds.cpp : Implementation of CnntpadmApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "nntpcmn.h"
  4. #include "feeds.h"
  5. #include "oleutil.h"
  6. #include "nntptype.h"
  7. #include "nntpapi.h"
  8. #include <lmapibuf.h>
  9. // Must define THIS_FILE_* macros to use NntpCreateException()
  10. #define THIS_FILE_HELP_CONTEXT 0
  11. #define THIS_FILE_PROG_ID _T("Nntpadm.Feeds.1")
  12. #define THIS_FILE_IID IID_INntpAdminFeeds
  13. /////////////////////////////////////////////////////////////////////////////
  14. // Defaults:
  15. #define DEFAULT_FEED_ID 0
  16. #define DEFAULT_FEED_SERVER _T("")
  17. #define DEFAULT_PULL_NEWS_DATE 0
  18. #define DEFAULT_START_TIME 0
  19. #define DEFAULT_FEED_INTERVAL 15
  20. #define DEFAULT_AUTO_CREATE TRUE
  21. #define DEFAULT_ENABLED TRUE
  22. #define DEFAULT_MAX_CONNECTIONS_ATTEMPTS 10
  23. #define DEFAULT_SECURITY_TYPE 0
  24. #define DEFAULT_AUTH_TYPE AUTH_PROTOCOL_NONE
  25. #define DEFAULT_ACCOUNT_NAME _T("")
  26. #define DEFAULT_PASSWORD _T("")
  27. #define DEFAULT_ALLOW_CONTROL_MESSAGES TRUE
  28. #define DEFAULT_UUCP_NAME _T("")
  29. #define DEFAULT_NEWSGROUPS _T("\0")
  30. #define DEFAULT_DISTRIBUTION _T("world\0")
  31. /////////////////////////////////////////////////////////////////////////////
  32. //
  33. //
  34. // Use a macro to define all the default methods
  35. //
  36. DECLARE_METHOD_IMPLEMENTATION_FOR_STANDARD_EXTENSION_INTERFACES(NntpAdminFeeds, CNntpAdminFeeds, IID_INntpAdminFeeds)
  37. STDMETHODIMP CNntpOneWayFeed::InterfaceSupportsErrorInfo(REFIID riid)
  38. {
  39. static const IID* arr[] =
  40. {
  41. &IID_INntpOneWayFeed,
  42. };
  43. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  44. {
  45. if (InlineIsEqualGUID(*arr[i],riid))
  46. return S_OK;
  47. }
  48. return S_FALSE;
  49. }
  50. CNntpOneWayFeed::CNntpOneWayFeed ()
  51. // CComBSTR's are initialized to NULL by default.
  52. {
  53. // InitAsyncTrace ( );
  54. }
  55. CNntpOneWayFeed::~CNntpOneWayFeed ()
  56. {
  57. // All CComBSTR's are freed automatically.
  58. // TermAsyncTrace ( );
  59. }
  60. STDMETHODIMP CNntpOneWayFeed::get_FeedId ( long * plFeedId )
  61. {
  62. return StdPropertyGet ( m_feed.m_dwFeedId, plFeedId );
  63. }
  64. STDMETHODIMP CNntpOneWayFeed::get_RemoteServer ( BSTR * pstrRemoteServer )
  65. {
  66. return StdPropertyGet ( m_feed.m_strRemoteServer, pstrRemoteServer );
  67. }
  68. STDMETHODIMP CNntpOneWayFeed::get_FeedAction ( NNTP_FEED_ACTION * pfeedaction )
  69. {
  70. return m_feed.get_FeedAction ( pfeedaction );
  71. }
  72. STDMETHODIMP CNntpOneWayFeed::put_FeedAction ( NNTP_FEED_ACTION feedaction )
  73. {
  74. return m_feed.put_FeedAction ( feedaction );
  75. }
  76. STDMETHODIMP CNntpOneWayFeed::get_UucpName ( BSTR * pstrUucpName )
  77. {
  78. return StdPropertyGet ( m_feed.m_strUucpName, pstrUucpName );
  79. }
  80. STDMETHODIMP CNntpOneWayFeed::put_UucpName ( BSTR strUucpName )
  81. {
  82. return StdPropertyPut ( &m_feed.m_strUucpName, strUucpName );
  83. }
  84. STDMETHODIMP CNntpOneWayFeed::get_PullNewsDate ( DATE * pdatePullNews )
  85. {
  86. return StdPropertyGet ( m_feed.m_datePullNews, pdatePullNews );
  87. }
  88. STDMETHODIMP CNntpOneWayFeed::put_PullNewsDate ( DATE datePullNews )
  89. {
  90. return StdPropertyPut ( &m_feed.m_datePullNews, datePullNews );
  91. }
  92. STDMETHODIMP CNntpOneWayFeed::get_FeedInterval ( long * plFeedInterval )
  93. {
  94. return StdPropertyGet ( m_feed.m_dwFeedInterval, plFeedInterval );
  95. }
  96. STDMETHODIMP CNntpOneWayFeed::put_FeedInterval ( long lFeedInterval )
  97. {
  98. return StdPropertyPut ( &m_feed.m_dwFeedInterval, lFeedInterval );
  99. }
  100. STDMETHODIMP CNntpOneWayFeed::get_AutoCreate ( BOOL * pfAutoCreate )
  101. {
  102. return StdPropertyGet ( m_feed.m_fCreateAutomatically, pfAutoCreate );
  103. }
  104. STDMETHODIMP CNntpOneWayFeed::put_AutoCreate ( BOOL fAutoCreate )
  105. {
  106. return StdPropertyPut ( &m_feed.m_fCreateAutomatically, fAutoCreate );
  107. }
  108. STDMETHODIMP CNntpOneWayFeed::get_Enabled ( BOOL * pfEnabled )
  109. {
  110. return StdPropertyGet ( m_feed.m_fEnabled, pfEnabled );
  111. }
  112. STDMETHODIMP CNntpOneWayFeed::put_Enabled ( BOOL fEnabled )
  113. {
  114. return StdPropertyPut ( &m_feed.m_fEnabled, fEnabled );
  115. }
  116. STDMETHODIMP CNntpOneWayFeed::get_MaxConnectionAttempts ( long * plMaxConnectionAttempts )
  117. {
  118. return StdPropertyGet ( m_feed.m_dwMaxConnectionAttempts, plMaxConnectionAttempts );
  119. }
  120. STDMETHODIMP CNntpOneWayFeed::put_MaxConnectionAttempts ( long lMaxConnectionAttempts )
  121. {
  122. return StdPropertyPut ( &m_feed.m_dwMaxConnectionAttempts, lMaxConnectionAttempts );
  123. }
  124. STDMETHODIMP CNntpOneWayFeed::get_SecurityType ( long * plSecurityType )
  125. {
  126. return StdPropertyGet ( m_feed.m_dwSecurityType, plSecurityType );
  127. }
  128. STDMETHODIMP CNntpOneWayFeed::put_SecurityType ( long lSecurityType )
  129. {
  130. return StdPropertyPut ( &m_feed.m_dwSecurityType, lSecurityType );
  131. }
  132. STDMETHODIMP CNntpOneWayFeed::get_AuthenticationType ( long * plAuthenticationType )
  133. {
  134. return StdPropertyGet ( m_feed.m_dwAuthenticationType, plAuthenticationType );
  135. }
  136. STDMETHODIMP CNntpOneWayFeed::put_AuthenticationType ( long lAuthenticationType )
  137. {
  138. return StdPropertyPut ( &m_feed.m_dwAuthenticationType, lAuthenticationType );
  139. }
  140. STDMETHODIMP CNntpOneWayFeed::get_AccountName ( BSTR * pstrAccountName )
  141. {
  142. return StdPropertyGet ( m_feed.m_strAccountName, pstrAccountName );
  143. }
  144. STDMETHODIMP CNntpOneWayFeed::put_AccountName ( BSTR strAccountName )
  145. {
  146. return StdPropertyPut ( &m_feed.m_strAccountName, strAccountName );
  147. }
  148. STDMETHODIMP CNntpOneWayFeed::get_Password ( BSTR * pstrPassword )
  149. {
  150. return StdPropertyGet ( m_feed.m_strPassword, pstrPassword );
  151. }
  152. STDMETHODIMP CNntpOneWayFeed::put_Password ( BSTR strPassword )
  153. {
  154. return StdPropertyPut ( &m_feed.m_strPassword, strPassword );
  155. }
  156. STDMETHODIMP CNntpOneWayFeed::get_AllowControlMessages ( BOOL * pfAllowControlMessages )
  157. {
  158. return StdPropertyGet ( m_feed.m_fAllowControlMessages, pfAllowControlMessages );
  159. }
  160. STDMETHODIMP CNntpOneWayFeed::put_AllowControlMessages ( BOOL fAllowControlMessages )
  161. {
  162. return StdPropertyPut ( &m_feed.m_fAllowControlMessages, fAllowControlMessages );
  163. }
  164. STDMETHODIMP CNntpOneWayFeed::get_OutgoingPort ( long * plOutgoingPort )
  165. {
  166. return StdPropertyGet ( m_feed.m_dwOutgoingPort, plOutgoingPort );
  167. }
  168. STDMETHODIMP CNntpOneWayFeed::put_OutgoingPort ( long lOutgoingPort )
  169. {
  170. return StdPropertyPut ( &m_feed.m_dwOutgoingPort, lOutgoingPort );
  171. }
  172. STDMETHODIMP CNntpOneWayFeed::get_Newsgroups ( SAFEARRAY ** ppsastrNewsgroups )
  173. {
  174. return StdPropertyGet ( &m_feed.m_mszNewsgroups, ppsastrNewsgroups );
  175. }
  176. STDMETHODIMP CNntpOneWayFeed::put_Newsgroups ( SAFEARRAY * psastrNewsgroups )
  177. {
  178. return StdPropertyPut ( &m_feed.m_mszNewsgroups, psastrNewsgroups );
  179. }
  180. STDMETHODIMP CNntpOneWayFeed::get_NewsgroupsVariant ( SAFEARRAY ** ppsavarNewsgroups )
  181. {
  182. HRESULT hr;
  183. SAFEARRAY * psastrNewsgroups = NULL;
  184. hr = get_Newsgroups ( &psastrNewsgroups );
  185. if ( FAILED(hr) ) {
  186. goto Exit;
  187. }
  188. hr = StringArrayToVariantArray ( psastrNewsgroups, ppsavarNewsgroups );
  189. Exit:
  190. if ( psastrNewsgroups ) {
  191. SafeArrayDestroy ( psastrNewsgroups );
  192. }
  193. return hr;
  194. }
  195. STDMETHODIMP CNntpOneWayFeed::put_NewsgroupsVariant ( SAFEARRAY * psavarNewsgroups )
  196. {
  197. HRESULT hr;
  198. SAFEARRAY * psastrNewsgroups = NULL;
  199. hr = VariantArrayToStringArray ( psavarNewsgroups, &psastrNewsgroups );
  200. if ( FAILED(hr) ) {
  201. goto Exit;
  202. }
  203. hr = put_Newsgroups ( psastrNewsgroups );
  204. Exit:
  205. if ( psastrNewsgroups ) {
  206. SafeArrayDestroy ( psastrNewsgroups );
  207. }
  208. return hr;
  209. }
  210. STDMETHODIMP CNntpOneWayFeed::get_Distributions ( SAFEARRAY ** ppsastrDistributions )
  211. {
  212. return StdPropertyGet ( &m_feed.m_mszDistributions, ppsastrDistributions );
  213. }
  214. STDMETHODIMP CNntpOneWayFeed::put_Distributions ( SAFEARRAY * psastrDistributions )
  215. {
  216. return StdPropertyPut ( &m_feed.m_mszDistributions, psastrDistributions );
  217. }
  218. STDMETHODIMP CNntpOneWayFeed::get_TempDirectory ( BSTR * pstrTempDirectory )
  219. {
  220. return StdPropertyGet ( m_feed.m_strTempDirectory, pstrTempDirectory );
  221. }
  222. STDMETHODIMP CNntpOneWayFeed::put_TempDirectory ( BSTR strTempDirectory )
  223. {
  224. return StdPropertyPut ( &m_feed.m_strTempDirectory, strTempDirectory );
  225. }
  226. STDMETHODIMP CNntpOneWayFeed::Default ( )
  227. {
  228. TraceFunctEnter ( "CNntpOneWayFeed::Default" );
  229. SYSTEMTIME st;
  230. DATE dateToday;
  231. GetSystemTime ( &st );
  232. SystemTimeToVariantTime ( &st, &dateToday );
  233. m_feed.m_dwFeedId = DEFAULT_FEED_ID;
  234. m_feed.m_strRemoteServer = DEFAULT_FEED_SERVER;
  235. m_feed.m_dwFeedInterval = DEFAULT_FEED_INTERVAL;
  236. m_feed.m_fCreateAutomatically = DEFAULT_AUTO_CREATE;
  237. m_feed.m_fEnabled = DEFAULT_ENABLED;
  238. m_feed.m_dwMaxConnectionAttempts = DEFAULT_MAX_CONNECTIONS_ATTEMPTS;
  239. m_feed.m_dwSecurityType = DEFAULT_SECURITY_TYPE;
  240. m_feed.m_dwAuthenticationType = DEFAULT_AUTH_TYPE;
  241. m_feed.m_strAccountName = DEFAULT_ACCOUNT_NAME;
  242. m_feed.m_strPassword = DEFAULT_PASSWORD;
  243. m_feed.m_fAllowControlMessages = DEFAULT_ALLOW_CONTROL_MESSAGES;
  244. m_feed.m_strUucpName = DEFAULT_UUCP_NAME;
  245. m_feed.m_dwOutgoingPort = 119;
  246. m_feed.m_mszNewsgroups = DEFAULT_NEWSGROUPS;
  247. m_feed.m_mszDistributions = DEFAULT_DISTRIBUTION;
  248. m_feed.m_datePullNews = dateToday;
  249. if ( !m_feed.CheckValid() ) {
  250. TraceFunctLeave ();
  251. return E_OUTOFMEMORY;
  252. }
  253. TraceFunctLeave ();
  254. return NOERROR;
  255. }
  256. /////////////////////////////////////////////////////////////////////////////
  257. //
  258. STDMETHODIMP CNntpFeed::InterfaceSupportsErrorInfo(REFIID riid)
  259. {
  260. static const IID* arr[] =
  261. {
  262. &IID_INntpFeed,
  263. };
  264. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  265. {
  266. if (InlineIsEqualGUID(*arr[i],riid))
  267. return S_OK;
  268. }
  269. return S_FALSE;
  270. }
  271. CNntpFeed::CNntpFeed () :
  272. m_type ( NNTP_FEED_TYPE_PEER )
  273. // CComBSTR's are initialized to NULL by default.
  274. {
  275. // InitAsyncTrace ( );
  276. }
  277. CNntpFeed::~CNntpFeed ()
  278. {
  279. // All CComBSTR's are freed automatically.
  280. // TermAsyncTrace ( );
  281. }
  282. STDMETHODIMP CNntpFeed::get_RemoteServer ( BSTR * pstrRemoteServer )
  283. {
  284. return StdPropertyGet ( m_strRemoteServer, pstrRemoteServer );
  285. }
  286. STDMETHODIMP CNntpFeed::put_RemoteServer ( BSTR strRemoteServer )
  287. {
  288. return StdPropertyPut ( &m_strRemoteServer, strRemoteServer );
  289. }
  290. STDMETHODIMP CNntpFeed::get_FeedType ( NNTP_FEED_SERVER_TYPE * pfeedtype )
  291. {
  292. *pfeedtype = m_type;
  293. return NOERROR;
  294. }
  295. STDMETHODIMP CNntpFeed::put_FeedType ( NNTP_FEED_SERVER_TYPE feedtype )
  296. {
  297. switch ( feedtype ) {
  298. case NNTP_FEED_TYPE_PEER:
  299. case NNTP_FEED_TYPE_MASTER:
  300. case NNTP_FEED_TYPE_SLAVE:
  301. m_type = feedtype;
  302. return NOERROR;
  303. break;
  304. default:
  305. return RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
  306. break;
  307. }
  308. }
  309. STDMETHODIMP CNntpFeed::get_HasInbound ( BOOL * pfHasInbound )
  310. {
  311. *pfHasInbound = m_pInbound != NULL;
  312. return NOERROR;
  313. }
  314. STDMETHODIMP CNntpFeed::get_HasOutbound ( BOOL * pfHasOutbound )
  315. {
  316. *pfHasOutbound = m_pOutbound != NULL;
  317. return NOERROR;
  318. }
  319. STDMETHODIMP CNntpFeed::get_InboundFeed ( INntpOneWayFeed ** ppFeed )
  320. {
  321. HRESULT hr = NOERROR;
  322. *ppFeed = NULL;
  323. if ( m_pInbound ) {
  324. hr = m_pInbound->QueryInterface ( IID_INntpOneWayFeed, (void **) ppFeed );
  325. return hr;
  326. }
  327. return E_FAIL;
  328. }
  329. STDMETHODIMP CNntpFeed::get_OutboundFeed ( INntpOneWayFeed ** ppFeed )
  330. {
  331. HRESULT hr = NOERROR;
  332. *ppFeed = NULL;
  333. if ( m_pOutbound ) {
  334. hr = m_pOutbound->QueryInterface ( IID_INntpOneWayFeed, (void **) ppFeed );
  335. return hr;
  336. }
  337. return E_FAIL;
  338. }
  339. STDMETHODIMP CNntpFeed::put_InboundFeed ( INntpOneWayFeed * pFeed )
  340. {
  341. HRESULT hr = NOERROR;
  342. // !!!magnush - Do some feed type checking here.
  343. m_pInbound.Release ();
  344. m_pInbound = pFeed;
  345. return NOERROR;
  346. }
  347. STDMETHODIMP CNntpFeed::put_OutboundFeed ( INntpOneWayFeed * pFeed )
  348. {
  349. HRESULT hr = NOERROR;
  350. // !!!magnush - Do some feed type checking here.
  351. m_pOutbound.Release ();
  352. m_pOutbound = pFeed;
  353. return hr;
  354. }
  355. STDMETHODIMP CNntpFeed::get_InboundFeedDispatch ( IDispatch ** ppDispatch )
  356. {
  357. HRESULT hr;
  358. CComPtr<INntpOneWayFeed> pInbound;
  359. hr = get_InboundFeed ( &pInbound );
  360. BAIL_ON_FAILURE(hr);
  361. hr = pInbound->QueryInterface ( IID_IDispatch, (void **) ppDispatch );
  362. BAIL_ON_FAILURE(hr);
  363. Exit:
  364. return hr;
  365. }
  366. STDMETHODIMP CNntpFeed::put_InboundFeedDispatch ( IDispatch * pDispatch )
  367. {
  368. HRESULT hr;
  369. CComPtr<INntpOneWayFeed> pInbound;
  370. hr = pDispatch->QueryInterface ( IID_INntpOneWayFeed, (void **) &pInbound );
  371. BAIL_ON_FAILURE(hr);
  372. hr = put_InboundFeed ( pInbound );
  373. BAIL_ON_FAILURE(hr);
  374. Exit:
  375. return hr;
  376. }
  377. STDMETHODIMP CNntpFeed::get_OutboundFeedDispatch ( IDispatch ** ppDispatch )
  378. {
  379. HRESULT hr;
  380. CComPtr<INntpOneWayFeed> pOutbound;
  381. hr = get_OutboundFeed ( &pOutbound );
  382. BAIL_ON_FAILURE(hr);
  383. hr = pOutbound->QueryInterface ( IID_IDispatch, (void **) ppDispatch );
  384. BAIL_ON_FAILURE(hr);
  385. Exit:
  386. return hr;
  387. }
  388. STDMETHODIMP CNntpFeed::put_OutboundFeedDispatch ( IDispatch * pDispatch )
  389. {
  390. HRESULT hr;
  391. CComPtr<INntpOneWayFeed> pOutbound;
  392. hr = pDispatch->QueryInterface ( IID_INntpOneWayFeed, (void **) &pOutbound );
  393. BAIL_ON_FAILURE(hr);
  394. hr = put_OutboundFeed ( pOutbound );
  395. BAIL_ON_FAILURE(hr);
  396. Exit:
  397. return hr;
  398. }
  399. HRESULT CNntpFeed::FromFeedPair ( CFeedPair * pFeedPair )
  400. {
  401. HRESULT hr = NOERROR;
  402. m_pInbound.Release ();
  403. m_pOutbound.Release ();
  404. m_strRemoteServer = pFeedPair->m_strRemoteServer;
  405. m_type = pFeedPair->m_type;
  406. if ( pFeedPair->m_pInbound ) {
  407. hr = pFeedPair->m_pInbound->ToINntpOneWayFeed ( &m_pInbound );
  408. BAIL_ON_FAILURE(hr);
  409. }
  410. if ( pFeedPair->m_pOutbound ) {
  411. hr = pFeedPair->m_pOutbound->ToINntpOneWayFeed ( &m_pOutbound );
  412. BAIL_ON_FAILURE(hr);
  413. }
  414. Exit:
  415. return hr;
  416. }
  417. /////////////////////////////////////////////////////////////////////////////
  418. //
  419. STDMETHODIMP CNntpAdminFeeds::InterfaceSupportsErrorInfo(REFIID riid)
  420. {
  421. static const IID* arr[] =
  422. {
  423. &IID_INntpAdminFeeds,
  424. };
  425. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  426. {
  427. if (InlineIsEqualGUID(*arr[i],riid))
  428. return S_OK;
  429. }
  430. return S_FALSE;
  431. }
  432. CNntpAdminFeeds::CNntpAdminFeeds () :
  433. m_fEnumerated ( FALSE )
  434. // CComBSTR's are initialized to NULL by default.
  435. {
  436. InitAsyncTrace ( );
  437. m_iadsImpl.SetService ( MD_SERVICE_NAME );
  438. m_iadsImpl.SetName ( _T("Feeds") );
  439. m_iadsImpl.SetClass ( _T("IIsNntpFeeds") );
  440. OleInitialize( NULL );
  441. }
  442. CNntpAdminFeeds::~CNntpAdminFeeds ()
  443. {
  444. // All CComBSTR's are freed automatically.
  445. TermAsyncTrace ( );
  446. OleUninitialize();
  447. }
  448. //
  449. // IADs methods:
  450. //
  451. DECLARE_SIMPLE_IADS_IMPLEMENTATION(CNntpAdminFeeds,m_iadsImpl)
  452. //////////////////////////////////////////////////////////////////////
  453. // Properties:
  454. //////////////////////////////////////////////////////////////////////
  455. // Enumeration Properties:
  456. STDMETHODIMP CNntpAdminFeeds::get_Count ( long * plCount )
  457. {
  458. return StdPropertyGet ( m_listFeeds.GetCount(), plCount );
  459. }
  460. //////////////////////////////////////////////////////////////////////
  461. // Methods:
  462. //////////////////////////////////////////////////////////////////////
  463. STDMETHODIMP CNntpAdminFeeds::Enumerate ( )
  464. {
  465. TraceFunctEnter ( "CNntpAdminFeeds::Enumerate" );
  466. HRESULT hr = NOERROR;
  467. DWORD dwError = NOERROR;
  468. DWORD cFeeds = 0;
  469. LPNNTP_FEED_INFO pFeedInfo = NULL;
  470. DWORD i;
  471. dwError = NntpEnumerateFeeds (
  472. m_iadsImpl.QueryComputer(),
  473. m_iadsImpl.QueryInstance(),
  474. &cFeeds,
  475. &pFeedInfo
  476. );
  477. if ( dwError != 0 ) {
  478. ErrorTrace ( (LPARAM) this, "Error enumerating feeds: %x", dwError );
  479. hr = RETURNCODETOHRESULT ( dwError );
  480. goto Exit;
  481. }
  482. // Empty the old feed list:
  483. m_fEnumerated = FALSE;
  484. m_listFeeds.Empty ();
  485. // Add each feed to our list:
  486. for ( i = 0; i < cFeeds; i++ ) {
  487. DWORD dwPairID;
  488. CFeedPair * pFeedPair;
  489. CFeed * pFeed;
  490. // Create a new Feed object:
  491. hr = CFeed::CreateFeedFromFeedInfo ( &pFeedInfo[i], &pFeed );
  492. if ( FAILED(hr) ) {
  493. goto Exit;
  494. }
  495. // Find the pair that matches Feed[i]:
  496. dwPairID = pFeed->m_dwPairFeedId;
  497. pFeedPair = m_listFeeds.Find ( dwPairID );
  498. if ( pFeedPair ) {
  499. // We found a matching pair, so add it:
  500. hr = pFeedPair->AddFeed ( pFeed );
  501. if ( hr == E_FAIL ) {
  502. // Something went wrong - Try to add the feed by itself.
  503. pFeedPair = NULL;
  504. hr = NOERROR;
  505. }
  506. if ( FAILED(hr) ) {
  507. goto Exit;
  508. }
  509. }
  510. if ( pFeedPair == NULL ) {
  511. // We need to create a new feed pair:
  512. hr = CFeedPair::CreateFeedPair (
  513. &pFeedPair,
  514. pFeedInfo[i].ServerName,
  515. FeedTypeToEnum ( pFeedInfo[i].FeedType )
  516. );
  517. if ( FAILED(hr) ) {
  518. goto Exit;
  519. }
  520. // Add the current feed to the new pair:
  521. hr = pFeedPair->AddFeed ( pFeed );
  522. if ( FAILED(hr) ) {
  523. goto Exit;
  524. }
  525. // Add the new pair to the pair list:
  526. m_listFeeds.Add ( pFeedPair );
  527. }
  528. }
  529. // !!!magnush - Stop memory leaks here.
  530. m_fEnumerated = TRUE;
  531. Exit:
  532. if ( FAILED(hr) ) {
  533. m_listFeeds.Empty();
  534. }
  535. if ( pFeedInfo ) {
  536. ::NetApiBufferFree ( pFeedInfo );
  537. }
  538. TRACE_HRESULT(hr);
  539. TraceFunctLeave ();
  540. return hr;
  541. }
  542. STDMETHODIMP CNntpAdminFeeds::Item ( long lIndex, INntpFeed ** ppFeed )
  543. {
  544. TraceFunctEnter ( "CNntpAdminFeeds::Item" );
  545. HRESULT hr = NOERROR;
  546. CFeedPair * pFeedPair;
  547. // Did we enumerate first?
  548. if ( !m_fEnumerated ) {
  549. hr = NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_ENUMERATE );
  550. TraceFunctLeave ();
  551. return hr;
  552. }
  553. pFeedPair = m_listFeeds.Item ( lIndex );
  554. if ( !pFeedPair ) {
  555. hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  556. goto Exit;
  557. }
  558. hr = pFeedPair->ToINntpFeed ( ppFeed );
  559. if ( FAILED(hr) ) {
  560. goto Exit;
  561. }
  562. Exit:
  563. TRACE_HRESULT(hr);
  564. TraceFunctLeave ();
  565. return hr;
  566. }
  567. STDMETHODIMP CNntpAdminFeeds::FindID ( long lID, long * plIndex )
  568. {
  569. TraceFunctEnter ( "CNntpAdminFeeds::FindID" );
  570. HRESULT hr = NOERROR;
  571. CFeedPair * pFeedPair;
  572. *plIndex = -1;
  573. pFeedPair = m_listFeeds.Find ( (DWORD) lID );
  574. if ( pFeedPair ) {
  575. *plIndex = (long) m_listFeeds.GetPairIndex ( pFeedPair );
  576. }
  577. TraceFunctLeave ();
  578. return hr;
  579. }
  580. HRESULT CNntpAdminFeeds::ReturnFeedPair ( CFeedPair * pFeedPair, INntpFeed * pFeed )
  581. {
  582. HRESULT hr;
  583. CComPtr<INntpOneWayFeed> pInbound;
  584. CComPtr<INntpOneWayFeed> pOutbound;
  585. CComPtr<INntpFeed> pNewFeedPair;
  586. hr = pFeedPair->ToINntpFeed ( &pNewFeedPair );
  587. BAIL_ON_FAILURE(hr);
  588. pNewFeedPair->get_InboundFeed ( &pInbound );
  589. pNewFeedPair->get_OutboundFeed ( &pOutbound );
  590. pFeed->put_InboundFeed ( pInbound );
  591. pFeed->put_OutboundFeed ( pOutbound );
  592. Exit:
  593. return hr;
  594. }
  595. STDMETHODIMP CNntpAdminFeeds::Add ( INntpFeed * pFeed )
  596. {
  597. TraceFunctEnter ( "CNntpAdminFeeds::Add" );
  598. HRESULT hr = NOERROR;
  599. CFeedPair * pFeedPair = NULL;
  600. CComBSTR strRemoteServer;
  601. CComBSTR strServer;
  602. NNTP_FEED_SERVER_TYPE type;
  603. CMetabaseKey *pMK = NULL;
  604. IMSAdminBase *pMeta = NULL;
  605. hr = pFeed->get_RemoteServer ( &strRemoteServer );
  606. BAIL_ON_FAILURE(hr);
  607. hr = get_Server(&strServer);
  608. BAIL_ON_FAILURE(hr);
  609. hr = CreateMetabaseObject( strServer, &pMeta );
  610. _ASSERT( SUCCEEDED( hr ) );
  611. BAIL_ON_FAILURE(hr);
  612. pMK = new CMetabaseKey(pMeta);
  613. if (!pMK)
  614. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  615. hr = pFeed->get_FeedType ( &type );
  616. BAIL_ON_FAILURE(hr);
  617. hr = CFeedPair::CreateFeedPair ( &pFeedPair, strRemoteServer, type );
  618. BAIL_ON_FAILURE(hr);
  619. hr = pFeedPair->FromINntpFeed ( pFeed );
  620. BAIL_ON_FAILURE(hr);
  621. hr = pFeedPair->AddToServer (
  622. m_iadsImpl.QueryComputer(),
  623. m_iadsImpl.QueryInstance(),
  624. pMK
  625. );
  626. BAIL_ON_FAILURE(hr);
  627. m_listFeeds.Add ( pFeedPair );
  628. // Return the new feeds (and their IDs) to the caller:
  629. hr = ReturnFeedPair ( pFeedPair, pFeed );
  630. BAIL_ON_FAILURE(hr);
  631. Exit:
  632. if ( FAILED(hr) ) {
  633. delete pFeedPair;
  634. }
  635. if (pMK)
  636. delete pMK;
  637. if (pMeta)
  638. pMeta->Release();
  639. TRACE_HRESULT(hr);
  640. TraceFunctLeave ();
  641. return hr;
  642. }
  643. STDMETHODIMP CNntpAdminFeeds::Set ( long lIndex, INntpFeed * pFeed )
  644. {
  645. TraceFunctEnter ( "CNntpAdminFeeds::Set" );
  646. HRESULT hr = NOERROR;
  647. CFeedPair * pFeedPair;
  648. CComPtr<INntpFeed> pNewFeedPair;
  649. CComPtr<INntpOneWayFeed> pInbound;
  650. CComPtr<INntpOneWayFeed> pOutbound;
  651. CComBSTR strServer;
  652. CMetabaseKey *pMK = NULL;
  653. IMSAdminBase *pMeta = NULL;
  654. hr = get_Server ( &strServer );
  655. BAIL_ON_FAILURE(hr);
  656. hr = CreateMetabaseObject( strServer, &pMeta );
  657. _ASSERT( SUCCEEDED( hr ) );
  658. BAIL_ON_FAILURE(hr);
  659. pMK = new CMetabaseKey(pMeta);
  660. if (!pMK)
  661. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  662. pFeedPair = m_listFeeds.Item ( lIndex );
  663. if ( !pFeedPair ) {
  664. hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  665. goto Exit;
  666. }
  667. hr = pFeedPair->SetToServer (
  668. m_iadsImpl.QueryComputer(),
  669. m_iadsImpl.QueryInstance(),
  670. pFeed,
  671. pMK
  672. );
  673. BAIL_ON_FAILURE(hr);
  674. // Return the new feeds (and their IDs) to the caller:
  675. hr = ReturnFeedPair ( pFeedPair, pFeed );
  676. BAIL_ON_FAILURE(hr);
  677. Exit:
  678. if (pMK)
  679. delete pMK;
  680. if (pMeta)
  681. pMeta->Release();
  682. TRACE_HRESULT(hr);
  683. TraceFunctLeave ();
  684. return hr;
  685. }
  686. STDMETHODIMP CNntpAdminFeeds::Remove ( long lIndex )
  687. {
  688. TraceFunctEnter ( "CNntpAdminFeeds::Remove" );
  689. HRESULT hr = NOERROR;
  690. CFeedPair * pFeedPair;
  691. CComBSTR strServer;
  692. CMetabaseKey *pMK = NULL;
  693. IMSAdminBase *pMeta = NULL;
  694. pFeedPair = m_listFeeds.Item ( lIndex );
  695. if ( !pFeedPair ) {
  696. hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  697. goto Exit;
  698. }
  699. hr = get_Server ( &strServer );
  700. BAIL_ON_FAILURE(hr);
  701. hr = CreateMetabaseObject( strServer, &pMeta );
  702. _ASSERT( SUCCEEDED( hr ) );
  703. BAIL_ON_FAILURE(hr);
  704. pMK = new CMetabaseKey(pMeta);
  705. if (!pMK)
  706. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  707. hr = pFeedPair->RemoveFromServer (
  708. m_iadsImpl.QueryComputer(),
  709. m_iadsImpl.QueryInstance(),
  710. pMK
  711. );
  712. if ( FAILED(hr) ) {
  713. goto Exit;
  714. }
  715. m_listFeeds.Remove ( pFeedPair );
  716. Exit:
  717. if (pMK)
  718. delete pMK;
  719. if (pMeta)
  720. pMeta->Release();
  721. TRACE_HRESULT(hr);
  722. TraceFunctLeave ();
  723. return hr;
  724. }
  725. STDMETHODIMP CNntpAdminFeeds::ItemDispatch ( long index, IDispatch ** ppDispatch )
  726. {
  727. HRESULT hr;
  728. CComPtr<INntpFeed> pFeed;
  729. hr = Item ( index, &pFeed );
  730. BAIL_ON_FAILURE ( hr );
  731. hr = pFeed->QueryInterface ( IID_IDispatch, (void **) ppDispatch );
  732. BAIL_ON_FAILURE ( hr );
  733. Exit:
  734. return hr;
  735. }
  736. STDMETHODIMP CNntpAdminFeeds::AddDispatch ( IDispatch * pFeed )
  737. {
  738. HRESULT hr;
  739. CComPtr<INntpFeed> pINntpFeed;
  740. hr = pFeed->QueryInterface ( IID_INntpFeed, (void **) &pINntpFeed );
  741. BAIL_ON_FAILURE(hr);
  742. hr = Add ( pINntpFeed );
  743. BAIL_ON_FAILURE(hr);
  744. Exit:
  745. return hr;
  746. }
  747. STDMETHODIMP CNntpAdminFeeds::SetDispatch ( long lIndex, IDispatch * pFeed )
  748. {
  749. HRESULT hr;
  750. CComPtr<INntpFeed> pINntpFeed;
  751. hr = pFeed->QueryInterface ( IID_INntpFeed, (void **) &pINntpFeed );
  752. BAIL_ON_FAILURE(hr);
  753. hr = Set ( lIndex, pINntpFeed );
  754. BAIL_ON_FAILURE(hr);
  755. Exit:
  756. return hr;
  757. }