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.

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