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.

1116 lines
30 KiB

  1. // Copyright (C) Microsoft Corporation, 1998 - 1999
  2. //
  3. // create new site and new subnet wizards
  4. //
  5. // 4-24-98 sburns
  6. // 9-23-98 jonn Subclassed off New Subnet Wizard
  7. #include "stdafx.h"
  8. #include "resource.h"
  9. #include "dsutil.h"
  10. #include "newobj.h"
  11. #include "dlgcreat.h"
  12. #include "querysup.h"
  13. #pragma warning (disable: 4100)
  14. #include <utility> // pair<>
  15. #include <list>
  16. #pragma warning (default: 4100)
  17. extern "C"
  18. {
  19. #include <dsgetdc.h> // DsValidateSubnetName
  20. }
  21. #define BREAK_ON_FAILED_HRESULT(hr) \
  22. if (FAILED(hr)) \
  23. { \
  24. ASSERT(FALSE); \
  25. break; \
  26. }
  27. #define BREAK_ON_NULL(p) \
  28. if (NULL == p) \
  29. { \
  30. ASSERT(FALSE); \
  31. break; \
  32. }
  33. // first in the pair is name of link, second is dn of the link
  34. typedef std::pair< CComBSTR, CComBSTR > TargetLinkInfo;
  35. typedef std::list< TargetLinkInfo > TargetLinkList;
  36. CreateNewSiteWizard::CreateNewSiteWizard(
  37. CNewADsObjectCreateInfo* pNewADsObjectCreateInfo)
  38. :
  39. CCreateNewObjectWizardBase(pNewADsObjectCreateInfo)
  40. {
  41. AddPage(&page);
  42. }
  43. CreateNewSubnetWizard::CreateNewSubnetWizard(
  44. CNewADsObjectCreateInfo* pNewADsObjectCreateInfo)
  45. :
  46. CCreateNewObjectWizardBase(pNewADsObjectCreateInfo)
  47. {
  48. AddPage(&page);
  49. }
  50. BEGIN_MESSAGE_MAP(CreateAndChoosePage, CCreateNewNamedObjectPage)
  51. ON_WM_DESTROY()
  52. END_MESSAGE_MAP()
  53. BEGIN_MESSAGE_MAP(CreateNewSubnetPage, CreateAndChoosePage)
  54. ON_EN_CHANGE(IDC_SUBNET_ADDRESS, OnSubnetMaskChange)
  55. ON_EN_CHANGE(IDC_SUBNET_MASK, OnSubnetMaskChange)
  56. END_MESSAGE_MAP()
  57. CreateAndChoosePage::CreateAndChoosePage(UINT nIDTemplate)
  58. :
  59. CCreateNewNamedObjectPage(nIDTemplate),
  60. listview(0),
  61. listview_imagelist(0)
  62. {
  63. }
  64. CreateNewSitePage::CreateNewSitePage()
  65. :
  66. CreateAndChoosePage(IDD_CREATE_NEW_SITE)
  67. {
  68. }
  69. CreateNewSubnetPage::CreateNewSubnetPage()
  70. :
  71. CreateAndChoosePage(IDD_CREATE_NEW_SUBNET)
  72. {
  73. }
  74. HRESULT
  75. CreateNewSitePage::SetData(BOOL bSilent)
  76. {
  77. if (0 < ListView_GetItemCount(listview))
  78. {
  79. if (0 >= ListView_GetSelectedCount(listview))
  80. {
  81. if (!bSilent)
  82. {
  83. ReportErrorEx (::GetParent(m_hWnd),IDS_NEW_SITE_SELECT_SITELINK,S_OK,
  84. MB_OK, NULL, 0);
  85. }
  86. (void) this->PostMessage( WM_NEXTDLGCTL,
  87. (WPARAM)listview,
  88. TRUE );
  89. return E_FAIL;
  90. }
  91. }
  92. return CreateAndChoosePage::SetData(bSilent);
  93. }
  94. HRESULT
  95. CreateNewSubnetPage::SetData(BOOL bSilent)
  96. {
  97. CNewADsObjectCreateInfo* info = GetWiz()->GetInfo();
  98. ASSERT(info);
  99. HRESULT hr = E_FAIL;
  100. if (!info)
  101. return hr;
  102. int count = ListView_GetItemCount(listview);
  103. if (count > 0)
  104. {
  105. if (0 >= ListView_GetSelectedCount(listview))
  106. {
  107. if (!bSilent)
  108. {
  109. ReportErrorEx (::GetParent(m_hWnd),IDS_NEW_SUBNET_SELECT_SITE,S_OK,
  110. MB_OK, NULL, 0);
  111. }
  112. (void) this->PostMessage( WM_NEXTDLGCTL,
  113. (WPARAM)listview,
  114. TRUE );
  115. return E_FAIL;
  116. }
  117. for (int i = 0; i < count; i++)
  118. {
  119. if (ListView_GetItemState(listview, i, LVIS_SELECTED))
  120. {
  121. LVITEM item = {0};
  122. item.mask = LVIF_PARAM;
  123. item.iItem = i;
  124. if (ListView_GetItem(listview, &item))
  125. {
  126. // the item.lParam field is the dn of the target site
  127. CComBSTR* dn = reinterpret_cast<CComBSTR*>(item.lParam);
  128. hr = info->HrAddVariantBstrIfNotEmpty(
  129. CComBSTR(gsz_siteObject),
  130. *dn,
  131. TRUE ); // HrCreateNew has not been called yet
  132. if ( FAILED(hr) )
  133. {
  134. ASSERT(FALSE);
  135. return hr;
  136. }
  137. // use the first site selected
  138. break;
  139. }
  140. }
  141. }
  142. ASSERT( i < count );
  143. }
  144. return CreateAndChoosePage::SetData(bSilent);
  145. }
  146. HRESULT
  147. CreateNewSitePage::tweakSiteLink(LPCTSTR siteDN)
  148. {
  149. ASSERT(siteDN);
  150. HRESULT hr = S_OK;
  151. do
  152. {
  153. // get the DN of the new site
  154. // this is a pointer alias: no need to AddRef/Release
  155. hr = E_FAIL;
  156. CPathCracker pathCracker;
  157. CCreateNewObjectWizardBase* pwiz = GetWiz();
  158. BREAK_ON_NULL(pwiz);
  159. CNewADsObjectCreateInfo* pinfo = pwiz->GetInfo();
  160. BREAK_ON_NULL(pinfo);
  161. IADs* piadsSite = pinfo->PGetIADsPtr();
  162. BREAK_ON_NULL(piadsSite);
  163. CComBSTR sbstrSitePath;
  164. hr = piadsSite->get_ADsPath( &sbstrSitePath );
  165. BREAK_ON_FAILED_HRESULT(hr);
  166. hr = pathCracker.Set(sbstrSitePath, ADS_SETTYPE_FULL);
  167. BREAK_ON_FAILED_HRESULT(hr);
  168. CComBSTR sbstrSiteDN;
  169. hr = pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
  170. BREAK_ON_FAILED_HRESULT(hr);
  171. hr = pathCracker.Retrieve(ADS_FORMAT_X500_DN, &sbstrSiteDN);
  172. BREAK_ON_FAILED_HRESULT(hr);
  173. // munge together the path name of the site link object
  174. hr = pathCracker.Set( CComBSTR(siteDN), ADS_SETTYPE_DN);
  175. BREAK_ON_FAILED_HRESULT(hr);
  176. CComBSTR sbstrSiteLinkPath;
  177. hr = pathCracker.Retrieve(ADS_FORMAT_X500, &sbstrSiteLinkPath);
  178. BREAK_ON_FAILED_HRESULT(hr);
  179. // bind to the site link
  180. CComPtr<IADs> link;
  181. hr = DSAdminOpenObject(sbstrSiteLinkPath,
  182. IID_IADs,
  183. (void**) &link,
  184. FALSE /*bServer*/);
  185. BREAK_ON_FAILED_HRESULT(hr);
  186. ASSERT(link);
  187. // Add the DN of the new site to the siteList attr of the link object
  188. // build the new value
  189. CComVariant var;
  190. hr = ADsBuildVarArrayStr(&sbstrSiteDN, 1, &var);
  191. BREAK_ON_FAILED_HRESULT(hr);
  192. // write it. whew.
  193. hr =
  194. link->PutEx(
  195. ADS_PROPERTY_APPEND,
  196. CComBSTR(gsz_siteList),
  197. var);
  198. BREAK_ON_FAILED_HRESULT(hr);
  199. hr = link->SetInfo();
  200. BREAK_ON_FAILED_HRESULT(hr);
  201. }
  202. while (0);
  203. if (FAILED(hr))
  204. {
  205. ReportError(hr, IDS_ERROR_TWEAKING_SITE_LINK, m_hWnd);
  206. }
  207. return hr;
  208. }
  209. HRESULT
  210. CreateNewSitePage::OnPostCommit(BOOL bSilent)
  211. {
  212. ASSERT(listview);
  213. int count = ListView_GetItemCount(listview);
  214. // JonN 10/30/01 396946
  215. if (count <= 0)
  216. return S_OK;
  217. for (int i = 0; i < count; i++)
  218. {
  219. if (ListView_GetItemState(listview, i, LVIS_SELECTED))
  220. {
  221. LVITEM item = {0};
  222. item.mask = LVIF_PARAM;
  223. item.iItem = i;
  224. if (ListView_GetItem(listview, &item))
  225. {
  226. // the item.lParam field is the dn of the target link
  227. CComBSTR* dn = reinterpret_cast<CComBSTR*>(item.lParam);
  228. tweakSiteLink(*dn);
  229. // only tweak the first site link selected
  230. return S_OK;
  231. }
  232. }
  233. }
  234. if (!bSilent)
  235. {
  236. ReportMessageEx(
  237. m_hWnd,
  238. IDS_NEWSITE_WARNING,
  239. MB_OK | MB_ICONWARNING,
  240. NULL,
  241. 0,
  242. IDS_WARNING_TITLE);
  243. }
  244. return S_OK;
  245. }
  246. HRESULT
  247. RecursiveFind(const CString& lpcwszADsPathDirectory,
  248. LPCTSTR lpcwszTargetClass,
  249. TargetLinkList& links,
  250. LPWSTR pszAttribute = L"distinguishedName");
  251. HRESULT
  252. RecursiveFind(const CString& lpcwszADsPathDirectory,
  253. LPCTSTR lpcwszTargetClass,
  254. TargetLinkList& links,
  255. LPWSTR pszAttribute)
  256. {
  257. links.clear();
  258. CDSSearch Search;
  259. Search.Init(lpcwszADsPathDirectory);
  260. CString filter;
  261. filter.Format(L"(objectClass=%s)", lpcwszTargetClass);
  262. Search.SetFilterString(const_cast<LPTSTR>((LPCTSTR) filter));
  263. LPWSTR pAttrs[2] =
  264. {
  265. L"name",
  266. pszAttribute
  267. };
  268. Search.SetAttributeList(pAttrs, 2);
  269. Search.SetSearchScope(ADS_SCOPE_SUBTREE);
  270. HRESULT hr = Search.DoQuery();
  271. while (SUCCEEDED(hr))
  272. {
  273. hr = Search.GetNextRow();
  274. if (S_ADS_NOMORE_ROWS == hr)
  275. {
  276. hr = S_OK;
  277. break;
  278. }
  279. BREAK_ON_FAILED_HRESULT(hr);
  280. ADS_SEARCH_COLUMN NameColumn;
  281. ::ZeroMemory(&NameColumn, sizeof(NameColumn));
  282. hr = Search.GetColumn (pAttrs[0], &NameColumn);
  283. BREAK_ON_FAILED_HRESULT(hr);
  284. ASSERT(ADSTYPE_CASE_IGNORE_STRING == NameColumn.pADsValues->dwType);
  285. ADS_SEARCH_COLUMN DistinguishedNameColumn;
  286. ::ZeroMemory(&DistinguishedNameColumn, sizeof(DistinguishedNameColumn));
  287. hr = Search.GetColumn (pAttrs[1], &DistinguishedNameColumn);
  288. BREAK_ON_FAILED_HRESULT(hr);
  289. ASSERT(ADSTYPE_DN_STRING == DistinguishedNameColumn.pADsValues->dwType
  290. || ADSTYPE_CASE_IGNORE_STRING == DistinguishedNameColumn.pADsValues->dwType);
  291. links.push_back(
  292. TargetLinkInfo(
  293. NameColumn.pADsValues->CaseIgnoreString,
  294. DistinguishedNameColumn.pADsValues->DNString));
  295. Search.FreeColumn(&NameColumn);
  296. Search.FreeColumn(&DistinguishedNameColumn);
  297. }
  298. #ifdef DBG
  299. // dump the list to the debugger
  300. for (
  301. TargetLinkList::iterator i = links.begin();
  302. i != links.end();
  303. i++)
  304. {
  305. OutputDebugString(i->first);
  306. OutputDebugString(L"\n");
  307. OutputDebugString(i->second);
  308. OutputDebugString(L"\n");
  309. }
  310. #endif
  311. return hr;
  312. }
  313. BOOL
  314. CreateAndChoosePage::OnSetActive()
  315. {
  316. CComQIPtr<IADs, &IID_IADs> container(GetWiz()->GetInfo()->m_pIADsContainer);
  317. if (container)
  318. {
  319. CComBSTR container_path;
  320. container->get_ADsPath(&container_path);
  321. initListContents(container_path);
  322. }
  323. return Base::OnSetActive();
  324. }
  325. void
  326. destroyListContents(HWND listview)
  327. {
  328. ASSERT(listview);
  329. for (int i = ListView_GetItemCount(listview) - 1; i >= 0; i--)
  330. {
  331. LVITEM item = {0};
  332. item.mask = LVIF_PARAM;
  333. item.iItem = i;
  334. if (ListView_GetItem(listview, &item))
  335. {
  336. ASSERT(item.lParam);
  337. delete reinterpret_cast<CComBSTR*>(item.lParam);
  338. ListView_DeleteItem(listview, i);
  339. return;
  340. }
  341. }
  342. }
  343. void
  344. CreateAndChoosePage::OnDestroy()
  345. {
  346. destroyListContents(listview);
  347. Base::OnDestroy();
  348. }
  349. void
  350. CreateNewSitePage::initListContents(LPCWSTR containerPath)
  351. {
  352. ASSERT(listview);
  353. CWaitCursor cwait;
  354. TargetLinkList links;
  355. bool links_present = false;
  356. HRESULT hr = RecursiveFind(containerPath, gsz_siteLink, links);
  357. if (SUCCEEDED(hr))
  358. {
  359. // walk the list and add nodes
  360. for (
  361. TargetLinkList::iterator i = links.begin();
  362. i != links.end();
  363. i++)
  364. {
  365. LVITEM item = {0};
  366. memset(&item, 0, sizeof(item));
  367. // this is deleted in destroyListContents
  368. CComBSTR* dn = new CComBSTR(i->second);
  369. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  370. item.iItem = 0;
  371. item.iSubItem = 0;
  372. item.pszText = static_cast<LPTSTR>(i->first);
  373. item.lParam = reinterpret_cast<LPARAM>(dn);
  374. item.iImage = 0; // always the same, first image
  375. item.iItem = ListView_InsertItem(listview, &item);
  376. ASSERT(item.iItem >= 0);
  377. // add the transport sub-item to the list control
  378. CPathCracker pathCracker;
  379. hr =
  380. pathCracker.Set(
  381. static_cast<LPTSTR>(i->second),
  382. ADS_SETTYPE_DN);
  383. ASSERT(SUCCEEDED(hr));
  384. hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
  385. ASSERT(SUCCEEDED(hr));
  386. CComBSTR b;
  387. hr = pathCracker.GetElement(1, &b);
  388. ASSERT(SUCCEEDED(hr));
  389. hr = pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
  390. ASSERT(SUCCEEDED(hr));
  391. item.mask = LVIF_TEXT;
  392. item.iSubItem = 1;
  393. item.pszText = b;
  394. ListView_SetItem(listview, &item);
  395. links_present = true;
  396. }
  397. if (!links_present)
  398. {
  399. ReportError(hr, IDS_WARNING_NO_SITE_LINKS, m_hWnd);
  400. }
  401. }
  402. else
  403. {
  404. ReportError(hr, IDS_CANT_FIND_SITE_LINKS, m_hWnd);
  405. }
  406. if (!links_present)
  407. {
  408. GetDlgItem(IDC_LINKS)->EnableWindow(FALSE);
  409. GetDlgItem(IDC_SITE_TEXT)->EnableWindow(FALSE);
  410. }
  411. else // JonN 3/28/01 319675
  412. {
  413. ListView_SetItemState( listview, 0, LVIS_FOCUSED, LVIS_FOCUSED );
  414. }
  415. }
  416. void
  417. CreateNewSubnetPage::initListContents(LPCWSTR containerPath)
  418. {
  419. ASSERT(listview);
  420. CWaitCursor cwait;
  421. TargetLinkList links;
  422. bool links_present = false;
  423. CComBSTR sbstrSites;
  424. CPathCracker pathCracker;
  425. HRESULT hr = pathCracker.Set(
  426. CComBSTR(containerPath),
  427. ADS_SETTYPE_FULL);
  428. if (SUCCEEDED(hr))
  429. hr = pathCracker.RemoveLeafElement();
  430. if (SUCCEEDED(hr))
  431. hr = pathCracker.Retrieve(ADS_FORMAT_X500, &sbstrSites);
  432. if (SUCCEEDED(hr))
  433. hr = RecursiveFind((LPCTSTR)sbstrSites, gsz_site, links);
  434. if (SUCCEEDED(hr))
  435. {
  436. // walk the list and add nodes
  437. for (
  438. TargetLinkList::iterator i = links.begin();
  439. i != links.end();
  440. i++)
  441. {
  442. LVITEM item;
  443. memset(&item, 0, sizeof(item));
  444. // this is deleted in destroyListContents
  445. CComBSTR* dn = new CComBSTR(i->second);
  446. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  447. item.iItem = 0;
  448. item.iSubItem = 0;
  449. item.pszText = static_cast<LPTSTR>(i->first);
  450. item.lParam = reinterpret_cast<LPARAM>(dn);
  451. item.iImage = 0; // always the same, first image
  452. item.iItem = ListView_InsertItem(listview, &item);
  453. ASSERT(item.iItem >= 0);
  454. links_present = true;
  455. }
  456. if (!links_present)
  457. {
  458. ReportError(hr, IDS_NEWSUBNET_WARNING_NO_SITES, m_hWnd);
  459. }
  460. }
  461. else
  462. {
  463. ReportError(hr, IDS_NEWSUBNET_CANT_FIND_SITES, m_hWnd);
  464. }
  465. if (!links_present)
  466. {
  467. GetDlgItem(IDC_LINKS)->EnableWindow(FALSE);
  468. GetDlgItem(IDC_SITE_TEXT)->EnableWindow(FALSE);
  469. }
  470. else // JonN 3/28/01 476589
  471. {
  472. ListView_SetItemState( listview, 0, LVIS_FOCUSED, LVIS_FOCUSED );
  473. }
  474. }
  475. BOOL
  476. CreateNewSitePage::OnInitDialog()
  477. {
  478. Base::OnInitDialog();
  479. MyBasePathsInfo* pBasePathsInfo = GetWiz()->GetInfo()->GetBasePathsInfo();
  480. // NTRAID#NTBUG9-477962-2001/10/09-jeffjon
  481. // Limit the site name to 63 characters to avoid overflow
  482. SendDlgItemMessage(IDC_EDIT_OBJECT_NAME, EM_SETLIMITTEXT, (WPARAM)63, 0);
  483. listview = ::GetDlgItem(m_hWnd, IDC_LINKS);
  484. ASSERT(listview);
  485. LVCOLUMN column = {0};
  486. column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  487. column.fmt = LVCFMT_LEFT;
  488. { // open scope
  489. CString w;
  490. w.LoadString(IDS_NEW_SITE_NAME_COLUMN_WIDTH);
  491. w.TrimLeft();
  492. w.TrimRight();
  493. long width = _tcstol(w, 0, 10);
  494. ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
  495. column.cx = width;
  496. CString label;
  497. label.LoadString(IDS_NEW_SITE_NAME_COLUMN);
  498. column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
  499. ListView_InsertColumn(listview, 0, &column);
  500. } // close scope
  501. // add a column to the list view for parent transport.
  502. { // open scope
  503. CString w;
  504. w.LoadString(IDS_NEW_SITE_XPORT_COLUMN_WIDTH);
  505. w.TrimLeft();
  506. w.TrimRight();
  507. long width = _tcstol(w, 0, 10);
  508. ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
  509. column.cx = width;
  510. CString label;
  511. label.LoadString(IDS_NEW_SITE_XPORT_COLUMN);
  512. column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
  513. ListView_InsertColumn(listview, 1, &column);
  514. } // close scope
  515. // create the image list containing the site link icon
  516. int cx = ::GetSystemMetrics(SM_CXSMICON);
  517. int cy = ::GetSystemMetrics(SM_CYSMICON);
  518. ASSERT(cx && cy);
  519. // deleted in OnDestroy
  520. listview_imagelist = ::ImageList_Create(cx, cy, ILC_MASK, 1, 0);
  521. ASSERT(listview_imagelist);
  522. HICON icon = pBasePathsInfo->GetIcon(
  523. // someone really blew it with const correctness...
  524. const_cast<LPTSTR>(gsz_siteLink),
  525. DSGIF_ISNORMAL | DSGIF_GETDEFAULTICON,
  526. 16,
  527. 16);
  528. ASSERT(icon);
  529. int i = ::ImageList_AddIcon(listview_imagelist, icon);
  530. ASSERT(i != -1);
  531. DestroyIcon(icon);
  532. ListView_SetImageList(listview, listview_imagelist, LVSIL_SMALL);
  533. ListView_SetExtendedListViewStyleEx(
  534. listview,
  535. LVS_EX_FULLROWSELECT,
  536. LVS_EX_FULLROWSELECT);
  537. return TRUE;
  538. }
  539. BOOL
  540. CreateNewSubnetPage::OnInitDialog()
  541. {
  542. Base::OnInitDialog();
  543. MyBasePathsInfo* pBasePathsInfo = GetWiz()->GetInfo()->GetBasePathsInfo();
  544. (void) SendDlgItemMessage( IDC_SUBNET_ADDRESS,
  545. IPM_SETADDRESS,
  546. 0,
  547. (LPARAM)MAKEIPADDRESS(0,0,0,0) );
  548. (void) SendDlgItemMessage( IDC_SUBNET_MASK,
  549. IPM_SETADDRESS,
  550. 0,
  551. (LPARAM)MAKEIPADDRESS(0,0,0,0) );
  552. listview = ::GetDlgItem(m_hWnd, IDC_LINKS);
  553. ASSERT(listview);
  554. { // open scope
  555. LVCOLUMN column = {0};
  556. column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  557. column.fmt = LVCFMT_LEFT;
  558. CString w;
  559. w.LoadString(IDS_COLUMN_SITE_WIDTH);
  560. w.TrimLeft();
  561. w.TrimRight();
  562. long width = _tcstol(w, 0, 10);
  563. ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
  564. column.cx = width;
  565. CString label;
  566. label.LoadString(IDS_COLUMN_SITE_NAME);
  567. column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
  568. ListView_InsertColumn(listview, 0, &column);
  569. } // close scope
  570. // create the image list containing the site link icon
  571. int cx = ::GetSystemMetrics(SM_CXSMICON);
  572. int cy = ::GetSystemMetrics(SM_CYSMICON);
  573. ASSERT(cx && cy);
  574. // deleted in OnDestroy
  575. listview_imagelist = ::ImageList_Create(cx, cy, ILC_MASK, 1, 0);
  576. ASSERT(listview_imagelist);
  577. HICON icon = pBasePathsInfo->GetIcon(
  578. // someone really blew it with const correctness...
  579. const_cast<LPTSTR>(gsz_site),
  580. DSGIF_ISNORMAL | DSGIF_GETDEFAULTICON | DSGIF_DEFAULTISCONTAINER,
  581. 16,
  582. 16);
  583. ASSERT(icon);
  584. int i = ::ImageList_AddIcon(listview_imagelist, icon);
  585. ASSERT(i != -1);
  586. DestroyIcon(icon);
  587. ListView_SetImageList(listview, listview_imagelist, LVSIL_SMALL);
  588. ListView_SetExtendedListViewStyleEx(
  589. listview,
  590. LVS_EX_FULLROWSELECT,
  591. LVS_EX_FULLROWSELECT);
  592. return TRUE;
  593. }
  594. BOOL CreateNewSitePage::ValidateName(LPCTSTR pcszName)
  595. {
  596. BOOL fNonRfcSiteName = FALSE;
  597. // NTRAID#NTBUG9-472020-2002/01/16-ronmart-Added support for new fInvalidChar flag
  598. BOOL fInvalidNameChar = FALSE;
  599. BOOL fValidSiteName = IsValidSiteName( pcszName, &fNonRfcSiteName, &fInvalidNameChar );
  600. if ( !fValidSiteName )
  601. {
  602. // NTRAID#NTBUG9-472020-2002/01/16-ronmart-Display new error message if invalid char
  603. if ( fInvalidNameChar )
  604. {
  605. ReportErrorEx (::GetParent(m_hWnd),IDS_SITE_INVALID_NAME_CHAR,S_OK,
  606. MB_OK, NULL, 0);
  607. }
  608. // NTRAID#NTBUG9-472020-2002/01/16-ronmart-otherwise display the old (but updated) error msg
  609. else
  610. {
  611. ReportErrorEx (::GetParent(m_hWnd),IDS_SITE_NAME,S_OK,
  612. MB_OK, NULL, 0);
  613. }
  614. }
  615. else if ( fNonRfcSiteName )
  616. {
  617. PVOID apv[1];
  618. apv[0] = (PVOID)pcszName;
  619. if (IDYES != ReportMessageEx( ::GetParent(m_hWnd),
  620. IDS_1_NON_RFC_SITE_NAME,
  621. MB_YESNO | MB_ICONWARNING,
  622. apv,
  623. 1 ) )
  624. {
  625. fValidSiteName = FALSE;
  626. }
  627. }
  628. if ( !fValidSiteName )
  629. {
  630. // Yes, this really does have to be PostMessage, SendMessage doesn't work
  631. // It also has to come after ReportErrorEx or else it doesn't work
  632. (void) this->PostMessage( WM_NEXTDLGCTL,
  633. (WPARAM)::GetDlgItem(m_hWnd, IDC_EDIT_OBJECT_NAME),
  634. TRUE );
  635. (void) ::PostMessage( ::GetDlgItem(m_hWnd, IDC_EDIT_OBJECT_NAME), EM_SETSEL, 0, -1 );
  636. return FALSE;
  637. }
  638. return TRUE;
  639. }
  640. // JonN 5/11/01 251560 Disable OK until site link chosen
  641. BEGIN_MESSAGE_MAP(CreateNewSitePage, CreateAndChoosePage)
  642. ON_EN_CHANGE(IDC_EDIT_OBJECT_NAME, OnChange)
  643. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LINKS, OnSelChange)
  644. END_MESSAGE_MAP()
  645. afx_msg void CreateNewSitePage::OnSelChange( NMHDR*, LRESULT* )
  646. {
  647. OnChange();
  648. }
  649. void CreateNewSitePage::OnChange()
  650. {
  651. // JonN 10/22/01 396946
  652. // New Site creation dialog box is launched even if there is no sitelink
  653. // and launched dialog has no function
  654. if ( (0 < ListView_GetItemCount(listview))
  655. && (0 >= ListView_GetSelectedCount(listview)))
  656. {
  657. GetWiz()->SetWizardButtons(this, FALSE);
  658. }
  659. else
  660. OnNameChange(); // Enable the OK button only if the name is not empty
  661. }
  662. // no need to validate subnet name, MapMaskAndAddress does this
  663. // return -32 for invalid mask
  664. int CountBits( DWORD dwOctet )
  665. {
  666. if ( 0xff < dwOctet )
  667. {
  668. ASSERT(FALSE);
  669. return -32;
  670. }
  671. for (int nBits = 0; dwOctet & 0x80; nBits++)
  672. dwOctet = (dwOctet & ~0x80) * 2;
  673. if (dwOctet != 0)
  674. return -32; // hole in the mask
  675. return nBits;
  676. }
  677. // returns <0 for invalid mask
  678. int CountMaskedBits( DWORD dwMask )
  679. {
  680. int nFirstOctet = FIRST_IPADDRESS(dwMask);
  681. int nSecondOctet = SECOND_IPADDRESS(dwMask);
  682. int nThirdOctet = THIRD_IPADDRESS(dwMask);
  683. int nFourthOctet = FOURTH_IPADDRESS(dwMask);
  684. if (nFirstOctet < 255)
  685. {
  686. if (0 != nSecondOctet || 0 != nThirdOctet || 0 != nFourthOctet)
  687. return -1;
  688. return CountBits(nFirstOctet);
  689. }
  690. if (nSecondOctet < 255)
  691. {
  692. if (255 != nFirstOctet || 0 != nThirdOctet || 0 != nFourthOctet)
  693. return -1;
  694. return 8 + CountBits(nSecondOctet);
  695. }
  696. if (nThirdOctet < 255)
  697. {
  698. if (255 != nFirstOctet || 255 != nSecondOctet || 0 != nFourthOctet)
  699. return -1;
  700. return 16 + CountBits(nThirdOctet);
  701. }
  702. if (255 != nFirstOctet || 255 != nSecondOctet || 255 != nThirdOctet)
  703. return -1;
  704. return 24 + CountBits(nFourthOctet);
  705. }
  706. // returns empty string for invalid address+mask
  707. void MapMaskAndAddress(
  708. OUT CString& strrefSubnetName,
  709. IN DWORD dwAddress,
  710. IN DWORD dwMask )
  711. {
  712. strrefSubnetName.Empty();
  713. dwAddress &= dwMask; // clear all bits set in the address and not in the mask
  714. int nMaskedBits = CountMaskedBits( dwMask );
  715. if (0 > nMaskedBits)
  716. return; // invalid mask
  717. strrefSubnetName.Format(L"%d.%d.%d.%d/%d",
  718. FIRST_IPADDRESS(dwAddress),
  719. SECOND_IPADDRESS(dwAddress),
  720. THIRD_IPADDRESS(dwAddress),
  721. FOURTH_IPADDRESS(dwAddress),
  722. nMaskedBits);
  723. // final test for edge cases such as "0.0.0.0/0"
  724. if (ERROR_SUCCESS != ::DsValidateSubnetName( strrefSubnetName ))
  725. strrefSubnetName.Empty();
  726. }
  727. void CreateNewSubnetPage::OnSubnetMaskChange()
  728. {
  729. DWORD dwAddress, dwMask;
  730. CString strSubnetName;
  731. // IPM_GETADDRESS returns the number of octets filled in. Address is
  732. // invalid if any of the four is left blank.
  733. if ( 4 == SendDlgItemMessage( IDC_SUBNET_ADDRESS,
  734. IPM_GETADDRESS,
  735. 0,
  736. (LPARAM)&dwAddress )
  737. && 4 == SendDlgItemMessage( IDC_SUBNET_MASK,
  738. IPM_GETADDRESS,
  739. 0,
  740. (LPARAM)&dwMask ) )
  741. {
  742. MapMaskAndAddress( strSubnetName, dwAddress, dwMask );
  743. }
  744. SetDlgItemText(IDC_EDIT_OBJECT_NAME, strSubnetName);
  745. OnNameChange();
  746. }
  747. BEGIN_MESSAGE_MAP(CMoveServerDialog, CDialog)
  748. //{{AFX_MSG_MAP(CMoveServerDialog)
  749. ON_WM_DESTROY()
  750. ON_NOTIFY(NM_DBLCLK, IDC_LINKS, OnDblclkListview)
  751. //}}AFX_MSG_MAP
  752. END_MESSAGE_MAP()
  753. CMoveServerDialog::CMoveServerDialog(LPCTSTR lpcszBrowseRootPath, HICON hIcon, CWnd* pParent /*=NULL*/)
  754. : CDialog(CMoveServerDialog::IDD, pParent)
  755. , m_strTargetContainer()
  756. , m_strBrowseRootPath(lpcszBrowseRootPath)
  757. , m_hIcon(hIcon)
  758. , listview(0)
  759. , listview_imagelist(0)
  760. {}
  761. BOOL
  762. CMoveServerDialog::OnInitDialog()
  763. {
  764. CDialog::OnInitDialog();
  765. CWaitCursor cwait;
  766. listview = ::GetDlgItem(m_hWnd, IDC_LINKS);
  767. ASSERT(listview);
  768. { // open scope
  769. LVCOLUMN column = {0};
  770. column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  771. column.fmt = LVCFMT_LEFT;
  772. CString w;
  773. w.LoadString(IDS_COLUMN_SITE_WIDTH);
  774. w.TrimLeft();
  775. w.TrimRight();
  776. long width = _tcstol(w, 0, 10);
  777. ASSERT(width != 0 && width != LONG_MAX && width != LONG_MIN);
  778. column.cx = width;
  779. CString label;
  780. label.LoadString(IDS_COLUMN_SITE_NAME);
  781. column.pszText = const_cast<LPTSTR>((LPCTSTR) label);
  782. ListView_InsertColumn(listview, 0, &column);
  783. } // close scope
  784. // create the image list containing the site link icon
  785. int cx = ::GetSystemMetrics(SM_CXSMICON);
  786. int cy = ::GetSystemMetrics(SM_CYSMICON);
  787. ASSERT(cx && cy);
  788. // deleted in OnDestroy
  789. listview_imagelist = ::ImageList_Create(cx, cy, ILC_MASK, 1, 0);
  790. ASSERT(listview_imagelist);
  791. ASSERT(m_hIcon != NULL);
  792. int i = ::ImageList_AddIcon(listview_imagelist, m_hIcon);
  793. ASSERT(i != -1);
  794. ListView_SetImageList(listview, listview_imagelist, LVSIL_SMALL);
  795. ListView_SetExtendedListViewStyleEx(
  796. listview,
  797. LVS_EX_FULLROWSELECT,
  798. LVS_EX_FULLROWSELECT);
  799. // add sites to listview
  800. TargetLinkList links;
  801. bool links_present = false;
  802. HRESULT hr = RecursiveFind(m_strBrowseRootPath, gsz_serversContainer, links, L"aDSPath");
  803. if (SUCCEEDED(hr))
  804. {
  805. // walk the list and add nodes
  806. for (
  807. TargetLinkList::iterator itr = links.begin();
  808. itr != links.end();
  809. ++itr)
  810. {
  811. LVITEM item;
  812. memset(&item, 0, sizeof(item));
  813. // Since the enumerated objects are of type serversContainer,
  814. // we display the name of the parent. Also, the aDSPath attribute may
  815. // contain a server indication, which must be removed.
  816. CPathCracker pathCracker;
  817. hr = pathCracker.Set( itr->second, ADS_SETTYPE_FULL );
  818. BREAK_ON_FAILED_HRESULT(hr);
  819. hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
  820. BREAK_ON_FAILED_HRESULT(hr);
  821. CComBSTR sbstrName;
  822. hr = pathCracker.GetElement( 1L, &sbstrName );
  823. BREAK_ON_FAILED_HRESULT(hr);
  824. hr = pathCracker.SetDisplayType(ADS_DISPLAY_FULL);
  825. BREAK_ON_FAILED_HRESULT(hr);
  826. CComBSTR sbstrDN;
  827. hr = pathCracker.Retrieve( ADS_FORMAT_X500, &sbstrDN );
  828. BREAK_ON_FAILED_HRESULT(hr);
  829. // this is deleted in destroyListContents
  830. CComBSTR* dn = new CComBSTR(sbstrDN);
  831. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  832. item.iItem = 0;
  833. item.iSubItem = 0;
  834. item.pszText = static_cast<LPTSTR>(sbstrName);
  835. item.lParam = reinterpret_cast<LPARAM>(dn);
  836. item.iImage = 0; // always the same, first image
  837. item.iItem = ListView_InsertItem(listview, &item);
  838. ASSERT(item.iItem >= 0);
  839. links_present = true;
  840. }
  841. if (!links_present)
  842. {
  843. ReportError(hr, IDS_MOVESERVER_ERROR_NO_SITES, m_hWnd);
  844. OnCancel();
  845. }
  846. }
  847. if ( FAILED(hr) )
  848. {
  849. ReportError(hr, IDS_MOVESERVER_ERROR_ENUMERATING_SITES, m_hWnd);
  850. OnCancel();
  851. }
  852. return TRUE; // return TRUE unless you set the focus to a control
  853. // EXCEPTION: OCX Property Pages should return FALSE
  854. }
  855. void
  856. CMoveServerDialog::OnDestroy()
  857. {
  858. destroyListContents(listview);
  859. CDialog::OnDestroy();
  860. }
  861. void CMoveServerDialog::OnOK()
  862. {
  863. int count = ListView_GetItemCount(listview);
  864. if (count > 0)
  865. {
  866. if (0 >= ListView_GetSelectedCount(listview))
  867. {
  868. ReportErrorEx (m_hWnd,IDS_MOVESERVER_SELECT_SITE,S_OK,
  869. MB_OK, NULL, 0);
  870. (void) this->PostMessage( WM_NEXTDLGCTL,
  871. (WPARAM)listview,
  872. TRUE );
  873. return;
  874. }
  875. for (int i = 0; i < count; i++)
  876. {
  877. if (ListView_GetItemState(listview, i, LVIS_SELECTED))
  878. {
  879. LVITEM item = {0};
  880. item.mask = LVIF_PARAM;
  881. item.iItem = i;
  882. if (ListView_GetItem(listview, &item))
  883. {
  884. // the item.lParam field is the dn of the target site
  885. CComBSTR* dn = reinterpret_cast<CComBSTR*>(item.lParam);
  886. m_strTargetContainer = *dn;
  887. // use the first site selected
  888. break;
  889. }
  890. }
  891. }
  892. ASSERT( i < count );
  893. }
  894. CDialog::OnOK();
  895. }
  896. void CMoveServerDialog::OnDblclkListview(NMHDR*, LRESULT*)
  897. {
  898. OnOK();
  899. }
  900. // NTRAID#NTBUG9-251563-2001/05/15-sburns
  901. void CreateNewSiteWizard::OnFinishSetInfoFailed(HRESULT hr)
  902. {
  903. // let the base class report the error to the user
  904. CCreateNewObjectWizardBase::OnFinishSetInfoFailed(hr);
  905. // set focus back to the name field on the page.
  906. // Yes, this really does have to be PostMessage, SendMessage doesn't work
  907. // It also has to come after ReportErrorEx or else it doesn't work
  908. ::PostMessage(
  909. page.m_hWnd,
  910. WM_NEXTDLGCTL,
  911. (WPARAM) ::GetDlgItem(page.m_hWnd, IDC_EDIT_OBJECT_NAME),
  912. TRUE );
  913. }