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.

1072 lines
22 KiB

  1. // admin.cpp : Implementation of CsmtpadmApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "metautil.h"
  4. #include "smtpadm.h"
  5. #include "smtpcmn.h"
  6. #include "smtpprop.h"
  7. #include "admin.h"
  8. #include "version.h"
  9. #include "oleutil.h"
  10. #include "metakey.h"
  11. #define SMTP_DEF_SERVICE_VERSION ( 0 ) // MCIS
  12. // Must define THIS_FILE_* macros to use NntpCreateException()
  13. #define THIS_FILE_HELP_CONTEXT 0
  14. #define THIS_FILE_PROG_ID _T("Smtpadm.Admin.1")
  15. #define THIS_FILE_IID IID_ISmtpAdmin
  16. /////////////////////////////////////////////////////////////////////////////
  17. //
  18. CSmtpAdmin::CSmtpAdmin () :
  19. m_dwServiceInstance ( 0 )
  20. // CComBSTR's are initialized to NULL by default.
  21. {
  22. m_dwServiceVersion = SMTP_DEF_SERVICE_VERSION;
  23. }
  24. CSmtpAdmin::~CSmtpAdmin ()
  25. {
  26. // All CComBSTR's are freed automatically.
  27. }
  28. STDMETHODIMP CSmtpAdmin::InterfaceSupportsErrorInfo(REFIID riid)
  29. {
  30. static const IID* arr[] =
  31. {
  32. &IID_ISmtpAdmin,
  33. };
  34. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  35. {
  36. if (InlineIsEqualGUID(*arr[i],riid))
  37. return S_OK;
  38. }
  39. return S_FALSE;
  40. }
  41. STDMETHODIMP CSmtpAdmin::get_ServiceAdmin ( IDispatch ** ppIDispatch )
  42. {
  43. HRESULT hr = NOERROR;
  44. BSTR bstrT = _T("");
  45. CComPtr<ISmtpAdminService> pISmtpAdminService;
  46. hr = StdPropertyHandoffIDispatch (
  47. CLSID_CSmtpAdminService,
  48. IID_ISmtpAdminService,
  49. &pISmtpAdminService,
  50. ppIDispatch
  51. );
  52. if ( FAILED(hr) ) {
  53. goto Error;
  54. }
  55. // Set default properties:
  56. hr = pISmtpAdminService->put_Server ( m_strServer ? m_strServer : bstrT );
  57. if ( FAILED (hr) ) {
  58. goto Error;
  59. }
  60. return hr;
  61. Error:
  62. SAFE_RELEASE ( *ppIDispatch );
  63. *ppIDispatch = NULL;
  64. return hr;
  65. // Destructor releases pISmtpAdminService
  66. }
  67. STDMETHODIMP CSmtpAdmin::get_VirtualServerAdmin ( IDispatch ** ppIDispatch )
  68. {
  69. HRESULT hr = NOERROR;
  70. BSTR bstrT = _T("");
  71. CComPtr<ISmtpAdminVirtualServer> pISmtpAdminVirtualServer;
  72. hr = StdPropertyHandoffIDispatch (
  73. CLSID_CSmtpAdminVirtualServer,
  74. IID_ISmtpAdminVirtualServer,
  75. &pISmtpAdminVirtualServer,
  76. ppIDispatch
  77. );
  78. if ( FAILED(hr) ) {
  79. goto Error;
  80. }
  81. // Set default properties:
  82. hr = pISmtpAdminVirtualServer->put_Server ( m_strServer ? m_strServer : bstrT );
  83. if ( FAILED (hr) ) {
  84. goto Error;
  85. }
  86. hr = pISmtpAdminVirtualServer->put_ServiceInstance ( m_dwServiceInstance );
  87. if ( FAILED (hr) ) {
  88. goto Error;
  89. }
  90. return hr;
  91. Error:
  92. SAFE_RELEASE ( *ppIDispatch );
  93. *ppIDispatch = NULL;
  94. return hr;
  95. // Destructor releases pISmtpAdminVirtualServer
  96. }
  97. STDMETHODIMP CSmtpAdmin::get_SessionsAdmin ( IDispatch ** ppIDispatch )
  98. {
  99. HRESULT hr = NOERROR;
  100. BSTR bstrT = _T("");
  101. CComPtr<ISmtpAdminSessions> pISmtpAdminSessions;
  102. hr = StdPropertyHandoffIDispatch (
  103. CLSID_CSmtpAdminSessions,
  104. IID_ISmtpAdminSessions,
  105. &pISmtpAdminSessions,
  106. ppIDispatch
  107. );
  108. if ( FAILED(hr) ) {
  109. goto Error;
  110. }
  111. // Set default properties:
  112. hr = pISmtpAdminSessions->put_Server ( m_strServer ? m_strServer : bstrT );
  113. if ( FAILED (hr) ) {
  114. goto Error;
  115. }
  116. hr = pISmtpAdminSessions->put_ServiceInstance ( m_dwServiceInstance );
  117. if ( FAILED (hr) ) {
  118. goto Error;
  119. }
  120. return hr;
  121. Error:
  122. SAFE_RELEASE ( *ppIDispatch );
  123. *ppIDispatch = NULL;
  124. return hr;
  125. // Destructor releases pISmtpAdminSessions
  126. }
  127. STDMETHODIMP CSmtpAdmin::get_AliasAdmin( IDispatch ** ppIDispatch )
  128. {
  129. HRESULT hr = NOERROR;
  130. BSTR bstrT = _T("");
  131. CComPtr<ISmtpAdminAlias> pISmtpAdminAlias;
  132. hr = StdPropertyHandoffIDispatch (
  133. CLSID_CSmtpAdminAlias,
  134. IID_ISmtpAdminAlias,
  135. &pISmtpAdminAlias,
  136. ppIDispatch
  137. );
  138. if ( FAILED(hr) ) {
  139. goto Error;
  140. }
  141. // Set default properties:
  142. hr = pISmtpAdminAlias->put_Server ( m_strServer ? m_strServer : bstrT );
  143. if ( FAILED (hr) ) {
  144. goto Error;
  145. }
  146. hr = pISmtpAdminAlias->put_ServiceInstance ( m_dwServiceInstance );
  147. if ( FAILED (hr) ) {
  148. goto Error;
  149. }
  150. return hr;
  151. Error:
  152. SAFE_RELEASE ( *ppIDispatch );
  153. *ppIDispatch = NULL;
  154. return hr;
  155. // Destructor releases pISmtpAdminAlias
  156. }
  157. STDMETHODIMP CSmtpAdmin::get_UserAdmin( IDispatch ** ppIDispatch )
  158. {
  159. HRESULT hr = NOERROR;
  160. BSTR bstrT = _T("");
  161. CComPtr<ISmtpAdminUser> pISmtpAdminUser;
  162. hr = StdPropertyHandoffIDispatch (
  163. CLSID_CSmtpAdminUser,
  164. IID_ISmtpAdminUser,
  165. &pISmtpAdminUser,
  166. ppIDispatch
  167. );
  168. if ( FAILED(hr) ) {
  169. goto Error;
  170. }
  171. // Set default properties:
  172. hr = pISmtpAdminUser->put_Server ( m_strServer ? m_strServer : bstrT );
  173. if ( FAILED (hr) ) {
  174. goto Error;
  175. }
  176. hr = pISmtpAdminUser->put_ServiceInstance ( m_dwServiceInstance );
  177. if ( FAILED (hr) ) {
  178. goto Error;
  179. }
  180. return hr;
  181. Error:
  182. SAFE_RELEASE ( *ppIDispatch );
  183. *ppIDispatch = NULL;
  184. return hr;
  185. // Destructor releases pISmtpAdminUser
  186. }
  187. STDMETHODIMP CSmtpAdmin::get_DLAdmin( IDispatch ** ppIDispatch )
  188. {
  189. HRESULT hr = NOERROR;
  190. BSTR bstrT = _T("");
  191. CComPtr<ISmtpAdminDL> pISmtpAdminDL;
  192. hr = StdPropertyHandoffIDispatch (
  193. CLSID_CSmtpAdminDL,
  194. IID_ISmtpAdminDL,
  195. &pISmtpAdminDL,
  196. ppIDispatch
  197. );
  198. if ( FAILED(hr) ) {
  199. goto Error;
  200. }
  201. // Set default properties:
  202. hr = pISmtpAdminDL->put_Server ( m_strServer ? m_strServer : bstrT );
  203. if ( FAILED (hr) ) {
  204. goto Error;
  205. }
  206. hr = pISmtpAdminDL->put_ServiceInstance ( m_dwServiceInstance );
  207. if ( FAILED (hr) ) {
  208. goto Error;
  209. }
  210. return hr;
  211. Error:
  212. SAFE_RELEASE ( *ppIDispatch );
  213. *ppIDispatch = NULL;
  214. return hr;
  215. // Destructor releases pISmtpAdminDL
  216. }
  217. STDMETHODIMP CSmtpAdmin::get_DomainAdmin( IDispatch ** ppIDispatch )
  218. {
  219. HRESULT hr = NOERROR;
  220. BSTR bstrT = _T("");
  221. CComPtr<ISmtpAdminDomain> pISmtpAdminDomain;
  222. hr = StdPropertyHandoffIDispatch (
  223. CLSID_CSmtpAdminDomain,
  224. IID_ISmtpAdminDomain,
  225. &pISmtpAdminDomain,
  226. ppIDispatch
  227. );
  228. if ( FAILED(hr) ) {
  229. goto Error;
  230. }
  231. // Set default properties:
  232. hr = pISmtpAdminDomain->put_Server ( m_strServer ? m_strServer : bstrT );
  233. if ( FAILED (hr) ) {
  234. goto Error;
  235. }
  236. hr = pISmtpAdminDomain->put_ServiceInstance ( m_dwServiceInstance );
  237. if ( FAILED (hr) ) {
  238. goto Error;
  239. }
  240. return hr;
  241. Error:
  242. SAFE_RELEASE ( *ppIDispatch );
  243. *ppIDispatch = NULL;
  244. return hr;
  245. // Destructor releases pISmtpAdminDomain
  246. }
  247. STDMETHODIMP CSmtpAdmin::get_VirtualDirectoryAdmin( IDispatch ** ppIDispatch )
  248. {
  249. HRESULT hr = NOERROR;
  250. BSTR bstrT = _T("");
  251. CComPtr<ISmtpAdminVirtualDirectory> pISmtpAdminVirtualDirectory;
  252. hr = StdPropertyHandoffIDispatch (
  253. CLSID_CSmtpAdminVirtualDirectory,
  254. IID_ISmtpAdminVirtualDirectory,
  255. &pISmtpAdminVirtualDirectory,
  256. ppIDispatch
  257. );
  258. if ( FAILED(hr) ) {
  259. goto Error;
  260. }
  261. // Set default properties:
  262. hr = pISmtpAdminVirtualDirectory->put_Server ( m_strServer ? m_strServer : bstrT );
  263. if ( FAILED (hr) ) {
  264. goto Error;
  265. }
  266. hr = pISmtpAdminVirtualDirectory->put_ServiceInstance ( m_dwServiceInstance );
  267. if ( FAILED (hr) ) {
  268. goto Error;
  269. }
  270. return hr;
  271. Error:
  272. SAFE_RELEASE ( *ppIDispatch );
  273. *ppIDispatch = NULL;
  274. return hr;
  275. // Destructor releases pISmtpAdminVirtualDirectory
  276. }
  277. // Which service to configure:
  278. STDMETHODIMP CSmtpAdmin::get_Server ( BSTR * pstrServer )
  279. {
  280. return StdPropertyGet ( m_strServer, pstrServer );
  281. }
  282. STDMETHODIMP CSmtpAdmin::put_Server ( BSTR strServer )
  283. {
  284. return StdPropertyPutServerName ( &m_strServer, strServer );
  285. }
  286. STDMETHODIMP CSmtpAdmin::get_ServiceInstance ( long * plServiceInstance )
  287. {
  288. return StdPropertyGet ( m_dwServiceInstance, plServiceInstance );
  289. }
  290. STDMETHODIMP CSmtpAdmin::put_ServiceInstance ( long lServiceInstance )
  291. {
  292. return StdPropertyPut ( &m_dwServiceInstance, lServiceInstance );
  293. }
  294. // Versioning:
  295. STDMETHODIMP CSmtpAdmin::get_HighVersion ( long * plHighVersion )
  296. {
  297. *plHighVersion = HIGH_VERSION;
  298. return NOERROR;
  299. }
  300. STDMETHODIMP CSmtpAdmin::get_LowVersion ( long * plLowVersion )
  301. {
  302. *plLowVersion = LOW_VERSION;
  303. return NOERROR;
  304. }
  305. STDMETHODIMP CSmtpAdmin::get_BuildNum ( long * plBuildNumber )
  306. {
  307. *plBuildNumber = BUILD_NUM;
  308. return NOERROR;
  309. }
  310. STDMETHODIMP CSmtpAdmin::get_ServiceVersion ( long * plServiceVersion )
  311. {
  312. *plServiceVersion = m_dwServiceVersion;
  313. return NOERROR;
  314. }
  315. //////////////////////////////////////////////////////////////////////
  316. // Methods:
  317. //////////////////////////////////////////////////////////////////////
  318. //$-------------------------------------------------------------------
  319. //
  320. // CSmtpAdmin::EnumerateInstances
  321. //
  322. // Description:
  323. //
  324. // Returns a list of the virtual servers on the given machine.
  325. //
  326. // Parameters:
  327. //
  328. // ppsaInstances - Returned SAFEARRAY of instance IDs.
  329. // Must be freed by caller.
  330. //
  331. // Returns:
  332. //
  333. //
  334. //--------------------------------------------------------------------
  335. STDMETHODIMP CSmtpAdmin::EnumerateInstances ( SAFEARRAY ** ppsaInstances )
  336. {
  337. TraceFunctEnter ( "CSmtpAdmin::EnumerateInstances" );
  338. HRESULT hr = NOERROR;
  339. CComPtr<IMSAdminBase> pMetabase;
  340. SAFEARRAY * psaEmpty = NULL;
  341. SAFEARRAYBOUND sabound[1];
  342. // Check parameters:
  343. _ASSERT ( ppsaInstances != NULL );
  344. _ASSERT ( IS_VALID_OUT_PARAM ( ppsaInstances ) );
  345. if ( ppsaInstances == NULL ) {
  346. FatalTrace ( 0, "Bad return pointer" );
  347. hr = E_POINTER;
  348. goto Exit;
  349. }
  350. // Zero the out parameters:
  351. *ppsaInstances = NULL;
  352. // Set the return array to an empty array:
  353. sabound[0].lLbound = 0;
  354. sabound[0].cElements = 0;
  355. psaEmpty = SafeArrayCreate ( VT_I4, 1, sabound );
  356. if ( psaEmpty == NULL ) {
  357. FatalTrace ( (LPARAM) this, "Out of memory" );
  358. hr = E_OUTOFMEMORY;
  359. goto Exit;
  360. }
  361. *ppsaInstances = psaEmpty;
  362. // Get the metabase pointer:
  363. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  364. BAIL_ON_FAILURE(hr);
  365. // Enumerate the instances:
  366. hr = QueryMetabaseInstances ( pMetabase, ppsaInstances );
  367. Exit:
  368. if ( FAILED(hr) ) {
  369. _VERIFY ( SUCCEEDED (SafeArrayDestroy ( psaEmpty )) );
  370. if (ppsaInstances)
  371. *ppsaInstances = NULL;
  372. }
  373. TraceFunctLeave ();
  374. return hr;
  375. }
  376. STDMETHODIMP CSmtpAdmin::EnumerateInstancesVariant ( SAFEARRAY ** ppsaInstances )
  377. {
  378. TraceFunctEnter ( "CSmtpAdmin::EnumerateInstancesVariant" );
  379. HRESULT hr;
  380. SAFEARRAY * psaInstances = NULL;
  381. hr = EnumerateInstances ( &psaInstances );
  382. BAIL_ON_FAILURE(hr);
  383. hr = LongArrayToVariantArray ( psaInstances, ppsaInstances );
  384. BAIL_ON_FAILURE(hr);
  385. Exit:
  386. TraceFunctLeave ();
  387. return hr;
  388. }
  389. //$-------------------------------------------------------------------
  390. //
  391. // CSmtpAdmin::CreateInstance
  392. //
  393. // Description:
  394. //
  395. // Creates a new SMTP virtual server on the given machine.
  396. //
  397. // Parameters:
  398. //
  399. // plInstanceId - The new virtual server ID.
  400. //
  401. // Returns:
  402. //
  403. //
  404. //--------------------------------------------------------------------
  405. STDMETHODIMP CSmtpAdmin::CreateInstance ( BSTR pstrMailRoot, long * plInstanceId )
  406. {
  407. TraceFunctEnter ( "CSmtpAdmin::CreateInstance" );
  408. HRESULT hr = NOERROR;
  409. CComPtr<IMSAdminBase> pMetabase;
  410. // Check parameters:
  411. _ASSERT ( plInstanceId != NULL );
  412. _ASSERT ( IS_VALID_OUT_PARAM ( plInstanceId ) );
  413. if ( plInstanceId == NULL ) {
  414. FatalTrace ( 0, "Bad return pointer" );
  415. hr = E_POINTER;
  416. goto Exit;
  417. }
  418. // Zero the out parameter:
  419. *plInstanceId = 0;
  420. // Get the metabase pointer:
  421. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  422. if ( FAILED(hr) ) {
  423. goto Exit;
  424. }
  425. // Create a new instance:
  426. hr = CreateNewInstance ( pMetabase, plInstanceId, pstrMailRoot );
  427. Exit:
  428. TraceFunctLeave ();
  429. return hr;
  430. }
  431. //$-------------------------------------------------------------------
  432. //
  433. // CSmtpAdmin::DestroyInstance
  434. //
  435. // Description:
  436. //
  437. // Removes the given virtual server.
  438. //
  439. // Parameters:
  440. //
  441. // lInstanceId - The ID of the virtual server to delete.
  442. //
  443. // Returns:
  444. //
  445. //
  446. //--------------------------------------------------------------------
  447. STDMETHODIMP CSmtpAdmin::DestroyInstance ( long lInstanceId )
  448. {
  449. TraceFunctEnter ( "CSmtpAdmin::DestroyInstance" );
  450. HRESULT hr = NOERROR;
  451. CComPtr<IMSAdminBase> pMetabase;
  452. // Get the metabase pointer:
  453. hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
  454. if ( FAILED(hr) ) {
  455. goto Exit;
  456. }
  457. // Delete the instance:
  458. hr = DeleteInstance ( pMetabase, lInstanceId );
  459. Exit:
  460. TraceFunctLeave ();
  461. return hr;
  462. }
  463. //$-------------------------------------------------------------------
  464. //
  465. // CSmtpAdmin::ErrorToString
  466. //
  467. // Description:
  468. //
  469. // Translates an SMTP_ERROR_CODE to a readable string.
  470. //
  471. // Parameters:
  472. //
  473. // lErrorCode - Win32 error code.
  474. // pstrError - the readable error string.
  475. //
  476. // Returns:
  477. //
  478. // The error string in *pstrError.
  479. //
  480. //--------------------------------------------------------------------
  481. STDMETHODIMP CSmtpAdmin::ErrorToString ( DWORD lErrorCode, BSTR * pstrError )
  482. {
  483. TraceFunctEnter ( "CSmtpAdmin::ErrorToString" );
  484. _ASSERT ( IS_VALID_OUT_PARAM ( pstrError ) );
  485. HRESULT hr = NOERROR;
  486. DWORD dwFormatFlags;
  487. WCHAR wszError [ 1024 ];
  488. if ( pstrError == NULL ) {
  489. FatalTrace ( (LPARAM) this, "Bad return pointer" );
  490. TraceFunctLeave ();
  491. return E_POINTER;
  492. }
  493. //----------------------------------------------------------------
  494. //
  495. // Map error codes here:
  496. //
  497. //
  498. //----------------------------------------------------------------
  499. dwFormatFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
  500. if ( !FormatMessage ( dwFormatFlags, NULL, lErrorCode, 0, // Lang ID - Should be nonzero?
  501. wszError, 1024, NULL ) ) {
  502. // Didn't work, so put in a default message:
  503. WCHAR wszFormat [ 256 ];
  504. wszFormat[0] = L'\0';
  505. if ( !LoadStringW ( _Module.GetResourceInstance (), IDS_UNKNOWN_ERROR, wszFormat, 256 ) ||
  506. !*wszFormat ) {
  507. wcscpy ( wszFormat, L"Unknown Error (%1!d!)" );
  508. }
  509. FormatMessage (
  510. FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  511. wszFormat,
  512. IDS_UNKNOWN_ERROR,
  513. 0,
  514. wszError,
  515. 1024,
  516. (va_list *) &lErrorCode
  517. );
  518. }
  519. //
  520. // We need to strip out any " from the string, because
  521. // Javascript will barf.
  522. //
  523. LPWSTR pch;
  524. for ( pch = wszError; *pch; pch++ ) {
  525. if ( *pch == L'\"' ) {
  526. *pch = L'\'';
  527. }
  528. }
  529. //
  530. // Strip off any trailing control characters.
  531. //
  532. for (pch = &wszError[wcslen(wszError) - 1];
  533. pch >= wszError && iswcntrl(*pch);
  534. pch --) {
  535. *pch = 0;
  536. }
  537. *pstrError = ::SysAllocString( wszError );
  538. if ( *pstrError == NULL ) {
  539. hr = E_OUTOFMEMORY;
  540. goto Exit;
  541. }
  542. Exit:
  543. TraceFunctLeave ();
  544. return hr;
  545. }
  546. //$-------------------------------------------------------------------
  547. //
  548. // CSmtpAdmin::Tokenize
  549. //
  550. // Description:
  551. //
  552. // Makes the given string safe for HTML & Javascript
  553. //
  554. // Parameters:
  555. //
  556. // strIn - the input string
  557. // strOut - the resulting string with appropriate escape sequences.
  558. //
  559. //--------------------------------------------------------------------
  560. STDMETHODIMP CSmtpAdmin::Tokenize ( BSTR strIn, BSTR * pstrOut )
  561. {
  562. TraceFunctEnter ( "CSmtpAdmin::Tokenize" );
  563. _ASSERT ( IS_VALID_STRING ( strIn ) );
  564. _ASSERT ( IS_VALID_OUT_PARAM ( pstrOut ) );
  565. HRESULT hr = NOERROR;
  566. PWCHAR pSrc = strIn;
  567. PWCHAR pSrcCur = NULL;
  568. PWCHAR pDstCur = NULL;
  569. PWCHAR pDst = NULL;
  570. *pstrOut = NULL;
  571. pDst = new WCHAR [ 3 * lstrlen ( strIn ) + 1 ];
  572. if ( pDst == NULL ) {
  573. FatalTrace ( (LPARAM) this, "Out of memory" );
  574. hr = E_OUTOFMEMORY;
  575. goto Exit;
  576. }
  577. for ( pSrcCur = pSrc, pDstCur = pDst; *pSrcCur; pSrcCur++ ) {
  578. switch ( *pSrcCur ) {
  579. case L'\\':
  580. *(pDstCur++) = L'%';
  581. *(pDstCur++) = L'5';
  582. *(pDstCur++) = L'c';
  583. break;
  584. case L' ':
  585. *(pDstCur++) = L'+';
  586. break;
  587. case L':':
  588. *(pDstCur++) = L'%';
  589. *(pDstCur++) = L'3';
  590. *(pDstCur++) = L'a';
  591. break;
  592. case L'/':
  593. *(pDstCur++) = L'%';
  594. *(pDstCur++) = L'2';
  595. *(pDstCur++) = L'f';
  596. break;
  597. default:
  598. *(pDstCur++) = *pSrcCur;
  599. }
  600. }
  601. *pDstCur = L'\0';
  602. *pstrOut = ::SysAllocString ( pDst );
  603. if ( *pstrOut == NULL ) {
  604. FatalTrace ( (LPARAM) this, "Out of memory" );
  605. hr = E_OUTOFMEMORY;
  606. goto Exit;
  607. }
  608. Exit:
  609. delete pDst;
  610. if ( FAILED(hr) && hr != DISP_E_EXCEPTION ) {
  611. hr = SmtpCreateExceptionFromHresult ( hr );
  612. }
  613. TraceFunctLeave ();
  614. return hr;
  615. }
  616. //$-------------------------------------------------------------------
  617. //
  618. // CSmtpAdmin::QueryMetabaseInstances
  619. //
  620. // Description:
  621. //
  622. // Retrieves the list of virtual servers from the metabase
  623. //
  624. // Parameters:
  625. //
  626. // pMetabase - the metabase object
  627. // ppsaInstances - resulting array of instance ids.
  628. //
  629. // Returns:
  630. //
  631. //
  632. //--------------------------------------------------------------------
  633. HRESULT CSmtpAdmin::QueryMetabaseInstances ( IMSAdminBase * pMetabase, SAFEARRAY ** ppsaInstances )
  634. {
  635. TraceFunctEnter ( "CSmtpAdmin::QueryMetabaseInstances" );
  636. _ASSERT ( IS_VALID_IN_PARAM ( pMetabase ) );
  637. _ASSERT ( IS_VALID_OUT_PARAM ( ppsaInstances ) );
  638. HRESULT hr = NOERROR;
  639. CMetabaseKey mkeySmtp ( pMetabase );
  640. SAFEARRAY * psaResult = NULL;
  641. DWORD cValidInstances = 0;
  642. SAFEARRAYBOUND rgsaBound[1];
  643. DWORD i;
  644. TCHAR szName[ METADATA_MAX_NAME_LEN ];
  645. long index[1];
  646. DWORD dwInstance;
  647. hr = mkeySmtp.Open ( SMTP_MD_ROOT_PATH );
  648. if ( FAILED(hr) ) {
  649. goto Exit;
  650. }
  651. // pickup the service version number:
  652. hr = mkeySmtp.GetDword ( _T(""), MD_SMTP_SERVICE_VERSION, &m_dwServiceVersion );
  653. if ( FAILED(hr) ) {
  654. m_dwServiceVersion = SMTP_DEF_SERVICE_VERSION;
  655. }
  656. hr = mkeySmtp.GetIntegerChildCount ( &cValidInstances );
  657. if ( FAILED(hr) ) {
  658. goto Exit;
  659. }
  660. // Allocate the array:
  661. rgsaBound[0].lLbound = 0;
  662. rgsaBound[0].cElements = cValidInstances;
  663. psaResult = SafeArrayCreate ( VT_I4, 1, rgsaBound );
  664. if ( psaResult == NULL ) {
  665. FatalTrace ( 0, "Out of memory" );
  666. hr = E_OUTOFMEMORY;
  667. goto Exit;
  668. }
  669. mkeySmtp.BeginChildEnumeration ();
  670. for ( i = 0; i < cValidInstances; i++ ) {
  671. hr = mkeySmtp.NextIntegerChild ( &dwInstance, szName );
  672. _ASSERT ( SUCCEEDED(hr) );
  673. index[0] = i;
  674. hr = SafeArrayPutElement ( psaResult, index, &dwInstance );
  675. _ASSERT ( SUCCEEDED(hr) );
  676. }
  677. *ppsaInstances = psaResult;
  678. _ASSERT ( SUCCEEDED(hr) );
  679. Exit:
  680. if ( FAILED (hr) ) {
  681. SafeArrayDestroy ( psaResult );
  682. }
  683. TraceFunctLeave ();
  684. return hr;
  685. }
  686. //$-------------------------------------------------------------------
  687. //
  688. // CSmtpAdmin::CreateNewInstance
  689. //
  690. // Description:
  691. //
  692. // Creates a new virtual server in the metabase.
  693. //
  694. // Parameters:
  695. //
  696. // pMetabase - The metabase object
  697. // plInstanceId - The new instance ID.
  698. //
  699. // Returns:
  700. //
  701. //
  702. //--------------------------------------------------------------------
  703. HRESULT CSmtpAdmin::CreateNewInstance (
  704. IMSAdminBase * pMetabase,
  705. long * plInstanceId,
  706. BSTR bstrMailRoot
  707. )
  708. {
  709. TraceFunctEnter ( "CSmtpAdmin::CreateNewInstance" );
  710. _ASSERT ( IS_VALID_IN_PARAM ( pMetabase ) );
  711. _ASSERT ( IS_VALID_OUT_PARAM ( plInstanceId ) );
  712. HRESULT hr = NOERROR;
  713. CMetabaseKey mkeySmtp ( pMetabase );
  714. DWORD dwInstance;
  715. TCHAR szInstance [ METADATA_MAX_NAME_LEN ];
  716. TCHAR szPath [ METADATA_MAX_NAME_LEN ];
  717. TCHAR szDir [512];
  718. DWORD cb;
  719. // Zero the out parameters:
  720. *plInstanceId = NULL;
  721. hr = mkeySmtp.Open ( SMTP_MD_ROOT_PATH, METADATA_PERMISSION_WRITE );
  722. if ( FAILED(hr) ) {
  723. ErrorTraceX ( (LPARAM) this, "Failed to open SmtpSvc key, %x", GetLastError() );
  724. goto Exit;
  725. }
  726. hr = mkeySmtp.CreateIntegerChild ( &dwInstance, szInstance );
  727. if ( FAILED (hr) ) {
  728. goto Exit;
  729. }
  730. wsprintf( szPath, _T("%s/Root"), szInstance );
  731. hr = mkeySmtp.CreateChild( szPath );
  732. if ( FAILED (hr) ) {
  733. goto Exit;
  734. }
  735. wsprintf( szPath, _T("%s/Root/MailRoot"), szInstance );
  736. hr = mkeySmtp.CreateChild( szPath );
  737. if ( FAILED (hr) ) {
  738. goto Exit;
  739. }
  740. // create mail root virtual directory
  741. if( bstrMailRoot && bstrMailRoot[0] )
  742. {
  743. // get rid of '\' at the end
  744. cb = lstrlen( bstrMailRoot );
  745. if( cb > 0 && bstrMailRoot[cb-1] == _T('\\') )
  746. bstrMailRoot[cb-1] = _T('\0');
  747. wsprintf( szPath, _T("%s/Root/MailRoot"), szInstance );
  748. cb = wsprintf( szDir, _T("%s\\Mailbox"), bstrMailRoot );
  749. mkeySmtp.SetString( szPath, MD_VR_PATH, szDir);
  750. // set badmail, drop, pickup, queue keys
  751. wsprintf( szPath, _T("%s"), szInstance );
  752. cb = wsprintf( szDir, _T("%s\\Badmail"), bstrMailRoot );
  753. mkeySmtp.SetString( szPath, MD_BAD_MAIL_DIR, szDir);
  754. // K2 only has drop doamin
  755. if( SERVICE_IS_K2(m_dwServiceVersion) )
  756. {
  757. cb = wsprintf( szDir, _T("%s\\Drop"), bstrMailRoot );
  758. mkeySmtp.SetString( szPath, MD_MAIL_DROP_DIR, szDir );
  759. }
  760. cb = wsprintf( szDir, _T("%s\\Pickup"), bstrMailRoot );
  761. mkeySmtp.SetString( szPath, MD_MAIL_PICKUP_DIR, szDir );
  762. cb = wsprintf( szDir, _T("%s\\Queue"), bstrMailRoot );
  763. mkeySmtp.SetString( szPath, MD_MAIL_QUEUE_DIR, szDir );
  764. // set the routing sources, it's MultiSZ
  765. cb = wsprintf( szDir, _T("szDataDirectory=%s\\Route"), bstrMailRoot );
  766. szDir[cb] = szDir[cb+1] = _T('\0');
  767. mkeySmtp.SetMultiSz( szPath, MD_ROUTING_SOURCES, szDir, (cb+2) * sizeof(TCHAR) );
  768. // MCIS needs SendNDRTo and SendBadTo as "Postmaster", setup should set it on service level
  769. if( SERVICE_IS_MCIS(m_dwServiceVersion) )
  770. {
  771. mkeySmtp.SetString( szPath, MD_SEND_NDR_TO, TSTR_POSTMASTR_NAME );
  772. mkeySmtp.SetString( szPath, MD_SEND_BAD_TO, TSTR_POSTMASTR_NAME );
  773. }
  774. }
  775. //
  776. // Initialize the server state:
  777. //
  778. mkeySmtp.SetDword ( szInstance, MD_SERVER_COMMAND, MD_SERVER_COMMAND_STOP );
  779. mkeySmtp.SetDword ( szInstance, MD_SERVER_STATE, MD_SERVER_STATE_STOPPED );
  780. mkeySmtp.SetDword ( szInstance, MD_SERVER_AUTOSTART, FALSE );
  781. // hr = mkeySmtp.Close();
  782. // BAIL_ON_FAILURE(hr);
  783. mkeySmtp.Close();
  784. hr = pMetabase->SaveData ( );
  785. if ( FAILED (hr) ) {
  786. goto Exit;
  787. }
  788. *plInstanceId = dwInstance;
  789. Exit:
  790. TraceFunctLeave ();
  791. return hr;
  792. }
  793. //$-------------------------------------------------------------------
  794. //
  795. // CSmtpAdmin::DeleteInstance
  796. //
  797. // Description:
  798. //
  799. // Removes a virtual server from the metabase
  800. //
  801. // Parameters:
  802. //
  803. // pMetabase - The metabase object
  804. // lInstanceId - The ID of the virtual server to delete.
  805. //
  806. // Returns:
  807. //
  808. //
  809. //--------------------------------------------------------------------
  810. HRESULT CSmtpAdmin::DeleteInstance ( IMSAdminBase * pMetabase, long lInstanceId )
  811. {
  812. TraceFunctEnter ( "CSmtpAdmin::CreateNewInstance" );
  813. _ASSERT ( IS_VALID_IN_PARAM ( pMetabase ) );
  814. HRESULT hr = NOERROR;
  815. CMetabaseKey mkeySmtp ( pMetabase );
  816. //
  817. // Tell U2 to delete any mappings associated with this virtual server:
  818. //
  819. ::DeleteMapping ( m_strServer, (BSTR) MD_SERVICE_NAME, lInstanceId );
  820. //
  821. // Delete the virtual server from the metabase:
  822. //
  823. hr = mkeySmtp.Open ( SMTP_MD_ROOT_PATH, METADATA_PERMISSION_WRITE );
  824. if ( FAILED(hr) ) {
  825. ErrorTraceX ( (LPARAM) this, "Failed to open SmtpSvc key, %x", GetLastError() );
  826. goto Exit;
  827. }
  828. hr = mkeySmtp.DestroyIntegerChild ( (DWORD) lInstanceId );
  829. if ( FAILED (hr) ) {
  830. goto Exit;
  831. }
  832. // hr = mkeySmtp.Close();
  833. // BAIL_ON_FAILURE(hr);
  834. mkeySmtp.Close();
  835. hr = pMetabase->SaveData ( );
  836. if ( FAILED (hr) ) {
  837. goto Exit;
  838. }
  839. Exit:
  840. TraceFunctLeave ();
  841. return hr;
  842. }