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.

983 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. return TRUE;
  437. }
  438. case DOMAIN_DFSROOTS:
  439. {
  440. CWaitCursor WaitCursor;
  441. // get the domain name
  442. HTREEITEM hParentItem = (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hCurrentItem);
  443. _ASSERT(hParentItem);
  444. CComBSTR bstrDomainName;
  445. hr = GetNodeInfo(hParentItem, &bstrDomainName, NULL);
  446. if(FAILED(hr))
  447. SetChildrenToZero(hCurrentItem);
  448. ExpandNode(bstrDomainName, ((NodeType == DOMAIN_DFSROOTS) ? FTDFS : SADFS), hCurrentItem);
  449. return TRUE;
  450. }
  451. default:
  452. break;
  453. }
  454. return FALSE;
  455. }
  456. LRESULT
  457. CConnectToDialog::DoNotifySelectionChanged(
  458. IN LPNM_TREEVIEW i_pNMTreeView
  459. )
  460. /*++
  461. Routine Description:
  462. Handles the WM_NOTIFY for TVN_SELCHANGED.
  463. The text in the edit box is set here to the dfs root path.
  464. Arguments:
  465. i_pNMTreeView - Information related to the tree and the node for which the message
  466. occurred
  467. Return value:
  468. TRUE, if we have handled the message
  469. FALSE, if we ignore it. The system handles the message then.
  470. --*/
  471. {
  472. HRESULT hr = S_OK;
  473. CComBSTR bstrNameForEditBox;
  474. CComBSTR bstrDisplayName;
  475. NODETYPE NodeType;
  476. HTREEITEM hItem = (i_pNMTreeView->itemNew).hItem;
  477. hr = GetNodeInfo(hItem, &bstrDisplayName, &NodeType);
  478. if(FAILED(hr))
  479. return FALSE;
  480. switch (NodeType)
  481. {
  482. case FTDFS:
  483. {
  484. // get its parent's display name
  485. HTREEITEM hParentItem =
  486. (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem);
  487. _ASSERT(hParentItem);
  488. HTREEITEM hGrandParentItem =
  489. (HTREEITEM)SendDlgItemMessage(IDC_TV, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hParentItem);
  490. _ASSERT(hGrandParentItem);
  491. CComBSTR bstrDomainName;
  492. hr = GetNodeInfo(hGrandParentItem, &bstrDomainName, NULL);
  493. if(FAILED(hr))
  494. return FALSE;
  495. bstrNameForEditBox = _T("\\\\");
  496. bstrNameForEditBox += bstrDomainName;
  497. bstrNameForEditBox += _T("\\");
  498. bstrNameForEditBox += bstrDisplayName;
  499. }
  500. break;
  501. /* case SADFS:
  502. bstrNameForEditBox = bstrDisplayName;
  503. break; */
  504. default:
  505. bstrNameForEditBox = _T("");
  506. break;
  507. }
  508. return SetDlgItemText(IDC_DLG_EDIT, bstrNameForEditBox);
  509. }
  510. LRESULT
  511. CConnectToDialog::OnOK(
  512. WORD wNotifyCode,
  513. WORD wID,
  514. HWND hWndCtl,
  515. BOOL& bHandled
  516. )
  517. /*++
  518. Routine Description:
  519. Called when the OK button is pressed.
  520. Arguments:
  521. None used.
  522. Return value:
  523. 0. As it is a command handler
  524. Calls EndDialog(S_OK). S_OK is passed back as return value of DoModal. This indicates
  525. that the dialog ended on OK being pressed
  526. --*/
  527. {
  528. DWORD dwTextLength = 0;
  529. HRESULT hr = S_OK;
  530. m_bstrDfsRoot.Empty();
  531. hr = GetInputText(GetDlgItem(IDC_DLG_EDIT), &m_bstrDfsRoot, &dwTextLength);
  532. if (FAILED(hr))
  533. {
  534. DisplayMessageBoxForHR(hr);
  535. ::SetFocus(GetDlgItem(IDC_DLG_EDIT));
  536. return FALSE;
  537. } else if (0 == dwTextLength)
  538. {
  539. DisplayMessageBoxWithOK(IDS_MSG_EMPTY_DFSROOT);
  540. ::SetFocus(GetDlgItem(IDC_DLG_EDIT));
  541. return FALSE;
  542. }
  543. EndDialog(S_OK);
  544. return 0;
  545. }
  546. LRESULT
  547. CConnectToDialog::OnCancel(
  548. WORD wNotifyCode,
  549. WORD wID,
  550. HWND hWndCtl,
  551. BOOL& bHandled
  552. )
  553. /*++
  554. Routine Description:
  555. Called when the Cancel button is pressed.
  556. Arguments:
  557. None used.
  558. Return value:
  559. 0. As it is a command handler
  560. Calls EndDialog(S_FALSE). S_FALSE is passed back as return value of DoModal.
  561. This indicates that the dialog ended on Cancel being pressed
  562. --*/
  563. {
  564. EndDialog(S_FALSE);
  565. return 0;
  566. }
  567. BOOL CConnectToDialog :: EndDialog(
  568. IN int i_RetCode
  569. )
  570. /*++
  571. Routine Description:
  572. Overridden method that calls the parent method after some internal processing.
  573. This includes deleting the objects stored in the lparams of the TV items.
  574. Arguments:
  575. None used.
  576. Return value:
  577. The return value of the parent method.
  578. --*/
  579. {
  580. ::ShowCursor(FALSE);
  581. SetCursor(::LoadCursor(NULL, IDC_WAIT));
  582. ::ShowCursor(TRUE);
  583. // Remove the Imagelist from the tree. We destroy it in the dtor
  584. SendDlgItemMessage(IDC_TV, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)NULL);
  585. return CDialogImpl<CConnectToDialog>::EndDialog(i_RetCode);
  586. }
  587. STDMETHODIMP CConnectToDialog::get_DfsRoot(
  588. OUT BSTR* pVal
  589. )
  590. /*++
  591. Routine Description:
  592. Return the selected DfsRoot name.
  593. Part of the interface IConnectToDialog.
  594. Arguments:
  595. pVal - Return the BSTR in this.
  596. Return value:
  597. S_OK, if successful
  598. E_FAIL, if the value is unavailable
  599. E_INVALIDARG, if the pointer is invalid(NULL)
  600. E_OUTOFMEMORY if we run out of memory
  601. --*/
  602. {
  603. RETURN_INVALIDARG_IF_NULL(pVal);
  604. if ((!m_bstrDfsRoot) || (0 == m_bstrDfsRoot.Length()))
  605. {
  606. return E_FAIL;
  607. }
  608. *pVal = SysAllocString(m_bstrDfsRoot);
  609. RETURN_OUTOFMEMORY_IF_NULL(*pVal);
  610. return S_OK;
  611. }
  612. void
  613. CConnectToDialog::SetChildrenToZero(
  614. IN HTREEITEM i_hItem
  615. )
  616. {
  617. TV_ITEM TVItem;
  618. ZeroMemory(&TVItem, sizeof TVItem);
  619. TVItem.mask = TVIF_CHILDREN;
  620. TVItem.cChildren = 0;
  621. TVItem.hItem = i_hItem;
  622. SendDlgItemMessage( IDC_TV, TVM_SETITEM, 0, (LPARAM)&TVItem);
  623. }
  624. HRESULT CConnectToDialog::InitTVImageList()
  625. {
  626. m_hImageList = ImageList_LoadBitmap(
  627. _Module.GetModuleInstance(),
  628. MAKEINTRESOURCE(IDB_CONNECT_16x16),
  629. 16,
  630. 8,
  631. CLR_DEFAULT);
  632. if (NULL == m_hImageList)
  633. return E_FAIL;
  634. ImageList_SetOverlayImage(
  635. m_hImageList,
  636. iOVERLAY_BUSY_IMAGE,
  637. OV_BUSY);
  638. ImageList_SetOverlayImage(
  639. m_hImageList,
  640. iOVERLAY_ERROR_IMAGE,
  641. OV_ERROR);
  642. SendDlgItemMessage(
  643. IDC_TV,
  644. TVM_SETIMAGELIST,
  645. TVSIL_NORMAL,
  646. (LPARAM)m_hImageList);
  647. return S_OK;
  648. }
  649. HRESULT
  650. CConnectToDialog::FillupTheTreeView(
  651. )
  652. /*++
  653. Routine Description:
  654. This routine does 2 things, adds the NT 5.0 domain names and the Standalone subtree label.
  655. Also makes the text over the TV invisible.
  656. Arguments:
  657. None.
  658. Return value:
  659. S_OK, On success
  660. HRESULT sent by methods called, if it is not S_OK.
  661. E_FAIL, on other errors.
  662. --*/
  663. {
  664. HRESULT hr = S_OK;
  665. //
  666. // add trusted domains DNS names
  667. // FT dfs roots will be added under these nodes
  668. //
  669. if (m_50DomainList.empty())
  670. return hr;
  671. for(NETNAMELIST::iterator i = m_50DomainList.begin(); i != m_50DomainList.end(); i++)
  672. {
  673. _ASSERTE((*i)->bstrNetName);
  674. hr = AddSingleItemtoTV(
  675. (*i)->bstrNetName,
  676. iDOMAIN_IMAGE,
  677. iDOMAIN_SELECTED_IMAGE,
  678. true, // Children = true
  679. TRUSTED_DOMAIN);
  680. if (FAILED(hr))
  681. break;
  682. }
  683. if (SUCCEEDED(hr))
  684. {
  685. // sort the trusted domains only
  686. SendDlgItemMessage(IDC_TV, TVM_SORTCHILDREN, 0, 0);
  687. }
  688. return hr;
  689. }
  690. HRESULT
  691. CConnectToDialog::AddSingleItemtoTV(
  692. IN const BSTR i_bstrItemLabel,
  693. IN const int i_iImageIndex,
  694. IN const int i_iImageSelectedIndex,
  695. IN const bool i_bChildren,
  696. IN const NODETYPE i_NodeType,
  697. IN HTREEITEM i_hItemParent /* = NULL */
  698. )
  699. {
  700. RETURN_INVALIDARG_IF_NULL(i_bstrItemLabel);
  701. HRESULT hr = S_OK;
  702. TV_INSERTSTRUCT TVInsertData;
  703. TV_ITEM TVItem;
  704. HTREEITEM hCurrentItem = NULL;
  705. ZeroMemory(&TVItem, sizeof(TVItem));
  706. ZeroMemory(&TVInsertData, sizeof(TVInsertData));
  707. TVItem.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  708. if (true == i_bChildren) // To decide whether we add the '+' or not
  709. {
  710. TVItem.mask |= TVIF_CHILDREN;
  711. TVItem.cChildren = 1;
  712. }
  713. TVItem.pszText = i_bstrItemLabel;
  714. TVItem.cchTextMax = _tcslen(i_bstrItemLabel);
  715. TVItem.iImage = i_iImageIndex;
  716. TVItem.iSelectedImage = i_iImageSelectedIndex;
  717. TVItem.lParam = (LPARAM)i_NodeType;
  718. TVInsertData.hParent = i_hItemParent;
  719. TVInsertData.hInsertAfter = TVI_LAST; // No sorting to improve performance
  720. TVInsertData.item = TVItem;
  721. hCurrentItem = (HTREEITEM) SendDlgItemMessage(IDC_TV, TVM_INSERTITEM, 0, (LPARAM) (LPTV_INSERTSTRUCT) &TVInsertData);
  722. if (NULL == hCurrentItem)
  723. return E_FAIL;
  724. return S_OK;
  725. }
  726. HRESULT
  727. CConnectToDialog::GetNodeInfo(
  728. IN HTREEITEM hItem,
  729. OUT BSTR* o_bstrName,
  730. OUT NODETYPE* pNodeType
  731. )
  732. {
  733. _ASSERT(o_bstrName || pNodeType);
  734. HRESULT hr = S_OK;
  735. TCHAR szName[MAX_PATH];
  736. TVITEM TVItem;
  737. ZeroMemory(&TVItem, sizeof(TVItem));
  738. TVItem.hItem = hItem;
  739. if (o_bstrName)
  740. {
  741. TVItem.mask |= TVIF_TEXT;
  742. TVItem.pszText = szName;
  743. TVItem.cchTextMax = MAX_PATH;
  744. }
  745. if (pNodeType)
  746. TVItem.mask |= TVIF_PARAM;
  747. if ( SendDlgItemMessage(IDC_TV, TVM_GETITEM, 0, (LPARAM)&TVItem) )
  748. {
  749. if (o_bstrName)
  750. {
  751. *o_bstrName = SysAllocString(szName);
  752. if (!*o_bstrName)
  753. hr = E_OUTOFMEMORY;
  754. }
  755. if (pNodeType)
  756. {
  757. *pNodeType = (NODETYPE)TVItem.lParam;
  758. }
  759. } else {
  760. hr = E_FAIL;
  761. }
  762. return hr;
  763. }