|
|
/**********************************************************************/ /** 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; } }
|