// FormAdv.cpp : implementation file // #include "stdafx.h" #include "pwsform.h" #include #include "mbobjs.h" #include "Title.h" #include "Sink.h" #include "pwsdoc.h" #include "EdDir.h" #include "FormAdv.h" #include "resource.h" #include #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; }