windows-nt/Source/XPSP1/NT/inetsrv/iis/admin/snapin/shts.cpp
2020-09-26 16:20:57 +08:00

771 lines
12 KiB
C++

/*++
Copyright (c) 1994-1999 Microsoft Corporation
Module Name :
shts.cpp
Abstract:
IIS Property sheet classes
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager (cluster edition)
Revision History:
--*/
#include "stdafx.h"
#include "common.h"
#include "inetprop.h"
#include "InetMgrApp.h"
#include "shts.h"
#include "mime.h"
#include "iisobj.h"
#include "shutdown.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
//
// CInetPropertySheet class
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IMPLEMENT_DYNAMIC(CInetPropertySheet, CPropertySheet)
CInetPropertySheet::CInetPropertySheet(
CComAuthInfo * pAuthInfo,
LPCTSTR lpszMetaPath,
CWnd * pParentWnd,
LPARAM lParam,
LONG_PTR handle,
UINT iSelectPage
)
/*++
Routine Description:
IIS Property Sheet constructor
Arguments:
CComAuthInfo * pAuthInfo : Authentication information
LPCTSTR lpszMetPath : Metabase path
CWnd * pParentWnd : Optional parent window
LPARAM lParam : MMC Console parameter
LONG_PTR handle : MMC Console handle
UINT iSelectPage : Initial page to be selected
Return Value:
N/A
--*/
: CPropertySheet(_T(""), pParentWnd, iSelectPage),
m_auth(pAuthInfo),
m_strMetaPath(lpszMetaPath),
m_dwInstance(0L),
m_bModeless(FALSE),
m_hConsole(handle),
m_lParam(lParam),
m_fHasAdminAccess(TRUE), // Assumed by default
m_pCap(NULL),
m_refcount(0),
m_fRestartRequired(FALSE),
m_fChanged(FALSE)
{
m_fIsMasterPath = CMetabasePath::IsMasterInstance(lpszMetaPath);
TRACEEOLID("Metabase path is master? " << m_fIsMasterPath);
}
void
CInetPropertySheet::NotifyMMC()
/*++
Routine Description:
Notify MMC that changes have been made, so that the changes are
reflected.
Arguments:
None
Return Value:
None
--*/
{
//
// Notify MMC to update changes.
//
if (m_hConsole != NULL)
{
ASSERT(m_lParam != 0L);
MMCPropertyChangeNotify(m_hConsole, m_lParam);
}
}
CInetPropertySheet::~CInetPropertySheet()
/*++
Routine Description:
IIS Property Sheet destructor
Arguments:
N/A
Return Value:
N/A
--*/
{
// At this moment we should have in m_pages only pages that were not activated
// in this session.
while (!m_pages.IsEmpty())
{
CInetPropertyPage * pPage = m_pages.RemoveHead();
delete pPage;
}
if (m_fChanged)
{
NotifyMMC();
}
if (m_hConsole != NULL)
{
MMCFreeNotifyHandle(m_hConsole);
}
}
void
CInetPropertySheet::AttachPage(CInetPropertyPage * pPage)
{
m_pages.AddTail(pPage);
}
void
CInetPropertySheet::DetachPage(CInetPropertyPage * pPage)
{
POSITION pos = m_pages.Find(pPage);
ASSERT(pos != NULL);
if (pos != NULL)
{
m_fChanged |= pPage->IsDirty();
m_pages.RemoveAt(pos);
}
}
WORD
CInetPropertySheet::QueryMajorVersion() const
{
CIISMBNode * pNode = (CIISMBNode *)m_lParam;
ASSERT(pNode != NULL);
return pNode->QueryMajorVersion();
}
WORD
CInetPropertySheet::QueryMinorVersion() const
{
CIISMBNode * pNode = (CIISMBNode *)m_lParam;
ASSERT(pNode != NULL);
return pNode->QueryMinorVersion();
}
/* virtual */
HRESULT
CInetPropertySheet::LoadConfigurationParameters()
/*++
Routine Description:
Load configuration parameters information
Arguments:
None
Return Value:
HRESULT
--*/
{
//
// Load base values
//
CError err;
if (m_pCap == NULL)
{
TRACEEOLID("Determining path locations for " << m_strMetaPath);
//
// Capability info stored off the service path ("lm/w3svc").
//
ASSERT(m_strInfoPath.IsEmpty());
//
// Building path components
//
CMetabasePath::GetServiceInfoPath(m_strMetaPath, m_strInfoPath);
TRACEEOLID("Storing info path: " << m_strInfoPath);
//
// Split into instance and directory paths
//
if (IsMasterInstance())
{
m_strServicePath = m_strInstancePath = QueryMetaPath();
}
else
{
VERIFY(CMetabasePath::GetInstancePath(
QueryMetaPath(),
m_strInstancePath,
&m_strDirectoryPath
));
VERIFY(CMetabasePath::GetServicePath(
QueryMetaPath(),
m_strServicePath
));
}
TRACEEOLID("Service path " << m_strServicePath);
TRACEEOLID("Instance path " << m_strInstancePath);
if (m_strDirectoryPath.IsEmpty() && !IsMasterInstance())
{
m_strDirectoryPath = CMetabasePath(FALSE, QueryMetaPath(), g_cszRoot);
}
else
{
m_strDirectoryPath = QueryMetaPath();
}
TRACEEOLID("Directory path " << m_strDirectoryPath);
m_dwInstance = CMetabasePath::GetInstanceNumber(m_strMetaPath);
TRACEEOLID("Instance number " << m_dwInstance);
m_pCap = new CServerCapabilities(QueryAuthInfo(), m_strInfoPath);
if (!m_pCap)
{
err = ERROR_NOT_ENOUGH_MEMORY;
return err;
}
err = m_pCap->LoadData();
if (err.Succeeded())
{
err = DetermineAdminAccess();
}
}
return err;
}
/* virtual */
void
CInetPropertySheet::FreeConfigurationParameters()
/*++
Routine Description:
Clean up configuration data
Arguments:
None
Return Value:
None
--*/
{
// ASSERT_PTR(m_pCap);
SAFE_DELETE(m_pCap);
}
void
CInetPropertySheet::WinHelp(
IN DWORD dwData,
IN UINT nCmd
)
/*++
Routine Description:
WinHelp override. We can't use the base class, because our
'sheet' doesn't usually have a window handle
Arguments:
DWORD dwData : Help data
UINT nCmd : Help command
Return Value:
None
--*/
{
#ifdef _DEBUG
TCHAR szBuffer[20];
_stprintf(szBuffer,_T("WinHelp:0x%x\n"),dwData);OutputDebugString(szBuffer);
#endif
if (m_hWnd == NULL)
{
/*
//
// Special case
//
::WinHelp(
HWND hWndMain,
LPCWSTR lpszHelp,
UINT uCommand,
DWORD dwData
);
*/
CWnd * pWnd = ::AfxGetMainWnd();
if (pWnd != NULL)
{
pWnd->WinHelp(dwData, nCmd);
}
return;
}
CPropertySheet::WinHelp(dwData, nCmd);
}
//
// Message Map
//
BEGIN_MESSAGE_MAP(CInetPropertySheet, CPropertySheet)
//{{AFX_MSG_MAP(CInetPropertySheet)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// CInetPropertyPage class
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//
// CInetPropertyPage property page
//
IMPLEMENT_DYNAMIC(CInetPropertyPage, CPropertyPage)
#ifdef _DEBUG
/* virtual */
void
CInetPropertyPage::AssertValid() const
{
}
/* virtual */
void
CInetPropertyPage::Dump(CDumpContext& dc) const
{
}
#endif // _DEBUG
CInetPropertyPage::CInetPropertyPage(
IN UINT nIDTemplate,
IN CInetPropertySheet * pSheet,
IN UINT nIDCaption,
IN BOOL fEnableEnhancedFonts OPTIONAL
)
/*++
Routine Description:
IIS Property Page Constructor
Arguments:
UINT nIDTemplate : Resource template
CInetPropertySheet * pSheet : Associated property sheet
UINT nIDCaption : Caption ID
BOOL fEnableEnhancedFonts : Enable enhanced fonts
Return Value:
N/A
--*/
: CPropertyPage(nIDTemplate, nIDCaption),
m_nHelpContext(nIDTemplate + 0x20000),
m_fEnableEnhancedFonts(fEnableEnhancedFonts),
m_bChanged(FALSE),
m_pSheet(pSheet)
{
//{{AFX_DATA_INIT(CInetPropertyPage)
//}}AFX_DATA_INIT
m_psp.dwFlags |= PSP_HASHELP;
ASSERT(m_pSheet != NULL);
m_pSheet->AttachPage(this);
}
CInetPropertyPage::~CInetPropertyPage()
/*++
Routine Description:
IIS Property Page Destructor
Arguments:
N/A
Return Value:
N/A
--*/
{
}
void
CInetPropertyPage::DoDataExchange(
IN CDataExchange * pDX
)
/*++
Routine Description:
Initialise/Store control data
Arguments:
CDataExchange * pDX - DDX/DDV control structure
Return Value:
None
--*/
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInetPropertyPage)
//}}AFX_DATA_MAP
}
/* virtual */
void
CInetPropertyPage::PostNcDestroy()
/*++
Routine Description:
handle destruction of the window by freeing the this
pointer (as this modeless dialog must have been created
on the heap)
Arguments:
None.
Return Value:
None
--*/
{
m_pSheet->Release(this);
delete this;
}
//
// Message Map
//
BEGIN_MESSAGE_MAP(CInetPropertyPage, CPropertyPage)
//{{AFX_MSG_MAP(CInetPropertyPage)
ON_COMMAND(ID_HELP, OnHelp)
ON_WM_HELPINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// Message Handlers
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/* virtual */
BOOL
CInetPropertyPage::OnInitDialog()
/*++
Routine Description:
WM_INITDIALOG handler. Initialize the dialog. Reset changed
status (sometimes gets set by e.g. spinboxes when the dialog is
constructed), so make sure the dialog is considered clean.
Arguments:
None
Return Value:
TRUE if no focus is to be set automatically, FALSE if the focus
is already set.
--*/
{
m_bChanged = FALSE;
//
// Tell derived class to load its configuration parameters
//
CError err(LoadConfigurationParameters());
if (err.Succeeded())
{
err = FetchLoadedValues();
}
BOOL bResult = CPropertyPage::OnInitDialog();
err.MessageBoxOnFailure();
if (m_fEnableEnhancedFonts)
{
CFont * pFont = &m_fontBold;
if (CreateSpecialDialogFont(this, pFont))
{
ApplyFontToControls(this, pFont, IDC_ED_BOLD1, IDC_ED_BOLD5);
}
}
// We should call AddRef here, not in page constructor, because PostNCDestroy()
// is getting called only for pages that were activated, not for all created pages.
// OnInitDialog is also called for activated pages only -- so we will get parity
// and delete property sheet.
//
ASSERT(m_pSheet != NULL);
m_pSheet->AddRef();
return bResult;
}
void
CInetPropertyPage::OnHelp()
/*++
Routine Description:
'Help' button handler
Arguments:
None
Return Value:
None
--*/
{
ASSERT_PTR(m_pSheet);
#ifdef _DEBUG
TCHAR szBuffer[20];
_stprintf(szBuffer,_T("WinHelp:0x%x\n"),m_nHelpContext);OutputDebugString(szBuffer);
#endif
m_pSheet->WinHelp(m_nHelpContext);
}
BOOL
CInetPropertyPage::OnHelpInfo(
IN HELPINFO * pHelpInfo
)
/*++
Routine Description:
Eat "help info" command
Arguments:
None
Return Value:
None
--*/
{
OnHelp();
return TRUE;
}
BOOL
CInetPropertyPage::OnApply()
/*++
Routine Description:
Handle "OK" or "APPLY". Call the derived class to save its stuff,
and set the dirty state depending on whether saving succeeded or
failed.
Arguments:
None
Return Value:
None
--*/
{
BOOL bSuccess = TRUE;
if (IsDirty())
{
CError err(SaveInfo());
if (err.MessageBoxOnFailure())
{
//
// Failed, sheet will not be dismissed.
//
// CODEWORK: This page should be activated.
//
bSuccess = FALSE;
}
SetModified(!bSuccess);
if (bSuccess && GetSheet()->RestartRequired())
{
// ask user about immediate restart
if (IDYES == ::AfxMessageBox(IDS_ASK_TO_RESTART, MB_YESNO | MB_ICONQUESTION))
{
// restart IIS
CIISMachine * pMachine = new CIISMachine(QueryAuthInfo());
if (pMachine != NULL)
{
CIISShutdownDlg dlg(pMachine, this);
dlg.PerformCommand(ISC_RESTART);
bSuccess = dlg.ServicesWereRestarted();
delete pMachine;
}
}
// mark restart required false to suppress it on other pages
GetSheet()->SetRestartRequired(FALSE);
}
}
return bSuccess;
}
void
CInetPropertyPage::SetModified(
IN BOOL bChanged
)
/*++
Routine Description:
Keep private check on dirty state of the property page.
Arguments:
BOOL bChanged : Dirty flag
Return Value:
None
--*/
{
CPropertyPage::SetModified(bChanged);
m_bChanged = bChanged;
}