Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

856 lines
18 KiB

/*++
Copyright (c) 1994-1999 Microsoft Corporation
Module Name :
idlg.cpp
Abstract:
Inheritance Dialog
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "common.h"
#include "idlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
extern HINSTANCE hDLLInstance;
//
// Inheritance dialog
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CInheritanceDlg::CInheritanceDlg(
IN DWORD dwMetaID,
IN BOOL fWrite,
IN CComAuthInfo * pAuthInfo, OPTIONAL
IN LPCTSTR lpstrMetaRoot,
IN CStringList & strlMetaChildNodes,
IN LPCTSTR lpstrPropertyName, OPTIONAL
IN CWnd * pParent OPTIONAL
)
/*++
Routine Description:
Inheritance dialog constructor. This constructor assumes GetDataPaths()
has already been called.
Arguments:
DWORD dwMetaID : Meta ID
BOOL fWrite : TRUE from write, FALSE from delete
CIISServer * pAuthInfo : Auth info object or NULL
LPCTSTR lpstrMetaRoot : Meta root
CStringList & strlMetaChildNodes : List of child nodes from GetDataPaths
LPCTSTR lpstrPropertyName : Optional text string for the property
CWnd * pParent : Optional parent window
Return Value:
None
--*/
: m_fWrite(fWrite),
m_fEmpty(TRUE),
m_fUseTable(TRUE),
m_strMetaRoot(lpstrMetaRoot),
m_strPropertyName(lpstrPropertyName ? lpstrPropertyName : _T("")),
m_mk(pAuthInfo),
CDialog(CInheritanceDlg::IDD, pParent)
{
m_strlMetaChildNodes = strlMetaChildNodes;
VERIFY(CMetaKey::GetMDFieldDef(
dwMetaID,
m_dwMDIdentifier,
m_dwMDAttributes,
m_dwMDUserType,
m_dwMDDataType
));
Initialize();
}
CInheritanceDlg::CInheritanceDlg(
IN DWORD dwMetaID,
IN BOOL fWrite,
IN CComAuthInfo * pAuthInfo, OPTIONAL
IN LPCTSTR lpstrMetaRoot,
IN LPCTSTR lpstrPropertyName, OPTIONAL
IN CWnd * pParent OPTIONAL
)
/*++
Routine Description:
Inheritance dialog constructor. This constructor will call GetDataPaths().
Arguments:
DWORD dwMetaID : Meta ID
BOOL fWrite : TRUE from write, FALSE from delete
CComAuthInfo * pAuthInfo : Auth info or NULL
LPCTSTR lpstrMetaRoot : Meta root
LPCTSTR lpstrPropertyName : Optional text string for the property
CWnd * pParent : Optional parent window
Return Value:
None
--*/
: m_fWrite(fWrite),
m_fEmpty(TRUE),
m_fUseTable(TRUE),
m_strMetaRoot(lpstrMetaRoot),
m_strlMetaChildNodes(),
m_strPropertyName(lpstrPropertyName ? lpstrPropertyName : _T("")),
m_mk(pAuthInfo),
CDialog(CInheritanceDlg::IDD, pParent)
{
//
// Specify the resources to use
//
HINSTANCE hOldRes = AfxGetResourceHandle();
AfxSetResourceHandle(hDLLInstance);
VERIFY(CMetaKey::GetMDFieldDef(
dwMetaID,
m_dwMDIdentifier,
m_dwMDAttributes,
m_dwMDUserType,
m_dwMDDataType
));
//
// Need to do our own GetDataPaths()
//
CError err(GetDataPaths());
if (!err.MessageBoxOnFailure())
{
Initialize();
}
//
// Restore the resources
//
AfxSetResourceHandle(hOldRes);
}
CInheritanceDlg::CInheritanceDlg(
IN BOOL fTryToFindInTable,
IN DWORD dwMDIdentifier,
IN DWORD dwMDAttributes,
IN DWORD dwMDUserType,
IN DWORD dwMDDataType,
IN LPCTSTR lpstrPropertyName,
IN BOOL fWrite,
IN CComAuthInfo * pAuthInfo, OPTIONAL
IN LPCTSTR lpstrMetaRoot,
IN CWnd * pParent OPTIONAL
)
/*++
Routine Description:
Inheritance dialog constructor. This constructor will call GetDataPaths(),
and will use the specified parameters if the property ID does not exist
in the property table
Arguments:
BOOL fTryToFindInTable : If TRUE, first look in table
DWORD dwMDIdentifier : Metadata identifier
DWORD dwMDAttributes : Metadata attributes
DWORD dwMDUserType : Metadata user type
DWORD dwMDDataType : Metadata data type
LPCTSTR lpstrPropertyName : Text string for the property
BOOL fWrite : TRUE from write, FALSE from delete
CComAuthInfo * pAuthInfo : Authentication info or NULL.
LPCTSTR lpstrMetaRoot : Meta root
CWnd * pParent : Optional parent window
Return Value:
None
--*/
: m_fWrite(fWrite),
m_fEmpty(TRUE),
m_fUseTable(FALSE),
m_strMetaRoot(lpstrMetaRoot),
m_strlMetaChildNodes(),
m_mk(pAuthInfo),
CDialog(CInheritanceDlg::IDD, pParent)
{
//
// Specify the resources to use
//
HINSTANCE hOldRes = AfxGetResourceHandle();
AfxSetResourceHandle(hDLLInstance);
if (fTryToFindInTable && !CMetaKey::GetMDFieldDef(
dwMDIdentifier,
m_dwMDIdentifier,
m_dwMDAttributes,
m_dwMDUserType,
m_dwMDDataType
))
{
//
// Did not exist in the table, use specified parameters
//
m_dwMDIdentifier = dwMDIdentifier;
m_dwMDAttributes = dwMDAttributes;
m_dwMDUserType = dwMDUserType;
m_dwMDDataType = dwMDDataType;
m_strPropertyName = lpstrPropertyName;
}
//
// Need to do our own GetDataPaths()
//
CError err(GetDataPaths());
if (!err.MessageBoxOnFailure())
{
Initialize();
}
//
// Restore the resources
//
AfxSetResourceHandle(hOldRes);
}
HRESULT
CInheritanceDlg::GetDataPaths()
/*++
Routine Description:
GetDataPaths()
Arguments:
None
Return Value:
HRESULT
--*/
{
//ASSERT(!m_strServer.IsEmpty());
CError err(m_mk.QueryResult());
if (err.Succeeded())
{
err = m_mk.GetDataPaths(
m_strlMetaChildNodes,
m_dwMDIdentifier,
m_dwMDDataType,
m_strMetaRoot
);
}
return err;
}
void
CInheritanceDlg::Initialize()
/*++
Routine Description:
Initialize data members. Set the m_fEmpty flag to determine if
it is necessary to proceed.
Arguments:
None
Return Value:
None
--*/
{
//{{AFX_DATA_INIT(CInheritanceDlg)
//}}AFX_DATA_INIT
CMetabasePath::CleanMetaPath(m_strMetaRoot);
if (m_fUseTable && !CMetaKey::IsPropertyInheritable(m_dwMDIdentifier))
{
//
// No point in displaying non-inheritable properties
//
return;
}
switch(m_dwMDIdentifier)
{
//
// Ignore these properties, even though they are inheritable
//
case MD_VR_PATH:
case MD_DOWNLEVEL_ADMIN_INSTANCE:
case MD_APP_ISOLATED:
case MD_APP_FRIENDLY_NAME:
return;
}
//
// Check to see if the current metabase path contains an instance
//
CString strTmp;
m_fHasInstanceInMaster = FriendlyInstance(m_strMetaRoot, strTmp);
//
// If property name was not specified in the constructor, load default
// one from table.
//
if (m_strPropertyName.IsEmpty())
{
ASSERT(m_fUseTable);
//
// Specify the resources to use
//
HINSTANCE hOldRes = AfxGetResourceHandle();
AfxSetResourceHandle(hDLLInstance);
VERIFY(CMetaKey::GetPropertyDescription(
m_dwMDIdentifier,
m_strPropertyName
));
AfxSetResourceHandle(hOldRes);
}
//
// Go through the list of metapaths, and clean them
// up.
//
POSITION pos = m_strlMetaChildNodes.GetHeadPosition();
while(pos)
{
CString & strMetaPath = m_strlMetaChildNodes.GetNext(pos);
CMetabasePath::CleanMetaPath(strMetaPath);
}
//
// If the special info key (lm/service/info) is in the list, remove it.
// We only need to this if the key that is getting the
// change (m_strMetaRoot) is the service master property (lm/service).
// If it is anything else, then the special "info" key cannot be below
// it so we don't need to check. Thus the first test is to see if there
// is only one "/" character. If there is only one, then we know it is
// the service and we can go ahead and do the test. In some ways,
// mfc is a pain, so we limited to the CString methods to do this
// copy the root into the temp string.
//
int iSlash = m_strMetaRoot.ReverseFind(SZ_MBN_SEP_CHAR);
if (iSlash >= 0)
{
strTmp = m_strMetaRoot.Left(iSlash);
//
// Now make sure that there aren't any more slashes
//
if (strTmp.Find(SZ_MBN_SEP_CHAR) == -1)
{
//
// Now build the path to the special info key by adding it
// to the meta root
//
strTmp = m_strMetaRoot + SZ_MBN_SEP_CHAR + IIS_MD_SVC_INFO_PATH;
TRACEEOLID("Removing any descendants of " << strTmp);
//
// Search the list for the info key and remove it if we find it
//
pos = m_strlMetaChildNodes.GetHeadPosition();
while(pos)
{
POSITION pos2 = pos;
CString & strMetaPath = m_strlMetaChildNodes.GetNext(pos);
TRACEEOLID("Checking " << strMetaPath);
if (strTmp.CompareNoCase(
strMetaPath.Left(strTmp.GetLength())) == 0)
{
TRACEEOLID("Removing service/info metapath from list");
m_strlMetaChildNodes.RemoveAt(pos2);
}
}
}
}
//
// Remove the first item if it's the current metapath
//
pos = m_strlMetaChildNodes.GetHeadPosition();
if (pos)
{
TRACEEOLID("Stripping " << m_strMetaRoot);
CString & strMetaPath = m_strlMetaChildNodes.GetAt(pos);
if (strMetaPath.CompareNoCase(m_strMetaRoot) == 0)
{
TRACEEOLID("Removing current metapath from list");
m_strlMetaChildNodes.RemoveHead();
}
}
m_fEmpty = m_strlMetaChildNodes.GetCount() == 0;
}
/* virtual */
INT_PTR
//int
CInheritanceDlg::DoModal()
/*++
Routine Description:
Display the dialog.
Arguments:
None
Return Value:
IDOK if the OK button was pressed, IDCANCEL otherwise.
--*/
{
//
// Specify the resources to use
//
HINSTANCE hOldRes = AfxGetResourceHandle();
AfxSetResourceHandle(hDLLInstance);
INT_PTR answer = CDialog::DoModal();
//
// restore the resources
//
AfxSetResourceHandle(hOldRes);
return answer;
}
void
CInheritanceDlg::DoDataExchange(
IN CDataExchange * pDX
)
/*++
Routine Description:
Initialise/Store control data
Arguments:
CDataExchange * pDX - DDX/DDV control structure
Return Value:
None
--*/
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInheritanceDlg)
DDX_Control(pDX, IDC_LIST_CHILD_NODES, m_list_ChildNodes);
//}}AFX_DATA_MAP
}
//
// Message Map
//
BEGIN_MESSAGE_MAP(CInheritanceDlg, CDialog)
//{{AFX_MSG_MAP(CInheritanceDlg)
ON_BN_CLICKED(IDC_BUTTON_SELECT_ALL, OnButtonSelectAll)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL
CInheritanceDlg::FriendlyInstance(
IN CString & strMetaRoot,
OUT CString & strFriendly
)
/*++
Routine Description:
Replace the instance number with its descriptive name.
Arguments:
CString & strMetaRoot : Metabase path
CString & strFriendly : Converted output friendly path.
Return Value:
TRUE if the path contained an instance number.
--*/
{
//
// Break into fields
//
// CODEWORK: make static like BuildMetaPath
//
LPCTSTR lp = _tcschr(strMetaRoot, SZ_MBN_SEP_CHAR); // lm
if (lp != NULL)
{
LPCTSTR lp2 = lp;
CString strService(++lp2);
lp = _tcschr(++lp, SZ_MBN_SEP_CHAR); // service name
if (lp == NULL)
{
//
// Master Instance (can never be a descendant)
//
//strFriendly = m_strWebMaster;
return FALSE;
}
else
{
strService.ReleaseBuffer(DIFF(lp - lp2));
}
TRACEEOLID(strService);
DWORD dwInstance = _ttol(++lp);
TRACEEOLID(dwInstance);
lp = _tcschr(lp, SZ_MBN_SEP_CHAR); // Instance #
if (lp != NULL)
{
lp = _tcschr(++lp, SZ_MBN_SEP_CHAR); // Skip "ROOT"
}
HRESULT hr = m_mk.Open(
METADATA_PERMISSION_READ,
CMetabasePath(strService, dwInstance)
);
if (SUCCEEDED(hr))
{
CString strComment;
hr = m_mk.QueryValue(MD_SERVER_COMMENT, strComment);
m_mk.Close();
if (FAILED(hr) || strComment.IsEmpty())
{
strFriendly.Format(
SZ_MBN_MACHINE SZ_MBN_SEP_STR _T("%s") SZ_MBN_SEP_STR _T("%d"),
(LPCTSTR)strService,
dwInstance
);
}
else
{
strFriendly.Format(
SZ_MBN_MACHINE SZ_MBN_SEP_STR _T("%s") SZ_MBN_SEP_STR _T("%s"),
(LPCTSTR)strService,
(LPCTSTR)strComment
);
}
TRACEEOLID(strFriendly);
//
// Append the rest of the path
//
if (lp != NULL)
{
strFriendly += lp;
}
return TRUE;
}
}
return FALSE;
}
CString &
CInheritanceDlg::CleanDescendantPath(
IN OUT CString & strMetaPath
)
/*++
Routine Description:
Clean the descendant metabase path. The path is shown
as a descendant of the current metabase root, and instance
numbers are replaced with their description names.
Arguments:
CString & strMetaPath : Metabase path to be treated
Return Value:
Reference to the cleaned-up path.
--*/
{
//
// This better be a descendant!
//
ASSERT(strMetaPath.GetLength() >= m_strMetaRoot.GetLength());
ASSERT(!::_tcsnicmp(strMetaPath, m_strMetaRoot, m_strMetaRoot.GetLength()));
// we do care only about something below LM
CString machine_path;
CMetabasePath::GetMachinePath(strMetaPath, machine_path);
if (machine_path.CompareNoCase(SZ_MBN_MACHINE) == 0)
{
if (!m_fHasInstanceInMaster)
{
//
// Need to replace the instance number with the friendly
// name.
//
CString strTmp;
VERIFY(FriendlyInstance(strMetaPath, strTmp));
strMetaPath = strTmp;
}
strMetaPath = strMetaPath.Mid(m_strMetaRoot.GetLength() + 1);
}
return strMetaPath;
}
//
// Message Handlers
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
BOOL
CInheritanceDlg::OnInitDialog()
/*++
Routine Description:
WM_INITDIALOG handler. Initialize the dialog.
Arguments:
None.
Return Value:
TRUE if focus is to be set automatically, FALSE if the focus
is already set.
--*/
{
CDialog::OnInitDialog();
//
// Get friendly name for the property, and set the text.
//
CString strPrompt;
CComBSTR bstrFmt;
VERIFY(bstrFmt.LoadString(hDLLInstance, IDS_INHERITANCE_PROMPT));
strPrompt.Format(bstrFmt, (LPCTSTR)m_strPropertyName);
GetDlgItem(IDC_STATIC_PROMPT)->SetWindowText(strPrompt);
//
// Turn inherited nodes into friendly paths, and add them
// to the listbox. Note the "current" node should have been
// deleted at this stage.
//
POSITION pos = m_strlMetaChildNodes.GetHeadPosition();
while(pos)
{
CString strNode = m_strlMetaChildNodes.GetNext(pos);
m_list_ChildNodes.AddString(CleanDescendantPath(strNode));
}
return TRUE;
}
void
CInheritanceDlg::OnButtonSelectAll()
/*++
Routine Description:
'Select All' button handler
Arguments:
None
Return Value:
None
--*/
{
//
// Select all entries
//
if (m_list_ChildNodes.GetCount() == 1)
{
//
// SelItemRange refuses to do a single member
//
m_list_ChildNodes.SetSel(0, TRUE);
}
else
{
m_list_ChildNodes.SelItemRange(
TRUE,
0,
m_list_ChildNodes.GetCount() - 1
);
}
}
void
CInheritanceDlg::OnOK()
/*++
Routine Description:
'OK' button handler
Arguments:
None
Return Value:
None
--*/
{
//
// Now delete the property for all selected child nodes.
// Grab from the orginal list, and not the listbox
// as the latter have been frienly-fied, and is no longer
// usable.
//
int cItems = m_list_ChildNodes.GetCount();
ASSERT(cItems > 0);
CString strMetaPath;
CError err(m_mk.QueryResult());
if (err.Succeeded())
{
int i = 0;
POSITION pos = m_strlMetaChildNodes.GetHeadPosition();
while(pos)
{
strMetaPath = m_strlMetaChildNodes.GetNext(pos);
if (m_list_ChildNodes.GetSel(i++) > 0)
{
TRACEEOLID("Deleting property on " << strMetaPath);
err = m_mk.Open(METADATA_PERMISSION_WRITE, strMetaPath);
if (err.Failed())
{
break;
}
err = m_mk.DeleteValue(m_dwMDIdentifier);
m_mk.Close();
if (err.Failed())
{
break;
}
}
}
}
if (!err.MessageBoxOnFailure())
{
//
// Dialog can be dismissed
//
CDialog::OnOK();
}
}