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.

1029 lines
22 KiB

  1. /*++
  2. Module Name:
  3. Connect.cpp
  4. Abstract:
  5. This module contains the implementation for CConnectToDialog.
  6. This is used to display the Connect To Dfs Root dialog box
  7. --*/
  8. #include "stdafx.h"
  9. #include <process.h>
  10. #include "DfsGUI.h"
  11. #include "Utils.h" // For the LoadStringFromResource and SetStandardCursor method
  12. #include "Connect.h"
  13. #include "dfshelp.h"
  14. static const int iFOLDER_IMAGE = 0;
  15. static const int iFOLDER_SELECTED_IMAGE = 1;
  16. static const int iDOMAIN_IMAGE = 2;
  17. static const int iDOMAIN_SELECTED_IMAGE = 2;
  18. static const int iSTANDALONE_DFSROOT_IMAGE = 3;
  19. static const int iFT_DFSROOT_IMAGE = 3;
  20. static const int iOVERLAY_BUSY_IMAGE = 4;
  21. static const int iOVERLAY_ERROR_IMAGE = 5;
  22. static const int OV_BUSY = 1;
  23. static const int OV_ERROR = 2;
  24. CConnectToDialog::CConnectToDialog()
  25. {
  26. CWaitCursor WaitCursor; // Display the wait cursor
  27. m_pBufferManager = NULL;
  28. m_hImageList = NULL;
  29. (void)Get50Domains(&m_50DomainList);
  30. LoadStringFromResource(IDS_DOMAIN_DFSROOTS_LABEL, &m_bstrDomainDfsRootsLabel);
  31. LoadStringFromResource(IDS_ALL_DFSROOTS_LABEL, &m_bstrAllDfsRootsLabel);
  32. }
  33. CConnectToDialog::~CConnectToDialog()
  34. {
  35. CWaitCursor WaitCursor; // An object to set\reset the cursor to wait cursor
  36. if(NULL != m_hImageList)
  37. {
  38. ImageList_Destroy(m_hImageList);
  39. m_hImageList = NULL;
  40. }
  41. // Free Domain List
  42. FreeNetNameList(&m_50DomainList);
  43. if (m_pBufferManager)
  44. {
  45. //
  46. // signal all related running threads to terminate
  47. //
  48. m_pBufferManager->SignalExit();
  49. //
  50. // decrement the reference count on the CBufferManager instance
  51. //
  52. m_pBufferManager->Release();
  53. }
  54. }
  55. LRESULT
  56. CConnectToDialog::OnInitDialog(
  57. UINT uMsg,
  58. WPARAM wParam,
  59. LPARAM lParam,
  60. BOOL& bHandled
  61. )
  62. {
  63. //
  64. // create instance of CBufferManager
  65. // m_pBufferManager will be set to NULL if CreateInstance() failed.
  66. //
  67. (void) CBufferManager::CreateInstance(m_hWnd, &m_pBufferManager);
  68. ::SendMessage(GetDlgItem(IDC_EditDfsRoot), EM_LIMITTEXT, DNSNAMELIMIT, 0);
  69. InitTVImageList(); // Get the image list for the TV
  70. FillupTheTreeView(); // Fill up the Tree View
  71. return TRUE; // let the dialog box set the focus to any control it wants.
  72. }
  73. /*++
  74. This function is called when a user clicks the ? in the top right of a property sheet
  75. and then clciks a control, or when they hit F1 in a control.
  76. --*/
  77. LRESULT CConnectToDialog::OnCtxHelp(
  78. IN UINT i_uMsg,
  79. IN WPARAM i_wParam,
  80. IN LPARAM i_lParam,
  81. IN OUT BOOL& io_bHandled
  82. )
  83. {
  84. LPHELPINFO lphi = (LPHELPINFO) i_lParam;
  85. if (!lphi || lphi->iContextType != HELPINFO_WINDOW || lphi->iCtrlId < 0)
  86. return FALSE;
  87. ::WinHelp((HWND)(lphi->hItemHandle),
  88. DFS_CTX_HELP_FILE,
  89. HELP_WM_HELP,
  90. (DWORD_PTR)(PVOID)g_aHelpIDs_IDD_DLGCONNECTTO);
  91. return TRUE;
  92. }
  93. /*++
  94. This function handles "What's This" help when a user right clicks the control
  95. --*/
  96. LRESULT CConnectToDialog::OnCtxMenuHelp(
  97. IN UINT i_uMsg,
  98. IN WPARAM i_wParam,
  99. IN LPARAM i_lParam,
  100. IN OUT BOOL& io_bHandled
  101. )
  102. {
  103. ::WinHelp((HWND)i_wParam,
  104. DFS_CTX_HELP_FILE,
  105. HELP_CONTEXTMENU,
  106. (DWORD_PTR)(PVOID)g_aHelpIDs_IDD_DLGCONNECTTO);
  107. return TRUE;
  108. }
  109. LRESULT
  110. CConnectToDialog::OnGetDataThreadDone(
  111. UINT uMsg,
  112. WPARAM wParam,
  113. LPARAM lParam,
  114. BOOL& bHandled
  115. )
  116. {
  117. _ASSERT(m_pBufferManager);
  118. bHandled = TRUE;
  119. CEntryData* pEntry = reinterpret_cast<CEntryData*>(wParam);
  120. HRESULT hr = (HRESULT)lParam;
  121. _ASSERT(pEntry);
  122. CComBSTR bstrNode = pEntry->GetNodeName();
  123. HTREEITEM hItem = pEntry->GetTreeItem();
  124. switch (pEntry->GetEntryType())
  125. {
  126. case BUFFER_ENTRY_TYPE_VALID:
  127. (void)InsertData(pEntry, hItem);
  128. ChangeIcon(hItem, ICONTYPE_NORMAL);
  129. break;
  130. case BUFFER_ENTRY_TYPE_ERROR:
  131. ExpandNodeErrorReport(hItem, bstrNode, pEntry->GetEntryHRESULT());
  132. break;
  133. default:
  134. _ASSERT(FALSE);
  135. break;
  136. }
  137. bHandled = TRUE;
  138. return TRUE;
  139. }
  140. void CConnectToDialog::ChangeIcon(
  141. IN HTREEITEM hItem,
  142. IN ICONTYPE IconType
  143. )
  144. {
  145. TVITEM TVItem;
  146. ZeroMemory(&TVItem, sizeof(TVItem));
  147. TVItem.hItem = hItem;
  148. TVItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  149. switch (IconType)
  150. {
  151. case ICONTYPE_BUSY:
  152. TVItem.iImage = iOVERLAY_BUSY_IMAGE;
  153. TVItem.iSelectedImage = iOVERLAY_BUSY_IMAGE;
  154. break;
  155. case ICONTYPE_ERROR:
  156. TVItem.iImage = iOVERLAY_ERROR_IMAGE;
  157. TVItem.iSelectedImage = iOVERLAY_ERROR_IMAGE;
  158. break;
  159. default: // ICONTYPE_NORMAL
  160. {
  161. NODETYPE NodeType = UNASSIGNED;
  162. HRESULT hr = GetNodeInfo(hItem, NULL, &NodeType);
  163. if (FAILED(hr))
  164. return;
  165. switch (NodeType)
  166. {
  167. case TRUSTED_DOMAIN:
  168. TVItem.iImage = iDOMAIN_IMAGE;
  169. TVItem.iSelectedImage = iDOMAIN_SELECTED_IMAGE;
  170. break;
  171. case DOMAIN_DFSROOTS:
  172. case ALL_DFSROOTS:
  173. TVItem.iImage = iFOLDER_IMAGE;
  174. TVItem.iSelectedImage = iFOLDER_SELECTED_IMAGE;
  175. break;
  176. case FTDFS:
  177. TVItem.iImage = iFT_DFSROOT_IMAGE;
  178. TVItem.iSelectedImage = iFT_DFSROOT_IMAGE;
  179. break;
  180. case SADFS:
  181. TVItem.iImage = iSTANDALONE_DFSROOT_IMAGE;
  182. TVItem.iSelectedImage = iSTANDALONE_DFSROOT_IMAGE;
  183. break;
  184. default:
  185. return;
  186. }
  187. }
  188. }
  189. SendDlgItemMessage(IDC_TV, TVM_SETITEM, 0, (LPARAM)&TVItem);
  190. UpdateWindow();
  191. }
  192. /*
  193. void CConnectToDialog::ChangeIcon(
  194. IN HTREEITEM hItem,
  195. IN ICONTYPE IconType
  196. )
  197. {
  198. TVITEM TVItem;
  199. ZeroMemory(&TVItem, sizeof(TVItem));
  200. TVItem.hItem = hItem;
  201. TVItem.mask = TVIF_STATE;
  202. TVItem.stateMask = TVIS_OVERLAYMASK;
  203. switch (IconType)
  204. {
  205. case ICONTYPE_BUSY:
  206. TVItem.state = INDEXTOOVERLAYMASK(OV_BUSY);
  207. break;
  208. case ICONTYPE_ERROR:
  209. TVItem.state = INDEXTOOVERLAYMASK(OV_ERROR);
  210. break;
  211. default:
  212. TVItem.state = 0;
  213. break;
  214. }
  215. SendDlgItemMessage(IDC_TV, TVM_SETITEM, 0, (LPARAM)&TVItem);
  216. UpdateWindow();
  217. }
  218. */
  219. void CConnectToDialog::ExpandNodeErrorReport(
  220. IN HTREEITEM hItem,
  221. IN PCTSTR pszNodeName,
  222. IN HRESULT hr
  223. )
  224. {
  225. // change the icon to "X"
  226. dfsDebugOut((_T("Failed to expand: %s, hr=%x\n"), pszNodeName, hr));
  227. SetChildrenToZero(hItem);
  228. ChangeIcon(hItem, ICONTYPE_ERROR);
  229. }
  230. void CConnectToDialog::ExpandNode(
  231. IN PCTSTR pszNodeName,
  232. IN NODETYPE nNodeType,
  233. IN HTREEITEM hParentItem
  234. )
  235. {
  236. HRESULT hr = S_OK;
  237. dfsDebugOut((_T("CConnectToDialog::ExpandNode for %s\n"), pszNodeName));
  238. if (m_pBufferManager)
  239. {
  240. //
  241. // change icon to wait
  242. //
  243. ChangeIcon(hParentItem, ICONTYPE_BUSY);
  244. UpdateWindow();
  245. //
  246. // start the thread to calculate a list of servers in the current selected domain
  247. //
  248. CEntryData *pEntry = NULL;
  249. hr = m_pBufferManager->LoadInfo(pszNodeName, nNodeType, hParentItem, &pEntry);
  250. if (SUCCEEDED(hr))
  251. {
  252. //
  253. // Either we get a valid ptr back (ie. data is ready), insert it;
  254. // or, a thread is alreay in progress, wait until a THREAD_DONE message.
  255. //
  256. if (pEntry)
  257. {
  258. _ASSERT(pEntry->GetEntryType() == BUFFER_ENTRY_TYPE_VALID);
  259. (void)InsertData(pEntry, hParentItem);
  260. }
  261. } else
  262. {
  263. ExpandNodeErrorReport(hParentItem, pszNodeName, hr);
  264. }
  265. }
  266. return;
  267. }
  268. HRESULT
  269. CConnectToDialog::InsertData(
  270. IN CEntryData* pEntry,
  271. IN HTREEITEM hParentItem
  272. )
  273. {
  274. _ASSERT(pEntry);
  275. CComBSTR bstrNode = pEntry->GetNodeName();
  276. NODETYPE nNodeType = pEntry->GetNodeType();
  277. NETNAMELIST* pList = pEntry->GetList();
  278. _ASSERT(pList);
  279. HRESULT hr = S_OK;
  280. if (0 == pList->size())
  281. {
  282. SetChildrenToZero(hParentItem);
  283. return hr;
  284. }
  285. int nImageIndex;
  286. int nSelectedImageIndex;
  287. bool bChildren;
  288. nImageIndex = iSTANDALONE_DFSROOT_IMAGE;
  289. nSelectedImageIndex = iSTANDALONE_DFSROOT_IMAGE;
  290. bChildren = false;
  291. for (NETNAMELIST::iterator i = pList->begin(); i != pList->end(); i++)
  292. {
  293. hr = AddSingleItemtoTV(
  294. (*i)->bstrNetName,
  295. nImageIndex,
  296. nSelectedImageIndex,
  297. bChildren,
  298. nNodeType,
  299. hParentItem);
  300. RETURN_IF_FAILED(hr);
  301. }
  302. // make the child items visible
  303. HTREEITEM hChildItem = (HTREEITEM)SendDlgItemMessage(
  304. IDC_TV, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hParentItem);
  305. if (hChildItem)
  306. SendDlgItemMessage(IDC_TV, TVM_ENSUREVISIBLE, 0, (LPARAM)hChildItem);
  307. // sort all its child items
  308. SendDlgItemMessage(IDC_TV, TVM_SORTCHILDREN, 0, (LPARAM)hParentItem);
  309. return S_OK;
  310. }
  311. LRESULT
  312. CConnectToDialog :: OnNotify(
  313. UINT uMsg,
  314. WPARAM wParam,
  315. LPARAM lParam,
  316. BOOL& bHandled
  317. )
  318. /*++
  319. Routine Description:
  320. Called on WM_NOTIFY.
  321. Used to set the Edit box depending on the current selection in the TV.
  322. Arguments:
  323. uMsg - The windows message being sent. This is WM_NOTIFY.
  324. lParam - Info about the message like control for which the message is being sent,
  325. what sub type of message, etc
  326. Return value:
  327. TRUE, if we have handled the message
  328. FALSE, if we ignore it. The system handles the message then.
  329. --*/
  330. {
  331. _ASSERTE(WM_NOTIFY == uMsg);
  332. _ASSERTE(lParam != NULL);
  333. LRESULT lr = FALSE; // Set it to true if we handle this message.
  334. LPNM_TREEVIEW pNMTreeView = (NM_TREEVIEW *) lParam;
  335. bHandled = FALSE;
  336. // Check if the message is for our tree control
  337. if (pNMTreeView && IDC_TV == pNMTreeView->hdr.idFrom)
  338. {
  339. // Check if the message is for selection change.
  340. if (TVN_SELCHANGED == pNMTreeView->hdr.code)
  341. {
  342. lr = DoNotifySelectionChanged(pNMTreeView);
  343. }
  344. else if (TVN_ITEMEXPANDING == pNMTreeView->hdr.code)
  345. {
  346. lr = DoNotifyItemExpanding(pNMTreeView);
  347. }
  348. else if (NM_DBLCLK == pNMTreeView->hdr.code)
  349. {
  350. lr = DoNotifyDoubleClick();
  351. } else
  352. {
  353. lr = FALSE;
  354. }
  355. }
  356. return (lr);
  357. }
  358. LRESULT
  359. CConnectToDialog::DoNotifyDoubleClick(
  360. )
  361. /*++
  362. Routine Description:
  363. Handles the WM_NOTIFY for NM_DBLCLK.
  364. This acts like a click on OK, if the current item is a dfsroot.
  365. Arguments:
  366. None
  367. Return value:
  368. TRUE, if we have handled the message
  369. FALSE, if we ignore it. The system handles the message then.
  370. --*/
  371. {
  372. HRESULT hr = E_FAIL;
  373. HTREEITEM hCurrentItem = NULL;
  374. NODETYPE NodeType = UNASSIGNED;
  375. hCurrentItem = TreeView_GetSelection(GetDlgItem(IDC_TV));
  376. if (NULL == hCurrentItem) // Unable to get the current selection
  377. {
  378. return FALSE;
  379. }
  380. hr = GetNodeInfo(hCurrentItem, NULL, &NodeType);
  381. if(FAILED(hr))
  382. return FALSE;
  383. // Take action only on a dfs root
  384. if (FTDFS == NodeType || SADFS == NodeType)
  385. {
  386. int iHandled = TRUE; // A variable used for communication with OnOK
  387. OnOK(NULL, 1, 0, iHandled); // On a double click, we simulate a click on OK.
  388. _ASSERTE(TRUE == iHandled);
  389. return TRUE;
  390. }
  391. return FALSE;
  392. }
  393. LRESULT
  394. CConnectToDialog::DoNotifyItemExpanding(
  395. IN LPNM_TREEVIEW i_pNMTreeView
  396. )
  397. /*++
  398. Routine Description:
  399. Handles the WM_NOTIFY for TVN_ITEMEXPANDING.
  400. If the expand is for "Standalone label", we create another thread
  401. to fill it up.
  402. Else, we get the Fault Tolerant Dfs Roots for the domain name.
  403. Also we removes the '+' sign, if the tree node is empty.
  404. Arguments:
  405. i_pNMTreeView - Information related to the tree and the node for which the message
  406. occurred
  407. Return value:
  408. TRUE, if we have handled the message
  409. FALSE, if we ignore it. The system handles the message then.
  410. --*/
  411. {
  412. HTREEITEM hCurrentItem = (i_pNMTreeView->itemNew).hItem;
  413. _ASSERT(hCurrentItem);
  414. // If children actually exist, we have nothing to do. It is a normal expand
  415. HTREEITEM hItemChild = (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hCurrentItem);
  416. if (hItemChild)
  417. return FALSE;
  418. NODETYPE NodeType = UNASSIGNED;
  419. HRESULT hr = GetNodeInfo(hCurrentItem, NULL, &NodeType);
  420. if(FAILED(hr))
  421. {
  422. SetChildrenToZero(hCurrentItem);
  423. return TRUE;
  424. }
  425. switch (NodeType)
  426. {
  427. case TRUSTED_DOMAIN:
  428. {
  429. AddSingleItemtoTV(
  430. m_bstrDomainDfsRootsLabel,
  431. iFOLDER_IMAGE,
  432. iFOLDER_SELECTED_IMAGE,
  433. true,
  434. DOMAIN_DFSROOTS,
  435. hCurrentItem);
  436. /* AddSingleItemtoTV(
  437. m_bstrAllDfsRootsLabel,
  438. iFOLDER_IMAGE,
  439. iFOLDER_SELECTED_IMAGE,
  440. true,
  441. ALL_DFSROOTS,
  442. hCurrentItem); */
  443. return TRUE;
  444. }
  445. case DOMAIN_DFSROOTS:
  446. // case ALL_DFSROOTS:
  447. {
  448. CWaitCursor WaitCursor;
  449. // get the domain name
  450. HTREEITEM hParentItem = (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hCurrentItem);
  451. _ASSERT(hParentItem);
  452. CComBSTR bstrDomainName;
  453. hr = GetNodeInfo(hParentItem, &bstrDomainName, NULL);
  454. if(FAILED(hr))
  455. SetChildrenToZero(hCurrentItem);
  456. ExpandNode(bstrDomainName, ((NodeType == DOMAIN_DFSROOTS) ? FTDFS : SADFS), hCurrentItem);
  457. return TRUE;
  458. }
  459. default:
  460. break;
  461. }
  462. return FALSE;
  463. }
  464. LRESULT
  465. CConnectToDialog::DoNotifySelectionChanged(
  466. IN LPNM_TREEVIEW i_pNMTreeView
  467. )
  468. /*++
  469. Routine Description:
  470. Handles the WM_NOTIFY for TVN_SELCHANGED.
  471. The text in the edit box is set here to the dfs root path.
  472. Arguments:
  473. i_pNMTreeView - Information related to the tree and the node for which the message
  474. occurred
  475. Return value:
  476. TRUE, if we have handled the message
  477. FALSE, if we ignore it. The system handles the message then.
  478. --*/
  479. {
  480. HRESULT hr = S_OK;
  481. CComBSTR bstrNameForEditBox;
  482. CComBSTR bstrDisplayName;
  483. NODETYPE NodeType;
  484. HTREEITEM hItem = (i_pNMTreeView->itemNew).hItem;
  485. hr = GetNodeInfo(hItem, &bstrDisplayName, &NodeType);
  486. if(FAILED(hr))
  487. return FALSE;
  488. switch (NodeType)
  489. {
  490. case FTDFS:
  491. {
  492. // get its parent's display name
  493. HTREEITEM hParentItem =
  494. (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem);
  495. _ASSERT(hParentItem);
  496. HTREEITEM hGrandParentItem =
  497. (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hParentItem);
  498. _ASSERT(hGrandParentItem);
  499. CComBSTR bstrDomainName;
  500. hr = GetNodeInfo(hGrandParentItem, &bstrDomainName, NULL);
  501. if(FAILED(hr))
  502. return FALSE;
  503. bstrNameForEditBox = _T("\\\\");
  504. bstrNameForEditBox += bstrDomainName;
  505. bstrNameForEditBox += _T("\\");
  506. bstrNameForEditBox += bstrDisplayName;
  507. }
  508. break;
  509. /* case SADFS:
  510. bstrNameForEditBox = bstrDisplayName;
  511. break; */
  512. default:
  513. bstrNameForEditBox = _T("");
  514. break;
  515. }
  516. return SetDlgItemText(IDC_DLG_EDIT, bstrNameForEditBox);
  517. }
  518. LRESULT
  519. CConnectToDialog::OnOK(
  520. WORD wNotifyCode,
  521. WORD wID,
  522. HWND hWndCtl,
  523. BOOL& bHandled
  524. )
  525. /*++
  526. Routine Description:
  527. Called when the OK button is pressed.
  528. Arguments:
  529. None used.
  530. Return value:
  531. 0. As it is a command handler
  532. Calls EndDialog(S_OK). S_OK is passed back as return value of DoModal. This indicates
  533. that the dialog ended on OK being pressed
  534. --*/
  535. {
  536. DWORD dwTextLength = 0;
  537. HRESULT hr = S_OK;
  538. m_bstrDfsRoot.Empty();
  539. hr = GetInputText(GetDlgItem(IDC_DLG_EDIT), &m_bstrDfsRoot, &dwTextLength);
  540. if (FAILED(hr))
  541. {
  542. DisplayMessageBoxForHR(hr);
  543. ::SetFocus(GetDlgItem(IDC_DLG_EDIT));
  544. return FALSE;
  545. } else if (0 == dwTextLength)
  546. {
  547. DisplayMessageBoxWithOK(IDS_MSG_EMPTY_DFSROOT);
  548. ::SetFocus(GetDlgItem(IDC_DLG_EDIT));
  549. return FALSE;
  550. }
  551. EndDialog(S_OK);
  552. return 0;
  553. }
  554. LRESULT
  555. CConnectToDialog::OnCancel(
  556. WORD wNotifyCode,
  557. WORD wID,
  558. HWND hWndCtl,
  559. BOOL& bHandled
  560. )
  561. /*++
  562. Routine Description:
  563. Called when the Cancel button is pressed.
  564. Arguments:
  565. None used.
  566. Return value:
  567. 0. As it is a command handler
  568. Calls EndDialog(S_FALSE). S_FALSE is passed back as return value of DoModal.
  569. This indicates that the dialog ended on Cancel being pressed
  570. --*/
  571. {
  572. EndDialog(S_FALSE);
  573. return 0;
  574. }
  575. BOOL CConnectToDialog :: EndDialog(
  576. IN int i_RetCode
  577. )
  578. /*++
  579. Routine Description:
  580. Overridden method that calls the parent method after some internal processing.
  581. This includes deleting the objects stored in the lparams of the TV items.
  582. Arguments:
  583. None used.
  584. Return value:
  585. The return value of the parent method.
  586. --*/
  587. {
  588. ::ShowCursor(FALSE);
  589. SetCursor(::LoadCursor(NULL, IDC_WAIT));
  590. ::ShowCursor(TRUE);
  591. // Remove the Imagelist from the tree. We destroy it in the dtor
  592. SendDlgItemMessage(IDC_TV, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)NULL);
  593. return CDialogImpl<CConnectToDialog>::EndDialog(i_RetCode);
  594. }
  595. STDMETHODIMP CConnectToDialog::get_DfsRoot(
  596. OUT BSTR* pVal
  597. )
  598. /*++
  599. Routine Description:
  600. Return the selected DfsRoot name.
  601. Part of the interface IConnectToDialog.
  602. Arguments:
  603. pVal - Return the BSTR in this.
  604. Return value:
  605. S_OK, if successful
  606. E_FAIL, if the value is unavailable
  607. E_INVALIDARG, if the pointer is invalid(NULL)
  608. E_OUTOFMEMORY if we run out of memory
  609. --*/
  610. {
  611. RETURN_INVALIDARG_IF_NULL(pVal);
  612. if ((!m_bstrDfsRoot) || (0 == m_bstrDfsRoot.Length()))
  613. {
  614. return E_FAIL;
  615. }
  616. *pVal = SysAllocString(m_bstrDfsRoot);
  617. RETURN_OUTOFMEMORY_IF_NULL(*pVal);
  618. return S_OK;
  619. }
  620. void
  621. CConnectToDialog::SetChildrenToZero(
  622. IN HTREEITEM i_hItem
  623. )
  624. {
  625. TV_ITEM TVItem;
  626. ZeroMemory(&TVItem, sizeof TVItem);
  627. TVItem.mask = TVIF_CHILDREN;
  628. TVItem.cChildren = 0;
  629. TVItem.hItem = i_hItem;
  630. SendDlgItemMessage( IDC_TV, TVM_SETITEM, 0, (LPARAM)&TVItem);
  631. }
  632. HRESULT CConnectToDialog::InitTVImageList()
  633. {
  634. m_hImageList = ImageList_LoadBitmap(
  635. _Module.GetModuleInstance(),
  636. MAKEINTRESOURCE(IDB_CONNECT_16x16),
  637. 16,
  638. 8,
  639. CLR_DEFAULT);
  640. if (NULL == m_hImageList)
  641. return E_FAIL;
  642. ImageList_SetOverlayImage(
  643. m_hImageList,
  644. iOVERLAY_BUSY_IMAGE,
  645. OV_BUSY);
  646. ImageList_SetOverlayImage(
  647. m_hImageList,
  648. iOVERLAY_ERROR_IMAGE,
  649. OV_ERROR);
  650. SendDlgItemMessage(
  651. IDC_TV,
  652. TVM_SETIMAGELIST,
  653. TVSIL_NORMAL,
  654. (LPARAM)m_hImageList);
  655. return S_OK;
  656. }
  657. HRESULT
  658. CConnectToDialog::FillupTheTreeView(
  659. )
  660. /*++
  661. Routine Description:
  662. This routine does 2 things, adds the NT 5.0 domain names and the Standalone subtree label.
  663. Also makes the text over the TV invisible.
  664. Arguments:
  665. None.
  666. Return value:
  667. S_OK, On success
  668. HRESULT sent by methods called, if it is not S_OK.
  669. E_FAIL, on other errors.
  670. --*/
  671. {
  672. HRESULT hr = S_OK;
  673. //
  674. // add trusted domains DNS names
  675. // FT dfs roots will be added under these nodes
  676. //
  677. if (m_50DomainList.empty())
  678. return hr;
  679. for(NETNAMELIST::iterator i = m_50DomainList.begin(); i != m_50DomainList.end(); i++)
  680. {
  681. _ASSERTE((*i)->bstrNetName);
  682. hr = AddSingleItemtoTV(
  683. (*i)->bstrNetName,
  684. iDOMAIN_IMAGE,
  685. iDOMAIN_SELECTED_IMAGE,
  686. true, // Children = true
  687. TRUSTED_DOMAIN);
  688. if (FAILED(hr))
  689. break;
  690. }
  691. if (SUCCEEDED(hr))
  692. {
  693. // sort the trusted domains only
  694. SendDlgItemMessage(IDC_TV, TVM_SORTCHILDREN, 0, 0);
  695. }
  696. return hr;
  697. }
  698. HRESULT
  699. CConnectToDialog::AddFaultTolerantDfsRoots(
  700. IN HTREEITEM i_hCurrentItem,
  701. IN BSTR i_bstrDomainName
  702. )
  703. {
  704. RETURN_INVALIDARG_IF_NULL(i_hCurrentItem);
  705. RETURN_INVALIDARG_IF_NULL(i_bstrDomainName);
  706. NETNAMELIST DfsRootList;
  707. HRESULT hr = GetDomainDfsRoots(&DfsRootList, i_bstrDomainName);
  708. if (S_OK != hr)
  709. return hr;
  710. for (NETNAMELIST::iterator i = DfsRootList.begin(); i != DfsRootList.end(); i++)
  711. {
  712. hr = AddSingleItemtoTV(
  713. (*i)->bstrNetName,
  714. iFT_DFSROOT_IMAGE,
  715. iFT_DFSROOT_IMAGE,
  716. false,
  717. FTDFS, // Children = false
  718. i_hCurrentItem);
  719. BREAK_IF_FAILED(hr);
  720. }
  721. FreeNetNameList(&DfsRootList);
  722. HTREEITEM hChildItem = (HTREEITEM)SendDlgItemMessage(
  723. IDC_TV, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)i_hCurrentItem);
  724. if (hChildItem)
  725. SendDlgItemMessage(IDC_TV, TVM_ENSUREVISIBLE, 0, (LPARAM)hChildItem);
  726. SendDlgItemMessage(IDC_TV, TVM_SORTCHILDREN, 0, (LPARAM)i_hCurrentItem);
  727. return hr;
  728. }
  729. HRESULT
  730. CConnectToDialog::AddSingleItemtoTV(
  731. IN const BSTR i_bstrItemLabel,
  732. IN const int i_iImageIndex,
  733. IN const int i_iImageSelectedIndex,
  734. IN const bool i_bChildren,
  735. IN const NODETYPE i_NodeType,
  736. IN HTREEITEM i_hItemParent /* = NULL */
  737. )
  738. {
  739. RETURN_INVALIDARG_IF_NULL(i_bstrItemLabel);
  740. HRESULT hr = S_OK;
  741. TV_INSERTSTRUCT TVInsertData;
  742. TV_ITEM TVItem;
  743. HTREEITEM hCurrentItem = NULL;
  744. ZeroMemory(&TVItem, sizeof(TVItem));
  745. ZeroMemory(&TVInsertData, sizeof(TVInsertData));
  746. TVItem.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  747. if (true == i_bChildren) // To decide whether we add the '+' or not
  748. {
  749. TVItem.mask |= TVIF_CHILDREN;
  750. TVItem.cChildren = 1;
  751. }
  752. TVItem.pszText = i_bstrItemLabel;
  753. TVItem.cchTextMax = _tcslen(i_bstrItemLabel);
  754. TVItem.iImage = i_iImageIndex;
  755. TVItem.iSelectedImage = i_iImageSelectedIndex;
  756. TVItem.lParam = (LPARAM)i_NodeType;
  757. TVInsertData.hParent = i_hItemParent;
  758. TVInsertData.hInsertAfter = TVI_LAST; // No sorting to improve performance
  759. TVInsertData.item = TVItem;
  760. hCurrentItem = (HTREEITEM) SendDlgItemMessage(IDC_TV, TVM_INSERTITEM, 0, (LPARAM) (LPTV_INSERTSTRUCT) &TVInsertData);
  761. if (NULL == hCurrentItem)
  762. return E_FAIL;
  763. return S_OK;
  764. }
  765. HRESULT
  766. CConnectToDialog::GetNodeInfo(
  767. IN HTREEITEM hItem,
  768. OUT BSTR* o_bstrName,
  769. OUT NODETYPE* pNodeType
  770. )
  771. {
  772. _ASSERT(o_bstrName || pNodeType);
  773. HRESULT hr = S_OK;
  774. TCHAR szName[MAX_PATH];
  775. TVITEM TVItem;
  776. ZeroMemory(&TVItem, sizeof(TVItem));
  777. TVItem.hItem = hItem;
  778. if (o_bstrName)
  779. {
  780. TVItem.mask |= TVIF_TEXT;
  781. TVItem.pszText = szName;
  782. TVItem.cchTextMax = MAX_PATH;
  783. }
  784. if (pNodeType)
  785. TVItem.mask |= TVIF_PARAM;
  786. if ( SendDlgItemMessage(IDC_TV, TVM_GETITEM, 0, (LPARAM)&TVItem) )
  787. {
  788. if (o_bstrName)
  789. {
  790. *o_bstrName = SysAllocString(szName);
  791. if (!*o_bstrName)
  792. hr = E_OUTOFMEMORY;
  793. }
  794. if (pNodeType)
  795. {
  796. *pNodeType = (NODETYPE)TVItem.lParam;
  797. }
  798. } else {
  799. hr = E_FAIL;
  800. }
  801. return hr;
  802. }