You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1831 lines
45 KiB
1831 lines
45 KiB
/*++
|
|
|
|
Copyright (c) 1994-2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
iisdirectory.cpp
|
|
|
|
Abstract:
|
|
|
|
IIS Directory node 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 "connects.h"
|
|
#include "iisobj.h"
|
|
#include "ftpsht.h"
|
|
#include "w3sht.h"
|
|
#include "wdir.h"
|
|
#include "docum.h"
|
|
#include "wfile.h"
|
|
#include "wsecure.h"
|
|
#include "httppage.h"
|
|
#include "errors.h"
|
|
#include "fltdlg.h"
|
|
#include "tracker.h"
|
|
#include <lm.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
extern CPropertySheetTracker g_OpenPropertySheetTracker;
|
|
|
|
|
|
//
|
|
// CIISDirectory Implementation
|
|
//
|
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
//
|
|
// Site Result View definition
|
|
//
|
|
/* static */ int
|
|
CIISDirectory::_rgnLabels[COL_TOTAL] =
|
|
{
|
|
IDS_RESULT_NAME,
|
|
IDS_RESULT_PATH,
|
|
IDS_RESULT_STATUS,
|
|
};
|
|
|
|
|
|
/* static */ int
|
|
CIISDirectory::_rgnWidths[COL_TOTAL] =
|
|
{
|
|
180,
|
|
200,
|
|
200,
|
|
};
|
|
|
|
#if 0
|
|
/* static */ CComBSTR CIISDirectory::_bstrName;
|
|
/* static */ CComBSTR CIISDirectory::_bstrPath;
|
|
/* static */ BOOL CIISDirectory::_fStaticsLoaded = FALSE;
|
|
#endif
|
|
|
|
CIISDirectory::CIISDirectory(
|
|
IN CIISMachine * pOwner,
|
|
IN CIISService * pService,
|
|
IN LPCTSTR szNodeName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructor which does not resolve all display information at
|
|
construction time.
|
|
|
|
Arguments:
|
|
|
|
CIISMachine * pOwner : Owner machine
|
|
CIISService * pService : Service type
|
|
LPCTSTR szNodeName : Node name
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
: CIISMBNode(pOwner, szNodeName),
|
|
m_pService(pService),
|
|
m_bstrDisplayName(szNodeName),
|
|
m_fResolved(FALSE),
|
|
//
|
|
// Default Data
|
|
//
|
|
m_fEnabledApplication(FALSE),
|
|
m_dwWin32Error(ERROR_SUCCESS),
|
|
m_dwEnumError(ERROR_SUCCESS)
|
|
{
|
|
ASSERT_PTR(m_pService);
|
|
m_pService->AddRef();
|
|
}
|
|
|
|
|
|
|
|
CIISDirectory::CIISDirectory(
|
|
CIISMachine * pOwner,
|
|
CIISService * pService,
|
|
LPCTSTR szNodeName,
|
|
BOOL fEnabledApplication,
|
|
DWORD dwWin32Error,
|
|
LPCTSTR strRedirPath
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructor that takes full information
|
|
|
|
Arguments:
|
|
|
|
CIISMachine * pOwner : Owner machine
|
|
CIISService * pService : Service type
|
|
LPCTSTR szNodeName : Node name
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
: CIISMBNode(pOwner, szNodeName),
|
|
m_pService(pService),
|
|
m_bstrDisplayName(szNodeName),
|
|
m_fResolved(TRUE),
|
|
//
|
|
// Data
|
|
//
|
|
m_fEnabledApplication(fEnabledApplication),
|
|
m_dwWin32Error(dwWin32Error),
|
|
m_dwEnumError(ERROR_SUCCESS)
|
|
{
|
|
m_strRedirectPath = strRedirPath;
|
|
ASSERT_PTR(m_pService);
|
|
m_pService->AddRef();
|
|
}
|
|
|
|
|
|
|
|
/* virtual */
|
|
CIISDirectory::~CIISDirectory()
|
|
{
|
|
m_pService->Release();
|
|
}
|
|
|
|
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISDirectory::RefreshData()
|
|
/*++
|
|
Refresh relevant configuration data required for display.
|
|
--*/
|
|
{
|
|
CError err;
|
|
|
|
CWaitCursor wait;
|
|
CComBSTR bstrPath;
|
|
CMetaKey * pKey = NULL;
|
|
|
|
do
|
|
{
|
|
err = BuildMetaPath(bstrPath);
|
|
BREAK_ON_ERR_FAILURE(err)
|
|
|
|
BOOL fContinue = TRUE;
|
|
while (fContinue)
|
|
{
|
|
fContinue = FALSE;
|
|
pKey = new CMetaKey(QueryInterface(), bstrPath);
|
|
|
|
if (!pKey)
|
|
{
|
|
TRACEEOLID("RefreshData: OOM");
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
err = pKey->QueryResult();
|
|
|
|
if (IsLostInterface(err))
|
|
{
|
|
SAFE_DELETE(pKey);
|
|
fContinue = OnLostInterface(err);
|
|
}
|
|
else
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
}
|
|
BREAK_ON_ERR_FAILURE(err)
|
|
|
|
CChildNodeProps child(pKey, NULL /*bstrPath*/, WITH_INHERITANCE, FALSE);
|
|
err = child.LoadData();
|
|
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);
|
|
}
|
|
}
|
|
m_dwWin32Error = child.QueryWin32Error();
|
|
m_fEnabledApplication = child.IsEnabledApplication();
|
|
if (!child.IsRedirected())
|
|
{
|
|
CString dir;
|
|
CString alias;
|
|
if (GetPhysicalPath(bstrPath, alias, dir))
|
|
{
|
|
m_bstrPath = dir;
|
|
if (PathIsUNCServerShare(dir))
|
|
{
|
|
if (FALSE == DoesUNCShareExist(dir))
|
|
{
|
|
err = ERROR_BAD_NETPATH;
|
|
break;
|
|
}
|
|
}
|
|
else if (!PathIsDirectory(dir))
|
|
{
|
|
err = ERROR_PATH_NOT_FOUND;
|
|
break;
|
|
}
|
|
}
|
|
m_strRedirectPath.Empty();
|
|
}
|
|
else
|
|
{
|
|
m_strRedirectPath = child.GetRedirectedPath();
|
|
}
|
|
}
|
|
while(FALSE);
|
|
|
|
SAFE_DELETE(pKey);
|
|
|
|
m_dwEnumError = err.Win32Error();
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISDirectory::EnumerateScopePane(HSCOPEITEM hParent)
|
|
{
|
|
CError err = EnumerateVDirs(hParent, m_pService);
|
|
if (err.Succeeded() && IsWebDir() && m_strRedirectPath.IsEmpty())
|
|
{
|
|
if (m_dwEnumError == ERROR_SUCCESS)
|
|
{
|
|
err = EnumerateWebDirs(hParent, m_pService);
|
|
}
|
|
}
|
|
if (err.Failed())
|
|
{
|
|
m_dwEnumError = err.Win32Error();
|
|
RefreshDisplay();
|
|
}
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
/* virtual */
|
|
int
|
|
CIISDirectory::QueryImage() const
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return bitmap index for the site
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Bitmap index
|
|
|
|
--*/
|
|
{
|
|
ASSERT_PTR(m_pService);
|
|
if (!m_fResolved)
|
|
{
|
|
if (m_hScopeItem == NULL)
|
|
{
|
|
return iError;
|
|
}
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CIISDirectory * that = (CIISDirectory *)this;
|
|
CError err = that->RefreshData();
|
|
that->m_fResolved = err.Succeeded();
|
|
}
|
|
if (!m_pService)
|
|
{
|
|
return iError;
|
|
}
|
|
|
|
if (IsEnabledApplication())
|
|
{
|
|
return SUCCEEDED(m_dwWin32Error) ? iApplication : iApplicationErr;
|
|
}
|
|
else
|
|
{
|
|
return SUCCEEDED(m_dwWin32Error) ?
|
|
m_pService->QueryVDirImage() : m_pService->QueryVDirImageErr();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
CIISDirectory::InitializeChildHeaders(LPHEADERCTRL lpHeader)
|
|
{
|
|
CIISDirectory::InitializeHeaders(lpHeader);
|
|
}
|
|
|
|
/* static */
|
|
void
|
|
CIISDirectory::InitializeHeaders(LPHEADERCTRL lpHeader)
|
|
{
|
|
CIISObject::BuildResultView(lpHeader, COL_TOTAL, _rgnLabels, _rgnWidths);
|
|
}
|
|
|
|
/* virtual */
|
|
LPOLESTR
|
|
CIISDirectory::GetResultPaneColInfo(int nCol)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return result pane string for the given column number
|
|
|
|
Arguments:
|
|
|
|
int nCol : Column number
|
|
|
|
Return Value:
|
|
|
|
String
|
|
|
|
--*/
|
|
{
|
|
switch(nCol)
|
|
{
|
|
case COL_ALIAS:
|
|
return QueryDisplayName();
|
|
|
|
case COL_PATH:
|
|
if (!m_strRedirectPath.IsEmpty())
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CString buf;
|
|
buf.Format(IDS_REDIRECT_FORMAT, m_strRedirectPath);
|
|
_bstrRedirectPathBuf = buf;
|
|
return _bstrRedirectPathBuf;
|
|
}
|
|
if (m_bstrPath.Length() == 0)
|
|
{
|
|
CComBSTR mp;
|
|
BuildMetaPath(mp);
|
|
CString name, pp;
|
|
GetPhysicalPath(mp, name, pp);
|
|
m_bstrPath = pp;
|
|
}
|
|
return m_bstrPath;
|
|
|
|
case COL_STATUS:
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CError err(m_dwWin32Error);
|
|
if (err.Succeeded())
|
|
{
|
|
return OLESTR("");
|
|
}
|
|
|
|
_bstrResult = err;
|
|
return _bstrResult;
|
|
}
|
|
}
|
|
TRACEEOLID("CIISDirectory: Bad column number" << nCol);
|
|
return OLESTR("");
|
|
}
|
|
|
|
/*virtual*/
|
|
HRESULT
|
|
CIISDirectory::AddMenuItems(
|
|
LPCONTEXTMENUCALLBACK piCallback,
|
|
long * pInsertionAllowed,
|
|
DATA_OBJECT_TYPES type
|
|
)
|
|
{
|
|
ASSERT_READ_PTR(piCallback);
|
|
//
|
|
// Add base menu items
|
|
//
|
|
HRESULT hr = CIISObject::AddMenuItems(
|
|
piCallback,
|
|
pInsertionAllowed,
|
|
type
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ASSERT(pInsertionAllowed != NULL);
|
|
if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
|
|
{
|
|
AddMenuSeparator(piCallback);
|
|
if (IsFtpDir())
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR);
|
|
if (IsConfigImportExportable())
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR_FROM_FILE);
|
|
}
|
|
}
|
|
else if (IsWebDir())
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR);
|
|
if (IsConfigImportExportable())
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR_FROM_FILE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) != 0)
|
|
{
|
|
AddMenuSeparator(piCallback);
|
|
if (IsConfigImportExportable())
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_TASK_EXPORT_CONFIG_WIZARD);
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CIISDirectory::InsertNewAlias(CString alias)
|
|
{
|
|
CError err;
|
|
if (!IsExpanded())
|
|
{
|
|
SelectScopeItem();
|
|
IConsoleNameSpace2 * pConsoleNameSpace
|
|
= (IConsoleNameSpace2 *)GetConsoleNameSpace();
|
|
pConsoleNameSpace->Expand(QueryScopeItem());
|
|
HSCOPEITEM hChildItem = NULL;
|
|
LONG_PTR cookie;
|
|
HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie);
|
|
while(SUCCEEDED(hr) && hChildItem)
|
|
{
|
|
CIISObject * pItem = (CIISObject *)cookie;
|
|
ASSERT_PTR(pItem);
|
|
if (0 == alias.Compare(pItem->QueryDisplayName()))
|
|
{
|
|
pItem->SelectScopeItem();
|
|
break;
|
|
}
|
|
hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Now we should insert and select this new site
|
|
CIISDirectory * pAlias = new CIISDirectory(m_pOwner, m_pService, alias);
|
|
if (pAlias != NULL)
|
|
{
|
|
pAlias->AddRef();
|
|
err = pAlias->AddToScopePaneSorted(QueryScopeItem(), FALSE);
|
|
if (err.Succeeded())
|
|
{
|
|
VERIFY(SUCCEEDED(pAlias->SelectScopeItem()));
|
|
}
|
|
else
|
|
{
|
|
pAlias->Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISDirectory::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;
|
|
CString alias;
|
|
CError err;
|
|
CComBSTR bstrMetaPath;
|
|
|
|
switch (lCommandID)
|
|
{
|
|
case IDM_NEW_FTP_VDIR:
|
|
BuildMetaPath(bstrMetaPath);
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
hr = CIISMBNode::AddFTPVDir(pObj, type, alias);
|
|
if (!alias.IsEmpty())
|
|
{
|
|
hr = InsertNewAlias(alias);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_NEW_WEB_VDIR:
|
|
BuildMetaPath(bstrMetaPath);
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
hr = CIISMBNode::AddWebVDir(pObj, type, alias,
|
|
m_pOwner->QueryMajorVersion(), m_pOwner->QueryMinorVersion());
|
|
if (!alias.IsEmpty())
|
|
{
|
|
hr = InsertNewAlias(alias);
|
|
}
|
|
}
|
|
break;
|
|
|
|
//
|
|
// Pass on to base class
|
|
//
|
|
default:
|
|
hr = CIISMBNode::Command(lCommandID, pObj, type);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISDirectory::CreatePropertyPages(
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LONG_PTR handle,
|
|
IUnknown * pUnk,
|
|
DATA_OBJECT_TYPES type
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create the property pages for the given object
|
|
|
|
Arguments:
|
|
|
|
LPPROPERTYSHEETCALLBACK lpProvider : Provider
|
|
LONG_PTR handle : Handle.
|
|
IUnknown * pUnk,
|
|
DATA_OBJECT_TYPES type
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CError err;
|
|
|
|
if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type)))
|
|
{
|
|
return S_OK;
|
|
}
|
|
if (ERROR_ALREADY_EXISTS == err.Win32Error())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
CComBSTR bstrPath;
|
|
//
|
|
// CODEWORK: What to do with m_err? This might be
|
|
// a bad machine object in the first place. Aborting
|
|
// when the machine object has an error code isn't
|
|
// such a bad solution here.
|
|
//
|
|
|
|
/*
|
|
if (m_err.Failed())
|
|
{
|
|
m_err.MessageBox();
|
|
return m_err;
|
|
}
|
|
*/
|
|
err = BuildMetaPath(bstrPath);
|
|
if (err.Succeeded())
|
|
{
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
// cache handle for user in MMCPropertyChangeNotify
|
|
m_ppHandle = handle;
|
|
err = ShowPropertiesDlg(lpProvider, QueryAuthInfo(),
|
|
bstrPath, GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetParentNode(),handle);
|
|
}
|
|
}
|
|
}
|
|
err.MessageBoxOnFailure();
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CIISDirectory::OnViewChange(BOOL fScope,
|
|
IResultData * pResult, IHeaderCtrl * pHeader, DWORD hint)
|
|
{
|
|
// If there is win32 error set, we should clear it to enable web dirs enumeration again
|
|
m_dwWin32Error = ERROR_SUCCESS;
|
|
CError err = CIISMBNode::OnViewChange(fScope, pResult, pHeader, hint);
|
|
// If parent node is selected, this node will be displayed on result
|
|
// pane, we may need to update the status, path, etc
|
|
if (err.Succeeded() && 0 != (hint & PROP_CHANGE_DISPLAY_ONLY))
|
|
{
|
|
// This is a VDir, so it's a scope only item....
|
|
RefreshDisplay(FALSE);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
CIISFileName::CIISFileName(
|
|
CIISMachine * pOwner,
|
|
CIISService * pService,
|
|
const DWORD dwAttributes,
|
|
LPCTSTR alias,
|
|
LPCTSTR redirect
|
|
)
|
|
: CIISMBNode(pOwner, alias),
|
|
m_dwAttribute(dwAttributes),
|
|
m_pService(pService),
|
|
m_bstrFileName(alias),
|
|
m_RedirectString(redirect),
|
|
m_fEnabledApplication(FALSE),
|
|
m_dwWin32Error(0),
|
|
m_dwEnumError(ERROR_SUCCESS),
|
|
m_fResolved(FALSE)
|
|
{
|
|
ASSERT_PTR(pService);
|
|
m_pService->AddRef();
|
|
}
|
|
|
|
/* virtual */
|
|
LPOLESTR
|
|
CIISFileName::GetResultPaneColInfo(int nCol)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return result pane string for the given column number
|
|
|
|
Arguments:
|
|
|
|
int nCol : Column number
|
|
|
|
Return Value:
|
|
|
|
String
|
|
|
|
--*/
|
|
{
|
|
switch(nCol)
|
|
{
|
|
case COL_ALIAS:
|
|
return QueryDisplayName();
|
|
|
|
case COL_PATH:
|
|
if (!m_strRedirectPath.IsEmpty())
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CString buf;
|
|
buf.Format(IDS_REDIRECT_FORMAT, m_strRedirectPath);
|
|
_bstrRedirectPathBuf = buf;
|
|
return _bstrRedirectPathBuf;
|
|
}
|
|
return OLESTR("");
|
|
|
|
case COL_STATUS:
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CError err(m_dwWin32Error);
|
|
if (err.Succeeded())
|
|
{
|
|
return OLESTR("");
|
|
}
|
|
_bstrResult = err;
|
|
return _bstrResult;
|
|
}
|
|
}
|
|
TRACEEOLID("CIISFileName: Bad column number" << nCol);
|
|
return OLESTR("");
|
|
}
|
|
|
|
void
|
|
CIISFileName::InitializeChildHeaders(LPHEADERCTRL lpHeader)
|
|
{
|
|
CIISDirectory::InitializeHeaders(lpHeader);
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISFileName::EnumerateScopePane(HSCOPEITEM hParent)
|
|
{
|
|
CError err = EnumerateVDirs(hParent, m_pService, FALSE);
|
|
if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
err.Reset();
|
|
}
|
|
if (err.Succeeded() && /*IsWebDir() &&*/ m_strRedirectPath.IsEmpty())
|
|
{
|
|
if (m_dwEnumError == ERROR_SUCCESS)
|
|
{
|
|
err = EnumerateWebDirs(hParent, m_pService);
|
|
}
|
|
}
|
|
if (err.Failed())
|
|
{
|
|
m_dwEnumError = err.Win32Error();
|
|
RefreshDisplay();
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
int
|
|
CIISFileName::QueryImage() const
|
|
{
|
|
ASSERT_PTR(m_pService);
|
|
if (!m_fResolved)
|
|
{
|
|
if (m_hScopeItem == NULL)
|
|
{
|
|
TRACEEOLID("BUGBUG: Prematurely asked for display information");
|
|
return MMC_IMAGECALLBACK;
|
|
}
|
|
//
|
|
// Required for the wait cursor
|
|
//
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
CIISFileName * that = (CIISFileName *)this;
|
|
CError err = that->RefreshData();
|
|
that->m_fResolved = err.Succeeded();
|
|
}
|
|
|
|
if (!m_pService)
|
|
{
|
|
return iError;
|
|
}
|
|
if (IsDir())
|
|
{
|
|
if (IsEnabledApplication())
|
|
{
|
|
return SUCCEEDED(m_dwWin32Error) ? iApplication : iApplicationErr;
|
|
}
|
|
else
|
|
{
|
|
return SUCCEEDED(m_dwWin32Error) ? iFolder : iError;
|
|
}
|
|
}
|
|
return SUCCEEDED(m_dwWin32Error) ? iFile : iError;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CIISFileName::DeleteNode(IResultData * pResult)
|
|
{
|
|
CError err;
|
|
CString path;
|
|
BOOL bDeletedPhysical = FALSE;
|
|
|
|
// check if they have the property sheet open on it.
|
|
if (IsMyPropertySheetOpen())
|
|
{
|
|
::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET);
|
|
return S_OK;
|
|
}
|
|
|
|
// this could be an orphaned property sheet
|
|
// check if an orphaned property sheet is open on this item.
|
|
CIISObject * pAlreadyOpenProp = NULL;
|
|
if (TRUE == g_OpenPropertySheetTracker.FindAlreadyOpenPropertySheet(this,&pAlreadyOpenProp))
|
|
{
|
|
// Bring it to the foreground, and bail
|
|
HWND hHwnd = 0;
|
|
if (pAlreadyOpenProp)
|
|
{
|
|
if (hHwnd = pAlreadyOpenProp->IsMyPropertySheetOpen())
|
|
{
|
|
if (hHwnd && (hHwnd != (HWND) 1))
|
|
{
|
|
// Perhapse we should cancel the already
|
|
// opened property sheet...just a thought
|
|
if (!SetForegroundWindow(hHwnd))
|
|
{
|
|
// wasn't able to bring this property sheet to
|
|
// the foreground, the propertysheet must not
|
|
// exist anymore. let's just clean the hwnd
|
|
// so that the user will be able to open propertysheet
|
|
pAlreadyOpenProp->SetMyPropertySheetOpen(0);
|
|
}
|
|
else
|
|
{
|
|
::AfxMessageBox(IDS_CLOSE_PROPERTY_SHEET);
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CComBSTR bstrMetaPath;
|
|
err = BuildMetaPath(bstrMetaPath);
|
|
if (err.Succeeded())
|
|
{
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_WRITE,this,TRUE,bstrMetaPath);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
}
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
CString physPath, alias, csPathMunged;
|
|
GetPhysicalPath(CString(bstrMetaPath), alias, physPath);
|
|
physPath.TrimRight(_T("/"));
|
|
|
|
csPathMunged = physPath;
|
|
#ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
|
|
GetSpecialPathRealPath(0,physPath,csPathMunged);
|
|
#endif
|
|
|
|
if (IsDevicePath(csPathMunged))
|
|
{
|
|
// check if the device path
|
|
// points to an actual dir/file
|
|
// if it does then enumerate it.
|
|
if (IsSpecialPath(csPathMunged,TRUE,TRUE))
|
|
{
|
|
// Remunge this one more time!
|
|
CString csBefore;
|
|
csBefore = csPathMunged;
|
|
GetSpecialPathRealPath(1,csBefore,csPathMunged);
|
|
}
|
|
else
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
// WARNING:physPath could be empty!
|
|
csPathMunged.TrimLeft();
|
|
csPathMunged.TrimRight();
|
|
if (csPathMunged.IsEmpty())
|
|
{
|
|
// Physical path is empty!
|
|
bDeletedPhysical = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (m_pService->IsLocal() || PathIsUNC(csPathMunged))
|
|
{
|
|
//
|
|
// Local directory, or already a unc path
|
|
//
|
|
path = csPathMunged;
|
|
}
|
|
else
|
|
{
|
|
::MakeUNCPath(path, m_pService->QueryMachineName(), csPathMunged);
|
|
}
|
|
LPTSTR p = path.GetBuffer(MAX_PATH);
|
|
PathRemoveBlanks(p);
|
|
PathRemoveBackslash(p);
|
|
path += _T('\0');
|
|
|
|
TRACEEOLID("Attempting to remove file/directory: " << path);
|
|
|
|
CWnd * pWnd = AfxGetMainWnd();
|
|
|
|
//
|
|
// Attempt to delete using shell APIs
|
|
//
|
|
SHFILEOPSTRUCT sos;
|
|
ZeroMemory(&sos, sizeof(sos));
|
|
sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
|
|
sos.wFunc = FO_DELETE;
|
|
sos.pFrom = path;
|
|
sos.fFlags = (GetAsyncKeyState(VK_SHIFT) < 0) ? 0 : FOF_ALLOWUNDO;
|
|
|
|
// Use assignment to avoid conversion and wrong constructor call
|
|
err = ::SHFileOperation(&sos);
|
|
if (err.Succeeded() && !sos.fAnyOperationsAborted)
|
|
{
|
|
bDeletedPhysical = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bDeletedPhysical)
|
|
{
|
|
CMetaInterface * pInterface = QueryInterface();
|
|
ASSERT(pInterface != NULL);
|
|
bstrMetaPath = _T("");
|
|
err = BuildMetaPath(bstrMetaPath);
|
|
if (err.Succeeded())
|
|
{
|
|
CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE);
|
|
if (mk.Succeeded())
|
|
{
|
|
err = mk.DeleteKey(bstrMetaPath);
|
|
}
|
|
// don't hold the Metabasekey open
|
|
// (RemoveScopeItem may do a lot of things,and lock the metabase for other read requests)
|
|
mk.Close();
|
|
}
|
|
if (IsDir())
|
|
{
|
|
err = RemoveScopeItem();
|
|
}
|
|
else
|
|
{
|
|
CIISMBNode * pParent = GetParentNode();
|
|
ASSERT(pParent != NULL);
|
|
if (pParent)
|
|
{
|
|
err = pParent->RemoveResultNode(this, pResult);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (err.Failed())
|
|
{
|
|
DisplayError(err);
|
|
}
|
|
path.ReleaseBuffer();
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CIISFileName::RenameItem(LPOLESTR new_name)
|
|
{
|
|
CError err;
|
|
CComBSTR old_name;
|
|
CComBSTR MetabaseParentPath;
|
|
CComBSTR MetabasePathOld;
|
|
CString PhysPathMetabase, PhysPathFrom, PhysPathTo;
|
|
CString alias, csPathMunged;
|
|
CIISMBNode * pParentNode = NULL;
|
|
CMetaInterface * pInterface = NULL;
|
|
SHFILEOPSTRUCT sos;
|
|
BOOL bDeletedPhysical = FALSE;
|
|
CWnd * pWnd = AfxGetMainWnd();
|
|
|
|
if (new_name == NULL || lstrlen(new_name) == 0)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// Make sure we have a metabase conneciton...
|
|
err = BuildMetaPath(MetabasePathOld);
|
|
if (err.Succeeded())
|
|
{
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_WRITE,this,TRUE,MetabasePathOld);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
}
|
|
|
|
pInterface = QueryInterface();
|
|
if (!pInterface)
|
|
{
|
|
err = E_FAIL;
|
|
goto RenameItem_Exit;
|
|
}
|
|
|
|
//
|
|
// Get all of the needed paths we need..
|
|
//
|
|
|
|
// get old paths...
|
|
old_name = QueryNodeName();
|
|
if (err.Succeeded())
|
|
{
|
|
GetPhysicalPath(CString(MetabasePathOld), alias, PhysPathMetabase);
|
|
PhysPathMetabase.TrimRight(_T("/"));
|
|
}
|
|
|
|
// get new paths...
|
|
if (err.Succeeded())
|
|
{
|
|
err = E_FAIL;
|
|
pParentNode = GetParentNode();
|
|
if (pParentNode)
|
|
{
|
|
err = pParentNode->BuildMetaPath(MetabaseParentPath);
|
|
}
|
|
}
|
|
|
|
// if anything fails up till this point, abort
|
|
if (err.Succeeded())
|
|
{
|
|
//
|
|
// Do the actual work
|
|
//
|
|
csPathMunged = PhysPathMetabase;
|
|
#ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
|
|
GetSpecialPathRealPath(0,PhysPathMetabase,csPathMunged);
|
|
#endif
|
|
|
|
if (IsDevicePath(csPathMunged))
|
|
{
|
|
// check if the device path
|
|
// points to an actual dir/file
|
|
// if it does then enumerate it.
|
|
if (IsSpecialPath(csPathMunged,TRUE,TRUE))
|
|
{
|
|
// Remunge this one more time!
|
|
CString csBefore;
|
|
csBefore = csPathMunged;
|
|
GetSpecialPathRealPath(1,csBefore,csPathMunged);
|
|
}
|
|
else
|
|
{
|
|
err = E_FAIL;
|
|
goto RenameItem_Exit;
|
|
}
|
|
}
|
|
|
|
// WARNING:physPath could be empty!
|
|
csPathMunged.TrimLeft();
|
|
csPathMunged.TrimRight();
|
|
if (csPathMunged.IsEmpty())
|
|
{
|
|
// Physical path is empty!
|
|
bDeletedPhysical = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (m_pService->IsLocal() || PathIsUNC(csPathMunged))
|
|
{
|
|
//
|
|
// Local directory, or already a unc path
|
|
//
|
|
PhysPathFrom = csPathMunged;
|
|
}
|
|
else
|
|
{
|
|
::MakeUNCPath(PhysPathFrom, m_pService->QueryMachineName(), csPathMunged);
|
|
}
|
|
LPTSTR p = PhysPathFrom.GetBuffer(MAX_PATH);
|
|
PathRemoveBlanks(p);
|
|
PathRemoveBackslash(p);
|
|
PhysPathFrom.ReleaseBuffer();
|
|
PhysPathFrom += _T('\0');
|
|
|
|
PhysPathTo = PhysPathFrom;
|
|
p = PhysPathTo.GetBuffer(MAX_PATH);
|
|
PathRemoveFileSpec(p);
|
|
PathAppend(p, new_name);
|
|
PhysPathTo.ReleaseBuffer();
|
|
PhysPathTo += _T('\0');
|
|
|
|
//
|
|
// Attempt to delete using shell APIs
|
|
//
|
|
ZeroMemory(&sos, sizeof(sos));
|
|
sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
|
|
sos.wFunc = FO_RENAME;
|
|
sos.pFrom = PhysPathFrom;
|
|
sos.pTo = PhysPathTo;
|
|
sos.fFlags = FOF_ALLOWUNDO;
|
|
|
|
// Use assignment to avoid conversion and wrong constructor call
|
|
err = ::SHFileOperation(&sos);
|
|
if (err.Succeeded() && !sos.fAnyOperationsAborted)
|
|
{
|
|
bDeletedPhysical = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bDeletedPhysical)
|
|
{
|
|
// rename the metabase path too...
|
|
if (pInterface)
|
|
{
|
|
err = CChildNodeProps::Rename(pInterface,
|
|
MetabaseParentPath,
|
|
old_name,
|
|
new_name
|
|
);
|
|
if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
err.Reset();
|
|
}
|
|
if (err.Win32Error() == ERROR_ALREADY_EXISTS)
|
|
{
|
|
CComBSTR MetabasePathNew;
|
|
|
|
// perhapes the path we are renaming to
|
|
// already is there???
|
|
// what should we do then????
|
|
// if we got this far, then the filename that this is being renamed to.
|
|
// cannot exists, therefore the metabase properties that were there for
|
|
// it is invalid...
|
|
MetabasePathNew = MetabaseParentPath;
|
|
MetabasePathNew.Append(_cszSeparator);
|
|
MetabasePathNew.Append(new_name);
|
|
|
|
//delete key and try again...
|
|
CMetaKey mk(pInterface, METADATA_MASTER_ROOT_HANDLE, METADATA_PERMISSION_WRITE);
|
|
if (mk.Succeeded())
|
|
{
|
|
err = mk.DeleteKey(MetabasePathNew);
|
|
mk.Close();
|
|
}
|
|
|
|
err = CChildNodeProps::Rename(pInterface,
|
|
MetabaseParentPath,
|
|
old_name,
|
|
new_name
|
|
);
|
|
if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
err.Reset();
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
err = E_FAIL;
|
|
}
|
|
|
|
if (err.Failed())
|
|
{
|
|
// if we failed to rename the metabase path in the
|
|
// metabase, then revert the file rename...
|
|
ZeroMemory(&sos, sizeof(sos));
|
|
sos.hwnd = pWnd ? pWnd->m_hWnd : NULL;
|
|
sos.wFunc = FO_RENAME;
|
|
sos.pFrom = PhysPathTo;
|
|
sos.pTo = PhysPathFrom;
|
|
sos.fFlags = FOF_ALLOWUNDO;
|
|
::SHFileOperation(&sos);
|
|
DisplayError(err);
|
|
goto RenameItem_Exit;
|
|
}
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
IConsole * pConsole = (IConsole *)GetConsole();
|
|
// Update result item in the mmc
|
|
CComQIPtr<IResultData, &IID_IResultData> lpResultData(pConsole);
|
|
m_bstrFileName = new_name;
|
|
err = lpResultData->UpdateItem(m_hResultItem);
|
|
m_bstrNode = new_name;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (err.Failed())
|
|
{
|
|
DisplayError(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
RenameItem_Exit:
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISFileName::RefreshData()
|
|
/*++
|
|
Refresh relevant configuration data required for display.
|
|
--*/
|
|
{
|
|
CError err;
|
|
|
|
CWaitCursor wait;
|
|
CComBSTR bstrPath;
|
|
CMetaKey * pKey = NULL;
|
|
|
|
do
|
|
{
|
|
err = BuildMetaPath(bstrPath);
|
|
if (err.Failed())
|
|
{
|
|
break;
|
|
}
|
|
|
|
BOOL fContinue = TRUE;
|
|
|
|
while (fContinue)
|
|
{
|
|
fContinue = FALSE;
|
|
pKey = new CMetaKey(QueryInterface(), bstrPath);
|
|
|
|
if (!pKey)
|
|
{
|
|
TRACEEOLID("RefreshData: OOM");
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
err = pKey->QueryResult();
|
|
if (IsLostInterface(err))
|
|
{
|
|
SAFE_DELETE(pKey);
|
|
fContinue = OnLostInterface(err);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
// No metabase path: nothing more to do
|
|
break;
|
|
}
|
|
CChildNodeProps child(pKey, NULL /*bstrPath*/, WITH_INHERITANCE, FALSE);
|
|
err = child.LoadData();
|
|
m_dwWin32Error = child.QueryWin32Error();
|
|
if (err.Succeeded())
|
|
{
|
|
CString buf = child.m_strAppRoot;
|
|
m_fEnabledApplication = (buf.CompareNoCase(bstrPath) == 0) && child.IsEnabledApplication();
|
|
}
|
|
m_strRedirectPath.Empty();
|
|
if (child.IsRedirected())
|
|
{
|
|
m_strRedirectPath = child.GetRedirectedPath();
|
|
}
|
|
}
|
|
while(FALSE);
|
|
|
|
SAFE_DELETE(pKey);
|
|
m_dwEnumError = err.Win32Error();
|
|
|
|
return err;
|
|
}
|
|
|
|
/*virtual*/
|
|
HRESULT
|
|
CIISFileName::AddMenuItems(
|
|
LPCONTEXTMENUCALLBACK piCallback,
|
|
long * pInsertionAllowed,
|
|
DATA_OBJECT_TYPES type
|
|
)
|
|
{
|
|
ASSERT_READ_PTR(piCallback);
|
|
//
|
|
// Add base menu items
|
|
//
|
|
HRESULT hr = CIISObject::AddMenuItems(
|
|
piCallback,
|
|
pInsertionAllowed,
|
|
type
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ((*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) != 0)
|
|
{
|
|
AddMenuSeparator(piCallback);
|
|
if (_tcsicmp(m_pService->QueryServiceName(), SZ_MBN_FTP) == 0)
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_FTP_VDIR);
|
|
}
|
|
else if (_tcsicmp(m_pService->QueryServiceName(), SZ_MBN_WEB) == 0)
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR);
|
|
if (_tcsicmp(GetKeyType(),IIS_CLASS_WEB_DIR_W) == 0)
|
|
{
|
|
if (IsConfigImportExportable())
|
|
{
|
|
AddMenuItemByCommand(piCallback, IDM_NEW_WEB_VDIR_FROM_FILE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ASSERT(pInsertionAllowed != NULL);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISFileName::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;
|
|
CString alias;
|
|
CError err;
|
|
CComBSTR bstrMetaPath;
|
|
BOOL bNeedMetabase = FALSE;
|
|
BOOL bHaveMetabase = FALSE;
|
|
|
|
switch (lCommandID)
|
|
{
|
|
case IDM_NEW_FTP_VDIR:
|
|
case IDM_NEW_WEB_VDIR:
|
|
bNeedMetabase = TRUE;
|
|
break;
|
|
case IDM_BROWSE:
|
|
if (m_hResultItem != 0)
|
|
{
|
|
bNeedMetabase = TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
bNeedMetabase = FALSE;
|
|
}
|
|
|
|
if (bNeedMetabase)
|
|
{
|
|
// WARNING:bstrMetaPath will be used by switch statement below
|
|
VERIFY(SUCCEEDED(BuildMetaPath(bstrMetaPath)));
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrMetaPath);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
bHaveMetabase = TRUE;
|
|
}
|
|
}
|
|
|
|
switch (lCommandID)
|
|
{
|
|
|
|
case IDM_NEW_FTP_VDIR:
|
|
if (bHaveMetabase)
|
|
{
|
|
hr = CIISMBNode::AddFTPVDir(pObj, type, alias);
|
|
if (!alias.IsEmpty())
|
|
{
|
|
hr = InsertNewAlias(alias);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_NEW_WEB_VDIR:
|
|
if (bHaveMetabase)
|
|
{
|
|
hr = CIISMBNode::AddWebVDir(pObj, type, alias,
|
|
m_pOwner->QueryMajorVersion(), m_pOwner->QueryMinorVersion());
|
|
if (!alias.IsEmpty())
|
|
{
|
|
hr = InsertNewAlias(alias);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_BROWSE:
|
|
if (m_hResultItem != 0)
|
|
{
|
|
if (bHaveMetabase)
|
|
{
|
|
BuildURL(m_bstrURL);
|
|
if (m_bstrURL.Length())
|
|
{
|
|
ShellExecute(GetMainWindow(GetConsole())->m_hWnd, _T("open"), m_bstrURL, NULL, NULL, SW_SHOWNORMAL);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = CIISMBNode::Command(lCommandID, pObj, type);
|
|
}
|
|
break;
|
|
|
|
//
|
|
// Pass on to base class
|
|
//
|
|
default:
|
|
hr = CIISMBNode::Command(lCommandID, pObj, type);
|
|
}
|
|
|
|
// ASSERT(SUCCEEDED(hr));
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CIISFileName::InsertNewAlias(CString alias)
|
|
{
|
|
CError err;
|
|
if (!IsExpanded())
|
|
{
|
|
SelectScopeItem();
|
|
IConsoleNameSpace2 * pConsoleNameSpace = (IConsoleNameSpace2 *)GetConsoleNameSpace();
|
|
pConsoleNameSpace->Expand(QueryScopeItem());
|
|
HSCOPEITEM hChildItem = NULL;
|
|
LONG_PTR cookie;
|
|
HRESULT hr = pConsoleNameSpace->GetChildItem(m_hScopeItem, &hChildItem, &cookie);
|
|
while(SUCCEEDED(hr) && hChildItem)
|
|
{
|
|
CIISObject * pItem = (CIISObject *)cookie;
|
|
ASSERT_PTR(pItem);
|
|
if (0 == alias.Compare(pItem->QueryDisplayName()))
|
|
{
|
|
pItem->SelectScopeItem();
|
|
break;
|
|
}
|
|
hr = pConsoleNameSpace->GetNextItem(hChildItem, &hChildItem, &cookie);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Now we should insert and select this new site
|
|
CIISDirectory * pAlias = new CIISDirectory(m_pOwner, m_pService, alias);
|
|
if (pAlias != NULL)
|
|
{
|
|
pAlias->AddRef();
|
|
err = pAlias->AddToScopePaneSorted(QueryScopeItem(), FALSE);
|
|
if (err.Succeeded())
|
|
{
|
|
VERIFY(SUCCEEDED(pAlias->SelectScopeItem()));
|
|
}
|
|
else
|
|
{
|
|
pAlias->Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/* virtual */
|
|
HRESULT
|
|
CIISFileName::CreatePropertyPages(
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
LONG_PTR handle,
|
|
IUnknown * pUnk,
|
|
DATA_OBJECT_TYPES type
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create the property pages for the given object
|
|
|
|
Arguments:
|
|
|
|
LPPROPERTYSHEETCALLBACK lpProvider : Provider
|
|
LONG_PTR handle : Handle.
|
|
IUnknown * pUnk,
|
|
DATA_OBJECT_TYPES type
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
|
|
CError err;
|
|
if (S_FALSE == (HRESULT)(err = CIISMBNode::CreatePropertyPages(lpProvider, handle, pUnk, type)))
|
|
{
|
|
return S_OK;
|
|
}
|
|
if (ERROR_ALREADY_EXISTS == err.Win32Error())
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
CComBSTR bstrPath;
|
|
CError err(BuildMetaPath(bstrPath));
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
//
|
|
// If there's already a property sheet open on this item
|
|
// then make it the foreground window and bail.
|
|
HWND MyPropWindow = IsMyPropertySheetOpen();
|
|
if (MyPropWindow && (MyPropWindow != (HWND) 1))
|
|
{
|
|
if (SetForegroundWindow(MyPropWindow))
|
|
{
|
|
if (handle)
|
|
{
|
|
MMCFreeNotifyHandle(handle);
|
|
handle = 0;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
// wasn't able to bring this property sheet to
|
|
// the foreground, the propertysheet must not
|
|
// exist anymore. let's just clean the hwnd
|
|
// so that the user will be able to open propertysheet
|
|
SetMyPropertySheetOpen(0);
|
|
}
|
|
}
|
|
|
|
// cache handle for user in MMCPropertyChangeNotify
|
|
m_ppHandle = handle;
|
|
|
|
err = CheckForMetabaseAccess(METADATA_PERMISSION_READ,this,TRUE,bstrPath);
|
|
if (!IsLostInterface(err))
|
|
{
|
|
// reset error if an other error other than No interface
|
|
err.Reset();
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
if (IsDir())
|
|
{
|
|
err = ShowDirPropertiesDlg(
|
|
lpProvider, QueryAuthInfo(), bstrPath,
|
|
GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetParentNode(), handle
|
|
);
|
|
}
|
|
else
|
|
{
|
|
err = ShowFilePropertiesDlg(
|
|
lpProvider, QueryAuthInfo(), bstrPath,
|
|
GetMainWindow(GetConsole()), (LPARAM)this, (LPARAM)GetParentNode(), handle
|
|
);
|
|
}
|
|
}
|
|
}
|
|
err.MessageBoxOnFailure();
|
|
}
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CIISFileName::ShowDirPropertiesDlg(
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
CComAuthInfo * pAuthInfo,
|
|
LPCTSTR lpszMDPath,
|
|
CWnd * pMainWnd,
|
|
LPARAM lParam,
|
|
LPARAM lParamParent,
|
|
LONG_PTR handle
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
ASSERT_PTR(lpProvider);
|
|
|
|
CError err;
|
|
|
|
if (TRUE == m_fFlaggedForDeletion)
|
|
{
|
|
// this item was marked for deletion during the RefreshData
|
|
// so don't display it's property page.
|
|
// instead popup an error.
|
|
err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
else
|
|
{
|
|
CW3Sheet * pSheet = new CW3Sheet(
|
|
pAuthInfo,
|
|
lpszMDPath,
|
|
0,
|
|
pMainWnd,
|
|
lParam,
|
|
lParamParent
|
|
);
|
|
|
|
if (pSheet)
|
|
{
|
|
pSheet->SetModeless();
|
|
|
|
//
|
|
// Add file pages
|
|
//
|
|
pSheet->SetSheetType(pSheet->SHEET_TYPE_DIR);
|
|
err = AddMMCPage(lpProvider, new CW3DirPage(pSheet));
|
|
err = AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet));
|
|
err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, FILE_ATTRIBUTE_DIRECTORY));
|
|
err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
|
|
err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CIISFileName::ShowFilePropertiesDlg(
|
|
LPPROPERTYSHEETCALLBACK lpProvider,
|
|
CComAuthInfo * pAuthInfo,
|
|
LPCTSTR lpszMDPath,
|
|
CWnd * pMainWnd,
|
|
LPARAM lParam,
|
|
LPARAM lParamParent,
|
|
LONG_PTR handle
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
|
|
ASSERT_PTR(lpProvider);
|
|
|
|
CError err;
|
|
|
|
if (TRUE == m_fFlaggedForDeletion)
|
|
{
|
|
// this item was marked for deletion during the RefreshData
|
|
// so don't display it's property page.
|
|
// instead popup an error.
|
|
err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
else
|
|
{
|
|
CW3Sheet * pSheet = new CW3Sheet(
|
|
pAuthInfo,
|
|
lpszMDPath,
|
|
0,
|
|
pMainWnd,
|
|
lParam,
|
|
lParamParent
|
|
);
|
|
|
|
if (pSheet)
|
|
{
|
|
pSheet->SetModeless();
|
|
//
|
|
// Add file pages
|
|
//
|
|
pSheet->SetSheetType(pSheet->SHEET_TYPE_FILE);
|
|
err = AddMMCPage(lpProvider, new CW3FilePage(pSheet));
|
|
err = AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, 0));
|
|
err = AddMMCPage(lpProvider, new CW3HTTPPage(pSheet));
|
|
err = AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet));
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CIISFileName::OnViewChange(BOOL fScope,
|
|
IResultData * pResult, IHeaderCtrl * pHeader, DWORD hint)
|
|
{
|
|
// If there is win32 error set, we should clear it to enable web dirs enumeration again
|
|
m_dwWin32Error = ERROR_SUCCESS;
|
|
CError err = CIISMBNode::OnViewChange(fScope, pResult, pHeader, hint);
|
|
// If parent node is selected, this node will be displayed on result
|
|
// pane, we may need to update the status, path, etc
|
|
//if (err.Succeeded() && 0 != (hint & PROP_CHANGE_DISPLAY_ONLY))
|
|
//{
|
|
// pResult->UpdateItem(IsDir() ? m_hScopeItem : m_hResultItem);
|
|
//}
|
|
return err;
|
|
}
|
|
|
|
HRESULT
|
|
CIISFileName::OnDblClick(IComponentData * pcd, IComponent * pc)
|
|
{
|
|
if (IsDir())
|
|
{
|
|
return CIISMBNode::OnDblClick(pcd, pc);
|
|
}
|
|
else
|
|
{
|
|
CComQIPtr<IPropertySheetProvider, &IID_IPropertySheetProvider> spProvider(GetConsole());
|
|
IDataObject * pdo = NULL;
|
|
GetDataObject(&pdo, CCT_RESULT);
|
|
CError err = spProvider->FindPropertySheet(reinterpret_cast<MMC_COOKIE>(this), 0, pdo);
|
|
if (err != S_OK)
|
|
{
|
|
err = spProvider->CreatePropertySheet(m_bstrFileName, TRUE, (MMC_COOKIE)this, pdo, MMC_PSO_HASHELP);
|
|
if (err.Succeeded())
|
|
{
|
|
err = spProvider->AddPrimaryPages(
|
|
pc,
|
|
TRUE, // we may want to get property change notifications
|
|
NULL, // according to docs
|
|
FALSE // for result item only
|
|
);
|
|
if (err.Succeeded())
|
|
{
|
|
err = spProvider->AddExtensionPages();
|
|
}
|
|
}
|
|
if (err.Succeeded())
|
|
{
|
|
HWND hWnd = NULL;
|
|
VERIFY(SUCCEEDED(GetConsole()->GetMainWindow(&hWnd)));
|
|
VERIFY(SUCCEEDED(spProvider->Show((LONG_PTR)hWnd, 0)));
|
|
}
|
|
else
|
|
{
|
|
spProvider->Show(-1, 0);
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
}
|