windows-nt/Source/XPSP1/NT/admin/netui/mprui/mpr/mprbrows.cxx

1955 lines
56 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/**********************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1990, 1991 **/
/**********************************************************************/
/*
mprbrows.cxx
Browse dialog for mpr.
FILE HISTORY:
Yi-HsinS 10-Nov-1992 Separated from mprconn.cxx
Yi-HsinS 20-Nov-1992 Added support for printer icons
Yi-HsinS 04-Mar-1993 Added support for multithreading
*/
#include <ntincl.hxx>
extern "C"
{
#include <ntlsa.h>
}
#define INCL_NETERRORS
#define INCL_WINDOWS_GDI
#define INCL_WINDOWS
#define INCL_DOSERRORS
#define INCL_NETLIB
#define INCL_NETWKSTA
#include <lmui.hxx>
#define INCL_BLT_DIALOG
#define INCL_BLT_CONTROL
#define INCL_BLT_MSGPOPUP
#include <blt.hxx>
#include <uitrace.hxx>
#include <regkey.hxx>
extern "C"
{
#include <mprconn.h>
#include <npapi.h>
#include <stdlib.h> // For qsort()
}
#include <mprmisc.hxx>
#include <mprbrows.hxx>
#define MAX_NET_PATH MAX_PATH
/*******************************************************************
NAME: MPR_BROWSE_BASE::MPR_BROWSE_BASE
SYNOPSIS: constructor for base connect dialog
NOTES: The use of the ?: operator in DISK vs PRINT means
that we assume if not DISK, must be PRINT. If more
types get added, this need to be taken into account.
HISTORY:
Kevinl? ??-Nov-1991 Created
ChuckC 09-Apr-1992 Added diff MRU keyname support
Added comments/notes.
********************************************************************/
MPR_BROWSE_BASE::MPR_BROWSE_BASE( const TCHAR *pszDialogName,
HWND hwndOwner,
DEVICE_TYPE devType,
TCHAR *lpHelpFile,
DWORD nHelpContext )
: DIALOG_WINDOW ( pszDialogName, hwndOwner ),
_uiType ( (devType == DEV_TYPE_DISK ) ?
RESOURCETYPE_DISK : RESOURCETYPE_PRINT),
_buttonSearch ( this, IDC_BUTTON_SEARCH ),
_buttonOK ( this, IDOK ),
_boxExpandDomain ( this, IDC_CHECKBOX_EXPANDLOGONDOMAIN ),
_sltShowLBTitle ( this, IDC_SLT_SHOW_LB_TITLE ),
_mprhlbShow ( this, IDC_NET_SHOW,
(devType == DEV_TYPE_DISK) ?
RESOURCETYPE_DISK : RESOURCETYPE_PRINT ),
_sleGetInfo ( this, IDC_SLE_GETINFO_TEXT ),
_pMprEnumThread ( NULL ),
_nlsProviderToExpand (),
_nlsWkstaDomain (),
_fSearchDialogUsed ( FALSE ),
_nlsHelpFile ( lpHelpFile ),
_nHelpContext ( nHelpContext )
{
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ((err = _nlsHelpFile.QueryError()) != NERR_Success )
|| ((err = _nlsProviderToExpand.QueryError()) != NERR_Success )
|| ((err = _nlsWkstaDomain.QueryError()) != NERR_Success )
)
{
ReportError( err );
return;
}
/* Select the correct text for the device dependent text fields
*/
MSGID msgidShowLBTitle;
switch ( QueryType() )
{
case RESOURCETYPE_DISK:
msgidShowLBTitle = IDS_SERVERS_LISTBOX_DRIVE ;
break ;
case RESOURCETYPE_PRINT:
msgidShowLBTitle = IDS_SERVERS_LISTBOX_PRINTER ;
break ;
default:
UIASSERT(FALSE) ;
ReportError( ERROR_INVALID_PARAMETER ) ;
return ;
}
/* Get the top level providers
*/
err = ::EnumerateShow( QueryHwnd(),
RESOURCE_GLOBALNET,
_uiType,
0,
NULL,
NULL,
&_mprhlbShow,
FALSE,
&_fSearchDialogUsed,
NULL );
if ( err != NERR_Success )
{
ReportError( err );
return;
}
_mprhlbShow.CalcMaxHorizontalExtent() ;
_buttonSearch.Show( _fSearchDialogUsed );
/* Set the title of the listbox
*/
RESOURCE_STR nlsShowLBTitle( msgidShowLBTitle ) ;
if ( err = nlsShowLBTitle.QueryError() )
{
ReportError( err ) ;
return ;
}
_sltShowLBTitle.SetText( nlsShowLBTitle ) ;
//
// Get the name of provider to expand and the domain name the
// workstation is in if we need to.
//
BOOL fExpandFirstProvider = IsExpandDomain();
_boxExpandDomain.SetCheck( fExpandFirstProvider );
if ( fExpandFirstProvider )
{
BOOL fProviderToExpandIsNT ;
RESOURCE_STR nlsGettingInfo( IDS_GETTING_INFO ) ;
//
// find the first in order and if it is NT
//
if ( (( err = nlsGettingInfo.QueryError()) != NERR_Success )
|| ((err = QueryProviderToExpand(&_nlsProviderToExpand,
&fProviderToExpandIsNT))
!= NERR_Success) )
{
ReportError( err );
return;
}
//
// if it is NT, we special case and need expand domain.
// so lets go find out what domain we are in,
//
if (fProviderToExpandIsNT)
{
err = QueryWkstaDomain( &_nlsWkstaDomain ) ;
if (err != NERR_Success ||
(err = _nlsWkstaDomain.QueryError()) != NERR_Success)
{
if ( (err = _nlsWkstaDomain.CopyFrom(SZ(""))) != NERR_Success )
{
ReportError( err );
return;
}
}
}
INT index = _mprhlbShow.FindItem( _nlsProviderToExpand, 0 );
if ( index >= 0 )
{
/* Disable the listbox until we get all the data
*/
_sleGetInfo.SetText( nlsGettingInfo ) ;
ShowMprListbox( FALSE );
return;
}
// At this point, we cannot find provider in the listbox.
// Hence, we don't need to expand the listbox.
}
/* Don't need to start the second thread here.
* So, we can show the listbox right away.
*/
ShowMprListbox( TRUE );
} // MPR_BROWSE_BASE::MPR_BROWSE_BASE
/*******************************************************************
NAME: MPR_BROWSE_BASE::~MPR_BROWSE_BASE
SYNOPSIS: desstructor for base connect dialog
NOTES:
HISTORY:
YiHsinS 04-Mar-1993 Created
********************************************************************/
MPR_BROWSE_BASE::~MPR_BROWSE_BASE()
{
if ( _pMprEnumThread != NULL )
{
_pMprEnumThread->ExitThread();
// Do not delete the thread object, it will delete itself
_pMprEnumThread = NULL;
}
} // MPR_BROWSE_BASE::~MPR_BROWSE_BASE
/*******************************************************************
NAME: MPR_BROWSE_BASE::ShowMprListbox
SYNOPSIS: Enable and show the listbox
NOTES:
HISTORY:
YiHsinS 04-Mar-1993 Created
********************************************************************/
VOID MPR_BROWSE_BASE::ShowMprListbox( BOOL fShow )
{
_sltShowLBTitle.Enable( fShow ) ;
_mprhlbShow.Enable( fShow );
_sleGetInfo.Show( !fShow );
_mprhlbShow.Show( fShow );
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::MayRun
SYNOPSIS: Start the second thread to get the data
NOTES:
HISTORY:
YiHsinS 04-Mar-1993 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::MayRun( VOID )
{
/* Start the second thread to get the data only if we need to
* expand the provider and domain
*/
if ( IsExpandDomain() )
{
APIERR err = NERR_Success;
/*
* Find the NETRESOURCE of the provider. In the dialog
* constructor, we already check to make sure that the provider
* indeed exist in the listbox.
*/
INT index = _mprhlbShow.FindItem( _nlsProviderToExpand, 0 );
UIASSERT( index >= 0 );
MPR_LBI *pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem( index );
UIASSERT( pmprlbi != NULL );
_pMprEnumThread = new MPR_ENUM_THREAD( QueryHwnd(),
QueryType(),
pmprlbi->QueryLPNETRESOURCE(),
_nlsWkstaDomain );
if ( ( _pMprEnumThread == NULL )
|| ( (err = _pMprEnumThread->QueryError()) != NERR_Success )
|| ( (err = _pMprEnumThread->Resume()) != NERR_Success )
)
{
delete _pMprEnumThread;
_pMprEnumThread = NULL;
err = err? err : ERROR_NOT_ENOUGH_MEMORY;
::MsgPopup( this, err );
return FALSE;
}
}
return TRUE;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::OnShowResourcesChange
SYNOPSIS: This method is called when the user takes an action in
the Show Resources listbox.
ENTRY: fEnumChildren - TRUE if the children for the current node in
the "Show" listbox should be enumerated, FALSE otherwise.
In general, the children are only enumerated on an
"expansion" event (double click or enter key).
RETURN: An error value, which is NERR_Success on success.
HISTORY:
rustanl ??-Nov-1991 Created
Johnl 10-Jan-1992 Added Wait indicator
********************************************************************/
APIERR MPR_BROWSE_BASE::OnShowResourcesChange( BOOL fEnumChildren )
{
AUTO_CURSOR hourglass ;
APIERR err = NERR_Success;
// Get the current listbox data item. This item is a pointer to
// an MPR_LBI. There must be a selection; otherwise, we shouldn't
// have been called.
MPR_LBI * pmprlbi = (MPR_LBI *)_mprhlbShow.QueryItem();
// QueryItem() can fail if its call to SendMessage fails
if (pmprlbi == NULL)
{
return ERROR_GEN_FAILURE;
}
// Update the Network Path MRU if an item was selected
if ( pmprlbi->IsConnectable() )
{
SetNetPathString( pmprlbi->QueryRemoteName() );
SetLastProviderInfo( pmprlbi->QueryLPNETRESOURCE()->lpProvider,
pmprlbi->QueryRemoteName());
}
else
ClearNetPathString();
// Clear the Resources listbox and turn its redraw switch off.
// Then, call the appropriate virtual method to fill it in.
// If nothing was added to the listbox, it is disabled; otherwise, it
// is enabled. (Enable/disable affect keyboard and mouse input.)
// Lastly, the redraw switch is turned on, and the listbox is invalidated.
if ( pmprlbi->IsContainer() && fEnumChildren )
{
//
// Fill lb with children if they haven't been added
// already
//
if ( !pmprlbi->QueryExpanded() && pmprlbi->IsRefreshNeeded() )
{
_mprhlbShow.DeleteChildren( pmprlbi );
pmprlbi->SetRefreshNeeded( FALSE );
}
if ( !pmprlbi->HasChildren() )
{
// Enumerate Children
err = ::EnumerateShow( QueryHwnd(),
RESOURCE_GLOBALNET,
QueryType(),
0,
pmprlbi->QueryLPNETRESOURCE(),
pmprlbi,
&_mprhlbShow );
}
}
// finally, enanle/disable the search button if need (ie. at least
// one provider is using it.
if (_fSearchDialogUsed)
_buttonSearch.Enable(pmprlbi->IsSearchDialogSupported()) ;
return err;
} // MPR_BROWSE_BASE::OnShowResourcesChange
/*******************************************************************
NAME: MPR_BROWSE_BASE::OnOK
SYNOPSIS: Set the expand domain checkbox
NOTES:
HISTORY:
YiHsinS 04-Mar-1993 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::OnOK( void )
{
if ( !SetExpandDomain( _boxExpandDomain.QueryCheck() ))
::MsgPopup(this, IERR_CANNOT_SET_EXPANDLOGONDOMAIN );
return TRUE;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::OnCommand
SYNOPSIS:
NOTES:
HISTORY:
********************************************************************/
BOOL MPR_BROWSE_BASE::OnCommand( const CONTROL_EVENT & event )
{
switch ( event.QueryCid() )
{
case IDC_NET_SHOW:
switch ( event.QueryCode() )
{
case LBN_SELCHANGE:
// No error will occur when not enumerating children
OnShowResourcesChange();
return TRUE;
case LBN_DBLCLK:
{
MPR_LBI * pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem();
if ( ShowSearchDialogOnDoubleClick( pmprlbi ) )
return TRUE;
APIERR err = OnShowResourcesChange( TRUE );
switch ( err )
{
case WN_SUCCESS:
break ;
case WN_EXTENDED_ERROR:
MsgExtendedError( this->QueryRobustHwnd() ) ;
break ;
case ERROR_GEN_FAILURE:
err = ERROR_UNEXP_NET_ERR ; // more friendly error
// drop thru
default:
MsgPopup( this, (MSGID) err ) ;
break ;
}
if (( err == NERR_Success )
&&
( pmprlbi != NULL ))
{
if ( pmprlbi->IsContainer())
{
//
// OnDoubleClick may call AddChildren (which does
// another enum if there are no children). But
// since we have already done the enum and we know
// there are no children, skip this.
//
if ( pmprlbi->HasChildren() )
{
_mprhlbShow.OnDoubleClick( (HIER_LBI *) pmprlbi );
_mprhlbShow.CalcMaxHorizontalExtent() ;
}
}
else
return OnOK();
}
}
return TRUE ;
default:
break;
}
break;
case IDC_BUTTON_SEARCH:
{
UIDEBUG(SZ("Search button was pressed")) ;
MPR_LBI * pmprlbi = (MPR_LBI *) QueryShowLB()->QueryItem();
if (pmprlbi != NULL)
{
CallSearchDialog(pmprlbi) ;
}
}
return TRUE ;
default:
break;
}
return DIALOG_WINDOW::OnCommand( event );
} // MPR_BROWSE_BASE::OnCommand
/*******************************************************************
NAME: MPR_BROWSE_BASE::OnUserMessage
SYNOPSIS: Standard on user processing. Catches the WM_LB_FILLED
response and fills the listbox
NOTES:
HISTORY:
YiHsinS 07-Mar-1992 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::OnUserMessage( const EVENT & event )
{
APIERR err = NERR_Success ;
switch ( event.QueryMessage() )
{
case WM_LB_FILLED:
{
// If listbox is already enabled, then the user has tried
// to expand a server that he has typed into the path sle.
// Hence, the listbox is already filled with the necessary
// information. So, we just ignore the cache returned to us.
if ( _mprhlbShow.IsEnabled() )
return TRUE;
BOOL fError = (BOOL) event.QueryWParam();
if ( fError ) // Error occurred in the other thread
{
RESOURCE_STR nlsError( (APIERR) event.QueryLParam() );
if ( (err = nlsError.QueryError()) != NERR_Success )
::MsgPopup( this, err );
else
_sleGetInfo.SetText( nlsError );
return TRUE;
}
//
// Successfully retrieved data in the other thread
//
MPR_RETURN_CACHE *p = (MPR_RETURN_CACHE *) event.QueryLParam() ;
_mprhlbShow.SetRedraw( FALSE );
if ( IsExpandDomain() )
{
if ( !Expand( _nlsProviderToExpand, 0, p->pcacheDomain ) )
{
// Cannot expand the provider name, set the selection
// to the first item
_mprhlbShow.SelectItem( 0 );
}
else
{
// If this is not successful, then the selection is the
// provider name ( expanded ) which is what we want
Expand( _nlsWkstaDomain, 1, p->pcacheServer, TRUE );
}
}
_mprhlbShow.CalcMaxHorizontalExtent() ;
_mprhlbShow.Invalidate( TRUE );
_mprhlbShow.SetRedraw( TRUE );
ShowMprListbox( TRUE );
MPR_LBI *pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem();
/* QueryItem() can fail if its call to SendMessage fails
*/
if ( (pmprlbi != NULL) && _fSearchDialogUsed )
_buttonSearch.Enable( pmprlbi->IsSearchDialogSupported());
delete p->pcacheDomain;
p->pcacheDomain = NULL;
delete p->pcacheServer;
p->pcacheServer = NULL;
}
break ;
default:
return DIALOG_WINDOW::OnUserMessage( event ) ;
}
return TRUE;
}
void MPR_BROWSE_BASE::CallSearchDialog( MPR_LBI *pmprlbi )
{
APIERR err ;
TCHAR szNetPath[MAX_NET_PATH] ;
LPNETRESOURCE lpNetRes = pmprlbi->QueryLPNETRESOURCE() ;
PF_NPSearchDialog pfn = (PF_NPSearchDialog)
::WNetGetSearchDialog(lpNetRes ? lpNetRes->lpProvider : NULL ) ;
DWORD lpnFlags;
if (pfn)
{
err = (*pfn)(QueryRobustHwnd(),
lpNetRes,
szNetPath,
sizeof(szNetPath)/sizeof(szNetPath[0]),
&lpnFlags);
}
else
{
err = WN_NOT_SUPPORTED;
}
if (err == WN_SUCCESS)
{
SetNetPathString( szNetPath );
SetFocusToNetPath();
if ( lpnFlags == WNSRCH_REFRESH_FIRST_LEVEL )
{
AUTO_CURSOR autocur;
MPR_HIER_LISTBOX *plb = QueryShowLB();
INT nPrevProvider = plb->FindNextProvider( 0 );
UIASSERT ( nPrevProvider >= 0 );
INT nNextProvider = plb->FindNextProvider( nPrevProvider + 1);
INT nCurrent = plb->QueryCurrentItem();
do {
if ( ( nCurrent >= nPrevProvider )
&& ( ( nCurrent < nNextProvider )
|| ( nNextProvider < 0 )
)
)
{
MPR_LBI *plbi = (MPR_LBI *) plb->QueryItem( nPrevProvider );
UIASSERT ( plbi != NULL );
plb->CollapseItem( plbi );
plb->SelectItem( nPrevProvider );
plb->DeleteChildren( plbi );
// Enumerate Children
err = ::EnumerateShow( QueryHwnd(),
RESOURCE_GLOBALNET,
QueryType(),
0,
plbi->QueryLPNETRESOURCE(),
plbi,
&_mprhlbShow );
err = err ? err : plb->ExpandItem( plbi );
break;
}
else if ( nPrevProvider < 0 )
{
UIASSERT( FALSE );
break;
}
nPrevProvider = nNextProvider;
nNextProvider = plb->FindNextProvider( nPrevProvider + 1);
} while ( TRUE );
}
_mprhlbShow.CalcMaxHorizontalExtent() ;
}
if ( err != WN_SUCCESS )
::MsgPopup( this, err );
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::ShowSearchDialogOnDoubleClick
SYNOPSIS: This method is called when the user double clicks
an item in the listbox or select an time/hit Enter key
in the listbox.
ENTRY: pmprlbi - the item selected in the listbox
RETURN: TRUE if we have shown the search dialog, FALSE otherwise.
NOTES: We will only show the search dialog only if the item
is a provider that supports the search dialog but
not global enumeration.
HISTORY:
Yi-HsinS 30-Nov-1992 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::ShowSearchDialogOnDoubleClick( MPR_LBI *pmprlbi )
{
if ( ( pmprlbi != NULL )
&& ( pmprlbi->IsProvider() )
)
{
if ( !pmprlbi->QueryExpanded()
&& pmprlbi->IsSearchDialogSupported()
&& !WNetSupportGlobalEnum((TCHAR *) pmprlbi->QueryRemoteName())
)
{
CallSearchDialog(pmprlbi) ;
return TRUE;
}
}
return FALSE;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::QueryWkstaDomain
SYNOPSIS: Get the user's logged on domain
ENTRY: pnlsWkstaDomain - NLS_STR to receive domain
EXIT: pnlsWkstaDomain will contain the user name or the empty string
RETURNS: NERR_Success if successful, error code otherwise
NOTES:
HISTORY:
Yi-HsinS 4-Nov-1992 Created
********************************************************************/
#define NETAPI_DLL_STRING SZ("netapi32.dll")
#define NETWKSTAUSERGETINFO ("NetWkstaGetInfo")
#define NETAPIBUFFERFREE ("NetApiBufferFree")
typedef APIERR (*PNETWKSTAUSERGETINFO)( const TCHAR FAR *, DWORD, BYTE FAR **);
typedef APIERR (*PNETAPIBUFFERFREE)( BYTE * );
APIERR MPR_BROWSE_BASE::QueryWkstaDomain( NLS_STR *pnlsWkstaDomain )
{
*pnlsWkstaDomain = SZ("");
HMODULE hmod = ::LoadLibraryEx( NETAPI_DLL_STRING,
NULL,
LOAD_WITH_ALTERED_SEARCH_PATH );
if ( hmod == NULL )
return ::GetLastError();
APIERR err;
PNETWKSTAUSERGETINFO plpfn;
plpfn = (PNETWKSTAUSERGETINFO) ::GetProcAddress( hmod, NETWKSTAUSERGETINFO);
if ( plpfn == NULL )
{
err = ::GetLastError();
}
else
{
WKSTA_INFO_100 *pwki100 = NULL;
err = (*plpfn)( NULL, 100, (BYTE **) &pwki100 );
if ( err == NERR_Success )
{
err = pnlsWkstaDomain->CopyFrom( pwki100->wki100_langroup );
}
PNETAPIBUFFERFREE plpfnBufferFree;
plpfnBufferFree = (PNETAPIBUFFERFREE) ::GetProcAddress( hmod, NETAPIBUFFERFREE );
if ( plpfnBufferFree != NULL )
{
// The error code is not interesting here
// We got the logon name and we'll just trying to free the
// buffer if possible
(*plpfnBufferFree)( (BYTE *) pwki100 );
}
}
::FreeLibrary( hmod );
return err;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::QueryProviderToExpand
SYNOPSIS: Get the lanman provider name
ENTRY: pnlsProvider - NLS_STR to receive lanman provider name
EXIT: pnlsProvider will contain the provider name or the
empty string
contents of pfIsNT is TRUE if the provider picked in
NT Lanman. else tis FALSE
RETURNS: NERR_Success if successful, error code otherwise
NOTES:
HISTORY:
Yi-HsinS 4-Nov-1992 Created
********************************************************************/
#define LANMAN_WORKSTATION_NODE SZ("System\\CurrentControlSet\\Services\\LanmanWorkstation\\networkprovider")
#define PROVIDER_VALUE_NAME SZ("Name")
APIERR MPR_BROWSE_BASE::QueryProviderToExpand( NLS_STR *pnlsProvider,
BOOL *pfIsNT )
{
//
// init some defaults
//
*pnlsProvider = SZ("");
*pfIsNT = FALSE ;
APIERR err ;
NLS_STR nlsLanmanProvider;
if ((err = nlsLanmanProvider.QueryError()) != NERR_Success)
return err ;
//
// get the NT supplied provider if we can
//
REG_KEY *pRegKeyLocalMachine = REG_KEY::QueryLocalMachine();
if ( ( pRegKeyLocalMachine == NULL )
|| ( (err = pRegKeyLocalMachine->QueryError()) != NERR_Success )
)
{
//
// if an error occurs just set the LM provider to be empty
//
err = nlsLanmanProvider.CopyFrom(SZ("")) ;
}
else
{
//
// get the name from registry
//
ALIAS_STR nlsNode( LANMAN_WORKSTATION_NODE );
REG_KEY regkey( *pRegKeyLocalMachine, nlsNode );
if ( ((err = regkey.QueryError()) != NERR_Success )
|| ((err = regkey.QueryValue( PROVIDER_VALUE_NAME,
&nlsLanmanProvider ))
!= NERR_Success )
)
{
//
// if an error occurs just set the LM provider to be empty
//
err = nlsLanmanProvider.CopyFrom(SZ("")) ;
}
}
delete pRegKeyLocalMachine;
pRegKeyLocalMachine = NULL;
if (err != NERR_Success)
return err ;
//
// now call WNet to enum the providers, and pick the first in order.
// this will be the one we choose to expand.
//
HANDLE hEnum;
BOOL fFoundOne = FALSE ;
DWORD dwErr = WNetOpenEnum( RESOURCE_GLOBALNET,
RESOURCETYPE_DISK,
0,
NULL,
&hEnum );
if (dwErr == WN_SUCCESS)
{
BUFFER buf( 1024 );
DWORD dwEnumErr = buf.QueryError() ;
while ( dwEnumErr == NERR_Success )
{
DWORD dwCount = 0xffffffff; // Return as many as possible
DWORD dwBuffSize = buf.QuerySize() ;
dwEnumErr = WNetEnumResource( hEnum,
&dwCount,
buf.QueryPtr(),
&dwBuffSize );
switch ( dwEnumErr )
{
case WN_SUCCESS:
//
// just use the very first entry
//
if (dwCount >= 1)
{
NETRESOURCE *pnetres = (NETRESOURCE * )buf.QueryPtr();
*pnlsProvider = pnetres->lpRemoteName ;
fFoundOne = TRUE ;
err = pnlsProvider->QueryError() ;
}
//
// exit the loop by setting this
//
dwEnumErr = WN_NO_MORE_ENTRIES ;
break ;
//
// The buffer wasn't big enough for even one entry,
// resize it and try again.
//
case WN_MORE_DATA:
if ( dwEnumErr = buf.Resize( buf.QuerySize()*2 ))
break;
//
// Continue looping
//
dwEnumErr = WN_SUCCESS;
break;
case WN_NO_MORE_ENTRIES: // Success code, map below
default:
//
// all errors will cause us to exit
//
break;
} // switch
} // while
WNetCloseEnum( hEnum );
}
if (err)
return err ;
if (fFoundOne)
{
//
// since err was not set, we know pnlsProvider is all setup.
// all we need do is set fIsNT.
//
*pfIsNT = (*pnlsProvider == nlsLanmanProvider) ;
}
return NERR_Success ;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::Expand
SYNOPSIS: Find the given item in the listbox and expand it
ENTRY: psz - The item to search for
nLevel - The indentation level of the item
fTopIndex - TRUE if we want to set the item to top index
EXIT:
RETURNS: TRUE if we can at least find and select the item requested,
FALSE otherwise
NOTES:
HISTORY:
Yi-HsinS 4-Nov-1992 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::Expand( const TCHAR *psz,
INT nLevel,
MPR_LBI_CACHE *pcache,
BOOL fTopIndex )
{
if (psz == NULL || *psz == 0)
return FALSE ;
INT index = _mprhlbShow.FindItem( psz, nLevel );
if ( index < 0 )
return FALSE;
_mprhlbShow.SelectItem( index );
if ( ( pcache != NULL )
&& ( pcache->QueryCount() != 0 )
)
{
MPR_LBI * pmprlbi = (MPR_LBI *) _mprhlbShow.QueryItem();
UIASSERT( pmprlbi != NULL);
_mprhlbShow.AddSortedItems( (HIER_LBI **) pcache->QueryPtr(),
pcache->QueryCount(),
pmprlbi );
if ( pmprlbi->IsContainer() )
_mprhlbShow.OnDoubleClick( (HIER_LBI *) pmprlbi );
}
if ( fTopIndex )
_mprhlbShow.SetTopIndex( index );
return TRUE;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::QueryHelpFile
SYNOPSIS: overwrites the default QueryHelpFile in DIALOG_WINDOW
to use an app supplied help rather than NETWORK.HLP if
we were given onr at construct time.
ENTRY:
EXIT:
RETURNS: a pointer to a string which is the help file to use.
NOTES:
HISTORY:
ChuckC 26-Cct-1992 Created
********************************************************************/
const TCHAR * MPR_BROWSE_BASE::QueryHelpFile( ULONG nHelpContext )
{
//
// if we were given a helpfile at construct time,
// we use the given help file.
//
const TCHAR *pszHelpFile = QuerySuppliedHelpFile() ;
if (pszHelpFile && *pszHelpFile)
{
return pszHelpFile ;
}
return DIALOG_WINDOW::QueryHelpFile(nHelpContext) ;
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::IsExpandDomain
SYNOPSIS: see if user wants to expand the logon domain at startup
ENTRY:
EXIT:
RETURNS: TRUE or FALSE
NOTES:
HISTORY:
Yi-HsinS 4-Nov-1992 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::IsExpandDomain( VOID )
{
// By adding the two, we are guaranteed to have enough
TCHAR szAnswer[(sizeof(MPR_YES_VALUE)+sizeof(MPR_NO_VALUE))/sizeof(TCHAR)];
ULONG len = sizeof(szAnswer)/sizeof(szAnswer[0]);
ULONG iRes = ::GetProfileString((const TCHAR *)MPR_NETWORK_SECTION,
(const TCHAR *)MPR_EXPANDLOGONDOMAIN_KEY,
(const TCHAR *)MPR_YES_VALUE,
szAnswer,
len);
if (iRes == len) // error
return(TRUE);
return( ::stricmpf(szAnswer,(const TCHAR *)MPR_YES_VALUE)==0 );
}
/*******************************************************************
NAME: MPR_BROWSE_BASE::SetExpandDomain
SYNOPSIS: sets the ExpandLogonDomain bit in user profile
ENTRY:
EXIT:
RETURNS: BOOL indicating success (TRUE) or failure (FALSE)
NOTES:
HISTORY:
Yi-HsinS 4-Nov-1992 Created
********************************************************************/
BOOL MPR_BROWSE_BASE::SetExpandDomain(BOOL fExpand)
{
return(::WriteProfileString( (const TCHAR *)MPR_NETWORK_SECTION,
(const TCHAR *)MPR_EXPANDLOGONDOMAIN_KEY,
fExpand? (const TCHAR *)MPR_YES_VALUE
: (const TCHAR *)MPR_NO_VALUE ) != 0) ;
}
/*******************************************************************
NAME: MPR_BROWSE_DIALOG::MPR_BROWSE_DIALOG
SYNOPSIS: Constructor for the browse dialog. Almost all of the
functionality is contained in the base class, we watch
for the OK button here.
ENTRY: hwndOwner - Owner window handle
devType - Type of device we are dealing with
RETURNS:
NOTES:
HISTORY:
Johnl 27-Jan-1992 Created
********************************************************************/
MPR_BROWSE_DIALOG::MPR_BROWSE_DIALOG( HWND hwndOwner,
DEVICE_TYPE devType,
TCHAR *lpHelpFile,
DWORD nHelpContext,
NLS_STR *pnlsPath,
PFUNC_VALIDATION_CALLBACK pfuncValidation)
: MPR_BROWSE_BASE ( MAKEINTRESOURCE(IDD_NET_BROWSE_DIALOG),
hwndOwner,
devType,
lpHelpFile,
nHelpContext ),
_sleNetPath ( this, IDC_NETPATH_CONTROL ),
_pnlsPath ( pnlsPath ),
_pfuncValidation( pfuncValidation )
{
UIASSERT( pnlsPath != NULL );
if ( QueryError() )
return ;
RESOURCE_STR nlsTitle( devType==DEV_TYPE_DISK? IDS_BROWSE_DRIVE_CAPTION
: IDS_BROWSE_PRINTER_CAPTION);
APIERR err = nlsTitle.QueryError();
if (err != NERR_Success )
{
ReportError( err ) ;
return ;
}
SetText( nlsTitle ) ;
// Set focus to the Network Path field
SetFocusToNetPath();
}
MPR_BROWSE_DIALOG::~MPR_BROWSE_DIALOG()
{
/* Nothing to do */
}
/*******************************************************************
NAME: MPR_BROWSE_DIALOG::OnOK
SYNOPSIS: The user pressed the OK button so try the following:
If net path is not empty,
attempt to connect to the server in the net path
else if current item in show listbox is expandable
attempt to expand that item
EXIT:
RETURNS:
NOTES:
HISTORY:
Johnl 27-Jan-1992 Created
********************************************************************/
BOOL MPR_BROWSE_DIALOG::OnOK( void )
{
if ( QueryShowLB()->HasFocus() && ( _sleNetPath.QueryTextLength() == 0 ))
{
MPR_LBI * pmprlbi = (MPR_LBI *) QueryShowLB()->QueryItem();
if ( pmprlbi )
{
if ( !ShowSearchDialogOnDoubleClick( pmprlbi ) )
QueryShowLB()->OnDoubleClick( (HIER_LBI *) pmprlbi );
}
}
else
{
APIERR err = _sleNetPath.QueryText( _pnlsPath );
if ( err == NERR_Success )
{
if ( ( _pfuncValidation == NULL )
|| ((*_pfuncValidation)( (LPTSTR) _pnlsPath->QueryPch() ) )
)
{
Dismiss( TRUE );
}
else
{
err = IERR_INVALID_PATH;
}
}
if ( err != NERR_Success )
{
::MsgPopup( this, err );
_sleNetPath.SelectString();
_sleNetPath.ClaimFocus();
}
}
return MPR_BROWSE_BASE::OnOK() ;
}
/*******************************************************************
NAME: MPR_BROWSE_DIALOG::QueryHelpContext
SYNOPSIS: Typical help context method
HISTORY:
Johnl 27-Jan-1992 Created
********************************************************************/
ULONG MPR_BROWSE_DIALOG::QueryHelpContext( void )
{
return QuerySuppliedHelpContext() ;
}
/*******************************************************************
NAME: MPR_HIER_LISTBOX::MPR_HIER_LISTBOX
SYNOPSIS: Constructor
ENTRY: powin - pointer to owner window
cid - control id
EXIT:
RETURNS:
NOTES:
HISTORY:
Johnl 30-Jan-1992 Commented
********************************************************************/
MPR_HIER_LISTBOX::MPR_HIER_LISTBOX( OWNER_WINDOW * powin, CID cid, UINT uiType )
: HIER_LISTBOX( powin, cid, FALSE, FONT_DEFAULT, FALSE ),
_dmapGeneric ( BMID_BROWSE_GEN ),
_dmapGenericExpanded( BMID_BROWSE_GENEX ),
_dmapGenericNoExpand( BMID_BROWSE_GENNOX ),
_dmapProvider ( BMID_BROWSE_PROV),
_dmapProviderExpanded( BMID_BROWSE_PROVEX ),
_dmapDomain ( BMID_BROWSE_DOM ),
_dmapDomainExpanded ( BMID_BROWSE_DOMEX ),
_dmapDomainNoExpand ( BMID_BROWSE_DOMNOX ),
_dmapServer ( BMID_BROWSE_SRV ),
_dmapServerExpanded ( BMID_BROWSE_SRVEX ),
_dmapServerNoExpand ( BMID_BROWSE_SRVNOX ),
_dmapFile ( BMID_BROWSE_FILE ),
_dmapFileExpanded ( BMID_BROWSE_FILEEX ),
_dmapFileNoExpand ( BMID_BROWSE_FILENOX ),
_dmapTree ( BMID_BROWSE_TREE ),
_dmapTreeExpanded ( BMID_BROWSE_TREEEX ),
_dmapTreeNoExpand ( BMID_BROWSE_TREENOX ),
_dmapGroup ( BMID_BROWSE_GROUP ),
_dmapGroupExpanded ( BMID_BROWSE_GROUPEX ),
_dmapGroupNoExpand ( BMID_BROWSE_GROUPNOX ),
_dmapShare ( uiType == DEV_TYPE_DISK? BMID_BROWSE_SHR
: BMID_BROWSE_PRINT ),
_dmapShareExpanded ( uiType == DEV_TYPE_DISK? BMID_BROWSE_SHREX
: BMID_BROWSE_PRINTEX ),
_dmapShareNoExpand ( uiType == DEV_TYPE_DISK? BMID_BROWSE_SHRNOX
: BMID_BROWSE_PRINTNOX ),
_uiType ( uiType ),
_nMaxPelIndent (0)
{
if ( QueryError() )
return ;
APIERR err ;
if ( (err = _dmapGeneric.QueryError()) ||
(err = _dmapGenericExpanded.QueryError()) ||
(err = _dmapGenericNoExpand.QueryError()) ||
(err = _dmapDomain.QueryError()) ||
(err = _dmapDomainExpanded.QueryError()) ||
(err = _dmapDomainNoExpand.QueryError()) ||
(err = _dmapShare.QueryError()) ||
(err = _dmapShareExpanded.QueryError()) ||
(err = _dmapShareNoExpand.QueryError()) ||
(err = _dmapServer.QueryError()) ||
(err = _dmapServerExpanded.QueryError()) ||
(err = _dmapServerNoExpand.QueryError()) ||
(err = _dmapFile.QueryError()) ||
(err = _dmapFileExpanded.QueryError()) ||
(err = _dmapFileNoExpand.QueryError()) ||
(err = _dmapTree.QueryError()) ||
(err = _dmapTreeExpanded.QueryError()) ||
(err = _dmapTreeNoExpand.QueryError()) ||
(err = _dmapGroup.QueryError()) ||
(err = _dmapGroupExpanded.QueryError()) ||
(err = _dmapGroupNoExpand.QueryError()) ||
(err = DISPLAY_TABLE::CalcColumnWidths( _adxColumns,
4,
powin,
QueryCid(),
FALSE )) )
{
ReportError( err ) ;
return ;
}
DISPLAY_CONTEXT dc( QueryHwnd() );
dc.SelectFont( QueryFont() );
// JonN 6/18/95 remove unnecessary floating point
_nAveCharWidth = (dc.QueryAveCharWidth() * 3) / 2;
}
MPR_HIER_LISTBOX::~MPR_HIER_LISTBOX()
{
/* Nothing to do */
}
/*******************************************************************
NAME: MPR_HIER_LISTBOX::AddChildren
SYNOPSIS: Redefined virtual to add enumerate the children of the
passed parent.
ENTRY: phlbi - Parent LBI to enumerate children under
EXIT:
RETURNS:
NOTES:
HISTORY:
Johnl 30-Jan-1992 Commented, made non-static
********************************************************************/
APIERR MPR_HIER_LISTBOX::AddChildren( HIER_LBI * phlbi )
{
UIASSERT( phlbi != NULL );
return ::EnumerateShow( QueryHwnd(),
RESOURCE_GLOBALNET,
QueryType(),
0,
((MPR_LBI *)phlbi)->QueryLPNETRESOURCE(),
(MPR_LBI *)phlbi,
this );
}
/*******************************************************************
NAME: MPR_HIER_LISTBOX::FindItem
SYNOPSIS: Find an LBI in the given indentation level that
matches the given string.
ENTRY: pszItem - the item we are looking for
nLevel - the indentation level of the item
EXIT:
RETURNS: The index of the item we are searching for. -1 if
we cannot find any.
NOTES:
HISTORY:
Yi-HsinS 04-Nov-1992 Created
********************************************************************/
INT MPR_HIER_LISTBOX::FindItem( const TCHAR *pszItem, INT nLevel )
{
for ( INT i = 0; i < QueryCount(); i ++ )
{
MPR_LBI *plbi = (MPR_LBI *) QueryItem( i );
/* QueryItem() can fail if its call to SendMessage fails
*/
if (( plbi != NULL )
&&
( ::stricmpf( pszItem, plbi->QueryRemoteName() ) == 0 )
&&
( plbi->QueryIndentLevel() == nLevel ))
{
return i;
}
}
return -1;
}
/*******************************************************************
NAME: MPR_HIER_LISTBOX::FindNextProvider
SYNOPSIS: Find the next LBI starting at the given index that
is represents a provider ( top level ).
ENTRY: iStart - The place the start the search
EXIT:
RETURNS: The index of the item we are searching for. -1 if
we cannot find any.
NOTES:
HISTORY:
Yi-HsinS 04-Nov-1992 Created
********************************************************************/
INT MPR_HIER_LISTBOX::FindNextProvider( INT iStart )
{
UIASSERT( iStart >= 0 );
for ( INT i = iStart; i < QueryCount(); i++ )
{
MPR_LBI *plbi = (MPR_LBI *) QueryItem( i );
if ( plbi->QueryIndentLevel() == 0 ) // Topmost level
return i;
}
return -1;
}
/*******************************************************************
NAME: MPR_HIER_LISTBOX::CalcMaxHorizontalExtent
SYNOPSIS: Traverses all items in the listbox and calculates the
indent level of the deepest item and the total horizontal
width
RETURNS: Count of PELs wher
NOTES: _nMaxPelIndent is set by this method
The container name field width is extended for each LBI to
the deepest indentation such that the comment will always
be aligned.
HISTORY:
Johnl 17-Mar-1993 Created
********************************************************************/
#define RIGHT_MARGIN 3 // Small white space on right side of Listbox
void MPR_HIER_LISTBOX::CalcMaxHorizontalExtent( void )
{
//
// Find the node that is indented the most and record the indentation
// and while we are at it, record the longest comment
//
UINT nPelIndent = 0 ;
UINT nMaxPelIndent = 0 ;
UINT nCommentSize = 0 ;
UINT nMaxCommentSize = 0 ;
DISPLAY_CONTEXT dc( QueryHwnd() ) ;
dc.SelectFont( QueryFont() ) ;
for ( int i = 0 ; i < QueryCount() ; i++ )
{
MPR_LBI * pmprlbi = (MPR_LBI*) QueryItem( i ) ;
if ( pmprlbi != NULL )
{
if ((nPelIndent = pmprlbi->QueryPelIndent()) > nMaxPelIndent )
{
nMaxPelIndent = nPelIndent ;
}
if ( pmprlbi->QueryComment() && *pmprlbi->QueryComment() )
{
nCommentSize = dc.QueryTextWidth( pmprlbi->QueryComment() ) ;
if ( nCommentSize > nMaxCommentSize )
nMaxCommentSize = nCommentSize ;
}
}
else
{
UIASSERT( FALSE ) ;
return ;
}
}
SetMaxPelIndent( nMaxPelIndent ) ;
SetHorizontalExtent( QueryMaxPelIndent() +
QueryColWidthArray()[1] +
QueryColWidthArray()[2] +
nMaxCommentSize + RIGHT_MARGIN ) ;
}
/*******************************************************************
NAME: MPR_HIER_LISTBOX::QueryDisplayMap
SYNOPSIS: Returns the appropriate display map based on the
type of the properties
ENTRY: fIsContainer - TRUE if this is a container object
fIsExpanded - TRUE if this is an expanded container object
EXIT:
RETURNS: Display Map for a Container, or an Expanded Container
NOTES:
HISTORY:
Johnl 09-Jan-1992 Created
********************************************************************/
DISPLAY_MAP * MPR_HIER_LISTBOX::QueryDisplayMap( BOOL fIsContainer,
BOOL fIsExpanded,
DWORD dwDisplayType,
BOOL fIsProvider )
{
UNREFERENCED( fIsContainer ) ;
switch (dwDisplayType)
{
case RESOURCEDISPLAYTYPE_DOMAIN:
if ( fIsExpanded )
return &_dmapDomainExpanded ;
return ( fIsContainer ? &_dmapDomain : &_dmapDomainNoExpand ) ;
case RESOURCEDISPLAYTYPE_SERVER:
if ( fIsExpanded )
return &_dmapServerExpanded ;
return ( fIsContainer ? &_dmapServer : &_dmapServerNoExpand ) ;
case RESOURCEDISPLAYTYPE_SHARE:
if ( fIsExpanded )
return &_dmapShareExpanded ;
return ( fIsContainer ? &_dmapShare : &_dmapShareNoExpand ) ;
case RESOURCEDISPLAYTYPE_FILE:
if ( fIsExpanded )
return &_dmapFileExpanded ;
return ( fIsContainer ? &_dmapFile : &_dmapFileNoExpand ) ;
case RESOURCEDISPLAYTYPE_TREE:
if ( fIsExpanded )
return &_dmapTreeExpanded ;
return ( fIsContainer ? &_dmapTree : &_dmapTreeNoExpand ) ;
case RESOURCEDISPLAYTYPE_GROUP:
if ( fIsExpanded )
return &_dmapGroupExpanded ;
return ( fIsContainer ? &_dmapGroup : &_dmapGroupNoExpand ) ;
default:
if ( fIsProvider )
{
if ( fIsExpanded )
return &_dmapProviderExpanded;
return &_dmapProvider;
}
else
{
if ( fIsExpanded )
return &_dmapGenericExpanded ;
return ( fIsContainer ? &_dmapGeneric : &_dmapGenericNoExpand ) ;
}
}
}
/*******************************************************************
NAME: MPR_LBI::MPR_LBI
SYNOPSIS: Normal LBI constructor
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Johnl 30-Jan-1992 Commented
beng 31-Mar-1992 Slight Unicode fix
********************************************************************/
MPR_LBI::MPR_LBI( LPNETRESOURCE lpnetresource )
: HIER_LBI( FALSE ),
_nlsDisplayName(),
_fRefreshNeeded( FALSE )
{
if ( QueryError() != NERR_Success )
return;
if ( _nlsDisplayName.QueryError() != NERR_Success )
{
ReportError( _nlsDisplayName.QueryError() );
return;
}
_netres.dwScope = lpnetresource->dwScope;
_netres.dwType = lpnetresource->dwType;
_netres.dwDisplayType = lpnetresource->dwDisplayType;
_netres.dwUsage = lpnetresource->dwUsage;
_netres.lpRemoteName = NULL ;
_netres.lpLocalName = NULL;
_netres.lpProvider = NULL ;
_netres.lpComment = NULL ;
/* Note that we do new(count of characters) because we are using
* the transmutable type TCHAR.
*/
if ( lpnetresource->lpRemoteName != NULL )
{
if ( (_netres.lpRemoteName = new TCHAR[ ::strlenf( lpnetresource->lpRemoteName ) + 1]) != NULL)
::strcpyf( _netres.lpRemoteName, lpnetresource->lpRemoteName);
else
ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
}
if ( lpnetresource->lpLocalName != NULL )
{
if ((_netres.lpLocalName = new TCHAR[ ::strlenf( lpnetresource->lpLocalName ) + 1]) != NULL)
::strcpyf( _netres.lpLocalName, lpnetresource->lpLocalName);
else
ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
}
if ( lpnetresource->lpProvider != NULL )
{
if ((_netres.lpProvider = new TCHAR[ ::strlenf( lpnetresource->lpProvider ) + 1]) != NULL)
::strcpyf( _netres.lpProvider, lpnetresource->lpProvider);
else
ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
}
if ( lpnetresource->lpComment != NULL )
{
if ((_netres.lpComment = new TCHAR[ ::strlenf( lpnetresource->lpComment ) + 1])!=NULL )
::strcpyf( _netres.lpComment, lpnetresource->lpComment);
else
ReportError( ERROR_NOT_ENOUGH_MEMORY ) ;
}
}
MPR_LBI::~MPR_LBI()
{
delete _netres.lpLocalName;
delete _netres.lpRemoteName;
delete _netres.lpProvider;
delete _netres.lpComment;
_netres.lpLocalName = _netres.lpRemoteName = NULL;
_netres.lpProvider = _netres.lpComment = NULL;
}
BOOL MPR_LBI::IsContainer( void ) const
{
if ( _netres.dwScope & RESOURCE_GLOBALNET )
return !!( _netres.dwUsage & RESOURCEUSAGE_CONTAINER );
else
return FALSE;
}
BOOL MPR_LBI::IsSearchDialogSupported( void ) const
{
return( ::WNetGetSearchDialog( _netres.lpProvider ) != NULL );
}
BOOL MPR_LBI::IsConnectable( void ) const
{
if ( _netres.dwScope & RESOURCE_GLOBALNET )
return !!(_netres.dwUsage & RESOURCEUSAGE_CONNECTABLE );
else
return FALSE;
}
BOOL MPR_LBI::IsProvider( void ) const
{
// Topmost level is provider
return ((MPR_LBI *) this)->QueryIndentLevel() == 0 ;
}
VOID MPR_LBI::Paint( LISTBOX * plb, HDC hdc, const RECT * prect,
GUILTT_INFO * pGUILTT ) const
{
MPR_HIER_LISTBOX * mprhlb = (MPR_HIER_LISTBOX *) plb ;
//
// Copy the master column widths array. The 0th item will be replaced
// by the pel-indent and the container name [2] will be adjusted to keep
// the comment aligned. Note that the base is widened such that the
// right edge will always cause the comment to line up in the next
// column.
//
UINT adxColumns[4];
for ( INT i = 1; i < 4; i++ )
adxColumns[ i ] = mprhlb->QueryColWidthArray()[ i ];
// adxColumns[2] += mprhlb->QueryMaxPelIndent() - QueryPelIndent() ;
UINT indent = QueryPelIndent();
adxColumns[0] = indent;
if (adxColumns[2] < 2 * indent)
{
adxColumns[2] = indent;
}
else
{
adxColumns[2] -= indent;
}
if ( _nlsDisplayName.QueryTextLength() == 0 )
{
APIERR err = ::GetNetworkDisplayName( _netres.lpProvider,
_netres.lpRemoteName,
WNFMT_ABBREVIATED | WNFMT_INENUM,
adxColumns[2] / mprhlb->QueryAveCharWidth(),
(NLS_STR *) & _nlsDisplayName );
if ( err != NERR_Success )
{
::MsgPopup( plb->QueryOwnerHwnd(), err );
return;
}
}
DM_DTE dmdte( mprhlb->QueryDisplayMap( IsContainer(),
QueryExpanded(),
QueryDisplayType(),
IsProvider())) ;
STR_DTE sdte( _nlsDisplayName.QueryPch() );
STR_DTE sdteComment( QueryComment() ) ;
DISPLAY_TABLE dtab( 4, adxColumns );
dtab[0] = NULL;
dtab[1] = &dmdte;
dtab[2] = &sdte;
dtab[3] = &sdteComment;
dtab.Paint( plb, hdc, prect, pGUILTT );
}
/*******************************************************************
NAME: MPR_LBI::QueryLeadingChar
SYNOPSIS: Returns the first non-'\\' character of the remote name
ENTRY:
RETURNS: The first non back slash character of the remote name
NOTES: This code is not DBCS safe, which is OK since it should
only be run with ANSI and UNICODE character sets.
HISTORY:
Johnl 09-Jan-1992 Changed to return first non-'\\' character
********************************************************************/
WCHAR MPR_LBI::QueryLeadingChar() const
{
TCHAR * pchRemoteName = _netres.lpRemoteName ;
while ( *pchRemoteName && *pchRemoteName == TCH('\\') )
pchRemoteName++ ;
return *pchRemoteName ;
}
INT MPR_LBI::Compare( const LBI * plbi ) const
{
return ::stricmpf( _netres.lpRemoteName,
((const MPR_LBI *)plbi)->_netres.lpRemoteName );
}
MPR_LBI_CACHE::MPR_LBI_CACHE( INT cInitialItems )
: BASE(),
_cItems( 0 ),
_cMaxItems( cInitialItems ),
_buffArray( cInitialItems * sizeof(MPR_LBI*) )
{
if ( QueryError() )
return ;
if ( _buffArray.QueryError() )
ReportError( _buffArray.QueryError() ) ;
}
MPR_LBI_CACHE::~MPR_LBI_CACHE()
{
// Nothing to do
}
/*******************************************************************
NAME: MPR_LBI_CACHE::AppendItem
SYNOPSIS: Adds an item to the end of the cache
ENTRY: plbi - Item to add
EXIT: The item will be deleted if an error occurs
RETURNS: NERR_Success is successful, error code otherwise
NOTES: Behave just like AddItem
HISTORY:
Johnl 27-Jan-1993 Created
********************************************************************/
#define CACHE_DELTA 100
APIERR MPR_LBI_CACHE::AppendItem( MPR_LBI * plbi )
{
APIERR err = ERROR_NOT_ENOUGH_MEMORY ;
if ( plbi == NULL ||
(err = plbi->QueryError()) )
{
delete plbi ;
return err ;
}
//
// Do we need to resize the array?
//
if ( _cItems >= _cMaxItems )
{
if ( err = _buffArray.Resize( _buffArray.QuerySize() +
CACHE_DELTA * sizeof(MPR_LBI*) ))
{
delete plbi ;
return err ;
}
_cMaxItems += CACHE_DELTA ;
}
QueryPtr()[_cItems++] = plbi ;
return err ;
}
void MPR_LBI_CACHE::Sort( void )
{
if ( QueryCount() > 0 )
{
::qsort( (void *) _buffArray.QueryPtr(),
QueryCount(),
sizeof(MPR_LBI*),
MPR_LBI_CACHE::CompareLbis ) ;
}
}
INT MPR_LBI_CACHE::FindItem( const TCHAR *psz )
{
for ( INT i= 0; i < QueryCount(); i++ )
{
if ( ::stricmpf( (QueryPtr()[i])->QueryRemoteName(), psz ) == 0 )
return i;
}
return -1;
}
VOID MPR_LBI_CACHE::DeleteAllItems( VOID )
{
for ( INT i= 0; i < QueryCount(); i++ )
{
MPR_LBI *plbi = QueryPtr()[i];
delete plbi;
QueryPtr()[i] = NULL;
}
_cItems = 0;
}
int __cdecl MPR_LBI_CACHE::CompareLbis( const void * p0,
const void * p1 )
{
MPR_LBI * plbi = (MPR_LBI*) *((MPR_LBI**)p0) ;
return plbi->Compare( (LBI*) *((MPR_LBI**)p1) ) ;
}