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.

1452 lines
43 KiB

  1. /*++
  2. Module Name:
  3. DfsWiz.cpp
  4. Abstract:
  5. This module contains the implementation for CCreateDfsRootWizPage1, 2, 3, 4, 5, 6.
  6. These classes implement pages in the CreateDfs Root wizard.
  7. --*/
  8. #include "stdafx.h"
  9. #include "resource.h" // To be able to use the resource symbols
  10. #include "DfsEnums.h" // for common enums, typedefs, etc
  11. #include "NetUtils.h"
  12. #include "ldaputils.h"
  13. #include "Utils.h" // For the LoadStringFromResource method
  14. #include "dfswiz.h" // For Ds Query Dialog
  15. #include <shlobj.h>
  16. #include <dsclient.h>
  17. #include <initguid.h>
  18. #include <cmnquery.h>
  19. #include <dsquery.h>
  20. #include <lmdfs.h>
  21. #include <iads.h>
  22. #include <icanon.h>
  23. #include <dns.h>
  24. HRESULT
  25. ValidateFolderPath(
  26. IN LPCTSTR lpszServer,
  27. IN LPCTSTR lpszPath
  28. );
  29. // ----------------------------------------------------------------------------
  30. // CCreateDfsRootWizPage1: Welcome page
  31. CCreateDfsRootWizPage1::CCreateDfsRootWizPage1(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  32. : CQWizardPageImpl<CCreateDfsRootWizPage1>(false),
  33. m_lpWizInfo(i_lpWizInfo)
  34. {
  35. }
  36. BOOL
  37. CCreateDfsRootWizPage1::OnSetActive()
  38. {
  39. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_NEXT);
  40. ::SetControlFont(m_lpWizInfo->hBigBoldFont, m_hWnd, IDC_WELCOME_BIG_TITLE);
  41. ::SetControlFont(m_lpWizInfo->hBoldFont, m_hWnd, IDC_WELCOME_SMALL_TITLE);
  42. return TRUE;
  43. }
  44. // ----------------------------------------------------------------------------
  45. // CCreateDfsRootWizPage2: Dfsroot type selection
  46. CCreateDfsRootWizPage2::CCreateDfsRootWizPage2(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  47. : CQWizardPageImpl<CCreateDfsRootWizPage2>(true),
  48. m_lpWizInfo(i_lpWizInfo)
  49. {
  50. CComBSTR bstrTitle;
  51. LoadStringFromResource(IDS_WIZ_PAGE2_TITLE, &bstrTitle);
  52. SetHeaderTitle(bstrTitle);
  53. CComBSTR bstrSubTitle;
  54. LoadStringFromResource(IDS_WIZ_PAGE2_SUBTITLE, &bstrSubTitle);
  55. SetHeaderSubTitle(bstrSubTitle);
  56. }
  57. BOOL
  58. CCreateDfsRootWizPage2::OnSetActive()
  59. {
  60. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
  61. if (DFS_TYPE_UNASSIGNED == m_lpWizInfo->DfsType)
  62. {
  63. CheckRadioButton(IDC_RADIO_FTDFSROOT, IDC_RADIO_STANDALONE_DFSROOT, IDC_RADIO_FTDFSROOT);
  64. m_lpWizInfo->DfsType = DFS_TYPE_FTDFS;
  65. }
  66. return TRUE;
  67. }
  68. BOOL
  69. CCreateDfsRootWizPage2::OnWizardNext()
  70. {
  71. m_lpWizInfo->DfsType = (IsDlgButtonChecked(IDC_RADIO_FTDFSROOT) ? DFS_TYPE_FTDFS : DFS_TYPE_STANDALONE);
  72. return TRUE;
  73. }
  74. BOOL
  75. CCreateDfsRootWizPage2::OnWizardBack()
  76. {
  77. m_lpWizInfo->DfsType = DFS_TYPE_UNASSIGNED; // Reset the dfsroot type
  78. return TRUE;
  79. }
  80. // ----------------------------------------------------------------------------
  81. // CCreateDfsRootWizPage3: Domain selection
  82. CCreateDfsRootWizPage3::CCreateDfsRootWizPage3(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  83. : CQWizardPageImpl<CCreateDfsRootWizPage3>(true),
  84. m_lpWizInfo(i_lpWizInfo)
  85. {
  86. CComBSTR bstrTitle;
  87. LoadStringFromResource(IDS_WIZ_PAGE3_TITLE, &bstrTitle);
  88. SetHeaderTitle(bstrTitle);
  89. CComBSTR bstrSubTitle;
  90. LoadStringFromResource(IDS_WIZ_PAGE3_SUBTITLE, &bstrSubTitle);
  91. SetHeaderSubTitle(bstrSubTitle);
  92. }
  93. BOOL
  94. CCreateDfsRootWizPage3::OnSetActive()
  95. {
  96. // Skip this page for standalone dfs roots
  97. if (DFS_TYPE_STANDALONE == m_lpWizInfo->DfsType)
  98. return FALSE;
  99. CWaitCursor WaitCursor;
  100. SetDefaultValues();
  101. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
  102. return TRUE;
  103. }
  104. HRESULT
  105. CCreateDfsRootWizPage3::SetDefaultValues()
  106. {
  107. if (NULL == m_lpWizInfo->bstrSelectedDomain)
  108. {
  109. // Page is displayed for the first time, Set domain to current domain
  110. CComBSTR bstrDomain;
  111. HRESULT hr = GetServerInfo(NULL, &bstrDomain);
  112. if (S_OK == hr && S_OK == Is50Domain(bstrDomain))
  113. {
  114. m_lpWizInfo->bstrSelectedDomain = bstrDomain.Detach();
  115. }
  116. }
  117. SetDlgItemText(IDC_EDIT_SELECTED_DOMAIN,
  118. m_lpWizInfo->bstrSelectedDomain ? m_lpWizInfo->bstrSelectedDomain : _T(""));
  119. // select the matching item in the listbox
  120. HWND hwndList = GetDlgItem(IDC_LIST_DOMAINS);
  121. if ( ListView_GetItemCount(hwndList) > 0)
  122. {
  123. int nIndex = -1;
  124. if (m_lpWizInfo->bstrSelectedDomain)
  125. {
  126. TCHAR szText[DNS_MAX_NAME_BUFFER_LENGTH];
  127. while (-1 != (nIndex = ListView_GetNextItem(hwndList, nIndex, LVNI_ALL)))
  128. {
  129. ListView_GetItemText(hwndList, nIndex, 0, szText, DNS_MAX_NAME_BUFFER_LENGTH);
  130. if (!lstrcmpi(m_lpWizInfo->bstrSelectedDomain, szText))
  131. {
  132. ListView_SetItemState(hwndList, nIndex, LVIS_SELECTED | LVIS_FOCUSED, 0xffffffff);
  133. ListView_Update(hwndList, nIndex);
  134. break;
  135. }
  136. }
  137. }
  138. if (-1 == nIndex)
  139. {
  140. ListView_SetItemState(hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, 0xffffffff);
  141. ListView_Update(hwndList, 0);
  142. }
  143. }
  144. return S_OK;
  145. }
  146. BOOL
  147. CCreateDfsRootWizPage3::OnWizardNext()
  148. {
  149. CWaitCursor WaitCursor;
  150. DWORD dwTextLength = 0;
  151. CComBSTR bstrCurrentText;
  152. HRESULT hr = GetInputText(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN), &bstrCurrentText, &dwTextLength);
  153. if (FAILED(hr))
  154. {
  155. DisplayMessageBoxForHR(hr);
  156. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN));
  157. return FALSE;
  158. } else if (0 == dwTextLength)
  159. {
  160. DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
  161. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN));
  162. return FALSE;
  163. }
  164. CComBSTR bstrDnsDomain;
  165. hr = Is50Domain(bstrCurrentText, &bstrDnsDomain);
  166. if (S_OK != hr)
  167. { // Error message on incorrect domain.
  168. DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_MSG_INCORRECT_DOMAIN, bstrCurrentText);
  169. return FALSE;
  170. }
  171. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedDomain);
  172. m_lpWizInfo->bstrSelectedDomain = bstrDnsDomain.Detach();
  173. return TRUE;
  174. }
  175. BOOL
  176. CCreateDfsRootWizPage3::OnWizardBack()
  177. {
  178. SetDlgItemText(IDC_EDIT_SELECTED_DOMAIN, _T("")); // Set edit box to empty
  179. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedDomain);
  180. return TRUE;
  181. }
  182. LRESULT
  183. CCreateDfsRootWizPage3::OnNotify(
  184. IN UINT i_uMsg,
  185. IN WPARAM i_wParam,
  186. IN LPARAM i_lParam,
  187. IN OUT BOOL& io_bHandled
  188. )
  189. {
  190. io_bHandled = FALSE; // So that the base class gets this notify too
  191. NMHDR* pNMHDR = (NMHDR*)i_lParam;
  192. if (!pNMHDR || IDC_LIST_DOMAINS != pNMHDR->idFrom) // We need to handle notifies only to the LV
  193. return TRUE;
  194. switch(pNMHDR->code)
  195. {
  196. case LVN_ITEMCHANGED:
  197. case NM_CLICK:
  198. {
  199. OnItemChanged(((NM_LISTVIEW *)i_lParam)->iItem);
  200. return 0; // Should be returning 0
  201. }
  202. case NM_DBLCLK: // Double click event
  203. {
  204. OnItemChanged(((NM_LISTVIEW *)i_lParam)->iItem);
  205. if (0 <= ((NM_LISTVIEW *)i_lParam)->iItem)
  206. ::PropSheet_PressButton(GetParent(), PSBTN_NEXT);
  207. break;
  208. }
  209. default:
  210. break;
  211. }
  212. return TRUE;
  213. }
  214. BOOL
  215. CCreateDfsRootWizPage3::OnItemChanged(IN INT i_iItem)
  216. /*++
  217. Routine Description:
  218. Handles item change notify. Change the edit box content to the current LV
  219. selection
  220. Arguments:
  221. i_iItem - Selected Item number of the LV.
  222. --*/
  223. {
  224. CComBSTR bstrDomain;
  225. HRESULT hr = GetListViewItemText(GetDlgItem(IDC_LIST_DOMAINS), i_iItem, &bstrDomain);
  226. if ((S_OK == hr) && (BSTR)bstrDomain)
  227. SetDlgItemText(IDC_EDIT_SELECTED_DOMAIN, bstrDomain);
  228. return TRUE;
  229. }
  230. LRESULT
  231. CCreateDfsRootWizPage3::OnInitDialog(
  232. IN UINT i_uMsg,
  233. IN WPARAM i_wParam,
  234. IN LPARAM i_lParam,
  235. IN OUT BOOL& io_bHandled
  236. )
  237. {
  238. CWaitCursor WaitCursor;
  239. ::SendMessage(GetDlgItem(IDC_EDIT_SELECTED_DOMAIN), EM_LIMITTEXT, DNSNAMELIMIT, 0);
  240. HIMAGELIST hImageList = NULL;
  241. int nIconIDs[] = {IDI_16x16_DOMAIN};
  242. HRESULT hr = CreateSmallImageList(
  243. _Module.GetResourceInstance(),
  244. nIconIDs,
  245. sizeof(nIconIDs) / sizeof(nIconIDs[0]),
  246. &hImageList);
  247. if (SUCCEEDED(hr))
  248. {
  249. // The current image list will be destroyed when the list-view control
  250. // is destroyed unless the LVS_SHAREIMAGELISTS style is set. If you
  251. // use this message to replace one image list with another, your
  252. // application must explicitly destroy all image lists other than
  253. // the current one.
  254. HWND hwndDomainList = GetDlgItem(IDC_LIST_DOMAINS);
  255. ListView_SetImageList(hwndDomainList, hImageList, LVSIL_SMALL);
  256. AddDomainsToList(hwndDomainList); // Add domains to the list view
  257. }
  258. return TRUE;
  259. }
  260. HRESULT
  261. CCreateDfsRootWizPage3::AddDomainsToList(IN HWND i_hImageList)
  262. {
  263. RETURN_INVALIDARG_IF_NULL(i_hImageList);
  264. NETNAMELIST ListOf50Domains;
  265. HRESULT hr = Get50Domains(&ListOf50Domains); // Get all the domains
  266. if (S_OK != hr)
  267. return hr;
  268. // Add domains to the LV
  269. for(NETNAMELIST::iterator i = ListOf50Domains.begin(); i != ListOf50Domains.end(); i++)
  270. {
  271. if ((*i)->bstrNetName)
  272. InsertIntoListView(i_hImageList, (*i)->bstrNetName);
  273. }
  274. if (!ListOf50Domains.empty())
  275. {
  276. for (NETNAMELIST::iterator i = ListOf50Domains.begin(); i != ListOf50Domains.end(); i++)
  277. {
  278. delete (*i);
  279. }
  280. ListOf50Domains.erase(ListOf50Domains.begin(), ListOf50Domains.end());
  281. }
  282. return S_OK;
  283. }
  284. // ----------------------------------------------------------------------------
  285. // CCreateDfsRootWizPage4: Server selection
  286. CCreateDfsRootWizPage4::CCreateDfsRootWizPage4(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  287. : CQWizardPageImpl<CCreateDfsRootWizPage4>(true),
  288. m_lpWizInfo(i_lpWizInfo),
  289. m_cfDsObjectNames(NULL)
  290. {
  291. CComBSTR bstrTitle;
  292. LoadStringFromResource(IDS_WIZ_PAGE4_TITLE, &bstrTitle);
  293. SetHeaderTitle(bstrTitle);
  294. CComBSTR bstrSubTitle;
  295. LoadStringFromResource(IDS_WIZ_PAGE4_SUBTITLE, &bstrSubTitle);
  296. SetHeaderSubTitle(bstrSubTitle);
  297. }
  298. BOOL
  299. CCreateDfsRootWizPage4::OnSetActive()
  300. {
  301. CWaitCursor WaitCursor;
  302. ::SendMessage(GetDlgItem(IDC_EDIT_SELECTED_SERVER), EM_LIMITTEXT, DNSNAMELIMIT, 0);
  303. if (DFS_TYPE_STANDALONE == m_lpWizInfo->DfsType)
  304. {
  305. // Standalone Setup, set domain to current domain.
  306. CComBSTR bstrDomain;
  307. HRESULT hr = GetServerInfo(NULL, &bstrDomain);
  308. if (S_OK == hr)
  309. m_lpWizInfo->bstrSelectedDomain = bstrDomain.Detach();
  310. }
  311. // Is50Domain will call DsGetDCName which is too slow in case of standalone server.
  312. // To improve the performance, we should always enable the Browse button, and report
  313. // error if user clicks the button.
  314. ::EnableWindow(GetDlgItem(IDCSERVERS_BROWSE), m_lpWizInfo->bstrSelectedDomain && *m_lpWizInfo->bstrSelectedDomain);
  315. SetDlgItemText(IDC_EDIT_SELECTED_SERVER, m_lpWizInfo->bstrSelectedServer ? m_lpWizInfo->bstrSelectedServer : _T(""));
  316. if (m_lpWizInfo->bRootReplica) // If a root replica is being added
  317. {
  318. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_NEXT);
  319. ::ShowWindow(GetDlgItem(IDC_SERVER_SHARE_LABEL), SW_NORMAL);
  320. ::ShowWindow(GetDlgItem(IDC_SERVER_SHARE), SW_NORMAL);
  321. SetDlgItemText(IDC_SERVER_SHARE, m_lpWizInfo->bstrDfsRootName);
  322. } else
  323. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
  324. return TRUE;
  325. }
  326. BOOL
  327. CCreateDfsRootWizPage4::OnWizardNext()
  328. {
  329. CWaitCursor WaitCursor;
  330. HRESULT hr = S_OK;
  331. DWORD dwTextLength = 0;
  332. CComBSTR bstrCurrentText;
  333. hr = GetInputText(GetDlgItem(IDC_EDIT_SELECTED_SERVER), &bstrCurrentText, &dwTextLength);
  334. if (FAILED(hr))
  335. {
  336. DisplayMessageBoxForHR(hr);
  337. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  338. return FALSE;
  339. } else if (0 == dwTextLength)
  340. {
  341. DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
  342. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  343. return FALSE;
  344. }
  345. // I_NetNameValidate will fail with \\server,
  346. // hence, removing the whackwhack when passing it to this validation api.
  347. PTSTR p = bstrCurrentText;
  348. if (!mylstrncmpi(p, _T("\\\\"), 2))
  349. p += 2;
  350. if (I_NetNameValidate(0, p, NAMETYPE_COMPUTER, 0))
  351. {
  352. DisplayMessageBoxWithOK(IDS_MSG_INVALID_SERVER_NAME, bstrCurrentText);
  353. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  354. return FALSE;
  355. }
  356. // remove the ending dot
  357. if (bstrCurrentText[dwTextLength - 1] == _T('.'))
  358. bstrCurrentText[dwTextLength - 1] = _T('\0');
  359. CComBSTR bstrComputerName;
  360. hr = CheckUserEnteredValues(bstrCurrentText, &bstrComputerName);
  361. if (S_OK != hr) // If server is not a valid one. The above function has already displayed the message
  362. {
  363. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  364. return FALSE;
  365. }
  366. if (m_lpWizInfo->bRootReplica)
  367. {
  368. hr = CheckShare(bstrCurrentText, m_lpWizInfo->bstrDfsRootName, &m_lpWizInfo->bShareExists);
  369. if (FAILED(hr))
  370. {
  371. DisplayMessageBoxForHR(hr);
  372. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  373. return FALSE;
  374. } else if (S_FALSE == hr)
  375. {
  376. DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOGOOD, m_lpWizInfo->bstrDfsRootName);
  377. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  378. return FALSE;
  379. }
  380. if (m_lpWizInfo->bPostW2KVersion && m_lpWizInfo->bShareExists && !CheckReparsePoint(bstrCurrentText, m_lpWizInfo->bstrDfsRootName))
  381. {
  382. DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOTNTFS5, m_lpWizInfo->bstrDfsRootName);
  383. ::SetFocus(GetDlgItem(IDC_EDIT_SELECTED_SERVER));
  384. return FALSE;
  385. }
  386. }
  387. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedServer);
  388. m_lpWizInfo->bstrSelectedServer = bstrComputerName.Detach();
  389. return TRUE;
  390. }
  391. // S_OK: Yes, it belongs to the selected domain
  392. // S_FALSE: No, it does not belong to the selected domain
  393. // hr: other errors
  394. HRESULT
  395. CCreateDfsRootWizPage4::IsServerInDomain(IN LPCTSTR lpszServer)
  396. {
  397. if (DFS_TYPE_FTDFS != m_lpWizInfo->DfsType)
  398. return S_OK;
  399. CComBSTR bstrActualDomain;
  400. HRESULT hr = GetServerInfo((LPTSTR)lpszServer, &bstrActualDomain);
  401. if (S_OK == hr)
  402. {
  403. if (!lstrcmpi(bstrActualDomain, m_lpWizInfo->bstrSelectedDomain))
  404. hr = S_OK;
  405. else
  406. hr = S_FALSE;
  407. }
  408. return hr;
  409. }
  410. HRESULT IsHostingDfsRootEx(IN BSTR i_bstrServer, IN BSTR i_bstrRootEntryPath)
  411. {
  412. if (!i_bstrServer || !*i_bstrServer || !i_bstrRootEntryPath || !*i_bstrRootEntryPath)
  413. return E_INVALIDARG;
  414. int len = lstrlen(i_bstrServer);
  415. DFS_INFO_3* pDfsInfo = NULL;
  416. NET_API_STATUS dwRet = NetDfsGetInfo(
  417. i_bstrRootEntryPath,
  418. NULL,
  419. NULL,
  420. 3,
  421. (LPBYTE *)&pDfsInfo);
  422. dfsDebugOut((_T("NetDfsGetInfo entry=%s, level 3 for IsHostingDfsRootEx, nRet=%d\n"),
  423. i_bstrRootEntryPath, dwRet));
  424. if (ERROR_NO_MORE_ITEMS == dwRet || ERROR_NOT_FOUND == dwRet)
  425. return S_FALSE;
  426. HRESULT hr = S_FALSE;
  427. if (NERR_Success == dwRet)
  428. {
  429. if (pDfsInfo->NumberOfStorages > 0)
  430. {
  431. LPDFS_STORAGE_INFO pStorage = pDfsInfo->Storage;
  432. for (DWORD i = 0; i < pDfsInfo->NumberOfStorages; i++)
  433. {
  434. //
  435. // We're doing simple comparison here.
  436. // In case of one server is IP address or a different name of the same machine,
  437. // we'll just leave it to Dfs API.
  438. //
  439. int lenServer = lstrlen(pStorage[i].ServerName);
  440. if (lenServer == len)
  441. {
  442. if (!lstrcmpi(pStorage[i].ServerName, i_bstrServer))
  443. {
  444. hr = S_OK;
  445. break;
  446. }
  447. } else
  448. {
  449. //
  450. // consider one is Netbios, the other is DNS
  451. //
  452. PTSTR pszLong = NULL;
  453. PTSTR pszShort = NULL;
  454. int minLen = 0;
  455. if (lenServer > len)
  456. {
  457. pszLong = pStorage[i].ServerName;
  458. pszShort = i_bstrServer;
  459. minLen = len;
  460. } else
  461. {
  462. pszShort = pStorage[i].ServerName;
  463. pszLong = i_bstrServer;
  464. minLen = lenServer;
  465. }
  466. if (!mylstrncmpi(pszLong, pszShort, minLen) && pszLong[minLen] == _T('.'))
  467. {
  468. hr = S_OK;
  469. break;
  470. }
  471. }
  472. }
  473. }
  474. NetApiBufferFree(pDfsInfo);
  475. } else
  476. {
  477. hr = HRESULT_FROM_WIN32(dwRet);
  478. }
  479. return hr;
  480. }
  481. HRESULT
  482. CCreateDfsRootWizPage4::CheckUserEnteredValues(
  483. IN LPCTSTR i_szMachineName,
  484. OUT BSTR* o_pbstrComputerName
  485. )
  486. /*++
  487. Routine Description:
  488. Checks the value that user has given for this page.
  489. This is done typically on "Next" key being pressed.
  490. Check, if the machine name is a server that is NT 5.0, belongs to
  491. the domain previously selected and is running dfs service.
  492. Arguments:
  493. i_szMachineName - Machine name given by the user
  494. --*/
  495. {
  496. RETURN_INVALIDARG_IF_NULL(i_szMachineName);
  497. RETURN_INVALIDARG_IF_NULL(o_pbstrComputerName);
  498. HRESULT hr = S_OK;
  499. BOOL bPostNTServer = FALSE;
  500. LONG lMajorVer = 0;
  501. LONG lMinorVer = 0;
  502. SERVER_INFO_101* pServerInfo = NULL;
  503. DWORD dwRet = NetServerGetInfo((LPTSTR)i_szMachineName, 101, (LPBYTE*)&pServerInfo);
  504. if (NERR_Success == dwRet)
  505. {
  506. lMajorVer = pServerInfo->sv101_version_major & MAJOR_VERSION_MASK;
  507. lMinorVer = pServerInfo->sv101_version_minor;
  508. bPostNTServer = (pServerInfo->sv101_type & SV_TYPE_NT) &&
  509. lMajorVer >= 5 &&
  510. ((pServerInfo->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
  511. (pServerInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) ||
  512. (pServerInfo->sv101_type & SV_TYPE_SERVER_NT));
  513. NetApiBufferFree(pServerInfo);
  514. } else
  515. {
  516. hr = HRESULT_FROM_WIN32(dwRet);
  517. DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_MSG_INCORRECT_SERVER, i_szMachineName);
  518. return hr;
  519. }
  520. if (!bPostNTServer)
  521. {
  522. DisplayMessageBoxWithOK(IDS_MSG_NOT_50);
  523. return S_FALSE;
  524. }
  525. /* LinanT 3/19/99: remove "check registry, if set, get dns server"
  526. CComBSTR bstrDnsComputerName;
  527. (void)GetServerInfo(
  528. (LPTSTR)i_szMachineName,
  529. NULL, // domain
  530. NULL, // Netbios
  531. NULL, // ValidDSObject
  532. &bstrDnsComputerName, // Dns
  533. NULL, // Guid
  534. NULL, // FQDN
  535. NULL, // lMajorVer
  536. NULL //lMinorVer
  537. );
  538. *o_pbstrComputerName = SysAllocString(bstrDnsComputerName ? bstrDnsComputerName : bstrNetbiosComputerName);
  539. */
  540. if ( !mylstrncmpi(i_szMachineName, _T("\\\\"), 2) )
  541. *o_pbstrComputerName = SysAllocString(i_szMachineName + 2);
  542. else
  543. *o_pbstrComputerName = SysAllocString(i_szMachineName);
  544. if (!*o_pbstrComputerName)
  545. {
  546. hr = E_OUTOFMEMORY;
  547. DisplayMessageBoxForHR(hr);
  548. return hr;
  549. }
  550. /*
  551. //
  552. // don't check, let DFS API handle it.
  553. // This way, we have space to handle new DFS service if introduced in the future.
  554. //
  555. hr = IsServerRunningDfs(*o_pbstrComputerName);
  556. if(S_OK != hr)
  557. {
  558. DisplayMessageBoxWithOK(IDS_MSG_NOT_RUNNING_DFS, *o_pbstrComputerName);
  559. return hr;
  560. }
  561. */
  562. hr = IsServerInDomain(*o_pbstrComputerName);
  563. if (FAILED(hr))
  564. {
  565. DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_MSG_INCORRECT_SERVER, *o_pbstrComputerName);
  566. return hr;
  567. } else if (S_FALSE == hr)
  568. {
  569. DisplayMessageBoxWithOK(IDS_MSG_SERVER_FROM_ANOTHER_DOMAIN, *o_pbstrComputerName);
  570. return hr;
  571. }
  572. //
  573. // for W2K, check if server already has a dfs root set up
  574. // do not check for Whistler (in which case the lMinorVer == 1).
  575. //
  576. if (lMajorVer == 5 && lMinorVer < 1 && S_OK == IsHostingDfsRoot(*o_pbstrComputerName))
  577. {
  578. DisplayMessageBoxWithOK(IDS_MSG_WIZ_DFS_ALREADY_PRESENT,NULL);
  579. return S_FALSE;
  580. }
  581. m_lpWizInfo->bPostW2KVersion = (lMajorVer >= 5 && lMinorVer >= 1);
  582. //
  583. // for postW2K in case of newRootTarget, check if server already host for this dfs root
  584. //
  585. if (m_lpWizInfo->bPostW2KVersion && m_lpWizInfo->bRootReplica)
  586. {
  587. CComBSTR bstrRootEntryPath = _T("\\\\");
  588. bstrRootEntryPath += m_lpWizInfo->bstrSelectedDomain;
  589. bstrRootEntryPath += _T("\\");
  590. bstrRootEntryPath += m_lpWizInfo->bstrDfsRootName;
  591. if (S_OK == IsHostingDfsRootEx(*o_pbstrComputerName, bstrRootEntryPath))
  592. {
  593. DisplayMessageBoxWithOK(IDS_MSG_WIZ_ALREADY_ROOTTARGET,NULL);
  594. return S_FALSE;
  595. }
  596. }
  597. return S_OK;
  598. }
  599. BOOL
  600. CCreateDfsRootWizPage4::OnWizardBack()
  601. {
  602. SetDlgItemText(IDC_EDIT_SELECTED_SERVER, _T("")); // Set edit box to empty
  603. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSelectedServer);
  604. return TRUE;
  605. }
  606. HRESULT
  607. GetComputerDnsNameFromLDAP(
  608. IN LPCTSTR lpszLDAPPath,
  609. OUT BSTR *o_pbstrName
  610. )
  611. {
  612. CComPtr<IADs> spIADs;
  613. HRESULT hr = ADsGetObject(const_cast<LPTSTR>(lpszLDAPPath), IID_IADs, (void**)&spIADs);
  614. if (SUCCEEDED(hr))
  615. {
  616. VARIANT var;
  617. VariantInit(&var);
  618. hr = spIADs->Get(_T("dnsHostName"), &var);
  619. if (SUCCEEDED(hr))
  620. {
  621. CComBSTR bstrComputer = V_BSTR(&var);
  622. *o_pbstrName = bstrComputer.Detach();
  623. VariantClear(&var);
  624. }
  625. }
  626. return hr;
  627. }
  628. HRESULT
  629. GetComputerNetbiosNameFromLDAP(
  630. IN LPCTSTR lpszLDAPPath,
  631. OUT BSTR *o_pbstrName
  632. )
  633. {
  634. CComPtr<IADsPathname> spIAdsPath;
  635. HRESULT hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (void**)&spIAdsPath);
  636. if (SUCCEEDED(hr))
  637. {
  638. hr = spIAdsPath->Set(const_cast<LPTSTR>(lpszLDAPPath), ADS_SETTYPE_FULL);
  639. if (SUCCEEDED(hr))
  640. {
  641. hr = spIAdsPath->SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
  642. if (SUCCEEDED(hr))
  643. {
  644. // Get first Component which is computer's Netbios name.
  645. CComBSTR bstrComputer;
  646. hr = spIAdsPath->GetElement(0, &bstrComputer);
  647. if (SUCCEEDED(hr))
  648. *o_pbstrName = bstrComputer.Detach();
  649. }
  650. }
  651. }
  652. return hr;
  653. }
  654. BOOL
  655. CCreateDfsRootWizPage4::OnBrowse(
  656. IN WORD wNotifyCode,
  657. IN WORD wID,
  658. IN HWND hWndCtl,
  659. IN BOOL& bHandled
  660. )
  661. /*++
  662. Routine Description:
  663. Handles the mouse click of the Browse button.
  664. Display the Computer Query Dialog.
  665. --*/
  666. {
  667. CWaitCursor WaitCursor;
  668. DSQUERYINITPARAMS dqip;
  669. OPENQUERYWINDOW oqw;
  670. CComPtr<ICommonQuery> pCommonQuery;
  671. CComPtr<IDataObject> pDataObject;
  672. HRESULT hr = S_OK;
  673. do {
  674. CComBSTR bstrDCName;
  675. CComBSTR bstrLDAPDomainPath;
  676. hr = GetDomainInfo(
  677. m_lpWizInfo->bstrSelectedDomain,
  678. &bstrDCName,
  679. NULL, // domainDns
  680. NULL, // domainDN
  681. &bstrLDAPDomainPath);
  682. if (FAILED(hr))
  683. break;
  684. dfsDebugOut((_T("OnBrowse bstrDCName=%s, bstrLDAPDomainPath=%s\n"),
  685. bstrDCName, bstrLDAPDomainPath));
  686. hr = CoCreateInstance(CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER, IID_ICommonQuery, (void **)&pCommonQuery);
  687. if (FAILED(hr)) break;
  688. // Parameters for Query Dialog.
  689. ZeroMemory(&dqip, sizeof(dqip));
  690. dqip.cbStruct = sizeof(dqip);
  691. dqip.dwFlags = DSQPF_HASCREDENTIALS;
  692. dqip.pDefaultScope = bstrLDAPDomainPath;
  693. dqip.pServer = bstrDCName;
  694. ZeroMemory(&oqw, sizeof(oqw));
  695. oqw.cbStruct = sizeof(oqw);
  696. oqw.clsidHandler = CLSID_DsQuery; // Handler is Ds Query.
  697. oqw.pHandlerParameters = &dqip;
  698. oqw.clsidDefaultForm = CLSID_DsFindComputer; // Show Find Computers Query Dialog
  699. oqw.dwFlags = OQWF_OKCANCEL |
  700. OQWF_SINGLESELECT |
  701. OQWF_DEFAULTFORM |
  702. OQWF_REMOVEFORMS |
  703. OQWF_ISSUEONOPEN |
  704. OQWF_REMOVESCOPES ;
  705. hr = pCommonQuery->OpenQueryWindow(m_hWnd, &oqw, &pDataObject);
  706. if (S_OK != hr) break;
  707. if (NULL == m_cfDsObjectNames )
  708. {
  709. m_cfDsObjectNames = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  710. }
  711. FORMATETC fmte = {
  712. CF_HDROP,
  713. NULL,
  714. DVASPECT_CONTENT,
  715. -1,
  716. TYMED_HGLOBAL
  717. };
  718. STGMEDIUM medium = {
  719. TYMED_NULL,
  720. NULL,
  721. NULL
  722. };
  723. fmte.cfFormat = m_cfDsObjectNames;
  724. hr = pDataObject->GetData(&fmte, &medium);
  725. if (FAILED(hr)) break;
  726. LPDSOBJECTNAMES pDsObjects = (LPDSOBJECTNAMES)medium.hGlobal;
  727. if (!pDsObjects || pDsObjects->cItems <= 0)
  728. {
  729. hr = S_FALSE;
  730. break;
  731. }
  732. // retrieve the full LDAP path to the computer
  733. LPTSTR lpszTemp =
  734. (LPTSTR)(((LPBYTE)pDsObjects)+(pDsObjects->aObjects[0].offsetName));
  735. // try to retrieve its Dns name
  736. CComBSTR bstrComputer;
  737. hr = GetComputerDnsNameFromLDAP(lpszTemp, &bstrComputer);
  738. // if failed, try to retrieve its Netbios name
  739. if (FAILED(hr))
  740. hr = GetComputerNetbiosNameFromLDAP(lpszTemp, &bstrComputer);
  741. if (FAILED(hr)) break;
  742. SetDlgItemText(IDC_EDIT_SELECTED_SERVER, bstrComputer);
  743. } while (0);
  744. if (FAILED(hr))
  745. DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_FAILED_TO_BROWSE_SERVER, m_lpWizInfo->bstrSelectedDomain);
  746. return (S_OK == hr);
  747. }
  748. // ----------------------------------------------------------------------------
  749. // CCreateDfsRootWizPage5: Share selection
  750. CCreateDfsRootWizPage5::CCreateDfsRootWizPage5(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  751. : CQWizardPageImpl<CCreateDfsRootWizPage5>(true),
  752. m_lpWizInfo(i_lpWizInfo)
  753. {
  754. CComBSTR bstrTitle;
  755. LoadStringFromResource(IDS_WIZ_PAGE5_TITLE, &bstrTitle);
  756. SetHeaderTitle(bstrTitle);
  757. CComBSTR bstrSubTitle;
  758. LoadStringFromResource(IDS_WIZ_PAGE5_SUBTITLE, &bstrSubTitle);
  759. SetHeaderSubTitle(bstrSubTitle);
  760. }
  761. BOOL
  762. CCreateDfsRootWizPage5::OnSetActive()
  763. {
  764. if (m_lpWizInfo->bShareExists)
  765. return FALSE; // root share exists, skip this page
  766. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
  767. return TRUE;
  768. }
  769. BOOL
  770. CCreateDfsRootWizPage5::OnWizardNext()
  771. {
  772. CWaitCursor WaitCursor;
  773. CComBSTR bstrCurrentText;
  774. DWORD dwTextLength = 0;
  775. // get share path
  776. HRESULT hr = GetInputText(GetDlgItem(IDC_EDIT_SHARE_PATH), &bstrCurrentText, &dwTextLength);
  777. if (FAILED(hr))
  778. {
  779. DisplayMessageBoxForHR(hr);
  780. ::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
  781. return FALSE;
  782. } else if (0 == dwTextLength)
  783. {
  784. DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
  785. ::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
  786. return FALSE;
  787. }
  788. // Removing the ending backslash, otherwise, GetFileAttribute/NetShareAdd will fail.
  789. TCHAR *p = bstrCurrentText + _tcslen(bstrCurrentText) - 1;
  790. if (IsValidLocalAbsolutePath(bstrCurrentText) && *p == _T('\\') && *(p-1) != _T(':'))
  791. *p = _T('\0');
  792. if (S_OK != ValidateFolderPath(m_lpWizInfo->bstrSelectedServer, bstrCurrentText))
  793. {
  794. ::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
  795. return FALSE;
  796. }
  797. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSharePath);
  798. m_lpWizInfo->bstrSharePath = bstrCurrentText.Detach();
  799. // Create the share.
  800. hr = CreateShare(
  801. m_lpWizInfo->bstrSelectedServer,
  802. m_lpWizInfo->bstrDfsRootName,
  803. _T(""), // Blank Comment
  804. m_lpWizInfo->bstrSharePath
  805. );
  806. if (FAILED(hr))
  807. {
  808. DisplayMessageBoxForHR(hr);
  809. return FALSE;
  810. }
  811. if (m_lpWizInfo->bPostW2KVersion && !CheckReparsePoint(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName))
  812. {
  813. DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOTNTFS5, m_lpWizInfo->bstrDfsRootName);
  814. NetShareDel(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName, 0);
  815. ::SetFocus(GetDlgItem(IDC_EDIT_SHARE_PATH));
  816. return FALSE;
  817. }
  818. SetDlgItemText(IDC_EDIT_SHARE_PATH, _T(""));
  819. return TRUE;
  820. }
  821. BOOL
  822. CCreateDfsRootWizPage5::OnWizardBack()
  823. {
  824. SetDlgItemText(IDC_EDIT_SHARE_PATH, _T(""));
  825. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrSharePath);
  826. return TRUE;
  827. }
  828. LRESULT CCreateDfsRootWizPage5::OnInitDialog(
  829. IN UINT i_uMsg,
  830. IN WPARAM i_wParam,
  831. IN LPARAM i_lParam,
  832. IN OUT BOOL& io_bHandled
  833. )
  834. {
  835. ::SendMessage(GetDlgItem(IDC_EDIT_SHARE_PATH), EM_LIMITTEXT, _MAX_DIR - 1, 0);
  836. return TRUE;
  837. }
  838. BOOL
  839. CCreateDfsRootWizPage5::OnBrowse(
  840. IN WORD wNotifyCode,
  841. IN WORD wID,
  842. IN HWND hWndCtl,
  843. IN BOOL& bHandled
  844. )
  845. /*++
  846. Routine Description:
  847. Handles the mouse click of the Browse button.
  848. Display the folder Dialog.
  849. --*/
  850. {
  851. CWaitCursor WaitCursor;
  852. BOOL bLocalComputer = (S_OK == IsComputerLocal(m_lpWizInfo->bstrSelectedServer));
  853. TCHAR szDir[MAX_PATH * 2] = _T(""); // double the size in case the remote path is itself close to MAX_PATH
  854. OpenBrowseDialog(m_hWnd, IDS_BROWSE_FOLDER, bLocalComputer, m_lpWizInfo->bstrSelectedServer, szDir);
  855. CComBSTR bstrPath;
  856. if (szDir[0])
  857. {
  858. if (bLocalComputer)
  859. bstrPath = szDir;
  860. else
  861. { // szDir is in the form of \\server\share or \\server\share\path....
  862. LPTSTR pShare = _tcschr(szDir + 2, _T('\\'));
  863. pShare++;
  864. LPTSTR pLeftOver = _tcschr(pShare, _T('\\'));
  865. if (pLeftOver && *pLeftOver)
  866. *pLeftOver++ = _T('\0');
  867. SHARE_INFO_2 *psi = NULL;
  868. if (NERR_Success == NetShareGetInfo(m_lpWizInfo->bstrSelectedServer, pShare, 2, (LPBYTE *)&psi))
  869. {
  870. bstrPath = psi->shi2_path;
  871. if (pLeftOver && *pLeftOver)
  872. {
  873. if (_T('\\') != bstrPath[lstrlen(bstrPath) - 1])
  874. bstrPath += _T("\\");
  875. bstrPath += pLeftOver;
  876. }
  877. NetApiBufferFree(psi);
  878. }
  879. }
  880. }
  881. if ((BSTR)bstrPath && *bstrPath)
  882. SetDlgItemText(IDC_EDIT_SHARE_PATH, bstrPath);
  883. return TRUE;
  884. }
  885. // ----------------------------------------------------------------------------
  886. // CCreateDfsRootWizPage6: DfsRoot name selection
  887. CCreateDfsRootWizPage6::CCreateDfsRootWizPage6(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  888. : CQWizardPageImpl<CCreateDfsRootWizPage6>(true),
  889. m_lpWizInfo(i_lpWizInfo)
  890. {
  891. CComBSTR bstrTitle;
  892. LoadStringFromResource(IDS_WIZ_PAGE6_TITLE, &bstrTitle);
  893. SetHeaderTitle(bstrTitle);
  894. CComBSTR bstrSubTitle;
  895. LoadStringFromResource(IDS_WIZ_PAGE6_SUBTITLE, &bstrSubTitle);
  896. SetHeaderSubTitle(bstrSubTitle);
  897. }
  898. BOOL
  899. CCreateDfsRootWizPage6::OnSetActive()
  900. {
  901. if (m_lpWizInfo->bRootReplica)
  902. return FALSE; // we skip this page in case of creating new root target
  903. ::SendMessage(GetDlgItem(IDC_EDIT_DFSROOT_NAME), EM_LIMITTEXT, MAX_RDN_KEY_SIZE, 0);
  904. if (NULL != m_lpWizInfo->bstrDfsRootName) // Set the default dfsroot name
  905. SetDlgItemText(IDC_EDIT_DFSROOT_NAME, m_lpWizInfo->bstrDfsRootName);
  906. ::SendMessage(GetDlgItem(IDC_EDIT_DFSROOT_COMMENT), EM_LIMITTEXT, MAXCOMMENTSZ, 0);
  907. UpdateLabels(); // Change the labels
  908. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT);
  909. return TRUE;
  910. }
  911. HRESULT
  912. CCreateDfsRootWizPage6::UpdateLabels()
  913. {
  914. CComBSTR bstrDfsRootName;
  915. DWORD dwTextLength = 0;
  916. (void)GetInputText(GetDlgItem(IDC_EDIT_DFSROOT_NAME), &bstrDfsRootName, &dwTextLength);
  917. SetDlgItemText(IDC_ROOT_SHARE, bstrDfsRootName);
  918. CComBSTR bstrFullPath = _T("\\\\");
  919. RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
  920. if (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType)
  921. bstrFullPath += m_lpWizInfo->bstrSelectedDomain;
  922. else
  923. bstrFullPath += m_lpWizInfo->bstrSelectedServer;
  924. RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
  925. bstrFullPath += _T("\\");
  926. RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
  927. bstrFullPath += bstrDfsRootName;
  928. RETURN_OUTOFMEMORY_IF_NULL((BSTR)bstrFullPath);
  929. SetDlgItemText(IDC_TEXT_DFSROOT_PREFIX, bstrFullPath);
  930. ::SendMessage(GetDlgItem(IDC_TEXT_DFSROOT_PREFIX), EM_SETSEL, 0, (LPARAM)-1);
  931. ::SendMessage(GetDlgItem(IDC_TEXT_DFSROOT_PREFIX), EM_SETSEL, (WPARAM)-1, 0);
  932. ::SendMessage(GetDlgItem(IDC_TEXT_DFSROOT_PREFIX), EM_SCROLLCARET, 0, 0);
  933. return S_OK;
  934. }
  935. LRESULT
  936. CCreateDfsRootWizPage6::OnChangeDfsRoot(
  937. WORD wNotifyCode,
  938. WORD wID,
  939. HWND hWndCtl,
  940. BOOL& bHandled)
  941. {
  942. UpdateLabels();
  943. return TRUE;
  944. }
  945. BOOL
  946. CCreateDfsRootWizPage6::OnWizardNext(
  947. )
  948. {
  949. CWaitCursor WaitCursor;
  950. HRESULT hr = S_OK;
  951. CComBSTR bstrCurrentText;
  952. DWORD dwTextLength = 0;
  953. // get dfsroot name
  954. hr = GetInputText(GetDlgItem(IDC_EDIT_DFSROOT_NAME), &bstrCurrentText, &dwTextLength);
  955. if (FAILED(hr))
  956. {
  957. DisplayMessageBoxForHR(hr);
  958. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  959. return FALSE;
  960. } else if (0 == dwTextLength)
  961. {
  962. DisplayMessageBoxWithOK(IDS_MSG_EMPTY_FIELD);
  963. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  964. return FALSE;
  965. }
  966. // See if the Dfs Name has illegal Characters.
  967. if (_tcscspn(bstrCurrentText, _T("\\/@")) != _tcslen(bstrCurrentText) ||
  968. (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType && I_NetNameValidate(NULL, bstrCurrentText, NAMETYPE_SHARE, 0)) )
  969. {
  970. DisplayMessageBoxWithOK(IDS_MSG_WIZ_BAD_DFS_NAME,NULL);
  971. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  972. return FALSE;
  973. }
  974. // domain DFS only: See if the Dfs Name exists.
  975. if (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType)
  976. {
  977. BOOL bRootAlreadyExist = FALSE;
  978. NETNAMELIST DfsRootList;
  979. if (S_OK == GetDomainDfsRoots(&DfsRootList, m_lpWizInfo->bstrSelectedDomain))
  980. {
  981. for (NETNAMELIST::iterator i = DfsRootList.begin(); i != DfsRootList.end(); i++)
  982. {
  983. if (!lstrcmpi((*i)->bstrNetName, bstrCurrentText))
  984. {
  985. bRootAlreadyExist = TRUE;
  986. break;
  987. }
  988. }
  989. FreeNetNameList(&DfsRootList);
  990. }
  991. if (bRootAlreadyExist)
  992. {
  993. DisplayMessageBoxWithOK(IDS_MSG_ROOT_ALREADY_EXISTS, bstrCurrentText);
  994. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  995. return FALSE;
  996. }
  997. }
  998. hr = CheckShare(m_lpWizInfo->bstrSelectedServer, bstrCurrentText, &m_lpWizInfo->bShareExists);
  999. if (FAILED(hr))
  1000. {
  1001. DisplayMessageBoxForHR(hr);
  1002. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  1003. return FALSE;
  1004. } else if (S_FALSE == hr)
  1005. {
  1006. DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOGOOD, bstrCurrentText);
  1007. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  1008. return FALSE;
  1009. }
  1010. if (m_lpWizInfo->bPostW2KVersion && m_lpWizInfo->bShareExists && !CheckReparsePoint(m_lpWizInfo->bstrSelectedServer, bstrCurrentText))
  1011. {
  1012. DisplayMessageBoxWithOK(IDS_MSG_ROOTSHARE_NOTNTFS5, bstrCurrentText);
  1013. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_NAME));
  1014. return FALSE;
  1015. }
  1016. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrDfsRootName);
  1017. m_lpWizInfo->bstrDfsRootName = bstrCurrentText.Detach();
  1018. // get dfsroot comment
  1019. hr = GetInputText(GetDlgItem(IDC_EDIT_DFSROOT_COMMENT), &bstrCurrentText, &dwTextLength);
  1020. if (FAILED(hr))
  1021. {
  1022. DisplayMessageBoxForHR(hr);
  1023. ::SetFocus(GetDlgItem(IDC_EDIT_DFSROOT_COMMENT));
  1024. return FALSE;
  1025. }
  1026. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrDfsRootComment);
  1027. m_lpWizInfo->bstrDfsRootComment = bstrCurrentText.Detach();
  1028. return TRUE;
  1029. }
  1030. BOOL
  1031. CCreateDfsRootWizPage6::OnWizardBack()
  1032. {
  1033. SAFE_SYSFREESTRING(&m_lpWizInfo->bstrDfsRootName);
  1034. return TRUE;
  1035. }
  1036. // ----------------------------------------------------------------------------
  1037. // CCreateDfsRootWizPage7: Completion page
  1038. CCreateDfsRootWizPage7::CCreateDfsRootWizPage7(IN LPCREATEDFSROOTWIZINFO i_lpWizInfo)
  1039. : CQWizardPageImpl<CCreateDfsRootWizPage7>(false),
  1040. m_lpWizInfo(i_lpWizInfo)
  1041. {
  1042. }
  1043. BOOL
  1044. CCreateDfsRootWizPage7::OnSetActive()
  1045. {
  1046. CWaitCursor wait;
  1047. CComBSTR bstrText;
  1048. if (DFS_TYPE_FTDFS == m_lpWizInfo->DfsType)
  1049. {
  1050. FormatMessageString(&bstrText, 0, IDS_DFSWIZ_TEXT_FTDFS,
  1051. m_lpWizInfo->bstrSelectedDomain,
  1052. m_lpWizInfo->bstrSelectedServer,
  1053. m_lpWizInfo->bstrDfsRootName,
  1054. m_lpWizInfo->bstrDfsRootName);
  1055. } else
  1056. {
  1057. FormatMessageString(&bstrText, 0, IDS_DFSWIZ_TEXT_SADFS,
  1058. m_lpWizInfo->bstrSelectedServer,
  1059. m_lpWizInfo->bstrDfsRootName,
  1060. m_lpWizInfo->bstrDfsRootName);
  1061. }
  1062. SetDlgItemText(IDC_DFSWIZ_TEXT, bstrText);
  1063. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_FINISH | PSWIZB_BACK);
  1064. ::SetControlFont(m_lpWizInfo->hBigBoldFont, m_hWnd, IDC_COMPLETE_BIG_TITLE);
  1065. ::SetControlFont(m_lpWizInfo->hBoldFont, m_hWnd, IDC_COMPLETE_SMALL_TITLE);
  1066. return TRUE;
  1067. }
  1068. BOOL
  1069. CCreateDfsRootWizPage7::OnWizardFinish()
  1070. {
  1071. return (S_OK == _SetUpDfs(m_lpWizInfo));
  1072. }
  1073. BOOL
  1074. CCreateDfsRootWizPage7::OnWizardBack()
  1075. {
  1076. //
  1077. // if share was created by the previous page, blow it away when we go back
  1078. //
  1079. if (!m_lpWizInfo->bShareExists)
  1080. NetShareDel(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName, 0);
  1081. return TRUE;
  1082. }
  1083. BOOL CCreateDfsRootWizPage7::OnQueryCancel()
  1084. {
  1085. //
  1086. // if share was created by the previous page, blow it away when we cancel the wizard
  1087. //
  1088. if (!m_lpWizInfo->bShareExists)
  1089. NetShareDel(m_lpWizInfo->bstrSelectedServer, m_lpWizInfo->bstrDfsRootName, 0);
  1090. return TRUE; // ok to cancel
  1091. }
  1092. HRESULT _SetUpDfs(
  1093. LPCREATEDFSROOTWIZINFO i_lpWizInfo
  1094. )
  1095. /*++
  1096. Routine Description:
  1097. Helper Function to Setup Dfs, called from wizard and new root replica,
  1098. Finish() method of Page5 if root level replca is created and Next() method of Page6
  1099. for Create New Dfs Root Wizard.
  1100. Arguments:
  1101. i_lpWizInfo - Wizard data.
  1102. Return value:
  1103. S_OK, on success
  1104. --*/
  1105. {
  1106. if (!i_lpWizInfo ||
  1107. !(i_lpWizInfo->bstrSelectedServer) ||
  1108. !(i_lpWizInfo->bstrDfsRootName))
  1109. return(E_INVALIDARG);
  1110. CWaitCursor WaitCursor;
  1111. NET_API_STATUS nstatRetVal = 0;
  1112. if (DFS_TYPE_FTDFS == i_lpWizInfo->DfsType)
  1113. {
  1114. nstatRetVal = NetDfsAddFtRoot(
  1115. i_lpWizInfo->bstrSelectedServer, // Remote Server
  1116. i_lpWizInfo->bstrDfsRootName, // Root Share
  1117. i_lpWizInfo->bstrDfsRootName, // FtDfs Name
  1118. i_lpWizInfo->bstrDfsRootComment, // Comment
  1119. 0 // No Flags.
  1120. );
  1121. dfsDebugOut((_T("NetDfsAddFtRoot server=%s, share=%s, DfsName=%s, comment=%s, nRet=%d\n"),
  1122. i_lpWizInfo->bstrSelectedServer, i_lpWizInfo->bstrDfsRootName, i_lpWizInfo->bstrDfsRootName, i_lpWizInfo->bstrDfsRootComment, nstatRetVal));
  1123. } else
  1124. {
  1125. nstatRetVal = NetDfsAddStdRoot(
  1126. i_lpWizInfo->bstrSelectedServer, // Remote Server
  1127. i_lpWizInfo->bstrDfsRootName, // Root Share
  1128. i_lpWizInfo->bstrDfsRootComment, // Comment
  1129. 0 // No Flags.
  1130. );
  1131. dfsDebugOut((_T("NetDfsAddStdRoot server=%s, share=%s, comment=%s, nRet=%d\n"),
  1132. i_lpWizInfo->bstrSelectedServer, i_lpWizInfo->bstrDfsRootName, i_lpWizInfo->bstrDfsRootComment, nstatRetVal));
  1133. }
  1134. HRESULT hr = S_OK;
  1135. if (NERR_Success != nstatRetVal)
  1136. {
  1137. hr = HRESULT_FROM_WIN32(nstatRetVal);
  1138. DisplayMessageBox(::GetActiveWindow(), MB_OK, hr, IDS_FAILED_TO_CREATE_DFSROOT, i_lpWizInfo->bstrSelectedServer);
  1139. hr = S_FALSE; // failed to create dfsroot, wizard cannot be closed
  1140. } else
  1141. {
  1142. i_lpWizInfo->bDfsSetupSuccess = true;
  1143. }
  1144. return hr;
  1145. }
  1146. HRESULT
  1147. ValidateFolderPath(
  1148. IN LPCTSTR lpszServer,
  1149. IN LPCTSTR lpszPath
  1150. )
  1151. {
  1152. if (!lpszPath || !*lpszPath)
  1153. return E_INVALIDARG;
  1154. HWND hwnd = ::GetActiveWindow();
  1155. HRESULT hr = S_FALSE;
  1156. do {
  1157. if (!IsValidLocalAbsolutePath(lpszPath))
  1158. {
  1159. DisplayMessageBox(hwnd, MB_OK, 0, IDS_INVALID_FOLDER);
  1160. break;
  1161. }
  1162. hr = IsComputerLocal(lpszServer);
  1163. if (FAILED(hr))
  1164. {
  1165. DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_VALIDATE_FOLDER, lpszPath);
  1166. break;
  1167. }
  1168. BOOL bLocal = (S_OK == hr);
  1169. hr = VerifyDriveLetter(lpszServer, lpszPath);
  1170. if (FAILED(hr))
  1171. {
  1172. DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_VALIDATE_FOLDER, lpszPath);
  1173. break;
  1174. } else if (S_OK != hr)
  1175. {
  1176. DisplayMessageBox(hwnd, MB_OK, 0, IDS_INVALID_FOLDER);
  1177. break;
  1178. }
  1179. if (!bLocal)
  1180. {
  1181. hr = IsAdminShare(lpszServer, lpszPath);
  1182. if (FAILED(hr))
  1183. {
  1184. DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_VALIDATE_FOLDER, lpszPath);
  1185. break;
  1186. } else if (S_OK != hr)
  1187. {
  1188. // there is no matching $ shares, hence, no need to call GetFileAttribute, CreateDirectory,
  1189. // assume lpszDir points to an existing directory
  1190. hr = S_OK;
  1191. break;
  1192. }
  1193. }
  1194. CComBSTR bstrFullPath;
  1195. GetFullPath(lpszServer, lpszPath, &bstrFullPath);
  1196. hr = IsAnExistingFolder(hwnd, bstrFullPath);
  1197. if (FAILED(hr) || S_OK == hr)
  1198. break;
  1199. if ( IDYES != DisplayMessageBox(hwnd, MB_YESNO, 0, IDS_CREATE_FOLDER, lpszPath, lpszServer) )
  1200. {
  1201. hr = S_FALSE;
  1202. break;
  1203. }
  1204. // create the directories layer by layer
  1205. hr = CreateLayeredDirectory(lpszServer, lpszPath);
  1206. if (FAILED(hr))
  1207. {
  1208. DisplayMessageBox(hwnd, MB_OK, hr, IDS_FAILED_TO_CREATE_FOLDER, lpszPath, lpszServer);
  1209. break;
  1210. }
  1211. } while (0);
  1212. return hr;
  1213. }