771 lines
12 KiB
C++
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;
|
|
}
|
|
|
|
|