2025-04-27 07:49:33 -04:00

1427 lines
45 KiB
C++

// FormAdv.cpp : implementation file
//
#include "stdafx.h"
#include "pwsform.h"
#include <inetcom.h>
#include "mbobjs.h"
#include "Title.h"
#include "Sink.h"
#include "pwsdoc.h"
#include "EdDir.h"
#include "FormAdv.h"
#include "resource.h"
#include <iwamreg.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// the key type string for the virtual directories
#define MDSZ_W3_VDIR_TYPE _T("IIsWebVirtualDir")
#define WIDE_MAX_PATH ( MAX_PATH * sizeof(WCHAR) )
// tree view icons
enum {
IMAGE_GOOD_FOLDER = 0,
IMAGE_SERVER,
IAMGE_BAD_FOLDER
};
#define WM_UPDATE_VITRUAL_TREE WM_USER
CFormAdvanced* g_FormAdv = NULL;
extern CPwsDoc* g_p_Doc;
extern CPWSForm* g_pCurrentForm;
/////////////////////////////////////////////////////////////////////////////
// CFormAdvanced
IMPLEMENT_DYNCREATE(CFormAdvanced, CFormView)
//------------------------------------------------------------------------
CFormAdvanced::CFormAdvanced()
: CPWSForm(CFormAdvanced::IDD),
m_hRoot( NULL ),
m_DirHelpID( 0 )
{
//{{AFX_DATA_INIT(CFormAdvanced)
m_sz_default_doc = _T("");
m_bool_allow_browsing = FALSE;
m_bool_enable_default = FALSE;
m_bool_save_log = FALSE;
//}}AFX_DATA_INIT
}
//------------------------------------------------------------------------
CFormAdvanced::~CFormAdvanced()
{
g_FormAdv = NULL;
}
//------------------------------------------------------------------------
void CFormAdvanced::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFormAdvanced)
DDX_Control(pDX, IDC_REMOVE, m_cbtn_remove);
DDX_Control(pDX, IDC_TITLE_BAR, m_ctitle_title);
DDX_Control(pDX, IDC_TREE, m_ctreectrl_tree);
DDX_Control(pDX, IDC_DEFAULT_TITLE, m_csz_default_doc_title);
DDX_Control(pDX, IDC_DEFAULT_DOC, m_csz_default_doc);
DDX_Text(pDX, IDC_DEFAULT_DOC, m_sz_default_doc);
DDX_Check(pDX, IDC_DIR_BROWSE, m_bool_allow_browsing);
DDX_Check(pDX, IDC_ENABLE_DEFAULT, m_bool_enable_default);
DDX_Check(pDX, IDC_SAVE_LOG, m_bool_save_log);
//}}AFX_DATA_MAP
}
//------------------------------------------------------------------------
BEGIN_MESSAGE_MAP(CFormAdvanced, CFormView)
ON_WM_CONTEXTMENU()
//{{AFX_MSG_MAP(CFormAdvanced)
ON_EN_KILLFOCUS(IDC_DEFAULT_DOC, OnKillfocusDefaultDoc)
ON_BN_CLICKED(IDC_ENABLE_DEFAULT, OnEnableDefault)
ON_BN_CLICKED(IDC_DIR_BROWSE, OnDirBrowse)
ON_BN_CLICKED(IDC_EDIT, OnEdit)
ON_NOTIFY(NM_DBLCLK, IDC_TREE, OnDblclkTree)
ON_BN_CLICKED(IDC_SAVE_LOG, OnSaveLog)
ON_BN_CLICKED(IDC_ADD, OnAdd)
ON_BN_CLICKED(IDC_REMOVE, OnRemove)
ON_COMMAND(ID_ADD_VIRT, OnAddVirt)
ON_UPDATE_COMMAND_UI(ID_ADD_VIRT, OnUpdateAddVirt)
ON_COMMAND(ID_PROPERTIES_VIRT, OnPropertiesVirt)
ON_UPDATE_COMMAND_UI(ID_PROPERTIES_VIRT, OnUpdatePropertiesVirt)
ON_UPDATE_COMMAND_UI(ID_DELETE_VIRT, OnUpdateDeleteVirt)
ON_COMMAND(ID_DELETE_VIRT, OnDeleteVirt)
ON_UPDATE_COMMAND_UI(ID_BROWSE_VIRT, OnUpdateBrowseVirt)
ON_COMMAND(ID_BROWSE_VIRT, OnBrowseVirt)
ON_UPDATE_COMMAND_UI(ID_EXPLORE_VIRT, OnUpdateExploreVirt)
ON_COMMAND(ID_EXPLORE_VIRT, OnExploreVirt)
ON_UPDATE_COMMAND_UI(ID_OPEN_VIRT, OnUpdateOpenVirt)
ON_COMMAND(ID_OPEN_VIRT, OnOpenVirt)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
ON_COMMAND(ID_EDIT_CUT, OnEditCut)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFormAdvanced diagnostics
#ifdef _DEBUG
void CFormAdvanced::AssertValid() const
{
CFormView::AssertValid();
}
void CFormAdvanced::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif //_DEBUG
//------------------------------------------------------------------------
// initialize the trees - done once
void CFormAdvanced::InitTree()
{
// prepare the list's image list
if ( m_imageList.Create( IDB_LIST_IMAGES, 17, 5, 0x00FF00FF ) )
// set the image list into the list control
m_ctreectrl_tree.SetImageList( &m_imageList, TVSIL_NORMAL );
}
//------------------------------------------------------------------------
// empty all the items out of the tree
void CFormAdvanced::EmptyTree()
{
m_ctreectrl_tree.DeleteAllItems();
m_hRoot = NULL;
}
//------------------------------------------------------------------------
// given an item in the tree, build its relative metabase path
void CFormAdvanced::BuildMetaPath( HTREEITEM hItem, CString &sz )
{
// clear the path to start with
sz.Empty();
// keep building as long as this is not the root node
while( hItem != m_hRoot )
{
// since we are working backwards, add the nodes to the front of the string
sz = m_ctreectrl_tree.GetItemText( hItem ) + sz;
// move up a level to the parent
hItem = m_ctreectrl_tree.GetParentItem( hItem );
}
}
//------------------------------------------------------------------------
BOOL CFormAdvanced::FIsVirtualDirectoryValid( CWrapMetaBase *pmb, CString szRelPath )
{
CString sz;
BOOL fAnswer = FALSE;
// we need to load the virtual directory path and see if it really exists
// and thus show the appropriate image
fAnswer = pmb->GetString(
szRelPath,
MD_VR_PATH,
IIS_MD_UT_FILE,
sz.GetBuffer(WIDE_MAX_PATH),
WIDE_MAX_PATH,
METADATA_INHERIT
);
sz.ReleaseBuffer();
if ( fAnswer )
{
fAnswer = FALSE;
DWORD dwAttrib = GetFileAttributes( sz );
// it can't be an error and the directory flag must be set
if ( (dwAttrib != 0xFFFFFFFF) &&
((dwAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0) )
fAnswer = TRUE;
}
// return the answer
return fAnswer;
}
//------------------------------------------------------------------------
// set the appropriate tree image for a given item
void CFormAdvanced::SetTreeImage( CWrapMetaBase *pmb, CString szRelPath, HTREEITEM hItem )
{
BOOL f;
int iTreeImage;
// we need to load the virtual directory path and see if it really exists
// and thus show the appropriate image
if ( FIsVirtualDirectoryValid( pmb, szRelPath ) )
iTreeImage = IMAGE_GOOD_FOLDER;
else
iTreeImage = IAMGE_BAD_FOLDER;
// set the image
f = m_ctreectrl_tree.SetItemImage( hItem, iTreeImage, iTreeImage );
}
//------------------------------------------------------------------------
// write out item data
void CFormAdvanced::WriteItemData( CWrapMetaBase *pmb, CString szRelPath, CEditDirectory *pdlg )
{
DWORD dword;
BOOL f;
// set the path into place
f = pmb->SetString( szRelPath, MD_VR_PATH, IIS_MD_UT_FILE, (LPCTSTR)pdlg->m_sz_path );
// put the access flags into place. There are other flags than the ones that are manupulated
// here, so be careful to read the value first, then flip the flags, then write it back
dword = 0;
pmb->GetDword( szRelPath, MD_ACCESS_PERM, IIS_MD_UT_FILE, &dword, METADATA_INHERIT );
// read permissions
if ( pdlg->m_bool_read )
dword |= MD_ACCESS_READ; // set the flag
else
dword &= ~MD_ACCESS_READ; // clear the flag
// write permissions
if ( pdlg->m_bool_write )
dword |= MD_ACCESS_WRITE; // set the flag
else
dword &= ~MD_ACCESS_WRITE; // clear the flag
// read source permissions
if ( pdlg->m_bool_source )
dword |= MD_ACCESS_SOURCE; // set the flag
else
dword &= ~MD_ACCESS_SOURCE; // clear the flag
// since the app permissions are now a set of radio buttons, use a case to discern
switch ( pdlg->m_int_AppPerms )
{
case CEditDirectory::APPPERM_NONE:
dword &= ~MD_ACCESS_SCRIPT; // clear the flag
dword &= ~MD_ACCESS_EXECUTE; // clear the flag
break;
case CEditDirectory::APPPERM_SCRIPTS:
dword |= MD_ACCESS_SCRIPT; // set the flag
dword &= ~MD_ACCESS_EXECUTE; // clear the flag
break;
case CEditDirectory::APPPERM_EXECUTE:
dword |= MD_ACCESS_SCRIPT; // set the flag
dword |= MD_ACCESS_EXECUTE; // set the flag
break;
};
// write the dword back into the metabase
f = pmb->SetDword( szRelPath, MD_ACCESS_PERM, IIS_MD_UT_FILE, dword );
}
//------------------------------------------------------------------------
// edit the selected item in the tree (calls EditTreeItem)
void CFormAdvanced::EditSelectedItem()
{
CString szRelativePath;
CString szOrigAlias;
BOOL f;
DWORD err;
DWORD dword;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// start by building the relative path name from the root node
HTREEITEM hItemEdit = m_ctreectrl_tree.GetSelectedItem();
// build the path
BuildMetaPath( hItemEdit, szRelativePath );
// prepare the edit dialog
CEditDirectory dlg;
// if this is the home directory - let it know
if ( hItemEdit == m_hRoot )
{
dlg.m_fHome = TRUE;
dlg.m_sz_alias.LoadString( IDS_HOME_DIRECTORY );
}
else
{
dlg.m_fHome = FALSE;
szOrigAlias = m_ctreectrl_tree.GetItemText( hItemEdit );
// get rid of the preceding '/' character
szOrigAlias = szOrigAlias.Right( szOrigAlias.GetLength() - 1 );
dlg.m_sz_alias = szOrigAlias;
}
// tell the edit dialog where this alias goes
dlg.m_szMetaPath = szRelativePath;
// now load in the directory path from the metabase
// go for the root directory first
if ( mb.Open(SZ_MB_ROOT) )
{
CString sz;
f = mb.GetString(
szRelativePath,
MD_VR_PATH,
IIS_MD_UT_FILE,
sz.GetBuffer(WIDE_MAX_PATH),
WIDE_MAX_PATH,
METADATA_INHERIT
);
sz.ReleaseBuffer();
if ( f )
{
dlg.m_sz_path = sz;
}
// now prep the access permisions
if ( mb.GetDword( szRelativePath, MD_ACCESS_PERM, IIS_MD_UT_FILE, &dword, METADATA_INHERIT ) )
{
// break the flags out into the dialog items
dlg.m_bool_read = (dword & MD_ACCESS_READ) > 0;
dlg.m_bool_write = (dword & MD_ACCESS_WRITE) > 0;
dlg.m_bool_source = (dword & MD_ACCESS_SOURCE) > 0;
// application permissions are a set of radio buttons, so break it out that way
dlg.m_int_AppPerms = CEditDirectory::APPPERM_NONE;
if ( dword & MD_ACCESS_EXECUTE )
{
dlg.m_int_AppPerms = CEditDirectory::APPPERM_EXECUTE;
}
else if ( dword & MD_ACCESS_SCRIPT )
{
dlg.m_int_AppPerms = CEditDirectory::APPPERM_SCRIPTS;
}
}
// close the metabase object
mb.Close();
}
// now edit the item
if ( dlg.DoModal() == IDOK )
{
// remove the WAM application - recoverable
CString szWAMLocation;
szWAMLocation = SZ_MB_ROOT;
szWAMLocation += szRelativePath;
BOOL fWAM = MakeWAMApplication( szWAMLocation, FALSE, TRUE, FALSE );
// write out the directory information
if ( mb.Open(SZ_MB_ROOT, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE) )
{
// write out the data
WriteItemData( &mb, szRelativePath, &dlg );
// update the tree image
SetTreeImage( &mb, szRelativePath, hItemEdit );
// if this is not the root - AND the alias has changed, rename the object in the metabase
// DO THIS LAST!! becuase it actually changes the metabase path
if ( (hItemEdit != m_hRoot) && (dlg.m_sz_alias != szOrigAlias) )
{
CString szNew = szRelativePath;
// truncate off the last part of the name
szNew = szNew.Left( szNew.ReverseFind(_T('/')) + 1 );
// add on the new name
szNew += dlg.m_sz_alias;
// rename the key in the metabase
f = mb.RenameObject( szRelativePath, dlg.m_sz_alias );
if ( !f )
err = GetLastError();
// build the display name
CString szName = '/';
szName += dlg.m_sz_alias;
// rename the item in the tree view with the display name
m_ctreectrl_tree.SetItemText( hItemEdit, szName );
}
// close the metabase object
mb.Close();
}
// recover the WAM application
if ( fWAM )
{
// build the path
BuildMetaPath( hItemEdit, szRelativePath );
// set the WAM app
szWAMLocation = SZ_MB_ROOT;
szWAMLocation += szRelativePath;
MakeWAMApplication( szWAMLocation, TRUE, TRUE, FALSE );
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Update info from the metabase
//------------------------------------------------------------------------
// recursively add all the items to the tree
void CFormAdvanced::RecurseAddVDItems( CWrapMetaBase* pmb, LPCTSTR szMB, HTREEITEM hParent )
{
CString szEnum;
CString szMBPath;
HTREEITEM hItem;
DWORD index = 0;
// enumerate the sub-directories of the open directory and add them
// to the tree. Recurse each to add its children as well
// enumerate the directories, adding each to the list
while ( pmb->EnumObjects(szMB, szEnum.GetBuffer(WIDE_MAX_PATH), WIDE_MAX_PATH, index) )
{
szEnum.ReleaseBuffer();
// build the display name for this item
szMBPath = _T('/');
szMBPath += szEnum;
// add the item to the tree
hItem = m_ctreectrl_tree.InsertItem( szMBPath, hParent, TVI_SORT );
// build the metabase path for this item
szMBPath = szMB;
szMBPath += _T('/');
szMBPath += szEnum;
// we need to load the virtual directory path and see if it really exists
// and thus show the appropriate image
SetTreeImage( pmb, szMBPath, hItem );
// recurse the item
RecurseAddVDItems( pmb, szMBPath, hItem );
// advance the index
index++;
}
szEnum.ReleaseBuffer();
// expand the parent
m_ctreectrl_tree.Expand( hParent, TVE_EXPAND );
}
//------------------------------------------------------------------------
// to rebuild the tree, first we add the homedirectory and open the metabase
// at that location. Then we recursively add all the subdirectories
void CFormAdvanced::UpdateVirtualTree()
{
BOOL f;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// go for the root directory first
if ( mb.Open(SZ_MB_ROOT) )
{
// prep the home directory name
CString szHome;
szHome.LoadString( IDS_HOME_DIRECTORY );
// insert the root item into the tree
m_hRoot = m_ctreectrl_tree.InsertItem( szHome );
f = m_ctreectrl_tree.SetItemImage( m_hRoot, IMAGE_SERVER, IMAGE_SERVER );
// do the recursive adding thing
RecurseAddVDItems( &mb, _T(""), m_hRoot );
// close the metabase object
mb.Close();
}
}
//------------------------------------------------------------------------
// update the default document info from the metabase
void CFormAdvanced::UpdateBrowseInfo()
{
DWORD dword;
PWCHAR pBuff;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// get ready
UpdateData( TRUE );
// go for the root directory first
if ( mb.Open(SZ_MB_ROOT) )
{
// first, the default directory string. Because this is a comma-list, it could get rather long.
// thus, instead of reading it into a static buffer, we should get it into a allocated one, read
// the string, and clean up
pBuff = (PWCHAR)mb.GetData(
_T(""),
MD_DEFAULT_LOAD_FILE,
IIS_MD_UT_FILE,
STRING_METADATA,
&dword
);
if ( !pBuff )
{
DWORD err = GetLastError( );
if ( err == RPC_E_SERVERCALL_RETRYLATER )
{
// we should try again later
PostMessage( WM_UPDATE_BROWSEINFO );
mb.Close();
return;
}
}
if ( pBuff )
{
m_sz_default_doc = pBuff;
// clean up
mb.FreeWrapData(pBuff);
}
else
{
m_sz_default_doc.Empty();
}
// now the dword representing the boolean flags
if ( mb.GetDword(
_T(""),
MD_DIRECTORY_BROWSING,
IIS_MD_UT_FILE,
&dword,
METADATA_INHERIT
))
{
m_bool_allow_browsing = (dword & MD_DIRBROW_ENABLED) > 0;
m_bool_enable_default = (dword & MD_DIRBROW_LOADDEFAULT) > 0;
}
// close the metabase object
mb.Close();
}
// put the answers back
UpdateData( FALSE );
// enable the default doc items as appropriate
EnableItems();
}
//------------------------------------------------------------------------
// update the save log info from the metabase
void CFormAdvanced::UpdateSaveLog()
{
DWORD dword;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// get ready
UpdateData( TRUE );
// open for the root key
if ( mb.Open(MB_SERVER_KEY_UPDATE) )
{
// get the dword representing log type
if ( mb.GetDword( _T(""), MD_LOG_TYPE, IIS_MD_UT_SERVER, &dword, METADATA_INHERIT ) )
{
m_bool_save_log = (dword == INET_LOG_TO_FILE) || (dword == INET_LOG_TO_SQL);
}
// close the metabase object
mb.Close();
}
// put the data into place
UpdateData( FALSE );
}
//------------------------------------------------------------------------
void CFormAdvanced::EnableItems()
{
UpdateData(TRUE);
// enable the default document windows as necessary
m_csz_default_doc_title.EnableWindow( m_bool_enable_default );
m_csz_default_doc.EnableWindow( m_bool_enable_default );
// if the root is selected, disable the remove button
// get the handle of the selected item in the tree
HTREEITEM hItem = m_ctreectrl_tree.GetSelectedItem();
m_cbtn_remove.EnableWindow( (hItem != m_hRoot) );
}
/////////////////////////////////////////////////////////////////////////////
// Write info to the metabase
//------------------------------------------------------------------------
// Write the default document & browsing info to the metabase
void CFormAdvanced::SaveBrowseInfo()
{
DWORD dword;
BOOL f;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// write out the correct data
UpdateData( TRUE );
// go for the root directory first
if ( mb.Open(SZ_MB_ROOT, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE) )
{
// first, write out the boolean flags
// to prepare the browsing flag for saving - we must get the current value
if ( mb.GetDword( _T(""), MD_DIRECTORY_BROWSING, IIS_MD_UT_FILE, &dword ) )
{
// start by setting or clearing the browsing allowed flag
if ( m_bool_allow_browsing )
dword |= MD_DIRBROW_ENABLED; // set the flag
else
dword &= ~MD_DIRBROW_ENABLED; // clear the flag
// next, set or clear the enable default flag
if ( m_bool_enable_default )
dword |= MD_DIRBROW_LOADDEFAULT; // set the flag
else
dword &= ~MD_DIRBROW_LOADDEFAULT; // clear the flag
// save the browsing flag
f = mb.SetDword( _T(""), MD_DIRECTORY_BROWSING, IIS_MD_UT_FILE, dword );
}
// if the default file is enabled, then write it out too
if ( m_bool_enable_default )
f = mb.SetString( _T(""), MD_DEFAULT_LOAD_FILE, IIS_MD_UT_FILE, (LPCTSTR)m_sz_default_doc );
// close the metabase object
mb.Close();
}
}
//------------------------------------------------------------------------
// Write the save log info to the metabase
void CFormAdvanced::SaveSaveLog()
{
DWORD dword;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// get ready
UpdateData( TRUE );
// open for the root key
if ( mb.Open(MB_SERVER_KEY_UPDATE, METADATA_PERMISSION_WRITE) )
{
if ( m_bool_save_log )
dword = INET_LOG_TO_FILE;
else
dword = INET_LOG_DISABLED;
// write out the flag
mb.SetDword( _T(""), MD_LOG_TYPE, IIS_MD_UT_SERVER, dword );
// close the metabase object
mb.Close();
}
// put the data into place
UpdateData( FALSE );
}
/////////////////////////////////////////////////////////////////////////////
// CFormAdvanced message handlers
//------------------------------------------------------------------------
void CFormAdvanced::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
// initialize the VD tree
InitTree();
// update the virtural directory tree
UpdateVirtualTree();
// update the directory browsing related information
UpdateBrowseInfo();
// update the logging information
UpdateSaveLog();
// let the sink object know we are here
g_FormAdv = this;
g_pCurrentForm = this;
}
//------------------------------------------------------------------------
void CFormAdvanced::SinkNotify(
/* [in] */ DWORD dwMDNumElements,
/* [size_is][in] */ MD_CHANGE_OBJECT __RPC_FAR pcoChangeList[ ])
{
// do the appropriate action based on the type of change
if ( (pcoChangeList->dwMDChangeType & MD_CHANGE_TYPE_DELETE_OBJECT) ||
(pcoChangeList->dwMDChangeType & MD_CHANGE_TYPE_ADD_OBJECT) ||
(pcoChangeList->dwMDChangeType & MD_CHANGE_TYPE_RENAME_OBJECT) )
{
PostMessage( WM_UPDATE_TREEINFO );
}
else if ( pcoChangeList->dwMDChangeType & MD_CHANGE_TYPE_SET_DATA )
{
// we are only concerned with changes in the state of the server here
// thus, we can just look for the MD_SERVER_STATE id
for ( DWORD iElement = 0; iElement < dwMDNumElements; iElement++ )
{
// each change has a list of IDs...
for ( DWORD iID = 0; iID < pcoChangeList[iElement].dwMDNumDataIDs; iID++ )
{
// look for the ids that we are interested in
switch( pcoChangeList[iElement].pdwMDDataIDs[iID] )
{
case MD_DIRECTORY_BROWSING:
case MD_DEFAULT_LOAD_FILE:
PostMessage( WM_UPDATE_BROWSEINFO );
break;
case MD_LOG_TYPE:
PostMessage( WM_UPDATE_LOGINFO );
break;
default:
// do nothing
break;
};
}
}
}
}
//------------------------------------------------------------------------
LRESULT CFormAdvanced::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// process the update message
switch( message )
{
case WM_UPDATE_BROWSEINFO:
UpdateBrowseInfo();
break;
case WM_UPDATE_LOGINFO:
break;
case WM_UPDATE_TREEINFO:
EmptyTree();
UpdateVirtualTree();
break;
};
// do the normal thing
return CFormView::WindowProc(message, wParam, lParam);
}
//------------------------------------------------------------------------
void CFormAdvanced::OnKillfocusDefaultDoc()
{
// write out the change to the metabase
SaveBrowseInfo();
// also, make sure we are showing the latest info
UpdateBrowseInfo();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnEnableDefault()
{
// write out the change to the metabase
SaveBrowseInfo();
// also, make sure we are showing the latest info
UpdateBrowseInfo();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnDirBrowse()
{
// write out the change to the metabase
SaveBrowseInfo();
// also, make sure we are showing the latest info
UpdateBrowseInfo();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnSaveLog()
{
// write out the change to the metabase
SaveSaveLog();
// also, make sure we are showing the latest info
UpdateSaveLog();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnEdit()
{
// prep the help
m_DirHelpID = IDD_DIRECTORY;
EditSelectedItem();
m_DirHelpID = 0;
}
//------------------------------------------------------------------------
void CFormAdvanced::OnDblclkTree(NMHDR* pNMHDR, LRESULT* pResult)
{
m_DirHelpID = IDD_DIRECTORY;
EditSelectedItem();
m_DirHelpID = 0;
*pResult = 1;
}
//------------------------------------------------------------------------
void CFormAdvanced::OnAdd()
{
HTREEITEM hItem;
BOOL fSuccess = FALSE;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// get the parent of the item
HTREEITEM hParent = m_ctreectrl_tree.GetSelectedItem();
// build a path going to the parent - then add on one more /
CString szRelativePath;
BuildMetaPath( hParent, szRelativePath );
szRelativePath += _T('/');
// start by editing a set of default values
CEditDirectory dlg;
dlg.m_sz_alias.LoadString( IDS_DEF_ALIAS );
dlg.m_bool_read = TRUE;
dlg.m_bool_write = FALSE;
dlg.m_bool_source = FALSE;
dlg.m_int_AppPerms = CEditDirectory::APPPERM_SCRIPTS;
dlg.m_szMetaPath = szRelativePath;
dlg.m_fNewItem = TRUE;
// tell the dialog to use the add directory title
dlg.m_idsTitle = IDS_ADD_DIRECTORY;
// prep the help
m_DirHelpID = 0x0504;
// if the user edits and says OK, then make the item and add it in and all that
if ( dlg.DoModal() == IDOK )
{
// the WAM stuff can take a few seconds so...
CWaitCursor waitcursor;
// where to put this new item in the tree??
// if there is no selected item, default to the root
if ( !hParent )
hParent = m_hRoot;
// add on the new child to the relative path
szRelativePath += dlg.m_sz_alias;
// open the metabase
if ( mb.Open(SZ_MB_ROOT, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE) )
{
// add the object to the metabase
if ( mb.AddObject( szRelativePath ) )
{
// so far, so good
fSuccess = TRUE;
// set the key type
mb.SetString( szRelativePath, MD_KEY_TYPE, IIS_MD_UT_SERVER, MDSZ_W3_VDIR_TYPE, 0 );
// write out the object's data
WriteItemData( &mb, szRelativePath, &dlg );
// build the display name
CString szName = _T('/');
szName += dlg.m_sz_alias;
// add the item to the tree
hItem = m_ctreectrl_tree.InsertItem( szName, hParent, TVI_SORT );
SetTreeImage( &mb, szRelativePath, hItem );
}
// close the metabase object
mb.Close();
// create the WAM application at the new virtual directory location
if ( fSuccess )
{
CString szWAMLocation;
szWAMLocation = SZ_MB_ROOT;
szWAMLocation += szRelativePath;
if ( !MakeWAMApplication( szWAMLocation, TRUE ) )
{
// it failed to create the WAM application, but we require it.
fSuccess = FALSE;
// remove the virtual directory
// open the metabase
if ( mb.Open(SZ_MB_ROOT, METADATA_PERMISSION_WRITE) )
{
// remove the object from the metabase
mb.DeleteObject( szRelativePath );
}
}
}
}
// make sure the parent is expanded
m_ctreectrl_tree.Expand( hParent, TVE_EXPAND );
// if it failed, put up an alert to that affect
if ( !fSuccess )
AfxMessageBox( IDS_ERR_ADD_VIRT );
}
// unprep the help
m_DirHelpID = 0;
}
//------------------------------------------------------------------------
// This routine takes a path to a virutal directory in the metabase and creates
// a WAM application there. Most of the code is actually obtaining and maintaining
// the interface to the WAM ole object
// szPath The path to the metabase
// fCreate True if creating an application, FALSE if deleting an existing app
BOOL CFormAdvanced::MakeWAMApplication( IN CString &szPath, IN BOOL fCreate, IN BOOL fRecover, IN BOOL fRecurse )
{
IClassFactory* pcsfFactory = NULL;
IWamAdmin2* pWAM;
HRESULT hresError;
BOOL fAnswer = FALSE;
hresError = CoGetClassObject( CLSID_WamAdmin, CLSCTX_SERVER, NULL,
IID_IClassFactory, (void**) &pcsfFactory);
if (FAILED(hresError))
return FALSE;
// create the instance of the interface
hresError = pcsfFactory->CreateInstance(NULL, IID_IWamAdmin2, (void **)&pWAM);
if (FAILED(hresError))
return FALSE;
// release the factory
pcsfFactory->Release();
// this part will be nicer after it is converted to unicode
WCHAR* pwch;
// allocate the name buffer
pwch = new WCHAR[szPath.GetLength() + 2];
if ( !pwch )
{
pWAM->Release();
return FALSE;
}
// unicodize the name into the buffer
if ( pwch )
{
#ifdef _UNICODE
lstrcpy(pwch, szPath);
#else
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
szPath,
-1,
pwch,
szPath.GetLength() + 1
);
#endif // _UNICODE
// create the in-proc application, if requested
if ( fCreate )
{
if ( fRecover )
hresError = pWAM->AppRecover( pwch, fRecurse );
else
hresError = pWAM->AppCreate2( pwch, eAppRunOutProcInDefaultPool );
}
else
{
// delete the application. Because the whole virtual dir is going away,
// delete any applications lower down in the tree as well
if ( fRecover )
hresError = pWAM->AppDeleteRecoverable( pwch, fRecurse );
else
hresError = pWAM->AppDelete( pwch, fRecurse );
}
// check the error code
fAnswer = SUCCEEDED( hresError );
// clean up
delete pwch;
}
// release the logging ui
pWAM->Release();
// return the answer
return fAnswer;
}
//------------------------------------------------------------------------
void CFormAdvanced::OnRemove()
{
BOOL fSuccess = FALSE;
// get the handle of the selected item in the tree
HTREEITEM hItem = m_ctreectrl_tree.GetSelectedItem();
// make sure its not the root
if ( hItem == m_hRoot ) return;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// get the name of the item
CString sz;
CString szItem = m_ctreectrl_tree.GetItemText( hItem );
// munge the name into the confirm string
AfxFormatString1( sz, IDS_CONFIRM_REMOVE, szItem );
// ask the user if the really want to do this
if ( AfxMessageBox( sz, MB_YESNO ) == IDYES )
{
CString szRelativePath;
// the WAM stuff can take a few seconds so...
CWaitCursor waitcursor;
// build the item's relative path in the metabase
BuildMetaPath( hItem, szRelativePath );
// delete the WAM application at the virtual directory location
CString szWAMLocation;
szWAMLocation = SZ_MB_ROOT;
szWAMLocation += szRelativePath;
fSuccess = MakeWAMApplication( szWAMLocation, FALSE );
// open the metabase
if ( fSuccess && mb.Open(SZ_MB_ROOT, METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE) )
{
// remove the item from the metabase
HRESULT hresError = mb.DeleteObject( szRelativePath );
// check the error code
fSuccess = SUCCEEDED( hresError );
// close the metabase object
mb.Close();
}
// remove the item from the tree
m_ctreectrl_tree.DeleteItem( hItem );
// if we did not succeed, tell the user
if ( !fSuccess )
AfxMessageBox( IDS_ERR_REMOVE_VIRT );
}
}
//------------------------------------------------------------------------
void CFormAdvanced::OnContextMenu(CWnd* pWnd, CPoint point)
{
UINT idMenu;
UINT flags;
// first, we need to convert the point from form coordinates, to tree coordinates
CPoint ptTree = point;
::ScreenToClient( m_ctreectrl_tree.m_hWnd, &ptTree );
// get the tree item that has been right-clicked on
HTREEITEM hHitItem = m_ctreectrl_tree.HitTest( ptTree, &flags );
// if we didn't hit an item, leave
if ( !hHitItem )
return;
// quick, make sure it is selected - if it isn't - select it
if ( m_ctreectrl_tree.GetSelectedItem() != hHitItem )
{
m_ctreectrl_tree.Select( hHitItem, TVGN_CARET );
}
// show the appropriate menu based on the selection
if ( hHitItem == m_hRoot )
idMenu = CG_IDR_POPUP_ADV_ROOT;
else
idMenu = CG_IDR_POPUP_ADV_VIRT;
CMenu menu;
VERIFY(menu.LoadMenu(idMenu));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
while (pWndPopupOwner->GetStyle() & WS_CHILD)
pWndPopupOwner = pWndPopupOwner->GetParent();
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner);
}
//------------------------------------------------------------------------
BOOL CFormAdvanced::PreTranslateMessage(MSG* pMsg)
{
// CG: This block was added by the Pop-up Menu component
{
// Shift+F10: show pop-up menu.
if ((((pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN) && // If we hit a key and
(pMsg->wParam == VK_F10) && (GetKeyState(VK_SHIFT) & ~1)) != 0) || // it's Shift+F10 OR
(pMsg->message == WM_CONTEXTMENU)) // Natural keyboard key
{
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
CPoint point = rect.TopLeft();
point.Offset(5, 5);
OnContextMenu(NULL, point);
return TRUE;
}
}
return CFormView::PreTranslateMessage(pMsg);
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateAddVirt(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnAddVirt()
{
OnAdd();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdatePropertiesVirt(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnPropertiesVirt()
{
OnEdit();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateDeleteVirt(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnDeleteVirt()
{
OnRemove();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateBrowseVirt(CCmdUI* pCmdUI)
{
CString szURL;
pCmdUI->Enable( g_p_Doc && g_p_Doc->BuildHomePageString(szURL) &&
m_ctreectrl_tree.GetSelectedItem() );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnBrowseVirt()
{
CString szURL;
CString szRelative;
// get the beginning part of the url
if ( !g_p_Doc ) return;
if ( !g_p_Doc->BuildHomePageString( szURL ) )
return;
// get the selected item's relative URL path
BuildMetaPath( m_ctreectrl_tree.GetSelectedItem(), szRelative );
// put it all together...
szURL += szRelative;
// and do it to it!
ShellExecute(
NULL, // handle to parent window
NULL, // pointer to string that specifies operation to perform
szURL, // pointer to filename or folder name string
NULL, // pointer to string that specifies executable-file parameters
NULL, // pointer to string that specifies default directory
SW_SHOW // whether file is shown when opened
);
}
//------------------------------------------------------------------------
BOOL CFormAdvanced::FIsVirtualDirectoryValid( HTREEITEM hItem )
{
BOOL fValid = FALSE;
if ( !hItem )
return FALSE;
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return FALSE;
// build the metabase path
CString szMB;
BuildMetaPath( m_ctreectrl_tree.GetSelectedItem(), szMB );
// open the metabase
if ( mb.Open(SZ_MB_ROOT) )
{
// do the test
fValid = FIsVirtualDirectoryValid( &mb, szMB );
// close the metabase object
mb.Close();
}
// finally, return the answer
return fValid;
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateExploreVirt(CCmdUI* pCmdUI)
{
pCmdUI->Enable( FIsVirtualDirectoryValid(m_ctreectrl_tree.GetSelectedItem()) );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnExploreVirt()
{
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// build the metabase path
CString szMB;
BuildMetaPath( m_ctreectrl_tree.GetSelectedItem(), szMB );
// open the metabase
if ( mb.Open(SZ_MB_ROOT) )
{
CString sz;
BOOL f = mb.GetString( szMB, MD_VR_PATH, IIS_MD_UT_FILE,
sz.GetBuffer( WIDE_MAX_PATH ), WIDE_MAX_PATH, METADATA_INHERIT);
sz.ReleaseBuffer();
if ( f )
{
// explore it!
ShellExecute(
NULL, // handle to parent window
_T("explore"), // pointer to string that specifies operation to perform
sz, // pointer to filename or folder name string
NULL, // pointer to string that specifies executable-file parameters
NULL, // pointer to string that specifies default directory
SW_SHOW // whether file is shown when opened
);
}
// close the metabase object
mb.Close();
}
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateOpenVirt(CCmdUI* pCmdUI)
{
pCmdUI->Enable( FIsVirtualDirectoryValid(m_ctreectrl_tree.GetSelectedItem()) );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnOpenVirt()
{
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// build the metabase path
CString szMB;
BuildMetaPath( m_ctreectrl_tree.GetSelectedItem(), szMB );
// open the metabase
if ( mb.Open(SZ_MB_ROOT) )
{
CString sz;
BOOL f = mb.GetString( szMB, MD_VR_PATH, IIS_MD_UT_FILE,
sz.GetBuffer(WIDE_MAX_PATH), WIDE_MAX_PATH, METADATA_INHERIT);
sz.ReleaseBuffer();
if ( f )
{
// explore it!
ShellExecute(
NULL, // handle to parent window
_T("open"), // pointer to string that specifies operation to perform
sz, // pointer to filename or folder name string
NULL, // pointer to string that specifies executable-file parameters
NULL, // pointer to string that specifies default directory
SW_SHOW // whether file is shown when opened
);
}
// close the metabase object
mb.Close();
}
}
//------------------------------------------------------------------------
void CFormAdvanced::OnFinalRelease()
{
// create the metabase wrapper
CWrapMetaBase mb;
if ( !mb.FInit() )
return;
// make sure the metabase saves the chagnes
mb.Save();
CFormView::OnFinalRelease();
}
//------------------------------------------------------------------------
WORD CFormAdvanced::GetContextHelpID()
{
if ( m_DirHelpID )
return m_DirHelpID;
return CFormAdvanced::IDD;
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateEditCopy(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_csz_default_doc.IsWindowEnabled() );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_csz_default_doc.IsWindowEnabled() );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnUpdateEditCut(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_csz_default_doc.IsWindowEnabled() );
}
//------------------------------------------------------------------------
void CFormAdvanced::OnEditCut()
{
m_csz_default_doc.Cut();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnEditCopy()
{
m_csz_default_doc.Copy();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnEditPaste()
{
m_csz_default_doc.Paste();
}
//------------------------------------------------------------------------
void CFormAdvanced::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// check the remove button
EnableItems();
*pResult = 0;
}