Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1293 lines
35 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996-1996, Microsoft Corporation.
  4. //
  5. // File: config.cxx
  6. //
  7. // Contents: Dialog for configuration of Dfs
  8. //
  9. // History: 6-Feb-96 BruceFo created
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include <windows.h>
  13. #include <ole2.h>
  14. #include <windowsx.h>
  15. #include <shlobj.h>
  16. #include <lm.h>
  17. // Update for share validation
  18. extern "C"
  19. {
  20. #include <netcan.h> // in net/inc
  21. #include <icanon.h>
  22. #include <dsrole.h> // DsRoleGetPrimaryDomainInformation
  23. }
  24. #include <msshrui.h>
  25. #include <debug.h>
  26. #include <dfsstr.h>
  27. #include "messages.h"
  28. #include "resource.h"
  29. #include "config.hxx"
  30. DECLARE_DEBUG(DfsSetup)
  31. #if DBG == 1
  32. #define dprintf(x) DfsSetupInlineDebugOut x
  33. #else
  34. #define dprintf(x)
  35. #endif
  36. #define CHECK_HRESULT(hr) \
  37. if ( FAILED(hr) ) \
  38. { \
  39. dprintf((DEB_ERROR, \
  40. "**** HRESULT ERROR RETURN <%s @line %d> -> 0x%08lx\n", \
  41. __FILE__, __LINE__, hr)); \
  42. }
  43. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  44. extern HINSTANCE g_hInstance;
  45. //+-------------------------------------------------------------------------
  46. //
  47. // Function: SetErrorFocus
  48. //
  49. // Synopsis: Set focus to an edit control and select its text.
  50. //
  51. // Arguments: [hwnd] - dialog window
  52. // [idCtrl] - edit control to set focus to (and select)
  53. //
  54. // Returns: nothing
  55. //
  56. // History: 3-May-95 BruceFo Stolen
  57. //
  58. //--------------------------------------------------------------------------
  59. VOID
  60. SetErrorFocus(
  61. IN HWND hwnd,
  62. IN UINT idCtrl
  63. )
  64. {
  65. HWND hCtrl = ::GetDlgItem(hwnd, idCtrl);
  66. ::SetFocus(hCtrl);
  67. ::SendMessage(hCtrl, EM_SETSEL, 0, -1);
  68. }
  69. //+-------------------------------------------------------------------------
  70. //
  71. // Function: MyFormatMessageText
  72. //
  73. // Synopsis: Given a resource IDs, load strings from given instance
  74. // and format the string into a buffer
  75. //
  76. // History: 11-Aug-93 WilliamW Created.
  77. //
  78. //--------------------------------------------------------------------------
  79. VOID
  80. MyFormatMessageText(
  81. IN HRESULT dwMsgId,
  82. IN PWSTR pszBuffer,
  83. IN DWORD dwBufferSize,
  84. IN va_list * parglist
  85. )
  86. {
  87. //
  88. // get message from system or app msg file.
  89. //
  90. DWORD dwReturn = FormatMessage(
  91. FORMAT_MESSAGE_FROM_HMODULE,
  92. g_hInstance,
  93. dwMsgId,
  94. LANG_USER_DEFAULT,
  95. pszBuffer,
  96. dwBufferSize,
  97. parglist);
  98. if (0 == dwReturn) // couldn't find message
  99. {
  100. dprintf((DEB_IERROR,
  101. "FormatMessage failed, 0x%08lx\n",
  102. GetLastError()));
  103. WCHAR szText[200];
  104. LoadString(g_hInstance, IDS_APP_MSG_NOT_FOUND, szText, ARRAYLEN(szText));
  105. wsprintf(pszBuffer,szText,dwMsgId);
  106. }
  107. }
  108. //+-------------------------------------------------------------------------
  109. //
  110. // Function: MyFormatMessage
  111. //
  112. // Synopsis: Given a resource IDs, load strings from given instance
  113. // and format the string into a buffer
  114. //
  115. // History: 11-Aug-93 WilliamW Created.
  116. //
  117. //--------------------------------------------------------------------------
  118. VOID
  119. MyFormatMessage(
  120. IN HRESULT dwMsgId,
  121. IN PWSTR pszBuffer,
  122. IN DWORD dwBufferSize,
  123. ...
  124. )
  125. {
  126. va_list arglist;
  127. va_start(arglist, dwBufferSize);
  128. MyFormatMessageText(dwMsgId, pszBuffer, dwBufferSize, &arglist);
  129. va_end(arglist);
  130. }
  131. //+-------------------------------------------------------------------------
  132. //
  133. // Method: MyCommonDialog
  134. //
  135. // Synopsis: Common popup dialog routine - stole from diskadm directory
  136. //
  137. //--------------------------------------------------------------------------
  138. DWORD
  139. MyCommonDialog(
  140. IN HWND hwnd,
  141. IN HRESULT dwMsgCode,
  142. IN PWSTR pszCaption,
  143. IN DWORD dwFlags,
  144. IN va_list arglist
  145. )
  146. {
  147. WCHAR szMsgBuf[500];
  148. MyFormatMessageText(dwMsgCode, szMsgBuf, ARRAYLEN(szMsgBuf), &arglist);
  149. SetCursor(LoadCursor(NULL, IDC_ARROW)); // in case it's an hourglass...
  150. return MessageBox(hwnd, szMsgBuf, pszCaption, dwFlags);
  151. }
  152. //+-------------------------------------------------------------------------
  153. //
  154. // Method: MyErrorDialog
  155. //
  156. // Synopsis: This routine retreives a message from the app or system
  157. // message file and displays it in a message box.
  158. //
  159. // Note: Stole from diskadm directory
  160. //
  161. //--------------------------------------------------------------------------
  162. VOID
  163. MyErrorDialog(
  164. IN HWND hwnd,
  165. IN HRESULT dwErrorCode,
  166. ...
  167. )
  168. {
  169. WCHAR szCaption[100];
  170. va_list arglist;
  171. va_start(arglist, dwErrorCode);
  172. LoadString(g_hInstance, IDS_MSGTITLE, szCaption, ARRAYLEN(szCaption));
  173. MyCommonDialog(hwnd, dwErrorCode, szCaption, MB_ICONSTOP | MB_OK, arglist);
  174. va_end(arglist);
  175. }
  176. //+-------------------------------------------------------------------------
  177. //
  178. // Method: MyConfirmationDialog
  179. //
  180. // Synopsis: This routine retreives a message from the app or system
  181. // message file and displays it in a message box.
  182. //
  183. // Note: Stole from diskadm directory
  184. //
  185. //--------------------------------------------------------------------------
  186. DWORD
  187. MyConfirmationDialog(
  188. IN HWND hwnd,
  189. IN HRESULT dwMsgCode,
  190. IN DWORD dwFlags,
  191. ...
  192. )
  193. {
  194. WCHAR szCaption[100];
  195. DWORD dwReturn;
  196. va_list arglist;
  197. va_start(arglist, dwFlags);
  198. LoadString(g_hInstance, IDS_MSGTITLE, szCaption, ARRAYLEN(szCaption));
  199. dwReturn = MyCommonDialog(hwnd, dwMsgCode, szCaption, dwFlags, arglist);
  200. va_end(arglist);
  201. return dwReturn;
  202. }
  203. //+-------------------------------------------------------------------------
  204. //
  205. // Method: IsLocalShareable, private
  206. //
  207. // Synopsis: Returns TRUE if the path is a local path on a shareable media
  208. // type.
  209. //
  210. //--------------------------------------------------------------------------
  211. BOOL
  212. IsLocalShareable(
  213. IN LPWSTR pszPath
  214. )
  215. {
  216. // ok? local, etc...
  217. if (NULL != pszPath
  218. && pszPath[1] == L':'
  219. )
  220. {
  221. // assume it's a drive letter. See if it's local.
  222. WCHAR szRoot[3];
  223. szRoot[0] = pszPath[0];
  224. szRoot[1] = L':';
  225. szRoot[2] = L'\0';
  226. UINT info = GetDriveType(szRoot);
  227. switch (info)
  228. {
  229. // the following list is a list of drive types I believe can
  230. // be shared by the server
  231. case DRIVE_FIXED:
  232. case DRIVE_REMOVABLE:
  233. case DRIVE_CDROM:
  234. return TRUE;
  235. break;
  236. }
  237. }
  238. return FALSE;
  239. }
  240. //+-------------------------------------------------------------------------
  241. //
  242. // Method: BrowseCallback, private
  243. //
  244. // Synopsis:
  245. //
  246. //--------------------------------------------------------------------------
  247. int
  248. BrowseCallback(
  249. IN HWND hwnd,
  250. IN UINT uMsg,
  251. IN LPARAM lParam,
  252. IN LPARAM lpData
  253. )
  254. {
  255. if (uMsg == BFFM_SELCHANGED)
  256. {
  257. LPITEMIDLIST pidl = (LPITEMIDLIST)lParam;
  258. TCHAR szPath[MAX_PATH];
  259. BOOL fEnable = FALSE;
  260. if (SHGetPathFromIDList(pidl, szPath))
  261. {
  262. // ok? local, etc...
  263. if (IsLocalShareable(szPath))
  264. {
  265. fEnable = TRUE;
  266. }
  267. }
  268. SendMessage(hwnd, BFFM_ENABLEOK, 0, fEnable);
  269. }
  270. return 0;
  271. }
  272. //+-------------------------------------------------------------------------
  273. //
  274. // Method: OnBrowse
  275. //
  276. // Synopsis:
  277. //
  278. //--------------------------------------------------------------------------
  279. BOOL
  280. OnBrowse(
  281. IN HWND hwnd
  282. )
  283. {
  284. LPITEMIDLIST pidlRoot;
  285. HRESULT hr = SHGetSpecialFolderLocation(hwnd, CSIDL_DRIVES, &pidlRoot);
  286. CHECK_HRESULT(hr);
  287. if (FAILED(hr))
  288. {
  289. return FALSE;
  290. }
  291. WCHAR szCaptionText[MAX_PATH];
  292. MyFormatMessage(MSG_BROWSE,szCaptionText,ARRAYLEN(szCaptionText));
  293. WCHAR szDisplayName[MAX_PATH];
  294. BROWSEINFO bi =
  295. {
  296. hwnd,
  297. pidlRoot,
  298. szDisplayName,
  299. szCaptionText,
  300. BIF_RETURNONLYFSDIRS,
  301. BrowseCallback,
  302. (LPARAM)0,
  303. 0
  304. };
  305. LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
  306. if (NULL != pidl)
  307. {
  308. WCHAR szPath[MAX_PATH];
  309. SHGetPathFromIDList(pidl, szPath);
  310. dprintf((DEB_ITRACE, "SHBrowseForFolder: got %ws\n", szPath));
  311. SetDlgItemText(hwnd, IDC_DIRECTORY, szPath);
  312. SetFocus(GetDlgItem(hwnd, IDC_CREATESHARE)); // so you can just hit "enter" afterwards...
  313. }
  314. else
  315. {
  316. dprintf((DEB_ITRACE, "SHBrowseForFolder was cancelled\n"));
  317. }
  318. // Now, free the shell data
  319. IMalloc* pMalloc;
  320. hr = SHGetMalloc(&pMalloc);
  321. CHECK_HRESULT(hr);
  322. if (SUCCEEDED(hr))
  323. {
  324. pMalloc->Free(pidlRoot);
  325. pMalloc->Free(pidl);
  326. pMalloc->Release();
  327. }
  328. return TRUE;
  329. }
  330. //-----------------------------------------------------------------------------
  331. // New Share Dialog
  332. //-----------------------------------------------------------------------------
  333. INT_PTR CALLBACK
  334. DlgProcNewShare(
  335. IN HWND hwnd,
  336. IN UINT uMsg,
  337. IN WPARAM wParam,
  338. IN LPARAM lParam
  339. )
  340. {
  341. static LPWSTR s_pszPath;
  342. switch (uMsg)
  343. {
  344. case WM_INITDIALOG:
  345. {
  346. s_pszPath = (LPWSTR)lParam;
  347. if (NULL == s_pszPath)
  348. {
  349. EndDialog(hwnd, -1); // internal error
  350. }
  351. EnableWindow(GetDlgItem(hwnd, IDC_CREATESHARE), FALSE);
  352. SendDlgItemMessage(hwnd, IDC_DIRECTORY, EM_LIMITTEXT, (WPARAM)(MAX_PATH - 1), (LPARAM)0);
  353. return 1; // didn't call SetFocus
  354. }
  355. case WM_COMMAND:
  356. {
  357. WORD wNotifyCode = HIWORD(wParam);
  358. WORD wID = LOWORD(wParam);
  359. switch (wID)
  360. {
  361. case IDC_CREATESHARE:
  362. {
  363. GetDlgItemText(hwnd, IDC_DIRECTORY, s_pszPath, MAX_PATH);
  364. if (!IsLocalShareable(s_pszPath))
  365. {
  366. MyErrorDialog(hwnd, MSG_ILLEGAL_DIRECTORY, s_pszPath);
  367. SetErrorFocus(hwnd, IDC_DIRECTORY);
  368. return TRUE;
  369. }
  370. DWORD attribs = GetFileAttributes(s_pszPath);
  371. if (0xffffffff == attribs)
  372. {
  373. if (ERROR_PATH_NOT_FOUND == GetLastError()
  374. || ERROR_FILE_NOT_FOUND == GetLastError()
  375. )
  376. {
  377. DWORD dw = MyConfirmationDialog(hwnd, MSG_NODIRECTORY, MB_YESNO | MB_ICONQUESTION, s_pszPath);
  378. if (dw == IDNO)
  379. {
  380. // ok, go away...
  381. SetErrorFocus(hwnd, IDC_DIRECTORY);
  382. return TRUE;
  383. }
  384. // try to create the directory
  385. BOOL b = CreateDirectory(s_pszPath, NULL);
  386. dprintf((DEB_TRACE,
  387. "CreateDirectory(%ws) = %d, last error = %d\n",
  388. s_pszPath, b, GetLastError()));
  389. if (!b)
  390. {
  391. MyErrorDialog(hwnd, MSG_COULDNT_CREATE_DIRECTORY, s_pszPath);
  392. SetErrorFocus(hwnd, IDC_DIRECTORY);
  393. return TRUE;
  394. }
  395. }
  396. else
  397. {
  398. dprintf((DEB_ERROR, "GetFileAttributes(%ws) failed, 0x%08lx\n",
  399. s_pszPath, GetLastError()));
  400. MyErrorDialog(hwnd, MSG_FILEATTRIBSFAIL, s_pszPath);
  401. SetErrorFocus(hwnd, IDC_DIRECTORY);
  402. return TRUE;
  403. }
  404. }
  405. else if (!(attribs & FILE_ATTRIBUTE_DIRECTORY))
  406. {
  407. MyErrorDialog(hwnd, MSG_NOT_A_DIRECTORY);
  408. SetErrorFocus(hwnd, IDC_DIRECTORY);
  409. return TRUE;
  410. }
  411. EndDialog(hwnd, TRUE);
  412. break;
  413. }
  414. case IDCANCEL:
  415. EndDialog(hwnd, FALSE);
  416. break;
  417. case IDC_BROWSE:
  418. return OnBrowse(hwnd);
  419. case IDC_DIRECTORY:
  420. if (wNotifyCode == EN_CHANGE)
  421. {
  422. EnableWindow(
  423. GetDlgItem(hwnd, IDC_CREATESHARE),
  424. (GetWindowTextLength(GetDlgItem(hwnd, IDC_DIRECTORY)) > 0) ? TRUE : FALSE);
  425. }
  426. break;
  427. }
  428. return 0;
  429. }
  430. default:
  431. return 0; // didn't process
  432. }
  433. }
  434. // TRUE == success, FALSE == failure
  435. BOOL
  436. FillCombo(
  437. IN HWND hwnd,
  438. IN LPWSTR pszSelectShare, // only one of pszSelectShare & pszSelectPath
  439. IN LPWSTR pszSelectPath // ... can be non-NULL
  440. )
  441. {
  442. LPWSTR pszShareForPath = NULL; // if passed pszSelectPath, this figures out the share name corresponding to it
  443. //
  444. // Fill the combo box with a list of existing shares from which to
  445. // pick one to use as the Dfs share. First, if necessary, try level 2
  446. // so we get a path to compare against pszSelectPath. If that fails with
  447. // access denied, then fall back to level 1.
  448. //
  449. int level;
  450. DWORD dwErr, entriesread, totalentries;
  451. PSHARE_INFO_1 pshi1Base = NULL;
  452. PSHARE_INFO_1 pshi1 = NULL;
  453. if (NULL != pszSelectPath)
  454. {
  455. level = 2;
  456. dwErr = NetShareEnum(
  457. NULL, // Server (local machine)
  458. 2, // Level
  459. (LPBYTE *) &pshi1Base, // Buffer
  460. 0xffffffff, // max len (all)
  461. &entriesread,
  462. &totalentries,
  463. NULL); // resume handle (unimplemented)
  464. }
  465. if (NULL == pshi1Base)
  466. {
  467. level = 1;
  468. dwErr = NetShareEnum(
  469. NULL, // Server (local machine)
  470. 1, // Level
  471. (LPBYTE *) &pshi1Base, // Buffer
  472. 0xffffffff, // max len (all)
  473. &entriesread,
  474. &totalentries,
  475. NULL); // resume handle (unimplemented)
  476. if (dwErr != ERROR_SUCCESS)
  477. {
  478. MyErrorDialog(hwnd, MSG_NOSERVER);
  479. return FALSE;
  480. }
  481. }
  482. // assert(entriesread == totalentries);
  483. HWND hwndCombo = GetDlgItem(hwnd, IDC_DFSROOT);
  484. for (DWORD i = 0; i < entriesread; i++)
  485. {
  486. pshi1 = (level == 1)
  487. ? &(pshi1Base[i])
  488. : (PSHARE_INFO_1)&(((PSHARE_INFO_2)pshi1Base)[i])
  489. ;
  490. if (pshi1->shi1_type == STYPE_DISKTREE)
  491. {
  492. ComboBox_AddString(hwndCombo, pshi1->shi1_netname);
  493. if (NULL != pszSelectPath && NULL == pszShareForPath && level == 2)
  494. {
  495. LPWSTR pszPath = ((PSHARE_INFO_2)pshi1)->shi2_path;
  496. if (0 == _wcsicmp(pszPath, pszSelectPath))
  497. {
  498. pszShareForPath = pshi1->shi1_netname;
  499. }
  500. }
  501. }
  502. }
  503. int index = -1;
  504. if (NULL != pszSelectShare)
  505. {
  506. index = ComboBox_FindStringExact(hwndCombo, -1, pszSelectShare);
  507. if (index == CB_ERR)
  508. {
  509. index = -1;
  510. }
  511. }
  512. else if (NULL != pszSelectPath)
  513. {
  514. if (NULL != pszShareForPath)
  515. {
  516. index = ComboBox_FindStringExact(hwndCombo, -1, pszShareForPath);
  517. if (index == CB_ERR)
  518. {
  519. index = -1;
  520. }
  521. }
  522. }
  523. if (-1 == index)
  524. {
  525. if (ComboBox_GetCount(hwndCombo) > 0)
  526. {
  527. index = 0;
  528. }
  529. }
  530. if (index != -1)
  531. {
  532. ComboBox_SetCurSel(hwndCombo, index);
  533. }
  534. pshi1=&pshi1Base[0];
  535. NetApiBufferFree(pshi1);
  536. return TRUE;
  537. }
  538. //-----------------------------------------------------------------------------
  539. // DFS Share Dialog
  540. //-----------------------------------------------------------------------------
  541. INT_PTR CALLBACK
  542. DlgProcDfsShare(
  543. IN HWND hwnd,
  544. IN UINT uMsg,
  545. IN WPARAM wParam,
  546. IN LPARAM lParam
  547. )
  548. {
  549. static DFS_CONFIGURATION* s_pConfig;
  550. switch (uMsg)
  551. {
  552. case WM_INITDIALOG:
  553. {
  554. s_pConfig = (DFS_CONFIGURATION*) lParam;
  555. if (NULL == s_pConfig)
  556. {
  557. EndDialog(hwnd, -1); // fail!
  558. return TRUE;
  559. }
  560. if (!FillCombo(hwnd, s_pConfig->szRootShare, NULL))
  561. {
  562. EndDialog(hwnd, -1); // fail!
  563. return TRUE;
  564. }
  565. s_pConfig->fHostsDfs=FALSE;
  566. HWND hwndCombo = GetDlgItem(hwnd, IDC_DFSROOT);
  567. int index = ComboBox_GetCurSel(hwndCombo);
  568. if (index == CB_ERR)
  569. EnableWindow(GetDlgItem(hwnd,IDOK), FALSE);
  570. return 1; // didn't call SetFocus
  571. }
  572. case WM_COMMAND:
  573. {
  574. WORD wNotifyCode = HIWORD(wParam);
  575. WORD wID = LOWORD(wParam);
  576. switch (wID)
  577. {
  578. case IDOK:
  579. {
  580. HWND hwndCombo = GetDlgItem(hwnd, IDC_DFSROOT);
  581. int index = ComboBox_GetCurSel(hwndCombo);
  582. if (index != CB_ERR)
  583. {
  584. int len = ComboBox_GetLBTextLen(hwndCombo, index);
  585. if (len < ARRAYLEN(s_pConfig->szRootShare) - 1)
  586. {
  587. ComboBox_GetLBText(hwndCombo, index, s_pConfig->szRootShare);
  588. s_pConfig->fHostsDfs=TRUE;
  589. }
  590. else
  591. {
  592. // internal error!
  593. }
  594. }
  595. else
  596. {
  597. // internal error!
  598. }
  599. EndDialog(hwnd, TRUE);
  600. break;
  601. }
  602. case IDCANCEL:
  603. EndDialog(hwnd, FALSE);
  604. break;
  605. case IDC_NEWSHARE:
  606. {
  607. // let the user create a new share on the machine.
  608. WCHAR szPath[MAX_PATH];
  609. INT_PTR ret = DialogBoxParam(
  610. g_hInstance,
  611. MAKEINTRESOURCE(IDD_NEWSHARE),
  612. hwnd,
  613. DlgProcNewShare,
  614. (LPARAM)szPath);
  615. if (ret == -1 || !ret)
  616. {
  617. // don't need to refresh.
  618. return TRUE;
  619. }
  620. dprintf((DEB_TRACE, "User wants to share path %ws\n", szPath));
  621. HINSTANCE hinst = LoadLibrary(TEXT("ntshrui.dll"));
  622. if (NULL == hinst)
  623. {
  624. MyErrorDialog(hwnd, MSG_NONTSHRUI);
  625. return TRUE;
  626. }
  627. PFNSHARINGDIALOG pfnSharingDialog = (PFNSHARINGDIALOG)GetProcAddress(hinst, "SharingDialogW");
  628. if (NULL == pfnSharingDialog)
  629. {
  630. FreeLibrary(hinst);
  631. MyErrorDialog(hwnd, MSG_NONTSHRUI);
  632. return TRUE;
  633. }
  634. BOOL b = (*pfnSharingDialog)(hwnd, NULL, szPath);
  635. if (!b)
  636. {
  637. // dialog failed
  638. FreeLibrary(hinst);
  639. return TRUE;
  640. }
  641. FreeLibrary(hinst);
  642. HWND hwndCombo = GetDlgItem(hwnd, IDC_DFSROOT);
  643. ComboBox_ResetContent(hwndCombo);
  644. if (!FillCombo(hwnd, NULL, szPath))
  645. {
  646. return TRUE;
  647. }
  648. hwndCombo = GetDlgItem(hwnd, IDC_DFSROOT);
  649. int index = ComboBox_GetCurSel(hwndCombo);
  650. if (index == CB_ERR)
  651. EnableWindow(GetDlgItem(hwnd,IDOK), FALSE);
  652. else
  653. EnableWindow(GetDlgItem(hwnd,IDOK), TRUE);
  654. break;
  655. }
  656. }
  657. return 0;
  658. }
  659. default:
  660. return 0; // didn't process
  661. }
  662. }
  663. extern "C" NET_API_STATUS NET_API_FUNCTION I_NetDfsGetFtServers(
  664. IN PVOID pLDAP OPTIONAL,
  665. IN LPWSTR wszDomainName OPTIONAL,
  666. IN LPWSTR wszDfsName,
  667. OUT LPWSTR **List
  668. );
  669. //-----------------------------------------------------------------------------
  670. // Fill FTDFS for this domain
  671. //-----------------------------------------------------------------------------
  672. // TRUE == success, FALSE == failure
  673. BOOL
  674. FillFTDfsCombo(
  675. IN HWND hwnd
  676. )
  677. {
  678. LPWSTR *list;
  679. if (I_NetDfsGetFtServers(NULL,NULL,NULL,&list)==NO_ERROR)
  680. {
  681. HWND hwndCombo = GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB);
  682. for (int i=0; list[i] != NULL; i++)
  683. {
  684. ComboBox_AddString(hwndCombo, list[i]);
  685. }
  686. NetApiBufferFree(list);
  687. // Select the first item in the combo
  688. ComboBox_SetCurSel(hwndCombo,0);
  689. }
  690. return TRUE;
  691. }
  692. //-----------------------------------------------------------------------------
  693. // Create DFS Share dialog
  694. //-----------------------------------------------------------------------------
  695. INT_PTR CALLBACK
  696. DlgProcCreateDfs(
  697. IN HWND hwnd,
  698. IN UINT uMsg,
  699. IN WPARAM wParam,
  700. IN LPARAM lParam
  701. )
  702. {
  703. static DFS_CONFIGURATION* s_pConfig;
  704. switch (uMsg)
  705. {
  706. case WM_INITDIALOG:
  707. {
  708. s_pConfig = (DFS_CONFIGURATION*) lParam;
  709. // Note that _InitConfigDfs might disable the IDC_JOIN_FTDFS button
  710. _InitConfigDfs(hwnd,s_pConfig);
  711. _ShowDomainName(hwnd);
  712. //
  713. // Enable the IDC_CREATE_FTDFS button only if
  714. // this can be shown not to be a workgroup server.
  715. // JonN 8/22/97
  716. //
  717. BOOL fDisableFTDFS = TRUE;
  718. DSROLE_PRIMARY_DOMAIN_INFO_BASIC* proleinfo = NULL;
  719. DWORD dwErr = DsRoleGetPrimaryDomainInformation(
  720. NULL,
  721. DsRolePrimaryDomainInfoBasic,
  722. reinterpret_cast<PBYTE*>(&proleinfo) );
  723. if ( ERROR_SUCCESS == dwErr )
  724. {
  725. // ASSERT( NULL != proleinfo );
  726. switch (proleinfo->MachineRole)
  727. {
  728. case DsRole_RoleMemberWorkstation:
  729. case DsRole_RoleMemberServer:
  730. case DsRole_RoleBackupDomainController:
  731. case DsRole_RolePrimaryDomainController:
  732. fDisableFTDFS = FALSE;
  733. default:
  734. break;
  735. }
  736. DsRoleFreeMemory( proleinfo );
  737. }
  738. if (fDisableFTDFS)
  739. {
  740. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS), FALSE);
  741. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX), FALSE);
  742. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS), FALSE);
  743. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), FALSE);
  744. SetFocus( GetDlgItem(hwnd, IDC_CREATE_DFS ));
  745. return 0; // called SetFocus
  746. }
  747. return 1; // didn't call SetFocus
  748. }
  749. case WM_COMMAND:
  750. {
  751. WORD wNotifyCode = HIWORD(wParam);
  752. WORD wID = LOWORD(wParam);
  753. switch (wNotifyCode)
  754. {
  755. case EN_CHANGE:
  756. {
  757. EnableWindow(GetDlgItem(hwnd, IDOK), _VerifyState(hwnd,DFSTYPE_CREATE_FTDFS));
  758. return 0;
  759. }
  760. }
  761. switch (wID)
  762. {
  763. case IDOK:
  764. {
  765. switch (s_pConfig->nDfsType)
  766. {
  767. case DFSTYPE_CREATE_FTDFS:
  768. GetDlgItemText(hwnd, IDC_CREATE_FTDFS_TX,s_pConfig->szFTDfs,NNLEN);
  769. if (!_ValidateShare(s_pConfig->szFTDfs))
  770. {
  771. MessageBox(hwnd,L"Invalid FTDfs Name. You must enter a valid FTDfs name before continuing.",L"Dfs Administration",MB_ICONEXCLAMATION | MB_OK);
  772. return 0;
  773. }
  774. break;
  775. case DFSTYPE_JOIN_FTDFS:
  776. {
  777. HWND hwndCombo = GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB);
  778. int index = ComboBox_GetCurSel(hwndCombo);
  779. if (index != CB_ERR)
  780. {
  781. int len = ComboBox_GetLBTextLen(hwndCombo, index);
  782. if (len < ARRAYLEN(s_pConfig->szFTDfs) - 1)
  783. {
  784. ComboBox_GetLBText(hwndCombo, index, s_pConfig->szFTDfs);
  785. }
  786. else
  787. {
  788. // internal error!
  789. }
  790. }
  791. else
  792. {
  793. // internal error!
  794. }
  795. }
  796. break;
  797. case DFSTYPE_CREATE_DFS:
  798. s_pConfig->szFTDfs[0]=NULL;
  799. break;
  800. }
  801. // TODO need to store the option
  802. EndDialog(hwnd, TRUE);
  803. break;
  804. }
  805. // need to cancel everything
  806. case IDCANCEL:
  807. s_pConfig->fFTDfs=FALSE;
  808. EndDialog(hwnd, FALSE);
  809. break;
  810. case IDC_CREATE_FTDFS:
  811. CheckDlgButton(hwnd, IDC_CREATE_FTDFS, BST_CHECKED);
  812. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX), TRUE);
  813. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), FALSE);
  814. s_pConfig->nDfsType=DFSTYPE_CREATE_FTDFS;
  815. EnableWindow(GetDlgItem(hwnd, IDOK), _VerifyState(hwnd,s_pConfig->nDfsType));
  816. s_pConfig->fFTDfs=TRUE;
  817. break;
  818. case IDC_JOIN_FTDFS:
  819. {
  820. CheckDlgButton(hwnd, IDC_JOIN_FTDFS, BST_CHECKED);
  821. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX), FALSE);
  822. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), TRUE);
  823. s_pConfig->nDfsType=DFSTYPE_JOIN_FTDFS;
  824. EnableWindow(GetDlgItem(hwnd, IDOK), _VerifyState(hwnd,s_pConfig->nDfsType));
  825. s_pConfig->fFTDfs=TRUE;
  826. }
  827. break;
  828. case IDC_CREATE_DFS:
  829. CheckDlgButton(hwnd, IDC_CREATE_DFS, BST_CHECKED);
  830. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX), FALSE);
  831. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), FALSE);
  832. s_pConfig->nDfsType=DFSTYPE_CREATE_DFS;
  833. EnableWindow(GetDlgItem(hwnd, IDOK), _VerifyState(hwnd,s_pConfig->nDfsType));
  834. s_pConfig->fFTDfs=FALSE;
  835. break;
  836. }
  837. return 0;
  838. }
  839. }
  840. return 0; // didn't process
  841. }
  842. BOOL _InitConfigDfs(IN HWND hwnd,DFS_CONFIGURATION* pConfig )
  843. {
  844. if (NULL == pConfig)
  845. {
  846. EndDialog(hwnd, -1); // fail!
  847. return TRUE;
  848. }
  849. if (!FillFTDfsCombo(hwnd))
  850. {
  851. EndDialog(hwnd, -1); // fail!
  852. return TRUE;
  853. }
  854. // Test to see if we have any item to join to
  855. EnableWindow(GetDlgItem(hwnd,IDC_JOIN_FTDFS), _VerifyState(hwnd,DFSTYPE_JOIN_FTDFS));
  856. // Disable the join dialog
  857. // Init UI
  858. switch (pConfig->nDfsType)
  859. {
  860. case DFSTYPE_CREATE_FTDFS:
  861. {
  862. CheckDlgButton(hwnd, IDC_CREATE_FTDFS, BST_CHECKED);
  863. SetDlgItemText(hwnd, IDC_CREATE_FTDFS_TX,pConfig->szFTDfs);
  864. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), FALSE);
  865. }
  866. break;
  867. case DFSTYPE_JOIN_FTDFS:
  868. {
  869. CheckDlgButton(hwnd, IDC_JOIN_FTDFS, BST_CHECKED);
  870. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX), FALSE);
  871. HWND hwndCombo = GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB);
  872. int index = -1;
  873. if (NULL != pConfig->szFTDfs)
  874. {
  875. index = ComboBox_FindStringExact(hwndCombo, -1, pConfig->szFTDfs);
  876. if (index == CB_ERR)
  877. {
  878. index = -1;
  879. }
  880. }
  881. else if (NULL != pConfig->szFTDfs)
  882. {
  883. if (NULL != pConfig->szFTDfs)
  884. {
  885. index = ComboBox_FindStringExact(hwndCombo, -1, pConfig->szFTDfs);
  886. if (index == CB_ERR)
  887. {
  888. index = -1;
  889. }
  890. }
  891. }
  892. if (-1 == index)
  893. {
  894. if (ComboBox_GetCount(hwndCombo) > 0)
  895. {
  896. index = 0;
  897. }
  898. }
  899. if (index != -1)
  900. {
  901. ComboBox_SetCurSel(hwndCombo, index);
  902. }
  903. EnableWindow(GetDlgItem(hwnd,IDC_JOIN_FTDFS), _VerifyState(hwnd,DFSTYPE_JOIN_FTDFS));
  904. }
  905. break;
  906. case DFSTYPE_CREATE_DFS:
  907. {
  908. CheckDlgButton(hwnd, IDC_CREATE_DFS, BST_CHECKED);
  909. EnableWindow(GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX), FALSE);
  910. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), FALSE);
  911. }
  912. break;
  913. default:
  914. CheckDlgButton(hwnd, IDC_CREATE_FTDFS, BST_CHECKED);
  915. pConfig->nDfsType=DFSTYPE_CREATE_FTDFS;
  916. pConfig->fFTDfs=TRUE;
  917. EnableWindow(GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB), FALSE);
  918. }
  919. EnableWindow(GetDlgItem(hwnd, IDOK), _VerifyState(hwnd,pConfig->nDfsType));
  920. return TRUE;
  921. }
  922. BOOL _VerifyState(IN HWND hwnd, IN int nType)
  923. {
  924. BOOL frtn=FALSE;
  925. switch (nType)
  926. {
  927. case DFSTYPE_CREATE_FTDFS:
  928. {
  929. TCHAR szText[MAX_PATH];
  930. GetDlgItemText(hwnd, IDC_CREATE_FTDFS_TX,szText,MAX_PATH);
  931. if (wcslen(szText)>0)
  932. frtn=TRUE;
  933. }
  934. break;
  935. case DFSTYPE_JOIN_FTDFS:
  936. {
  937. HWND hwndCombo = GetDlgItem(hwnd, IDC_JOIN_FTDFS_CB);
  938. int index = ComboBox_GetCurSel(hwndCombo);
  939. if (index != CB_ERR)
  940. frtn=TRUE;
  941. }
  942. break;
  943. case DFSTYPE_CREATE_DFS:
  944. {
  945. frtn=TRUE;
  946. }
  947. break;
  948. }
  949. return frtn;
  950. }
  951. BOOL _ValidateShare(LPCWSTR lpszShare)
  952. {
  953. WCHAR pathName[ MAX_PATH ];
  954. DWORD pathtype;
  955. // validate input
  956. if (lpszShare==NULL || wcslen( lpszShare ) > MAX_PATH)
  957. {
  958. return FALSE;
  959. }
  960. // copy string
  961. wcscpy( pathName, lpszShare);
  962. // check for valid path
  963. if( wcslen( pathName ) > NNLEN ||
  964. wcspbrk( pathName, L"\\/ " ) ||
  965. NetpwPathType( pathName, &pathtype, FALSE ) != NO_ERROR ||
  966. pathtype != ITYPE_PATH )
  967. {
  968. return FALSE;
  969. }
  970. return TRUE;
  971. }
  972. DWORD
  973. GetDomainAndComputerName(
  974. OUT LPWSTR wszDomain OPTIONAL,
  975. OUT LPWSTR wszComputer OPTIONAL);
  976. VOID
  977. _ShowDomainName(
  978. IN HWND hwnd)
  979. {
  980. WCHAR wszDomainName[MAX_PATH];
  981. WCHAR wszDomainNamePath[MAX_PATH];
  982. DWORD dwErr = GetDomainAndComputerName( wszDomainName, NULL);
  983. if (dwErr != ERROR_SUCCESS)
  984. return;
  985. if (wcslen(wszDomainName)>MAX_PATH-5)
  986. return;
  987. wsprintf(wszDomainNamePath,L"\\\\%ws\\",wszDomainName);
  988. int len = wcslen(wszDomainNamePath);
  989. SetDlgItemText(hwnd, IDC_CREATE_DOMAIN_TX, wszDomainNamePath);
  990. HDC hdc = GetDC(hwnd);
  991. if (NULL != hdc)
  992. {
  993. // make sure the right font is selected in...
  994. HFONT hfontDlg = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
  995. if (NULL != hfontDlg)
  996. {
  997. HFONT hfontOld = SelectFont(hdc, hfontDlg);
  998. SIZE size;
  999. BOOL b = GetTextExtentPoint32(hdc, wszDomainNamePath, len, &size);
  1000. if (hfontOld)
  1001. {
  1002. SelectFont(hdc, hfontOld);
  1003. }
  1004. if (b)
  1005. {
  1006. // resize the static control to size.cx. Then, resize the
  1007. // adjacent edit control to adjust for it.
  1008. HWND hwndMountAsFixed = GetDlgItem(hwnd, IDC_CREATE_DOMAIN_TX);
  1009. HWND hwndMountAs = GetDlgItem(hwnd, IDC_CREATE_FTDFS_TX);
  1010. RECT rc1, rc2;
  1011. // Get static control coordinates
  1012. GetWindowRect(hwndMountAsFixed, &rc1);
  1013. MapWindowPoints(NULL, hwnd, (LPPOINT)&rc1, 2); // map x,y to dialog-relative coordinates instead of windows-relative coordinates
  1014. // Get edit control coordinates
  1015. GetWindowRect(hwndMountAs, &rc2);
  1016. MapWindowPoints(NULL, hwnd, (LPPOINT)&rc2, 2); // map x,y to dialog-relative coordinates instead of windows-relative coordinates
  1017. // Make sure the edit control doesn't take up more than 50% of
  1018. // the width. If it does, put it in the tab order (it's already
  1019. // a read-only edit control).
  1020. int halfwidth = (rc2.right - rc1.left) / 2;
  1021. if (size.cx > halfwidth)
  1022. {
  1023. size.cx = halfwidth;
  1024. //SetWindowLong(hwndMountAsFixed, GWL_STYLE,
  1025. // GetWindowLong(hwndMountAsFixed, GWL_STYLE) | WS_TABSTOP);
  1026. }
  1027. else
  1028. {
  1029. if (GetFocus() == hwndMountAsFixed)
  1030. {
  1031. ::SetFocus(hwndMountAs);
  1032. }
  1033. //SetWindowLong(hwndMountAsFixed, GWL_STYLE,
  1034. // GetWindowLong(hwndMountAsFixed, GWL_STYLE) & ~WS_TABSTOP);
  1035. }
  1036. size.cx+=10;
  1037. SetWindowPos(
  1038. hwndMountAsFixed,
  1039. NULL,
  1040. 0, 0,
  1041. size.cx,
  1042. rc1.bottom - rc1.top, // leave height intact
  1043. SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  1044. // adjust the edit control
  1045. size.cx += 2; // add a buffer between controls
  1046. SetWindowPos(
  1047. hwndMountAs,
  1048. NULL,
  1049. rc1.left + size.cx, // left side + static width + buffer
  1050. rc2.top,
  1051. (rc2.right - rc1.left) - size.cx, // total width - static width - buffer
  1052. rc2.bottom - rc2.top, // leave height intact
  1053. SWP_NOZORDER | SWP_NOACTIVATE);
  1054. }
  1055. else
  1056. {
  1057. //appDebugOut((DEB_ERROR, "GetTextExtentPoint32 failed, 0x%08lx\n", GetLastError()));
  1058. }
  1059. }
  1060. ReleaseDC(GetDlgItem(hwnd, IDC_CREATE_DOMAIN_TX), hdc);
  1061. }
  1062. else
  1063. {
  1064. //appDebugOut((DEB_ERROR, "GetDC failed, 0x%08lx\n", GetLastError()));
  1065. }
  1066. }
  1067. int
  1068. ConfigDfsShare(
  1069. IN HWND hwnd,
  1070. IN DFS_CONFIGURATION* pConfiguration
  1071. )
  1072. {
  1073. HMODULE hmod=GetModuleHandle(TEXT("dfssetup.dll"));
  1074. return (int)DialogBoxParam(
  1075. hmod,
  1076. MAKEINTRESOURCE(IDD_DFSSHARE),
  1077. hwnd,
  1078. DlgProcDfsShare,
  1079. (LPARAM)pConfiguration);
  1080. }
  1081. int
  1082. ConfigureDfs(
  1083. IN HWND hwnd,
  1084. IN DFS_CONFIGURATION* pConfiguration
  1085. )
  1086. {
  1087. HMODULE hmod=GetModuleHandle(TEXT("dfssetup.dll"));
  1088. return (int)DialogBoxParam(
  1089. hmod,
  1090. MAKEINTRESOURCE(IDD_CREATEDFS),
  1091. hwnd,
  1092. DlgProcCreateDfs,
  1093. (LPARAM)pConfiguration);
  1094. }