windows-nt/Source/XPSP1/NT/admin/netui/shellui/share/sharebas.cxx
2020-09-26 16:20:57 +08:00

1575 lines
40 KiB
C++

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
* sharebas.cxx
* This file contains the definitions of base share dialog class,
* and some common classes used by the share dialogs,
* including SHARE_DIALOG_BASE, SHARE_LEVEL_PERMISSIONS_DIALOG,
* PERMISSION_GROUP, SHARE_NAME_WITH_PATH_ENUM_ITER,
* SERVER_WITH_PASSWORD_PROMPT and SHARE_NET_NAME.
*
* History:
* Yi-HsinS 8/15/91 Created
* Yi-HsinS 11/15/91 Changed all USHORT to UINT
* Yi-HsinS 12/5/91 Test more thoroughly for invalid
* path name
* Yi-HsinS 12/6/91 Uses NET_NAME
* Yi-HsinS 12/31/91 Unicode work
* Yi-HsinS 1/8/92 Moved SHARE_PROPERTIES_BASE to
* sharewnp.cxx
* Yi-HsinS 3/12/92 Added ACCESS_PERM to PERMISSIONS_GROUP
* Terryk 4/12/92 Change USER limit from UINT to ULONG
* Yi-HsinS 4/21/92 Remove unnecessay code, and remove
* _uiSpecialUserLimit
* Yi-HsinS 5/15/92 Make password dialog show up only if
* focus on share-level servers
* Yi-HsinS 8/6/92 Reorganize to match Winball dialogs.
* ChuckC 8/12/92 Added support for ACLs on Shares.
* Yi-HsinS 11/16/92 Removed SLT_ADMININFO
* YiHsinS 4/2/93 Disable viewing/changing permission on special
* shares ( [A-Z]$, IPC$, ADMIN$ )
*/
#define INCL_WINDOWS_GDI
#define INCL_WINDOWS
#define INCL_DOSERRORS
#define INCL_NETERRORS
#define INCL_NETSHARE
#define INCL_NETSERVER
#define INCL_NETWKSTA
#define INCL_NETLIB
#include <lmui.hxx>
extern "C"
{
#include <sharedlg.h>
#include <helpnums.h>
}
#define INCL_BLT_DIALOG
#define INCL_BLT_CONTROL
#define INCL_BLT_MSGPOPUP
#define INCL_BLT_SPIN_GROUP
#define INCL_BLT_GROUP
#include <blt.hxx>
#include <string.hxx>
#include <uitrace.hxx>
#include <dbgstr.hxx>
#include <lmoesh.hxx>
#include <lmoeusr.hxx>
#include <lmosrv.hxx>
#include <lmoshare.hxx>
#include <lmowks.hxx>
#include <strchlit.hxx> // for string and character constants
#include "sharebas.hxx"
#include <shareacl.hxx> // for the function prototypes
#define USERS_DEFAULT 10
#define USERS_MIN 1
#define PERM_DEFAULT_LEN 7 // length of "RWCXDAP"
/*******************************************************************
NAME: SHARE_DIALOG_BASE::SHARE_DIALOG_BASE
SYNOPSIS: Constructor for SHARE_DIALOG_BASE class
ENTRY: pszDlgResource - resource name for DIALOG_WINDOW
hwndParent - handle of parent window
ulMaxUserLimit - the maximum user limit to be set
in the user limit spin button
ulHelpContextBase - the base help context
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
Yi-HsinS 1/17/91 Added _uiSpecialUserLimit
Yi-HsinS 4/25/91 Remove _uiSpecialUserLimit
Yi-HsinS 10/9/92 Added _ulHelpContextBase
********************************************************************/
SHARE_DIALOG_BASE::SHARE_DIALOG_BASE( const TCHAR *pszDlgResource,
HWND hwndParent,
ULONG ulHelpContextBase,
ULONG ulMaxUserLimit )
: DIALOG_WINDOW ( pszDlgResource, hwndParent ),
_slePath( this, SLE_PATH ),
_sleComment( this, SLE_COMMENT, SHARE_COMMENT_LENGTH ),
_mgrpUserLimit( this, RB_UNLIMITED, 2, RB_UNLIMITED), // 2 buttons
_spsleUsers( this, SLE_USERS, USERS_DEFAULT,
USERS_MIN, ulMaxUserLimit - USERS_MIN + 1, TRUE,
FRAME_USERS ),
_spgrpUsers( this, SB_USERS_GROUP, SB_USERS_UP, SB_USERS_DOWN),
_buttonOK( this, IDOK ),
_buttonCancel( this, IDCANCEL ),
_buttonPermissions( this, BUTTON_PERMISSIONS ),
_pStoredSecDesc( NULL ), // default : NULL
_fSecDescModified( FALSE ), // initially unchanged
_nlsStoredPassword(), // default : empty string
_uiStoredPermissions( ACCESS_READ | ACCESS_EXEC ), // default permission
_fStoredAdminOnly( FALSE ),
_ulHelpContextBase( ulHelpContextBase )
{
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
|| ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
|| ((err = _mgrpUserLimit.AddAssociation( RB_USERS, &_spgrpUsers ))
!= NERR_Success )
|| ((err = _nlsStoredPassword.QueryError()) != NERR_Success )
)
{
ReportError( err );
return;
}
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::~SHARE_DIALOG_BASE
SYNOPSIS: Destructor for SHARE_DIALOG_BASE class
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
SHARE_DIALOG_BASE::~SHARE_DIALOG_BASE()
{
delete _pStoredSecDesc;
memsetf((LPVOID)_nlsStoredPassword.QueryPch(),
0,
_nlsStoredPassword.QueryTextSize()) ;
_pStoredSecDesc = NULL;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::ClearStoredInfo
SYNOPSIS: Clear the permission or security description stored
internally.
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/6/92 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::ClearStoredInfo( VOID )
{
delete _pStoredSecDesc;
_pStoredSecDesc = NULL;
_nlsStoredPassword = EMPTY_STRING;
_uiStoredPermissions = ACCESS_READ | ACCESS_EXEC;
return _nlsStoredPassword.QueryError();
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::UpdateInfo
SYNOPSIS: Set the information about the share in the dialog
ENTRY: psvr - pointer to the server object that the share is on
pszShare - the share to display
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::UpdateInfo( SERVER_WITH_PASSWORD_PROMPT *psvr,
const TCHAR *pszShare )
{
AUTO_CURSOR autocur;
UIASSERT( psvr != NULL );
UIASSERT( pszShare != NULL );
APIERR err;
SHARE_2 sh2( pszShare, psvr->QueryName(), FALSE );
if ( ((err = sh2.QueryError() ) == NERR_Success )
&& ((err = sh2.GetInfo()) == NERR_Success )
)
{
if ( _slePath.QueryTextLength() == 0
&& NULL != sh2.QueryPath() ) // JonN 01/27/00: PREFIX bug 444916
SetPath( sh2.QueryPath() );
SetComment( sh2.QueryComment() );
SetUserLimit( sh2.QueryMaxUses() );
err = UpdatePermissionsInfo( psvr, &sh2, pszShare );
}
return err;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::UpdatePermissionsInfo
SYNOPSIS: Set the permissions information about the share
ENTRY: psvr - pointer to the server object that the share is on
psh2 - pointer to an existing SHARE_2 object
pszShare - the share to display
EXIT:
RETURNS:
NOTES:
HISTORY:
JonN 11/22/93 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::UpdatePermissionsInfo(
SERVER_WITH_PASSWORD_PROMPT *psvr,
SHARE_2 * psh2,
const TCHAR *pszShare )
{
AUTO_CURSOR autocur;
UIASSERT( psvr != NULL );
UIASSERT( psh2 != NULL );
UIASSERT( pszShare != NULL );
APIERR err = NERR_Success;
if ( psvr->IsNT() )
{
_fSecDescModified = FALSE ;
if ( psh2->IsAdminOnly() ) // There are no security descriptors in
// special shares.
{
delete _pStoredSecDesc;
_pStoredSecDesc = NULL;
_fStoredAdminOnly = TRUE;
}
else
{
_fStoredAdminOnly = FALSE;
err = QuerySharePermissions( psvr->QueryName(),
pszShare,
&_pStoredSecDesc );
}
}
else if ( psvr->IsShareLevel() ) // LM 2.x share-level server
{
_nlsStoredPassword = psh2->QueryPassword();
_uiStoredPermissions = psh2->QueryPermissions();
err = _nlsStoredPassword.QueryError();
}
//
// Do not need to get permissions on LM2.x user-level server
// because it has no permissions for shares.
//
return err;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::OnChangeShareProperty
SYNOPSIS: Helper method to change the properties of the share
ENTRY: psvr - pointer the server object that the share is on
pszShare - the share that we want to change properties on
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::OnChangeShareProperty(
SERVER_WITH_PASSWORD_PROMPT *psvr,
const TCHAR *pszShare )
{
APIERR err;
UIASSERT( psvr != NULL );
UIASSERT( pszShare != NULL );
//
// Get all information about the share
//
SHARE_2 sh2( pszShare, psvr->QueryName(), FALSE);
NLS_STR nlsComment;
do { // Not a loop
if ( ((err = sh2.QueryError() ) != NERR_Success )
|| ((err = sh2.GetInfo()) != NERR_Success )
|| ((err = nlsComment.QueryError()) != NERR_Success )
)
{
break;
}
//
// Set validation flag to TRUE to enable checking for invalid
// information set to the share object.
//
sh2.SetValidation( TRUE );
//
// Query, validate and set the comment on the share
//
if ( ((err = QueryComment( &nlsComment )) != NERR_Success )
|| ((err = sh2.SetComment( nlsComment )) != NERR_Success )
)
{
err = ( err == ERROR_INVALID_PARAMETER ) ?
(APIERR) IERR_SHARE_INVALID_COMMENT : err;
SetFocusOnComment();
break;
}
//
// Set the max uses on the share
//
if ((err = sh2.SetMaxUses( (UINT) QueryUserLimit())) != NERR_Success )
{
SetFocusOnUserLimit();
break;
}
//
// Set the permissions on the share if it's on LM share level servers
//
if ( !psvr->IsNT() && psvr->IsShareLevel() )
{
//
// Upper case the password => same as netcmd
// since Share-level servers are down level servers only
//
_nlsStoredPassword._strupr();
//
// Give a warning if the user wants to change the password
//
if ( ::stricmpf( _nlsStoredPassword, sh2.QueryPassword() ) != 0 )
{
NLS_STR nlsComputer;
if ( ((err = nlsComputer.QueryError()) != NERR_Success )
|| ((err = psvr->QueryDisplayName( &nlsComputer ))
!= NERR_Success )
)
{
break;
}
if ( ::MsgPopup( this,
(MSGID) IDS_SHARE_PROP_CHANGE_PASSWD_WARN_TEXT,
MPSEV_WARNING, MP_OKCANCEL,
nlsComputer.QueryPch(),
sh2.QueryName(), MP_CANCEL ) == IDCANCEL )
{
//
// User click CANCEL =>
// Reset password to the original value!
//
_nlsStoredPassword = sh2.QueryPassword();
err = IERR_USER_CLICKED_CANCEL;
break;
}
//
// Set the password on the share
//
if (( err = sh2.SetPassword( _nlsStoredPassword ))
!= NERR_Success )
break;
}
//
// We are successful up to this point, so set the permissions
//
if ( (err = sh2.SetPermissions( _uiStoredPermissions ))
!= NERR_Success )
break;
}
//
// Write the information out
//
if ( (err = sh2.WriteInfo()) != NERR_Success )
break;
//
// If the share is on an NT server and it is not
// a special share, set the permission to it.
//
if ( psvr->IsNT() && !sh2.IsAdminOnly() )
{
err = ApplySharePermissions( sh2.QueryServer(),
sh2.QueryName(),
QueryStoredSecDesc() );
if (err)
break ;
}
// Falls through if error occurs
}
while (FALSE);
return err;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::OnCommand
SYNOPSIS: Handle the case where the user clicked the permission button
ENTRY: event - the CONTROL_EVENT that occurred
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/6/92 Created
********************************************************************/
BOOL SHARE_DIALOG_BASE::OnCommand( const CONTROL_EVENT &event )
{
APIERR err = NERR_Success;
if ( event.QueryCid() == BUTTON_PERMISSIONS )
{
OnPermissions();
return TRUE;
}
return DIALOG_WINDOW::OnCommand( event );
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::OnPermissions
SYNOPSIS: Helper method to popup the permission dialog
when the permission button is clicked
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/6/92 Created
********************************************************************/
VOID SHARE_DIALOG_BASE::OnPermissions( VOID )
{
AUTO_CURSOR autocur;
//
// Get the server that the share is on
//
SERVER_WITH_PASSWORD_PROMPT *psvr = NULL;
APIERR err = QueryServer2( &psvr );
if ( err == NERR_Success )
{
if ( psvr->IsNT() ) // On NT servers
{
//
// If we are viewing a admin only share,
// we cannot change permission on it.
//
if ( _fStoredAdminOnly )
{
err = IERR_SPECIAL_SHARE_CANNOT_SET_PERMISSIONS;
}
else
{
NLS_STR nlsShare;
if ( ((err = nlsShare.QueryError()) == NERR_Success )
&& ((err = QueryShare( &nlsShare )) == NERR_Success )
)
{
err = EditShareAcl( QueryHwnd(),
psvr->QueryName(),
nlsShare.QueryPch(),
&_fSecDescModified,
&_pStoredSecDesc,
QueryHelpContextBase() ) ;
}
}
}
else if ( psvr->IsShareLevel() ) // On LM share-level server
{
SHARE_LEVEL_PERMISSIONS_DIALOG *pdlg =
new SHARE_LEVEL_PERMISSIONS_DIALOG( QueryHwnd(),
&_nlsStoredPassword,
&_uiStoredPermissions,
QueryHelpContextBase() );
if ( ( pdlg == NULL )
|| (( pdlg->QueryError()) != NERR_Success )
|| (( pdlg->Process()) != NERR_Success )
)
{
err = err? err: ERROR_NOT_ENOUGH_MEMORY;
}
delete pdlg;
}
else // On LM user-level server
{
err = IERR_CANNOT_SET_PERM_ON_LMUSER_SERVER;
}
}
if ( err != NERR_Success )
{
if ( (err == IERR_CANNOT_SET_PERM_ON_LMUSER_SERVER )
|| (err == IERR_SPECIAL_SHARE_CANNOT_SET_PERMISSIONS )
)
{
::MsgPopup( this, err, MPSEV_WARNING );
}
else
{
::MsgPopup( this, err );
}
}
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::SetMaxUserLimit
SYNOPSIS: Set the maximum number of users in the spin button
ENTRY: ulMaxUserLimit - the maximum user limit to be set
in the spin button
EXIT:
RETURNS:
NOTES: We need this because the maximum number of users on
LM servers and on NT servers are different.
HISTORY:
Yi-HsinS 1/17/92 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::SetMaxUserLimit( ULONG ulMaxUserLimit )
{
APIERR err = NERR_Success;
if (ulMaxUserLimit < _spsleUsers.QueryValue())
{
// the maximum is less than the default, so adjust the default
err = _spsleUsers.SetSaveValue(ulMaxUserLimit);
}
_spsleUsers.SetRange( ulMaxUserLimit - USERS_MIN + 1);
return err;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::QueryUserLimit
SYNOPSIS: Get the user limit from the magic group
ENTRY:
EXIT:
RETURNS: The user limit stored in the user limit magic group
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
ULONG SHARE_DIALOG_BASE::QueryUserLimit( VOID ) const
{
ULONG ulUserLimit;
switch ( _mgrpUserLimit.QuerySelection() )
{
case RB_UNLIMITED:
ulUserLimit = (ULONG) SHI_USES_UNLIMITED;
break;
case RB_USERS:
// We don't need to check whether the value is valid or not
// because SPIN_BUTTON checks it.
ulUserLimit = _spsleUsers.QueryValue();
UIASSERT( ( ulUserLimit <= _spsleUsers.QueryMax() )
&& ( ulUserLimit >= USERS_MIN )
);
break;
default:
UIASSERT(!SZ("User Limit: This shouldn't have happened!\n\r"));
ulUserLimit = (ULONG) SHI_USES_UNLIMITED;
break;
}
return ulUserLimit;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::SetUserLimit
SYNOPSIS: Sets the user limit on the magic group
ENTRY: ulUserLimit - maximum number of users allowed
EXIT:
RETURNS: NERR_Success
NOTES: If the limit is invalid, sets it to "Maximum allowed".
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::SetUserLimit( ULONG ulUserLimit )
{
APIERR err = NERR_Success;
if ( ulUserLimit == (ULONG) SHI_USES_UNLIMITED )
{
// Set selection to the Unlimited button
_mgrpUserLimit.SetSelection( RB_UNLIMITED );
ULONG ulMaxUserLimit = _spsleUsers.QueryMax();
ULONG ulNewUserLimit = (ulMaxUserLimit < USERS_DEFAULT) ? ulMaxUserLimit : USERS_DEFAULT;
_spsleUsers.SetSaveValue( ulNewUserLimit );
}
else if ( ( ulUserLimit >= USERS_MIN)
&& ( ulUserLimit <= _spsleUsers.QueryMax())
)
{
// Set the Users button
_mgrpUserLimit.SetSelection( RB_USERS );
_spsleUsers.SetValue( ulUserLimit );
_spsleUsers.Update();
}
else
{
// The user limit wasn't in range. Go back and set the share to
// "maximum allowed".
return SetUserLimit((ULONG)SHI_USES_UNLIMITED);
}
return err;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::ApplySharePermissions
SYNOPSIS: Sets the NT permissions of a share (security descriptor)
ENTRY: pszServer - the server that the share is on
pszShare - the share that we want to set permissions on
posSecDesc - the security descriptor to be set to the share
EXIT:
RETURNS:
NOTES:
HISTORY:
ChuckC 8/10/92 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::ApplySharePermissions( const TCHAR *pszServer,
const TCHAR *pszShare,
const OS_SECURITY_DESCRIPTOR *
posSecDesc)
{
UIASSERT(pszShare) ;
// if nothing changed, no need to set.
if (!_fSecDescModified)
return NERR_Success ;
return ( ::SetSharePerm(pszServer,
pszShare,
posSecDesc) ) ;
}
/*******************************************************************
NAME: SHARE_DIALOG_BASE::QuerySharePermissions
SYNOPSIS: Gets the NT permissions of a share (security descriptor)
ENTRY: pszServer - the server that the share is on
pszShare - the share that we want to set permissions on
EXIT: posSecDesc - pointer to the security descriptor
of the share
RETURNS:
NOTES:
HISTORY:
ChuckC 8/10/92 Created
********************************************************************/
APIERR SHARE_DIALOG_BASE::QuerySharePermissions( const TCHAR *pszServer,
const TCHAR *pszShare,
OS_SECURITY_DESCRIPTOR **pposSecDesc)
{
UIASSERT(pszShare) ;
UIASSERT(pposSecDesc) ;
return ( ::GetSharePerm(pszServer,
pszShare,
pposSecDesc) ) ;
}
/*******************************************************************
NAME: SHARE_LEVEL_PERMISSIONS_DIALOG
SYNOPSIS: The permission dialog for LM share-level servers
ENTRY: hwndParent - parent window
pnlsPassword - the initial password to be displayed and
place to return the password typed by the
user
puiPermissions - the initial permission to be displayed and
place to return the permission entered by
the user
ulHelpContextBase - the base help context
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
SHARE_LEVEL_PERMISSIONS_DIALOG::SHARE_LEVEL_PERMISSIONS_DIALOG( HWND hwndParent,
NLS_STR *pnlsPassword,
UINT *puiPermissions,
ULONG ulHelpContextBase )
: DIALOG_WINDOW ( IDD_SHAREPERMDLG, hwndParent ),
_pnlsPassword ( pnlsPassword ),
_puiPermissions( puiPermissions ),
_permgrp ( this, RB_READONLY, SLE_OTHER ),
_slePassword ( this, SLE_PASSWORD, SHPWLEN ),
_ulHelpContextBase( ulHelpContextBase )
{
UIASSERT( pnlsPassword != NULL );
UIASSERT( puiPermissions != NULL );
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ((err = _permgrp.QueryError()) != NERR_Success )
|| ((err = _permgrp.SetPermission( *_puiPermissions )) != NERR_Success)
)
{
ReportError( err );
return;
}
_slePassword.SetText( *_pnlsPassword );
_permgrp.ClaimFocus();
}
/*******************************************************************
NAME: SHARE_LEVEL_PERMISSION_DIALOG::OnOK
SYNOPSIS: Validate and return the password/permission that
the user entered.
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/25/91 Created
********************************************************************/
BOOL SHARE_LEVEL_PERMISSIONS_DIALOG::OnOK( VOID )
{
APIERR err = NERR_Success;
UINT uiPerm;
if ( ( err = _permgrp.QueryPermission( &uiPerm ) ) != NERR_Success)
{
err = IERR_SHARE_INVALID_PERMISSIONS;
_permgrp.SetFocusOnOther();
}
else
{
*_puiPermissions = uiPerm;
err = _slePassword.QueryText( _pnlsPassword );
}
if ( err == NERR_Success )
{
Dismiss( TRUE );
}
else
{
::MsgPopup( this, err );
}
return TRUE;
}
/*******************************************************************
NAME: SHARE_LEVEL_PERMISSIONS_DIALOG::QueryHelpContext
SYNOPSIS: Query the help context of the dialog
ENTRY:
EXIT:
RETURNS: Return the help context of the dialog
NOTES:
HISTORY:
Yi-HsinS 8/25/91 Created
********************************************************************/
ULONG SHARE_LEVEL_PERMISSIONS_DIALOG::QueryHelpContext( VOID )
{
return _ulHelpContextBase + HC_LMSHARELEVELPERMS;
}
/*******************************************************************
NAME: PERMISSION_GROUP::PERMISSION_GROUP
SYNOPSIS: Constructor for PERMISSION_GROUP
ENTRY: powin - pointer to the parent window
cidBase - CID of first button of the permission group
cidOtherEditField - CID of the Other Edit field
cidInitialSelection - CID of the initial selection
pGroupOwner - pointer to owner group
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
//
// Table for converting permissions from string to UINT and vice versa.
//
static struct {
WCHAR chPerm;
UINT uiPerm;
} permTable[] = {
{ READ_CHAR, ACCESS_READ},
{ WRITE_CHAR, ACCESS_WRITE},
{ CREATE_CHAR, ACCESS_CREATE},
{ EXEC_CHAR, ACCESS_EXEC},
{ DEL_CHAR, ACCESS_DELETE},
{ ACCESS_CHAR, ACCESS_ATRIB},
{ PERM_CHAR, ACCESS_PERM}
};
PERMISSION_GROUP::PERMISSION_GROUP( OWNER_WINDOW *powin,
CID cidBase,
CID cidOtherEditField,
CID cidInitialSelection,
CONTROL_GROUP *pGroupOwner)
: _mgrpPermission( powin, cidBase, 3, cidInitialSelection, pGroupOwner),
// 3 is the number of buttons in the magic group
_sleOther(powin, cidOtherEditField, PERM_DEFAULT_LEN )
{
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ((err = _mgrpPermission.QueryError()) != NERR_Success )
|| ((err = _mgrpPermission.AddAssociation( RB_OTHER, &_sleOther ))
!= NERR_Success )
)
{
ReportError( err );
return;
}
}
/*******************************************************************
NAME: PERMISSION_GROUP::GetAndCheckOtherField
SYNOPSIS: Validate the contents in "Other" Edit field
ENTRY:
EXIT: puiPermission - the permission
RETURNS: returns ERROR_INVALID_PARAMETER if the string in
other edit field is not valid
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR PERMISSION_GROUP::GetAndCheckOtherField( UINT *puiPermission ) const
{
APIERR err = NERR_Success;
NLS_STR nlsOther( PERM_DEFAULT_LEN );
if ( (( err = nlsOther.QueryError()) != NERR_Success )
|| (( err = _sleOther.QueryText( &nlsOther )) != NERR_Success )
)
{
return err;
}
nlsOther._strupr();
*puiPermission = 0;
ISTR istrOther( nlsOther );
BOOL fFound = FALSE; // A flag indicating whether a valid char is found
// in the permission string.
while ( nlsOther.QueryChar( istrOther) != STRING_TERMINATOR )
{
for ( UINT i = 0; i < PERM_DEFAULT_LEN; i++ )
{
if ( nlsOther.QueryChar( istrOther ) == permTable[i].chPerm )
{
fFound = TRUE;
if ( !(*puiPermission & permTable[i].uiPerm ))
{
*puiPermission |= permTable[i].uiPerm;
break; // break the for loop but continue the while loop
}
else
return ERROR_INVALID_PARAMETER;
}
else if ( nlsOther.QueryChar( istrOther) == SPACE )
fFound = TRUE;
}
//
// If the current character does not belong to "RWCXDAP" or is not
// a space, then error
//
if ( fFound )
fFound = FALSE;
else
return ERROR_INVALID_PARAMETER;
++istrOther;
}
//
// If the assigned permission is still zero, then the user
// did not type anything in _sleOther.
//
if ( *puiPermission == 0 )
return ERROR_INVALID_PARAMETER;
else
return NERR_Success;
}
/*******************************************************************
NAME: PERMISSION_GROUP::SetPermission
SYNOPSIS: Check the permission to see if it's READ_ONLY or MODIFY.
If yes, set the corresponding radio button. Else convert
the permission to a string of "RWCXDAP" and displayed
it on the Other Edit field
ENTRY: uiPermission - the permission
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR PERMISSION_GROUP::SetPermission( UINT uiPermission )
{
if ( (uiPermission & ACCESS_ALL ) == (ACCESS_READ | ACCESS_EXEC) )
{
_sleOther.SetText( EMPTY_STRING );
_mgrpPermission.SetSelection( RB_READONLY );
}
else if ( (uiPermission & ACCESS_ALL ) == (ACCESS_ALL & ~ACCESS_PERM))
{
_sleOther.SetText( EMPTY_STRING );
_mgrpPermission.SetSelection( RB_MODIFY );
}
else
{
NLS_STR nlsPermission( PERM_DEFAULT_LEN );
APIERR err = NERR_Success;
if ( ( err = nlsPermission.QueryError()) != NERR_Success )
return err;
for ( UINT i = 0; i < PERM_DEFAULT_LEN; i++ )
{
if ( uiPermission & permTable[i].uiPerm )
{
if ( (err = nlsPermission.AppendChar( permTable[i].chPerm ))
!= NERR_Success )
return err;
}
}
_mgrpPermission.SetSelection( RB_OTHER );
_sleOther.SetText( nlsPermission );
}
return NERR_Success;
}
/*******************************************************************
NAME: PERMISSION_GROUP::QueryPermission
SYNOPSIS: Get the permission from the permission group
ENTRY:
EXIT: puiPermission - will contain the permission
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR PERMISSION_GROUP::QueryPermission( UINT *puiPermission ) const
{
APIERR err = NERR_Success;
switch ( _mgrpPermission.QuerySelection() )
{
case RB_READONLY:
*puiPermission = ACCESS_READ | ACCESS_EXEC;
break;
case RB_MODIFY:
*puiPermission = ACCESS_ALL & ~ACCESS_PERM;
break;
case RB_OTHER:
err = GetAndCheckOtherField( puiPermission );
break;
}
return err;
}
/*******************************************************************
NAME: SHARE_NAME_WITH_PATH_ENUM_ITER::SHARE_NAME_WITH_PATH_ENUM_ITER
SYNOPSIS: Constructor
ENTRY: sh2Enum - The thing to iterate on
nlsActPath - The path we are interested in finding
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
SHARE_NAME_WITH_PATH_ENUM_ITER::SHARE_NAME_WITH_PATH_ENUM_ITER(
SHARE2_ENUM &sh2Enum,
const NLS_STR &nlsActPath)
: _sh2EnumIter( sh2Enum ),
_nlsActPath( nlsActPath )
{
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ( err = _nlsActPath.QueryError() ) != NERR_Success )
{
ReportError( err );
return;
}
}
/*******************************************************************
NAME: SHARE_NAME_WITH_PATH_ENUM_ITER::operator()
SYNOPSIS: iterator
ENTRY:
EXIT:
RETURNS: returns the share name if its path matches the _nlsActPath
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
const TCHAR *SHARE_NAME_WITH_PATH_ENUM_ITER::operator()( VOID )
{
const SHARE2_ENUM_OBJ *pshi2;
while ( (pshi2 = _sh2EnumIter()) != NULL )
{
if ( ::stricmpf( pshi2->QueryPath(), _nlsActPath) == 0)
return( pshi2->QueryName());
}
return NULL;
}
/*******************************************************************
NAME: SERVER_WITH_PASSWORD_PROMPT::SERVER_WITH_PASSWORD_PROMPT
SYNOPSIS: Constructor
ENTRY:
EXIT: pszServer - Server name
hwndParent - Handle of the parent window
ulHelpContextBase - The base help context
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
SERVER_WITH_PASSWORD_PROMPT::SERVER_WITH_PASSWORD_PROMPT(const TCHAR *pszServer,
HWND hwndParent,
ULONG ulHelpContextBase )
: SERVER_2( pszServer ),
_hwndParent( hwndParent ),
_pprompt( NULL ),
_ulHelpContextBase( ulHelpContextBase )
{
if ( QueryError() != NERR_Success )
return;
}
/*******************************************************************
NAME: SERVER_WITH_PASSWORD_PROMPT::~SERVER_WITH_PASSWORD_PROMPT
SYNOPSIS: Destructor
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
SERVER_WITH_PASSWORD_PROMPT::~SERVER_WITH_PASSWORD_PROMPT()
{
delete _pprompt;
_pprompt = NULL;
}
/*******************************************************************
NAME: SERVER_WITH_PASSWORD_PROMPT::I_GetInfo
SYNOPSIS: Get the SERVER_2 Info and if the user does not have admin
privilege and the server is a LM share-level server,
it will pop up a dialog asking for password,
make a connection to the server's ADMIN$ with the
password and attempts to get SERVER_2 info again.
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
APIERR SERVER_WITH_PASSWORD_PROMPT::I_GetInfo( VOID )
{
APIERR errOriginal = SERVER_2::I_GetInfo();
if ( errOriginal == NERR_Success )
return errOriginal;
APIERR err;
switch ( errOriginal )
{
case ERROR_ACCESS_DENIED:
case ERROR_INVALID_PASSWORD:
{
//
// Check if the machine is user level or share level
// Return the original error if it's user level
//
LOCATION loc( QueryName() );
BOOL fNT;
if ( ((err = loc.QueryError()) == NERR_Success )
&& ((err = loc.CheckIfNT( &fNT )) == NERR_Success )
)
{
if ( fNT ) // Always user level
{
err = errOriginal;
break;
}
else
{
USER0_ENUM usr0( QueryName() );
if ((err = usr0.QueryError()) != NERR_Success )
break;
//
// ERROR_NOT_SUPPORTED is returned by share level servers
//
if ((err = usr0.GetInfo()) != ERROR_NOT_SUPPORTED )
{
// user level
err = errOriginal;
break;
}
}
}
else
{
break;
}
//
// Prompt password and connect to the ADMIN$ share of
// share-level servers.
//
NLS_STR nlsServer( QueryName() );
if ( ((err = nlsServer.QueryError()) != NERR_Success )
|| ((err = QueryDisplayName( &nlsServer )) != NERR_Success)
)
{
break;
}
NLS_STR nlsAdmin( nlsServer );
ALIAS_STR nlsAdminShare( ADMIN_SHARE );
if ( ((err = nlsAdmin.QueryError()) == NERR_Success )
&& ((err = nlsAdmin.AppendChar( PATH_SEPARATOR)) == NERR_Success)
&& ((err = nlsAdmin.Append( nlsAdminShare )) == NERR_Success )
)
{
_pprompt = new PROMPT_AND_CONNECT( _hwndParent,
nlsAdmin,
_ulHelpContextBase
+ HC_SHAREPASSWORDPROMPT,
SHPWLEN);
if ( ( _pprompt != NULL )
&& ( (err = _pprompt->QueryError()) == NERR_Success )
&& ( (err = _pprompt->Connect()) == NERR_Success )
)
{
if ( _pprompt->IsConnected() )
{
err = SERVER_2::I_GetInfo();
}
else // user clicks CANCEL in the password dialog
{
err = IERR_USER_CLICKED_CANCEL;
}
}
}
break;
}
case NERR_BadTransactConfig:
err = (APIERR) IERR_SHARE_REMOTE_ADMIN_NOT_SUPPORTED;
break;
default:
err = errOriginal;
break;
}
return err;
}
/*******************************************************************
NAME: SERVER_WITH_PASSWORD_PROMPT::QueryName
SYNOPSIS: Query the name of the server
ENTRY:
EXIT:
RETURNS:
NOTES: Redefine SERVER_2::QueryName because we want to return
EMPTY_STRING instead of NULL when the server is local.
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
const TCHAR *SERVER_WITH_PASSWORD_PROMPT::QueryName( VOID ) const
{
if ( SERVER_2::QueryName() == NULL )
return EMPTY_STRING;
else
return SERVER_2::QueryName();
}
/*******************************************************************
NAME: SERVER_WITH_PASSWORD_PROMPT::IsNT
SYNOPSIS: Check if the server is an NT server or not.
ENTRY:
EXIT:
RETURNS: TRUE if the server is a NT server, FALSE otherwise.
NOTES:
HISTORY:
Yi-HsinS 8/6/92 Created
********************************************************************/
#define NT_NOS_MAJOR_VER 3
BOOL SERVER_WITH_PASSWORD_PROMPT::IsNT( VOID ) const
{
return ( QueryMajorVer() >= NT_NOS_MAJOR_VER );
}
/*******************************************************************
NAME: SHARE_NET_NAME::SHARE_NET_NAME
SYNOPSIS: Constructor
ENTRY:
EXIT:
RETURNS:
NOTES: Report why the local server cannot share directories,
whether it's because NT server service is not started
or if the local computer is a WIN16 computer
HISTORY:
Yi-HsinS 8/15/91 Created
********************************************************************/
SHARE_NET_NAME::SHARE_NET_NAME( const TCHAR *pszSharePath,
NETNAME_TYPE netNameType )
: NET_NAME( pszSharePath, netNameType )
{
if ( QueryError() != NERR_Success )
return;
APIERR err;
BOOL fLocal = IsLocal( &err );
if ( err != NERR_Success )
{
ReportError( err );
return;
}
if ( !fLocal )
return;
//
// Check whether the local computer can share directories
//
if ( IsSharable( &err ) && ( err == NERR_Success ))
{
return;
}
else if ( err == NERR_Success ) // Not sharable!
{
//
// Determine the reason why the local computer cannot share directories
//
LOCATION loc; // Local Computer
BOOL fNT;
if ( ((err = loc.QueryError()) == NERR_Success )
&& ((err = loc.CheckIfNT( &fNT )) == NERR_Success )
)
{
// NOTE: What should we do here if we admin NT from
// WinBall machine?
if ( !fNT )
err = NERR_RemoteOnly;
else
err = NERR_ServerNotStarted;
}
}
if ( err != NERR_Success )
{
ReportError( err );
return;
}
}