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.

626 lines
16 KiB

  1. // This node class represents the root node of our snap-in
  2. #include "stdafx.h"
  3. #include "MyNodes.h"
  4. #include "DomSel.h"
  5. #include "TSync.hpp"
  6. #include "ResStr.h"
  7. #include "HrMsg.h"
  8. #include "RegistryHelper.h"
  9. #include "IsAdmin.hpp"
  10. //#import "\bin\DBManager.tlb" no_namespace,named_guids
  11. //#import "\bin\McsVarSetMin.tlb" no_namespace, named_guids
  12. #import "DBMgr.tlb" no_namespace,named_guids
  13. #import "VarSet.tlb" no_namespace, named_guids rename("property", "aproperty")
  14. #import "UpdateMOT.tlb" no_namespace,named_guids
  15. // {C8C24622-3FA1-11d3-8AED-00A0C9AFE114}
  16. static const GUID CRootGUID_NODETYPE =
  17. { 0xc8c24622, 0x3fa1, 0x11d3, { 0x8a, 0xed, 0x0, 0xa0, 0xc9, 0xaf, 0xe1, 0x14 } };
  18. const GUID* CRootNode::m_NODETYPE = &CRootGUID_NODETYPE;
  19. const OLECHAR* CRootNode::m_SZNODETYPE = OLESTR("C8C24622-3FA1-11d3-8AED-00A0C9AFE114");
  20. const OLECHAR* CRootNode::m_SZDISPLAY_NAME = NULL;
  21. const CLSID* CRootNode::m_SNAPIN_CLASSID = &CLSID_DomMigrator;
  22. static LONG SnapInCount = -1;
  23. extern "C" int runWizard(int whichWizard, HWND hParentWindow);
  24. #define WIZARD_SEMNAME L"McsDomMigrAgent.990000.Sem"
  25. CSnapInToolbarInfo m_toolBar;
  26. namespace
  27. {
  28. //---------------------------------------------------------------------------
  29. // DisplayError Helper Function
  30. //---------------------------------------------------------------------------
  31. void DisplayError(HRESULT hr, UINT uFormatId)
  32. {
  33. _com_error ce = GetError(hr);
  34. if (FAILED(ce.Error()))
  35. {
  36. CString strTitle;
  37. strTitle.LoadString(IDS_Title);
  38. CString strMessage;
  39. strMessage.Format(uFormatId);
  40. _bstr_t bstrSource = ce.Source();
  41. if (bstrSource.length() > 0)
  42. {
  43. strMessage += _T(" : ");
  44. strMessage += bstrSource;
  45. }
  46. _bstr_t bstrDescription = ce.Description();
  47. if (bstrDescription.length() > 0)
  48. {
  49. strMessage += _T(" : ");
  50. strMessage += bstrDescription;
  51. }
  52. else
  53. {
  54. CString strError;
  55. strError.Format(_T(" : %s (%08lX)"), ce.ErrorMessage(), ce.Error());
  56. strMessage += strError;
  57. }
  58. MessageBox(NULL, strMessage, strTitle, MB_OK|MB_ICONERROR);
  59. }
  60. }
  61. }
  62. CRootNode::CRootNode() :
  63. m_hwndMainWindow(0)
  64. {
  65. // Initialize the array of children
  66. CReportingNode * pNode = new CReportingNode;
  67. if (pNode)
  68. {
  69. pNode->UpdateChildren(NULL);
  70. m_ChildArray.Add(pNode);
  71. }
  72. HRESULT hr;
  73. CString title, sFormat, msg;
  74. DWORD rc = IsAdminLocal();
  75. if (rc != ERROR_SUCCESS)
  76. {
  77. hr = HRESULT_FROM_WIN32(rc);
  78. title.LoadString(IDS_Title);
  79. sFormat.LoadString(IDS_ERR_LOCALADMINCHECK_MSG);
  80. msg.Format(sFormat, rc);
  81. MessageBox(NULL, msg, title, MB_ICONERROR | MB_OK);
  82. _com_issue_error(hr);
  83. }
  84. rc = MoveRegistry();
  85. if (rc != ERROR_SUCCESS)
  86. {
  87. hr = HRESULT_FROM_WIN32(rc);
  88. title.LoadString(IDS_Title);
  89. sFormat.LoadString(IDS_ERR_UPDATEREGISTRY_MSG);
  90. msg.Format(sFormat, rc);
  91. MessageBox(NULL, msg, title, MB_ICONERROR | MB_OK);
  92. _com_issue_error(hr);
  93. }
  94. UpdateMigratedObjectsTable();
  95. UpdateAccountReferenceTable();
  96. CheckForFailedActions(FALSE);
  97. //m_ChildArray.Add(new CPruneGraftNode);
  98. if (InterlockedIncrement(&SnapInCount) == 0)
  99. m_SZDISPLAY_NAME = GET_BSTR(IDS_ActiveDirectoryMigrationTool).copy();
  100. }
  101. CRootNode::~CRootNode()
  102. {
  103. if ((m_SZDISPLAY_NAME) && (InterlockedDecrement(&SnapInCount) < 0))
  104. {
  105. SysFreeString(const_cast<OLECHAR*>(m_SZDISPLAY_NAME));
  106. m_SZDISPLAY_NAME = NULL;
  107. }
  108. }
  109. class CWizardRunner
  110. {
  111. public:
  112. int RunTheWizard(int wizardNdx, HWND hwndParent)
  113. {
  114. int result = 0;
  115. TSemaphoreNamed cSem; // named semaphore
  116. BOOL bExisted = FALSE;
  117. CString message;
  118. CString title;
  119. DWORD rcOs = cSem.Create( WIZARD_SEMNAME, 0, 1, &bExisted );
  120. if ( rcOs || bExisted )
  121. {
  122. message.LoadString(IDS_WizardAlreadyRunning);
  123. title.LoadString(IDS_Title);
  124. MessageBox(NULL,message,title,MB_OK | MB_ICONERROR);
  125. }
  126. else
  127. {
  128. result = runWizard(wizardNdx, hwndParent);
  129. // if user cancels wizard or an error occurs
  130. if (result == 0)
  131. {
  132. // if able to retrieve error information
  133. // then an error occurred, notify user
  134. // Note: It is currently possible for errors
  135. // to occur without the error information being set
  136. DisplayError(S_OK, IDS_ERR_RUN_WIZARD);
  137. }
  138. }
  139. return result;
  140. }
  141. };
  142. void CRootNode::CheckUndoable()
  143. {
  144. IIManageDBPtr pDB;
  145. HRESULT hr;
  146. _bstr_t sWizard = L"Options.Wizard";
  147. long lAction = -2;
  148. VARIANT var;
  149. _variant_t vnt;
  150. hr = pDB.CreateInstance(CLSID_IManageDB);
  151. if ( SUCCEEDED(hr) )
  152. hr = pDB->raw_GetCurrentActionID(&lAction);
  153. if ( SUCCEEDED(hr) )
  154. {
  155. VariantInit(&var);
  156. hr = pDB->raw_GetActionHistoryKey(lAction, sWizard, &var);
  157. vnt.Attach(var);
  158. }
  159. if ( SUCCEEDED(hr) && (V_VT(&vnt) == VT_BSTR) )
  160. {
  161. sWizard = vnt;
  162. if (sWizard.length() > 0)
  163. {
  164. IsUndoable = ( !_wcsicmp(sWizard, L"user") || !_wcsicmp(sWizard, L"group") || !_wcsicmp(sWizard, L"computer") );
  165. if ( IsUndoable )
  166. {
  167. sWizard = GET_BSTR(DCTVS_Options_NoChange);
  168. VariantInit(&var);
  169. hr = pDB->raw_GetActionHistoryKey(lAction, sWizard, &var);
  170. vnt.Attach(var);
  171. if ( SUCCEEDED(hr) && (V_VT(&vnt) == VT_BSTR) )
  172. {
  173. sWizard = vnt;
  174. if (!sWizard || !UStrICmp(sWizard,GET_STRING(IDS_YES)) )
  175. {
  176. IsUndoable = false; // can't undo a no-change mode operation
  177. }
  178. }
  179. }
  180. }
  181. else
  182. {
  183. IsUndoable = false;
  184. }
  185. }
  186. else
  187. {
  188. IsUndoable = false;
  189. }
  190. if ( hr == 0x800a0bb9 )
  191. {
  192. // the database is missing or corrupt
  193. CString msg;
  194. CString title;
  195. msg.LoadString(IDS_NoDatabase);
  196. title.LoadString(IDS_Title);
  197. MessageBox(NULL,msg,title,MB_ICONERROR | MB_OK);
  198. throw new _com_error(hr);
  199. }
  200. }
  201. void CRootNode::CheckForST()
  202. {
  203. IIManageDBPtr pDB;
  204. HRESULT hr = S_OK;
  205. long cnt = 0;
  206. CanUseST = false;
  207. if ( SUCCEEDED(hr) )
  208. {
  209. hr = pDB.CreateInstance(CLSID_IManageDB);
  210. }
  211. if ( SUCCEEDED(hr) )
  212. {
  213. hr = pDB->raw_AreThereAnyMigratedObjects(&cnt);
  214. }
  215. if ( SUCCEEDED(hr) )
  216. {
  217. if ( cnt > 0 )
  218. {
  219. // there are some migrated objects
  220. CanUseST = true;
  221. }
  222. }
  223. }
  224. void CRootNode::CheckForFailedActions(BOOL bPrompt)
  225. {
  226. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  227. HRESULT hr = S_OK;
  228. IIManageDBPtr pDB;
  229. IVarSetPtr pVarSet(CLSID_VarSet);
  230. IUnknown * pUnk = NULL;
  231. long lAction = -2;
  232. CanRetry = false;
  233. hr = pDB.CreateInstance(CLSID_IManageDB);
  234. if ( SUCCEEDED(hr) )
  235. {
  236. hr = pVarSet.QueryInterface(IID_IUnknown,&pUnk);
  237. if ( SUCCEEDED(hr) )
  238. {
  239. // we will also check the last action type and set the IsUndoable flag.
  240. CheckUndoable();
  241. CheckForST();
  242. hr = pDB->raw_GetFailedDistributedActions(-1,&pUnk);
  243. pUnk->Release();
  244. if ( SUCCEEDED(hr) )
  245. {
  246. _bstr_t numItemsText = pVarSet->get(L"DA");
  247. long nItems = _wtoi(numItemsText);
  248. if ( nItems )
  249. {
  250. CString str;
  251. CString title;
  252. title.LoadString(IDS_Title);
  253. str.FormatMessage(IDS_FailedActions,nItems);
  254. CanRetry = true;
  255. if ( bPrompt && IDYES == MessageBox(NULL,str,title,MB_YESNO) )
  256. {
  257. bool bHandled;
  258. OnRetry(bHandled,NULL);
  259. }
  260. }
  261. }
  262. }
  263. }
  264. if (FAILED(hr))
  265. {
  266. DisplayError(hr, IDS_ERR_CHECK_FAILED_ACTIONS);
  267. _com_issue_error(hr);
  268. }
  269. }
  270. HRESULT CRootNode::OnMigrateUsers(bool &bHandled, CSnapInObjectRootBase* pObj)
  271. {
  272. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  273. CWaitCursor wait;
  274. HRESULT hr = S_OK;
  275. int result;
  276. CWizardRunner r;
  277. result = r.RunTheWizard(1, m_hwndMainWindow);
  278. if (result)
  279. {
  280. CheckUndoable();
  281. CheckForST();
  282. }
  283. return hr;
  284. }
  285. HRESULT CRootNode::OnMigrateGroups(bool &bHandled, CSnapInObjectRootBase* pObj)
  286. {
  287. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  288. CWaitCursor wait;
  289. HRESULT hr = S_OK;
  290. int result;
  291. CWizardRunner r;
  292. result = r.RunTheWizard(2, m_hwndMainWindow);
  293. if (result)
  294. {
  295. CheckUndoable();
  296. CheckForST();
  297. }
  298. return hr;
  299. }
  300. HRESULT CRootNode::OnMigrateComputers(bool &bHandled, CSnapInObjectRootBase* pObj)
  301. {
  302. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  303. CWaitCursor wait;
  304. HRESULT hr = S_OK;
  305. CWizardRunner r;
  306. int result = r.RunTheWizard(3, m_hwndMainWindow);
  307. if (result)
  308. {
  309. CheckUndoable();
  310. CheckForFailedActions(FALSE);
  311. }
  312. return hr;
  313. }
  314. HRESULT CRootNode::OnTranslateSecurity(bool &bHandled, CSnapInObjectRootBase* pObj)
  315. {
  316. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  317. CWaitCursor wait;
  318. HRESULT hr = S_OK;
  319. CWizardRunner r;
  320. int result = r.RunTheWizard(4, m_hwndMainWindow);
  321. if (result)
  322. IsUndoable = false;
  323. CheckForFailedActions(FALSE);
  324. return hr;
  325. }
  326. HRESULT CRootNode::OnMigrateExchangeServer(bool &bHandled, CSnapInObjectRootBase* pObj)
  327. {
  328. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  329. CWaitCursor wait;
  330. HRESULT hr = S_OK;
  331. CWizardRunner r;
  332. int result = r.RunTheWizard(11, m_hwndMainWindow);
  333. if (result)
  334. IsUndoable = false;
  335. return hr;
  336. }
  337. HRESULT CRootNode::OnMigrateExchangeDirectory(bool &bHandled, CSnapInObjectRootBase* pObj)
  338. {
  339. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  340. CWaitCursor wait;
  341. HRESULT hr = S_OK;
  342. CWizardRunner r;
  343. int result = r.RunTheWizard(7, m_hwndMainWindow);
  344. if (result)
  345. IsUndoable = false;
  346. return hr;
  347. }
  348. HRESULT CRootNode::OnMigrateServiceAccounts(bool &bHandled, CSnapInObjectRootBase* pObj)
  349. {
  350. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  351. CWaitCursor wait;
  352. HRESULT hr = S_OK;
  353. CWizardRunner r;
  354. int result = r.RunTheWizard(5, m_hwndMainWindow);
  355. if (result)
  356. IsUndoable = false;
  357. CheckForFailedActions(FALSE);
  358. return hr;
  359. }
  360. HRESULT CRootNode::OnReporting(bool &bHandled, CSnapInObjectRootBase* pObj)
  361. {
  362. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  363. CWaitCursor wait;
  364. HRESULT hr = S_OK;
  365. CWizardRunner r;
  366. int result = r.RunTheWizard(8, m_hwndMainWindow);
  367. IConsole * pConsole = NULL;
  368. // Reload the Child-Nodes for the reporting node
  369. CReportingNode * pRept = (CReportingNode*)m_ChildArray[0];
  370. if ( pRept )
  371. {
  372. hr = GetConsoleFromCSnapInObjectRootBase(pObj,&pConsole);
  373. if ( SUCCEEDED(hr) )
  374. {
  375. pRept->UpdateChildren(pConsole);
  376. }
  377. }
  378. if (result)
  379. IsUndoable = false;
  380. CheckForFailedActions(FALSE);
  381. return hr;
  382. }
  383. HRESULT CRootNode::OnUndo(bool &bHandled, CSnapInObjectRootBase* pObj)
  384. {
  385. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  386. CWaitCursor wait;
  387. HRESULT hr = S_OK;
  388. CWizardRunner r;
  389. int result = r.RunTheWizard(6, m_hwndMainWindow);
  390. if (result)
  391. {
  392. IsUndoable = false;
  393. CheckForST();
  394. }
  395. return hr;
  396. }
  397. HRESULT CRootNode::OnRetry(bool &bHandled, CSnapInObjectRootBase* pObj)
  398. {
  399. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  400. CWaitCursor wait;
  401. HRESULT hr = S_OK;
  402. CWizardRunner r;
  403. int result = r.RunTheWizard(9, m_hwndMainWindow);
  404. if (result)
  405. IsUndoable = false;
  406. CheckForFailedActions(FALSE);
  407. return hr;
  408. }
  409. HRESULT CRootNode::OnMigrateTrusts(bool &bHandled, CSnapInObjectRootBase* pObj)
  410. {
  411. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  412. CWaitCursor wait;
  413. HRESULT hr = S_OK;
  414. int result;
  415. CWizardRunner r;
  416. result = r.RunTheWizard(10, m_hwndMainWindow);
  417. if (result)
  418. IsUndoable = false;
  419. return hr;
  420. }
  421. HRESULT CRootNode::OnGroupMapping(bool &bHandled, CSnapInObjectRootBase* pObj)
  422. {
  423. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  424. CWaitCursor wait;
  425. HRESULT hr = S_OK;
  426. int result;
  427. CWizardRunner r;
  428. result = r.RunTheWizard(12, m_hwndMainWindow);
  429. if (result)
  430. IsUndoable = false;
  431. return hr;
  432. }
  433. void CRootNode::UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  434. {
  435. switch (id)
  436. {
  437. case ID_TOP_UNDO:
  438. if ( !IsUndoable )
  439. *flags = MF_DISABLED | MF_GRAYED;
  440. else
  441. *flags = MF_ENABLED;
  442. break;
  443. case ID_TOP_MIGRATEEXCHANGEDIRECTORY:
  444. if ( ! CanUseST )
  445. *flags = MF_DISABLED | MF_GRAYED;
  446. else
  447. *flags = MF_ENABLED;
  448. break;
  449. case ID_TOP_TRANSLATESECURITY:
  450. //always allow the Security Translation wizards now
  451. //that we can reACL using a sid mapping file
  452. *flags = MF_ENABLED;
  453. break;
  454. case ID_TOP_RETRY:
  455. if ( ! CanRetry )
  456. *flags = MF_DISABLED | MF_GRAYED;
  457. else
  458. *flags = MF_ENABLED;
  459. break;
  460. };
  461. }
  462. void CRootNode::UpdateMigratedObjectsTable()
  463. {
  464. ISrcSidUpdatePtr pSrcUpdate(CLSID_SrcSidUpdate);
  465. HRESULT hr;
  466. VARIANT_BOOL bvar;
  467. VARIANT_BOOL bHide = VARIANT_FALSE;
  468. CString title;
  469. CString sFormat;
  470. CString msg;
  471. //see if the new Source domain Sid column is in this migrated object's table
  472. hr = pSrcUpdate->raw_QueryForSrcSidColumn(&bvar);
  473. if ( FAILED(hr) )
  474. {
  475. _bstr_t sDescription = HResultToText(hr);
  476. title.LoadString(IDS_QUERYCLM_TITLE);
  477. sFormat.LoadString(IDS_ERR_QUERYCLM_MSG);
  478. msg.Format(sFormat, (WCHAR*)sDescription);
  479. MessageBox(NULL, msg, title, MB_ICONERROR | MB_OK);
  480. _com_issue_error(hr);
  481. return;
  482. }
  483. //if not then run the code to add it
  484. if ( bvar == VARIANT_FALSE )
  485. {
  486. //add and populate the new source Sid column
  487. hr = pSrcUpdate->raw_CreateSrcSidColumn(bHide, &bvar);
  488. if ( FAILED(hr) )
  489. {
  490. _bstr_t sDescription = HResultToText(hr);
  491. title.LoadString(IDS_NOSRCSIDCLM_TITLE);
  492. sFormat.LoadString(IDS_ERR_NOSRCSIDCLM_MSG);
  493. msg.Format(sFormat, (WCHAR*)sDescription);
  494. MessageBox(NULL, msg, title, MB_ICONERROR | MB_OK);
  495. _com_issue_error(hr);
  496. }
  497. if ( bvar == VARIANT_FALSE )
  498. {
  499. // title.LoadString(IDS_NOSRCSIDCLM_TITLE);
  500. // msg.LoadString(IDS_ERR_NOSRCSIDCLM_MSG);
  501. // MessageBox(NULL, msg, title, MB_ICONERROR | MB_OK);
  502. _com_issue_error(hr);
  503. }
  504. }
  505. }
  506. void CRootNode::UpdateAccountReferenceTable()
  507. {
  508. IIManageDBPtr pDB(CLSID_IManageDB);
  509. VARIANT_BOOL bFound = VARIANT_FALSE;
  510. //see if the new AccountSid column has already been added to
  511. //the AccountRefs table
  512. bFound = pDB->SidColumnInARTable();
  513. //if not there, create it
  514. if (!bFound)
  515. pDB->CreateSidColumnInAR();
  516. }