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.

1007 lines
25 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: domobj.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "domobj.h"
  12. #include "domobjui.h"
  13. #include "cdomain.h"
  14. #include "domain.h"
  15. #include "proppage.h"
  16. #include "notify.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. ///////////////////////////////////////////////////////////////////////
  23. // global helper functions
  24. int _MessageBox(HWND hWnd, // handle to owner window
  25. LPCTSTR lpText, // pointer to text in message box
  26. UINT uType) // style of message box
  27. {
  28. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  29. CString szCaption;
  30. szCaption.LoadString(AFX_IDS_APP_TITLE);
  31. return ::MessageBox(hWnd, lpText, szCaption, uType);
  32. }
  33. void ReportError(HWND hWnd, UINT nMsgID, HRESULT hr)
  34. {
  35. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  36. LPTSTR ptzSysMsg = NULL;
  37. int cch = 0;
  38. int retval = MB_OK;
  39. // load message for this HRESULT
  40. cch = cchLoadHrMsg( hr, &ptzSysMsg, TRUE );
  41. CString szError;
  42. if (cch == 0)
  43. {
  44. // could not get a message string, format the raw hr value
  45. CString s;
  46. s.LoadString(IDS_FAILURE_UNK);
  47. szError.Format((LPCWSTR)s, hr);
  48. }
  49. else
  50. {
  51. szError = ptzSysMsg;
  52. }
  53. // format message string with
  54. CString szFmt;
  55. szFmt.LoadString(nMsgID);
  56. CString szMsg;
  57. szMsg.Format((LPCWSTR)szFmt, (LPCWSTR)szError);
  58. _MessageBox(hWnd, szMsg, MB_OK|MB_ICONERROR);
  59. // cleanup
  60. if (NULL != ptzSysMsg)
  61. LocalFree(ptzSysMsg);
  62. }
  63. ///////////////////////////////////////////////////////////////////////
  64. //CDsUiWizDLL g_dsUiWizDLL;
  65. enum
  66. {
  67. // Identifiers for each of the commands to be inserted into the context menu.
  68. IDM_MANAGE,
  69. IDM_TRUST_WIZ,
  70. IDM_RETARGET,
  71. IDM_EDIT_FSMO,
  72. IDM_DOMAIN_VERSION,
  73. IDM_FOREST_VERSION
  74. };
  75. HRESULT _AddMenuItemHelper(IContextMenuCallback* pIContextMenuCallback,
  76. UINT nResourceID, // contains text and status text seperated by '\n'
  77. long lCommandID,
  78. long lInsertionPointID,
  79. long fFlags = 0,
  80. long fSpecialFlags = 0)
  81. {
  82. ASSERT( pIContextMenuCallback != NULL );
  83. // load the resource
  84. CString strText;
  85. strText.LoadString(nResourceID);
  86. ASSERT( !strText.IsEmpty() );
  87. // split the resource into the menu text and status text
  88. CString strStatusText;
  89. int iSeparator = strText.Find(_T('\n'));
  90. if (0 > iSeparator)
  91. {
  92. ASSERT( FALSE );
  93. strStatusText = strText;
  94. }
  95. else
  96. {
  97. strStatusText = strText.Right( strText.GetLength()-(iSeparator+1) );
  98. strText = strText.Left( iSeparator );
  99. }
  100. // add the menu item
  101. USES_CONVERSION;
  102. CONTEXTMENUITEM contextmenuitem;
  103. ::ZeroMemory( &contextmenuitem, sizeof(contextmenuitem) );
  104. contextmenuitem.strName = T2OLE(const_cast<LPTSTR>((LPCTSTR)strText));
  105. contextmenuitem.strStatusBarText = T2OLE(const_cast<LPTSTR>((LPCTSTR)strStatusText));
  106. contextmenuitem.lCommandID = lCommandID;
  107. contextmenuitem.lInsertionPointID = lInsertionPointID;
  108. contextmenuitem.fFlags = fFlags;
  109. contextmenuitem.fSpecialFlags = fSpecialFlags;
  110. HRESULT hr = pIContextMenuCallback->AddItem( &contextmenuitem );
  111. ASSERT(hr == S_OK);
  112. return hr;
  113. }
  114. ///////////////////////////////////////////////////////////////////////
  115. // CDomainTreeBrowser
  116. HRESULT CDomainTreeBrowser::Bind(MyBasePathsInfo* pInfo)
  117. {
  118. TRACE(L"CDomainTreeBrowser::Bind()\n");
  119. ASSERT(pInfo != NULL);
  120. _Reset();
  121. HRESULT hr = S_OK;
  122. // create a browse object
  123. hr = ::CoCreateInstance(CLSID_DsDomainTreeBrowser,
  124. NULL,
  125. CLSCTX_INPROC_SERVER,
  126. IID_IDsBrowseDomainTree,
  127. (LPVOID*)&m_spIDsBrowseDomainTree);
  128. if (FAILED(hr))
  129. {
  130. TRACE(L"CoCreateInstance(CLSID_DsDomainTreeBrowser, ...) failed with hr = 0x%x\n");
  131. goto error;
  132. }
  133. // set the target computer
  134. hr = m_spIDsBrowseDomainTree->SetComputer(pInfo->GetServerName(), NULL, NULL);
  135. TRACE(L"m_spIDsBrowseDomainTree->SetComputer(%s, NULL, NULL) returned hr = 0x%x\n",
  136. pInfo->GetServerName(), hr);
  137. if (FAILED(hr))
  138. goto error;
  139. ASSERT(SUCCEEDED(hr));
  140. return hr; // all was fine
  141. error:
  142. // things went wrong, clear all
  143. _Reset();
  144. return hr;
  145. }
  146. HRESULT CDomainTreeBrowser::GetData()
  147. {
  148. ASSERT(m_spIDsBrowseDomainTree != NULL);
  149. HRESULT hr = S_OK;
  150. PDOMAIN_TREE pNewDomains = NULL;
  151. m_spIDsBrowseDomainTree->FlushCachedDomains();
  152. DWORD dwFlags = DBDTF_RETURNFQDN;
  153. hr = m_spIDsBrowseDomainTree->GetDomains(&pNewDomains, dwFlags);
  154. TRACE(L"m_spIDsBrowseDomainTree->GetDomains(...) returned hr = 0x%x\n", hr);
  155. if (SUCCEEDED(hr) && (pNewDomains != NULL))
  156. {
  157. _FreeDomains();
  158. m_pDomains = pNewDomains;
  159. }
  160. return hr;
  161. }
  162. ///////////////////////////////////////////////////////////////////////
  163. // CFolderObject
  164. CFolderObject::~CFolderObject()
  165. {
  166. RemoveAllChildren();
  167. }
  168. BOOL CFolderObject::AddChild(CFolderObject* pChildFolderObject)
  169. {
  170. return (m_childList.AddTail(pChildFolderObject) != NULL);
  171. }
  172. void CFolderObject::RemoveAllChildren()
  173. {
  174. while (!m_childList.IsEmpty())
  175. delete m_childList.RemoveHead();
  176. }
  177. void CFolderObject::IncrementSheetLockCount()
  178. {
  179. ++m_nSheetLockCount;
  180. if (m_pParentFolder != NULL)
  181. m_pParentFolder->IncrementSheetLockCount();
  182. }
  183. void CFolderObject::DecrementSheetLockCount()
  184. {
  185. ASSERT(m_nSheetLockCount > 0);
  186. --m_nSheetLockCount;
  187. if (m_pParentFolder != NULL)
  188. m_pParentFolder->DecrementSheetLockCount();
  189. }
  190. BOOL CFolderObject::_WarningOnSheetsUp(CComponentDataImpl* pCD)
  191. {
  192. if (!IsSheetLocked())
  193. return FALSE; // no warning, all is cool
  194. // warning to user that oeration cannot be performed
  195. CThemeContextActivator activator;
  196. AfxMessageBox(IDS_SHEETS_UP_DELETE, MB_OK);
  197. ASSERT(FALSE);
  198. // need to bring sheets on the foreground
  199. pCD->GetCookieSheet()->BringToForeground(this, pCD);
  200. return TRUE;
  201. }
  202. ///////////////////////////////////////////////////////////////////////
  203. // CRootFolderObject
  204. CRootFolderObject::CRootFolderObject(CComponentDataImpl* pCD) :
  205. m_pEnterpriseRoot(NULL)
  206. {
  207. m_pCD = pCD;
  208. }
  209. HRESULT CRootFolderObject::Bind()
  210. {
  211. return m_domainTreeBrowser.Bind(m_pCD->GetBasePathsInfo());
  212. }
  213. HRESULT CRootFolderObject::GetData()
  214. {
  215. HRESULT hr = m_domainTreeBrowser.GetData();
  216. if (FAILED(hr))
  217. return hr;
  218. // firs time, try to load the domain icon
  219. VERIFY(SUCCEEDED(m_pCD->AddDomainIcon()));
  220. RemoveAllChildren(); // clear the UI structures
  221. return hr;
  222. }
  223. HRESULT CRootFolderObject::EnumerateRootFolder(CComponentDataImpl* pComponentData)
  224. {
  225. TRACE(L"CRootFolderObject::EnumerateRootFolder()\n");
  226. if (!m_domainTreeBrowser.HasData())
  227. {
  228. TRACE(L"m_domainTreeBrowser.HasData() == FALSE \n");
  229. return S_OK;
  230. }
  231. HRESULT hr = S_OK;
  232. MyBasePathsInfo * pBPI;
  233. //
  234. // Get the enterprise root domain DN from the RootDSE.
  235. //
  236. pBPI = pComponentData->GetBasePathsInfo();
  237. if (!pBPI)
  238. {
  239. ASSERT(FALSE);
  240. return E_FAIL;
  241. }
  242. PCWSTR pwzRoot = pBPI->GetRootDomainNamingContext();
  243. TRACE(L"Root path: %ws\n", pwzRoot);
  244. PDOMAIN_DESC pRootDomain = NULL;
  245. //
  246. // Insert the root nodes. First insert the enterprise root.
  247. //
  248. for (pRootDomain = m_domainTreeBrowser.GetDomainTree()->aDomains; pRootDomain;
  249. pRootDomain = pRootDomain->pdNextSibling)
  250. {
  251. if (_wcsicmp(pwzRoot, pRootDomain->pszNCName) == 0)
  252. {
  253. TRACE(L"Enterprise root found!\n");
  254. CDomainObject* pDomain = new CDomainObject;
  255. if (!pDomain)
  256. {
  257. ASSERT(FALSE);
  258. return E_OUTOFMEMORY;
  259. }
  260. pDomain->Initialize(pRootDomain, m_pCD->GetDomainImageIndex());
  261. AddChild(pDomain);
  262. pDomain->SetParentFolder(this);
  263. hr = pComponentData->AddFolder(pDomain, GetScopeID(), TRUE); // has children
  264. if (FAILED(hr))
  265. {
  266. return hr;
  267. }
  268. //
  269. // Create a non-refcounted reference to the enterprise root domain node.
  270. // Do NOT call delete on the m_pEnterpriseRoot pointer!
  271. //
  272. m_pEnterpriseRoot = pDomain;
  273. break;
  274. }
  275. }
  276. //
  277. // Now insert the rest of the root nodes.
  278. //
  279. for (pRootDomain = m_domainTreeBrowser.GetDomainTree()->aDomains; pRootDomain;
  280. pRootDomain = pRootDomain->pdNextSibling)
  281. {
  282. if (_wcsicmp(pwzRoot, pRootDomain->pszNCName) == 0)
  283. {
  284. // Root already inserted.
  285. continue;
  286. }
  287. CDomainObject* pDomain = new CDomainObject;
  288. if (!pDomain)
  289. {
  290. ASSERT(FALSE);
  291. return E_OUTOFMEMORY;
  292. }
  293. pDomain->Initialize(pRootDomain, m_pCD->GetDomainImageIndex());
  294. AddChild(pDomain);
  295. pDomain->SetParentFolder(this);
  296. hr = pComponentData->AddFolder(pDomain, GetScopeID(), TRUE); // has children
  297. if (FAILED(hr))
  298. {
  299. break;
  300. }
  301. }
  302. return hr;
  303. }
  304. HRESULT
  305. CRootFolderObject::EnumerateFolder(CFolderObject* pFolderObject,
  306. HSCOPEITEM pParent,
  307. CComponentDataImpl* pComponentData)
  308. {
  309. HRESULT hr = E_FAIL;
  310. if (!m_domainTreeBrowser.HasData())
  311. return hr;
  312. ASSERT(pFolderObject != NULL);
  313. ASSERT(pFolderObject->GetScopeID() == pParent);
  314. CDomainObject* pDomainObject = dynamic_cast<CDomainObject*>(pFolderObject);
  315. if (pDomainObject == NULL)
  316. return hr;
  317. DOMAIN_DESC* pDomainDesc = pDomainObject->GetDescriptionPtr();
  318. if (pDomainDesc == NULL)
  319. return hr;
  320. if (pDomainDesc->pdChildList == NULL)
  321. return S_OK;
  322. for (DOMAIN_DESC* pChild = pDomainDesc->pdChildList; pChild;
  323. pChild = pChild->pdNextSibling)
  324. {
  325. CDomainObject* pDomain = new CDomainObject;
  326. pDomain->Initialize(pChild,
  327. m_pCD->GetDomainImageIndex());
  328. hr = pComponentData->AddFolder(pDomain, pDomainObject->GetScopeID(),
  329. TRUE); // has children
  330. pFolderObject->AddChild(pDomain);
  331. pDomain->SetParentFolder(pFolderObject);
  332. if (FAILED(hr))
  333. break;
  334. } // for
  335. return hr;
  336. }
  337. HRESULT CRootFolderObject::OnAddMenuItems(LPCONTEXTMENUCALLBACK pContextMenuCallback,
  338. long *pInsertionAllowed)
  339. {
  340. HRESULT hr = S_OK;
  341. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  342. {
  343. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  344. /*
  345. if (g_dsUiWizDLL.Load())
  346. {
  347. return _AddMenuItemHelper(pContextMenuCallback, IDS_COMMAND_TRUST_WIZ, IDM_TRUST_WIZ, CCM_INSERTIONPOINTID_PRIMARY_TOP);
  348. }
  349. */
  350. _AddMenuItemHelper(pContextMenuCallback, IDS_COMMAND_RETARGET, IDM_RETARGET, CCM_INSERTIONPOINTID_PRIMARY_TOP);
  351. _AddMenuItemHelper(pContextMenuCallback, IDS_COMMAND_EDIT_FSMO, IDM_EDIT_FSMO, CCM_INSERTIONPOINTID_PRIMARY_TOP);
  352. _AddMenuItemHelper(pContextMenuCallback, IDS_COMMAND_FOREST_VER, IDM_FOREST_VERSION, CCM_INSERTIONPOINTID_PRIMARY_TOP);
  353. }
  354. return hr;
  355. }
  356. HRESULT CRootFolderObject::OnCommand(CComponentDataImpl* pCD, long nCommandID)
  357. {
  358. HRESULT hr = S_OK;
  359. CString strConfig, strPartitions, strSchema;
  360. switch (nCommandID)
  361. {
  362. //case IDM_TRUST_WIZ:
  363. // OnDomainTrustWizard();
  364. // break;
  365. case IDM_RETARGET:
  366. OnRetarget();
  367. break;
  368. case IDM_EDIT_FSMO:
  369. OnEditFSMO();
  370. break;
  371. case IDM_FOREST_VERSION:
  372. MyBasePathsInfo * pBPI;
  373. pBPI = pCD->GetBasePathsInfo();
  374. if (!pBPI)
  375. {
  376. ASSERT(FALSE);
  377. return E_FAIL;
  378. }
  379. pBPI->GetConfigPath(strConfig);
  380. pBPI->GetPartitionsPath(strPartitions);
  381. pBPI->GetSchemaPath(strSchema);
  382. HWND hWndParent;
  383. pCD->GetMainWindow(&hWndParent);
  384. CDomainObject* pRoot;
  385. pRoot = GetEnterpriseRootNode();
  386. if (!pRoot)
  387. {
  388. ASSERT(FALSE);
  389. return E_FAIL;
  390. }
  391. DSPROP_ForestVersionDlg(strConfig, strPartitions, strSchema,
  392. pRoot->GetDomainName(), hWndParent);
  393. break;
  394. default:
  395. ASSERT(FALSE); // Unknown command!
  396. hr = E_FAIL;
  397. }
  398. return hr;
  399. }
  400. //void CRootFolderObject::OnDomainTrustWizard()
  401. //{
  402. //g_dsUiWizDLL.TrustWizard();
  403. //}
  404. void CRootFolderObject::OnRetarget()
  405. {
  406. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  407. if (_WarningOnSheetsUp(m_pCD))
  408. return;
  409. HWND hWndParent;
  410. m_pCD->GetMainWindow(&hWndParent);
  411. CComPtr<IDsAdminChooseDC> spIDsAdminChooseDC;
  412. CComBSTR bstrSelectedDC;
  413. HRESULT hr = ::CoCreateInstance(CLSID_DsAdminChooseDCObj,
  414. NULL,
  415. CLSCTX_INPROC_SERVER,
  416. IID_IDsAdminChooseDC,
  417. (void **) &spIDsAdminChooseDC);
  418. if (FAILED(hr))
  419. {
  420. ::ReportError(hWndParent, IDS_CANT_GET_PARTITIONS_INFORMATION, hr);
  421. return;
  422. }
  423. // invoke the dialog
  424. CThemeContextActivator activator;
  425. hr = spIDsAdminChooseDC->InvokeDialog(hWndParent,
  426. m_pCD->GetBasePathsInfo()->GetDomainName(),
  427. m_pCD->GetBasePathsInfo()->GetServerName(),
  428. 0x0,
  429. &bstrSelectedDC);
  430. if (SUCCEEDED(hr) && (hr != S_FALSE))
  431. {
  432. TRACE(L"CChangeDCDialog returned IDOK, with dlg.GetNewDCName() = %s\n", bstrSelectedDC);
  433. // attempt to bind
  434. MyBasePathsInfo tempBasePathsInfo;
  435. {
  436. CWaitCursor wait;
  437. hr = tempBasePathsInfo.InitFromName(bstrSelectedDC);
  438. }
  439. TRACE(L"tempBasePathsInfo.GetServerName() == %s\n", tempBasePathsInfo.GetServerName());
  440. if (FAILED(hr))
  441. {
  442. TRACE(L"tempBasePathsInfo.InitFromName(bstrSelectedDC) failed with hr = 0x%x\n", hr);
  443. ReportError(hWndParent, IDS_CANT_GET_PARTITIONS_INFORMATION, hr);
  444. // TODO: error handling, change icon
  445. }
  446. else
  447. {
  448. m_pCD->GetBasePathsInfo()->InitFromInfo(&tempBasePathsInfo);
  449. m_pCD->SetInit();
  450. TRACE(L"m_pCD->GetBasePathsInfo()->GetServerName() == %s\n", m_pCD->GetBasePathsInfo()->GetServerName());
  451. hr = m_pCD->GetDsDisplaySpecOptionsCFHolder()->Init(m_pCD->GetBasePathsInfo());
  452. ASSERT(SUCCEEDED(hr));
  453. {
  454. CWaitCursor wait;
  455. m_pCD->OnRefreshVerbHandler(this, NULL, TRUE /*bBindAgain */);
  456. }
  457. } // if
  458. } // if
  459. }
  460. void CRootFolderObject::OnEditFSMO()
  461. {
  462. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  463. HWND hWndParent;
  464. m_pCD->GetMainWindow(&hWndParent);
  465. CComPtr<IDisplayHelp> spIDisplayHelp;
  466. HRESULT hr = m_pCD->m_pConsole->QueryInterface (IID_IDisplayHelp,
  467. (void **)&spIDisplayHelp);
  468. ASSERT(spIDisplayHelp != NULL);
  469. CEditFsmoDialog dlg(m_pCD->GetBasePathsInfo(), hWndParent, spIDisplayHelp);
  470. CThemeContextActivator activator;
  471. dlg.DoModal();
  472. }
  473. HRESULT
  474. CRootFolderObject::OnAddPages(LPPROPERTYSHEETCALLBACK lpProvider,
  475. LONG_PTR handle)
  476. {
  477. MyBasePathsInfo * pBPI;
  478. //
  479. // Get the enterprise partition path from the RootDSE.
  480. //
  481. pBPI = m_pCD->GetBasePathsInfo();
  482. if (!pBPI)
  483. {
  484. ASSERT(FALSE);
  485. return E_FAIL;
  486. }
  487. CString strPartitions;
  488. pBPI->GetPartitionsPath(strPartitions);
  489. if (strPartitions.IsEmpty())
  490. {
  491. return E_OUTOFMEMORY;
  492. }
  493. CUpnSuffixPropertyPage* pPage = new CUpnSuffixPropertyPage(strPartitions);
  494. if (!pPage)
  495. {
  496. return E_OUTOFMEMORY;
  497. }
  498. // Theming changes
  499. PROPSHEETPAGEW_V3 pspv3 = {0};
  500. CopyMemory(&pspv3, &pPage->m_psp, pPage->m_psp.dwSize);
  501. pspv3.dwSize = sizeof(pspv3);
  502. HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(&pspv3);
  503. if (!hPage)
  504. {
  505. DWORD dwErr = GetLastError();
  506. TRACE(L"CreatePropertySheetPage failed with error %d\n", dwErr);
  507. delete pPage;
  508. return HRESULT_FROM_WIN32(dwErr);
  509. }
  510. return lpProvider->AddPage(hPage);
  511. }
  512. ///////////////////////////////////////////////////////////////////////
  513. // CDomainObject
  514. CDomainObject::~CDomainObject()
  515. {
  516. if (m_bSecondary)
  517. {
  518. ASSERT(m_pDomainDescription != NULL);
  519. ::free(m_pDomainDescription);
  520. }
  521. }
  522. LPCTSTR CDomainObject::GetDisplayString(int nCol)
  523. {
  524. switch (nCol)
  525. {
  526. case 0:
  527. return GetDomainName();
  528. case 1:
  529. return GetClass();
  530. default:
  531. ASSERT(FALSE);
  532. } // switch
  533. return _T("");
  534. }
  535. void CDomainObject::Initialize(DOMAIN_DESC* pDomainDescription,
  536. int nImage,
  537. BOOL bHasChildren)
  538. {
  539. SetImageIndex(nImage);
  540. // save pointer to domain description in DOMAIN_TREE
  541. m_pDomainDescription = pDomainDescription;
  542. }
  543. void CDomainObject::InitializeForSecondaryPage(LPCWSTR pszNCName,
  544. LPCWSTR pszObjectClass,
  545. int nImage)
  546. {
  547. ASSERT(pszNCName != NULL);
  548. ASSERT(pszObjectClass != NULL);
  549. SetImageIndex(nImage);
  550. // standalone node, need to build a dummy DOMAIN_DESC
  551. m_bSecondary = TRUE;
  552. // allocate and zero memory
  553. int nNCNameLen = lstrlen(pszNCName)+1;
  554. int nObjectClassLen = lstrlen(pszObjectClass)+1;
  555. int nByteLen = sizeof(DOMAIN_DESC) + sizeof(WCHAR)*(nNCNameLen + nObjectClassLen);
  556. m_pDomainDescription = (DOMAIN_DESC*)::malloc(nByteLen);
  557. ASSERT(m_pDomainDescription);
  558. if (!m_pDomainDescription)
  559. {
  560. return;
  561. }
  562. ::ZeroMemory(m_pDomainDescription, nByteLen);
  563. // copy the strings
  564. m_pDomainDescription->pszNCName = (WCHAR*) (((BYTE*)m_pDomainDescription) + sizeof(DOMAIN_DESC));
  565. wcscpy(m_pDomainDescription->pszNCName, pszNCName);
  566. m_pDomainDescription->pszObjectClass = (WCHAR*) (((BYTE*)m_pDomainDescription->pszNCName) + sizeof(WCHAR)*nNCNameLen);
  567. wcscpy(m_pDomainDescription->pszObjectClass, pszObjectClass);
  568. }
  569. HRESULT CDomainObject::OnAddMenuItems(LPCONTEXTMENUCALLBACK pContextMenuCallback,
  570. long *pInsertionAllowed)
  571. {
  572. HRESULT hr = S_OK;
  573. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  574. {
  575. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  576. hr = _AddMenuItemHelper(pContextMenuCallback, IDS_COMMAND_MANAGE, IDM_MANAGE, CCM_INSERTIONPOINTID_PRIMARY_TOP);
  577. if (FAILED(hr))
  578. return hr;
  579. hr = _AddMenuItemHelper(pContextMenuCallback, IDS_COMMAND_DOMAIN_VER, IDM_DOMAIN_VERSION, CCM_INSERTIONPOINTID_PRIMARY_TOP);
  580. if (FAILED(hr))
  581. return hr;
  582. }
  583. return hr;
  584. }
  585. HRESULT CDomainObject::OnCommand(CComponentDataImpl* pCD, long nCommandID)
  586. {
  587. HRESULT hr = S_OK;
  588. CString strPath;
  589. switch (nCommandID)
  590. {
  591. case IDM_MANAGE:
  592. OnManage(pCD);
  593. break;
  594. //case IDM_TRUST_WIZ:
  595. // OnDomainTrustWizard(pCD);
  596. // break;
  597. case IDM_DOMAIN_VERSION:
  598. HWND hWndParent;
  599. MyBasePathsInfo * pBPI;
  600. pBPI = pCD->GetBasePathsInfo();
  601. if (!pBPI)
  602. {
  603. ASSERT(FALSE);
  604. return E_FAIL;
  605. }
  606. pCD->GetMainWindow(&hWndParent);
  607. // build an LDAP path out of the DN
  608. if (PdcAvailable())
  609. {
  610. strPath = L"LDAP://";
  611. strPath += GetPDC();
  612. strPath += L"/";
  613. strPath += GetNCName();
  614. }
  615. else
  616. {
  617. pBPI->ComposeADsIPath(strPath, GetNCName());
  618. }
  619. DSPROP_DomainVersionDlg(strPath, GetDomainName(), hWndParent);
  620. break;
  621. default:
  622. ASSERT(FALSE); // Unknown command!
  623. hr = E_FAIL;
  624. }
  625. return hr;
  626. }
  627. void CDomainObject::OnManage(CComponentDataImpl* pCD)
  628. {
  629. static LPCWSTR lpszSearchArr[] =
  630. {
  631. L"%userprofile%\\Application Data\\Microsoft\\AdminTools\\dsa.msc",
  632. L"%systemroot%\\system32\\dsa.msc",
  633. NULL
  634. };
  635. WCHAR szParamString[MAX_PATH+1] = {0};
  636. wcscpy (szParamString, L" /Domain=");
  637. wcsncat (szParamString, (LPWSTR)(GetDomainName()), MAX_PATH - wcslen(szParamString));
  638. SHELLEXECUTEINFO seiManage = {0};
  639. seiManage.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI;
  640. seiManage.cbSize = sizeof (SHELLEXECUTEINFO);
  641. seiManage.lpParameters = szParamString;
  642. seiManage.nShow = SW_SHOW;
  643. BOOL bExecuted = FALSE;
  644. DWORD dwErr = 0;
  645. for (int k=0; lpszSearchArr[k] != NULL; k++)
  646. {
  647. CWaitCursor cWait;
  648. seiManage.lpFile = (LPCWSTR)lpszSearchArr[k];
  649. if (!ShellExecuteEx(&seiManage))
  650. {
  651. dwErr = ::GetLastError();
  652. }
  653. else
  654. {
  655. bExecuted = TRUE;
  656. break;
  657. }
  658. }
  659. if (!bExecuted)
  660. {
  661. HWND hWndParent;
  662. pCD->GetMainWindow(&hWndParent);
  663. ReportError(hWndParent, IDS_ERROR_MANAGE, HRESULT_FROM_WIN32(dwErr));
  664. }
  665. }
  666. //void CDomainObject::OnDomainTrustWizard(CComponentDataImpl* pCD)
  667. //{
  668. //g_dsUiWizDLL.TrustWizard();
  669. //}
  670. void CDomainObject::SetPdcAvailable(bool fAvail)
  671. {
  672. _fPdcAvailable = fAvail;
  673. }
  674. ////////////////////////////////////////////////////////////////////
  675. // CCookieTableBase
  676. #define NUMBER_OF_COOKIE_TABLE_ENTRIES 4 // default count, expandable at run time
  677. CCookieTableBase::CCookieTableBase() :
  678. m_pCookieArr(NULL)
  679. {
  680. m_nEntries = NUMBER_OF_COOKIE_TABLE_ENTRIES;
  681. m_pCookieArr =(CFolderObject**)malloc(m_nEntries*sizeof(CFolderObject*));
  682. ASSERT(m_pCookieArr);
  683. if (m_pCookieArr)
  684. {
  685. ZeroMemory(m_pCookieArr, m_nEntries*sizeof(CFolderObject*));
  686. }
  687. }
  688. CCookieTableBase::~CCookieTableBase()
  689. {
  690. if (m_pCookieArr)
  691. {
  692. free(m_pCookieArr);
  693. }
  694. }
  695. void CCookieTableBase::Add(CFolderObject* pCookie)
  696. {
  697. ASSERT(!IsPresent(pCookie));
  698. if (!m_pCookieArr)
  699. {
  700. return;
  701. }
  702. for (UINT k=0; k<m_nEntries; k++)
  703. {
  704. if (m_pCookieArr[k] == NULL)
  705. {
  706. m_pCookieArr[k] = pCookie;
  707. return;
  708. }
  709. }
  710. // no space left, need to allocate
  711. int nAlloc = m_nEntries*2;
  712. CFolderObject** pCookieArrTemp = NULL;
  713. pCookieArrTemp = (CFolderObject**)realloc(m_pCookieArr, sizeof(CFolderObject*)*nAlloc);
  714. ASSERT(pCookieArrTemp);
  715. if (pCookieArrTemp)
  716. {
  717. m_pCookieArr = pCookieArrTemp;
  718. ::ZeroMemory(&m_pCookieArr[m_nEntries], sizeof(CFolderObject*)*m_nEntries);
  719. m_pCookieArr[m_nEntries] = pCookie;
  720. m_nEntries = nAlloc;
  721. }
  722. }
  723. BOOL CCookieTableBase::Remove(CFolderObject* pCookie)
  724. {
  725. if (!m_pCookieArr)
  726. {
  727. return FALSE;
  728. }
  729. for (UINT k=0; k<m_nEntries; k++)
  730. {
  731. if (m_pCookieArr[k] == pCookie)
  732. {
  733. m_pCookieArr[k] = NULL;
  734. return TRUE; // found
  735. }
  736. }
  737. return FALSE; // not found
  738. }
  739. BOOL CCookieTableBase::IsPresent(CFolderObject* pCookie)
  740. {
  741. if (!m_pCookieArr)
  742. {
  743. return FALSE;
  744. }
  745. for (UINT k=0; k<m_nEntries; k++)
  746. {
  747. if (m_pCookieArr[k] == pCookie)
  748. return TRUE;
  749. }
  750. return FALSE;
  751. }
  752. void CCookieTableBase::Reset()
  753. {
  754. if (!m_pCookieArr)
  755. {
  756. return;
  757. }
  758. for (UINT k=0; k<m_nEntries; k++)
  759. {
  760. m_pCookieArr[k] = NULL;
  761. }
  762. }
  763. UINT CCookieTableBase::GetCount()
  764. {
  765. if (!m_pCookieArr)
  766. {
  767. return 0;
  768. }
  769. UINT nCount = 0;
  770. for (UINT k=0; k<m_nEntries; k++)
  771. {
  772. if (m_pCookieArr[k] != NULL)
  773. nCount++;
  774. }
  775. return nCount;
  776. }
  777. ////////////////////////////////////////////////////////////////////
  778. // CDSCookieSheetTable
  779. void CCookieSheetTable::BringToForeground(CFolderObject* pCookie, CComponentDataImpl* pCD)
  780. {
  781. ASSERT(pCD != NULL);
  782. ASSERT(pCookie != NULL);
  783. if (!m_pCookieArr)
  784. {
  785. return;
  786. }
  787. // look for the cookie itself and for all the cookies that have the
  788. // given cookie as parent or ancestor
  789. BOOL bActivate = TRUE;
  790. for (UINT k=0; k<m_nEntries; k++)
  791. {
  792. if (m_pCookieArr[k] != NULL)
  793. {
  794. CFolderObject* pAncestorCookie = m_pCookieArr[k];
  795. while (pAncestorCookie != NULL)
  796. {
  797. if (pAncestorCookie == pCookie)
  798. {
  799. CString szADSIPath;
  800. LPCWSTR lpszNamingContext = ((CDomainObject *)m_pCookieArr[k])->GetNCName();
  801. pCD->GetBasePathsInfo()->ComposeADsIPath(szADSIPath, lpszNamingContext);
  802. // the first one will be also activated
  803. VERIFY(BringSheetToForeground((LPWSTR)(LPCWSTR)szADSIPath, bActivate));
  804. if (bActivate)
  805. bActivate = !bActivate;
  806. }
  807. pAncestorCookie = pAncestorCookie->GetParentFolder();
  808. } // while
  809. } // if
  810. } // for
  811. }
  812. ///////////////////////////////////////////////////////////////////////
  813. // CDsUiWizDLL