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.

1167 lines
29 KiB

  1. // VirtualRoot.cpp : Implementation of CNntpVirtualRoot & CNntpVirtualRoots.
  2. #include "stdafx.h"
  3. #include "nntpcmn.h"
  4. #include "cmultisz.h"
  5. #include "vroots.h"
  6. #include "oleutil.h"
  7. #include "metautil.h"
  8. #include "metakey.h"
  9. #define THIS_FILE_HELP_CONTEXT 0
  10. #define THIS_FILE_PROG_ID _T("Nntpadm.VirtualServer.1")
  11. #define THIS_FILE_IID IID_INntpVirtualServer
  12. #define DEFAULT_ACCESS_PERM ( 0 )
  13. CVRoot::CVRoot () :
  14. m_dwWin32Error ( 0 ),
  15. m_bvAccess ( 0 ),
  16. m_bvSslAccess ( 0 ),
  17. m_fLogAccess ( TRUE ),
  18. m_fIndexContent ( TRUE ),
  19. m_dwUseAccount ( 0 ),
  20. m_fDoExpire ( FALSE ),
  21. m_fOwnModerator ( FALSE )
  22. {
  23. }
  24. HRESULT CVRoot::SetProperties (
  25. BSTR strNewsgroupSubtree,
  26. BSTR strDirectory,
  27. DWORD dwWin32Error,
  28. DWORD bvAccess,
  29. DWORD bvSslAccess,
  30. BOOL fLogAccess,
  31. BOOL fIndexContent,
  32. BSTR strUNCUsername,
  33. BSTR strUNCPassword,
  34. BSTR strDriverProgId,
  35. BSTR strGroupPropFile,
  36. DWORD dwUseAccount,
  37. BOOL fDoExpire,
  38. BOOL fOwnModerator,
  39. BSTR strMdbGuid
  40. )
  41. {
  42. _ASSERT ( IS_VALID_STRING ( strNewsgroupSubtree ) );
  43. _ASSERT ( IS_VALID_STRING ( strDirectory ) );
  44. _ASSERT ( IS_VALID_STRING ( strUNCUsername ) );
  45. _ASSERT ( IS_VALID_STRING ( strUNCPassword ) );
  46. _ASSERT ( IS_VALID_STRING ( strDriverProgId ) );
  47. _ASSERT ( IS_VALID_STRING ( strGroupPropFile ) );
  48. _ASSERT ( IS_VALID_STRING ( strMdbGuid ) );
  49. m_strNewsgroupSubtree = strNewsgroupSubtree;
  50. m_strDirectory = strDirectory;
  51. m_dwWin32Error = dwWin32Error;
  52. m_bvAccess = bvAccess;
  53. m_bvSslAccess = bvSslAccess;
  54. m_fLogAccess = fLogAccess;
  55. m_fIndexContent = fIndexContent;
  56. m_strUNCUsername = strUNCUsername;
  57. m_strUNCPassword = strUNCPassword;
  58. m_strDriverProgId = strDriverProgId;
  59. m_strGroupPropFile = strGroupPropFile;
  60. m_dwUseAccount = dwUseAccount;
  61. m_fDoExpire = fDoExpire;
  62. m_fOwnModerator = fOwnModerator,
  63. m_strMdbGuid = strMdbGuid;
  64. if ( !m_strNewsgroupSubtree || !m_strDirectory || !m_strUNCUsername || !m_strUNCPassword ) {
  65. return E_OUTOFMEMORY;
  66. }
  67. return NOERROR;
  68. }
  69. HRESULT CVRoot::SetProperties ( INntpVirtualRoot * pVirtualRoot )
  70. {
  71. HRESULT hr;
  72. BOOL fAllowPosting;
  73. BOOL fRestrictVisibility;
  74. BOOL fRequireSsl;
  75. BOOL fRequire128BitSsl;
  76. m_strDirectory.Empty ();
  77. m_strUNCUsername.Empty ();
  78. m_strUNCPassword.Empty ();
  79. m_strDriverProgId.Empty();
  80. m_strGroupPropFile.Empty();
  81. m_strMdbGuid.Empty();
  82. hr = pVirtualRoot->get_NewsgroupSubtree ( &m_strNewsgroupSubtree );
  83. BAIL_ON_FAILURE(hr);
  84. hr = pVirtualRoot->get_Directory ( &m_strDirectory );
  85. BAIL_ON_FAILURE(hr);
  86. hr = pVirtualRoot->get_Win32Error ( (long *) &m_dwWin32Error );
  87. BAIL_ON_FAILURE(hr);
  88. hr = pVirtualRoot->get_UNCUsername ( &m_strUNCUsername );
  89. BAIL_ON_FAILURE(hr);
  90. hr = pVirtualRoot->get_UNCPassword ( &m_strUNCPassword );
  91. BAIL_ON_FAILURE(hr);
  92. hr = pVirtualRoot->get_DriverProgId ( &m_strDriverProgId );
  93. BAIL_ON_FAILURE( hr );
  94. hr = pVirtualRoot->get_GroupPropFile ( &m_strGroupPropFile );
  95. BAIL_ON_FAILURE( hr );
  96. hr = pVirtualRoot->get_MdbGuid ( &m_strMdbGuid );
  97. BAIL_ON_FAILURE( hr );
  98. hr = pVirtualRoot->get_UseAccount( &m_dwUseAccount );
  99. BAIL_ON_FAILURE( hr );
  100. hr = pVirtualRoot->get_OwnExpire( &m_fDoExpire );
  101. BAIL_ON_FAILURE( hr );
  102. hr = pVirtualRoot->get_OwnModerator( &m_fOwnModerator );
  103. BAIL_ON_FAILURE( hr );
  104. hr = pVirtualRoot->get_LogAccess ( &m_fLogAccess );
  105. _ASSERT ( SUCCEEDED(hr) );
  106. hr = pVirtualRoot->get_IndexContent ( &m_fIndexContent );
  107. _ASSERT ( SUCCEEDED(hr) );
  108. hr = pVirtualRoot->get_AllowPosting ( &fAllowPosting );
  109. _ASSERT ( SUCCEEDED(hr) );
  110. hr = pVirtualRoot->get_RestrictGroupVisibility ( &fRestrictVisibility );
  111. _ASSERT ( SUCCEEDED(hr) );
  112. hr = pVirtualRoot->get_RequireSsl ( &fRequireSsl );
  113. _ASSERT ( SUCCEEDED(hr) );
  114. hr = pVirtualRoot->get_Require128BitSsl ( &fRequire128BitSsl );
  115. _ASSERT ( SUCCEEDED(hr) );
  116. SetBitFlag ( &m_bvAccess, MD_ACCESS_ALLOW_POSTING, fAllowPosting );
  117. SetBitFlag ( &m_bvAccess, MD_ACCESS_RESTRICT_VISIBILITY, fRestrictVisibility );
  118. SetBitFlag ( &m_bvSslAccess, MD_ACCESS_SSL, fRequireSsl );
  119. SetBitFlag ( &m_bvSslAccess, MD_ACCESS_SSL128, fRequire128BitSsl );
  120. Exit:
  121. return hr;
  122. }
  123. HRESULT CVRoot::GetFromMetabase ( CMetabaseKey * pMB,
  124. LPCWSTR wszName,
  125. DWORD dwInstanceId,
  126. LPWSTR wszServerName )
  127. {
  128. HRESULT hr = NOERROR;
  129. DWORD dwDontLog = TRUE;
  130. m_strDirectory.Empty();
  131. m_strUNCUsername.Empty();
  132. m_strUNCPassword.Empty();
  133. StdGetMetabaseProp ( pMB, MD_ACCESS_PERM, 0, &m_bvAccess, wszName );
  134. StdGetMetabaseProp ( pMB, MD_SSL_ACCESS_PERM, 0, &m_bvSslAccess, wszName );
  135. StdGetMetabaseProp ( pMB, MD_DONT_LOG, FALSE, &dwDontLog, wszName );
  136. StdGetMetabaseProp ( pMB, MD_IS_CONTENT_INDEXED, FALSE, &m_fIndexContent, wszName, IIS_MD_UT_FILE);
  137. StdGetMetabaseProp ( pMB, MD_VR_PATH, _T(""), &m_strDirectory, wszName );
  138. //StdGetMetabaseProp ( pMB, MD_WIN32_ERROR, 0, &m_dwWin32Error, wszName, IIS_MD_UT_FILE, METADATA_NO_ATTRIBUTES );
  139. StdGetMetabaseProp ( pMB, MD_VR_USERNAME, _T(""), &m_strUNCUsername, wszName );
  140. StdGetMetabaseProp ( pMB, MD_VR_PASSWORD, _T(""), &m_strUNCPassword, wszName, IIS_MD_UT_SERVER, METADATA_SECURE );
  141. StdGetMetabaseProp ( pMB, MD_VR_USE_ACCOUNT, 0, &m_dwUseAccount, wszName );
  142. StdGetMetabaseProp ( pMB, MD_VR_DO_EXPIRE, FALSE, &m_fDoExpire, wszName );
  143. StdGetMetabaseProp ( pMB, MD_VR_OWN_MODERATOR, FALSE, &m_fOwnModerator, wszName );
  144. StdGetMetabaseProp ( pMB, MD_VR_DRIVER_PROGID, _T("NNTP.FSPrepare"), &m_strDriverProgId, wszName );
  145. StdGetMetabaseProp ( pMB, MD_FS_PROPERTY_PATH, m_strDirectory, &m_strGroupPropFile, wszName );
  146. StdGetMetabaseProp ( pMB, MD_EX_MDB_GUID, _T(""), &m_strMdbGuid, wszName );
  147. //
  148. // Get the win32 error code from RPC
  149. //
  150. DWORD dw = NntpGetVRootWin32Error( (LPWSTR)wszServerName, dwInstanceId, (LPWSTR)wszName, (LPDWORD)&m_dwWin32Error );
  151. switch (dw) {
  152. case ERROR_SERVICE_NOT_ACTIVE:
  153. m_dwWin32Error = dw;
  154. break;
  155. case NOERROR:
  156. break;
  157. default:
  158. hr = HRESULT_FROM_WIN32( dw );
  159. goto Exit;
  160. }
  161. m_strNewsgroupSubtree = wszName;
  162. m_fLogAccess = !dwDontLog;
  163. if ( !m_strNewsgroupSubtree || !m_strDirectory || !m_strUNCUsername || !m_strUNCPassword ) {
  164. hr = E_OUTOFMEMORY;
  165. goto Exit;
  166. }
  167. Exit:
  168. return hr;
  169. }
  170. HRESULT CVRoot::SendToMetabase ( CMetabaseKey * pMB, LPCWSTR wszName )
  171. {
  172. HRESULT hr = NOERROR;
  173. hr = pMB->SetString ( wszName, MD_KEY_TYPE, _T("IIsNntpVirtualDir"), METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER );
  174. BAIL_ON_FAILURE(hr);
  175. hr = pMB->SetString ( wszName, MD_VR_PATH, m_strDirectory, METADATA_INHERIT, IIS_MD_UT_FILE );
  176. BAIL_ON_FAILURE(hr);
  177. StdPutMetabaseProp ( pMB, MD_ACCESS_PERM, m_bvAccess, wszName, IIS_MD_UT_FILE );
  178. StdPutMetabaseProp ( pMB, MD_SSL_ACCESS_PERM, m_bvSslAccess, wszName, IIS_MD_UT_FILE );
  179. StdPutMetabaseProp ( pMB, MD_DONT_LOG, !m_fLogAccess, wszName, IIS_MD_UT_FILE );
  180. StdPutMetabaseProp ( pMB, MD_IS_CONTENT_INDEXED, m_fIndexContent, wszName, IIS_MD_UT_FILE );
  181. StdPutMetabaseProp ( pMB, MD_WIN32_ERROR, m_dwWin32Error, wszName, IIS_MD_UT_SERVER, METADATA_VOLATILE );
  182. StdPutMetabaseProp ( pMB, MD_VR_USERNAME, m_strUNCUsername, wszName, IIS_MD_UT_FILE );
  183. StdPutMetabaseProp ( pMB, MD_VR_PASSWORD, m_strUNCPassword, wszName, IIS_MD_UT_FILE, METADATA_SECURE | METADATA_INHERIT );
  184. StdPutMetabaseProp ( pMB, MD_VR_USE_ACCOUNT, m_dwUseAccount, wszName, IIS_MD_UT_SERVER );
  185. StdPutMetabaseProp ( pMB, MD_VR_DO_EXPIRE, m_fDoExpire, wszName, IIS_MD_UT_SERVER );
  186. StdPutMetabaseProp ( pMB, MD_VR_OWN_MODERATOR, m_fOwnModerator, wszName, IIS_MD_UT_SERVER );
  187. StdPutMetabaseProp ( pMB, MD_VR_DRIVER_PROGID, m_strDriverProgId, wszName, IIS_MD_UT_SERVER );
  188. StdPutMetabaseProp ( pMB, MD_FS_PROPERTY_PATH, m_strGroupPropFile, wszName, IIS_MD_UT_SERVER );
  189. StdPutMetabaseProp ( pMB, MD_EX_MDB_GUID, m_strMdbGuid, wszName, IIS_MD_UT_SERVER );
  190. Exit:
  191. return hr;
  192. }
  193. /////////////////////////////////////////////////////////////////////////////
  194. //
  195. STDMETHODIMP CNntpVirtualRoot::InterfaceSupportsErrorInfo(REFIID riid)
  196. {
  197. static const IID* arr[] =
  198. {
  199. &IID_INntpVirtualRoot,
  200. };
  201. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  202. {
  203. if (InlineIsEqualGUID(*arr[i],riid))
  204. return S_OK;
  205. }
  206. return S_FALSE;
  207. }
  208. CNntpVirtualRoot::CNntpVirtualRoot ()
  209. // CComBSTR's are initialized to NULL by default.
  210. {
  211. }
  212. CNntpVirtualRoot::~CNntpVirtualRoot ()
  213. {
  214. // All CComBSTR's are freed automatically.
  215. }
  216. //////////////////////////////////////////////////////////////////////
  217. // Properties:
  218. //////////////////////////////////////////////////////////////////////
  219. STDMETHODIMP CNntpVirtualRoot::get_NewsgroupSubtree ( BSTR * pstrNewsgroupSubtree )
  220. {
  221. return StdPropertyGet ( m_vroot.m_strNewsgroupSubtree, pstrNewsgroupSubtree );
  222. }
  223. STDMETHODIMP CNntpVirtualRoot::put_NewsgroupSubtree ( BSTR strNewsgroupSubtree )
  224. {
  225. if ( wcslen( strNewsgroupSubtree ) > METADATA_MAX_NAME_LEN - 20 ) return CO_E_PATHTOOLONG;
  226. return StdPropertyPut ( &m_vroot.m_strNewsgroupSubtree, strNewsgroupSubtree );
  227. }
  228. STDMETHODIMP CNntpVirtualRoot::get_Directory ( BSTR * pstrDirectory )
  229. {
  230. return StdPropertyGet ( m_vroot.m_strDirectory, pstrDirectory );
  231. }
  232. STDMETHODIMP CNntpVirtualRoot::put_Directory ( BSTR strDirectory )
  233. {
  234. return StdPropertyPut ( &m_vroot.m_strDirectory, strDirectory );
  235. }
  236. STDMETHODIMP CNntpVirtualRoot::get_Win32Error ( long * plWin32Error )
  237. {
  238. return StdPropertyGet ( m_vroot.m_dwWin32Error, plWin32Error );
  239. }
  240. STDMETHODIMP CNntpVirtualRoot::get_LogAccess ( BOOL * pfLogAccess )
  241. {
  242. return StdPropertyGet ( m_vroot.m_fLogAccess, pfLogAccess );
  243. }
  244. STDMETHODIMP CNntpVirtualRoot::put_LogAccess ( BOOL fLogAccess )
  245. {
  246. return StdPropertyPut ( &m_vroot.m_fLogAccess, fLogAccess );
  247. }
  248. STDMETHODIMP CNntpVirtualRoot::get_IndexContent ( BOOL * pfIndexContent )
  249. {
  250. return StdPropertyGet ( m_vroot.m_fIndexContent, pfIndexContent );
  251. }
  252. STDMETHODIMP CNntpVirtualRoot::put_IndexContent ( BOOL fIndexContent )
  253. {
  254. return StdPropertyPut ( &m_vroot.m_fIndexContent, fIndexContent );
  255. }
  256. STDMETHODIMP CNntpVirtualRoot::get_AllowPosting ( BOOL * pfAllowPosting )
  257. {
  258. return StdPropertyGetBit ( m_vroot.m_bvAccess, MD_ACCESS_ALLOW_POSTING, pfAllowPosting );
  259. }
  260. STDMETHODIMP CNntpVirtualRoot::put_AllowPosting ( BOOL fAllowPosting )
  261. {
  262. return StdPropertyPutBit ( &m_vroot.m_bvAccess, MD_ACCESS_ALLOW_POSTING, fAllowPosting );
  263. }
  264. STDMETHODIMP CNntpVirtualRoot::get_RestrictGroupVisibility ( BOOL * pfRestrictGroupVisibility )
  265. {
  266. return StdPropertyGetBit ( m_vroot.m_bvAccess, MD_ACCESS_RESTRICT_VISIBILITY, pfRestrictGroupVisibility );
  267. }
  268. STDMETHODIMP CNntpVirtualRoot::put_RestrictGroupVisibility ( BOOL fRestrictGroupVisibility )
  269. {
  270. return StdPropertyPutBit ( &m_vroot.m_bvAccess, MD_ACCESS_RESTRICT_VISIBILITY, fRestrictGroupVisibility );
  271. }
  272. STDMETHODIMP SSLNegotiateCert ( BOOL * pfSSLNegotiateCert );
  273. STDMETHODIMP SSLNegotiateCert ( BOOL fSSLNegotiateCert );
  274. STDMETHODIMP SSLRequireCert ( BOOL * pfSSLRequireCert );
  275. STDMETHODIMP SSLRequireCert ( BOOL fSSLRequireCert );
  276. STDMETHODIMP SSLMapCert ( BOOL * pfSSLMapCert );
  277. STDMETHODIMP SSLMapCert ( BOOL fSSLMapCert );
  278. STDMETHODIMP CNntpVirtualRoot::get_RequireSsl ( BOOL * pfRequireSsl )
  279. {
  280. return StdPropertyGetBit ( m_vroot.m_bvSslAccess, MD_ACCESS_SSL, pfRequireSsl );
  281. }
  282. STDMETHODIMP CNntpVirtualRoot::put_RequireSsl ( BOOL fRequireSsl )
  283. {
  284. return StdPropertyPutBit ( &m_vroot.m_bvSslAccess, MD_ACCESS_SSL, fRequireSsl );
  285. }
  286. STDMETHODIMP CNntpVirtualRoot::get_Require128BitSsl ( BOOL * pfRequire128BitSsl )
  287. {
  288. return StdPropertyGetBit ( m_vroot.m_bvSslAccess, MD_ACCESS_SSL128, pfRequire128BitSsl );
  289. }
  290. STDMETHODIMP CNntpVirtualRoot::put_Require128BitSsl ( BOOL fRequire128BitSsl )
  291. {
  292. return StdPropertyPutBit ( &m_vroot.m_bvSslAccess, MD_ACCESS_SSL128, fRequire128BitSsl );
  293. }
  294. STDMETHODIMP CNntpVirtualRoot::get_UNCUsername ( BSTR * pstrUNCUsername )
  295. {
  296. return StdPropertyGet ( m_vroot.m_strUNCUsername, pstrUNCUsername );
  297. }
  298. STDMETHODIMP CNntpVirtualRoot::put_UNCUsername ( BSTR strUNCUsername )
  299. {
  300. return StdPropertyPut ( &m_vroot.m_strUNCUsername, strUNCUsername );
  301. }
  302. STDMETHODIMP CNntpVirtualRoot::get_UNCPassword ( BSTR * pstrUNCPassword )
  303. {
  304. return StdPropertyGet ( m_vroot.m_strUNCPassword, pstrUNCPassword );
  305. }
  306. STDMETHODIMP CNntpVirtualRoot::put_UNCPassword ( BSTR strUNCPassword )
  307. {
  308. return StdPropertyPut ( &m_vroot.m_strUNCPassword, strUNCPassword );
  309. }
  310. STDMETHODIMP CNntpVirtualRoot::get_DriverProgId( BSTR *pstrDriverProgId )
  311. {
  312. return StdPropertyGet( m_vroot.m_strDriverProgId, pstrDriverProgId );
  313. }
  314. STDMETHODIMP CNntpVirtualRoot::put_DriverProgId( BSTR strDriverProgId )
  315. {
  316. return StdPropertyPut( &m_vroot.m_strDriverProgId, strDriverProgId );
  317. }
  318. STDMETHODIMP CNntpVirtualRoot::get_GroupPropFile( BSTR *pstrGroupPropFile )
  319. {
  320. return StdPropertyGet( m_vroot.m_strGroupPropFile, pstrGroupPropFile );
  321. }
  322. STDMETHODIMP CNntpVirtualRoot::put_GroupPropFile( BSTR strGroupPropFile )
  323. {
  324. return StdPropertyPut( &m_vroot.m_strGroupPropFile, strGroupPropFile );
  325. }
  326. STDMETHODIMP CNntpVirtualRoot::get_MdbGuid( BSTR *pstrMdbGuid )
  327. {
  328. return StdPropertyGet( m_vroot.m_strMdbGuid, pstrMdbGuid );
  329. }
  330. STDMETHODIMP CNntpVirtualRoot::put_MdbGuid( BSTR strMdbGuid )
  331. {
  332. return StdPropertyPut( &m_vroot.m_strMdbGuid, strMdbGuid );
  333. }
  334. STDMETHODIMP CNntpVirtualRoot::get_UseAccount( DWORD *pdwUseAccount )
  335. {
  336. return StdPropertyGet( m_vroot.m_dwUseAccount, pdwUseAccount );
  337. }
  338. STDMETHODIMP CNntpVirtualRoot::put_UseAccount( DWORD dwUseAccount )
  339. {
  340. return StdPropertyPut( &m_vroot.m_dwUseAccount, dwUseAccount );
  341. }
  342. STDMETHODIMP CNntpVirtualRoot::get_OwnExpire( BOOL *pfOwnExpire )
  343. {
  344. return StdPropertyGet( m_vroot.m_fDoExpire, pfOwnExpire );
  345. }
  346. STDMETHODIMP CNntpVirtualRoot::put_OwnExpire( BOOL fOwnExpire )
  347. {
  348. return StdPropertyPut( &m_vroot.m_fDoExpire, fOwnExpire );
  349. }
  350. STDMETHODIMP CNntpVirtualRoot::get_OwnModerator( BOOL *pfOwnModerator )
  351. {
  352. return StdPropertyGet( m_vroot.m_fOwnModerator, pfOwnModerator );
  353. }
  354. STDMETHODIMP CNntpVirtualRoot::put_OwnModerator( BOOL fOwnModerator )
  355. {
  356. return StdPropertyPut( &m_vroot.m_fOwnModerator, fOwnModerator );
  357. }
  358. /////////////////////////////////////////////////////////////////////////////
  359. //
  360. STDMETHODIMP CNntpVirtualRoots::InterfaceSupportsErrorInfo(REFIID riid)
  361. {
  362. static const IID* arr[] =
  363. {
  364. &IID_INntpVirtualRoots,
  365. };
  366. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  367. {
  368. if (InlineIsEqualGUID(*arr[i],riid))
  369. return S_OK;
  370. }
  371. return S_FALSE;
  372. }
  373. CNntpVirtualRoots::CNntpVirtualRoots () :
  374. m_dwCount ( 0 ),
  375. m_rgVRoots ( NULL ),
  376. m_dwServiceInstance ( 0 )
  377. // CComBSTR's are initialized to NULL by default.
  378. {
  379. }
  380. CNntpVirtualRoots::~CNntpVirtualRoots ()
  381. {
  382. // All CComBSTR's are freed automatically.
  383. delete [] m_rgVRoots;
  384. }
  385. HRESULT CNntpVirtualRoots::Init ( BSTR strServer, DWORD dwServiceInstance )
  386. {
  387. m_strServer = strServer;
  388. m_dwServiceInstance = dwServiceInstance;
  389. if ( !m_strServer ) {
  390. return E_OUTOFMEMORY;
  391. }
  392. return NOERROR;
  393. }
  394. //////////////////////////////////////////////////////////////////////
  395. // Properties:
  396. //////////////////////////////////////////////////////////////////////
  397. // Which service to configure:
  398. STDMETHODIMP CNntpVirtualRoots::get_Server ( BSTR * pstrServer )
  399. {
  400. return StdPropertyGet ( m_strServer, pstrServer );
  401. }
  402. STDMETHODIMP CNntpVirtualRoots::put_Server ( BSTR strServer )
  403. {
  404. _ASSERT ( strServer );
  405. _ASSERT ( IS_VALID_STRING ( strServer ) );
  406. if ( strServer == NULL ) {
  407. return E_POINTER;
  408. }
  409. if ( lstrcmp ( strServer, _T("") ) == 0 ) {
  410. m_strServer.Empty();
  411. return NOERROR;
  412. }
  413. else {
  414. return StdPropertyPutServerName ( &m_strServer, strServer );
  415. }
  416. }
  417. STDMETHODIMP CNntpVirtualRoots::get_ServiceInstance ( long * plServiceInstance )
  418. {
  419. return StdPropertyGet ( m_dwServiceInstance, plServiceInstance );
  420. }
  421. STDMETHODIMP CNntpVirtualRoots::put_ServiceInstance ( long lServiceInstance )
  422. {
  423. return StdPropertyPut ( &m_dwServiceInstance, lServiceInstance );
  424. }
  425. STDMETHODIMP CNntpVirtualRoots::get_Count ( long * pdwCount )
  426. {
  427. return StdPropertyGet ( m_dwCount, pdwCount );
  428. }
  429. //////////////////////////////////////////////////////////////////////
  430. // Methods:
  431. //////////////////////////////////////////////////////////////////////
  432. STDMETHODIMP CNntpVirtualRoots::Enumerate ( )
  433. {
  434. TraceFunctEnter ( "CNntpVirtualRoots::Enumerate" );
  435. HRESULT hr = NOERROR;
  436. CComPtr<IMSAdminBase> pMetabase;
  437. // Clear the old enumeration:
  438. delete [] m_rgVRoots;
  439. m_rgVRoots = NULL;
  440. m_dwCount = 0;
  441. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  442. if ( FAILED(hr) ) {
  443. goto Exit;
  444. }
  445. hr = GetVRootsFromMetabase ( pMetabase );
  446. if ( FAILED(hr) ) {
  447. goto Exit;
  448. }
  449. Exit:
  450. TRACE_HRESULT(hr);
  451. TraceFunctLeave ();
  452. return hr;
  453. }
  454. STDMETHODIMP CNntpVirtualRoots::Item (
  455. long index,
  456. INntpVirtualRoot ** ppVirtualRoot
  457. )
  458. {
  459. TraceFunctEnter ( "CNntpVirtualRoots::Item" );
  460. _ASSERT ( IS_VALID_OUT_PARAM ( ppVirtualRoot ) );
  461. *ppVirtualRoot = NULL;
  462. HRESULT hr = NOERROR;
  463. CComObject<CNntpVirtualRoot> * pVirtualRoot = NULL;
  464. if ( index < 0 || index >= m_dwCount ) {
  465. hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  466. goto Exit;
  467. }
  468. hr = CComObject<CNntpVirtualRoot>::CreateInstance ( &pVirtualRoot );
  469. if ( FAILED(hr) ) {
  470. goto Exit;
  471. }
  472. _ASSERT ( pVirtualRoot );
  473. hr = pVirtualRoot->SetProperties ( m_rgVRoots[index] );
  474. if ( FAILED(hr) ) {
  475. goto Exit;
  476. }
  477. hr = pVirtualRoot->QueryInterface ( IID_INntpVirtualRoot, (void **) ppVirtualRoot );
  478. _ASSERT ( SUCCEEDED(hr) );
  479. Exit:
  480. if ( FAILED(hr) ) {
  481. delete pVirtualRoot;
  482. }
  483. TRACE_HRESULT(hr);
  484. TraceFunctLeave ();
  485. return hr;
  486. }
  487. STDMETHODIMP CNntpVirtualRoots::Add (
  488. INntpVirtualRoot * pVirtualRoot
  489. )
  490. {
  491. TraceFunctEnter ( "CNntpVirtualRoots::Add" );
  492. _ASSERT ( IS_VALID_IN_PARAM ( pVirtualRoot ) );
  493. HRESULT hr = NOERROR;
  494. CVRoot * rgNewVirtualRoots = NULL;
  495. long i;
  496. CComPtr<IMSAdminBase> pMetabase;
  497. CVRoot newVroot;
  498. WCHAR wszName [ 2*METADATA_MAX_NAME_LEN ];
  499. WCHAR wszVRootPath [ 2*METADATA_MAX_NAME_LEN ];
  500. // Validate the new Virtual Root:
  501. hr = newVroot.SetProperties ( pVirtualRoot );
  502. if ( FAILED(hr) ) {
  503. return hr;
  504. }
  505. if ( !newVroot.m_strNewsgroupSubtree ||
  506. !newVroot.m_strNewsgroupSubtree[0] ) {
  507. return RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
  508. }
  509. // Add the new virtual root to the metabase:
  510. GetVRootName ( newVroot.m_strNewsgroupSubtree, wszName );
  511. //
  512. // The sub tree itself should not exceed length METADATA_MAX_NAME_LEN
  513. //
  514. _ASSERT( wcslen( wszName ) <= METADATA_MAX_NAME_LEN );
  515. if ( wcslen( wszName ) > METADATA_MAX_NAME_LEN ) {
  516. return CO_E_PATHTOOLONG;
  517. }
  518. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  519. if ( FAILED(hr) ) {
  520. return hr;
  521. }
  522. CMetabaseKey mb ( pMetabase );
  523. GetMDVRootPath ( wszVRootPath );
  524. //
  525. // I trust wszVRootPath, it's shorter than METADATA_MAX_NAME_LEN
  526. //
  527. //
  528. // Test to see if this item exists already:
  529. //
  530. WCHAR wszTempPath [ 2 * METADATA_MAX_NAME_LEN + 1];
  531. wsprintf ( wszTempPath, _T("%s%s"), wszVRootPath, wszName );
  532. if ( wcslen( wszTempPath ) > METADATA_MAX_NAME_LEN ) {
  533. //
  534. // I can't handle it either
  535. //
  536. return CO_E_PATHTOOLONG;
  537. }
  538. hr = mb.Open ( wszTempPath );
  539. if ( SUCCEEDED(hr) ) {
  540. DWORD cbVrootDir;
  541. if ( SUCCEEDED ( mb.GetDataSize (
  542. _T(""),
  543. MD_VR_PATH,
  544. STRING_METADATA,
  545. &cbVrootDir,
  546. METADATA_NO_ATTRIBUTES )
  547. ) ) {
  548. mb.Close();
  549. hr = NntpCreateException ( IDS_NNTPEXCEPTION_VROOT_ALREADY_EXISTS );
  550. goto Exit;
  551. }
  552. }
  553. hr = mb.Open ( wszVRootPath, METADATA_PERMISSION_WRITE );
  554. BAIL_ON_FAILURE(hr);
  555. /*
  556. hr = mb.CreateChild ( wszName );
  557. BAIL_ON_FAILURE(hr);
  558. */
  559. hr = newVroot.SendToMetabase ( &mb, wszName );
  560. BAIL_ON_FAILURE(hr);
  561. hr = mb.Save ();
  562. BAIL_ON_FAILURE(hr);
  563. // Allocate the new VirtualRoot array:
  564. rgNewVirtualRoots = new CVRoot [ m_dwCount + 1 ];
  565. if ( !rgNewVirtualRoots ) {
  566. hr = E_OUTOFMEMORY;
  567. goto Exit;
  568. }
  569. // Copy the old VirtualRoots to the new array:
  570. for ( i = 0; i < m_dwCount; i++ ) {
  571. hr = rgNewVirtualRoots[i].SetProperties ( m_rgVRoots[i] );
  572. if ( FAILED (hr) ) {
  573. goto Exit;
  574. }
  575. }
  576. // Add the new VirtualRoot to the end of the array:
  577. hr = rgNewVirtualRoots[m_dwCount].SetProperties ( pVirtualRoot );
  578. if ( FAILED(hr) ) {
  579. goto Exit;
  580. }
  581. _ASSERT ( SUCCEEDED(hr) );
  582. delete [] m_rgVRoots;
  583. m_rgVRoots = rgNewVirtualRoots;
  584. m_dwCount++;
  585. Exit:
  586. TraceFunctLeave ();
  587. return hr;
  588. }
  589. STDMETHODIMP CNntpVirtualRoots::Set (
  590. long index,
  591. INntpVirtualRoot * pVirtualRoot
  592. )
  593. {
  594. TraceFunctEnter ( "CNntpVirtualRoots::ChangeVirtualRoot" );
  595. HRESULT hr = NOERROR;
  596. CComBSTR strNewsgroupSubtree;
  597. CComBSTR strDirectory;
  598. CVRoot temp;
  599. CComPtr<IMSAdminBase> pMetabase;
  600. WCHAR wszVRootPath [ METADATA_MAX_NAME_LEN ];
  601. WCHAR wszName [ METADATA_MAX_NAME_LEN ];
  602. // Send the new virtual root to the metabase:
  603. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  604. if ( FAILED(hr) ) {
  605. return hr;
  606. }
  607. CMetabaseKey mb ( pMetabase );
  608. if ( index < 0 || index >= m_dwCount ) {
  609. hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  610. goto Exit;
  611. }
  612. hr = temp.SetProperties ( pVirtualRoot );
  613. if ( FAILED(hr) ) {
  614. goto Exit;
  615. }
  616. GetMDVRootPath ( wszVRootPath );
  617. hr = mb.Open ( wszVRootPath, METADATA_PERMISSION_WRITE );
  618. BAIL_ON_FAILURE(hr);
  619. GetVRootName ( temp.m_strNewsgroupSubtree, wszName );
  620. hr = temp.SendToMetabase ( &mb, wszName );
  621. BAIL_ON_FAILURE(hr);
  622. hr = m_rgVRoots[index].SetProperties ( pVirtualRoot );
  623. BAIL_ON_FAILURE(hr);
  624. Exit:
  625. TraceFunctLeave ();
  626. return hr;
  627. }
  628. STDMETHODIMP CNntpVirtualRoots::Remove ( long index )
  629. {
  630. TraceFunctEnter ( "CNntpVirtualRoots::Remove" );
  631. HRESULT hr = NOERROR;
  632. CVRoot temp;
  633. long cPositionsToSlide;
  634. CComPtr<IMSAdminBase> pMetabase;
  635. WCHAR wszName [ METADATA_MAX_NAME_LEN ];
  636. WCHAR wszVRootPath [ METADATA_MAX_NAME_LEN ];
  637. if ( index < 0 || index >= m_dwCount ) {
  638. return NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
  639. }
  640. // Delete the virtual root from the metabase:
  641. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  642. if ( FAILED(hr) ) {
  643. return hr;
  644. }
  645. CMetabaseKey mb ( pMetabase );
  646. GetMDVRootPath ( wszVRootPath );
  647. hr = mb.Open ( wszVRootPath, METADATA_PERMISSION_WRITE );
  648. BAIL_ON_FAILURE(hr);
  649. GetVRootName ( m_rgVRoots[index].m_strNewsgroupSubtree, wszName );
  650. hr = mb.DeleteAllData ( wszName );
  651. BAIL_ON_FAILURE(hr);
  652. /*
  653. hr = mb.DestroyChild ( wszName );
  654. BAIL_ON_FAILURE(hr);
  655. */
  656. hr = mb.Save ();
  657. BAIL_ON_FAILURE(hr);
  658. mb.Close ();
  659. // Slide the array down by one position:
  660. _ASSERT ( m_rgVRoots );
  661. cPositionsToSlide = (m_dwCount - 1) - index;
  662. _ASSERT ( cPositionsToSlide < m_dwCount );
  663. if ( cPositionsToSlide > 0 ) {
  664. // Save the deleted VirtualRoot in temp:
  665. CopyMemory ( &temp, &m_rgVRoots[index], sizeof ( CVRoot ) );
  666. // Move the array down one:
  667. MoveMemory ( &m_rgVRoots[index], &m_rgVRoots[index + 1], sizeof ( CVRoot ) * cPositionsToSlide );
  668. // Put the deleted VirtualRoot on the end (so it gets destructed):
  669. CopyMemory ( &m_rgVRoots[m_dwCount - 1], &temp, sizeof ( CVRoot ) );
  670. // Zero out the temp VirtualRoot:
  671. ZeroMemory ( &temp, sizeof ( CVRoot ) );
  672. }
  673. m_dwCount--;
  674. Exit:
  675. TraceFunctLeave ();
  676. return hr;
  677. }
  678. STDMETHODIMP CNntpVirtualRoots::Find ( BSTR strNewsgroupSubtree, long * pIndex )
  679. {
  680. HRESULT hr = NOERROR;
  681. long i;
  682. _ASSERT ( pIndex );
  683. *pIndex = -1;
  684. for ( i = 0; i < m_dwCount; i++ ) {
  685. if ( lstrcmp ( m_rgVRoots[i].m_strNewsgroupSubtree, strNewsgroupSubtree ) == 0 ) {
  686. *pIndex = i;
  687. }
  688. }
  689. return NOERROR;
  690. }
  691. static HRESULT CountVrootsIterator (
  692. CMetabaseKey * pMB,
  693. LPCWSTR wszVrootPath,
  694. LPARAM lParam
  695. )
  696. {
  697. DWORD * pcVroots = (DWORD *) lParam;
  698. (*pcVroots)++;
  699. return NOERROR;
  700. }
  701. typedef struct tagAddVrootsParms
  702. {
  703. DWORD cCount;
  704. CVRoot * rgVroots;
  705. DWORD dwCurrentIndex;
  706. LPWSTR wszServerName;
  707. DWORD dwInstanceId;
  708. } ADD_VROOTS_PARMS;
  709. static HRESULT AddVrootsIterator (
  710. CMetabaseKey * pMB,
  711. LPCWSTR wszVrootPath,
  712. LPARAM lParam
  713. )
  714. {
  715. _ASSERT ( pMB );
  716. _ASSERT ( wszVrootPath );
  717. _ASSERT ( lParam );
  718. HRESULT hr;
  719. ADD_VROOTS_PARMS * pParms = (ADD_VROOTS_PARMS *) lParam;
  720. LPWSTR wszServerName = pParms->wszServerName;
  721. DWORD dwInstanceId = pParms->dwInstanceId;
  722. _ASSERT ( pParms->dwCurrentIndex < pParms->cCount );
  723. hr = pParms->rgVroots[pParms->dwCurrentIndex].GetFromMetabase (
  724. pMB,
  725. wszVrootPath,
  726. dwInstanceId,
  727. wszServerName
  728. );
  729. BAIL_ON_FAILURE(hr);
  730. pParms->dwCurrentIndex++;
  731. Exit:
  732. return hr;
  733. }
  734. HRESULT CNntpVirtualRoots::GetVRootsFromMetabase ( IMSAdminBase * pMetabase )
  735. {
  736. HRESULT hr = NOERROR;
  737. CMetabaseKey mb ( pMetabase );
  738. WCHAR wszVRootPath [ METADATA_MAX_NAME_LEN ];
  739. DWORD cCount = 0;
  740. CVRoot * rgVroots = NULL;
  741. ADD_VROOTS_PARMS parms;
  742. //
  743. // Initialize the metabase:
  744. //
  745. GetMDVRootPath ( wszVRootPath );
  746. hr = mb.Open ( wszVRootPath );
  747. BAIL_ON_FAILURE(hr);
  748. //
  749. // Count the virtual roots:
  750. //
  751. hr = IterateOverVroots ( &mb, CountVrootsIterator, (LPARAM) &cCount );
  752. BAIL_ON_FAILURE(hr);
  753. //
  754. // Create the virtual roots array:
  755. //
  756. rgVroots = new CVRoot [ cCount ];
  757. if ( !rgVroots ) {
  758. hr = E_OUTOFMEMORY;
  759. goto Exit;
  760. }
  761. //
  762. // Add the virtual roots to the array:
  763. //
  764. parms.cCount = cCount;
  765. parms.rgVroots = rgVroots;
  766. parms.dwCurrentIndex = 0;
  767. parms.wszServerName = m_strServer;
  768. parms.dwInstanceId = m_dwServiceInstance;
  769. hr = IterateOverVroots ( &mb, AddVrootsIterator, (LPARAM) &parms );
  770. BAIL_ON_FAILURE(hr);
  771. _ASSERT ( SUCCEEDED(hr) );
  772. _ASSERT ( m_rgVRoots == NULL );
  773. m_rgVRoots = rgVroots;
  774. m_dwCount = cCount;
  775. Exit:
  776. if ( FAILED(hr) ) {
  777. delete [] rgVroots;
  778. }
  779. return hr;
  780. }
  781. HRESULT CNntpVirtualRoots::IterateOverVroots (
  782. CMetabaseKey * pMB,
  783. VROOT_ITERATOR fpIterator,
  784. LPARAM lParam,
  785. LPCWSTR wszPath // = _T("")
  786. )
  787. {
  788. HRESULT hr;
  789. WCHAR wszSubKey[ METADATA_MAX_NAME_LEN ];
  790. WCHAR wszSubPath[ METADATA_MAX_NAME_LEN ];
  791. BOOL fRealVroot;
  792. DWORD cbVrootDir;
  793. DWORD i;
  794. //
  795. // Is this a real vroot?
  796. //
  797. fRealVroot =
  798. !*wszPath || // Always count the home directory
  799. SUCCEEDED ( pMB->GetDataSize (
  800. wszPath,
  801. MD_VR_PATH,
  802. STRING_METADATA,
  803. &cbVrootDir,
  804. METADATA_NO_ATTRIBUTES )
  805. );
  806. if ( fRealVroot ) {
  807. // Call the iterator on this key:
  808. hr = (*fpIterator) ( pMB, wszPath, lParam );
  809. BAIL_ON_FAILURE(hr);
  810. }
  811. //
  812. // Recurse down the tree:
  813. //
  814. for ( i = 0; ; ) {
  815. hr = pMB->EnumObjects ( wszPath, wszSubKey, i );
  816. if ( HRESULTTOWIN32(hr) == ERROR_NO_MORE_ITEMS ) {
  817. // This is expected, end the loop:
  818. if ( !fRealVroot && i == 0 ) {
  819. //
  820. // This key isn't a vroot and has no children, so delete it.
  821. //
  822. hr = pMB->ChangePermissions ( METADATA_PERMISSION_WRITE );
  823. if ( SUCCEEDED(hr) ) {
  824. hr = pMB->DeleteKey ( wszPath );
  825. }
  826. pMB->ChangePermissions ( METADATA_PERMISSION_READ );
  827. if ( SUCCEEDED(hr) ) {
  828. hr = pMB->Save ();
  829. }
  830. if ( SUCCEEDED(hr) ) {
  831. //
  832. // Tell our parent that this key was deleted.
  833. //
  834. hr = S_FALSE;
  835. }
  836. else {
  837. //
  838. // Ignore any deleting problems:
  839. //
  840. hr = NOERROR;
  841. }
  842. }
  843. else {
  844. hr = NOERROR;
  845. }
  846. break;
  847. }
  848. BAIL_ON_FAILURE(hr);
  849. if ( *wszPath ) {
  850. wsprintf ( wszSubPath, _T("%s/%s"), wszPath, wszSubKey );
  851. }
  852. else {
  853. wcscpy ( wszSubPath, wszSubKey );
  854. }
  855. hr = IterateOverVroots ( pMB, fpIterator, lParam, wszSubPath );
  856. BAIL_ON_FAILURE(hr);
  857. if ( hr != S_FALSE ) {
  858. //
  859. // This means the child key still exists, so increment
  860. // the counter and go on to the next one.
  861. //
  862. i++;
  863. }
  864. //
  865. // Else the return code is S_FALSE, which means the current key
  866. // has been deleted, shifting all indicies down by one. Therefore,
  867. // there is no need to increment i.
  868. //
  869. }
  870. Exit:
  871. return hr;
  872. }
  873. void CNntpVirtualRoots::GetVRootName ( LPWSTR wszDisplayName, LPWSTR wszPathName )
  874. {
  875. wcscpy ( wszPathName, wszDisplayName );
  876. }
  877. void CNntpVirtualRoots::GetMDVRootPath ( LPWSTR wszPath )
  878. {
  879. GetMDInstancePath ( wszPath, m_dwServiceInstance );
  880. wcscat ( wszPath, _T("Root/") );
  881. }
  882. STDMETHODIMP CNntpVirtualRoots::ItemDispatch ( long index, IDispatch ** ppDispatch )
  883. {
  884. HRESULT hr;
  885. CComPtr<INntpVirtualRoot> pVirtualRoot;
  886. hr = Item ( index, &pVirtualRoot );
  887. BAIL_ON_FAILURE ( hr );
  888. hr = pVirtualRoot->QueryInterface ( IID_IDispatch, (void **) ppDispatch );
  889. BAIL_ON_FAILURE ( hr );
  890. Exit:
  891. return hr;
  892. }
  893. STDMETHODIMP CNntpVirtualRoots::AddDispatch ( IDispatch * pVirtualRoot )
  894. {
  895. HRESULT hr;
  896. CComPtr<INntpVirtualRoot> pINntpVirtualRoot;
  897. hr = pVirtualRoot->QueryInterface ( IID_INntpVirtualRoot, (void **) &pINntpVirtualRoot );
  898. BAIL_ON_FAILURE(hr);
  899. hr = Add ( pINntpVirtualRoot );
  900. BAIL_ON_FAILURE(hr);
  901. Exit:
  902. return hr;
  903. }
  904. STDMETHODIMP CNntpVirtualRoots::SetDispatch ( long lIndex, IDispatch * pVirtualRoot )
  905. {
  906. HRESULT hr;
  907. CComPtr<INntpVirtualRoot> pINntpVirtualRoot;
  908. hr = pVirtualRoot->QueryInterface ( IID_INntpVirtualRoot, (void **) &pINntpVirtualRoot );
  909. BAIL_ON_FAILURE(hr);
  910. hr = Set ( lIndex, pINntpVirtualRoot );
  911. BAIL_ON_FAILURE(hr);
  912. Exit:
  913. return hr;
  914. }