|
|
/**********************************************************************/ /** 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;
SecureZeroMemory((LPVOID) _nlsStoredPassword.QueryPch(), _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; } }
|