windows-nt/Source/XPSP1/NT/inetsrv/iis/ui/admin/pws/eddir.cpp
2020-09-26 16:20:57 +08:00

374 lines
11 KiB
C++

// EdDir.cpp : implementation file
//
#include "stdafx.h"
#include "EdDir.h"
#include "mbobjs.h"
#include "resource.h"
#include <shlobj.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CEditDirectory dialog
CEditDirectory::CEditDirectory(CWnd* pParent /*=NULL*/)
: CDialog(CEditDirectory::IDD, pParent),
m_fHome( FALSE ),
m_fNewItem( FALSE ),
m_idsTitle( 0 )
{
//{{AFX_DATA_INIT(CEditDirectory)
m_sz_alias = _T("");
m_sz_path = _T("");
m_bool_read = FALSE;
m_bool_source = FALSE;
m_bool_write = FALSE;
m_int_AppPerms = -1;
//}}AFX_DATA_INIT
m_cedit_path.LoadIllegalChars( IDS_ILLEGAL_PHYS_PATH_CHARS );
m_cedit_alias.LoadIllegalChars( IDS_ILLEGAL_VIRT_DIR_CHARS );
}
void CEditDirectory::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEditDirectory)
DDX_Control(pDX, IDC_SOURCE, m_cbtn_source);
DDX_Control(pDX, IDC_PATH, m_cedit_path);
DDX_Control(pDX, IDC_ALIAS, m_cedit_alias);
DDX_Text(pDX, IDC_ALIAS, m_sz_alias);
DDX_Text(pDX, IDC_PATH, m_sz_path);
DDX_Check(pDX, IDC_READ, m_bool_read);
DDX_Check(pDX, IDC_SOURCE, m_bool_source);
DDX_Check(pDX, IDC_WRITE, m_bool_write);
DDX_Radio(pDX, IDC_RDO_NONE, m_int_AppPerms);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEditDirectory, CDialog)
ON_WM_CONTEXTMENU()
//{{AFX_MSG_MAP(CEditDirectory)
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(IDC_READ, OnRead)
ON_BN_CLICKED(IDC_SOURCE, OnSource)
ON_BN_CLICKED(IDC_WRITE, OnWrite)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//----------------------------------------------------------------
BOOL CEditDirectory::OnInitDialog()
{
// call the parental oninitdialog
BOOL f = CDialog::OnInitDialog();
// if there is a requested title for the dialog, use it
if ( m_idsTitle )
{
CString szTitle;
szTitle.LoadString( m_idsTitle );
SetWindowText( szTitle );
}
// if this is the root directory, disable editing of the alias
if ( m_fHome )
m_cedit_alias.EnableWindow( FALSE );
// keep a copy of the original alias for later verification
m_szOrigAlias = m_sz_alias;
m_bOldSourceControl = m_bool_source;
EnableSourceControl();
// return the answer
return f;
}
/////////////////////////////////////////////////////////////////////////////
// CEditDirectory message handlers
//----------------------------------------------------------------
void CEditDirectory::OnBrowse()
{
UpdateData( TRUE );
BROWSEINFO bi;
LPTSTR lpBuffer;
LPITEMIDLIST pidlBrowse; // PIDL selected by user
// Allocate a buffer to receive browse information.
lpBuffer = (LPTSTR) GlobalAlloc( GPTR, (MAX_PATH + 1) * sizeof(TCHAR) );
if ( !lpBuffer )
{
return;
}
// load the title
CString szTitle;
szTitle.LoadString( IDS_CHOOSE_DIR );
// Fill in the BROWSEINFO structure.
bi.hwndOwner = this->m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = lpBuffer;
bi.lpszTitle = szTitle;
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_DONTGOBELOWDOMAIN;
bi.lpfn = NULL;
bi.lParam = 0;
// Browse for a folder and return its PIDL.
pidlBrowse = SHBrowseForFolder(&bi);
if (pidlBrowse != NULL)
{
// Show the display name, title, and file system path.
if (SHGetPathFromIDList(pidlBrowse, lpBuffer))
{
m_sz_path = lpBuffer;
}
// Free the PIDL returned by SHBrowseForFolder.
GlobalFree(pidlBrowse);
// put the string back
UpdateData( FALSE );
}
// Clean up.
GlobalFree( lpBuffer );
}
//----------------------------------------------------------------
// we now have to test the physical path that the alias points to
// 1) it must be a valid path. This prevents dumb users from entering
// a garbage path. 2) it can't be a redirected hard drive. 3) (I may not
// get to this part now) it would be nice if it is on a local hard drive
// but doesn't exist that the user be asked if they want to create
// the directory. If they say yes, create it.
BOOL CEditDirectory::VerifyDirectoryPath( CString szPath )
{
CString sz;
DWORD attrib;
// first we test the drive to see if it is local or remote
// but before that we need to get the drive letter
_tsplitpath( (LPCTSTR)szPath, sz.GetBuffer(_MAX_DRIVE+1), NULL, NULL, NULL );
sz.ReleaseBuffer();
// it can't be a unc path
if ( sz.IsEmpty() )
{
AfxMessageBox( IDS_ERR_USE_VALID_DRIVE );
return FALSE;
}
// test the drive and only accept valid, non-remote drives
attrib = GetDriveType( (LPCTSTR)sz );
if ( (attrib == DRIVE_REMOTE) )
{
AfxMessageBox( IDS_ERR_USE_VALID_DRIVE );
return FALSE;
}
// now that we know it is a valid drive, get the attributes of the file
attrib = GetFileAttributes( szPath );
// if the directory doesn't exists
if ( attrib == 0xffffffff )
{
CString szMessage;
AfxFormatString1( szMessage, IDS_MAKE_DIRECTORY, szPath );
if ( AfxMessageBox( szMessage, MB_YESNO ) == IDNO )
return FALSE;
// create the directory
if ( !CreateDirectory((LPCTSTR)szPath, NULL) )
{
AfxMessageBox( IDS_ERR_MAKE_DIRECTORY );
return FALSE;
}
// reget the attibutes for the final check below
attrib = GetFileAttributes( szPath );
}
// if the use chose a file, or something not a directory, tell them no.
if ( (attrib == 0xffffffff) || ((attrib & FILE_ATTRIBUTE_DIRECTORY) == 0) )
{
AfxMessageBox( IDS_ERR_USE_VALID_DIR );
return FALSE;
}
// it is OK
return TRUE;
}
//----------------------------------------------------------------
// we need to make sure that there is something in the alias field
// an empty alias is not OK
void CEditDirectory::OnOK()
{
UpdateData( TRUE );
// if write and script or execute is set, it creates a potential security hole.
// warn the user of this situation before continuing
if ( m_bool_write && ((m_int_AppPerms==APPPERM_SCRIPTS)||(m_int_AppPerms==APPPERM_EXECUTE)) )
{
if ( AfxMessageBox( IDS_WRITEEXECUTE_WARNING, MB_YESNO | MB_ICONEXCLAMATION ) != IDYES )
return;
}
// trim leading and trailing spaces
m_sz_alias.TrimLeft();
m_sz_alias.TrimRight();
m_sz_path.TrimLeft();
m_sz_path.TrimRight();
// first test is to see if there is anything in the alias
if ( m_sz_alias.IsEmpty() )
{
AfxMessageBox( IDS_EMPTY_ALIAS );
return;
}
// we now have to test the physical path that the alias points to
// 1) it must be a valid path. This prevents dumb users from entering
// a garbage path. 2) it can't be a redirected hard drive. 3) (I may not
// get to this part now) it would be nice if it is on a local hard drive
// but doesn't exist that the user be asked if they want to create
// the directory. If they say yes, create it.
// VerifyDirectoryPath takes care of any error messages
if ( !VerifyDirectoryPath(m_sz_path) )
return;
// Now we need to make sure that alias isn't already taken
CString szTestPath = SZ_MB_ROOT;
szTestPath += m_szMetaPath.Left( m_szMetaPath.ReverseFind('/') + 1 );
szTestPath += m_sz_alias;
// if we can open the metabase object, then it is already taken
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// try to open the object
// however, if it is not a new object, and the alias has not changed, do not
// see if the object is there becuase we know that it is and it is ok in this case
// use a case insensitive compare because thats what the metabase uses
if ( m_sz_alias.CompareNoCase(m_szOrigAlias) || m_fNewItem )
{
if ( mb.Open(szTestPath) )
{
// we did open it! Close it right away
mb.Close();
// tell the user to pick another name
CString szMessage;
AfxFormatString1( szMessage, IDS_ALIAS_IS_TAKEN, m_sz_alias );
AfxMessageBox( szMessage );
return;
}
}
// make sure the string goes back
UpdateData( FALSE );
// do the default...
CDialog::OnOK();
}
//----------------------------------------------------------------
void CEditDirectory::WinHelp(DWORD dwData, UINT nCmd)
{
CDialog::WinHelp(dwData, nCmd);
}
/////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------
void CEditDirectory::EnableSourceControl()
{
// get the currect button values
UpdateData( TRUE );
// if both read and write are unchecked, then we clear and disable source control
if ( !m_bool_read && !m_bool_write )
{
// save the value of source control
m_bOldSourceControl = m_bool_source;
// clear the source control
m_bool_source = FALSE;
UpdateData( FALSE );
// disable the source control window
m_cbtn_source.EnableWindow( FALSE );
}
else
{
// we enable source control
// disable the source control window
m_cbtn_source.EnableWindow( TRUE );
// and set the value back
m_bool_source = m_bOldSourceControl;
UpdateData( FALSE );
}
}
//----------------------------------------------------------------
void CEditDirectory::OnSource()
{
// get the currect button values
UpdateData( TRUE );
// save the value of source control
m_bOldSourceControl = m_bool_source;
}
//----------------------------------------------------------------
void CEditDirectory::OnRead()
{
EnableSourceControl();
}
//----------------------------------------------------------------
void CEditDirectory::OnWrite()
{
EnableSourceControl();
}
/////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------
void CVDEdit::LoadIllegalChars( int idChars )
{
szExclude.LoadString( idChars );
}
//----------------------------------------------------------------
BOOL CVDEdit::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// if it is a character
if ( message == WM_CHAR )
{
TCHAR chCharCode = (TCHAR)wParam;
// test for bad or control characters
if (_tcschr(szExclude, chCharCode))
{
MessageBeep(0);
return 1;
}
}
// return the default answer
return CEdit::OnWndMsg( message, wParam, lParam, pResult);
}