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.

1954 lines
57 KiB

  1. /**********************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1990, 1991 **/
  4. /**********************************************************************/
  5. /*
  6. mprbrows.cxx
  7. Browse dialog for mpr.
  8. FILE HISTORY:
  9. Yi-HsinS 10-Nov-1992 Separated from mprconn.cxx
  10. Yi-HsinS 20-Nov-1992 Added support for printer icons
  11. Yi-HsinS 04-Mar-1993 Added support for multithreading
  12. */
  13. #include <ntincl.hxx>
  14. extern "C"
  15. {
  16. #include <ntlsa.h>
  17. }
  18. #define INCL_NETERRORS
  19. #define INCL_WINDOWS_GDI
  20. #define INCL_WINDOWS
  21. #define INCL_DOSERRORS
  22. #define INCL_NETLIB
  23. #define INCL_NETWKSTA
  24. #include <lmui.hxx>
  25. #define INCL_BLT_DIALOG
  26. #define INCL_BLT_CONTROL
  27. #define INCL_BLT_MSGPOPUP
  28. #include <blt.hxx>
  29. #include <uitrace.hxx>
  30. #include <regkey.hxx>
  31. extern "C"
  32. {
  33. #include <mprconn.h>
  34. #include <npapi.h>
  35. #include <stdlib.h> // For qsort()
  36. }
  37. #include <mprmisc.hxx>
  38. #include <mprbrows.hxx>
  39. #define MAX_NET_PATH MAX_PATH
  40. /*******************************************************************
  41. NAME: MPR_BROWSE_BASE::MPR_BROWSE_BASE
  42. SYNOPSIS: constructor for base connect dialog
  43. NOTES: The use of the ?: operator in DISK vs PRINT means
  44. that we assume if not DISK, must be PRINT. If more
  45. types get added, this need to be taken into account.
  46. HISTORY:
  47. Kevinl? ??-Nov-1991 Created
  48. ChuckC 09-Apr-1992 Added diff MRU keyname support
  49. Added comments/notes.
  50. ********************************************************************/
  51. MPR_BROWSE_BASE::MPR_BROWSE_BASE( const TCHAR *pszDialogName,
  52. HWND hwndOwner,
  53. DEVICE_TYPE devType,
  54. TCHAR *lpHelpFile,
  55. DWORD nHelpContext )
  56. : DIALOG_WINDOW ( pszDialogName, hwndOwner ),
  57. _uiType ( (devType == DEV_TYPE_DISK ) ?
  58. RESOURCETYPE_DISK : RESOURCETYPE_PRINT),
  59. _buttonSearch ( this, IDC_BUTTON_SEARCH ),
  60. _buttonOK ( this, IDOK ),
  61. _boxExpandDomain ( this, IDC_CHECKBOX_EXPANDLOGONDOMAIN ),
  62. _sltShowLBTitle ( this, IDC_SLT_SHOW_LB_TITLE ),
  63. _mprhlbShow ( this, IDC_NET_SHOW,
  64. (devType == DEV_TYPE_DISK) ?
  65. RESOURCETYPE_DISK : RESOURCETYPE_PRINT ),
  66. _sleGetInfo ( this, IDC_SLE_GETINFO_TEXT ),
  67. _pMprEnumThread ( NULL ),
  68. _nlsProviderToExpand (),
  69. _nlsWkstaDomain (),
  70. _fSearchDialogUsed ( FALSE ),
  71. _nlsHelpFile ( lpHelpFile ),
  72. _nHelpContext ( nHelpContext )
  73. {
  74. if ( QueryError() != NERR_Success )
  75. return;
  76. APIERR err;
  77. if ( ((err = _nlsHelpFile.QueryError()) != NERR_Success )
  78. || ((err = _nlsProviderToExpand.QueryError()) != NERR_Success )
  79. || ((err = _nlsWkstaDomain.QueryError()) != NERR_Success )
  80. )
  81. {
  82. ReportError( err );
  83. return;
  84. }
  85. /* Select the correct text for the device dependent text fields
  86. */
  87. MSGID msgidShowLBTitle;
  88. switch ( QueryType() )
  89. {
  90. case RESOURCETYPE_DISK:
  91. msgidShowLBTitle = IDS_SERVERS_LISTBOX_DRIVE ;
  92. break ;
  93. case RESOURCETYPE_PRINT:
  94. msgidShowLBTitle = IDS_SERVERS_LISTBOX_PRINTER ;
  95. break ;
  96. default:
  97. UIASSERT(FALSE) ;
  98. ReportError( ERROR_INVALID_PARAMETER ) ;
  99. return ;
  100. }
  101. /* Get the top level providers
  102. */
  103. err = ::EnumerateShow( QueryHwnd(),
  104. RESOURCE_GLOBALNET,
  105. _uiType,
  106. 0,
  107. NULL,
  108. NULL,
  109. &_mprhlbShow,
  110. FALSE,
  111. &_fSearchDialogUsed,
  112. NULL );
  113. if ( err != NERR_Success )
  114. {
  115. ReportError( err );
  116. return;
  117. }
  118. _mprhlbShow.CalcMaxHorizontalExtent() ;
  119. _buttonSearch.Show( _fSearchDialogUsed );
  120. /* Set the title of the listbox
  121. */
  122. RESOURCE_STR nlsShowLBTitle( msgidShowLBTitle ) ;
  123. if ( err = nlsShowLBTitle.QueryError() )
  124. {
  125. ReportError( err ) ;
  126. return ;
  127. }
  128. _sltShowLBTitle.SetText( nlsShowLBTitle ) ;
  129. //
  130. // Get the name of provider to expand and the domain name the
  131. // workstation is in if we need to.
  132. //
  133. BOOL fExpandFirstProvider = IsExpandDomain();
  134. _boxExpandDomain.SetCheck( fExpandFirstProvider );
  135. if ( fExpandFirstProvider )
  136. {
  137. BOOL fProviderToExpandIsNT ;
  138. RESOURCE_STR nlsGettingInfo( IDS_GETTING_INFO ) ;
  139. //
  140. // find the first in order and if it is NT
  141. //
  142. if ( (( err = nlsGettingInfo.QueryError()) != NERR_Success )
  143. || ((err = QueryProviderToExpand(&_nlsProviderToExpand,
  144. &fProviderToExpandIsNT))
  145. != NERR_Success) )
  146. {
  147. ReportError( err );
  148. return;
  149. }
  150. //
  151. // if it is NT, we special case and need expand domain.
  152. // so lets go find out what domain we are in,
  153. //
  154. if (fProviderToExpandIsNT)
  155. {
  156. err = QueryWkstaDomain( &_nlsWkstaDomain ) ;
  157. if (err != NERR_Success ||
  158. (err = _nlsWkstaDomain.QueryError()) != NERR_Success)
  159. {
  160. if ( (err = _nlsWkstaDomain.CopyFrom(SZ(""))) != NERR_Success )
  161. {
  162. ReportError( err );
  163. return;
  164. }
  165. }
  166. }
  167. INT index = _mprhlbShow.FindItem( _nlsProviderToExpand, 0 );
  168. if ( index >= 0 )
  169. {
  170. /* Disable the listbox until we get all the data
  171. */
  172. _sleGetInfo.SetText( nlsGettingInfo ) ;
  173. ShowMprListbox( FALSE );
  174. return;
  175. }
  176. // At this point, we cannot find provider in the listbox.
  177. // Hence, we don't need to expand the listbox.
  178. }
  179. /* Don't need to start the second thread here.
  180. * So, we can show the listbox right away.
  181. */
  182. ShowMprListbox( TRUE );
  183. } // MPR_BROWSE_BASE::MPR_BROWSE_BASE
  184. /*******************************************************************
  185. NAME: MPR_BROWSE_BASE::~MPR_BROWSE_BASE
  186. SYNOPSIS: desstructor for base connect dialog
  187. NOTES:
  188. HISTORY:
  189. YiHsinS 04-Mar-1993 Created
  190. ********************************************************************/
  191. MPR_BROWSE_BASE::~MPR_BROWSE_BASE()
  192. {
  193. if ( _pMprEnumThread != NULL )
  194. {
  195. _pMprEnumThread->ExitThread();
  196. // Do not delete the thread object, it will delete itself
  197. _pMprEnumThread = NULL;
  198. }
  199. } // MPR_BROWSE_BASE::~MPR_BROWSE_BASE
  200. /*******************************************************************
  201. NAME: MPR_BROWSE_BASE::ShowMprListbox
  202. SYNOPSIS: Enable and show the listbox
  203. NOTES:
  204. HISTORY:
  205. YiHsinS 04-Mar-1993 Created
  206. ********************************************************************/
  207. VOID MPR_BROWSE_BASE::ShowMprListbox( BOOL fShow )
  208. {
  209. _sltShowLBTitle.Enable( fShow ) ;
  210. _mprhlbShow.Enable( fShow );
  211. _sleGetInfo.Show( !fShow );
  212. _mprhlbShow.Show( fShow );
  213. }
  214. /*******************************************************************
  215. NAME: MPR_BROWSE_BASE::MayRun
  216. SYNOPSIS: Start the second thread to get the data
  217. NOTES:
  218. HISTORY:
  219. YiHsinS 04-Mar-1993 Created
  220. ********************************************************************/
  221. BOOL MPR_BROWSE_BASE::MayRun( VOID )
  222. {
  223. /* Start the second thread to get the data only if we need to
  224. * expand the provider and domain
  225. */
  226. if ( IsExpandDomain() )
  227. {
  228. APIERR err = NERR_Success;
  229. /*
  230. * Find the NETRESOURCE of the provider. In the dialog
  231. * constructor, we already check to make sure that the provider
  232. * indeed exist in the listbox.
  233. */
  234. INT index = _mprhlbShow.FindItem( _nlsProviderToExpand, 0 );
  235. UIASSERT( index >= 0 );
  236. MPR_LBI *pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem( index );
  237. UIASSERT( pmprlbi != NULL );
  238. _pMprEnumThread = new MPR_ENUM_THREAD( QueryHwnd(),
  239. QueryType(),
  240. pmprlbi->QueryLPNETRESOURCE(),
  241. _nlsWkstaDomain );
  242. if ( ( _pMprEnumThread == NULL )
  243. || ( (err = _pMprEnumThread->QueryError()) != NERR_Success )
  244. || ( (err = _pMprEnumThread->Resume()) != NERR_Success )
  245. )
  246. {
  247. delete _pMprEnumThread;
  248. _pMprEnumThread = NULL;
  249. err = err? err : ERROR_NOT_ENOUGH_MEMORY;
  250. ::MsgPopup( this, err );
  251. return FALSE;
  252. }
  253. }
  254. return TRUE;
  255. }
  256. /*******************************************************************
  257. NAME: MPR_BROWSE_BASE::OnShowResourcesChange
  258. SYNOPSIS: This method is called when the user takes an action in
  259. the Show Resources listbox.
  260. ENTRY: fEnumChildren - TRUE if the children for the current node in
  261. the "Show" listbox should be enumerated, FALSE otherwise.
  262. In general, the children are only enumerated on an
  263. "expansion" event (double click or enter key).
  264. RETURN: An error value, which is NERR_Success on success.
  265. HISTORY:
  266. rustanl ??-Nov-1991 Created
  267. Johnl 10-Jan-1992 Added Wait indicator
  268. ********************************************************************/
  269. APIERR MPR_BROWSE_BASE::OnShowResourcesChange( BOOL fEnumChildren )
  270. {
  271. AUTO_CURSOR hourglass ;
  272. APIERR err = NERR_Success;
  273. // Get the current listbox data item. This item is a pointer to
  274. // an MPR_LBI. There must be a selection; otherwise, we shouldn't
  275. // have been called.
  276. MPR_LBI * pmprlbi = (MPR_LBI *)_mprhlbShow.QueryItem();
  277. // QueryItem() can fail if its call to SendMessage fails
  278. if (pmprlbi == NULL)
  279. {
  280. return ERROR_GEN_FAILURE;
  281. }
  282. // Update the Network Path MRU if an item was selected
  283. if ( pmprlbi->IsConnectable() )
  284. {
  285. SetNetPathString( pmprlbi->QueryRemoteName() );
  286. SetLastProviderInfo( pmprlbi->QueryLPNETRESOURCE()->lpProvider,
  287. pmprlbi->QueryRemoteName());
  288. }
  289. else
  290. ClearNetPathString();
  291. // Clear the Resources listbox and turn its redraw switch off.
  292. // Then, call the appropriate virtual method to fill it in.
  293. // If nothing was added to the listbox, it is disabled; otherwise, it
  294. // is enabled. (Enable/disable affect keyboard and mouse input.)
  295. // Lastly, the redraw switch is turned on, and the listbox is invalidated.
  296. if ( pmprlbi->IsContainer() && fEnumChildren )
  297. {
  298. //
  299. // Fill lb with children if they haven't been added
  300. // already
  301. //
  302. if ( !pmprlbi->QueryExpanded() && pmprlbi->IsRefreshNeeded() )
  303. {
  304. _mprhlbShow.DeleteChildren( pmprlbi );
  305. pmprlbi->SetRefreshNeeded( FALSE );
  306. }
  307. if ( !pmprlbi->HasChildren() )
  308. {
  309. // Enumerate Children
  310. err = ::EnumerateShow( QueryHwnd(),
  311. RESOURCE_GLOBALNET,
  312. QueryType(),
  313. 0,
  314. pmprlbi->QueryLPNETRESOURCE(),
  315. pmprlbi,
  316. &_mprhlbShow );
  317. }
  318. }
  319. // finally, enanle/disable the search button if need (ie. at least
  320. // one provider is using it.
  321. if (_fSearchDialogUsed)
  322. _buttonSearch.Enable(pmprlbi->IsSearchDialogSupported()) ;
  323. return err;
  324. } // MPR_BROWSE_BASE::OnShowResourcesChange
  325. /*******************************************************************
  326. NAME: MPR_BROWSE_BASE::OnOK
  327. SYNOPSIS: Set the expand domain checkbox
  328. NOTES:
  329. HISTORY:
  330. YiHsinS 04-Mar-1993 Created
  331. ********************************************************************/
  332. BOOL MPR_BROWSE_BASE::OnOK( void )
  333. {
  334. if ( !SetExpandDomain( _boxExpandDomain.QueryCheck() ))
  335. ::MsgPopup(this, IERR_CANNOT_SET_EXPANDLOGONDOMAIN );
  336. return TRUE;
  337. }
  338. /*******************************************************************
  339. NAME: MPR_BROWSE_BASE::OnCommand
  340. SYNOPSIS:
  341. NOTES:
  342. HISTORY:
  343. ********************************************************************/
  344. BOOL MPR_BROWSE_BASE::OnCommand( const CONTROL_EVENT & event )
  345. {
  346. switch ( event.QueryCid() )
  347. {
  348. case IDC_NET_SHOW:
  349. switch ( event.QueryCode() )
  350. {
  351. case LBN_SELCHANGE:
  352. // No error will occur when not enumerating children
  353. OnShowResourcesChange();
  354. return TRUE;
  355. case LBN_DBLCLK:
  356. {
  357. MPR_LBI * pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem();
  358. if ( ShowSearchDialogOnDoubleClick( pmprlbi ) )
  359. return TRUE;
  360. APIERR err = OnShowResourcesChange( TRUE );
  361. switch ( err )
  362. {
  363. case WN_SUCCESS:
  364. break ;
  365. case WN_EXTENDED_ERROR:
  366. MsgExtendedError( this->QueryRobustHwnd() ) ;
  367. break ;
  368. case ERROR_GEN_FAILURE:
  369. err = ERROR_UNEXP_NET_ERR ; // more friendly error
  370. // drop thru
  371. default:
  372. MsgPopup( this, (MSGID) err ) ;
  373. break ;
  374. }
  375. if (( err == NERR_Success )
  376. &&
  377. ( pmprlbi != NULL ))
  378. {
  379. if ( pmprlbi->IsContainer())
  380. {
  381. //
  382. // OnDoubleClick may call AddChildren (which does
  383. // another enum if there are no children). But
  384. // since we have already done the enum and we know
  385. // there are no children, skip this.
  386. //
  387. if ( pmprlbi->HasChildren() )
  388. {
  389. _mprhlbShow.OnDoubleClick( (HIER_LBI *) pmprlbi );
  390. _mprhlbShow.CalcMaxHorizontalExtent() ;
  391. }
  392. }
  393. else
  394. return OnOK();
  395. }
  396. }
  397. return TRUE ;
  398. default:
  399. break;
  400. }
  401. break;
  402. case IDC_BUTTON_SEARCH:
  403. {
  404. UIDEBUG(SZ("Search button was pressed")) ;
  405. MPR_LBI * pmprlbi = (MPR_LBI *) QueryShowLB()->QueryItem();
  406. if (pmprlbi != NULL)
  407. {
  408. CallSearchDialog(pmprlbi) ;
  409. }
  410. }
  411. return TRUE ;
  412. default:
  413. break;
  414. }
  415. return DIALOG_WINDOW::OnCommand( event );
  416. } // MPR_BROWSE_BASE::OnCommand
  417. /*******************************************************************
  418. NAME: MPR_BROWSE_BASE::OnUserMessage
  419. SYNOPSIS: Standard on user processing. Catches the WM_LB_FILLED
  420. response and fills the listbox
  421. NOTES:
  422. HISTORY:
  423. YiHsinS 07-Mar-1992 Created
  424. ********************************************************************/
  425. BOOL MPR_BROWSE_BASE::OnUserMessage( const EVENT & event )
  426. {
  427. APIERR err = NERR_Success ;
  428. switch ( event.QueryMessage() )
  429. {
  430. case WM_LB_FILLED:
  431. {
  432. // If listbox is already enabled, then the user has tried
  433. // to expand a server that he has typed into the path sle.
  434. // Hence, the listbox is already filled with the necessary
  435. // information. So, we just ignore the cache returned to us.
  436. if ( _mprhlbShow.IsEnabled() )
  437. return TRUE;
  438. BOOL fError = (BOOL) event.QueryWParam();
  439. if ( fError ) // Error occurred in the other thread
  440. {
  441. RESOURCE_STR nlsError( (APIERR) event.QueryLParam() );
  442. if ( (err = nlsError.QueryError()) != NERR_Success )
  443. ::MsgPopup( this, err );
  444. else
  445. _sleGetInfo.SetText( nlsError );
  446. return TRUE;
  447. }
  448. //
  449. // Successfully retrieved data in the other thread
  450. //
  451. MPR_RETURN_CACHE *p = (MPR_RETURN_CACHE *) event.QueryLParam() ;
  452. _mprhlbShow.SetRedraw( FALSE );
  453. if ( IsExpandDomain() )
  454. {
  455. if ( !Expand( _nlsProviderToExpand, 0, p->pcacheDomain ) )
  456. {
  457. // Cannot expand the provider name, set the selection
  458. // to the first item
  459. _mprhlbShow.SelectItem( 0 );
  460. }
  461. else
  462. {
  463. // If this is not successful, then the selection is the
  464. // provider name ( expanded ) which is what we want
  465. Expand( _nlsWkstaDomain, 1, p->pcacheServer, TRUE );
  466. }
  467. }
  468. _mprhlbShow.CalcMaxHorizontalExtent() ;
  469. _mprhlbShow.Invalidate( TRUE );
  470. _mprhlbShow.SetRedraw( TRUE );
  471. ShowMprListbox( TRUE );
  472. MPR_LBI *pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem();
  473. /* QueryItem() can fail if its call to SendMessage fails
  474. */
  475. if ( (pmprlbi != NULL) && _fSearchDialogUsed )
  476. _buttonSearch.Enable( pmprlbi->IsSearchDialogSupported());
  477. delete p->pcacheDomain;
  478. p->pcacheDomain = NULL;
  479. delete p->pcacheServer;
  480. p->pcacheServer = NULL;
  481. }
  482. break ;
  483. default:
  484. return DIALOG_WINDOW::OnUserMessage( event ) ;
  485. }
  486. return TRUE;
  487. }
  488. void MPR_BROWSE_BASE::CallSearchDialog( MPR_LBI *pmprlbi )
  489. {
  490. APIERR err ;
  491. TCHAR szNetPath[MAX_NET_PATH] ;
  492. LPNETRESOURCE lpNetRes = pmprlbi->QueryLPNETRESOURCE() ;
  493. PF_NPSearchDialog pfn = (PF_NPSearchDialog)
  494. ::WNetGetSearchDialog(lpNetRes ? lpNetRes->lpProvider : NULL ) ;
  495. DWORD lpnFlags;
  496. if (pfn)
  497. {
  498. err = (*pfn)(QueryRobustHwnd(),
  499. lpNetRes,
  500. szNetPath,
  501. sizeof(szNetPath)/sizeof(szNetPath[0]),
  502. &lpnFlags);
  503. }
  504. else
  505. {
  506. err = WN_NOT_SUPPORTED;
  507. }
  508. if (err == WN_SUCCESS)
  509. {
  510. SetNetPathString( szNetPath );
  511. SetFocusToNetPath();
  512. if ( lpnFlags == WNSRCH_REFRESH_FIRST_LEVEL )
  513. {
  514. AUTO_CURSOR autocur;
  515. MPR_HIER_LISTBOX *plb = QueryShowLB();
  516. INT nPrevProvider = plb->FindNextProvider( 0 );
  517. UIASSERT ( nPrevProvider >= 0 );
  518. INT nNextProvider = plb->FindNextProvider( nPrevProvider + 1);
  519. INT nCurrent = plb->QueryCurrentItem();
  520. do {
  521. if ( ( nCurrent >= nPrevProvider )
  522. && ( ( nCurrent < nNextProvider )
  523. || ( nNextProvider < 0 )
  524. )
  525. )
  526. {
  527. MPR_LBI *plbi = (MPR_LBI *) plb->QueryItem( nPrevProvider );
  528. UIASSERT ( plbi != NULL );
  529. plb->CollapseItem( plbi );
  530. plb->SelectItem( nPrevProvider );
  531. plb->DeleteChildren( plbi );
  532. // Enumerate Children
  533. err = ::EnumerateShow( QueryHwnd(),
  534. RESOURCE_GLOBALNET,
  535. QueryType(),
  536. 0,
  537. plbi->QueryLPNETRESOURCE(),
  538. plbi,
  539. &_mprhlbShow );
  540. err = err ? err : plb->ExpandItem( plbi );
  541. break;
  542. }
  543. else if ( nPrevProvider < 0 )
  544. {
  545. UIASSERT( FALSE );
  546. break;
  547. }
  548. nPrevProvider = nNextProvider;
  549. nNextProvider = plb->FindNextProvider( nPrevProvider + 1);
  550. } while ( TRUE );
  551. }
  552. _mprhlbShow.CalcMaxHorizontalExtent() ;
  553. }
  554. if ( err != WN_SUCCESS )
  555. ::MsgPopup( this, err );
  556. }
  557. /*******************************************************************
  558. NAME: MPR_BROWSE_BASE::ShowSearchDialogOnDoubleClick
  559. SYNOPSIS: This method is called when the user double clicks
  560. an item in the listbox or select an time/hit Enter key
  561. in the listbox.
  562. ENTRY: pmprlbi - the item selected in the listbox
  563. RETURN: TRUE if we have shown the search dialog, FALSE otherwise.
  564. NOTES: We will only show the search dialog only if the item
  565. is a provider that supports the search dialog but
  566. not global enumeration.
  567. HISTORY:
  568. Yi-HsinS 30-Nov-1992 Created
  569. ********************************************************************/
  570. BOOL MPR_BROWSE_BASE::ShowSearchDialogOnDoubleClick( MPR_LBI *pmprlbi )
  571. {
  572. if ( ( pmprlbi != NULL )
  573. && ( pmprlbi->IsProvider() )
  574. )
  575. {
  576. if ( !pmprlbi->QueryExpanded()
  577. && pmprlbi->IsSearchDialogSupported()
  578. && !WNetSupportGlobalEnum((TCHAR *) pmprlbi->QueryRemoteName())
  579. )
  580. {
  581. CallSearchDialog(pmprlbi) ;
  582. return TRUE;
  583. }
  584. }
  585. return FALSE;
  586. }
  587. /*******************************************************************
  588. NAME: MPR_BROWSE_BASE::QueryWkstaDomain
  589. SYNOPSIS: Get the user's logged on domain
  590. ENTRY: pnlsWkstaDomain - NLS_STR to receive domain
  591. EXIT: pnlsWkstaDomain will contain the user name or the empty string
  592. RETURNS: NERR_Success if successful, error code otherwise
  593. NOTES:
  594. HISTORY:
  595. Yi-HsinS 4-Nov-1992 Created
  596. ********************************************************************/
  597. #define NETAPI_DLL_STRING SZ("netapi32.dll")
  598. #define NETWKSTAUSERGETINFO ("NetWkstaGetInfo")
  599. #define NETAPIBUFFERFREE ("NetApiBufferFree")
  600. typedef APIERR (*PNETWKSTAUSERGETINFO)( const TCHAR FAR *, DWORD, BYTE FAR **);
  601. typedef APIERR (*PNETAPIBUFFERFREE)( BYTE * );
  602. APIERR MPR_BROWSE_BASE::QueryWkstaDomain( NLS_STR *pnlsWkstaDomain )
  603. {
  604. *pnlsWkstaDomain = SZ("");
  605. HMODULE hmod = ::LoadLibraryEx( NETAPI_DLL_STRING,
  606. NULL,
  607. LOAD_WITH_ALTERED_SEARCH_PATH );
  608. if ( hmod == NULL )
  609. return ::GetLastError();
  610. APIERR err;
  611. PNETWKSTAUSERGETINFO plpfn;
  612. plpfn = (PNETWKSTAUSERGETINFO) ::GetProcAddress( hmod, NETWKSTAUSERGETINFO);
  613. if ( plpfn == NULL )
  614. {
  615. err = ::GetLastError();
  616. }
  617. else
  618. {
  619. WKSTA_INFO_100 *pwki100 = NULL;
  620. err = (*plpfn)( NULL, 100, (BYTE **) &pwki100 );
  621. if ( err == NERR_Success )
  622. {
  623. err = pnlsWkstaDomain->CopyFrom( pwki100->wki100_langroup );
  624. }
  625. PNETAPIBUFFERFREE plpfnBufferFree;
  626. plpfnBufferFree = (PNETAPIBUFFERFREE) ::GetProcAddress( hmod, NETAPIBUFFERFREE );
  627. if ( plpfnBufferFree != NULL )
  628. {
  629. // The error code is not interesting here
  630. // We got the logon name and we'll just trying to free the
  631. // buffer if possible
  632. (*plpfnBufferFree)( (BYTE *) pwki100 );
  633. }
  634. }
  635. ::FreeLibrary( hmod );
  636. return err;
  637. }
  638. /*******************************************************************
  639. NAME: MPR_BROWSE_BASE::QueryProviderToExpand
  640. SYNOPSIS: Get the lanman provider name
  641. ENTRY: pnlsProvider - NLS_STR to receive lanman provider name
  642. EXIT: pnlsProvider will contain the provider name or the
  643. empty string
  644. contents of pfIsNT is TRUE if the provider picked in
  645. NT Lanman. else tis FALSE
  646. RETURNS: NERR_Success if successful, error code otherwise
  647. NOTES:
  648. HISTORY:
  649. Yi-HsinS 4-Nov-1992 Created
  650. ********************************************************************/
  651. #define LANMAN_WORKSTATION_NODE SZ("System\\CurrentControlSet\\Services\\LanmanWorkstation\\networkprovider")
  652. #define PROVIDER_VALUE_NAME SZ("Name")
  653. APIERR MPR_BROWSE_BASE::QueryProviderToExpand( NLS_STR *pnlsProvider,
  654. BOOL *pfIsNT )
  655. {
  656. //
  657. // init some defaults
  658. //
  659. *pnlsProvider = SZ("");
  660. *pfIsNT = FALSE ;
  661. APIERR err ;
  662. NLS_STR nlsLanmanProvider;
  663. if ((err = nlsLanmanProvider.QueryError()) != NERR_Success)
  664. return err ;
  665. //
  666. // get the NT supplied provider if we can
  667. //
  668. REG_KEY *pRegKeyLocalMachine = REG_KEY::QueryLocalMachine();
  669. if ( ( pRegKeyLocalMachine == NULL )
  670. || ( (err = pRegKeyLocalMachine->QueryError()) != NERR_Success )
  671. )
  672. {
  673. //
  674. // if an error occurs just set the LM provider to be empty
  675. //
  676. err = nlsLanmanProvider.CopyFrom(SZ("")) ;
  677. }
  678. else
  679. {
  680. //
  681. // get the name from registry
  682. //
  683. ALIAS_STR nlsNode( LANMAN_WORKSTATION_NODE );
  684. REG_KEY regkey( *pRegKeyLocalMachine, nlsNode );
  685. if ( ((err = regkey.QueryError()) != NERR_Success )
  686. || ((err = regkey.QueryValue( PROVIDER_VALUE_NAME,
  687. &nlsLanmanProvider ))
  688. != NERR_Success )
  689. )
  690. {
  691. //
  692. // if an error occurs just set the LM provider to be empty
  693. //
  694. err = nlsLanmanProvider.CopyFrom(SZ("")) ;
  695. }
  696. }
  697. delete pRegKeyLocalMachine;
  698. pRegKeyLocalMachine = NULL;
  699. if (err != NERR_Success)
  700. return err ;
  701. //
  702. // now call WNet to enum the providers, and pick the first in order.
  703. // this will be the one we choose to expand.
  704. //
  705. HANDLE hEnum;
  706. BOOL fFoundOne = FALSE ;
  707. DWORD dwErr = WNetOpenEnum( RESOURCE_GLOBALNET,
  708. RESOURCETYPE_DISK,
  709. 0,
  710. NULL,
  711. &hEnum );
  712. if (dwErr == WN_SUCCESS)
  713. {
  714. BUFFER buf( 1024 );
  715. DWORD dwEnumErr = buf.QueryError() ;
  716. while ( dwEnumErr == NERR_Success )
  717. {
  718. DWORD dwCount = 0xffffffff; // Return as many as possible
  719. DWORD dwBuffSize = buf.QuerySize() ;
  720. dwEnumErr = WNetEnumResource( hEnum,
  721. &dwCount,
  722. buf.QueryPtr(),
  723. &dwBuffSize );
  724. switch ( dwEnumErr )
  725. {
  726. case WN_SUCCESS:
  727. //
  728. // just use the very first entry
  729. //
  730. if (dwCount >= 1)
  731. {
  732. NETRESOURCE *pnetres = (NETRESOURCE * )buf.QueryPtr();
  733. *pnlsProvider = pnetres->lpRemoteName ;
  734. fFoundOne = TRUE ;
  735. err = pnlsProvider->QueryError() ;
  736. }
  737. //
  738. // exit the loop by setting this
  739. //
  740. dwEnumErr = WN_NO_MORE_ENTRIES ;
  741. break ;
  742. //
  743. // The buffer wasn't big enough for even one entry,
  744. // resize it and try again.
  745. //
  746. case WN_MORE_DATA:
  747. if ( dwEnumErr = buf.Resize( buf.QuerySize()*2 ))
  748. break;
  749. //
  750. // Continue looping
  751. //
  752. dwEnumErr = WN_SUCCESS;
  753. break;
  754. case WN_NO_MORE_ENTRIES: // Success code, map below
  755. default:
  756. //
  757. // all errors will cause us to exit
  758. //
  759. break;
  760. } // switch
  761. } // while
  762. WNetCloseEnum( hEnum );
  763. }
  764. if (err)
  765. return err ;
  766. if (fFoundOne)
  767. {
  768. //
  769. // since err was not set, we know pnlsProvider is all setup.
  770. // all we need do is set fIsNT.
  771. //
  772. *pfIsNT = (*pnlsProvider == nlsLanmanProvider) ;
  773. }
  774. return NERR_Success ;
  775. }
  776. /*******************************************************************
  777. NAME: MPR_BROWSE_BASE::Expand
  778. SYNOPSIS: Find the given item in the listbox and expand it
  779. ENTRY: psz - The item to search for
  780. nLevel - The indentation level of the item
  781. fTopIndex - TRUE if we want to set the item to top index
  782. EXIT:
  783. RETURNS: TRUE if we can at least find and select the item requested,
  784. FALSE otherwise
  785. NOTES:
  786. HISTORY:
  787. Yi-HsinS 4-Nov-1992 Created
  788. ********************************************************************/
  789. BOOL MPR_BROWSE_BASE::Expand( const TCHAR *psz,
  790. INT nLevel,
  791. MPR_LBI_CACHE *pcache,
  792. BOOL fTopIndex )
  793. {
  794. if (psz == NULL || *psz == 0)
  795. return FALSE ;
  796. INT index = _mprhlbShow.FindItem( psz, nLevel );
  797. if ( index < 0 )
  798. return FALSE;
  799. _mprhlbShow.SelectItem( index );
  800. if ( ( pcache != NULL )
  801. && ( pcache->QueryCount() != 0 )
  802. )
  803. {
  804. MPR_LBI * pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem();
  805. UIASSERT( pmprlbi != NULL);
  806. _mprhlbShow.AddSortedItems( (HIER_LBI **) pcache->QueryPtr(),
  807. pcache->QueryCount(),
  808. pmprlbi );
  809. if ( pmprlbi->IsContainer() )
  810. _mprhlbShow.OnDoubleClick( (HIER_LBI *) pmprlbi );
  811. }
  812. if ( fTopIndex )
  813. _mprhlbShow.SetTopIndex( index );
  814. return TRUE;
  815. }
  816. /*******************************************************************
  817. NAME: MPR_BROWSE_BASE::QueryHelpFile
  818. SYNOPSIS: overwrites the default QueryHelpFile in DIALOG_WINDOW
  819. to use an app supplied help rather than NETWORK.HLP if
  820. we were given onr at construct time.
  821. ENTRY:
  822. EXIT:
  823. RETURNS: a pointer to a string which is the help file to use.
  824. NOTES:
  825. HISTORY:
  826. ChuckC 26-Cct-1992 Created
  827. ********************************************************************/
  828. const TCHAR * MPR_BROWSE_BASE::QueryHelpFile( ULONG nHelpContext )
  829. {
  830. //
  831. // if we were given a helpfile at construct time,
  832. // we use the given help file.
  833. //
  834. const TCHAR *pszHelpFile = QuerySuppliedHelpFile() ;
  835. if (pszHelpFile && *pszHelpFile)
  836. {
  837. return pszHelpFile ;
  838. }
  839. return DIALOG_WINDOW::QueryHelpFile(nHelpContext) ;
  840. }
  841. /*******************************************************************
  842. NAME: MPR_BROWSE_BASE::IsExpandDomain
  843. SYNOPSIS: see if user wants to expand the logon domain at startup
  844. ENTRY:
  845. EXIT:
  846. RETURNS: TRUE or FALSE
  847. NOTES:
  848. HISTORY:
  849. Yi-HsinS 4-Nov-1992 Created
  850. ********************************************************************/
  851. BOOL MPR_BROWSE_BASE::IsExpandDomain( VOID )
  852. {
  853. // By adding the two, we are guaranteed to have enough
  854. TCHAR szAnswer[(sizeof(MPR_YES_VALUE)+sizeof(MPR_NO_VALUE))/sizeof(TCHAR)];
  855. ULONG len = sizeof(szAnswer)/sizeof(szAnswer[0]);
  856. ULONG iRes = ::GetProfileString((const TCHAR *)MPR_NETWORK_SECTION,
  857. (const TCHAR *)MPR_EXPANDLOGONDOMAIN_KEY,
  858. (const TCHAR *)MPR_YES_VALUE,
  859. szAnswer,
  860. len);
  861. if (iRes == len) // error
  862. return(TRUE);
  863. return( ::stricmpf(szAnswer,(const TCHAR *)MPR_YES_VALUE)==0 );
  864. }
  865. /*******************************************************************
  866. NAME: MPR_BROWSE_BASE::SetExpandDomain
  867. SYNOPSIS: sets the ExpandLogonDomain bit in user profile
  868. ENTRY:
  869. EXIT:
  870. RETURNS: BOOL indicating success (TRUE) or failure (FALSE)
  871. NOTES:
  872. HISTORY:
  873. Yi-HsinS 4-Nov-1992 Created
  874. ********************************************************************/
  875. BOOL MPR_BROWSE_BASE::SetExpandDomain(BOOL fExpand)
  876. {
  877. return(::WriteProfileString( (const TCHAR *)MPR_NETWORK_SECTION,
  878. (const TCHAR *)MPR_EXPANDLOGONDOMAIN_KEY,
  879. fExpand? (const TCHAR *)MPR_YES_VALUE
  880. : (const TCHAR *)MPR_NO_VALUE ) != 0) ;
  881. }
  882. /*******************************************************************
  883. NAME: MPR_BROWSE_DIALOG::MPR_BROWSE_DIALOG
  884. SYNOPSIS: Constructor for the browse dialog. Almost all of the
  885. functionality is contained in the base class, we watch
  886. for the OK button here.
  887. ENTRY: hwndOwner - Owner window handle
  888. devType - Type of device we are dealing with
  889. RETURNS:
  890. NOTES:
  891. HISTORY:
  892. Johnl 27-Jan-1992 Created
  893. ********************************************************************/
  894. MPR_BROWSE_DIALOG::MPR_BROWSE_DIALOG( HWND hwndOwner,
  895. DEVICE_TYPE devType,
  896. TCHAR *lpHelpFile,
  897. DWORD nHelpContext,
  898. NLS_STR *pnlsPath,
  899. PFUNC_VALIDATION_CALLBACK pfuncValidation)
  900. : MPR_BROWSE_BASE ( MAKEINTRESOURCE(IDD_NET_BROWSE_DIALOG),
  901. hwndOwner,
  902. devType,
  903. lpHelpFile,
  904. nHelpContext ),
  905. _sleNetPath ( this, IDC_NETPATH_CONTROL ),
  906. _pnlsPath ( pnlsPath ),
  907. _pfuncValidation( pfuncValidation )
  908. {
  909. UIASSERT( pnlsPath != NULL );
  910. if ( QueryError() )
  911. return ;
  912. RESOURCE_STR nlsTitle( devType==DEV_TYPE_DISK? IDS_BROWSE_DRIVE_CAPTION
  913. : IDS_BROWSE_PRINTER_CAPTION);
  914. APIERR err = nlsTitle.QueryError();
  915. if (err != NERR_Success )
  916. {
  917. ReportError( err ) ;
  918. return ;
  919. }
  920. SetText( nlsTitle ) ;
  921. // Set focus to the Network Path field
  922. SetFocusToNetPath();
  923. }
  924. MPR_BROWSE_DIALOG::~MPR_BROWSE_DIALOG()
  925. {
  926. /* Nothing to do */
  927. }
  928. /*******************************************************************
  929. NAME: MPR_BROWSE_DIALOG::OnOK
  930. SYNOPSIS: The user pressed the OK button so try the following:
  931. If net path is not empty,
  932. attempt to connect to the server in the net path
  933. else if current item in show listbox is expandable
  934. attempt to expand that item
  935. EXIT:
  936. RETURNS:
  937. NOTES:
  938. HISTORY:
  939. Johnl 27-Jan-1992 Created
  940. ********************************************************************/
  941. BOOL MPR_BROWSE_DIALOG::OnOK( void )
  942. {
  943. if ( QueryShowLB()->HasFocus() && ( _sleNetPath.QueryTextLength() == 0 ))
  944. {
  945. MPR_LBI * pmprlbi = (MPR_LBI *) QueryShowLB()->QueryItem();
  946. if ( pmprlbi )
  947. {
  948. if ( !ShowSearchDialogOnDoubleClick( pmprlbi ) )
  949. QueryShowLB()->OnDoubleClick( (HIER_LBI *) pmprlbi );
  950. }
  951. }
  952. else
  953. {
  954. APIERR err = _sleNetPath.QueryText( _pnlsPath );
  955. if ( err == NERR_Success )
  956. {
  957. if ( ( _pfuncValidation == NULL )
  958. || ((*_pfuncValidation)( (LPTSTR) _pnlsPath->QueryPch() ) )
  959. )
  960. {
  961. Dismiss( TRUE );
  962. }
  963. else
  964. {
  965. err = IERR_INVALID_PATH;
  966. }
  967. }
  968. if ( err != NERR_Success )
  969. {
  970. ::MsgPopup( this, err );
  971. _sleNetPath.SelectString();
  972. _sleNetPath.ClaimFocus();
  973. }
  974. }
  975. return MPR_BROWSE_BASE::OnOK() ;
  976. }
  977. /*******************************************************************
  978. NAME: MPR_BROWSE_DIALOG::QueryHelpContext
  979. SYNOPSIS: Typical help context method
  980. HISTORY:
  981. Johnl 27-Jan-1992 Created
  982. ********************************************************************/
  983. ULONG MPR_BROWSE_DIALOG::QueryHelpContext( void )
  984. {
  985. return QuerySuppliedHelpContext() ;
  986. }
  987. /*******************************************************************
  988. NAME: MPR_HIER_LISTBOX::MPR_HIER_LISTBOX
  989. SYNOPSIS: Constructor
  990. ENTRY: powin - pointer to owner window
  991. cid - control id
  992. EXIT:
  993. RETURNS:
  994. NOTES:
  995. HISTORY:
  996. Johnl 30-Jan-1992 Commented
  997. ********************************************************************/
  998. MPR_HIER_LISTBOX::MPR_HIER_LISTBOX( OWNER_WINDOW * powin, CID cid, UINT uiType )
  999. : HIER_LISTBOX( powin, cid, FALSE, FONT_DEFAULT, FALSE ),
  1000. _dmapGeneric ( BMID_BROWSE_GEN ),
  1001. _dmapGenericExpanded( BMID_BROWSE_GENEX ),
  1002. _dmapGenericNoExpand( BMID_BROWSE_GENNOX ),
  1003. _dmapProvider ( BMID_BROWSE_PROV),
  1004. _dmapProviderExpanded( BMID_BROWSE_PROVEX ),
  1005. _dmapDomain ( BMID_BROWSE_DOM ),
  1006. _dmapDomainExpanded ( BMID_BROWSE_DOMEX ),
  1007. _dmapDomainNoExpand ( BMID_BROWSE_DOMNOX ),
  1008. _dmapServer ( BMID_BROWSE_SRV ),
  1009. _dmapServerExpanded ( BMID_BROWSE_SRVEX ),
  1010. _dmapServerNoExpand ( BMID_BROWSE_SRVNOX ),
  1011. _dmapFile ( BMID_BROWSE_FILE ),
  1012. _dmapFileExpanded ( BMID_BROWSE_FILEEX ),
  1013. _dmapFileNoExpand ( BMID_BROWSE_FILENOX ),
  1014. _dmapTree ( BMID_BROWSE_TREE ),
  1015. _dmapTreeExpanded ( BMID_BROWSE_TREEEX ),
  1016. _dmapTreeNoExpand ( BMID_BROWSE_TREENOX ),
  1017. _dmapGroup ( BMID_BROWSE_GROUP ),
  1018. _dmapGroupExpanded ( BMID_BROWSE_GROUPEX ),
  1019. _dmapGroupNoExpand ( BMID_BROWSE_GROUPNOX ),
  1020. _dmapShare ( uiType == DEV_TYPE_DISK? BMID_BROWSE_SHR
  1021. : BMID_BROWSE_PRINT ),
  1022. _dmapShareExpanded ( uiType == DEV_TYPE_DISK? BMID_BROWSE_SHREX
  1023. : BMID_BROWSE_PRINTEX ),
  1024. _dmapShareNoExpand ( uiType == DEV_TYPE_DISK? BMID_BROWSE_SHRNOX
  1025. : BMID_BROWSE_PRINTNOX ),
  1026. _uiType ( uiType ),
  1027. _nMaxPelIndent (0)
  1028. {
  1029. if ( QueryError() )
  1030. return ;
  1031. APIERR err ;
  1032. if ( (err = _dmapGeneric.QueryError()) ||
  1033. (err = _dmapGenericExpanded.QueryError()) ||
  1034. (err = _dmapGenericNoExpand.QueryError()) ||
  1035. (err = _dmapDomain.QueryError()) ||
  1036. (err = _dmapDomainExpanded.QueryError()) ||
  1037. (err = _dmapDomainNoExpand.QueryError()) ||
  1038. (err = _dmapShare.QueryError()) ||
  1039. (err = _dmapShareExpanded.QueryError()) ||
  1040. (err = _dmapShareNoExpand.QueryError()) ||
  1041. (err = _dmapServer.QueryError()) ||
  1042. (err = _dmapServerExpanded.QueryError()) ||
  1043. (err = _dmapServerNoExpand.QueryError()) ||
  1044. (err = _dmapFile.QueryError()) ||
  1045. (err = _dmapFileExpanded.QueryError()) ||
  1046. (err = _dmapFileNoExpand.QueryError()) ||
  1047. (err = _dmapTree.QueryError()) ||
  1048. (err = _dmapTreeExpanded.QueryError()) ||
  1049. (err = _dmapTreeNoExpand.QueryError()) ||
  1050. (err = _dmapGroup.QueryError()) ||
  1051. (err = _dmapGroupExpanded.QueryError()) ||
  1052. (err = _dmapGroupNoExpand.QueryError()) ||
  1053. (err = DISPLAY_TABLE::CalcColumnWidths( _adxColumns,
  1054. 4,
  1055. powin,
  1056. QueryCid(),
  1057. FALSE )) )
  1058. {
  1059. ReportError( err ) ;
  1060. return ;
  1061. }
  1062. DISPLAY_CONTEXT dc( QueryHwnd() );
  1063. dc.SelectFont( QueryFont() );
  1064. // JonN 6/18/95 remove unnecessary floating point
  1065. _nAveCharWidth = (dc.QueryAveCharWidth() * 3) / 2;
  1066. }
  1067. MPR_HIER_LISTBOX::~MPR_HIER_LISTBOX()
  1068. {
  1069. /* Nothing to do */
  1070. }
  1071. /*******************************************************************
  1072. NAME: MPR_HIER_LISTBOX::AddChildren
  1073. SYNOPSIS: Redefined virtual to add enumerate the children of the
  1074. passed parent.
  1075. ENTRY: phlbi - Parent LBI to enumerate children under
  1076. EXIT:
  1077. RETURNS:
  1078. NOTES:
  1079. HISTORY:
  1080. Johnl 30-Jan-1992 Commented, made non-static
  1081. ********************************************************************/
  1082. APIERR MPR_HIER_LISTBOX::AddChildren( HIER_LBI * phlbi )
  1083. {
  1084. UIASSERT( phlbi != NULL );
  1085. return ::EnumerateShow( QueryHwnd(),
  1086. RESOURCE_GLOBALNET,
  1087. QueryType(),
  1088. 0,
  1089. ((MPR_LBI *)phlbi)->QueryLPNETRESOURCE(),
  1090. (MPR_LBI *)phlbi,
  1091. this );
  1092. }
  1093. /*******************************************************************
  1094. NAME: MPR_HIER_LISTBOX::FindItem
  1095. SYNOPSIS: Find an LBI in the given indentation level that
  1096. matches the given string.
  1097. ENTRY: pszItem - the item we are looking for
  1098. nLevel - the indentation level of the item
  1099. EXIT:
  1100. RETURNS: The index of the item we are searching for. -1 if
  1101. we cannot find any.
  1102. NOTES:
  1103. HISTORY:
  1104. Yi-HsinS 04-Nov-1992 Created
  1105. ********************************************************************/
  1106. INT MPR_HIER_LISTBOX::FindItem( const TCHAR *pszItem, INT nLevel )
  1107. {
  1108. for ( INT i = 0; i < QueryCount(); i ++ )
  1109. {
  1110. MPR_LBI *plbi = (MPR_LBI *) QueryItem( i );
  1111. /* QueryItem() can fail if its call to SendMessage fails
  1112. */
  1113. if (( plbi != NULL )
  1114. &&
  1115. ( ::stricmpf( pszItem, plbi->QueryRemoteName() ) == 0 )
  1116. &&
  1117. ( plbi->QueryIndentLevel() == nLevel ))
  1118. {
  1119. return i;
  1120. }
  1121. }
  1122. return -1;
  1123. }
  1124. /*******************************************************************
  1125. NAME: MPR_HIER_LISTBOX::FindNextProvider
  1126. SYNOPSIS: Find the next LBI starting at the given index that
  1127. is represents a provider ( top level ).
  1128. ENTRY: iStart - The place the start the search
  1129. EXIT:
  1130. RETURNS: The index of the item we are searching for. -1 if
  1131. we cannot find any.
  1132. NOTES:
  1133. HISTORY:
  1134. Yi-HsinS 04-Nov-1992 Created
  1135. ********************************************************************/
  1136. INT MPR_HIER_LISTBOX::FindNextProvider( INT iStart )
  1137. {
  1138. UIASSERT( iStart >= 0 );
  1139. for ( INT i = iStart; i < QueryCount(); i++ )
  1140. {
  1141. MPR_LBI *plbi = (MPR_LBI *) QueryItem( i );
  1142. if ( plbi->QueryIndentLevel() == 0 ) // Topmost level
  1143. return i;
  1144. }
  1145. return -1;
  1146. }
  1147. /*******************************************************************
  1148. NAME: MPR_HIER_LISTBOX::CalcMaxHorizontalExtent
  1149. SYNOPSIS: Traverses all items in the listbox and calculates the
  1150. indent level of the deepest item and the total horizontal
  1151. width
  1152. RETURNS: Count of PELs wher
  1153. NOTES: _nMaxPelIndent is set by this method
  1154. The container name field width is extended for each LBI to
  1155. the deepest indentation such that the comment will always
  1156. be aligned.
  1157. HISTORY:
  1158. Johnl 17-Mar-1993 Created
  1159. ********************************************************************/
  1160. #define RIGHT_MARGIN 3 // Small white space on right side of Listbox
  1161. void MPR_HIER_LISTBOX::CalcMaxHorizontalExtent( void )
  1162. {
  1163. //
  1164. // Find the node that is indented the most and record the indentation
  1165. // and while we are at it, record the longest comment
  1166. //
  1167. UINT nPelIndent = 0 ;
  1168. UINT nMaxPelIndent = 0 ;
  1169. UINT nCommentSize = 0 ;
  1170. UINT nMaxCommentSize = 0 ;
  1171. DISPLAY_CONTEXT dc( QueryHwnd() ) ;
  1172. dc.SelectFont( QueryFont() ) ;
  1173. for ( int i = 0 ; i < QueryCount() ; i++ )
  1174. {
  1175. MPR_LBI * pmprlbi = (MPR_LBI*) QueryItem( i ) ;
  1176. if ( pmprlbi != NULL )
  1177. {
  1178. if ((nPelIndent = pmprlbi->QueryPelIndent()) > nMaxPelIndent )
  1179. {
  1180. nMaxPelIndent = nPelIndent ;
  1181. }
  1182. if ( pmprlbi->QueryComment() && *pmprlbi->QueryComment() )
  1183. {
  1184. nCommentSize = dc.QueryTextWidth( pmprlbi->QueryComment() ) ;
  1185. if ( nCommentSize > nMaxCommentSize )
  1186. nMaxCommentSize = nCommentSize ;
  1187. }
  1188. }
  1189. else
  1190. {
  1191. UIASSERT( FALSE ) ;
  1192. return ;
  1193. }
  1194. }
  1195. SetMaxPelIndent( nMaxPelIndent ) ;
  1196. SetHorizontalExtent( QueryMaxPelIndent() +
  1197. QueryColWidthArray()[1] +
  1198. QueryColWidthArray()[2] +
  1199. nMaxCommentSize + RIGHT_MARGIN ) ;
  1200. }
  1201. /*******************************************************************
  1202. NAME: MPR_HIER_LISTBOX::QueryDisplayMap
  1203. SYNOPSIS: Returns the appropriate display map based on the
  1204. type of the properties
  1205. ENTRY: fIsContainer - TRUE if this is a container object
  1206. fIsExpanded - TRUE if this is an expanded container object
  1207. EXIT:
  1208. RETURNS: Display Map for a Container, or an Expanded Container
  1209. NOTES:
  1210. HISTORY:
  1211. Johnl 09-Jan-1992 Created
  1212. ********************************************************************/
  1213. DISPLAY_MAP * MPR_HIER_LISTBOX::QueryDisplayMap( BOOL fIsContainer,
  1214. BOOL fIsExpanded,
  1215. DWORD dwDisplayType,
  1216. BOOL fIsProvider )
  1217. {
  1218. UNREFERENCED( fIsContainer ) ;
  1219. switch (dwDisplayType)
  1220. {
  1221. case RESOURCEDISPLAYTYPE_DOMAIN:
  1222. if ( fIsExpanded )
  1223. return &_dmapDomainExpanded ;
  1224. return ( fIsContainer ? &_dmapDomain : &_dmapDomainNoExpand ) ;
  1225. case RESOURCEDISPLAYTYPE_SERVER:
  1226. if ( fIsExpanded )
  1227. return &_dmapServerExpanded ;
  1228. return ( fIsContainer ? &_dmapServer : &_dmapServerNoExpand ) ;
  1229. case RESOURCEDISPLAYTYPE_SHARE:
  1230. if ( fIsExpanded )
  1231. return &_dmapShareExpanded ;
  1232. return ( fIsContainer ? &_dmapShare : &_dmapShareNoExpand ) ;
  1233. case RESOURCEDISPLAYTYPE_FILE:
  1234. if ( fIsExpanded )
  1235. return &_dmapFileExpanded ;
  1236. return ( fIsContainer ? &_dmapFile : &_dmapFileNoExpand ) ;
  1237. case RESOURCEDISPLAYTYPE_TREE:
  1238. if ( fIsExpanded )
  1239. return &_dmapTreeExpanded ;
  1240. return ( fIsContainer ? &_dmapTree : &_dmapTreeNoExpand ) ;
  1241. case RESOURCEDISPLAYTYPE_GROUP:
  1242. if ( fIsExpanded )
  1243. return &_dmapGroupExpanded ;
  1244. return ( fIsContainer ? &_dmapGroup : &_dmapGroupNoExpand ) ;
  1245. default:
  1246. if ( fIsProvider )
  1247. {
  1248. if ( fIsExpanded )
  1249. return &_dmapProviderExpanded;
  1250. return &_dmapProvider;
  1251. }
  1252. else
  1253. {
  1254. if ( fIsExpanded )
  1255. return &_dmapGenericExpanded ;
  1256. return ( fIsContainer ? &_dmapGeneric : &_dmapGenericNoExpand ) ;
  1257. }
  1258. }
  1259. }
  1260. /*******************************************************************
  1261. NAME: MPR_LBI::MPR_LBI
  1262. SYNOPSIS: Normal LBI constructor
  1263. ENTRY:
  1264. EXIT:
  1265. RETURNS:
  1266. NOTES:
  1267. HISTORY:
  1268. Johnl 30-Jan-1992 Commented
  1269. beng 31-Mar-1992 Slight Unicode fix
  1270. ********************************************************************/
  1271. MPR_LBI::MPR_LBI( LPNETRESOURCE lpnetresource )
  1272. : HIER_LBI( FALSE ),
  1273. _nlsDisplayName(),
  1274. _fRefreshNeeded( FALSE )
  1275. {
  1276. if ( QueryError() != NERR_Success )
  1277. return;
  1278. if ( _nlsDisplayName.QueryError() != NERR_Success )
  1279. {
  1280. ReportError( _nlsDisplayName.QueryError() );
  1281. return;
  1282. }
  1283. _netres.dwScope = lpnetresource->dwScope;
  1284. _netres.dwType = lpnetresource->dwType;
  1285. _netres.dwDisplayType = lpnetresource->dwDisplayType;
  1286. _netres.dwUsage = lpnetresource->dwUsage;
  1287. _netres.lpRemoteName = NULL ;
  1288. _netres.lpLocalName = NULL;
  1289. _netres.lpProvider = NULL ;
  1290. _netres.lpComment = NULL ;
  1291. /* Note that we do new(count of characters) because we are using
  1292. * the transmutable type TCHAR.
  1293. */
  1294. if ( lpnetresource->lpRemoteName != NULL )
  1295. {
  1296. if ( (_netres.lpRemoteName = new TCHAR[ ::strlenf( lpnetresource->lpRemoteName ) + 1]) != NULL)
  1297. ::strcpyf( _netres.lpRemoteName, lpnetresource->lpRemoteName);
  1298. else
  1299. ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
  1300. }
  1301. if ( lpnetresource->lpLocalName != NULL )
  1302. {
  1303. if ((_netres.lpLocalName = new TCHAR[ ::strlenf( lpnetresource->lpLocalName ) + 1]) != NULL)
  1304. ::strcpyf( _netres.lpLocalName, lpnetresource->lpLocalName);
  1305. else
  1306. ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
  1307. }
  1308. if ( lpnetresource->lpProvider != NULL )
  1309. {
  1310. if ((_netres.lpProvider = new TCHAR[ ::strlenf( lpnetresource->lpProvider ) + 1]) != NULL)
  1311. ::strcpyf( _netres.lpProvider, lpnetresource->lpProvider);
  1312. else
  1313. ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
  1314. }
  1315. if ( lpnetresource->lpComment != NULL )
  1316. {
  1317. if ((_netres.lpComment = new TCHAR[ ::strlenf( lpnetresource->lpComment ) + 1])!=NULL )
  1318. ::strcpyf( _netres.lpComment, lpnetresource->lpComment);
  1319. else
  1320. ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
  1321. }
  1322. }
  1323. MPR_LBI::~MPR_LBI()
  1324. {
  1325. delete _netres.lpLocalName;
  1326. delete _netres.lpRemoteName;
  1327. delete _netres.lpProvider;
  1328. delete _netres.lpComment;
  1329. _netres.lpLocalName = _netres.lpRemoteName = NULL;
  1330. _netres.lpProvider = _netres.lpComment = NULL;
  1331. }
  1332. BOOL MPR_LBI::IsContainer( void ) const
  1333. {
  1334. if ( _netres.dwScope & RESOURCE_GLOBALNET )
  1335. return !!( _netres.dwUsage & RESOURCEUSAGE_CONTAINER );
  1336. else
  1337. return FALSE;
  1338. }
  1339. BOOL MPR_LBI::IsSearchDialogSupported( void ) const
  1340. {
  1341. return( ::WNetGetSearchDialog( _netres.lpProvider ) != NULL );
  1342. }
  1343. BOOL MPR_LBI::IsConnectable( void ) const
  1344. {
  1345. if ( _netres.dwScope & RESOURCE_GLOBALNET )
  1346. return !!(_netres.dwUsage & RESOURCEUSAGE_CONNECTABLE );
  1347. else
  1348. return FALSE;
  1349. }
  1350. BOOL MPR_LBI::IsProvider( void ) const
  1351. {
  1352. // Topmost level is provider
  1353. return ((MPR_LBI *) this)->QueryIndentLevel() == 0 ;
  1354. }
  1355. VOID MPR_LBI::Paint( LISTBOX * plb, HDC hdc, const RECT * prect,
  1356. GUILTT_INFO * pGUILTT ) const
  1357. {
  1358. MPR_HIER_LISTBOX * mprhlb = (MPR_HIER_LISTBOX *) plb ;
  1359. //
  1360. // Copy the master column widths array. The 0th item will be replaced
  1361. // by the pel-indent and the container name [2] will be adjusted to keep
  1362. // the comment aligned. Note that the base is widened such that the
  1363. // right edge will always cause the comment to line up in the next
  1364. // column.
  1365. //
  1366. UINT adxColumns[4];
  1367. for ( INT i = 1; i < 4; i++ )
  1368. adxColumns[ i ] = mprhlb->QueryColWidthArray()[ i ];
  1369. // adxColumns[2] += mprhlb->QueryMaxPelIndent() - QueryPelIndent() ;
  1370. UINT indent = QueryPelIndent();
  1371. adxColumns[0] = indent;
  1372. if (adxColumns[2] < 2 * indent)
  1373. {
  1374. adxColumns[2] = indent;
  1375. }
  1376. else
  1377. {
  1378. adxColumns[2] -= indent;
  1379. }
  1380. if ( _nlsDisplayName.QueryTextLength() == 0 )
  1381. {
  1382. APIERR err = ::GetNetworkDisplayName( _netres.lpProvider,
  1383. _netres.lpRemoteName,
  1384. WNFMT_ABBREVIATED | WNFMT_INENUM,
  1385. adxColumns[2] / mprhlb->QueryAveCharWidth(),
  1386. (NLS_STR *) & _nlsDisplayName );
  1387. if ( err != NERR_Success )
  1388. {
  1389. ::MsgPopup( plb->QueryOwnerHwnd(), err );
  1390. return;
  1391. }
  1392. }
  1393. DM_DTE dmdte( mprhlb->QueryDisplayMap( IsContainer(),
  1394. QueryExpanded(),
  1395. QueryDisplayType(),
  1396. IsProvider())) ;
  1397. STR_DTE sdte( _nlsDisplayName.QueryPch() );
  1398. STR_DTE sdteComment( QueryComment() ) ;
  1399. DISPLAY_TABLE dtab( 4, adxColumns );
  1400. dtab[0] = NULL;
  1401. dtab[1] = &dmdte;
  1402. dtab[2] = &sdte;
  1403. dtab[3] = &sdteComment;
  1404. dtab.Paint( plb, hdc, prect, pGUILTT );
  1405. }
  1406. /*******************************************************************
  1407. NAME: MPR_LBI::QueryLeadingChar
  1408. SYNOPSIS: Returns the first non-'\\' character of the remote name
  1409. ENTRY:
  1410. RETURNS: The first non back slash character of the remote name
  1411. NOTES: This code is not DBCS safe, which is OK since it should
  1412. only be run with ANSI and UNICODE character sets.
  1413. HISTORY:
  1414. Johnl 09-Jan-1992 Changed to return first non-'\\' character
  1415. ********************************************************************/
  1416. WCHAR MPR_LBI::QueryLeadingChar() const
  1417. {
  1418. TCHAR * pchRemoteName = _netres.lpRemoteName ;
  1419. while ( *pchRemoteName && *pchRemoteName == TCH('\\') )
  1420. pchRemoteName++ ;
  1421. return *pchRemoteName ;
  1422. }
  1423. INT MPR_LBI::Compare( const LBI * plbi ) const
  1424. {
  1425. return ::stricmpf( _netres.lpRemoteName,
  1426. ((const MPR_LBI *)plbi)->_netres.lpRemoteName );
  1427. }
  1428. MPR_LBI_CACHE::MPR_LBI_CACHE( INT cInitialItems )
  1429. : BASE(),
  1430. _cItems( 0 ),
  1431. _cMaxItems( cInitialItems ),
  1432. _buffArray( cInitialItems * sizeof(MPR_LBI*) )
  1433. {
  1434. if ( QueryError() )
  1435. return ;
  1436. if ( _buffArray.QueryError() )
  1437. ReportError( _buffArray.QueryError() ) ;
  1438. }
  1439. MPR_LBI_CACHE::~MPR_LBI_CACHE()
  1440. {
  1441. // Nothing to do
  1442. }
  1443. /*******************************************************************
  1444. NAME: MPR_LBI_CACHE::AppendItem
  1445. SYNOPSIS: Adds an item to the end of the cache
  1446. ENTRY: plbi - Item to add
  1447. EXIT: The item will be deleted if an error occurs
  1448. RETURNS: NERR_Success is successful, error code otherwise
  1449. NOTES: Behave just like AddItem
  1450. HISTORY:
  1451. Johnl 27-Jan-1993 Created
  1452. ********************************************************************/
  1453. #define CACHE_DELTA 100
  1454. APIERR MPR_LBI_CACHE::AppendItem( MPR_LBI * plbi )
  1455. {
  1456. APIERR err = ERROR_NOT_ENOUGH_MEMORY ;
  1457. if ( plbi == NULL ||
  1458. (err = plbi->QueryError()) )
  1459. {
  1460. delete plbi ;
  1461. return err ;
  1462. }
  1463. //
  1464. // Do we need to resize the array?
  1465. //
  1466. if ( _cItems >= _cMaxItems )
  1467. {
  1468. if ( err = _buffArray.Resize( _buffArray.QuerySize() +
  1469. CACHE_DELTA * sizeof(MPR_LBI*) ))
  1470. {
  1471. delete plbi ;
  1472. return err ;
  1473. }
  1474. _cMaxItems += CACHE_DELTA ;
  1475. }
  1476. QueryPtr()[_cItems++] = plbi ;
  1477. return err ;
  1478. }
  1479. void MPR_LBI_CACHE::Sort( void )
  1480. {
  1481. if ( QueryCount() > 0 )
  1482. {
  1483. ::qsort( (void *) _buffArray.QueryPtr(),
  1484. QueryCount(),
  1485. sizeof(MPR_LBI*),
  1486. MPR_LBI_CACHE::CompareLbis ) ;
  1487. }
  1488. }
  1489. INT MPR_LBI_CACHE::FindItem( const TCHAR *psz )
  1490. {
  1491. for ( INT i= 0; i < QueryCount(); i++ )
  1492. {
  1493. if ( ::stricmpf( (QueryPtr()[i])->QueryRemoteName(), psz ) == 0 )
  1494. return i;
  1495. }
  1496. return -1;
  1497. }
  1498. VOID MPR_LBI_CACHE::DeleteAllItems( VOID )
  1499. {
  1500. for ( INT i= 0; i < QueryCount(); i++ )
  1501. {
  1502. MPR_LBI *plbi = QueryPtr()[i];
  1503. delete plbi;
  1504. QueryPtr()[i] = NULL;
  1505. }
  1506. _cItems = 0;
  1507. }
  1508. int __cdecl MPR_LBI_CACHE::CompareLbis( const void * p0,
  1509. const void * p1 )
  1510. {
  1511. MPR_LBI * plbi = (MPR_LBI*) *((MPR_LBI**)p0) ;
  1512. return plbi->Compare( (LBI*) *((MPR_LBI**)p1) ) ;
  1513. }