windows-nt/Source/XPSP1/NT/net/sfm/afp/ui/afpmgr/newvol.cxx
2020-09-26 16:20:57 +08:00

1831 lines
38 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
newvol.cxx
This file contains the definition of NEW_VOLUME_DIALOG.
History:
NarenG 11/18/92 Modified SHARE_DIALOG_BASE for
AFPMGR
*/
extern "C"
{
#include <nt.h>
#include <ntrtl.h>
#include <ntseapi.h>
#include <nturtl.h>
}
#define INCL_WINDOWS_GDI
#define INCL_WINDOWS
#define INCL_DOSERRORS
#define INCL_NET
#define INCL_NETERRORS
#define INCL_NETSHARE
#define INCL_NETSERVER
#define INCL_NETCONS
#define INCL_NETLIB
#define INCL_NETUSE
#define INCL_NETSHARE
#include <lmui.hxx>
#define INCL_BLT_WINDOW
#define INCL_BLT_DIALOG
#define INCL_BLT_CONTROL
#define INCL_BLT_MISC
#define INCL_BLT_CLIENT
#define INCL_BLT_MSGPOPUP
#define INCL_BLT_SPIN_GROUP
#define INCL_BLT_GROUP
#include <blt.hxx>
#include <lmodev.hxx>
#include <lmoshare.hxx>
#include <string.hxx>
#include <uitrace.hxx>
#include <dbgstr.hxx>
#include <netname.hxx>
extern "C"
{
#include <mnet.h>
#include <afpmgr.h>
#include <macfile.h>
extern APIERR ConvertRedirectedDriveToLocal( NLS_STR nlsServer,
NLS_STR * pnlsDrive,
NLS_STR * pnlsPath );
extern BOOL IsDriveGreaterThan2Gig( LPWSTR lpwsVolPath,
APIERR * perr );
}
#include "util.hxx"
#include "perms.hxx"
#include "newvol.hxx"
/*******************************************************************
NAME: NEW_VOLUME_SRVMGR_DIALOG::NEW_VOLUME_SRVMGR_DIALOG
SYNOPSIS: Constructor for NEW_VOLUME_SRVMGR_DIALOG class
ENTRY: hwndParent - handle of parent window
EXIT:
RETURNS:
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
NEW_VOLUME_SRVMGR_DIALOG::NEW_VOLUME_SRVMGR_DIALOG(
HWND hwndParent,
AFP_SERVER_HANDLE hServer,
const TCHAR * pszServerName )
: DIALOG_WINDOW ( MAKEINTRESOURCE(IDD_NEW_VOLUME_DIALOG), hwndParent ),
_sleVolumeName( this, IDNV_SLE_NAME, AFP_VOLNAME_LEN ),
_sleVolumePath( this, IDNV_SLE_PATH ),
_slePassword( this, IDNV_SLE_PASSWORD, AFP_VOLPASS_LEN ),
_slePasswordConfirm( this, IDNV_SLE_CONFIRM_PASSWORD, AFP_VOLPASS_LEN ),
_chkReadOnly( this, IDNV_CHK_READONLY ),
_chkGuestAccess( this, IDNV_CHK_GUEST_ACCESS ),
_mgrpUserLimit( this, IDNV_RB_UNLIMITED, 2, IDNV_RB_UNLIMITED),
_spsleUsers( this, IDNV_SLE_USERS,1,1,AFP_VOLUME_UNLIMITED_USES-1,
TRUE,IDNV_SLE_USERS_GROUP),
_spgrpUsers(this,IDNV_SB_USERS_GROUP,IDNV_SB_USERS_UP,IDNV_SB_USERS_DOWN),
_pbPermissions( this, IDNV_PB_PERMISSIONS ),
_pbOK( this, IDOK ),
_pbCancel( this, IDCANCEL ),
_nlsOwner(),
_nlsGroup(),
_hServer( hServer ),
_nlsServerName( pszServerName ),
_fCommitDirInfo( FALSE )
{
AUTO_CURSOR Cursor;
//
// Make sure everything constructed OK
//
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
|| ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
|| ((err = _mgrpUserLimit.AddAssociation( IDNV_RB_USERS, &_spgrpUsers ))
!= NERR_Success )
|| ((err = _chkReadOnly.QueryError()) != NERR_Success )
|| ((err = _chkGuestAccess.QueryError()) != NERR_Success )
|| ((err = _nlsServerName.QueryError()) != NERR_Success )
|| ((err = _nlsOwner.QueryError()) != NERR_Success )
|| ((err = _nlsGroup.QueryError()) != NERR_Success )
)
{
ReportError( err );
return;
}
//
// Set the caption
//
err = ::SetCaption( this, IDS_CAPTION_CREATE_VOLUME, pszServerName );
if ( err != NO_ERROR )
{
ReportError( err );
return;
}
//
// Set the defaults
//
_chkReadOnly.SetCheck( FALSE );
_chkGuestAccess.SetCheck( TRUE );
_mgrpUserLimit.SetSelection( IDNV_RB_UNLIMITED );
_pbPermissions.Enable( FALSE );
}
/*******************************************************************
NAME: NEW_VOLUME_SRVMGR_DIALOG::OnCommand
SYNOPSIS: Handle the case where the user clicked the permission button
ENTRY: event - the CONTROL_EVENT that occurred
EXIT:
RETURNS:
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
BOOL NEW_VOLUME_SRVMGR_DIALOG::OnCommand( const CONTROL_EVENT &event )
{
APIERR err;
if ( event.QueryCid() == IDNV_PB_PERMISSIONS )
{
AUTO_CURSOR Cursor;
//
// Get the volume path and validate it.
//
NLS_STR nlsDisplayPath;
NLS_STR nlsVolumePath;
BOOL fOk;
if ((( err = nlsVolumePath.QueryError() ) != NERR_Success ) ||
(( err = nlsDisplayPath.QueryError() ) != NERR_Success ) ||
(( err = _sleVolumePath.QueryText(&nlsDisplayPath))
!= NERR_Success ))
{
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
return FALSE;
}
//
// Validate the path.
//
NET_NAME netname( nlsDisplayPath.QueryPch() );
if ( ( err = netname.QueryError() ) != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
if ( netname.QueryType() == TYPE_PATH_UNC )
{
::MsgPopup( this, IDS_TYPE_LOCAL_PATH );
SetFocusOnPath();
return TRUE;
}
nlsVolumePath.CopyFrom( nlsDisplayPath );
_fCommitDirInfo = TRUE;
DIRECTORY_PERMISSIONS_DLG *pdlg = new DIRECTORY_PERMISSIONS_DLG(
QueryHwnd(),
_hServer,
_nlsServerName.QueryPch(),
TRUE,
nlsVolumePath.QueryPch(),
nlsDisplayPath.QueryPch(),
FALSE,
&_nlsOwner,
&_nlsGroup,
&_dwPerms );
if ( ( pdlg == NULL )
|| (( err = pdlg->QueryError()) != NERR_Success )
|| (( err = pdlg->Process( &fOk )) != NERR_Success )
)
{
err = (pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY : err;
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
}
delete pdlg;
if ( ( err != NERR_Success ) || ( !fOk ) )
{
_fCommitDirInfo = FALSE;
}
return TRUE;
}
//
// Enable the permissions button if the path string is filled in.
//
if ( event.QueryCid() == IDNV_SLE_PATH )
{
if ( event.QueryCode() == EN_CHANGE )
{
if ( _sleVolumePath.QueryTextLength() > 0 )
{
_pbOK.MakeDefault();
_pbPermissions.Enable( TRUE );
}
else
{
_pbPermissions.Enable( FALSE );
_pbCancel.MakeDefault();
}
}
return TRUE;
}
return DIALOG_WINDOW::OnCommand( event );
}
/*******************************************************************
NAME: NEW_VOLUME_SRVMGR_DIALOG::OnOK
SYNOPSIS: Validate all the information and create the volume.
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
BOOL NEW_VOLUME_SRVMGR_DIALOG::OnOK( VOID )
{
APIERR err;
NLS_STR nlsVolumePath;
NLS_STR nlsVolumeName;
NLS_STR nlsPassword;
NLS_STR nlsPasswordConfirm;
WCHAR szVolPath[CNLEN+6];
WCHAR *wchTemp;
AUTO_CURSOR Cursor;
//
// This is not a loop.
//
do {
//
// Get the volume name.
//
if ( ( err = nlsVolumeName.QueryError() ) != NERR_Success )
break;
if ((err = _sleVolumeName.QueryText( &nlsVolumeName )) != NERR_Success)
break;
//
// Get the volume path.
//
if ( ( err = nlsVolumePath.QueryError() ) != NERR_Success )
break;
if (( err = _sleVolumePath.QueryText(&nlsVolumePath)) != NERR_Success)
break;
//
// Get the password if there is one.
//
if ( ( err = nlsPassword.QueryError() ) != NERR_Success )
break;
if ( ( err = _slePassword.QueryText( &nlsPassword )) != NERR_Success )
break;
//
// Get the password confirmation.
//
if ( ( err = nlsPasswordConfirm.QueryError() ) != NERR_Success )
break;
if ( ( err = _slePasswordConfirm.QueryText( &nlsPasswordConfirm ))
!= NERR_Success )
break;
}while( FALSE );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
return TRUE;
}
//
// Set up the volume structure
//
AFP_VOLUME_INFO AfpVolume;
if ( nlsVolumeName.strlen() > 0 )
{
//
// Validate the volume name
//
ISTR istr( nlsVolumeName );
if ( nlsVolumeName.strchr( &istr, TEXT(':') ) )
{
::MsgPopup( this, IDS_AFPERR_InvalidVolumeName );
SetFocusOnName();
return FALSE;
}
AfpVolume.afpvol_name = (LPWSTR)(nlsVolumeName.QueryPch());
}
else
{
::MsgPopup( this, IDS_NEED_VOLUME_NAME );
SetFocusOnName();
return TRUE;
}
//
// Validate the path.
//
NET_NAME netname( nlsVolumePath.QueryPch() );
if ( ( err = netname.QueryError() ) != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
if ( netname.QueryType() == TYPE_PATH_UNC )
{
::MsgPopup( this, IDS_TYPE_LOCAL_PATH );
SetFocusOnPath();
return TRUE;
}
::wcscpy(szVolPath, _nlsServerName.QueryPch());
wchTemp = szVolPath + wcslen(szVolPath);
*wchTemp++ = TEXT('\\');
*wchTemp++ = (nlsVolumePath.QueryPch())[0];
*wchTemp++ = TEXT('$');
*wchTemp++ = TEXT('\\');
*wchTemp++ = 0;
BOOL fDriveGreaterThan2Gig = ::IsDriveGreaterThan2Gig( (LPWSTR)(szVolPath), &err );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
if ( fDriveGreaterThan2Gig )
{
if ( ::MsgPopup( this,
IDS_VOLUME_TOO_BIG,
MPSEV_WARNING,
MP_YESNO,
MP_NO ) == IDNO )
{
SetFocusOnPath();
return TRUE;
}
}
AfpVolume.afpvol_path = (LPWSTR)(nlsVolumePath.QueryPch());
//
// Make sure the passwords match.
//
if ( nlsPassword.strcmp( nlsPasswordConfirm ) )
{
::MsgPopup( this, IDS_PASSWORD_MISMATCH );
SetFocusOnPasswordConfirm();
return TRUE;
}
if ( nlsPassword.strlen() > 0 )
{
AfpVolume.afpvol_password = (LPWSTR)(nlsPassword.QueryPch());
}
else
{
AfpVolume.afpvol_password = (LPWSTR)NULL;
}
AfpVolume.afpvol_props_mask = _chkReadOnly.QueryCheck()
? AFP_VOLUME_READONLY
: 0;
AfpVolume.afpvol_props_mask = _chkGuestAccess.QueryCheck()
? (AFP_VOLUME_GUESTACCESS | AfpVolume.afpvol_props_mask)
: AfpVolume.afpvol_props_mask;
AfpVolume.afpvol_max_uses = QueryUserLimit();
//
// Try to create the volume.
//
err = ::AfpAdminVolumeAdd( _hServer, (LPBYTE)&AfpVolume );
if ( err != NO_ERROR )
{
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
SetFocusOnPath();
return FALSE;
}
//
// If the user mucked around with the root directory's permissions
// the we have to set it.
//
if ( _fCommitDirInfo )
{
AFP_DIRECTORY_INFO AfpDirInfo;
AfpDirInfo.afpdir_path = (LPWSTR)nlsVolumePath.QueryPch();
AfpDirInfo.afpdir_owner = (LPWSTR)_nlsOwner.QueryPch();
AfpDirInfo.afpdir_group = (LPWSTR)_nlsGroup.QueryPch();
AfpDirInfo.afpdir_perms = _dwPerms;
err = ::AfpAdminDirectorySetInfo( _hServer,
(LPBYTE)&AfpDirInfo,
AFP_DIR_PARMNUM_ALL );
}
else
{
//
// User did not muck arount with the permissions, so we have
// to get and reset the current permissions. This is requred
// to remove everyone as the owner.
//
PAFP_DIRECTORY_INFO pAfpDirInfo;
err = ::AfpAdminDirectoryGetInfo( _hServer,
(LPWSTR)nlsVolumePath.QueryPch(),
(LPBYTE*)&pAfpDirInfo );
if ( err == NO_ERROR )
{
DWORD dwParmNum = AFP_DIR_PARMNUM_PERMS;
pAfpDirInfo->afpdir_path = (LPWSTR)(nlsVolumePath.QueryPch());
if ( pAfpDirInfo->afpdir_owner != (LPWSTR)NULL )
{
dwParmNum |= AFP_DIR_PARMNUM_OWNER;
}
if ( pAfpDirInfo->afpdir_group != (LPWSTR)NULL )
{
dwParmNum |= AFP_DIR_PARMNUM_GROUP;
}
err = ::AfpAdminDirectorySetInfo( _hServer,
(LPBYTE)pAfpDirInfo,
dwParmNum );
::AfpAdminBufferFree( pAfpDirInfo );
}
}
switch( err )
{
case NO_ERROR:
case AFPERR_SecurityNotSupported:
Dismiss( TRUE );
break;
case AFPERR_NoSuchUser:
case AFPERR_NoSuchGroup:
case AFPERR_NoSuchUserGroup:
case ERROR_NONE_MAPPED:
::MsgPopup( this, IDS_INVALID_DIR_ACCOUNT, MPSEV_INFO );
Dismiss( TRUE );
break;
case AFPERR_UnsupportedFS:
//
// Ignore this error
//
Dismiss( TRUE );
break;
default:
::AfpAdminVolumeDelete( _hServer, (LPWSTR)(nlsVolumeName.QueryPch()));
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
break;
}
return TRUE;
}
/*******************************************************************
NAME: NEW_VOLUME_SRVMGR_DIALOG::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:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
DWORD NEW_VOLUME_SRVMGR_DIALOG::QueryUserLimit( VOID ) const
{
switch ( _mgrpUserLimit.QuerySelection() )
{
case IDNV_RB_UNLIMITED:
return( AFP_VOLUME_UNLIMITED_USES );
case IDNV_RB_USERS:
return( _spsleUsers.QueryValue() );
default:
//
// Should never get here but in case we do, return unlimited
//
return( AFP_VOLUME_UNLIMITED_USES );
}
}
/*******************************************************************
NAME: NEW_VOLUME_SRVMGR_DIALOG::QueryHelpContext
SYNOPSIS: Query the help context of the dialog
ENTRY:
EXIT:
RETURNS: Return the help context of the dialog
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
ULONG NEW_VOLUME_SRVMGR_DIALOG::QueryHelpContext( VOID )
{
return HC_NEW_VOLUME_SRVMGR_DIALOG;
}
/*******************************************************************
NAME: NEW_VOLUME_FILEMGR_DIALOG::NEW_VOLUME_FILEMGR_DIALOG
SYNOPSIS: Constructor for NEW_VOLUME_FILEMGR_DIALOG class
ENTRY: hwndParent - handle of parent window
EXIT:
RETURNS:
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
NEW_VOLUME_FILEMGR_DIALOG::NEW_VOLUME_FILEMGR_DIALOG(
HWND hwndParent,
const TCHAR * pszPath,
BOOL fIsFile )
: DIALOG_WINDOW ( MAKEINTRESOURCE(IDD_NEW_VOLUME_DIALOG), hwndParent ),
_sleVolumeName( this, IDNV_SLE_NAME, AFP_VOLNAME_LEN ),
_sleVolumePath( this, IDNV_SLE_PATH ),
_slePassword( this, IDNV_SLE_PASSWORD, AFP_VOLPASS_LEN ),
_slePasswordConfirm( this, IDNV_SLE_CONFIRM_PASSWORD, AFP_VOLPASS_LEN ),
_chkReadOnly( this, IDNV_CHK_READONLY ),
_chkGuestAccess( this, IDNV_CHK_GUEST_ACCESS ),
_mgrpUserLimit( this, IDNV_RB_UNLIMITED, 2, IDNV_RB_UNLIMITED),
_spsleUsers( this, IDNV_SLE_USERS,1,1,AFP_VOLUME_UNLIMITED_USES-1,
TRUE,IDNV_SLE_USERS_GROUP),
_spgrpUsers(this,IDNV_SB_USERS_GROUP,IDNV_SB_USERS_UP,IDNV_SB_USERS_DOWN),
_pbPermissions( this, IDNV_PB_PERMISSIONS ),
_pbOK( this, IDOK ),
_pbCancel( this, IDCANCEL ),
_nlsOwner(),
_nlsGroup(),
_fCommitDirInfo( FALSE )
{
AUTO_CURSOR Cursor;
//
// Make sure everything constructed OK
//
if ( QueryError() != NERR_Success )
return;
APIERR err;
if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
|| ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
|| ((err = _mgrpUserLimit.AddAssociation( IDNV_RB_USERS, &_spgrpUsers ))
!= NERR_Success )
|| ((err = _chkReadOnly.QueryError()) != NERR_Success )
|| ((err = _chkGuestAccess.QueryError()) != NERR_Success )
|| ((err = _nlsOwner.QueryError()) != NERR_Success )
|| ((err = _nlsGroup.QueryError()) != NERR_Success )
)
{
ReportError( err );
return;
}
//
// Set the defaults
//
_chkReadOnly.SetCheck( FALSE );
_chkGuestAccess.SetCheck( TRUE );
_mgrpUserLimit.SetSelection( IDNV_RB_UNLIMITED );
_pbPermissions.Enable( FALSE );
//
// Set the volumename and path if the path drive is NTFS
//
NLS_STR nlsVolumePath( pszPath );
NLS_STR nlsVolumeName;
NLS_STR nlsUNCPath;
if ( (( err = nlsVolumePath.QueryError() ) != NERR_Success ) ||
(( err = nlsVolumeName.QueryError() ) != NERR_Success ) ||
(( err = nlsUNCPath.QueryError() ) != NERR_Success ) )
{
ReportError( err );
return;
}
err = ValidateVolumePath( nlsVolumePath.QueryPch() );
if ( ( err != NO_ERROR ) && ( err != AFPERR_UnsupportedFS ) )
{
ReportError( err );
return;
}
//
// If the drive is an NTFS/CDFS drive, then set the volume name and path
//
if ( err == NO_ERROR )
{
//
// If this is a file then we need to remove the file name from the
// path.
//
if ( fIsFile )
{
ISTR istrVolumePath( nlsVolumePath );
if ( nlsVolumePath.strrchr( &istrVolumePath, TEXT('\\') ))
{
nlsVolumePath.DelSubStr( istrVolumePath );
}
}
//
// Extract the last component of the path and use it to set the
// volume name
//
nlsVolumeName = nlsVolumePath;
ISTR istrStart( nlsVolumeName );
ISTR istrEnd( nlsVolumeName );
if ( nlsVolumeName.strrchr( &istrEnd, TEXT('\\') ))
{
nlsVolumeName.DelSubStr( istrStart, ++istrEnd );
}
if ( nlsVolumeName.QueryTextLength() <= AFP_VOLNAME_LEN )
_sleVolumeName.SetText( nlsVolumeName );
//
// Ok, if the drive is remote then we need to display the UNC path
//
NET_NAME netname( nlsVolumePath );
if ( ( err = netname.QueryError() ) != NERR_Success )
{
ReportError( err );
return;
}
BOOL fIsLocal = netname.IsLocal( &err );
if ( err != NERR_Success )
{
ReportError( err );
return;
}
if ( fIsLocal )
{
_sleVolumePath.SetText( nlsVolumePath );
}
else
{
if ( ( err = netname.QueryUNCPath( &nlsUNCPath ) ) != NERR_Success )
{
ReportError( err );
return;
}
_sleVolumePath.SetText( nlsUNCPath );
}
_pbPermissions.Enable( TRUE );
_sleVolumeName.SelectString();
SetFocusOnName();
}
}
/*******************************************************************
NAME: NEW_VOLUME_FILEMGR_DIALOG::OnCommand
SYNOPSIS: Handle the case where the user clicked the permission button
ENTRY: event - the CONTROL_EVENT that occurred
EXIT:
RETURNS:
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
BOOL NEW_VOLUME_FILEMGR_DIALOG::OnCommand( const CONTROL_EVENT &event )
{
APIERR err;
AFP_SERVER_HANDLE hServer = NULL;
if ( event.QueryCid() == IDNV_PB_PERMISSIONS )
{
AUTO_CURSOR Cursor;
//
// Get the volume path and validate it.
//
NLS_STR nlsDisplayPath;
NLS_STR nlsVolumePath;
NLS_STR nlsComputerName;
NLS_STR nlsDrive;
BOOL fOk;
if ((( err = nlsVolumePath.QueryError() ) != NERR_Success ) ||
(( err = nlsComputerName.QueryError() ) != NERR_Success ) ||
(( err = nlsDrive.QueryError() ) != NERR_Success ) ||
(( err = nlsDisplayPath.QueryError() ) != NERR_Success ) ||
(( err = _sleVolumePath.QueryText(&nlsDisplayPath))
!= NERR_Success ))
{
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
return FALSE;
}
//
// If the path is not local then we need to get the local
// path.
//
NET_NAME netname( nlsDisplayPath.QueryPch() );
if ( ( err = netname.QueryError() ) != NERR_Success )
{
::MsgPopup( this, err );
return FALSE;
}
BOOL fIsLocal = netname.IsLocal( &err );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
return FALSE;
}
//
// Get the computer name for this volume
//
if ((err = netname.QueryComputerName(&nlsComputerName)) != NERR_Success)
{
if ( err == NERR_InvalidDevice )
{
err = ERROR_INVALID_DRIVE;
}
::MsgPopup( this, err );
return FALSE;
}
if ((!fIsLocal) || (fIsLocal && (netname.QueryType() == TYPE_PATH_UNC)))
{
//
// If the path is remote get the absolute path with
// the drive letter.
//
err = netname.QueryLocalPath( &nlsVolumePath );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
}
else
{
//
// If the path happens to be a loopback redirected drive then we
// replace
// the redirected drive with the action drive.
//
if ( (err = netname.QueryDrive( &nlsDrive )) != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
nlsVolumePath.CopyFrom( nlsDisplayPath );
if ( (err=::ConvertRedirectedDriveToLocal(
nlsComputerName,
&nlsDrive,
&nlsVolumePath ))!= NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
}
if ( ( err = ::AfpAdminConnect((LPWSTR)(nlsComputerName.QueryPch()),
&hServer ) ) != NO_ERROR )
{
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
_fCommitDirInfo = TRUE;
DIRECTORY_PERMISSIONS_DLG *pdlg = new DIRECTORY_PERMISSIONS_DLG(
QueryHwnd(),
hServer,
NULL,
FALSE,
nlsVolumePath.QueryPch(),
nlsDisplayPath.QueryPch(),
FALSE,
&_nlsOwner,
&_nlsGroup,
&_dwPerms );
if ( ( pdlg == NULL )
|| (( err = pdlg->QueryError()) != NERR_Success )
|| (( err = pdlg->Process( &fOk )) != NERR_Success )
)
{
err = (pdlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY : err;
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
}
delete pdlg;
if ( ( err != NERR_Success ) || ( !fOk ) )
{
_fCommitDirInfo = FALSE;
}
if ( hServer != NULL )
{
::AfpAdminDisconnect( hServer );
}
return TRUE;
}
//
// Enable the permissions button if the path string is filled in.
//
if ( event.QueryCid() == IDNV_SLE_PATH )
{
if ( event.QueryCode() == EN_CHANGE )
{
if ( _sleVolumePath.QueryTextLength() > 0 )
{
_pbOK.MakeDefault();
_pbPermissions.Enable( TRUE );
}
else
{
_pbPermissions.Enable( FALSE );
_pbCancel.MakeDefault();
}
}
return TRUE;
}
return DIALOG_WINDOW::OnCommand( event );
}
/*******************************************************************
NAME: NEW_VOLUME_FILEMGR_DIALOG::OnOK
SYNOPSIS: Validate all the information and create the volume.
ENTRY:
EXIT:
RETURNS:
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
BOOL NEW_VOLUME_FILEMGR_DIALOG::OnOK( VOID )
{
APIERR err;
NLS_STR nlsVolumePath;
NLS_STR nlsVolumeName;
NLS_STR nlsPassword;
NLS_STR nlsPasswordConfirm;
NLS_STR nlsComputerName;
NLS_STR nlsDrive;
AFP_SERVER_HANDLE hServer = NULL;
AUTO_CURSOR Cursor;
//
// This is not a loop.
//
do {
if ( ( err = nlsComputerName.QueryError() ) != NERR_Success )
break;
if ( ( err = nlsDrive.QueryError() ) != NERR_Success )
break;
//
// Get the volume name.
//
if ( ( err = nlsVolumeName.QueryError() ) != NERR_Success )
break;
if ((err = _sleVolumeName.QueryText( &nlsVolumeName )) != NERR_Success)
break;
//
// Get the volume path.
//
if ( ( err = nlsVolumePath.QueryError() ) != NERR_Success )
break;
if (( err = _sleVolumePath.QueryText(&nlsVolumePath)) != NERR_Success)
break;
//
// Get the password if there is one.
//
if ( ( err = nlsPassword.QueryError() ) != NERR_Success )
break;
if ( ( err = _slePassword.QueryText( &nlsPassword )) != NERR_Success )
break;
//
// Get the password confirmation.
//
if ( ( err = nlsPasswordConfirm.QueryError() ) != NERR_Success )
break;
if ( ( err = _slePasswordConfirm.QueryText( &nlsPasswordConfirm ))
!= NERR_Success )
break;
}while( FALSE );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
return TRUE;
}
//
// Set up the volume structure
//
AFP_VOLUME_INFO AfpVolume;
if ( nlsVolumeName.strlen() > 0 )
{
//
// Validate the volume name
//
ISTR istr( nlsVolumeName );
if ( nlsVolumeName.strchr( &istr, TEXT(':') ) )
{
::MsgPopup( this, IDS_AFPERR_InvalidVolumeName );
SetFocusOnName();
return FALSE;
}
AfpVolume.afpvol_name = (LPWSTR)(nlsVolumeName.QueryPch());
}
else
{
::MsgPopup( this, IDS_NEED_VOLUME_NAME );
SetFocusOnName();
return TRUE;
}
//
// If the path is not local then we need to get the local
// path.
//
NET_NAME netname( nlsVolumePath.QueryPch() );
if ( ( err = netname.QueryError() ) != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
BOOL fIsLocal = netname.IsLocal( &err );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
if ( (err = netname.QueryComputerName( &nlsComputerName )) != NERR_Success)
{
if ( err == NERR_InvalidDevice )
{
err = ERROR_INVALID_DRIVE;
}
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
BOOL fDriveGreaterThan2Gig = ::IsDriveGreaterThan2Gig( (LPWSTR)(nlsVolumePath.QueryPch()),
&err );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
if ( (!fIsLocal) || (fIsLocal && (netname.QueryType() == TYPE_PATH_UNC)))
{
//
// If the path is remote then get the absolute path and drive letter.
//
err = netname.QueryLocalPath( &nlsVolumePath );
if ( err != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
}
else
{
//
// If the path happens to be a loopback redirected drive then we
// replace
// the redirected drive with the action drive.
//
if ( (err = netname.QueryDrive( &nlsDrive )) != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return TRUE;
}
if ( (err=::ConvertRedirectedDriveToLocal(
nlsComputerName,
&nlsDrive,
&nlsVolumePath )) != NERR_Success )
{
::MsgPopup( this, err );
SetFocusOnPath();
return FALSE;
}
}
if ( fDriveGreaterThan2Gig )
{
if ( ::MsgPopup( this,
IDS_VOLUME_TOO_BIG,
MPSEV_WARNING,
MP_YESNO,
MP_NO ) == IDNO )
{
SetFocusOnPath();
return TRUE;
}
}
AfpVolume.afpvol_path = (LPWSTR)(nlsVolumePath.QueryPch());
if ( nlsPassword.strcmp( nlsPasswordConfirm ) )
{
::MsgPopup( this, IDS_PASSWORD_MISMATCH );
SetFocusOnPasswordConfirm();
return TRUE;
}
if ( nlsPassword.strlen() > 0 )
{
AfpVolume.afpvol_password = (LPWSTR)(nlsPassword.QueryPch());
}
else
{
AfpVolume.afpvol_password = (LPWSTR)NULL;
}
AfpVolume.afpvol_props_mask = _chkReadOnly.QueryCheck()
? AFP_VOLUME_READONLY
: 0;
AfpVolume.afpvol_props_mask = _chkGuestAccess.QueryCheck()
? (AFP_VOLUME_GUESTACCESS | AfpVolume.afpvol_props_mask)
: AfpVolume.afpvol_props_mask;
AfpVolume.afpvol_max_uses = QueryUserLimit();
//
// Try to create the volume.
//
err = ::AfpAdminConnect((LPWSTR)(nlsComputerName.QueryPch()), &hServer );
if ( err == NO_ERROR )
{
err = ::AfpAdminVolumeAdd( hServer, (LPBYTE)&AfpVolume );
}
if ( err == NO_ERROR )
{
//
// If the user mucked around with the root directory's permissions
// the we have to set it.
//
if ( _fCommitDirInfo )
{
AFP_DIRECTORY_INFO AfpDirInfo;
AfpDirInfo.afpdir_path = (LPWSTR)(nlsVolumePath.QueryPch());
AfpDirInfo.afpdir_owner = (LPWSTR)(_nlsOwner.QueryPch());
AfpDirInfo.afpdir_group = (LPWSTR)(_nlsGroup.QueryPch());
AfpDirInfo.afpdir_perms = _dwPerms;
err = ::AfpAdminDirectorySetInfo( hServer,
(LPBYTE)&AfpDirInfo,
AFP_DIR_PARMNUM_ALL );
}
else
{
//
// User did not muck arount with the permissions, so we have
// to get and reset the current permissions. This is requred
// to remove everyone as the owner.
//
PAFP_DIRECTORY_INFO pAfpDirInfo;
err = ::AfpAdminDirectoryGetInfo(hServer,
(LPWSTR)(nlsVolumePath.QueryPch()),
(LPBYTE*)&pAfpDirInfo );
if ( err == NO_ERROR )
{
DWORD dwParmNum = AFP_DIR_PARMNUM_PERMS;
pAfpDirInfo->afpdir_path = (LPWSTR)(nlsVolumePath.QueryPch());
if ( pAfpDirInfo->afpdir_owner != (LPWSTR)NULL )
{
dwParmNum |= AFP_DIR_PARMNUM_OWNER;
}
if ( pAfpDirInfo->afpdir_group != (LPWSTR)NULL )
{
dwParmNum |= AFP_DIR_PARMNUM_GROUP;
}
err = ::AfpAdminDirectorySetInfo( hServer,
(LPBYTE)pAfpDirInfo,
dwParmNum );
::AfpAdminBufferFree( pAfpDirInfo );
}
}
switch( err )
{
case NO_ERROR:
break;
case AFPERR_SecurityNotSupported:
err = NO_ERROR;
break;
case AFPERR_NoSuchUser:
case AFPERR_NoSuchGroup:
case AFPERR_NoSuchUserGroup:
case ERROR_NONE_MAPPED:
err = NO_ERROR;
::MsgPopup( this, IDS_INVALID_DIR_ACCOUNT, MPSEV_INFO );
break;
case AFPERR_UnsupportedFS:
//
// Ignore this error
//
err = NO_ERROR;
break;
default:
::AfpAdminVolumeDelete( hServer,
(LPWSTR)(nlsVolumeName.QueryPch()));
break;
}
}
if ( hServer != NULL )
{
::AfpAdminDisconnect( hServer );
}
if ( err == NO_ERROR )
{
Dismiss( TRUE );
}
else
{
::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
SetFocusOnPath();
}
return TRUE;
}
/*******************************************************************
NAME: NEW_VOLUME_FILEGMR_DIALOG::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:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
DWORD NEW_VOLUME_FILEMGR_DIALOG::QueryUserLimit( VOID ) const
{
switch ( _mgrpUserLimit.QuerySelection() )
{
case IDNV_RB_UNLIMITED:
return( AFP_VOLUME_UNLIMITED_USES );
case IDNV_RB_USERS:
return( _spsleUsers.QueryValue() );
default:
//
// Should never get here but in case we do, return unlimited
//
return( AFP_VOLUME_UNLIMITED_USES );
}
}
/*******************************************************************
NAME: NEW_VOLUME_FILEMGR_DIALOG::ValidateVolumePath
SYNOPSIS: Validates the volume path. It makes sure that the
the path syntax is valid and the volume of the drive
is either NTFS or CDFS.
ENTRY: pszPath - Pointer to the volume path
EXIT:
RETURNS: Any error encountered. (Path syntax is invalid etc)
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
DWORD NEW_VOLUME_FILEMGR_DIALOG::ValidateVolumePath( const WCHAR * pszPath )
{
WCHAR wchDrive[5];
DWORD dwMaxCompSize;
DWORD dwFlags;
WCHAR wchFileSystem[10];
DWORD err = NO_ERROR;
NET_NAME Path( pszPath );
if ( ( err = Path.QueryError() ) != NERR_Success )
{
return err;
}
// Get the drive letter, : and backslash
//
::ZeroMemory( wchDrive, sizeof( wchDrive ) );
::wcsncpy( wchDrive, pszPath, 3 );
if ( !( ::GetVolumeInformation( (LPWSTR)wchDrive,
NULL,
0,
NULL,
&dwMaxCompSize,
&dwFlags,
(LPWSTR)wchFileSystem,
sizeof( wchFileSystem ) ) ) ){
return GetLastError();
}
if ( ( ::_wcsicmp( wchFileSystem, SZ("NTFS") ) == 0 ) ||
( ::_wcsicmp( wchFileSystem, SZ("CDFS") ) == 0 ) ||
( ::_wcsicmp( wchFileSystem, SZ("AHFS") ) == 0 ) )
return( NO_ERROR );
else
return( (DWORD)AFPERR_UnsupportedFS );
}
/*******************************************************************
NAME: NEW_VOLUME_FILEMGR_DIALOG::QueryHelpContext
SYNOPSIS: Query the help context of the dialog
ENTRY:
EXIT:
RETURNS: Return the help context of the dialog
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
ULONG NEW_VOLUME_FILEMGR_DIALOG::QueryHelpContext( VOID )
{
return HC_NEW_VOLUME_FILEMGR_DIALOG;
}
/*******************************************************************
NAME: ::ConvertRedirectedDriveToLocal
SYNOPSIS: Determines if a drive is a loopback redirected drive or
not. If it is, then the redirected drive is changed to
the local drive.
ENTRY:
EXIT:
RETURNS: NERR_Success - Success
Non zero return codes - failure
NOTES:
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
APIERR ConvertRedirectedDriveToLocal( NLS_STR nlsServer,
NLS_STR * pnlsDrive,
NLS_STR * pnlsPath )
{
PBYTE pBuf;
APIERR err;
NLS_STR nlsDrive;
if ( ( err = nlsDrive.QueryError() ) != NERR_Success )
{
return err;
}
err = ::MNetUseGetInfo(nlsServer.QueryPch(),pnlsDrive->QueryPch(),1,&pBuf);
if ( err != NERR_Success )
{
if ( err == NERR_UseNotFound )
return NERR_Success;
else
return err;
}
NET_NAME netname( ((PUSE_INFO_0)pBuf)->ui0_remote );
::MNetApiBufferFree( &pBuf );
if ( ( err = netname.QueryError() ) != NERR_Success )
{
return err;
}
if ( ( err = netname.QueryLocalPath( pnlsPath ) ) != NERR_Success )
{
return err;
}
return( NERR_Success );
}
/*******************************************************************
NAME: ::IsDriveGreaterThan2Gig
SYNOPSIS: Determines if the disk is bigger than 2Gig. If it, return
TRUE so that a warning can be displayed to the user
RETURNS: TRUE if disk is larger than 2Gig
FALSE otherwise
HISTORY:
NarenG 11/18/92 Modified for AFPMGR
********************************************************************/
BOOL IsDriveGreaterThan2Gig( LPWSTR lpwsVolPath,
APIERR * perr )
{
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
LARGE_INTEGER DriveSize;
LARGE_INTEGER TwoGig = { MAXLONG, 0 };
LPWSTR lpwsPath;
LPWSTR lpwsTmp;
//
// If this drive volume is greater than 2G then we print warning
//
*perr = NERR_Success;
lpwsPath = (LPWSTR)::LocalAlloc( LPTR, (::wcslen(lpwsVolPath) + 2)*sizeof(WCHAR));
if (lpwsPath == NULL)
{
*perr = ERROR_NOT_ENOUGH_MEMORY;
return( TRUE );
}
::wcscpy(lpwsPath, lpwsVolPath);
// if this is a unc path of the type \\foo\bar\path\name then we must
// generate a string that is "\\foo\bar\"
if ( lpwsPath[0] == TEXT('\\') && lpwsPath[1] == TEXT('\\'))
{
lpwsTmp = lpwsPath;
lpwsTmp++;
lpwsTmp++; // point to f in \\foo\bar\path\name
lpwsTmp = ::wcschr(lpwsTmp, TEXT('\\'));
lpwsTmp++; // point to b in \\foo\bar\path\name
lpwsTmp = ::wcschr(lpwsTmp, TEXT('\\'));
// if the path is \\foo\bar\path\name then
if (lpwsTmp != NULL)
{
lpwsTmp++;
}
// else if the path is just \\foo\bar then
else
{
lpwsTmp = lpwsPath + ::wcslen(lpwsPath);
if ( *(lpwsTmp-1) != TEXT('\\'))
{
*lpwsTmp = TEXT('\\');
lpwsTmp++;
}
}
*(lpwsTmp) = 0;
}
// else if this is a local path of the type c:\foo\bar\path\name then
// we must generate a string that is "c:\"
else if (lpwsPath[1] == TEXT(':'))
{
lpwsPath[2] = TEXT('\\');
lpwsPath[3] = 0;
}
// huh?? how did this happen?
else
{
*perr = ERROR_INVALID_DRIVE;
::LocalFree(lpwsPath);
return( TRUE );
}
if ( !::GetDiskFreeSpace( lpwsPath,
&SectorsPerCluster,
&BytesPerSector,
&NumberOfFreeClusters,
&TotalNumberOfClusters
))
{
::LocalFree(lpwsPath);
// call failed: it's not fatal, treat it like disk size is ok
return FALSE;
}
::LocalFree(lpwsPath);
DriveSize = RtlEnlargedIntegerMultiply( SectorsPerCluster * BytesPerSector,
TotalNumberOfClusters ) ;
if ( DriveSize.QuadPart > TwoGig.QuadPart )
{
return TRUE;
}
else
{
return FALSE;
}
}