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.

1076 lines
23 KiB

  1. // expire.cpp : Implementation of CnntpadmApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "nntpcmn.h"
  4. #include "expire.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.Expiration.1")
  12. #define THIS_FILE_IID IID_INntpAdminExpiration
  13. /////////////////////////////////////////////////////////////////////////////
  14. //
  15. //
  16. // Use a macro to define all the default methods
  17. //
  18. DECLARE_METHOD_IMPLEMENTATION_FOR_STANDARD_EXTENSION_INTERFACES(NntpAdminExpiration, CNntpAdminExpiration, IID_INntpAdminExpiration)
  19. STDMETHODIMP CNntpAdminExpiration::InterfaceSupportsErrorInfo(REFIID riid)
  20. {
  21. static const IID* arr[] =
  22. {
  23. &IID_INntpAdminExpiration,
  24. };
  25. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  26. {
  27. if (InlineIsEqualGUID(*arr[i],riid))
  28. return S_OK;
  29. }
  30. return S_FALSE;
  31. }
  32. CNntpAdminExpiration::CNntpAdminExpiration () :
  33. m_fEnumerated ( FALSE ),
  34. m_bvChangedFields ( 0 ),
  35. m_cCount ( 0 ),
  36. m_rgExpires ( NULL )
  37. // CComBSTR's are initialized to NULL by default.
  38. {
  39. InitAsyncTrace ( );
  40. m_iadsImpl.SetService ( MD_SERVICE_NAME );
  41. m_iadsImpl.SetName ( _T("Expires") );
  42. m_iadsImpl.SetClass ( _T("IIsNntpExpires") );
  43. }
  44. CNntpAdminExpiration::~CNntpAdminExpiration ()
  45. {
  46. // All CComBSTR's are freed automatically.
  47. if ( m_rgExpires ) {
  48. delete [] m_rgExpires;
  49. m_rgExpires = NULL;
  50. }
  51. TermAsyncTrace ( );
  52. }
  53. //
  54. // IADs methods:
  55. //
  56. DECLARE_SIMPLE_IADS_IMPLEMENTATION(CNntpAdminExpiration,m_iadsImpl)
  57. //////////////////////////////////////////////////////////////////////
  58. // Properties:
  59. //////////////////////////////////////////////////////////////////////
  60. // Enumeration Properties:
  61. STDMETHODIMP CNntpAdminExpiration::get_Count ( long * plCount )
  62. {
  63. return StdPropertyGet ( m_cCount, plCount );
  64. }
  65. // Cursor Expire Properties:
  66. STDMETHODIMP CNntpAdminExpiration::get_ExpireId ( long * plId )
  67. {
  68. return StdPropertyGet ( m_expireCurrent.m_dwExpireId, plId );
  69. }
  70. STDMETHODIMP CNntpAdminExpiration::put_ExpireId ( long lId )
  71. {
  72. return StdPropertyPut ( &m_expireCurrent.m_dwExpireId, lId, &m_bvChangedFields, CHNG_EXPIRE_ID );
  73. }
  74. STDMETHODIMP CNntpAdminExpiration::get_PolicyName ( BSTR * pstrPolicyName )
  75. {
  76. return StdPropertyGet ( m_expireCurrent.m_strPolicyName, pstrPolicyName );
  77. }
  78. STDMETHODIMP CNntpAdminExpiration::put_PolicyName ( BSTR strPolicyName )
  79. {
  80. return StdPropertyPut ( &m_expireCurrent.m_strPolicyName, strPolicyName, &m_bvChangedFields, CHNG_EXPIRE_POLICY_NAME );
  81. }
  82. STDMETHODIMP CNntpAdminExpiration::get_ExpireTime ( long * plExpireTime )
  83. {
  84. return StdPropertyGet ( m_expireCurrent.m_dwTime, plExpireTime );
  85. }
  86. STDMETHODIMP CNntpAdminExpiration::put_ExpireTime ( long lExpireTime )
  87. {
  88. return StdPropertyPut ( &m_expireCurrent.m_dwTime, lExpireTime, &m_bvChangedFields, CHNG_EXPIRE_TIME );
  89. }
  90. STDMETHODIMP CNntpAdminExpiration::get_ExpireSize ( long * plExpireSize )
  91. {
  92. return StdPropertyGet ( m_expireCurrent.m_dwSize, plExpireSize );
  93. }
  94. STDMETHODIMP CNntpAdminExpiration::put_ExpireSize ( long lExpireSize )
  95. {
  96. return StdPropertyPut ( &m_expireCurrent.m_dwSize, lExpireSize, &m_bvChangedFields, CHNG_EXPIRE_SIZE );
  97. }
  98. STDMETHODIMP CNntpAdminExpiration::get_Newsgroups ( SAFEARRAY ** ppsastrNewsgroups )
  99. {
  100. return StdPropertyGet ( &m_expireCurrent.m_mszNewsgroups, ppsastrNewsgroups );
  101. }
  102. STDMETHODIMP CNntpAdminExpiration::put_Newsgroups ( SAFEARRAY * psastrNewsgroups )
  103. {
  104. return StdPropertyPut ( &m_expireCurrent.m_mszNewsgroups, psastrNewsgroups, &m_bvChangedFields, CHNG_EXPIRE_NEWSGROUPS );
  105. }
  106. STDMETHODIMP CNntpAdminExpiration::get_NewsgroupsVariant ( SAFEARRAY ** ppsavarNewsgroups )
  107. {
  108. HRESULT hr;
  109. SAFEARRAY * psastrNewsgroups = NULL;
  110. hr = get_Newsgroups ( &psastrNewsgroups );
  111. if ( FAILED(hr) ) {
  112. goto Exit;
  113. }
  114. hr = StringArrayToVariantArray ( psastrNewsgroups, ppsavarNewsgroups );
  115. Exit:
  116. if ( psastrNewsgroups ) {
  117. SafeArrayDestroy ( psastrNewsgroups );
  118. }
  119. return hr;
  120. }
  121. STDMETHODIMP CNntpAdminExpiration::put_NewsgroupsVariant ( SAFEARRAY * psavarNewsgroups )
  122. {
  123. HRESULT hr;
  124. SAFEARRAY * psastrNewsgroups = NULL;
  125. hr = VariantArrayToStringArray ( psavarNewsgroups, &psastrNewsgroups );
  126. if ( FAILED(hr) ) {
  127. goto Exit;
  128. }
  129. hr = put_Newsgroups ( psastrNewsgroups );
  130. Exit:
  131. if ( psastrNewsgroups ) {
  132. SafeArrayDestroy ( psastrNewsgroups );
  133. }
  134. return hr;
  135. }
  136. //////////////////////////////////////////////////////////////////////
  137. // Methods:
  138. //////////////////////////////////////////////////////////////////////
  139. STDMETHODIMP CNntpAdminExpiration::Default ( )
  140. {
  141. TraceFunctEnter ( "CNntpAdminExpiration::Default" );
  142. HRESULT hr = NOERROR;
  143. m_expireCurrent.m_dwSize = DEFAULT_EXPIRE_SIZE;
  144. m_expireCurrent.m_dwTime = DEFAULT_EXPIRE_TIME;
  145. m_expireCurrent.m_mszNewsgroups = DEFAULT_EXPIRE_NEWSGROUPS;
  146. m_bvChangedFields = (DWORD) -1;
  147. if ( !m_expireCurrent.CheckValid() ) {
  148. BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
  149. }
  150. Exit:
  151. TRACE_HRESULT(hr);
  152. TraceFunctLeave ();
  153. return hr;
  154. }
  155. STDMETHODIMP CNntpAdminExpiration::Enumerate ( )
  156. {
  157. TraceFunctEnter ( "CNntpAdminExpiration::Enumerate" );
  158. HRESULT hr = NOERROR;
  159. DWORD dwError = NOERROR;
  160. DWORD cExpires = 0;
  161. LPNNTP_EXPIRE_INFO pExpireInfo = NULL;
  162. CExpirationPolicy * rgNewExpires = NULL;
  163. DWORD i;
  164. dwError = NntpEnumerateExpires (
  165. m_iadsImpl.QueryComputer(),
  166. m_iadsImpl.QueryInstance(),
  167. &cExpires,
  168. &pExpireInfo
  169. );
  170. if ( dwError != 0 ) {
  171. ErrorTrace ( (LPARAM) this, "Error enumerating Expires: %x", dwError );
  172. hr = RETURNCODETOHRESULT ( dwError );
  173. goto Exit;
  174. }
  175. // Empty the old Expire list:
  176. m_fEnumerated = FALSE;
  177. if ( m_rgExpires ) {
  178. delete [] m_rgExpires;
  179. m_rgExpires = NULL;
  180. }
  181. m_cCount = 0;
  182. // Attempt to copy the Expire list into our structures:
  183. if ( cExpires > 0 ) {
  184. rgNewExpires = new CExpirationPolicy [ cExpires ];
  185. for ( i = 0; i < cExpires; i++ ) {
  186. rgNewExpires[i].FromExpireInfo ( &pExpireInfo[i] );
  187. if ( !rgNewExpires[i].CheckValid () ) {
  188. hr = E_OUTOFMEMORY;
  189. goto Exit;
  190. }
  191. }
  192. }
  193. m_fEnumerated = TRUE;
  194. m_rgExpires = rgNewExpires;
  195. m_cCount = cExpires;
  196. Exit:
  197. if ( FAILED(hr) ) {
  198. delete [] rgNewExpires;
  199. }
  200. if ( pExpireInfo ) {
  201. ::NetApiBufferFree ( pExpireInfo );
  202. }
  203. TRACE_HRESULT(hr);
  204. TraceFunctLeave ();
  205. return hr;
  206. }
  207. STDMETHODIMP CNntpAdminExpiration::GetNth ( long lIndex )
  208. {
  209. TraceFunctEnter ( "CNntpAdminExpiration::GetNth" );
  210. HRESULT hr = NOERROR;
  211. // Did we enumerate first?
  212. if ( m_rgExpires == NULL ) {
  213. TraceFunctLeave ();
  214. return NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_ENUMERATE );
  215. }
  216. // Is the index valid?
  217. if ( lIndex < 0 || (DWORD) lIndex >= m_cCount ) {
  218. TraceFunctLeave ();
  219. return NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  220. }
  221. //
  222. // Copy the properties from m_rgExpires [ lIndex ] to member variables:
  223. //
  224. _ASSERT ( lIndex >= 0 );
  225. _ASSERT ( (DWORD) lIndex < m_cCount );
  226. _ASSERT ( m_rgExpires != NULL );
  227. m_expireCurrent = m_rgExpires[ (DWORD) lIndex ];
  228. // Check to make sure the strings were copied okay:
  229. if ( !m_expireCurrent.CheckValid() ) {
  230. return E_OUTOFMEMORY;
  231. }
  232. _ASSERT ( m_expireCurrent.CheckValid() );
  233. // ( CComBSTR handles free-ing of old properties )
  234. TraceFunctLeave ();
  235. return NOERROR;
  236. }
  237. STDMETHODIMP CNntpAdminExpiration::FindID ( long lID, long * plIndex )
  238. {
  239. TraceFunctEnter ( "CNntpAdminExpiration::FindID" );
  240. HRESULT hr = NOERROR;
  241. // Assume that we can't find it:
  242. *plIndex = IndexFromID ( lID );
  243. TraceFunctLeave ();
  244. return hr;
  245. }
  246. STDMETHODIMP CNntpAdminExpiration::Add ( )
  247. {
  248. TraceFunctEnter ( "CNntpAdminExpiration::Add" );
  249. HRESULT hr = NOERROR;
  250. CExpirationPolicy * rgNewExpireArray = NULL;
  251. DWORD cNewCount = m_cCount + 1;
  252. DWORD i;
  253. hr = m_expireCurrent.Add (
  254. m_iadsImpl.QueryComputer(),
  255. m_iadsImpl.QueryInstance()
  256. );
  257. BAIL_ON_FAILURE(hr);
  258. // Add the new Expire to our current Expire list:
  259. _ASSERT ( IndexFromID ( m_expireCurrent.m_dwExpireId ) == (DWORD) -1 );
  260. // Allocate the new array:
  261. _ASSERT ( cNewCount == m_cCount + 1 );
  262. rgNewExpireArray = new CExpirationPolicy [ cNewCount ];
  263. if ( rgNewExpireArray == NULL ) {
  264. FatalTrace ( (LPARAM) this, "Out of memory" );
  265. hr = E_OUTOFMEMORY;
  266. goto Exit;
  267. }
  268. // Copy the old array into the new one:
  269. for ( i = 0; i < m_cCount; i++ ) {
  270. rgNewExpireArray[i] = m_rgExpires[i];
  271. }
  272. // Add the new element:
  273. rgNewExpireArray[cNewCount - 1] = m_expireCurrent;
  274. // Check to make sure everything was allocated okay:
  275. for ( i = 0; i < cNewCount; i++ ) {
  276. if ( !rgNewExpireArray[i].CheckValid() ) {
  277. FatalTrace ( (LPARAM) this, "Out of memory" );
  278. hr = E_OUTOFMEMORY;
  279. goto Exit;
  280. }
  281. }
  282. // Replace the old array with the new one:
  283. delete [] m_rgExpires;
  284. m_rgExpires = rgNewExpireArray;
  285. m_cCount = cNewCount;
  286. Exit:
  287. if ( FAILED(hr) ) {
  288. delete [] rgNewExpireArray;
  289. }
  290. TRACE_HRESULT(hr);
  291. TraceFunctLeave ();
  292. return hr;
  293. }
  294. STDMETHODIMP CNntpAdminExpiration::Set ( )
  295. {
  296. TraceFunctEnter ( "CNntpAdminExpiration::Set" );
  297. HRESULT hr = NOERROR;
  298. DWORD index;
  299. hr = m_expireCurrent.Set (
  300. m_iadsImpl.QueryComputer(),
  301. m_iadsImpl.QueryInstance()
  302. );
  303. if ( FAILED(hr) ) {
  304. goto Exit;
  305. }
  306. index = IndexFromID ( m_expireCurrent.m_dwExpireId );
  307. if ( index == (DWORD) -1 ) {
  308. ErrorTraceX ( (LPARAM) this, "Couldn't find Expire with ID: %d", m_expireCurrent.m_dwExpireId );
  309. // This is okay, since we succeeded in setting the current Expire already.
  310. goto Exit;
  311. }
  312. // Set the current Expire in the current Expire list:
  313. m_rgExpires[index] = m_expireCurrent;
  314. if ( !m_rgExpires[index].CheckValid () ) {
  315. FatalTrace ( (LPARAM) this, "Out of memory" );
  316. hr = E_OUTOFMEMORY;
  317. goto Exit;
  318. }
  319. Exit:
  320. TRACE_HRESULT(hr);
  321. TraceFunctLeave ();
  322. return hr;
  323. }
  324. STDMETHODIMP CNntpAdminExpiration::Remove ( long lID )
  325. {
  326. TraceFunctEnter ( "CNntpAdminExpiration::Remove" );
  327. HRESULT hr = NOERROR;
  328. DWORD index;
  329. index = IndexFromID ( lID );
  330. if ( index == (DWORD) -1 ) {
  331. ErrorTraceX ( (LPARAM) this, "Couldn't find Expire with ID: %d", lID );
  332. hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  333. goto Exit;
  334. }
  335. hr = m_rgExpires[index].Remove (
  336. m_iadsImpl.QueryComputer(),
  337. m_iadsImpl.QueryInstance()
  338. );
  339. if ( FAILED(hr) ) {
  340. goto Exit;
  341. }
  342. // Slide the array down by one position:
  343. _ASSERT ( m_rgExpires );
  344. DWORD cPositionsToSlide;
  345. cPositionsToSlide = (m_cCount - 1) - index;
  346. _ASSERT ( cPositionsToSlide < m_cCount );
  347. if ( cPositionsToSlide > 0 ) {
  348. CExpirationPolicy temp;
  349. // Save the deleted binding in temp:
  350. CopyMemory ( &temp, &m_rgExpires[index], sizeof ( CExpirationPolicy ) );
  351. // Move the array down one:
  352. MoveMemory ( &m_rgExpires[index], &m_rgExpires[index + 1], sizeof ( CExpirationPolicy ) * cPositionsToSlide );
  353. // Put the deleted binding on the end (so it gets destructed):
  354. CopyMemory ( &m_rgExpires[m_cCount - 1], &temp, sizeof ( CExpirationPolicy ) );
  355. // Zero out the temp binding:
  356. ZeroMemory ( &temp, sizeof ( CExpirationPolicy ) );
  357. }
  358. m_cCount--;
  359. Exit:
  360. TRACE_HRESULT(hr);
  361. TraceFunctLeave ();
  362. return hr;
  363. }
  364. long CNntpAdminExpiration::IndexFromID ( long dwExpireId )
  365. {
  366. TraceFunctEnter ( "CNntpAdminExpiration::IndexFromID" );
  367. DWORD i;
  368. if ( m_rgExpires == NULL ) {
  369. return -1;
  370. }
  371. _ASSERT ( !IsBadReadPtr ( m_rgExpires, sizeof ( CExpirationPolicy ) * m_cCount ) );
  372. for ( i = 0; i < m_cCount; i++ ) {
  373. _ASSERT ( m_rgExpires[i].m_dwExpireId != 0 );
  374. if ( (DWORD) dwExpireId == m_rgExpires[i].m_dwExpireId ) {
  375. TraceFunctLeave ();
  376. return i;
  377. }
  378. }
  379. TraceFunctLeave ();
  380. return (DWORD) -1;
  381. }
  382. //
  383. // Use RPCs instead of direct metabase calls:
  384. //
  385. #if 0
  386. STDMETHODIMP CNntpAdminExpiration::Enumerate ( )
  387. {
  388. TraceFunctEnter ( "CNntpadminExpiration::Enumerate" );
  389. HRESULT hr = NOERROR;
  390. CComPtr<IMSAdminBase> pMetabase;
  391. // Reset our last enumeration:
  392. delete [] m_rgExpires;
  393. m_rgExpires = NULL;
  394. m_cCount = 0;
  395. m_fEnumerated = FALSE;
  396. // Get the metabase pointer:
  397. hr = m_mbFactory.GetMetabaseObject (
  398. m_iadsImpl.QueryComputer(),
  399. m_iadsImpl.QueryInstance()
  400. );
  401. if ( FAILED(hr) ) {
  402. goto Exit;
  403. }
  404. // Enumerate the policies:
  405. hr = EnumerateMetabaseExpirationPolicies ( pMetabase );
  406. if ( FAILED(hr) ) {
  407. goto Exit;
  408. }
  409. Exit:
  410. TRACE_HRESULT(hr);
  411. TraceFunctLeave ();
  412. return hr;
  413. }
  414. STDMETHODIMP CNntpAdminExpiration::GetNth ( DWORD lIndex )
  415. {
  416. HRESULT hr = NOERROR;
  417. // Did we enumerate first?
  418. if ( m_rgExpires == NULL ) {
  419. return NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_ENUMERATE );
  420. }
  421. // Is the index valid?
  422. if ( lIndex < 0 || (DWORD) lIndex >= m_cCount ) {
  423. return NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  424. }
  425. //
  426. // Copy the properties from m_rgExpires [ lIndex ] to member variables:
  427. //
  428. _ASSERT ( lIndex >= 0 );
  429. _ASSERT ( (DWORD) lIndex < m_cCount );
  430. _ASSERT ( m_rgExpires != NULL );
  431. m_expireCurrent = m_rgExpires[ (DWORD) lIndex ];
  432. // Check to make sure the strings were copied okay:
  433. if ( !m_expireCurrent.CheckValid() ) {
  434. return E_OUTOFMEMORY;
  435. }
  436. m_bvChangedFields = 0;
  437. _ASSERT ( m_expireCurrent.CheckValid() );
  438. // ( CComBSTR handles free-ing of old properties )
  439. return NOERROR;
  440. }
  441. STDMETHODIMP CNntpAdminExpiration::FindID ( DWORD lID, DWORD * plIndex )
  442. {
  443. TraceFunctEnter ( "CNntpAdminExpiration::FindID" );
  444. HRESULT hr = NOERROR;
  445. DWORD i;
  446. _ASSERT ( IS_VALID_OUT_PARAM ( plIndex ) );
  447. *plIndex = IndexFromID ( lID );
  448. TraceFunctLeave ();
  449. return hr;
  450. }
  451. STDMETHODIMP CNntpAdminExpiration::Add ( )
  452. {
  453. TraceFunctEnter ( "CNntpAdminExpiration::Add" );
  454. HRESULT hr = NOERROR;
  455. CComPtr<IMSAdminBase> pMetabase;
  456. // Get the metabase pointer:
  457. hr = m_mbFactory.GetMetabaseObject (
  458. m_iadsImpl.QueryComputer(),
  459. m_iadsImpl.QueryInstance()
  460. );
  461. if ( FAILED(hr) ) {
  462. goto Exit;
  463. }
  464. hr = AddPolicyToMetabase ( pMetabase );
  465. if ( FAILED(hr) ) {
  466. goto Exit;
  467. }
  468. m_bvChangedFields = 0;
  469. hr = AddPolicyToArray ( );
  470. if ( FAILED(hr) ) {
  471. goto Exit;
  472. }
  473. Exit:
  474. TRACE_HRESULT(hr);
  475. TraceFunctLeave ();
  476. return hr;
  477. }
  478. STDMETHODIMP CNntpAdminExpiration::Set ( BOOL fFailIfChanged)
  479. {
  480. TraceFunctEnter ( "CNntpadminExpiration::Enumerate" );
  481. HRESULT hr = NOERROR;
  482. CComPtr<IMSAdminBase> pMetabase;
  483. // Get the metabase pointer:
  484. hr = m_mbFactory.GetMetabaseObject (
  485. m_iadsImpl.QueryComputer(),
  486. m_iadsImpl.QueryInstance()
  487. );
  488. if ( FAILED(hr) ) {
  489. goto Exit;
  490. }
  491. // Set the policy:
  492. hr = SetPolicyToMetabase ( pMetabase );
  493. if ( FAILED(hr) ) {
  494. goto Exit;
  495. }
  496. m_bvChangedFields = 0;
  497. hr = SetPolicyToArray ( );
  498. if ( FAILED(hr) ) {
  499. goto Exit;
  500. }
  501. Exit:
  502. TRACE_HRESULT(hr);
  503. TraceFunctLeave ();
  504. return hr;
  505. }
  506. STDMETHODIMP CNntpAdminExpiration::Remove ( DWORD lID)
  507. {
  508. TraceFunctEnter ( "CNntpadminExpiration::Remove" );
  509. HRESULT hr = NOERROR;
  510. CComPtr<IMSAdminBase> pMetabase;
  511. DWORD index;
  512. // Find the index of the policy to remove:
  513. index = IndexFromID ( lID );
  514. if ( index == (DWORD) -1 ) {
  515. hr = RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
  516. goto Exit;
  517. }
  518. // Get the metabase pointer:
  519. hr = m_mbFactory.GetMetabaseObject (
  520. m_iadsImpl.QueryComputer(),
  521. m_iadsImpl.QueryInstance()
  522. );
  523. if ( FAILED(hr) ) {
  524. goto Exit;
  525. }
  526. // Remove the current policy:
  527. hr = RemovePolicyFromMetabase ( pMetabase, index );
  528. if ( FAILED(hr) ) {
  529. goto Exit;
  530. }
  531. hr = RemovePolicyFromArray ( index );
  532. if ( FAILED(hr) ) {
  533. goto Exit;
  534. }
  535. Exit:
  536. TRACE_HRESULT(hr);
  537. TraceFunctLeave ();
  538. return hr;
  539. }
  540. HRESULT CNntpAdminExpiration::EnumerateMetabaseExpirationPolicies ( IMSAdminBase * pMetabase)
  541. {
  542. TraceFunctEnter ( "CNE::EnumerateMetabaseExpirationPolicies" );
  543. _ASSERT ( pMetabase );
  544. HRESULT hr = NOERROR;
  545. char szExpirationPath[ METADATA_MAX_NAME_LEN ];
  546. METADATA_HANDLE hExpiration = NULL;
  547. CMetabaseKey mkeyExpiration ( pMetabase );
  548. DWORD cExpires;
  549. DWORD i;
  550. _ASSERT ( m_dwServiceInstance != 0 );
  551. hr = CreateSubkeyOfInstanceKey (
  552. pMetabase,
  553. NNTP_MD_ROOT_PATH,
  554. m_dwServiceInstance,
  555. NNTP_MD_EXPIRES_PATH,
  556. &hExpiration
  557. );
  558. if ( FAILED(hr) ) {
  559. goto Exit;
  560. }
  561. mkeyExpiration.Attach ( hExpiration );
  562. // Count the items under the /LM/NntpSvc/Expires/ key:
  563. hr = mkeyExpiration.GetCustomChildCount ( IsKeyValidExpire, &cExpires );
  564. if ( FAILED (hr) ) {
  565. goto Exit;
  566. }
  567. if ( cExpires != 0 ) {
  568. // Allocate the expiration policy array:
  569. m_rgExpires = new CExpirationPolicy [ cExpires ];
  570. mkeyExpiration.BeginChildEnumeration ();
  571. for ( i = 0; i < cExpires; i++ ) {
  572. char szName[ METADATA_MAX_NAME_LEN ];
  573. DWORD dwID;
  574. hr = mkeyExpiration.NextCustomChild ( IsKeyValidExpire, szName );
  575. _ASSERT ( SUCCEEDED(hr) );
  576. hr = m_rgExpires[i].GetFromMetabase ( &mkeyExpiration, szName );
  577. if ( FAILED (hr) ) {
  578. goto Exit;
  579. }
  580. }
  581. }
  582. m_cCount = cExpires;
  583. m_fEnumerated = TRUE;
  584. _ASSERT ( SUCCEEDED(hr) );
  585. Exit:
  586. if ( FAILED(hr) ) {
  587. delete [] m_rgExpires;
  588. m_rgExpires = NULL;
  589. m_cCount = 0;
  590. m_fEnumerated = FALSE;
  591. }
  592. TraceFunctLeave ();
  593. return hr;
  594. }
  595. HRESULT CNntpAdminExpiration::AddPolicyToMetabase ( IMSAdminBase * pMetabase)
  596. {
  597. TraceFunctEnter ( "CNE::AddPolicyToMetabase" );
  598. _ASSERT ( pMetabase );
  599. HRESULT hr = NOERROR;
  600. char szExpirationPath [ METADATA_MAX_NAME_LEN ];
  601. METADATA_HANDLE hExpiration = NULL;
  602. CMetabaseKey mkeyExpiration ( pMetabase );
  603. char szNewId [ METADATA_MAX_NAME_LEN ];
  604. DWORD dwNewId;
  605. if ( !m_expireCurrent.CheckPolicyProperties ( ) ) {
  606. hr = RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
  607. goto Exit;
  608. }
  609. hr = CreateSubkeyOfInstanceKey (
  610. pMetabase,
  611. NNTP_MD_ROOT_PATH,
  612. m_dwServiceInstance,
  613. NNTP_MD_EXPIRES_PATH,
  614. &hExpiration,
  615. METADATA_PERMISSION_WRITE
  616. );
  617. if ( FAILED(hr) ) {
  618. goto Exit;
  619. }
  620. mkeyExpiration.Attach ( hExpiration );
  621. hr = m_expireCurrent.AddToMetabase ( &mkeyExpiration );
  622. if ( FAILED(hr) ) {
  623. goto Exit;
  624. }
  625. _ASSERT ( SUCCEEDED(hr) );
  626. hr = pMetabase->SaveData ( );
  627. if ( FAILED(hr) ) {
  628. goto Exit;
  629. }
  630. Exit:
  631. TraceFunctLeave ();
  632. return hr;
  633. }
  634. HRESULT CNntpAdminExpiration::AddPolicyToArray ( )
  635. {
  636. TraceFunctEnter ( "CNE::AddPolicyToArray" );
  637. HRESULT hr = NOERROR;
  638. CExpirationPolicy * rgNewPolicyArray = NULL;
  639. DWORD i;
  640. // Adjust the expiration policy array:
  641. rgNewPolicyArray = new CExpirationPolicy [ m_cCount + 1 ];
  642. if ( rgNewPolicyArray == NULL ) {
  643. hr = E_OUTOFMEMORY;
  644. goto Exit;
  645. }
  646. // Copy the old entries:
  647. for ( i = 0; i < m_cCount; i++ ) {
  648. _ASSERT ( m_rgExpires[i].CheckValid() );
  649. rgNewPolicyArray[i] = m_rgExpires[i];
  650. if ( !rgNewPolicyArray[i].CheckValid() ) {
  651. hr = E_OUTOFMEMORY;
  652. goto Exit;
  653. }
  654. }
  655. // Add the new entry:
  656. _ASSERT ( m_expireCurrent.CheckValid() );
  657. rgNewPolicyArray[m_cCount] = m_expireCurrent;
  658. if ( !rgNewPolicyArray[m_cCount].CheckValid() ) {
  659. hr = E_OUTOFMEMORY;
  660. goto Exit;
  661. }
  662. _ASSERT ( SUCCEEDED(hr) );
  663. delete [] m_rgExpires;
  664. m_rgExpires = rgNewPolicyArray;
  665. m_cCount++;
  666. Exit:
  667. if ( FAILED(hr) ) {
  668. delete [] rgNewPolicyArray;
  669. }
  670. TRACE_HRESULT(hr);
  671. TraceFunctLeave ();
  672. return hr;
  673. }
  674. HRESULT CNntpAdminExpiration::SetPolicyToMetabase ( IMSAdminBase * pMetabase)
  675. {
  676. TraceFunctEnter ( "CNE::SetPolicyToMetabase" );
  677. _ASSERT ( pMetabase );
  678. HRESULT hr = NOERROR;
  679. CMetabaseKey mkeyExpiration ( pMetabase );
  680. char szExpirationPath [ METADATA_MAX_NAME_LEN ];
  681. if ( !m_expireCurrent.CheckPolicyProperties ( ) ) {
  682. hr = RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
  683. goto Exit;
  684. }
  685. GetMDExpirationPath ( szExpirationPath, m_dwServiceInstance );
  686. hr = mkeyExpiration.Open ( szExpirationPath, METADATA_PERMISSION_WRITE );
  687. if ( FAILED(hr) ) {
  688. goto Exit;
  689. }
  690. _ASSERT ( m_expireCurrent.m_dwExpireId != 0 );
  691. hr = m_expireCurrent.SendToMetabase ( &mkeyExpiration, m_bvChangedFields );
  692. if ( FAILED(hr) ) {
  693. goto Exit;
  694. }
  695. hr = pMetabase->SaveData ( );
  696. if ( FAILED(hr) ) {
  697. goto Exit;
  698. }
  699. Exit:
  700. TraceFunctLeave ();
  701. return hr;
  702. }
  703. HRESULT CNntpAdminExpiration::SetPolicyToArray ( )
  704. {
  705. TraceFunctEnter ( "CNE::SetPolicyToArray" );
  706. HRESULT hr = NOERROR;
  707. // Find the index of the current ID:
  708. DWORD i;
  709. BOOL fFound = FALSE;
  710. DWORD index;
  711. index = IndexFromID ( m_expireCurrent.m_dwExpireId );
  712. if ( index == (DWORD) -1 ) {
  713. // Couldn't find an id that matched, but the policy was successfully
  714. // set. Just ignore:
  715. goto Exit;
  716. }
  717. _ASSERT ( index >= 0 && index < m_cCount );
  718. m_rgExpires[index] = m_expireCurrent;
  719. if ( !m_rgExpires[index].CheckValid() ) {
  720. FatalTrace ( (LPARAM) this, "Out of memory" );
  721. hr = E_OUTOFMEMORY;
  722. goto Exit;
  723. }
  724. Exit:
  725. TraceFunctLeave ();
  726. return hr;
  727. }
  728. HRESULT CNntpAdminExpiration::RemovePolicyFromMetabase ( IMSAdminBase * pMetabase, DWORD index)
  729. {
  730. TraceFunctEnter ( "CNE::RemovePolicyFromMetabase" );
  731. _ASSERT ( pMetabase );
  732. HRESULT hr = NOERROR;
  733. CMetabaseKey mkeyExpiration ( pMetabase );
  734. char szExpirationPath [ METADATA_MAX_NAME_LEN ];
  735. char szID [ METADATA_MAX_NAME_LEN ];
  736. GetMDExpirationPath ( szExpirationPath, m_dwServiceInstance );
  737. hr = mkeyExpiration.Open ( szExpirationPath, METADATA_PERMISSION_WRITE );
  738. if ( FAILED(hr) ) {
  739. goto Exit;
  740. }
  741. _ASSERT ( index >= 0 && index < m_cCount );
  742. wsprintfA ( szID, "expire%ud", m_rgExpires[index].m_dwExpireId );
  743. hr = mkeyExpiration.DestroyChild ( szID );
  744. if ( FAILED(hr) ) {
  745. goto Exit;
  746. }
  747. _ASSERT ( SUCCEEDED(hr) );
  748. hr = pMetabase->SaveData ( );
  749. if ( FAILED(hr) ) {
  750. goto Exit;
  751. }
  752. Exit:
  753. TraceFunctLeave ();
  754. return hr;
  755. }
  756. HRESULT CNntpAdminExpiration::RemovePolicyFromArray ( DWORD index )
  757. {
  758. TraceFunctEnter ( "CNE::RemovePolicyFromArray" );
  759. HRESULT hr = NOERROR;
  760. CExpirationPolicy * rgNewExpireArray = NULL;
  761. DWORD i;
  762. // !!!magnush - Should I just do a memmove and slide the entries
  763. // down, and zero out the last entry?
  764. _ASSERT ( index >= 0 && index < m_cCount );
  765. // Adjust the Expiration policy array:
  766. if ( m_cCount > 1 ) {
  767. // Allocate a new expiration policy array:
  768. rgNewExpireArray = new CExpirationPolicy [ m_cCount - 1 ];
  769. // Copy the items from 0 .. (current index) to the new list:
  770. for ( i = 0; i < index; i++ ) {
  771. _ASSERT ( m_rgExpires[i].CheckValid() );
  772. rgNewExpireArray[i] = m_rgExpires[i];
  773. if ( !rgNewExpireArray[i].CheckValid() ) {
  774. hr = E_OUTOFMEMORY;
  775. goto Exit;
  776. }
  777. }
  778. // Copy the items from (current index + 1) .. m_cCount to the new list:
  779. for ( i = index + 1; i < m_cCount; i++ ) {
  780. _ASSERT ( m_rgExpires[i].CheckValid() );
  781. rgNewExpireArray[i - 1] = m_rgExpires[i];
  782. if ( !rgNewExpireArray[i - 1].CheckValid() ) {
  783. hr = E_OUTOFMEMORY;
  784. goto Exit;
  785. }
  786. }
  787. }
  788. _ASSERT ( SUCCEEDED(hr) );
  789. // Replace the old expiration list with the new one:
  790. delete [] m_rgExpires;
  791. m_rgExpires = rgNewExpireArray;
  792. m_cCount--;
  793. Exit:
  794. if ( FAILED (hr) ) {
  795. delete [] rgNewExpireArray;
  796. }
  797. TraceFunctLeave ();
  798. return hr;
  799. }
  800. long CNntpAdminExpiration::IndexFromID ( long dwID )
  801. {
  802. TraceFunctEnter ( "CNE::IndexFromID" );
  803. DWORD i;
  804. if ( m_rgExpires == NULL ) {
  805. DebugTrace ( (LPARAM) this, "Expire array is NULL" );
  806. TraceFunctLeave ();
  807. return (DWORD) -1;
  808. }
  809. _ASSERT ( !IsBadReadPtr ( m_rgExpires, sizeof ( CExpirationPolicy ) * m_cCount ) );
  810. for ( i = 0; i < m_cCount; i++ ) {
  811. if ( m_rgExpires[i].m_dwExpireId == dwID ) {
  812. DebugTraceX ( (LPARAM) this, "Found ID: %d, index = ", dwID, i );
  813. TraceFunctLeave ();
  814. return i;
  815. }
  816. }
  817. DebugTraceX ( (LPARAM) this, "Failed to find ID: %d", dwID );
  818. TraceFunctLeave ();
  819. return (DWORD) -1;
  820. }
  821. #endif