Leaked source code of windows server 2003
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.

1003 lines
26 KiB

  1. #include "stdafx.h"
  2. #include "feedpach.h"
  3. #define ALLOCATE_HEAP( nBytes ) LocalAlloc( 0, nBytes )
  4. #define FREE_HEAP( _heap ) LocalFree( (PVOID)(_heap) )
  5. #define ERR_KEY_ALREADY_EXIST 0x800700b7 // BugBug: This key macro should be
  6. // replaced by the official one
  7. VOID
  8. FillFeedRoot( DWORD dwInstance, LPWSTR wszBuffer )
  9. {
  10. swprintf( wszBuffer, L"/LM/nntpsvc/%d/feeds/", dwInstance );
  11. }
  12. BOOL
  13. VerifyMultiSzListW(
  14. LPBYTE List,
  15. DWORD cbList
  16. )
  17. /*++
  18. Routine Description:
  19. This routine verifies that the list is indeed a multisz
  20. Arguments:
  21. List - the list to be verified
  22. cbList - size of the list
  23. Return Value:
  24. TRUE, list is a multisz
  25. FALSE, otherwise
  26. --*/
  27. {
  28. PWCHAR wList = (PWCHAR)List;
  29. DWORD len;
  30. //
  31. // null are considered no hits
  32. //
  33. if ( (List == NULL) || (*List == L'\0') ) {
  34. return(FALSE);
  35. }
  36. //
  37. // see if they are ok
  38. //
  39. for ( DWORD j = 0; j < cbList; ) {
  40. len = wcslen((LPWSTR)&List[j]);
  41. if ( len > 0 ) {
  42. j += ((len + 1) * sizeof(WCHAR));
  43. } else {
  44. //
  45. // all done
  46. //
  47. return(TRUE);
  48. }
  49. }
  50. #ifndef UNIT_TEST
  51. ErrorTraceX(0,"VerifyMultiSzListW: exception handled\n");
  52. #endif
  53. return(FALSE);
  54. } // VerifyMultiSzList
  55. DWORD
  56. MultiListSize(
  57. LPWSTR *List
  58. )
  59. /*++
  60. Routine Description:
  61. This routine computes the size of the multisz structure needed
  62. to accomodate a list.
  63. Arguments:
  64. List - the list whose string lengths are to be computed
  65. Return Value:
  66. Size of buffer needed to accomodate list.
  67. --*/
  68. {
  69. TraceFunctEnter( "MultiListSize" );
  70. _ASSERT( List );
  71. DWORD nBytes = 2;
  72. DWORD i = 0;
  73. if ( List != NULL ) {
  74. while ( List[i] != NULL ) {
  75. nBytes += ( lstrlen(List[i]) + 1 ) * sizeof( WCHAR );
  76. i++;
  77. }
  78. }
  79. TraceFunctLeave();
  80. return(nBytes);
  81. } // MultiListSize
  82. DWORD
  83. GetNumStringsInMultiSz(
  84. PWCHAR Blob,
  85. DWORD BlobSize
  86. )
  87. /*++
  88. Routine Description:
  89. This routine returns the number of strings in the multisz
  90. Arguments:
  91. Blob - the list to be verified
  92. BlobSize - size of the list
  93. Return Value:
  94. number of entries in the multisz structure.
  95. --*/
  96. {
  97. TraceFunctEnter( "GetNumStringInMultiSz" );
  98. _ASSERT( Blob );
  99. DWORD entries = 0;
  100. DWORD len;
  101. DWORD j;
  102. for ( j = 0; j < BlobSize; ) {
  103. len = lstrlen(&Blob[j]);
  104. if ( len > 0 ) {
  105. entries++;
  106. }
  107. j += (len + 1);
  108. if( len == 0 ) {
  109. break;
  110. }
  111. }
  112. _ASSERT( j == BlobSize );
  113. TraceFunctLeave();
  114. return(entries);
  115. } // GetNumStringsInMultiSz
  116. LPWSTR *
  117. AllocateMultiSzTable(
  118. IN PWCHAR List,
  119. IN DWORD cbList
  120. )
  121. {
  122. TraceFunctEnter( "AllocateMultiSzTable" );
  123. _ASSERT( List );
  124. DWORD len;
  125. PCHAR buffer;
  126. DWORD entries = 0;
  127. LPWSTR* table;
  128. PWCHAR nextVar;
  129. DWORD numItems;
  130. numItems = GetNumStringsInMultiSz( List, cbList );
  131. if ( numItems == 0 ) {
  132. return(NULL);
  133. }
  134. buffer = (PCHAR)ALLOCATE_HEAP((numItems + 1) * sizeof(LPWSTR) + cbList * sizeof( WCHAR ));
  135. if ( buffer == NULL ) {
  136. return(NULL);
  137. }
  138. table = (LPWSTR *)buffer;
  139. nextVar = PWCHAR( buffer + (numItems + 1)*sizeof(LPWSTR) );
  140. for ( DWORD j = 0; j < cbList; ) {
  141. len = lstrlen(&List[j]);
  142. if ( len > 0 ) {
  143. table[entries] = (LPWSTR)nextVar;
  144. CopyMemory(nextVar,&List[j],(len+1)*sizeof( WCHAR ));
  145. (VOID)_wcslwr(table[entries]);
  146. entries++;
  147. nextVar += (len+1);
  148. }
  149. j += (len + 1);
  150. }
  151. *nextVar = L'\0';
  152. table[numItems] = NULL;
  153. TraceFunctLeave();
  154. return(table);
  155. } // AllocateMultiSzTable
  156. HRESULT
  157. OpenKey( DWORD dwFeedId, CMetabaseKey* pMK, DWORD dwPermission, DWORD dwInstance )
  158. {
  159. TraceFunctEnter( "OpenKey" );
  160. _ASSERT( dwFeedId > 0 );
  161. _ASSERT( pMK );
  162. HRESULT hr;
  163. WCHAR wszFeedKey[MAX_PATH];
  164. swprintf( wszFeedKey, L"/LM/nntpsvc/%d/Feeds/feed%d/", dwInstance, dwFeedId );
  165. hr = pMK->Open( METADATA_MASTER_ROOT_HANDLE,
  166. wszFeedKey,
  167. dwPermission );
  168. if ( FAILED( hr ) ) {
  169. ErrorTrace(0, "Open feed key fail with 0x%x", hr );
  170. return hr;
  171. }
  172. TraceFunctLeave();
  173. return S_OK;
  174. }
  175. VOID
  176. CloseKey( CMetabaseKey* pMK )
  177. {
  178. pMK->Close();
  179. }
  180. VOID
  181. SaveKey( CMetabaseKey* pMK )
  182. {
  183. pMK->Save();
  184. }
  185. HRESULT
  186. AddKey( DWORD dwFeedId, CMetabaseKey* pMK, DWORD dwInstance )
  187. {
  188. TraceFunctEnter( "Addkey" );
  189. _ASSERT( dwFeedId > 0 );
  190. _ASSERT( pMK );
  191. HRESULT hResult;
  192. WCHAR wszFeedRoot[MAX_PATH];
  193. WCHAR wszFeedKey[MAX_PATH];
  194. FillFeedRoot( dwInstance, wszFeedRoot );
  195. hResult = pMK->Open( METADATA_MASTER_ROOT_HANDLE,
  196. wszFeedRoot,
  197. METADATA_PERMISSION_WRITE );
  198. if ( FAILED( hResult ) ) {
  199. ErrorTrace( 0, "Open root for write fail with 0x%x", hResult );
  200. return hResult;
  201. }
  202. swprintf( wszFeedKey, L"feed%d", dwFeedId );
  203. hResult = pMK->CreateChild( wszFeedKey );
  204. if ( FAILED( hResult ) ) {
  205. ErrorTrace( 0, "Create key fail with 0x%x", hResult );
  206. pMK->Close();
  207. return hResult;
  208. }
  209. pMK->Close();
  210. TraceFunctLeave();
  211. return S_OK;
  212. }
  213. HRESULT
  214. DeleteKey( DWORD dwFeedId, CMetabaseKey* pMK, DWORD dwInstance )
  215. {
  216. TraceFunctEnter( "DeleteKey" );
  217. _ASSERT( pMK );
  218. HRESULT hResult;
  219. WCHAR wszFeedRoot[MAX_PATH];
  220. WCHAR wszFeedKey[MAX_PATH];
  221. FillFeedRoot( dwInstance, wszFeedRoot );
  222. hResult = pMK->Open( METADATA_MASTER_ROOT_HANDLE,
  223. wszFeedRoot,
  224. METADATA_PERMISSION_WRITE );
  225. if ( FAILED( hResult ) ) {
  226. ErrorTrace( 0, "Open root key for write fail with 0x%x", hResult );
  227. return hResult;
  228. }
  229. swprintf( wszFeedKey, L"feed%d", dwFeedId );
  230. hResult = pMK->DestroyChild( wszFeedKey );
  231. if ( FAILED( hResult ) ) {
  232. ErrorTrace(0, "Delete key fail with 0x%x", hResult );
  233. pMK->Close();
  234. }
  235. pMK->Close();
  236. TraceFunctLeave();
  237. return S_OK;
  238. }
  239. HRESULT
  240. SetDwordProp( DWORD dwPropId, DWORD dwPropVal, CMetabaseKey* pMK )
  241. {
  242. TraceFunctEnter( "SetDwordProp" );
  243. _ASSERT( pMK );
  244. HRESULT hResult;
  245. hResult = pMK->SetDword( dwPropId, dwPropVal );
  246. if ( FAILED( hResult ) ) {
  247. ErrorTrace( 0, "Set DWord fail with 0x%x", hResult );
  248. return hResult;
  249. }
  250. TraceFunctLeave();
  251. return S_OK;
  252. }
  253. HRESULT
  254. SetStringProp( DWORD dwPropId, LPWSTR wszStringVal, CMetabaseKey* pMK )
  255. {
  256. TraceFunctEnter( "SetStringProp" );
  257. HRESULT hr;
  258. hr = pMK->SetString( dwPropId, wszStringVal );
  259. if ( FAILED( hr ) ) {
  260. ErrorTrace( 0, "Open key for property setting fail with 0x%x", hr );
  261. return hr;
  262. }
  263. TraceFunctLeave();
  264. return S_OK;
  265. }
  266. HRESULT
  267. SetStringProp( DWORD dwPropId, LPWSTR wszStringVal, CMetabaseKey* pMK, DWORD dwFlags, DWORD dwUserType)
  268. {
  269. TraceFunctEnter( "SetStringProp" );
  270. HRESULT hr;
  271. hr = pMK->SetString( dwPropId, wszStringVal, dwFlags, dwUserType );
  272. if ( FAILED( hr ) ) {
  273. ErrorTrace( 0, "Open key for property setting fail with 0x%x", hr );
  274. return hr;
  275. }
  276. TraceFunctLeave();
  277. return S_OK;
  278. }
  279. HRESULT
  280. SetMultiString( DWORD dwPropId,
  281. LPWSTR* mszPropVal,
  282. CMetabaseKey* pMK )
  283. {
  284. TraceFunctEnter( "SetMultiString" );
  285. HRESULT hr;
  286. hr = pMK->SetMultiSz( dwPropId, mszPropVal[0], MultiListSize( mszPropVal ) );
  287. if ( FAILED( hr ) ) {
  288. ErrorTrace( 0, "Set multisz property fail with 0x%x", hr );
  289. return hr;
  290. }
  291. TraceFunctLeave();
  292. return S_OK;
  293. }
  294. HRESULT
  295. AllocNextAvailableFeedId( CMetabaseKey* pMK, PDWORD pdwFeedId, DWORD dwInstance )
  296. {
  297. TraceFunctEnter( "AllocNextAvailableFeedId" );
  298. _ASSERT( pMK );
  299. HRESULT hr;
  300. DWORD dwCounter = 0;
  301. while( TRUE ) {
  302. hr = AddKey( ++dwCounter, pMK, dwInstance );
  303. if ( SUCCEEDED( hr ) ) {
  304. TraceFunctLeave();
  305. *pdwFeedId = dwCounter;
  306. return S_OK;
  307. }
  308. if ( hr != ERR_KEY_ALREADY_EXIST ) {
  309. TraceFunctLeave();
  310. ErrorTrace( 0, "Alloc key fail with 0x%x", hr );
  311. return hr;
  312. }
  313. }
  314. TraceFunctLeave(); // will never reach here
  315. return E_FAIL;
  316. }
  317. //
  318. // The pMK should already have been opened for write permission
  319. //
  320. HRESULT
  321. UpdateFeedMetabaseValues( CMetabaseKey* pMK,
  322. LPNNTP_FEED_INFO pFeedInfo,
  323. DWORD dwMask,
  324. PDWORD dwRetMask )
  325. {
  326. TraceFunctEnter( "UpdateFeedMetabaseValues" );
  327. _ASSERT( pMK );
  328. _ASSERT( pFeedInfo );
  329. HRESULT hr;
  330. LPWSTR* stringList;
  331. //
  332. // Set the KeyType.
  333. //
  334. hr = SetStringProp( MD_KEY_TYPE,
  335. TEXT(NNTP_ADSI_OBJECT_FEED),
  336. pMK,
  337. METADATA_NO_ATTRIBUTES,
  338. IIS_MD_UT_SERVER
  339. );
  340. if (FAILED(hr))
  341. {
  342. goto fail_exit;
  343. }
  344. if ( ( dwMask & FEED_PARM_FEEDTYPE) != 0 ) {
  345. hr = SetDwordProp( MD_FEED_TYPE,
  346. pFeedInfo->FeedType,
  347. pMK );
  348. if ( FAILED( hr ) ) {
  349. ErrorTrace(0, "Set feed type fail with 0x%x", hr );
  350. *dwRetMask |= FEED_PARM_FEEDTYPE;
  351. goto fail_exit;
  352. }
  353. }
  354. if ( ( dwMask & FEED_PARM_AUTOCREATE ) != 0 ) {
  355. hr = SetDwordProp( MD_FEED_CREATE_AUTOMATICALLY,
  356. DWORD(pFeedInfo->AutoCreate),
  357. pMK );
  358. if ( FAILED( hr ) ) {
  359. ErrorTrace(0, "Set auto creat fail with 0x%x", hr );
  360. *dwRetMask |= FEED_PARM_AUTOCREATE;
  361. goto fail_exit;
  362. }
  363. }
  364. if ( !FEED_IS_PASSIVE( pFeedInfo->FeedType ) ) {
  365. if ( ( dwMask & FEED_PARM_FEEDINTERVAL ) != 0 ) {
  366. hr = SetDwordProp( MD_FEED_INTERVAL,
  367. pFeedInfo->FeedInterval,
  368. pMK );
  369. if ( FAILED( hr ) ) {
  370. ErrorTrace(0, "Set feed interval fail with 0x%x", hr );
  371. *dwRetMask |= FEED_PARM_FEEDINTERVAL;
  372. goto fail_exit;
  373. }
  374. }
  375. if ( ( dwMask & FEED_PARM_STARTTIME ) != 0 ) {
  376. hr = SetDwordProp( MD_FEED_START_TIME_HIGH,
  377. (pFeedInfo->StartTime).dwHighDateTime,
  378. pMK );
  379. if ( FAILED( hr ) ) {
  380. ErrorTrace(0, "Set start time fail with 0x%x", hr );
  381. *dwRetMask |= FEED_PARM_STARTTIME;
  382. goto fail_exit;
  383. }
  384. hr = SetDwordProp( MD_FEED_START_TIME_LOW,
  385. (pFeedInfo->StartTime).dwLowDateTime,
  386. pMK );
  387. if ( FAILED( hr ) ) {
  388. ErrorTrace(0, "Set start time fail with 0x%x" , hr );
  389. *dwRetMask |= FEED_PARM_STARTTIME;
  390. goto fail_exit;
  391. }
  392. }
  393. if ( ( dwMask & FEED_PARM_PULLREQUESTTIME ) != 0 ) {
  394. hr = SetDwordProp(
  395. MD_FEED_NEXT_PULL_HIGH,
  396. (pFeedInfo->PullRequestTime).dwHighDateTime,
  397. pMK );
  398. if ( FAILED( hr ) ) {
  399. ErrorTrace(0, "Set pull request time fail with 0x%x", hr );
  400. *dwRetMask |= FEED_PARM_PULLREQUESTTIME;
  401. goto fail_exit;
  402. }
  403. hr = SetDwordProp(
  404. MD_FEED_NEXT_PULL_LOW,
  405. (pFeedInfo->PullRequestTime).dwLowDateTime,
  406. pMK );
  407. if ( FAILED( hr ) ) {
  408. ErrorTrace(0, "Set pull request time fail with 0x%x", hr );
  409. *dwRetMask |= FEED_PARM_PULLREQUESTTIME;
  410. goto fail_exit;
  411. }
  412. }
  413. }
  414. if ( ( dwMask & FEED_PARM_SERVERNAME ) != 0 ) {
  415. hr = SetStringProp( MD_FEED_SERVER_NAME,
  416. pFeedInfo->ServerName,
  417. pMK );
  418. if ( FAILED( hr ) ) {
  419. ErrorTrace(0, "Set server name fail with 0x%x", hr ) ;
  420. *dwRetMask |= FEED_PARM_SERVERNAME;
  421. goto fail_exit;
  422. }
  423. }
  424. if ( ( dwMask & FEED_PARM_NEWSGROUPS ) != 0 ) {
  425. stringList = AllocateMultiSzTable( pFeedInfo->Newsgroups,
  426. pFeedInfo->cbNewsgroups / sizeof( WCHAR ));
  427. if ( !stringList ) {
  428. ErrorTrace(0, "Generate multi sz fail" );
  429. hr = E_OUTOFMEMORY;
  430. *dwRetMask |= FEED_PARM_NEWSGROUPS;
  431. goto fail_exit;
  432. }
  433. hr = SetMultiString( MD_FEED_NEWSGROUPS,
  434. stringList,
  435. pMK );
  436. if ( FAILED( hr ) ) {
  437. ErrorTrace(0, "Set newsgroups fail with 0x%x", hr );
  438. *dwRetMask |= MD_FEED_NEWSGROUPS;
  439. goto fail_exit;
  440. }
  441. FREE_HEAP( stringList );
  442. }
  443. if ( ( dwMask & FEED_PARM_DISTRIBUTION ) != 0 ) {
  444. stringList = AllocateMultiSzTable( pFeedInfo->Distribution,
  445. pFeedInfo->cbDistribution / sizeof( WCHAR ));
  446. if ( !stringList ) {
  447. ErrorTrace(0, "Generate multi sz fail" );
  448. hr = E_OUTOFMEMORY;
  449. *dwRetMask |= FEED_PARM_DISTRIBUTION;
  450. goto fail_exit;
  451. }
  452. hr = SetMultiString( MD_FEED_DISTRIBUTION,
  453. stringList,
  454. pMK );
  455. if ( FAILED( hr ) ) {
  456. ErrorTrace(0, "Set distribution fail with 0x%x", hr );
  457. *dwRetMask |= FEED_PARM_DISTRIBUTION;
  458. goto fail_exit;
  459. }
  460. FREE_HEAP( stringList );
  461. }
  462. if ( ( dwMask & FEED_PARM_ENABLED ) != 0 ) {
  463. hr = SetDwordProp( MD_FEED_DISABLED,
  464. DWORD( pFeedInfo->Enabled ),
  465. pMK );
  466. if ( FAILED( hr ) ) {
  467. ErrorTrace(0, "Set feed enable fail with 0x%x", hr );
  468. *dwRetMask |= FEED_PARM_ENABLED;
  469. goto fail_exit;
  470. }
  471. }
  472. if ( ( dwMask & FEED_PARM_UUCPNAME ) != 0 && pFeedInfo->UucpName ){
  473. hr = SetStringProp( MD_FEED_UUCP_NAME,
  474. pFeedInfo->UucpName,
  475. pMK );
  476. if ( FAILED( hr ) ) {
  477. ErrorTrace(0, "Set uucp name fail with 0x%x", hr );
  478. *dwRetMask |= FEED_PARM_UUCPNAME;
  479. goto fail_exit;
  480. }
  481. }
  482. if ( ( dwMask & FEED_PARM_TEMPDIR ) != 0 && pFeedInfo->FeedTempDirectory ) {
  483. hr = SetStringProp( MD_FEED_TEMP_DIRECTORY,
  484. pFeedInfo->FeedTempDirectory,
  485. pMK );
  486. if ( FAILED( hr ) ) {
  487. ErrorTrace(0, "Set temp dir fail with 0x%x", hr );
  488. *dwRetMask |= FEED_PARM_TEMPDIR;
  489. goto fail_exit;
  490. }
  491. }
  492. if ( ( dwMask & FEED_PARM_MAXCONNECT ) != 0 ) {
  493. hr = SetDwordProp( MD_FEED_MAX_CONNECTION_ATTEMPTS,
  494. pFeedInfo->MaxConnectAttempts,
  495. pMK );
  496. if ( FAILED( hr ) ) {
  497. ErrorTrace(0, "Set max connect fail with 0x%x", hr );
  498. *dwRetMask |= FEED_PARM_MAXCONNECT;
  499. goto fail_exit;
  500. }
  501. }
  502. if ( ( dwMask & FEED_PARM_SESSIONSECURITY ) != 0 ) {
  503. hr = SetDwordProp( MD_FEED_SECURITY_TYPE,
  504. pFeedInfo->SessionSecurityType,
  505. pMK );
  506. if ( FAILED( hr ) ) {
  507. ErrorTrace(0, "Set session sec type fail with 0x%x", hr );
  508. *dwRetMask |= FEED_PARM_SESSIONSECURITY;
  509. goto fail_exit;
  510. }
  511. }
  512. if ( ( dwMask & FEED_PARM_CONCURRENTSESSION ) != 0 ) {
  513. hr = SetDwordProp( MD_FEED_CONCURRENT_SESSIONS,
  514. pFeedInfo->ConcurrentSessions,
  515. pMK );
  516. if ( FAILED(hr ) ) {
  517. ErrorTrace(0, "Set concurrent sessions fail with 0x%x", hr );
  518. *dwRetMask |= FEED_PARM_CONCURRENTSESSION;
  519. goto fail_exit;
  520. }
  521. }
  522. if ( ( dwMask & FEED_PARM_AUTHTYPE ) != 0 ) {
  523. hr = SetDwordProp( MD_FEED_AUTHENTICATION_TYPE,
  524. pFeedInfo->AuthenticationSecurityType,
  525. pMK );
  526. if ( FAILED( hr ) ) {
  527. ErrorTrace(0, "Set auth type fail with 0x%x", hr );
  528. *dwRetMask |= FEED_PARM_AUTHTYPE;
  529. goto fail_exit;
  530. }
  531. }
  532. if ( ( dwMask & FEED_PARM_ACCOUNTNAME ) != 0 && pFeedInfo->NntpAccountName ) {
  533. hr = SetStringProp( MD_FEED_ACCOUNT_NAME,
  534. pFeedInfo->NntpAccountName,
  535. pMK );
  536. if ( FAILED( hr ) ) {
  537. ErrorTrace(0, "Set account name fail with 0x%x", hr );
  538. *dwRetMask |= FEED_PARM_ACCOUNTNAME;
  539. goto fail_exit;
  540. }
  541. }
  542. if ( ( dwMask & FEED_PARM_PASSWORD ) != 0 && pFeedInfo->NntpPassword ) {
  543. hr = SetStringProp( MD_FEED_PASSWORD,
  544. pFeedInfo->NntpPassword,
  545. pMK,
  546. METADATA_SECURE,
  547. IIS_MD_UT_SERVER);
  548. if( FAILED( hr ) ) {
  549. ErrorTrace(0, "Set password fail with 0x%x", hr );
  550. *dwRetMask |= FEED_PARM_PASSWORD;
  551. goto fail_exit;
  552. }
  553. }
  554. if ( ( dwMask & FEED_PARM_ALLOW_CONTROL ) != 0 ) {
  555. hr = SetDwordProp( MD_FEED_ALLOW_CONTROL_MSGS,
  556. DWORD( pFeedInfo->fAllowControlMessages ),
  557. pMK );
  558. if ( FAILED( hr ) ) {
  559. ErrorTrace( 0, "Set allow control msgs fail with 0x%x", hr );
  560. *dwRetMask |= FEED_PARM_ALLOW_CONTROL;
  561. goto fail_exit;
  562. }
  563. }
  564. if ( ( dwMask & FEED_PARM_OUTGOING_PORT ) != 0 ) {
  565. hr = SetDwordProp( MD_FEED_OUTGOING_PORT,
  566. pFeedInfo->OutgoingPort,
  567. pMK );
  568. if ( FAILED( hr ) ) {
  569. ErrorTrace(0, "Set outgoing port fail with 0x%x", hr );
  570. *dwRetMask |= FEED_PARM_OUTGOING_PORT;
  571. goto fail_exit;
  572. }
  573. }
  574. if ( ( dwMask & FEED_PARM_FEEDPAIR_ID ) != 0 ) {
  575. hr = SetDwordProp( MD_FEED_FEEDPAIR_ID,
  576. pFeedInfo->FeedPairId,
  577. pMK );
  578. if ( FAILED( hr ) ) {
  579. ErrorTrace(0, "Set pair id fail with 0x%x", hr );
  580. *dwRetMask |= FEED_PARM_FEEDPAIR_ID;
  581. goto fail_exit;
  582. }
  583. }
  584. TraceFunctLeave();
  585. return S_OK;
  586. fail_exit:
  587. TraceFunctLeave();
  588. return hr;
  589. }
  590. VOID
  591. SetPresenceMask( LPNNTP_FEED_INFO pFeedInfo, PDWORD pdwMask, BOOL fIsAdd )
  592. {
  593. TraceFunctEnter( "SetPresenceMask" );
  594. _ASSERT( pFeedInfo );
  595. _ASSERT( pdwMask );
  596. BOOL newsPresent = FALSE;
  597. *pdwMask = 0;
  598. //
  599. // feed type, assume always exist for add, non-existant for set
  600. //
  601. if ( fIsAdd ) *pdwMask |= FEED_PARM_FEEDTYPE;
  602. //
  603. // server name
  604. //
  605. if ( pFeedInfo->ServerName != FEED_STRINGS_NOCHANGE &&
  606. *pFeedInfo->ServerName != L'\0' )
  607. *pdwMask |= FEED_PARM_SERVERNAME;
  608. //
  609. // news groups
  610. //
  611. if ( VerifyMultiSzListW( LPBYTE( pFeedInfo->Newsgroups ),
  612. pFeedInfo->cbNewsgroups ) ) {
  613. *pdwMask |= FEED_PARM_NEWSGROUPS;
  614. newsPresent = TRUE;
  615. }
  616. //
  617. // Distribution
  618. //
  619. if ( VerifyMultiSzListW( LPBYTE( pFeedInfo->Distribution ),
  620. pFeedInfo->cbDistribution ) )
  621. *pdwMask |= FEED_PARM_DISTRIBUTION;
  622. //
  623. // Uucp Name
  624. //
  625. if ( pFeedInfo->UucpName != FEED_STRINGS_NOCHANGE &&
  626. *pFeedInfo->UucpName != L'\0' )
  627. *pdwMask |= FEED_PARM_UUCPNAME;
  628. //
  629. // account name
  630. //
  631. if ( pFeedInfo->NntpAccountName != FEED_STRINGS_NOCHANGE &&
  632. *pFeedInfo->NntpAccountName != L'\0' )
  633. *pdwMask |= FEED_PARM_ACCOUNTNAME;
  634. //
  635. // Password
  636. //
  637. if ( pFeedInfo->NntpPassword != FEED_STRINGS_NOCHANGE &&
  638. *pFeedInfo->NntpPassword != L'\0' )
  639. *pdwMask |= FEED_PARM_PASSWORD;
  640. //
  641. // Temp dir
  642. //
  643. if ( pFeedInfo->FeedTempDirectory != FEED_STRINGS_NOCHANGE &&
  644. *pFeedInfo->FeedTempDirectory != L'\0' )
  645. *pdwMask |= FEED_PARM_TEMPDIR;
  646. //
  647. // auth type
  648. //
  649. if ( pFeedInfo->AuthenticationSecurityType == AUTH_PROTOCOL_NONE ||
  650. pFeedInfo->AuthenticationSecurityType == AUTH_PROTOCOL_CLEAR ) {
  651. *pdwMask |= FEED_PARM_AUTHTYPE;
  652. if ( pFeedInfo->AuthenticationSecurityType == AUTH_PROTOCOL_NONE ) {
  653. *pdwMask &= ~FEED_PARM_ACCOUNTNAME;
  654. *pdwMask &= ~FEED_PARM_PASSWORD;
  655. }
  656. }
  657. //
  658. // start time
  659. //
  660. if ( pFeedInfo->StartTime.dwHighDateTime != FEED_STARTTIME_NOCHANGE )
  661. *pdwMask |= FEED_PARM_STARTTIME;
  662. //
  663. // pull request time
  664. //
  665. if ( pFeedInfo->PullRequestTime.dwHighDateTime != FEED_PULLTIME_NOCHANGE )
  666. *pdwMask |= FEED_PARM_PULLREQUESTTIME;
  667. //
  668. // feed interval
  669. //
  670. if ( pFeedInfo->FeedInterval != FEED_FEEDINTERVAL_NOCHANGE )
  671. *pdwMask |= FEED_PARM_FEEDINTERVAL;
  672. //
  673. // auto create
  674. //
  675. if ( pFeedInfo->AutoCreate != FEED_AUTOCREATE_NOCHANGE )
  676. *pdwMask |= FEED_PARM_AUTOCREATE;
  677. if ( newsPresent ) {
  678. *pdwMask |= FEED_PARM_AUTOCREATE;
  679. pFeedInfo->AutoCreate = TRUE;
  680. }
  681. //
  682. // allow control
  683. //
  684. *pdwMask |= FEED_PARM_ALLOW_CONTROL;
  685. //
  686. // Max connect
  687. //
  688. if ( pFeedInfo->MaxConnectAttempts != FEED_MAXCONNECTS_NOCHANGE )
  689. *pdwMask |= FEED_PARM_MAXCONNECT;
  690. //
  691. // outgoing port
  692. //
  693. *pdwMask |= FEED_PARM_OUTGOING_PORT;
  694. //
  695. // feedpair id
  696. //
  697. *pdwMask |= FEED_PARM_FEEDPAIR_ID;
  698. //
  699. // feed enable
  700. //
  701. *pdwMask |= FEED_PARM_ENABLED;
  702. TraceFunctLeave();
  703. }
  704. HRESULT AddFeedToMB( LPNNTP_FEED_INFO pFeedInfo, CMetabaseKey* pMK, PDWORD pdwErrMask, DWORD dwInstance, PDWORD pdwFeedId )
  705. {
  706. TraceFunctEnter( "AddFeed" );
  707. _ASSERT( pFeedInfo );
  708. HRESULT hr;
  709. DWORD dwSetMask = 0;
  710. //
  711. // Get set mask
  712. //
  713. //SetPresenceMask( pFeedInfo, &dwSetMask, TRUE );
  714. //
  715. // Alloc and create the feed key in the metabase
  716. //
  717. hr = AllocNextAvailableFeedId( pMK, pdwFeedId, dwInstance );
  718. if ( FAILED( hr ) ) {
  719. TraceFunctLeave();
  720. return hr;
  721. }
  722. pFeedInfo->FeedId = *pdwFeedId;
  723. //
  724. // Open that key for write
  725. //
  726. hr = OpenKey( *pdwFeedId, pMK, METADATA_PERMISSION_WRITE, dwInstance );
  727. if ( FAILED( hr ) )
  728. goto fail_exit;
  729. //
  730. // Write the handshake start updating flag
  731. //
  732. hr = SetDwordProp( MD_FEED_HANDSHAKE,
  733. FEED_UPDATING,
  734. pMK );
  735. if ( FAILED( hr ) )
  736. goto fail_exit;
  737. //
  738. // Set feed info
  739. //
  740. hr = UpdateFeedMetabaseValues( pMK,
  741. pFeedInfo,
  742. FEED_ALL_PARAMS,
  743. pdwErrMask );
  744. if ( FAILED( hr ) )
  745. goto fail_exit;
  746. //
  747. // Set handshake
  748. //
  749. hr = SetDwordProp( MD_FEED_HANDSHAKE,
  750. FEED_UPDATE_COMPLETE,
  751. pMK );
  752. if ( FAILED( hr ) )
  753. goto fail_exit;
  754. //
  755. // done.
  756. //
  757. CloseKey( pMK );
  758. SaveKey( pMK );
  759. TraceFunctLeave();
  760. return S_OK;
  761. fail_exit:
  762. CloseKey( pMK );
  763. DeleteKey( 1, pMK, dwInstance );
  764. TraceFunctLeave();
  765. return hr;
  766. }
  767. HRESULT
  768. SetFeedToMB( LPNNTP_FEED_INFO pFeedInfo, CMetabaseKey* pMK, PDWORD pdwErrMask, DWORD dwInstance )
  769. {
  770. TraceFunctEnter( "AddFeed" );
  771. _ASSERT( pFeedInfo );
  772. HRESULT hr;
  773. DWORD dwSetMask = 0;
  774. //
  775. // Get set mask
  776. //
  777. SetPresenceMask( pFeedInfo, &dwSetMask, FALSE );
  778. //
  779. // Open that key for write
  780. //
  781. hr = OpenKey( pFeedInfo->FeedId, pMK, METADATA_PERMISSION_WRITE, dwInstance );
  782. if ( FAILED( hr ) )
  783. goto fail_exit;
  784. //
  785. // Write the handshake start updating flag
  786. //
  787. hr = SetDwordProp( MD_FEED_HANDSHAKE,
  788. FEED_UPDATING,
  789. pMK );
  790. if ( FAILED( hr ) )
  791. goto fail_exit;
  792. //
  793. // Set feed info
  794. //
  795. hr = UpdateFeedMetabaseValues( pMK,
  796. pFeedInfo,
  797. dwSetMask,
  798. pdwErrMask );
  799. if ( FAILED( hr ) )
  800. goto fail_exit;
  801. //
  802. // Set handshake
  803. //
  804. hr = SetDwordProp( MD_FEED_HANDSHAKE,
  805. FEED_UPDATE_COMPLETE,
  806. pMK );
  807. if ( FAILED( hr ) )
  808. goto fail_exit;
  809. //
  810. // done.
  811. //
  812. CloseKey( pMK );
  813. SaveKey( pMK );
  814. TraceFunctLeave();
  815. return S_OK;
  816. fail_exit:
  817. CloseKey( pMK );
  818. TraceFunctLeave();
  819. return hr;
  820. }
  821. HRESULT
  822. DeleteFeed( DWORD dwFeedId, CMetabaseKey* pMK, DWORD dwInstance )
  823. {
  824. return DeleteKey( dwFeedId, pMK, dwInstance);
  825. }