|
|
/*++
Copyright (c) 1994-2001 Microsoft Corporation
Module Name : iismbnode.cpp
Abstract: CIISMBNode Object
Author: Ronald Meijer (ronaldm) Sergei Antonov (sergeia)
Project: Internet Services Manager
Revision History: 10/28/2000 sergeia Split from iisobj.cpp
--*/ #include "stdafx.h"
#include "common.h"
#include "inetprop.h"
#include "InetMgrApp.h"
#include "supdlgs.h"
#include "iisobj.h"
#include "ftpsht.h"
#include "w3sht.h"
#include "fltdlg.h"
#include "pwiz.h"
#include <lm.h>
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
#define new DEBUG_NEW
//
// CIISMBNode implementation
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/* static */ LPOLESTR CIISMBNode::_cszSeparator = _T("/");
CIISMBNode::CIISMBNode( IN CIISMachine * pOwner, IN LPCTSTR szNode ) /*++
Routine Description:
Constructor
Arguments:
CIISMachine * pOwner : Owner machine object LPCTSTR szNode : Node name
Return Value:
N/A
--*/ : m_bstrNode(szNode), m_bstrURL(NULL), m_pOwner(pOwner) { ASSERT_READ_PTR(szNode); ASSERT_READ_PTR(pOwner); }
CIISMBNode::~CIISMBNode() { RemoveResultItems(); }
void CIISMBNode::SetErrorOverrides( IN OUT CError & err, IN BOOL fShort ) const /*++
Routine Description:
Set error message overrides
Arguments:
CError err : Error message object BOOL fShort : TRUE to use only single-line errors
Return Value:
None
--*/ { //
// Substitute friendly message for some ID codes.
//
// CODEWORK: Add global overrides as well.
//
err.AddOverride(EPT_S_NOT_REGISTERED, fShort ? IDS_ERR_RPC_NA_SHORT : IDS_ERR_RPC_NA); err.AddOverride(RPC_S_SERVER_UNAVAILABLE, fShort ? IDS_ERR_RPC_NA_SHORT : IDS_ERR_RPC_NA);
err.AddOverride(RPC_S_UNKNOWN_IF, IDS_ERR_INTERFACE); err.AddOverride(RPC_S_PROCNUM_OUT_OF_RANGE, IDS_ERR_INTERFACE); err.AddOverride(REGDB_E_CLASSNOTREG, IDS_ERR_NO_INTERFACE);
if (!fShort) { err.AddOverride(ERROR_ACCESS_DENIED, IDS_ERR_ACCESS_DENIED); } }
BOOL CIISMBNode::IsAdministrator() const { CIISMBNode * that = (CIISMBNode *)this; return that->GetOwner()->HasAdministratorAccess(); }
void CIISMBNode::DisplayError( IN OUT CError & err ) const /*++
Routine Description:
Display error message box. Substituting some friendly messages for some specific error codes
Arguments:
CError & err : Error object contains code to be displayed
Return Value:
Noen
--*/ { SetErrorOverrides(err); err.MessageBox(); }
CIISMBNode * CIISMBNode::GetParentNode() const /*++
Routine Description:
Helper function to return the parent node in the scope tree
Arguments:
None
Return Value:
Parent CIISMBNode or NULL.
--*/ { LONG_PTR cookie = NULL; HSCOPEITEM hParent; CIISMBNode * pNode = NULL; HRESULT hr = S_OK;
ASSERT_PTR(_lpConsoleNameSpace);
if (m_hResultItem != 0) { SCOPEDATAITEM si; ::ZeroMemory(&si, sizeof(SCOPEDATAITEM)); si.mask = SDI_PARAM; si.ID = m_hScopeItem; hr = _lpConsoleNameSpace->GetItem(&si); if (SUCCEEDED(hr)) { cookie = si.lParam; } } else { hr = _lpConsoleNameSpace->GetParentItem( m_hScopeItem, &hParent, &cookie ); }
if (SUCCEEDED(hr)) { pNode = (CIISMBNode *)cookie; ASSERT_PTR(pNode); }
return pNode; }
/* virtual */ HRESULT CIISMBNode::BuildMetaPath( OUT CComBSTR & bstrPath ) const /*++
Routine Description:
Recursively build up the metabase path from the current node and its parents
Arguments:
CComBSTR & bstrPath : Returns metabase path
Return Value:
HRESULT
--*/ { HRESULT hr = S_OK; CIISMBNode * pNode = GetParentNode();
if (pNode) { hr = pNode->BuildMetaPath(bstrPath);
if (SUCCEEDED(hr)) { bstrPath.Append(_cszSeparator); bstrPath.Append(QueryNodeName()); }
return hr; }
//
// No parent node
//
ASSERT_MSG("No parent node"); return E_UNEXPECTED; }
HRESULT CIISMBNode::FillCustomData(CLIPFORMAT cf, LPSTREAM pStream) { HRESULT hr = DV_E_CLIPFORMAT; ULONG uWritten;
if (cf == m_CCF_MachineName) { hr = pStream->Write( QueryMachineName(), (ocslen((OLECHAR*)QueryMachineName()) + 1) * sizeof(OLECHAR), &uWritten );
ASSERT(SUCCEEDED(hr)); return hr; } //
// Generate complete metabase path for this node
//
CString strField; CString strMetaPath; CComBSTR bstr; if (FAILED(hr = BuildMetaPath(bstr))) { ASSERT(FALSE); return hr; } strMetaPath = bstr;
if (cf == m_CCF_MetaPath) { //
// Whole metabase path requested
//
strField = strMetaPath; } else { //
// A portion of the metabase is requested. Return the requested
// portion
//
LPCTSTR lpMetaPath = (LPCTSTR)strMetaPath; LPCTSTR lpEndPath = lpMetaPath + strMetaPath.GetLength() + 1; LPCTSTR lpSvc = NULL; LPCTSTR lpInstance = NULL; LPCTSTR lpParent = NULL; LPCTSTR lpNode = NULL;
//
// Break up the metabase path in portions
//
if (lpSvc = _tcschr(lpMetaPath, _T('/'))) { ++lpSvc;
if (lpInstance = _tcschr(lpSvc, _T('/'))) { ++lpInstance;
if (lpParent = _tcschr(lpInstance, _T('/'))) { ++lpParent; lpNode = _tcsrchr(lpParent, _T('/'));
if (lpNode) { ++lpNode; } } } }
int n1, n2; if (cf == m_CCF_Service) { //
// Requested the service string
//
if (lpSvc) { n1 = DIFF(lpSvc - lpMetaPath); n2 = lpInstance ? DIFF(lpInstance - lpSvc) : DIFF(lpEndPath - lpSvc); strField = strMetaPath.Mid(n1, n2 - 1); } } else if (cf == m_CCF_Instance) { //
// Requested the instance number
//
if (lpInstance) { n1 = DIFF(lpInstance - lpMetaPath); n2 = lpParent ? DIFF(lpParent - lpInstance) : DIFF(lpEndPath - lpInstance); strField = strMetaPath.Mid(n1, n2 - 1); } } else if (cf == m_CCF_ParentPath) { //
// Requestd the parent path
//
if (lpParent) { n1 = DIFF(lpParent - lpMetaPath); n2 = lpNode ? DIFF(lpNode - lpParent) : DIFF(lpEndPath - lpParent); strField = strMetaPath.Mid(n1, n2 - 1); } } else if (cf == m_CCF_Node) { //
// Requested the node name
//
if (lpNode) { n1 = DIFF(lpNode - lpMetaPath); n2 = DIFF(lpEndPath - lpNode); strField = strMetaPath.Mid(n1, n2 - 1); } } else { ASSERT(FALSE); DV_E_CLIPFORMAT; } }
TRACEEOLID("Requested metabase path data: " << strField); int len = strField.GetLength() + 1; hr = pStream->Write(strField, (ocslen(strField) + 1) * sizeof(OLECHAR), &uWritten); ASSERT(SUCCEEDED(hr)); return hr; }
HRESULT CIISMBNode::BuildURL( OUT CComBSTR & bstrURL ) const /*++
Routine Description:
Recursively build up the URL from the current node and its parents.
Arguments:
CComBSTR & bstrURL : Returns URL
Return Value:
HRESULT
--*/ { HRESULT hr = S_OK;
//
// Prepend parent portion
//
CIISMBNode * pNode = GetParentNode();
if (pNode) { hr = pNode->BuildURL(bstrURL);
//
// And our portion
//
if (SUCCEEDED(hr)) { bstrURL.Append(_cszSeparator); bstrURL.Append(QueryNodeName()); }
return hr; }
//
// No parent node
//
ASSERT_MSG("No parent node"); return E_UNEXPECTED; }
BOOL CIISMBNode::OnLostInterface( IN OUT CError & err ) /*++
Routine Description:
Deal with lost interface. Ask the user to reconnect.
Arguments:
CError & err : Error object
Return Value:
TRUE if the interface was successfully recreated. FALSE otherwise. If it tried and failed the error will
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CString str; str.Format(IDS_RECONNECT_WARNING, QueryMachineName());
if (YesNoMessageBox(str)) { //
// Attempt to recreate the interface
//
err = CreateInterface(TRUE); return err.Succeeded(); } return FALSE; }
HRESULT CIISMBNode::DeleteNode(IResultData * pResult) { CError err;
if (!NoYesMessageBox(IDS_CONFIRM_DELETE)) return err;
do { CComBSTR path; CMetaInterface * pInterface = QueryInterface(); ASSERT(pInterface != NULL); err = BuildMetaPath(path); if (err.Failed()) break; CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE); if (!mk.Succeeded()) break; err = mk.DeleteKey(path); if (err.Failed()) break;
err = RemoveScopeItem();
} while (FALSE);
if (err.Failed()) { DisplayError(err); } return err; }
HRESULT CIISMBNode::EnumerateVDirs(HSCOPEITEM hParent, CIISService * pService) /*++
Routine Description:
Enumerate scope child items.
Arguments:
HSCOPEITEM hParent : Parent console handle CIISService * pService : Service type
Return Value:
HRESULT
--*/ { ASSERT_PTR(pService);
CError err; CString strVRoot; CMetaEnumerator * pme = NULL;
err = CreateEnumerator(pme); while (err.Succeeded()) { CIISDirectory * pDir;
err = pme->Next(strVRoot);
if (err.Succeeded()) { TRACEEOLID("Enumerating node: " << strVRoot);
CChildNodeProps child(pme, strVRoot, WITH_INHERITANCE, FALSE); err = child.LoadData(); DWORD dwWin32Error = err.Win32Error();
if (err.Failed()) { //
// Filter out the non-fatal errors
//
switch(err.Win32Error()) { case ERROR_ACCESS_DENIED: case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: err.Reset(); break;
default: TRACEEOLID("Fatal error occurred " << err); } }
if (err.Succeeded()) { //
// Skip non-virtual directories (that is, those with
// inherited vrpaths)
//
if (!child.IsPathInherited()) { //
// Construct with full information.
//
pDir = new CIISDirectory( m_pOwner, pService, strVRoot, child.IsEnabledApplication(), child.QueryWin32Error(), child.GetRedirectedPath() );
if (!pDir) { err = ERROR_NOT_ENOUGH_MEMORY; break; }
err = pDir->AddToScopePane(hParent); } } } }
SAFE_DELETE(pme);
if (err.Win32Error() == ERROR_NO_MORE_ITEMS) { err.Reset(); }
if (err.Failed()) { DisplayError(err); }
// SetInterfaceError(err);
return err; }
BOOL CIISMBNode::GetPhysicalPath( LPCTSTR metaPath, CString & alias, CString & physicalPath ) /*++
Routine Description:
Build a physical path for the current node. Starting with the current node, walk up the tree appending node names until a virtual directory with a real physical path is found
Arguments:
CString & physicalPath : Returns file path
Return Value:
Pointer to path
--*/ { if (CMetabasePath::IsMasterInstance(metaPath)) return FALSE;
BOOL fInherit = FALSE; CMetaInterface * pInterface = QueryInterface(); ASSERT(pInterface != NULL); CMetaKey mk(pInterface); CError err(mk.QueryValue( MD_VR_PATH, physicalPath, &fInherit, metaPath ));
if (err.Failed()) { CString lastNode; CMetabasePath::GetLastNodeName(metaPath, lastNode); PathAppend(lastNode.GetBuffer(MAX_PATH), alias); lastNode.ReleaseBuffer(); CString buf(metaPath); if (NULL == CMetabasePath::ConvertToParentPath(buf)) { return FALSE; } else if (GetPhysicalPath(buf, lastNode, physicalPath)) { return TRUE; } } if (!alias.IsEmpty()) { PathAppend(physicalPath.GetBuffer(MAX_PATH), alias); physicalPath.ReleaseBuffer(); } return TRUE; }
HRESULT CIISMBNode::CleanResult(IResultData * lpResultData) { CError err;
if (!m_ResultItems.IsEmpty()) { POSITION pos = m_ResultItems.GetHeadPosition(); while (pos != NULL) { CIISFileName * pNode = m_ResultItems.GetNext(pos); err = lpResultData->DeleteItem(pNode->m_hResultItem, 0); if (err.Failed()) { ASSERT(FALSE); break; } delete pNode; } m_ResultItems.RemoveAll(); } return err; }
HRESULT CIISMBNode::EnumerateResultPane_( BOOL fExpand, IHeaderCtrl * lpHeader, IResultData * lpResultData, CIISService * pService ) { CError err; if (HasFileSystemFiles()) { if (fExpand) { do { CString dir; CComBSTR root; BuildMetaPath(root); CString physPath, alias; GetPhysicalPath(CString(root), alias, physPath);
if (pService->IsLocal() || PathIsUNC(physPath)) { dir = physPath; } else { ::MakeUNCPath(dir, pService->QueryMachineName(), physPath); }
dir.TrimLeft(); dir.TrimRight();
if (dir.IsEmpty()) { break; }
if (PathIsUNCServerShare(dir)) { CString server, share; int idx = dir.ReverseFind(_T('\\')); ASSERT(idx != -1); server = dir.Left(idx); share = dir.Mid(++idx); LPBYTE pbuf = NULL; NET_API_STATUS rc = NetShareGetInfo((LPTSTR)(LPCTSTR)server, (LPTSTR)(LPCTSTR)share, 0, &pbuf); if (NERR_Success == rc) { NetApiBufferFree(pbuf); } else { err = ERROR_BAD_NETPATH; break; } }
dir += _T("\\*"); WIN32_FIND_DATA w32data; HANDLE hFind = ::FindFirstFile(dir, &w32data);
if (hFind == INVALID_HANDLE_VALUE) { err.GetLastWinError(); ASSERT(FALSE); break; }
do { LPCTSTR name = w32data.cFileName; if ((w32data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { CIISFileName * pNode = new CIISFileName( GetOwner(), pService, w32data.dwFileAttributes, name, NULL); if (!pNode) { err = ERROR_NOT_ENOUGH_MEMORY; break; } RESULTDATAITEM ri; ::ZeroMemory(&ri, sizeof(ri)); ri.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; ri.str = MMC_CALLBACK; ri.nImage = pNode->QueryImage(); ri.lParam = (LPARAM)pNode; err = lpResultData->InsertItem(&ri); if (err.Succeeded()) { pNode->SetScopeItem(m_hScopeItem); pNode->SetResultItem(ri.itemID); m_ResultItems.AddTail(pNode); } else { delete pNode; } }
} while (err.Succeeded() && FindNextFile(hFind, &w32data));
FindClose(hFind);
} while (FALSE); } else { RemoveResultItems(); } } ASSERT(err.Succeeded()); return err; }
void CIISMBNode::RemoveResultItems() { if (!m_ResultItems.IsEmpty()) { POSITION pos = m_ResultItems.GetHeadPosition(); while (pos != NULL) { CIISFileName * pNode = m_ResultItems.GetNext(pos); delete pNode; } m_ResultItems.RemoveAll(); } }
HRESULT CIISMBNode::EnumerateWebDirs(HSCOPEITEM hParent, CIISService * pService) /*++
Routine Description:
Enumerate scope file system child items.
Arguments:
HSCOPEITEM hParent : Parent console handle CIISService * pService : Service type
Return Value:
HRESULT
--*/ { ASSERT_PTR(pService); CError err; do { CString dir; CComBSTR root; BuildMetaPath(root); CString physPath, alias; GetPhysicalPath(CString(root), alias, physPath);
if (pService->IsLocal() || PathIsUNC(physPath)) { dir = physPath; } else { ::MakeUNCPath(dir, pService->QueryMachineName(), physPath); } dir.TrimLeft(); dir.TrimRight(); if (dir.IsEmpty()) { break; }
// Prepare for target machine metabase lookup
BOOL fCheckMetabase = TRUE; CMetaKey mk(QueryInterface(), root, METADATA_PERMISSION_READ, METADATA_MASTER_ROOT_HANDLE); CError errMB(mk.QueryResult()); if (errMB.Win32Error() == ERROR_PATH_NOT_FOUND) { //
// Metabase path not found, not a problem.
//
fCheckMetabase = FALSE; errMB.Reset(); }
// We could have vroot pointed to target machine, or to another remote machine.
// Check if this resource is available and we have access to this resource
if (PathIsUNC(dir)) { CString server, user, password;
server = PathFindNextComponent(dir); int n = server.Find(_T('\\')); if (n != -1) { server = server.Left(n); } user = QueryInterface()->QueryAuthInfo()->QueryUserName(); password = QueryInterface()->QueryAuthInfo()->QueryPassword(); if (server.CompareNoCase(pService->QueryMachineName()) != 0) { // non-local resource, get connection credentials
if (fCheckMetabase) { err = mk.QueryValue(MD_VR_USERNAME, user); if (err.Succeeded()) { err = mk.QueryValue(MD_VR_PASSWORD, password); } // these credentials could be empty. try defaults
err.Reset(); } } // Add use for this resource
NETRESOURCE nr; nr.dwType = RESOURCETYPE_DISK; nr.lpLocalName = NULL; nr.lpRemoteName = (LPTSTR)(LPCTSTR)dir; nr.lpProvider = NULL; // Empty strings below mean no password, which is wrong. NULLs mean
// default user and default password -- this could work better for local case.
LPCTSTR p1 = password, p2 = user; if (password.IsEmpty()) { p1 = NULL; } if (user.IsEmpty()) { p2 = NULL; } DWORD rc = WNetAddConnection2(&nr, p1, p2, 0); if (NO_ERROR != rc) { err = rc; break; } } #if 0
// This is obsolete now
if (PathIsUNCServerShare(dir)) { CString server, share; int idx = dir.ReverseFind(_T('\\')); ASSERT(idx != -1); server = dir.Left(idx); share = dir.Mid(++idx); LPBYTE pbuf = NULL; NET_API_STATUS rc = NetShareGetInfo((LPTSTR)(LPCTSTR)server, (LPTSTR)(LPCTSTR)share, 0, &pbuf); if (NERR_Success == rc) { NetApiBufferFree(pbuf); } else { err = ERROR_BAD_NETPATH; break; } } #endif
dir += _T("\\*"); WIN32_FIND_DATA w32data; HANDLE hFind = ::FindFirstFile(dir, &w32data);
if (hFind == INVALID_HANDLE_VALUE) { err.GetLastWinError(); break; } do { LPCTSTR name = w32data.cFileName; if ( (w32data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && lstrcmp(name, _T(".")) != 0 && lstrcmp(name, _T("..")) != 0 ) { CIISFileName * pNode = new CIISFileName(m_pOwner, pService, w32data.dwFileAttributes, name, NULL); if (!pNode) { err = ERROR_NOT_ENOUGH_MEMORY; break; } if (fCheckMetabase) { errMB = mk.DoesPathExist(w32data.cFileName); if (errMB.Succeeded()) { //
// Match up with metabase properties. If the item
// is found in the metabase with a non-inherited vrpath,
// than a virtual root with this name exists, and this
// file/directory should not be shown.
//
CString vrpath; BOOL f = FALSE; DWORD attr = 0; errMB = mk.QueryValue(MD_VR_PATH, vrpath, NULL, w32data.cFileName, &attr); if (errMB.Succeeded() && (attr & METADATA_ISINHERITED) == 0) { TRACEEOLID("file/directory exists as vroot -- tossing" << w32data.cFileName); delete pNode; continue; } } } err = pNode->AddToScopePane(hParent); } } while (err.Succeeded() && FindNextFile(hFind, &w32data));
FindClose(hFind);
} while (FALSE);
if (err.Failed()) { DisplayError(err); } return err; }
HRESULT CIISMBNode::CreateEnumerator(CMetaEnumerator *& pEnum) /*++
Routine Description:
Create enumerator object for the current path. Requires interface to already be initialized
Arguments:
CMetaEnumerator *& pEnum : Returns enumerator
Return Value:
HRESULT
--*/ { ASSERT(pEnum == NULL); ASSERT(m_hScopeItem != NULL);
CComBSTR bstrPath;
CError err(BuildMetaPath(bstrPath));
if (err.Succeeded()) { TRACEEOLID("Build metabase path: " << bstrPath);
BOOL fContinue = TRUE;
while(fContinue) { fContinue = FALSE;
pEnum = new CMetaEnumerator(QueryInterface(), bstrPath);
err = pEnum ? pEnum->QueryResult() : ERROR_NOT_ENOUGH_MEMORY;
if (IsLostInterface(err)) { SAFE_DELETE(pEnum);
fContinue = OnLostInterface(err); } } }
return err; }
/* virtual */ HRESULT CIISMBNode::Refresh(BOOL fReEnumerate) /*++
Routine Description: Refresh current node, and optionally re-enumerate child objects
Arguments: BOOL fReEnumerate : If true, kill child objects, and re-enumerate
--*/ { CError err;
//
// Set MFC state for wait cursor
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); CWaitCursor wait;
if (fReEnumerate) { //
// Kill child objects
//
TRACEEOLID("Killing child objects");
ASSERT(m_hScopeItem != NULL); err = RemoveChildren(m_hScopeItem);
if (err.Succeeded()) { err = EnumerateScopePane(m_hScopeItem); } }
if (err.Succeeded()) { //
// Refresh current node
//
err = RefreshData(); if (err.Succeeded()) { err = RefreshDisplay(); } }
return err; }
/* virtual */ HRESULT CIISMBNode::GetResultViewType( OUT LPOLESTR * lplpViewType, OUT long * lpViewOptions ) /*++
Routine Description:
If we have an URL built up, display our result view as that URL, and destroy it. This is done when 'browsing' a metabase node. The derived class will build the URL, and reselect the node.
Arguments:
BSTR * lplpViewType : Return view type here long * lpViewOptions : View options
Return Value:
S_FALSE to use default view type, S_OK indicates the view type is returned in *ppViewType
--*/ { if (m_bstrURL.Length()) { *lpViewOptions = MMC_VIEW_OPTIONS_NONE; *lplpViewType = (LPOLESTR)::CoTaskMemAlloc( (m_bstrURL.Length() + 1) * sizeof(WCHAR) );
if (*lplpViewType) { lstrcpy(*lplpViewType, m_bstrURL);
//
// Destroy URL so we get a normal result view next time
//
m_bstrURL.Empty(); m_fSkipEnumResult = TRUE; return S_OK; }
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); }
//
// No URL waiting -- use standard result view
//
return CIISObject::GetResultViewType(lplpViewType, lpViewOptions); }
HRESULT ShellExecuteDirectory( IN LPCTSTR lpszCommand, IN LPCTSTR lpszOwner, IN LPCTSTR lpszDirectory ) /*++
Routine Description:
Shell Open or explore on a given directory path
Arguments:
LPCTSTR lpszCommand : "open" or "explore" LPCTSTR lpszOwner : Owner server LPCTSTR lpszDirectory : Directory path
Return Value:
Error return code.
--*/ { CString strDir;
if (::IsServerLocal(lpszOwner) || ::IsUNCName(lpszDirectory)) { //
// Local directory, or already a unc path
//
strDir = lpszDirectory; } else { ::MakeUNCPath(strDir, lpszOwner, lpszDirectory); }
TRACEEOLID("Attempting to " << lpszCommand << " Path: " << strDir);
CError err; { //
// AFX_MANAGE_STATE required for wait cursor
//
AFX_MANAGE_STATE(::AfxGetStaticModuleState() ); CWaitCursor wait;
if (::ShellExecute( NULL, lpszCommand, strDir, NULL, _T(""), SW_SHOW ) <= (HINSTANCE)32) { err.GetLastWinError(); } }
return err; }
HRESULT CIISMBNode::Command( IN long lCommandID, IN CSnapInObjectRootBase * pObj, IN DATA_OBJECT_TYPES type ) /*++
Routine Description:
Handle command from context menu.
Arguments:
long lCommandID : Command ID CSnapInObjectRootBase * pObj : Base object DATA_OBJECT_TYPES type : Data object type
Return Value:
HRESULT
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
HRESULT hr = S_OK;
CError err = ERROR_NOT_ENOUGH_MEMORY;
switch (lCommandID) { case IDM_BROWSE: //
// Build URL for this node, and force a re-select so as to change
// the result view
//
BuildURL(m_bstrURL);
if (m_bstrURL.Length()) { //
// After selection, the browsed URL will come up in the result view
//
SelectScopeItem(); } break;
//
// CODEWORK: Build path, and, using the explorer URL, put this stuff
// in the result view.
//
case IDM_OPEN: { CComBSTR meta_path; CString phys_path, alias; BuildMetaPath(meta_path); if (GetPhysicalPath(meta_path, alias, phys_path)) { hr = ShellExecuteDirectory(_T("open"), QueryMachineName(), phys_path); } } break;
case IDM_EXPLORE: { CComBSTR meta_path; CString phys_path, alias; BuildMetaPath(meta_path); if (GetPhysicalPath(meta_path, alias, phys_path)) { TCHAR url[MAX_PATH]; DWORD len = MAX_PATH; hr = UrlCreateFromPath(phys_path, url, &len, NULL); m_bstrURL = url; SelectScopeItem(); } } break;
case IDM_TASK_SECURITY_WIZARD: { CComBSTR path; VERIFY(SUCCEEDED(BuildMetaPath(path))); hr = RunSecurityWizard(QueryAuthInfo(), QueryInterface(), CString(path), IDB_WIZ_FTP_LEFT_SEC, IDB_WIZ_FTP_HEAD_SEC); } break; //
// Pass on to base class
//
default: hr = CIISObject::Command(lCommandID, pObj, type); }
return hr; }
HRESULT CIISMBNode::OnPropertyChange(BOOL fScope, IResultData * pResult) { CError err;
err = Refresh(fScope); if (err.Succeeded()) { if ( fScope && HasFileSystemFiles() && !m_ResultItems.IsEmpty() ) { err = CleanResult(pResult); if (err.Succeeded()) { err = EnumerateResultPane(fScope, NULL, pResult); } } else if (!fScope) { pResult->UpdateItem(m_hResultItem); }
}
return err; }
HRESULT CIISMBNode::RemoveResultNode(CIISMBNode * pNode, IResultData * pResult) { CError err; ASSERT(HasFileSystemFiles()); err = pResult->DeleteItem(pNode->m_hResultItem, 0); if (err.Succeeded()) { BOOL found = FALSE; POSITION pos = m_ResultItems.GetHeadPosition(); while (pos != NULL) { if (m_ResultItems.GetNext(pos) == pNode) { found = TRUE; break; } } if (found) { m_ResultItems.RemoveAt(pos); delete pNode; } } return err; }
// See FtpAddNew.cpp for the method CIISMBNode::AddFTPSite
// See WebAddNew.cpp for the method CIISMBNode::AddWebSite
// See add_app_pool.cpp for the method CIISMBNode::AddAppPool
|