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.

1604 lines
36 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. dialogs.cxx
  7. This module contains the Add Port and Configure dialogs.
  8. FILE HISTORY:
  9. NarenG 17-May-1993 Converted C code for the 2 dialogs to C++
  10. */
  11. #define INCL_NET
  12. #define INCL_NETLIB
  13. #define INCL_NETSERVICE
  14. #define INCL_WINDOWS
  15. #define INCL_WINDOWS_GDI
  16. #define INCL_NETERRORS
  17. #define INCL_DOSERRORS
  18. #include <lmui.hxx>
  19. #if defined(DEBUG)
  20. static const CHAR szFileName[] = __FILE__;
  21. #define _FILENAME_DEFINED_ONCE szFileName
  22. #endif
  23. #include <uiassert.hxx>
  24. #include <uitrace.hxx>
  25. #define INCL_BLT_WINDOW
  26. #define INCL_BLT_DIALOG
  27. #define INCL_BLT_CONTROL
  28. #define INCL_BLT_CLIENT
  29. #define INCL_BLT_MSGPOPUP
  30. #define INCL_BLT_EVENT
  31. #define INCL_BLT_MISC
  32. #define INCL_BLT_TIMER
  33. #define INCL_BLT_CC
  34. #include <blt.hxx>
  35. #include <dbgstr.hxx>
  36. extern "C"
  37. {
  38. #include <stdlib.h>
  39. #include <winsock.h>
  40. #include <atalkwsh.h>
  41. #include "atalkmon.h"
  42. #include "dialogs.h"
  43. } // extern "C"
  44. //#include <colwidth.hxx>
  45. #include <ellipsis.hxx>
  46. #include "getprint.hxx"
  47. #include "dialogs.hxx"
  48. #define STRING_SIZE_CHARS 255
  49. #define STRING_SIZE_BYTES (STRING_SIZE_CHARS * sizeof(WCHAR))
  50. /*******************************************************************
  51. NAME: InitializeBlt
  52. SYNOPSIS: Called during processing of DLL_PROCESS_ATTACH notification to
  53. initialize the DLL.
  54. ENTRY:
  55. RETURNS: BOOL - TRUE = AfpMgr should be installed.
  56. FALSE = AfpMgr cannot be installed.
  57. HISTORY:
  58. NarenG 71-May-1993 Created
  59. ********************************************************************/
  60. BOOL InitializeBlt( VOID )
  61. {
  62. WaitForSingleObject( hmutexBlt, INFINITE );
  63. //
  64. // Initialize all of the NetUI goodies.
  65. //
  66. APIERR err = BLT::Init( (HINSTANCE)hInst,
  67. IDRSRC_RASMAC_BASE, IDRSRC_RASMAC_LAST,
  68. IDS_UI_RASMAC_BASE, IDS_UI_RASMAC_LAST );
  69. if( err == NERR_Success )
  70. {
  71. err = BLT_MASTER_TIMER::Init();
  72. if( err != NERR_Success )
  73. {
  74. //
  75. // BLT initialized OK, but BLT_MASTER_TIMER
  76. // failed. So, before we bag-out, we must
  77. // deinitialize BLT.
  78. //
  79. BLT::Term( (HINSTANCE)hInst );
  80. }
  81. }
  82. if( err == NERR_Success )
  83. {
  84. err = BLT::RegisterHelpFile( (HINSTANCE)hInst,
  85. IDS_MACPRINT_HELPFILENAME,
  86. HC_UI_RASMAC_BASE,
  87. HC_UI_RASMAC_LAST );
  88. if( err != NERR_Success )
  89. {
  90. //
  91. // This is the only place where we can safely
  92. // invoke MsgPopup, since we *know* that all of
  93. // the BLT goodies were initialized properly.
  94. //
  95. // ::MsgPopup( QueryHwnd(), err );
  96. }
  97. }
  98. if ( err != NERR_Success )
  99. ReleaseMutex( hmutexBlt );
  100. return err == NERR_Success;
  101. } // InitializeBlt
  102. /*******************************************************************
  103. NAME: TerminateBlt
  104. SYNOPSIS: Called during processing of DLL_PROCESS_DETACH notification to
  105. terminate the DLL.
  106. ENTRY:
  107. HISTORY:
  108. NarenG 24-May-1993 Created.
  109. ********************************************************************/
  110. VOID TerminateBlt( VOID )
  111. {
  112. //
  113. // Kill the NetUI goodies.
  114. //
  115. BLT_MASTER_TIMER::Term();
  116. BLT::Term( (HINSTANCE)hInst );
  117. ReleaseMutex( hmutexBlt );
  118. } // TerminateBlt
  119. /********************************************************************
  120. NAME: ConfigPortDialog
  121. SYNOPSIS: Called to bring up the configure port dialog.
  122. ENTRY: lParam is a pointer to an ATALKPORT structure for the
  123. port being configured.
  124. HISTORY:
  125. NarenG 24-May-1993 Created.
  126. *********************************************************************/
  127. BOOL ConfigPortDialog( HWND hdlg, BOOL fIsSpooler, BOOL * pfCapture )
  128. {
  129. if ( !InitializeBlt() )
  130. {
  131. return FALSE;
  132. }
  133. //
  134. // If this is a spooler then we have nothing to configure
  135. //
  136. if ( fIsSpooler )
  137. {
  138. ::MsgPopup( hdlg, IDS_NOTHING_TO_CONFIGURE, MPSEV_INFO, 1, MP_OK );
  139. TerminateBlt();
  140. return FALSE;
  141. }
  142. BOOL fOk = FALSE;
  143. CONFIGURE_PORT_DIALOG * pdlg = new CONFIGURE_PORT_DIALOG( hdlg, pfCapture );
  144. APIERR err = ( pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY
  145. : pdlg->Process( &fOk );
  146. delete pdlg;
  147. if ( err != NO_ERROR )
  148. {
  149. ::MsgPopup( hdlg, err );
  150. TerminateBlt() ;
  151. return FALSE;
  152. }
  153. TerminateBlt();
  154. return fOk;
  155. }
  156. /********************************************************************
  157. NAME: CONFIGURE_PORT_DIALOG::CONFIGURE_PORT_DIALOG
  158. SYNOPSIS: CONFIGURE_PORT_DIALOG constructor
  159. ENTRY: hwndOwner - Handle to the owner window.
  160. pAtalkPort - Pointer to the ATALKPORT structure for the
  161. port being configured.
  162. HISTORY:
  163. NarenG 24-May-1993 Created.
  164. *********************************************************************/
  165. CONFIGURE_PORT_DIALOG::CONFIGURE_PORT_DIALOG( HWND hWndOwner,
  166. BOOL * pfCapture )
  167. : DIALOG_WINDOW( MAKEINTRESOURCE(IDD_CONFIG_PORT_DIALOG ), hWndOwner ),
  168. _pfCapture( pfCapture ),
  169. _chkCapture( this, IDCP_CHK_CAPTURE )
  170. {
  171. //
  172. // Make sure everything constructed correctly
  173. //
  174. if ( QueryError() != NERR_Success )
  175. {
  176. return;
  177. }
  178. APIERR err;
  179. if ( (( err = _chkCapture.QueryError() ) != NERR_Success ) )
  180. {
  181. ReportError( err );
  182. return;
  183. }
  184. _chkCapture.SetCheck( *pfCapture );
  185. }
  186. /********************************************************************
  187. NAME: CONFIGURE_PORT_DIALOG::OnOK
  188. SYNOPSIS: Called when the user hits the OK button
  189. ENTRY:
  190. HISTORY:
  191. NarenG 24-May-1993 Created.
  192. *********************************************************************/
  193. BOOL CONFIGURE_PORT_DIALOG::OnOK( VOID )
  194. {
  195. *_pfCapture = _chkCapture.QueryCheck();
  196. Dismiss( TRUE );
  197. return TRUE;
  198. }
  199. /*******************************************************************
  200. NAME: CONFIGURE_PORT_DIALOG :: QueryHelpContext
  201. SYNOPSIS: This function returns the appropriate help context
  202. value (HC_*) for this particular dialog.
  203. RETURNS: ULONG - The help context for this
  204. dialog.
  205. ********************************************************************/
  206. ULONG CONFIGURE_PORT_DIALOG :: QueryHelpContext( void )
  207. {
  208. return HC_CONFIGURE_PORT_DIALOG;
  209. } // CONFIGURE_PORT_DIALOG :: QueryHelpContext
  210. /*********************************************************************
  211. NAME: AddPortDialog
  212. SYNOPSIS: Called to bring dialog to add a port.
  213. ENTRY: lParam - Pointer to the ATALKPORT structure for the
  214. new port being added.
  215. HISTORY:
  216. NarenG 24-May-1993 Created.
  217. ***********************************************************************/
  218. BOOL AddPortDialog( HWND hdlg, PATALKPORT pAtalkPort )
  219. {
  220. if ( !InitializeBlt() )
  221. return FALSE;
  222. BOOL fOk = FALSE;
  223. ADD_PORT_DIALOG * pdlg = new ADD_PORT_DIALOG( hdlg, pAtalkPort );
  224. APIERR err = ( pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY
  225. : pdlg->Process( &fOk );
  226. delete pdlg;
  227. if ( err != NO_ERROR )
  228. {
  229. ::MsgPopup( hdlg, err );
  230. TerminateBlt() ;
  231. return FALSE;
  232. }
  233. TerminateBlt();
  234. return fOk;
  235. }
  236. /********************************************************************
  237. NAME: ADD_PORT_DIALOG::ADD_PORT_DIALOG
  238. SYNOPSIS: ADD_PORT_DIALOG constructor
  239. ENTRY: hwndOwner - Handle to the owner window.
  240. pNewPort - Pointer to the ATALKPORT structure for the
  241. new port being added.
  242. HISTORY:
  243. NarenG 24-May-1993 Created.
  244. *********************************************************************/
  245. ADD_PORT_DIALOG::ADD_PORT_DIALOG( HWND hWndOwner,
  246. PATALKPORT pNewPort )
  247. : DIALOG_WINDOW( MAKEINTRESOURCE(IDD_ADDPORT_DIALOG), hWndOwner ),
  248. _pNewPort( pNewPort ),
  249. _pbOK( this, IDOK ),
  250. _ollb( this, IDAP_LB_OUTLINE, pNewPort->sockQuery )
  251. {
  252. //
  253. // Make sure everything constructed correctly
  254. //
  255. if ( QueryError() != NERR_Success )
  256. {
  257. return;
  258. }
  259. APIERR err;
  260. if ( pNewPort->sockQuery == INVALID_SOCKET )
  261. {
  262. ReportError( IDS_MUST_START_STACK );
  263. return;
  264. }
  265. if ( (( err = _ollb.QueryError() ) != NERR_Success ) ||
  266. (( err = _pbOK.QueryError() ) != NERR_Success ) )
  267. {
  268. ReportError( err );
  269. return;
  270. }
  271. //
  272. // Just to be cool...
  273. //
  274. AUTO_CURSOR Cursor;
  275. //
  276. // Initialize the outline listbox with Zones
  277. //
  278. err = _ollb.FillZones();
  279. if ( err != NO_ERROR )
  280. {
  281. ReportError( err );
  282. return;
  283. }
  284. if ( _ollb.QueryCount() > 0 )
  285. {
  286. OLLB_ENTRY * pollbe = _ollb.QueryItem( 0 );
  287. if ( ( _ollb.QueryCount() == 1 ) &&
  288. ( ::_wcsicmp( pollbe->QueryZone(), (LPWSTR)TEXT("*") ) == 0 ) )
  289. {
  290. Show();
  291. err = _ollb.ExpandZone( 0 );
  292. if ( err != NO_ERROR )
  293. {
  294. ReportError( err );
  295. return;
  296. }
  297. }
  298. _ollb.SelectItem( 0 );
  299. }
  300. else
  301. {
  302. ReportError( IDS_NO_ZONES );
  303. return;
  304. }
  305. return;
  306. }
  307. /*******************************************************************
  308. NAME: ADD_PORT_DIALOG :: ~ADD_PORT_DIALOG
  309. SYNOPSIS: ADD_PORT_DIALOG class destructor.
  310. EXIT: The object is destroyed.
  311. HISTORY:
  312. NarenG 25-May-1993 Created
  313. ********************************************************************/
  314. ADD_PORT_DIALOG :: ~ADD_PORT_DIALOG()
  315. {
  316. //
  317. // Nothing to be done here.
  318. //
  319. } // ADD_PORT_DIALOG :: ~ADD_PORT_DIALOG
  320. /*******************************************************************
  321. NAME: ADD_PORT_DIALOG :: QueryHelpContext
  322. SYNOPSIS: This function returns the appropriate help context
  323. value (HC_*) for this particular dialog.
  324. RETURNS: ULONG - The help context for this
  325. dialog.
  326. ********************************************************************/
  327. ULONG ADD_PORT_DIALOG :: QueryHelpContext( void )
  328. {
  329. return HC_ADD_PORT_DIALOG;
  330. } // ADD_PORT_DIALOG :: QueryHelpContext
  331. /********************************************************************
  332. NAME: ADD_PORT_DIALOG::OnCommand
  333. SYNOPSIS: Called whenever a WM_COMMAND message is send to the
  334. dialog procedure.
  335. ENTRY:
  336. HISTORY:
  337. NarenG 24-May-1993 Created.
  338. *********************************************************************/
  339. BOOL ADD_PORT_DIALOG::OnCommand( const CONTROL_EVENT & event )
  340. {
  341. if ( event.QueryCid() == _ollb.QueryCid() )
  342. {
  343. //
  344. // This method handles double clicks of domains
  345. //
  346. if ( event.QueryCode() == LBN_DBLCLK )
  347. {
  348. INT i = _ollb.QueryCurrentItem();
  349. OLLB_ENTRY * pollbe = _ollb.QueryItem( i );
  350. if ( pollbe == NULL )
  351. {
  352. return FALSE;
  353. }
  354. if ( pollbe->QueryType() == SFM_OLLBL_ZONE )
  355. {
  356. //
  357. // Toggle zone.
  358. //
  359. if ( pollbe->IsExpanded() )
  360. return _ollb.CollapseZone( i );
  361. else
  362. return _ollb.ExpandZone( i );
  363. }
  364. else
  365. {
  366. return OnOK();
  367. }
  368. }
  369. }
  370. return DIALOG_WINDOW::OnCommand( event );
  371. }
  372. /********************************************************************
  373. NAME: ADD_PORT_DIALOG::OnOK
  374. SYNOPSIS: Called when the user hits the OK button
  375. ENTRY:
  376. HISTORY:
  377. NarenG 24-May-1993 Created.
  378. *********************************************************************/
  379. BOOL ADD_PORT_DIALOG::OnOK( VOID )
  380. {
  381. //
  382. // Just to be cool...
  383. //
  384. AUTO_CURSOR Cursor;
  385. OLLB_ENTRY * pollbe = _ollb.QueryItem();
  386. if ( pollbe == NULL)
  387. {
  388. return ( FALSE );
  389. }
  390. if ( pollbe->QueryType() == SFM_OLLBL_PRINTER )
  391. {
  392. //
  393. // First find out if the user has selected a spooler
  394. //
  395. BOOL fIsSpooler = FALSE;
  396. ::IsSpooler( pollbe->QueryAddress(), &fIsSpooler );
  397. if ( fIsSpooler )
  398. {
  399. if ( ::MsgPopup( this,
  400. IDS_SPOOLER,
  401. MPSEV_INFO,
  402. HC_CONFIGURE_PORT_DIALOG,
  403. MP_YESNO,
  404. NULL,
  405. MP_YES ) == IDNO )
  406. {
  407. return( FALSE );
  408. }
  409. }
  410. LPWSTR lpwsZoneName = (LPWSTR)(pollbe->QueryZone());
  411. //
  412. // Build the port name
  413. //
  414. ::wcscpy( _pNewPort->pPortName, lpwsZoneName );
  415. ::wcscat( _pNewPort->pPortName, (LPWSTR)TEXT(":") );
  416. ::wcscat( _pNewPort->pPortName, pollbe->QueryPrinter() );
  417. //
  418. // Build the NBP name
  419. //
  420. CHAR chPortName[MAX_ENTITY+1];
  421. ::wcstombs( chPortName, lpwsZoneName, MAX_ENTITY+1 ) ;
  422. ::strncpy ( (CHAR*)(_pNewPort->nbpPortName.ZoneName),
  423. chPortName,
  424. ::strlen( chPortName ) );
  425. _pNewPort->nbpPortName.ZoneNameLen = (CHAR)::strlen( chPortName );
  426. ::wcstombs( chPortName, pollbe->QueryPrinter(), MAX_ENTITY+1 );
  427. ::strncpy( (CHAR*)(_pNewPort->nbpPortName.ObjectName),
  428. chPortName,
  429. ::strlen( chPortName ) );
  430. _pNewPort->nbpPortName.ObjectNameLen = (CHAR)::strlen( chPortName );
  431. if ( fIsSpooler )
  432. {
  433. ::strncpy( (CHAR*)(_pNewPort->nbpPortName.TypeName),
  434. ATALKMON_RELEASED_TYPE,
  435. ::strlen(ATALKMON_RELEASED_TYPE) );
  436. _pNewPort->nbpPortName.TypeNameLen =
  437. (CHAR)::strlen(ATALKMON_RELEASED_TYPE);
  438. _pNewPort->fPortFlags |= SFM_PORT_IS_SPOOLER;
  439. }
  440. else
  441. {
  442. if ( ::MsgPopup( this,
  443. IDS_WANT_TO_CAPTURE,
  444. MPSEV_INFO,
  445. HC_CONFIGURE_PORT_DIALOG,
  446. MP_YESNO,
  447. NULL,
  448. MP_YES ) == IDYES )
  449. {
  450. ::strncpy( (CHAR*)(_pNewPort->nbpPortName.TypeName),
  451. chComputerName,
  452. ::strlen(chComputerName) );
  453. _pNewPort->nbpPortName.TypeNameLen = (CHAR)::strlen(chComputerName);
  454. _pNewPort->fPortFlags |= SFM_PORT_CAPTURED;
  455. }
  456. else
  457. {
  458. ::strncpy( (CHAR*)(_pNewPort->nbpPortName.TypeName),
  459. ATALKMON_RELEASED_TYPE,
  460. ::strlen(ATALKMON_RELEASED_TYPE) );
  461. _pNewPort->nbpPortName.TypeNameLen =
  462. (CHAR)::strlen(ATALKMON_RELEASED_TYPE);
  463. _pNewPort->fPortFlags &= ~SFM_PORT_CAPTURED;
  464. }
  465. }
  466. _pNewPort->wshatPrinterAddress = *(pollbe->QueryAddress());
  467. Dismiss( TRUE );
  468. return TRUE;
  469. }
  470. else
  471. {
  472. //
  473. // If focus is on the OK button
  474. //
  475. if ( _pbOK.HasFocus() )
  476. {
  477. //
  478. // Tell user to select printer or press Cancel
  479. //
  480. ::MsgPopup( this, IDS_MUST_SELECT_PRINTER );
  481. return FALSE;
  482. }
  483. else
  484. {
  485. //
  486. // Focus is on the listbox so the user wants to expand/collapse
  487. // the zone
  488. //
  489. if ( pollbe->IsExpanded() )
  490. return _ollb.CollapseZone();
  491. else
  492. return _ollb.ExpandZone();
  493. }
  494. }
  495. }
  496. /*******************************************************************
  497. NAME: OLLB_ENTRY::OLLB_ENTRY
  498. SYNOPSIS: Outline listbox item constructor
  499. ENTRY: ollbl - Indicates level in hierarchy (zone, or printer)
  500. fExpanded - Indicates whether or not the item should
  501. take the expanded look. Must be
  502. FALSE for servers.
  503. It may be either for domains, since these
  504. are expandable/collapsable.
  505. pszZone - Pointer to name of zone (for zones),
  506. and name of the zone in which a printer
  507. exists (for printers).
  508. pszPrinter - Pointer to name of printer. Must be NULL
  509. for the zones.
  510. HISTORY:
  511. NarenG 1-June-1993 Stole from file manager
  512. ********************************************************************/
  513. OLLB_ENTRY::OLLB_ENTRY( SFM_OUTLINE_LB_LEVEL ollbl,
  514. BOOL fExpanded,
  515. const TCHAR * pszZone,
  516. const TCHAR * pszPrinter,
  517. const PWSH_ATALK_ADDRESS pwshAtalkAddress )
  518. : LBI(),
  519. _ollbl( ollbl ),
  520. _fExpanded( fExpanded ),
  521. _nlsZone( pszZone ),
  522. _nlsPrinter( pszPrinter )
  523. {
  524. //
  525. // Ensure everything constructed properly.
  526. //
  527. if( QueryError() != NERR_Success )
  528. {
  529. return;
  530. }
  531. APIERR err;
  532. if( ( ( err = _nlsZone.QueryError() ) != NERR_Success ) ||
  533. ( ( err = _nlsPrinter.QueryError() ) != NERR_Success ) )
  534. {
  535. ReportError( err );
  536. return;
  537. }
  538. if ( pwshAtalkAddress != NULL )
  539. _wshAtalkAddress = *pwshAtalkAddress;
  540. }
  541. OLLB_ENTRY::~OLLB_ENTRY()
  542. {
  543. // nothing else to do
  544. }
  545. /*******************************************************************
  546. NAME: OLLB_ENTRY::Paint
  547. SYNOPSIS: Paint an entry in the outline listbox
  548. NOTES:
  549. HISTORY:
  550. NarenG 1-June-1993 Stole from file manager
  551. ********************************************************************/
  552. VOID OLLB_ENTRY::Paint( LISTBOX * plb, HDC hdc, const RECT * prect,
  553. GUILTT_INFO * pGUILTT ) const
  554. {
  555. // Note. plb is assumed to point to an OUTLINE_LISTBOX object.
  556. UINT anColWidths[ 3 ];
  557. anColWidths[ 0 ] = QueryLevel() * COL_WIDTH_OUTLINE_INDENT;
  558. anColWidths[ 1 ] = COL_WIDTH_DM;
  559. anColWidths[ 2 ] = COL_WIDTH_AWAP;
  560. const TCHAR * pszName = NULL;
  561. switch ( QueryType() )
  562. {
  563. case SFM_OLLBL_ZONE:
  564. pszName = QueryZone();
  565. break;
  566. case SFM_OLLBL_PRINTER:
  567. pszName = QueryPrinter();
  568. break;
  569. default:
  570. ASSERTSZ( FALSE, "Invalid OLLBL type!" );
  571. return;
  572. }
  573. STR_DTE strdteName( pszName );
  574. DISPLAY_TABLE dt( 3, anColWidths );
  575. dt[ 0 ] = NULL;
  576. dt[ 1 ] = ((OUTLINE_LISTBOX *)plb)->QueryDmDte( QueryType(), _fExpanded );
  577. dt[ 2 ] = &strdteName;
  578. dt.Paint( plb, hdc, prect, pGUILTT );
  579. }
  580. INT OLLB_ENTRY::Compare( const LBI * plbi ) const
  581. {
  582. //
  583. // Compare the zone names.
  584. //
  585. const NLS_STR * pnls = &(((const OLLB_ENTRY *)plbi)->_nlsZone);
  586. INT result = _nlsZone.strcmp( *pnls );
  587. if( result == 0 )
  588. {
  589. //
  590. // The zones match, so compare the servers.
  591. //
  592. const NLS_STR * pnls = &(((const OLLB_ENTRY *)plbi)->_nlsPrinter);
  593. result = _nlsPrinter.strcmp( *pnls );
  594. }
  595. return result;
  596. }
  597. WCHAR OLLB_ENTRY::QueryLeadingChar() const
  598. {
  599. if ( QueryType() != SFM_OLLBL_ZONE )
  600. {
  601. ISTR istr( _nlsPrinter );
  602. return _nlsPrinter.QueryChar( istr );
  603. }
  604. else
  605. {
  606. ISTR istr( _nlsZone );
  607. return _nlsZone.QueryChar( istr );
  608. }
  609. }
  610. /*******************************************************************
  611. NAME: OUTLINE_LISTBOX::OUTLINE_LISTBOX
  612. SYNOPSIS: Constructor
  613. ENTRY: powin - pointer OWNER_WINDOW
  614. cid - CID
  615. EXIT: The object is constructed.
  616. HISTORY:
  617. NarenG 1-June-1993 Stole from file manager
  618. ********************************************************************/
  619. OUTLINE_LISTBOX::OUTLINE_LISTBOX( OWNER_WINDOW * powin,
  620. CID cid,
  621. SOCKET hSocket )
  622. : BLT_LISTBOX( powin, cid ),
  623. _nS( 0 ),
  624. _pdmiddteZone( NULL ),
  625. _pdmiddteZoneExpanded( NULL ),
  626. _pdmiddtePrinter( NULL ),
  627. _hSocket( hSocket )
  628. {
  629. if ( QueryError() != NERR_Success )
  630. return;
  631. _pdmiddteZone = new DMID_DTE( IDBM_LB_ZONE_NOT_EXPANDED );
  632. _pdmiddteZoneExpanded = new DMID_DTE( IDBM_LB_ZONE_EXPANDED );
  633. _pdmiddtePrinter = new DMID_DTE( IDBM_LB_PRINTER );
  634. if ( ( _pdmiddteZone == NULL ) ||
  635. ( _pdmiddteZoneExpanded == NULL ) ||
  636. ( _pdmiddtePrinter == NULL ) )
  637. {
  638. ReportError( ERROR_NOT_ENOUGH_MEMORY );
  639. return;
  640. }
  641. APIERR err;
  642. if (((err = _pdmiddteZone->QueryError()) != NERR_Success) ||
  643. ((err = _pdmiddteZoneExpanded->QueryError()) != NERR_Success) ||
  644. ((err = _pdmiddtePrinter->QueryError()) != NERR_Success) )
  645. {
  646. ReportError(err);
  647. return;
  648. }
  649. }
  650. OUTLINE_LISTBOX::~OUTLINE_LISTBOX()
  651. {
  652. delete _pdmiddteZone;
  653. delete _pdmiddteZoneExpanded;
  654. delete _pdmiddtePrinter;
  655. _pdmiddteZone = NULL;
  656. _pdmiddteZoneExpanded = NULL;
  657. _pdmiddtePrinter = NULL;
  658. }
  659. INT OUTLINE_LISTBOX::AddItem( SFM_OUTLINE_LB_LEVEL ollbl,
  660. BOOL fExpanded,
  661. const TCHAR * pszZone,
  662. const TCHAR * pszPrinter,
  663. const PWSH_ATALK_ADDRESS pwshAtalkAddress )
  664. {
  665. // Note. BLT_LISTBOX::AddItem will check for NULL and QueryError.
  666. // Hence, this is not done here.
  667. return BLT_LISTBOX::AddItem( new OLLB_ENTRY( ollbl,
  668. fExpanded,
  669. pszZone,
  670. pszPrinter,
  671. pwshAtalkAddress ));
  672. }
  673. /*
  674. * OUTLINE_LISTBOX::FindItem
  675. *
  676. * Finds a particular item in the listbox
  677. *
  678. * Parameters:
  679. * pszZone A pointer to the zone name to be searched for
  680. * pszPrinter A pointer to the printer name to be searched for.
  681. * If NULL, the domain itself is searched for.
  682. *
  683. * Return value:
  684. * The index of the specified item, or
  685. * a negative value on error (generally, not found)
  686. *
  687. */
  688. INT OUTLINE_LISTBOX::FindItem( const TCHAR * pszZone,
  689. const TCHAR * pszPrinter ) const
  690. {
  691. OLLB_ENTRY ollbe( (( pszPrinter == NULL )
  692. ? SFM_OLLBL_ZONE
  693. : SFM_OLLBL_PRINTER ),
  694. FALSE,
  695. pszZone,
  696. pszPrinter,
  697. NULL );
  698. if ( ollbe.QueryError() != NERR_Success )
  699. return -1;
  700. return BLT_LISTBOX::FindItem( ollbe );
  701. }
  702. INT OUTLINE_LISTBOX::AddZone( const TCHAR * pszZone, BOOL fExpanded )
  703. {
  704. return AddItem( SFM_OLLBL_ZONE, fExpanded, pszZone, NULL, NULL );
  705. }
  706. /*******************************************************************
  707. NAME: OUTLINE_LISTBOX::AddPrinter
  708. SYNOPSIS: Adds a printer to the listbox. Marks the zone as
  709. expanded.
  710. ENTRY: pszZone - Pointer to name of zone of printer to
  711. be added.
  712. pszPrinter - Pointer to name of printer.
  713. NOTES:
  714. This method marks the zone as expanded.
  715. HISTORY:
  716. NarenG 1-June-1993 Stole from file manager
  717. ********************************************************************/
  718. INT OUTLINE_LISTBOX::AddPrinter( const TCHAR * pszZone,
  719. const TCHAR * pszPrinter,
  720. const PWSH_ATALK_ADDRESS pwshAtalkAddress )
  721. {
  722. INT iZoneIndex = FindItem( pszZone, NULL );
  723. if ( iZoneIndex < 0 )
  724. {
  725. //
  726. // don't add a server for which there is no domain
  727. //
  728. return -1;
  729. }
  730. //
  731. // Attempt to add the printer
  732. //
  733. INT iPrinterIndex = AddItem( SFM_OLLBL_PRINTER,
  734. FALSE, // a printer is never expanded
  735. pszZone,
  736. pszPrinter,
  737. pwshAtalkAddress );
  738. if ( iPrinterIndex >= 0 )
  739. {
  740. //
  741. // The printer was successfully added so expand zone
  742. //
  743. SetZoneExpanded( iZoneIndex );
  744. }
  745. return iPrinterIndex;
  746. }
  747. VOID OUTLINE_LISTBOX::SetZoneExpanded( INT i, BOOL f )
  748. {
  749. if ( i < 0 )
  750. {
  751. //
  752. // Invalid index
  753. //
  754. return;
  755. }
  756. OLLB_ENTRY * pollbe = QueryItem( i );
  757. if ( pollbe == NULL )
  758. {
  759. //
  760. // Invalid index
  761. //
  762. return;
  763. }
  764. BOOL fCurrent = pollbe->IsExpanded();
  765. //
  766. // If current state is the same as what we want then simply return
  767. //
  768. if (( fCurrent && f ) || ( !fCurrent && !f ))
  769. {
  770. return;
  771. }
  772. //
  773. // Set the expanded state to "expanded". Then, invalidate the item
  774. // so that it will be repainted later.
  775. //
  776. pollbe->SetExpanded( f );
  777. InvalidateItem( i );
  778. }
  779. DM_DTE * OUTLINE_LISTBOX::QueryDmDte( SFM_OUTLINE_LB_LEVEL ollbl,
  780. BOOL fExpanded ) const
  781. {
  782. switch ( ollbl )
  783. {
  784. case SFM_OLLBL_ZONE:
  785. return( ( fExpanded ) ? _pdmiddteZoneExpanded : _pdmiddteZone );
  786. case SFM_OLLBL_PRINTER:
  787. return _pdmiddtePrinter;
  788. default:
  789. break;
  790. }
  791. return NULL;
  792. }
  793. /*
  794. * OUTLINE_LISTBOX::FillZones
  795. *
  796. * This method adds the zones to the listbox by calling AddZone.
  797. * Then, calls SelectItem to select the first zone.
  798. *
  799. * Parameters:
  800. * None
  801. *
  802. * Return value:
  803. * An error code, which is NERR_Success on success.
  804. *
  805. * Assumptions:
  806. *
  807. */
  808. APIERR OUTLINE_LISTBOX::FillZones( VOID )
  809. {
  810. //
  811. // Just to be cool...
  812. //
  813. AUTO_CURSOR Cursor;
  814. //
  815. // Enumerate all the zones
  816. //
  817. PBYTE pBuffer = NULL;
  818. INT BufferSize = ((MAX_ENTITY+1)*255)+sizeof(WSH_LOOKUP_ZONES);
  819. INT intBytesWritten = BufferSize;
  820. INT intRetCode = NO_ERROR;
  821. DWORD err = NO_ERROR;
  822. pBuffer = (PBYTE)LocalAlloc( LPTR, BufferSize );
  823. if ( pBuffer == NULL )
  824. {
  825. return( ERROR_NOT_ENOUGH_MEMORY );
  826. }
  827. do {
  828. intRetCode = ::getsockopt(
  829. _hSocket,
  830. SOL_APPLETALK,
  831. SO_LOOKUP_ZONES,
  832. (PCHAR)pBuffer,
  833. &intBytesWritten );
  834. if ( intRetCode == SOCKET_ERROR )
  835. {
  836. err = ::GetLastError();
  837. if ( ( err != WSAEINVAL ) && ( err != WSAENOBUFS ) )
  838. {
  839. DeleteAllItems();
  840. Invalidate( TRUE );
  841. break;
  842. }
  843. else
  844. {
  845. PBYTE pTmpBuffer = NULL;
  846. BufferSize *= 2;
  847. intBytesWritten = BufferSize;
  848. err = NO_ERROR;
  849. pTmpBuffer = (PBYTE)LocalReAlloc( pBuffer,
  850. BufferSize,
  851. LMEM_MOVEABLE );
  852. if ( pTmpBuffer == NULL )
  853. {
  854. err = ERROR_NOT_ENOUGH_MEMORY;
  855. break;
  856. }
  857. pBuffer = pTmpBuffer;
  858. }
  859. }
  860. else
  861. {
  862. break;
  863. }
  864. } while( TRUE );
  865. if ( err != NO_ERROR )
  866. {
  867. if ( pBuffer != NULL )
  868. {
  869. LocalFree( pBuffer );
  870. }
  871. return( err );
  872. }
  873. //
  874. // Now that we know the zones.
  875. // let's nuke everything in the listbox.
  876. //
  877. SetRedraw( FALSE );
  878. DeleteAllItems();
  879. //
  880. // For iterating the zones.
  881. //
  882. PCHAR pZone = (PCHAR)pBuffer + sizeof( WSH_LOOKUP_ZONES );
  883. //
  884. // Iterate the volumes adding them to the listbox.
  885. //
  886. err = NO_ERROR;
  887. DWORD dwZoneCount = ((PWSH_LOOKUP_ZONES)pBuffer)->NoZones;
  888. while( ( err == NO_ERROR ) && ( dwZoneCount-- ) )
  889. {
  890. WCHAR wchBuffer[MAX_ENTITY+1];
  891. ::mbstowcs( wchBuffer, pZone, sizeof( wchBuffer ) / sizeof( wchBuffer[0] ) );
  892. if( AddZone( wchBuffer, FALSE ) < 0 )
  893. {
  894. err = ERROR_NOT_ENOUGH_MEMORY;
  895. }
  896. pZone += (::strlen(pZone) + 1) ;
  897. }
  898. SetRedraw( TRUE );
  899. Invalidate( TRUE );
  900. LocalFree( pBuffer );
  901. return err;
  902. }
  903. /*
  904. * OUTLINE_LISTBOX::FillPrinters
  905. *
  906. * Calls AddPrinter for every visible printer in the given zone.
  907. *
  908. * Parameters:
  909. * pszZone The zone of interest
  910. * pcPrintersAdded Pointer to location receiving the number
  911. * of printers that were added by calling
  912. * AddPrinter. *pusServerAdded is always valid
  913. * on return from this function, regardless
  914. * of the error code. This is because an
  915. * error may occur in the middle of adding
  916. * servers.
  917. *
  918. * Return value:
  919. * An error code, which is NERR_Success on success.
  920. *
  921. */
  922. APIERR OUTLINE_LISTBOX::FillPrinters( const TCHAR * pszZone,
  923. UINT * pcPrintersAdded )
  924. {
  925. NBP_LOOKUP_STRUCT NBPLookup;
  926. ZeroMemory ((PVOID)&NBPLookup, sizeof(NBP_LOOKUP_STRUCT));
  927. *pcPrintersAdded = 0;
  928. //
  929. // Copy the zone name into the buffer
  930. //
  931. ::wcscpy( NBPLookup.wchZone, pszZone );
  932. NBPLookup.hSocket = _hSocket;
  933. GET_PRINTERS_DIALOG * pdlg = new GET_PRINTERS_DIALOG( QueryOwnerHwnd(),
  934. &NBPLookup );
  935. APIERR err = ( pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY
  936. : pdlg->Process();
  937. delete pdlg;
  938. if ( err != NO_ERROR )
  939. {
  940. return err;
  941. }
  942. //
  943. // Check to see if any printers were found
  944. //
  945. if ( NBPLookup.cPrinters == 0 )
  946. {
  947. ::LocalFree( NBPLookup.pPrinters );
  948. return NO_ERROR;
  949. }
  950. SetRedraw( FALSE );
  951. //
  952. // For iterating the available printers.
  953. //
  954. PWSH_NBP_TUPLE pPrinters = NBPLookup.pPrinters;
  955. DWORD cPrinters = NBPLookup.cPrinters;
  956. //
  957. // Iterate the printers adding them to the listbox.
  958. //
  959. err = NO_ERROR;
  960. while( ( err == NO_ERROR ) && ( cPrinters-- ) )
  961. {
  962. WCHAR wchBuffer[MAX_ENTITY+1];
  963. CHAR chBuffer[MAX_ENTITY+1];
  964. ::ZeroMemory( chBuffer, sizeof( chBuffer ) );
  965. ::strncpy( chBuffer,
  966. pPrinters->NbpName.ObjectName,
  967. pPrinters->NbpName.ObjectNameLen );
  968. ::mbstowcs( wchBuffer, chBuffer, sizeof( wchBuffer ) / sizeof( wchBuffer[0] ) );
  969. if ( AddPrinter( pszZone, wchBuffer, &(pPrinters->Address) ) < 0 )
  970. {
  971. err = ERROR_NOT_ENOUGH_MEMORY;
  972. }
  973. else
  974. {
  975. (*pcPrintersAdded)++;
  976. }
  977. pPrinters++;
  978. }
  979. SetRedraw( TRUE );
  980. ::LocalFree( NBPLookup.pPrinters );
  981. return err;
  982. }
  983. /*******************************************************************
  984. NAME: OUTLINE_LISTBOX::ExpandZone
  985. SYNOPSIS: Expands a zone. On success, also selects it.
  986. ENTRY: iZone - Specifies the index of the zone to be expanded.
  987. RETURNS:
  988. An error code, which is NERR_Success on success.
  989. NOTES:
  990. HISTORY:
  991. NarenG 1-June-1993 Stole from file manager
  992. ********************************************************************/
  993. APIERR OUTLINE_LISTBOX::ExpandZone( INT iZone )
  994. {
  995. OLLB_ENTRY * pollbe = QueryItem( iZone );
  996. if ( pollbe == NULL )
  997. {
  998. return ERROR_MENU_ITEM_NOT_FOUND;
  999. }
  1000. if ( pollbe->QueryType() != SFM_OLLBL_ZONE )
  1001. {
  1002. return ERROR_INVALID_PARAMETER;
  1003. }
  1004. if ( pollbe->IsExpanded())
  1005. {
  1006. //
  1007. // domain is already expanded; select the item, and return with
  1008. // success
  1009. //
  1010. SelectItem( iZone );
  1011. return NO_ERROR;
  1012. }
  1013. UINT cPrintersAdded = 0;
  1014. DWORD err = FillPrinters( pollbe->QueryZone(), &cPrintersAdded );
  1015. if ( cPrintersAdded > 0 )
  1016. {
  1017. Invalidate( TRUE );
  1018. }
  1019. if ( ( err == NERR_Success ) && ( cPrintersAdded > 0 ) )
  1020. {
  1021. //
  1022. // Adjust the listbox according to how many servers are added
  1023. // Warning: The following is a problem when LM_OLLB becomes
  1024. // LBS_OWNERDRAWVARIABLE with multi-line LBIs
  1025. //
  1026. XYDIMENSION xydim = QuerySize();
  1027. INT nTotalItems = xydim.QueryHeight()/QuerySingleLineHeight();
  1028. INT nTopIndex = QueryTopIndex();
  1029. INT nBottomIndex = nTopIndex + nTotalItems - 1;
  1030. if ( iZone >= nTopIndex && iZone <= nBottomIndex )
  1031. {
  1032. if ( cPrintersAdded >= (UINT) nTotalItems )
  1033. {
  1034. SetTopIndex( iZone );
  1035. }
  1036. else
  1037. {
  1038. INT n = iZone + cPrintersAdded;
  1039. if ( n > nBottomIndex )
  1040. {
  1041. SetTopIndex( nTopIndex + ( n - nBottomIndex ) );
  1042. }
  1043. }
  1044. }
  1045. else
  1046. {
  1047. SetTopIndex( iZone );
  1048. }
  1049. }
  1050. if ( ( err == NERR_Success ) && ( cPrintersAdded == 0 ) )
  1051. {
  1052. ::MsgPopup( QueryOwnerHwnd(), IDS_NO_PRINTERS, MPSEV_INFO );
  1053. SetZoneExpanded( iZone, TRUE );
  1054. }
  1055. return err;
  1056. }
  1057. /*******************************************************************
  1058. NAME: OUTLINE_LISTBOX::CollapseZone
  1059. SYNOPSIS: Collapses a given zone. On success, also selects it.
  1060. ENTRY: iZone - Specifies the index of the domain to be expanded.
  1061. RETURNS:
  1062. An error code, which is NERR_Success on success.
  1063. NOTES:
  1064. HISTORY:
  1065. NarenG 1-June-1993 Stole from file manager
  1066. ********************************************************************/
  1067. APIERR OUTLINE_LISTBOX::CollapseZone( INT iZone )
  1068. {
  1069. OLLB_ENTRY * pollbe = QueryItem( iZone );
  1070. if ( iZone < 0 || pollbe == NULL )
  1071. {
  1072. return ERROR_INVALID_PARAMETER;
  1073. }
  1074. if ( pollbe->QueryType() != SFM_OLLBL_ZONE )
  1075. {
  1076. return ERROR_INVALID_PARAMETER;
  1077. }
  1078. //
  1079. // Change the expanded state of the listbox item to "not expanded"
  1080. //
  1081. if ( !pollbe->IsExpanded())
  1082. {
  1083. //
  1084. // Select the item, and then return.
  1085. //
  1086. SelectItem( iZone );
  1087. return NERR_Success;
  1088. }
  1089. //
  1090. // Now, we know we'll take some action which may take a little time.
  1091. // Hence, let AUTO_CURSOR kick in.
  1092. //
  1093. AUTO_CURSOR autocur;
  1094. SetRedraw( FALSE );
  1095. SetZoneExpanded( iZone, FALSE );
  1096. //
  1097. // Set iNext to the next item in the listbox. This item, if any, is
  1098. // either another zone, or a printer in the zone.
  1099. //
  1100. INT iNext = iZone + 1;
  1101. BOOL fDeletedAny = FALSE;
  1102. while ( ( pollbe = QueryItem( iNext )) != NULL &&
  1103. pollbe->QueryType() == SFM_OLLBL_PRINTER )
  1104. {
  1105. DeleteItem( iNext );
  1106. fDeletedAny = TRUE;
  1107. }
  1108. SetRedraw( TRUE );
  1109. if ( fDeletedAny )
  1110. {
  1111. Invalidate( TRUE );
  1112. }
  1113. //
  1114. // To make sure that the zone is indeed in view in the listbox,
  1115. // select it .
  1116. //
  1117. SelectItem( iZone );
  1118. return NERR_Success;
  1119. }
  1120. /*******************************************************************
  1121. NAME: OUTLINE_LISTBOX::CD_Char
  1122. SYNOPSIS: We catch the '+' and '-' keys to expand and collapse
  1123. the zone if the current selection is a zone.
  1124. ENTRY: wch - character typed
  1125. nLastPos - position in lb
  1126. EXIT:
  1127. RETURNS:
  1128. HISTORY:
  1129. NarenG 1-June-1993 Stole from file manager
  1130. ********************************************************************/
  1131. INT OUTLINE_LISTBOX::CD_Char( WCHAR wch, USHORT nLastPos )
  1132. {
  1133. static WCHAR vpwS[] = { 0xc, 0x2, 0x10, 0x10, 0x5, 0x13, 0x7, 0x3 };
  1134. if ( wch == (WCHAR) TCH('+') || wch == (WCHAR) TCH('-') )
  1135. {
  1136. OLLB_ENTRY * pollbe = QueryItem( nLastPos );
  1137. if ( pollbe != NULL && pollbe->QueryType() == SFM_OLLBL_ZONE )
  1138. {
  1139. APIERR err = NERR_Success ;
  1140. if ( wch == (WCHAR)TCH('-') && pollbe->IsExpanded() )
  1141. {
  1142. err = CollapseZone() ;
  1143. }
  1144. else if ( wch == (WCHAR) TCH('+') && !pollbe->IsExpanded() )
  1145. {
  1146. err = ExpandZone() ;
  1147. }
  1148. if ( err != NERR_Success )
  1149. MsgPopup( QueryOwnerHwnd(), err, MPSEV_ERROR ) ;
  1150. return -2 ;
  1151. }
  1152. }
  1153. if ( _nS >= 0 )
  1154. {
  1155. if ( wch == (WCHAR) (vpwS[ _nS ] - _nS ))
  1156. {
  1157. // Note, 47 and 3 are prime, whereas 0x15 is not
  1158. if ( ( 47 & vpwS[ ++_nS ] ) * 3 == 0x15 )
  1159. _nS = -1;
  1160. }
  1161. else
  1162. {
  1163. _nS = 0;
  1164. }
  1165. }
  1166. return BLT_LISTBOX::CD_Char( wch, nLastPos );
  1167. }