|
|
/*++
Copyright (c) 1994-1998 Microsoft Corporation
Module Name :
w3scfg.h
Abstract:
WWW Configuration Module
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "wincrypt.h"
#include <process.h>
#include <afxtempl.h>
#include "w3scfg.h"
#include "w3servic.h"
#include "w3accts.h"
#include "vdir.h"
#include "perform.h"
#include "docum.h"
#include "security.h"
#include "httppage.h"
#include "defws.h"
#include "fltdlg.h"
#include "filters.h"
#include "errors.h"
#include "wizard.h"
#include "iisfilt.h"
#include "..\mmc\constr.h"
#define CDELETE(x) {if (x != NULL) delete x;}
//
// Standard configuration Information
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#define SVC_ID INET_HTTP_SVC_ID
//
// Is this server discoverable by INETSLOC?
//
#define INETSLOC_DISCOVERY TRUE
#if (INETSLOC_DISCOVERY) && !defined(_SVCLOC_)
#error You must include svcloc.h.
#endif
//
// If INETSLOC_DISCOVERY == TRUE, define the discovery MASK here.
//
#if (INETSLOC_DISCOVERY)
#define INETSLOC_MASK INET_W3_SVCLOC_ID
#else // (!INETSLOC_DISCOVERY)
#define INETSLOC_MASK (ULONGLONG)(0x00000000)
#endif // (INETSLOC_DISCOVERY)
#ifdef NO_SERVICE_CONTROLLER
#define CAN_CHANGE_SERVICE_STATE FALSE
#define CAN_PAUSE_SERVICE FALSE
#else
//
// Can we change the service state (start/pause/continue)?
//
#define CAN_CHANGE_SERVICE_STATE TRUE
//
// Can we pause this service?
//
#define CAN_PAUSE_SERVICE TRUE
#endif // NO_SERVICE_CONTROLLER
//
// Name used for this service by the service controller manager.
//
#define SERVICE_SC_NAME _T("W3Svc")
//
// Longer name. This is the text that shows up in
// the tooltips text on the internet manager
// tool. This probably should be localised.
//
#define SERVICE_LONG_NAME _T("Web Service")
//
// Web browser protocol name. e.g. xxxxx://address
// A blank string if this is not supported.
//
#define SERVICE_PROTOCOL _T("http")
//
// Use normal colour mapping.
//
#define NORMAL_TB_MAPPING TRUE
//
// Toolbar button background mask. This is
// the colour that gets masked out in
// the bitmap file and replaced with the
// actual button background. This setting
// is automatically assumed to be lt. gray
// if NORMAL_TB_MAPPING (above) is TRUE
//
#define BUTTON_BMP_BACKGROUND RGB(192, 192, 192) // Lt. Gray
//
// Resource ID of the toolbar button bitmap.
//
// The bitmap must be 16x16
//
#define BUTTON_BMP_ID IDB_WWW
//
// Similar to BUTTON_BMP_BACKGROUND, this is the
// background mask for the service ID
//
#define SERVICE_BMP_BACKGROUND RGB(255, 0, 255) // Magenta
//
// Bitmap id which is used in the service view
// of the service manager. It may be the same
// bitmap as the BUTTON_BMP_ID bitmap.
//
// The bitmap must be 16x16.
//
#define SERVICE_BMP_ID IDB_WWW
//
// /* K2 */
//
// Similar to BUTTON_BMP_BACKGROUND, this is the
// background mask for the child bitmap
//
#define CHILD_BMP_BACKGROUND RGB(255, 0, 255) // Magenta
//
// /* K2 */
//
// Bitmap id which is used for the child
//
// The bitmap must be 16x16
//
#define CHILD_BMP_ID IDB_WWWVDIR
//
// Large child bitmap ID
//
#define CHILD_BMP32_ID IDB_WWWVDIR32
//
// /* K2 */
//
// Large bitmap (32x32) id
//
#define SERVICE_BMP32_ID IDB_WWW32
//
// Help IDs
//
#define HIDD_DIRECTORY_PROPERTIES (0x207DB)
#define HIDD_HOME_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20000)
#define HIDD_FS_DIRECTORY_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20001)
#define HIDD_FS_FILE_PROPERTIES (HIDD_DIRECTORY_PROPERTIES + 0x20002)
//
// Metabase node ID
//
const LPCTSTR g_cszSvc = _T("W3SVC"); const LPCTSTR g_cszFilters = _T("Filters"); const LPCTSTR g_cszSSLKeys = _T("SSLKeys");
//
// End Of Standard configuration Information
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CW3InstanceProps::CW3InstanceProps( IN LPCTSTR lpszServerName, IN DWORD dwInstance OPTIONAL ) /*++
Routine Description:
Constructor for WWW instance properties
Arguments:
LPCTSTR lpszServerName : Server name DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
Return Value:
None.
--*/ : CInstanceProps(lpszServerName, g_cszSvc, dwInstance, 80U), /**/ m_nMaxConnections(INITIAL_MAX_CONNECTIONS), m_nConnectionTimeOut((LONG)900L), m_strlSecureBindings(), m_dwLogType(MD_LOG_TYPE_DISABLED), /**/ m_fUseKeepAlives(TRUE), m_fEnableCPUAccounting(FALSE), m_nServerSize(MD_SERVER_SIZE_MEDIUM), m_nMaxNetworkUse(INFINITE_BANDWIDTH), /**/ m_dwCPULimitLogEventRaw(INFINITE_CPU_RAW), m_dwCPULimitPriorityRaw(0), m_dwCPULimitPauseRaw(0), m_dwCPULimitProcStopRaw(0), /**/ m_acl(), /**/ m_dwDownlevelInstance(1), m_CertHash() { //
// Fetch everything
//
m_dwMDUserType = ALL_METADATA; m_dwMDDataType = ALL_METADATA; }
/* virtual */ void CW3InstanceProps::ParseFields() /*++
Routine Description:
Break into fields.
Arguments:
None.
Return Value:
None.
--*/ { //
// Fetch base properties
//
CInstanceProps::ParseFields();
BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData) //
// Service Page
//
HANDLE_META_RECORD(MD_MAX_CONNECTIONS, m_nMaxConnections) HANDLE_META_RECORD(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut) HANDLE_META_RECORD(MD_SECURE_BINDINGS, m_strlSecureBindings) HANDLE_META_RECORD(MD_LOG_TYPE, m_dwLogType) //
// Performance Page
//
HANDLE_META_RECORD(MD_SERVER_SIZE, m_nServerSize) HANDLE_META_RECORD(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives) HANDLE_META_RECORD(MD_MAX_BANDWIDTH, m_nMaxNetworkUse) HANDLE_META_RECORD(MD_CPU_LIMITS_ENABLED, m_fEnableCPUAccounting) HANDLE_META_RECORD(MD_CPU_LIMIT_LOGEVENT, m_dwCPULimitLogEventRaw) HANDLE_META_RECORD(MD_CPU_LIMIT_PRIORITY, m_dwCPULimitPriorityRaw) HANDLE_META_RECORD(MD_CPU_LIMIT_PAUSE, m_dwCPULimitPauseRaw) HANDLE_META_RECORD(MD_CPU_LIMIT_PROCSTOP, m_dwCPULimitProcStopRaw) //
// Operators Page
//
HANDLE_META_RECORD(MD_ADMIN_ACL, m_acl)
//
// Certificate and CTL information
//
HANDLE_META_RECORD(MD_SSL_CERT_HASH, m_CertHash) HANDLE_META_RECORD(MD_SSL_CERT_STORE_NAME, m_strCertStoreName) HANDLE_META_RECORD(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier) HANDLE_META_RECORD(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName) END_PARSE_META_RECORDS }
/* virtual */ HRESULT CW3InstanceProps::WriteDirtyProps() /*++
Routine Description:
Write the dirty properties to the metabase
Arguments:
None
Return Value:
HRESULT
--*/ { CError err(CInstanceProps::WriteDirtyProps());
if (err.Failed()) { return err; }
BEGIN_META_WRITE() //
// Service Page
//
META_WRITE(MD_MAX_CONNECTIONS, m_nMaxConnections) META_WRITE(MD_CONNECTION_TIMEOUT, m_nConnectionTimeOut) META_WRITE(MD_SECURE_BINDINGS, m_strlSecureBindings) META_WRITE(MD_LOG_TYPE, m_dwLogType) //
// Performance Page
//
META_WRITE(MD_SERVER_SIZE, m_nServerSize) META_WRITE(MD_ALLOW_KEEPALIVES, m_fUseKeepAlives) META_WRITE(MD_MAX_BANDWIDTH, m_nMaxNetworkUse) META_WRITE(MD_CPU_LIMITS_ENABLED, m_fEnableCPUAccounting) META_WRITE(MD_CPU_LIMIT_LOGEVENT, m_dwCPULimitLogEventRaw) META_WRITE(MD_CPU_LIMIT_PRIORITY, m_dwCPULimitPriorityRaw) META_WRITE(MD_CPU_LIMIT_PAUSE, m_dwCPULimitPauseRaw) META_WRITE(MD_CPU_LIMIT_PROCSTOP, m_dwCPULimitProcStopRaw) //
// Operators Page
//
META_WRITE(MD_ADMIN_ACL, m_acl)
//
// Certificate and CTL information
//
//META_WRITE(MD_SSL_CERT_HASH, m_CertHash)
//META_WRITE(MD_SSL_CERT_STORE_NAME, m_strCertStoreName)
META_WRITE(MD_SSL_CTL_IDENTIFIER, m_strCTLIdentifier) META_WRITE(MD_SSL_CTL_STORE_NAME, m_strCTLStoreName) END_META_WRITE(err);
return err; }
CW3DirProps::CW3DirProps( IN LPCTSTR lpszServerName, IN DWORD dwInstance, OPTIONAL IN LPCTSTR lpszParent, OPTIONAL IN LPCTSTR lpszAlias OPTIONAL ) /*++
Routine Description:
WWW Directory Properties Constructor
Arguments:
LPCTSTR lpszServerName : Server Name DWORD dwInstance : Instance number (could be MASTER_INSTANCE) LPCTSTR lpszParent : Parent path (could be NULL or "") LPCTSTR lpszAlias : Alias name (could be NULL or "")
--*/ : CChildNodeProps( lpszServerName, g_cszSvc, dwInstance, lpszParent, lpszAlias, WITH_INHERITANCE, FALSE // Full information
), /**/ m_strUserName(), m_strPassword(), m_strDefaultDocument(), m_strFooter(), m_dwDirBrowsing(0L), m_fEnableFooter(FALSE), m_fDontLog(FALSE), m_fIndexed(FALSE), /**/ m_strExpiration(), m_strlCustomHeaders(), /**/ m_strlCustomErrors(), /**/ m_strAnonUserName(), m_strAnonPassword(), m_fPasswordSync(TRUE), m_fU2Installed(FALSE), m_fUseNTMapper(FALSE), m_dwAuthFlags(MD_AUTH_ANONYMOUS), m_dwSSLAccessPermissions(0L), m_strBasicDomain(), m_ipl() { //
// Fetch everything
//
m_dwMDUserType = ALL_METADATA; m_dwMDDataType = ALL_METADATA; }
/* virtual */ void CW3DirProps::ParseFields() /*++
Routine Description:
Break into fields.
Arguments:
None.
Return Value:
None.
--*/ { //
// Fetch base properties
//
CChildNodeProps::ParseFields();
BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData) //
// VDir Page
//
HANDLE_META_RECORD(MD_VR_USERNAME, m_strUserName) HANDLE_META_RECORD(MD_VR_PASSWORD, m_strPassword) HANDLE_META_RECORD(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument); HANDLE_META_RECORD(MD_FOOTER_ENABLED, m_fEnableFooter); HANDLE_META_RECORD(MD_FOOTER_DOCUMENT, m_strFooter); HANDLE_META_RECORD(MD_DIRECTORY_BROWSING, m_dwDirBrowsing); HANDLE_META_RECORD(MD_DONT_LOG, m_fDontLog); HANDLE_META_RECORD(MD_IS_CONTENT_INDEXED, m_fIndexed); //
// HTTP Page
//
HANDLE_META_RECORD(MD_HTTP_EXPIRES, m_strExpiration); HANDLE_META_RECORD(MD_HTTP_CUSTOM, m_strlCustomHeaders); //
// Custom Errors
//
HANDLE_META_RECORD(MD_CUSTOM_ERROR, m_strlCustomErrors); //
// Security page
//
HANDLE_META_RECORD(MD_AUTHORIZATION, m_dwAuthFlags); HANDLE_META_RECORD(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions); HANDLE_META_RECORD(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain); HANDLE_META_RECORD(MD_ANONYMOUS_USER_NAME, m_strAnonUserName) HANDLE_META_RECORD(MD_ANONYMOUS_PWD, m_strAnonPassword) HANDLE_META_RECORD(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync) HANDLE_META_RECORD(MD_U2_AUTH, m_fU2Installed) HANDLE_META_RECORD(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper); HANDLE_META_RECORD(MD_IP_SEC, m_ipl); END_PARSE_META_RECORDS }
/* virtual */ HRESULT CW3DirProps::WriteDirtyProps() /*++
Routine Description:
Write the dirty properties to the metabase
Arguments:
None
Return Value:
HRESULT
--*/ { CError err(CChildNodeProps::WriteDirtyProps());
if (err.Failed()) { return err; }
//
// CODEWORK: Consider DDX/DDV like methods which do both
// ParseFields and WriteDirtyProps in a single method. Must
// take care not to write data which should only be read, not
// written
//
BEGIN_META_WRITE() //
// VDir Page
//
META_WRITE(MD_VR_USERNAME, m_strUserName) META_WRITE(MD_VR_PASSWORD, m_strPassword) META_WRITE(MD_DEFAULT_LOAD_FILE, m_strDefaultDocument) META_WRITE(MD_FOOTER_ENABLED, m_fEnableFooter) META_WRITE(MD_FOOTER_DOCUMENT, m_strFooter) META_WRITE(MD_DIRECTORY_BROWSING, m_dwDirBrowsing) META_WRITE(MD_DONT_LOG, m_fDontLog) META_WRITE(MD_IS_CONTENT_INDEXED, m_fIndexed) //
// HTTP Page
//
META_WRITE(MD_HTTP_EXPIRES, m_strExpiration) META_WRITE(MD_HTTP_CUSTOM, m_strlCustomHeaders) //
// Custom Errors
//
META_WRITE(MD_CUSTOM_ERROR, m_strlCustomErrors) //
// Security page
//
META_WRITE(MD_AUTHORIZATION, m_dwAuthFlags) META_WRITE(MD_SSL_ACCESS_PERM, m_dwSSLAccessPermissions) META_WRITE(MD_DEFAULT_LOGON_DOMAIN, m_strBasicDomain) META_WRITE(MD_ANONYMOUS_USER_NAME, m_strAnonUserName) META_WRITE(MD_ANONYMOUS_PWD, m_strAnonPassword) META_WRITE(MD_ANONYMOUS_USE_SUBAUTH, m_fPasswordSync) META_WRITE(MD_SSL_USE_DS_MAPPER, m_fUseNTMapper) META_WRITE(MD_IP_SEC, m_ipl) END_META_WRITE(err);
return err; }
CIISFilter::CIISFilter() /*++
Routine Description:
Filter contructor for a new filter
Arguments:
None
Return Value:
N/A
--*/ : CObjectPlus(), m_strName(),
//
// Default Values
//
m_strExecutable(), m_nPriority(FLTR_PR_INVALID), m_nOrder(-1), m_dwState(MD_FILTER_STATE_UNLOADED), m_dwFlags(0L), m_hrResult(S_OK), m_dwWin32Error(ERROR_SUCCESS), m_fEnabled(TRUE), m_fDirty(FALSE), m_fFlaggedForDeletion(FALSE) { }
CIISFilter::CIISFilter( IN CMetaKey * pKey, IN LPCTSTR lpszName ) /*++
Routine Description:
Fully defined constructor
Arguments:
CMetaKey * pKey : Open key to read from LPCTSTR lpszName : Name of the filter
Return Value:
N/A
--*/ : m_strName(lpszName), //
// Default Values
//
m_strExecutable(), m_nPriority(FLTR_PR_INVALID), m_nOrder(-1), m_dwState(MD_FILTER_STATE_UNLOADED), m_dwFlags(0L), m_hrResult(S_OK), m_dwWin32Error(ERROR_SUCCESS), m_fEnabled(TRUE), m_fDirty(FALSE), m_fFlaggedForDeletion(FALSE) { ASSERT(pKey != NULL);
m_hrResult = pKey->QueryValue( MD_FILTER_IMAGE_PATH, m_strExecutable, NULL, m_strName );
pKey->QueryValue(MD_FILTER_ENABLED, m_fEnabled, NULL, m_strName); pKey->QueryValue(MD_FILTER_STATE, m_dwState, NULL, m_strName); pKey->QueryValue(MD_FILTER_FLAGS, m_dwFlags, NULL, m_strName); if (m_dwFlags & SF_NOTIFY_ORDER_HIGH) { m_nPriority = FLTR_PR_HIGH; } else if (m_dwFlags & SF_NOTIFY_ORDER_MEDIUM) { m_nPriority = FLTR_PR_MEDIUM; } else if (m_dwFlags & SF_NOTIFY_ORDER_LOW) { m_nPriority = FLTR_PR_LOW; } else { m_nPriority = FLTR_PR_INVALID; } }
CIISFilter::CIISFilter( IN const CIISFilter & flt ) /*++
Routine Description:
Copy Constructor
Arguments:
const CIISFilter & flt : Source filter object
Return Value:
N/A
--*/ : m_strName(flt.m_strName), m_strExecutable(flt.m_strExecutable), m_nPriority(flt.m_nPriority), m_nOrder(flt.m_nOrder), m_hrResult(flt.m_hrResult), m_dwState(flt.m_dwState), m_dwFlags(flt.m_dwFlags), m_dwWin32Error(flt.m_dwWin32Error), m_fEnabled(flt.m_fEnabled), m_fDirty(FALSE), m_fFlaggedForDeletion(FALSE) { }
HRESULT CIISFilter::Write( IN CMetaKey * pKey ) /*++
Routine Description:
Write the current value to the metabase
Arguments:
CMetaKey * pKey : Open key
Return Value:
HRESULT
--*/ { ASSERT(pKey != NULL);
CError err;
CString strKey(_T("IIsFilter")); err = pKey->SetValue(MD_KEY_TYPE, strKey, NULL, QueryName());
if (err.Succeeded()) { err = pKey->SetValue( MD_FILTER_IMAGE_PATH, m_strExecutable, NULL, QueryName() ); }
return err; }
int CIISFilter::OrderByPriority( IN const CObjectPlus * pobAccess ) const /*++
Routine Description:
Compare two filters against each other, and sort on priority first, and order secondarily.
Arguments:
const CObjectPlus * pobAccess : This really refers to another CIISFilter to be compared to.
Return Value:
Sort (+1, 0, -1) return value
--*/ { const CIISFilter * pob = (CIISFilter *)pobAccess;
if (pob->m_nPriority != m_nPriority) { return pob->m_nPriority - m_nPriority; }
//
// Sort by order in reverse order
//
return m_nOrder - pob->m_nOrder; }
//
// Static initialization
//
const LPCTSTR CIISFilterList::s_lpszSep = _T(",");
CIISFilterList::CIISFilterList( IN LPCTSTR lpszServerName, IN LPCTSTR lpszService, IN DWORD dwInstance OPTIONAL ) /*++
Routine Description:
Constructor for filter list
Arguments:
LPCTSTR lpszServerName : Server name DWORD dwInstance : Instance number (could be MASTER_INSTANCE)
Return Value:
N/A
--*/ : CMetaKey( lpszServerName, METADATA_PERMISSION_READ, lpszService, dwInstance, g_cszFilters ), m_dwInstance(dwInstance), m_hrResult(S_OK), //
// Default properties
//
m_strFilterOrder(), m_fFiltersLoaded(FALSE) { m_hrResult = CMetaKey::QueryResult();
if (SUCCEEDED(m_hrResult)) { m_hrResult = QueryValue(MD_FILTER_LOAD_ORDER, m_strFilterOrder); } if (m_hrResult == CError::HResult(ERROR_PATH_NOT_FOUND)) { //
// Harmless
//
m_hrResult = S_OK; }
if (IsOpen()) { Close(); } }
HRESULT CIISFilterList::LoadAllFilters() /*++
Routine Description:
Loop through the filter order string, and load information about each filter in turn.
Arguments:
None.
Return Value:
HRESULT. The first error stops filter loading.
--*/ { ASSERT(SUCCEEDED(m_hrResult));
if (m_fFiltersLoaded) { //
// Already done
//
return S_OK; }
int cItems = 0; CError err(ReOpen(METADATA_PERMISSION_READ));
if (err.Failed()) { return err; }
try { CString strSrc(m_strFilterOrder); LPTSTR lp = strSrc.GetBuffer(0); lp = StringTok(lp, s_lpszSep);
int nOrder = 0;
while (lp) { CString str(lp); str.TrimLeft(); str.TrimRight();
TRACEEOLID("Adding filter: " << str);
CIISFilter * pFilter = new CIISFilter(this, str); err = pFilter->QueryResult();
if (err.Failed()) { break; }
pFilter->m_nOrder = nOrder++; m_oblFilters.AddTail(pFilter);
lp = StringTok(NULL, s_lpszSep); ++cItems; }
//
// Sort filters list
//
m_oblFilters.Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) &CIISFilter::OrderByPriority ); } catch(CMemoryException * e) { e->Delete(); err = ERROR_NOT_ENOUGH_MEMORY; }
m_fFiltersLoaded = err.Succeeded();
if (IsOpen()) { Close(); }
return err; }
HRESULT CIISFilterList::WriteIfDirty() /*++
Routine Description:
Write all the changes in the filters list to the metabase
Arguments:
None.
Return Value:
HRESULT
--*/ { CError err;
CString strNewOrder; VERIFY(BuildFilterOrderString(strNewOrder));
//
// Check to see if this new list is different
//
if (!strNewOrder.CompareNoCase(m_strFilterOrder) && !HasDirtyFilter()) { //
// The priority list hasn't changed, and no filter is marked
// as dirty, so all done.
//
return err; }
//
// It's dirty -- save it
//
do { err = ReOpen(METADATA_PERMISSION_WRITE);
if (err.Failed()) { if (err.Win32Error() == ERROR_PATH_NOT_FOUND) { //
// Path didn't exist yet, create it and reopen
// it.
//
err = CreatePathFromFailedOpen();
if (err.Succeeded()) { err = ReOpen(METADATA_PERMISSION_WRITE); } }
if (err.Failed()) { break; } }
//
// Delete deleted filters
//
POSITION pos1, pos2;
for (pos1 = m_oblFilters.GetHeadPosition(); (pos2 = pos1) != NULL; ) { CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos1); ASSERT(pFilter != NULL);
if (pFilter->IsFlaggedForDeletion()) { TRACEEOLID("Deleting filter " << pFilter->QueryName()); err = DeleteKey(pFilter->QueryName());
if (err.Failed()) { break; }
m_oblFilters.RemoveAt(pos2); } }
if (err.Failed()) { break; }
//
// Two passes are necessary, because the filter may
// have been re-added after it was deleted from the
// list as new entry. This could be somewhat improved
//
ResetEnumerator();
while(MoreFilters()) { CIISFilter * pFilter = GetNextFilter(); ASSERT(pFilter != NULL);
if (pFilter->IsDirty()) { TRACEEOLID("Writing filter " << pFilter->QueryName()); err = pFilter->Write(this);
if (err.Failed()) { break; }
pFilter->Dirty(FALSE); } }
if (err.Failed()) { break; }
//
// Write the new filter load order
//
err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
if (err.Failed()) { break; }
CString strKey(_T("IIsFilters")); err = SetValue(MD_KEY_TYPE, strKey); err = SetValue(MD_FILTER_LOAD_ORDER, strNewOrder);
m_strFilterOrder = strNewOrder; } while(FALSE);
if (IsOpen()) { Close(); }
return err; }
POSITION CIISFilterList::GetFilterPositionByIndex( IN int nSel ) /*++
Routine Description:
Return the position of a filter object by index, skipping filters marked for deletion.
Arguments:
int nSel - 0 based index into the list
Return Value:
The POSITION into the filters ObList of the filter at the index specified, or NULL if the filter is not found.
--*/ { int nIndex = -1; CIISFilter * pFilter; POSITION pos, posReturn = NULL;
pos = m_oblFilters.GetHeadPosition();
while(pos && nIndex < nSel) { posReturn = pos; pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
//
// Skipping deleted filters
//
if (!pFilter->IsFlaggedForDeletion()) { ++nIndex; } } return posReturn; }
BOOL CIISFilterList::ExchangePositions( IN int nSel1, IN int nSel2, OUT CIISFilter *& p1, OUT CIISFilter *& p2 ) /*++
Routine Description:
Exchange the positions of two filters in the list
Arguments:
int nSel1 : Item 1 int nSel2 : Item 2 CIISFilter *& p1 : Returns the item moved to position 1 CIISFilter *& p2 : Returns the item moved to position 2
Return Value:
TRUE for success, FALSE for failure.
--*/ { ASSERT(SUCCEEDED(m_hrResult));
//
// Fetch filters at the two positions (deleted filters are
// skipped in the index count)
//
POSITION pos1 = GetFilterPositionByIndex(nSel1); POSITION pos2 = GetFilterPositionByIndex(nSel2); p1 = pos2 ? (CIISFilter *)m_oblFilters.GetAt(pos2) : NULL; p2 = pos1 ? (CIISFilter *)m_oblFilters.GetAt(pos1) : NULL;
if (!p1 || !p2) { TRACEEOLID("Invalid internal state -- filter exchange impossible"); ASSERT(FALSE);
return FALSE; }
TRACEEOLID("Filter (1) name is " << p1->m_strName); TRACEEOLID("Filter (2) name is " << p2->m_strName);
//
// Exchange
//
m_oblFilters.SetAt(pos1, p1); m_oblFilters.SetAt(pos2, p2);
//
// Success
//
return TRUE; }
LPCTSTR CIISFilterList::BuildFilterOrderString( OUT CString & strFilterOrder ) /*++
Routine Description:
Convert the oblist of filters to a single filter order string fit to be stuffed into the metabase
Arguments:
CString & strFilterOrder : Output to receive the order string
Return Value:
A pointer to the new filter order string.
--*/ { BOOL fFirst = TRUE; POSITION pos = m_oblFilters.GetHeadPosition();
strFilterOrder.Empty();
while(pos) { CIISFilter * pFlt = (CIISFilter *)m_oblFilters.GetNext(pos);
if (!pFlt->IsFlaggedForDeletion()) { if (!fFirst) { strFilterOrder += s_lpszSep; } else { fFirst = FALSE; }
strFilterOrder += pFlt->m_strName; } }
return (LPCTSTR)strFilterOrder; }
BOOL CIISFilterList::HasDirtyFilter() const /*++
Routine Description:
Go through the list of filters, and return TRUE if any filter in the list is dirty or flagged for deletion
Arguments:
None
Return Value:
TRUE if any filter is dirty or flagged for deletion.
--*/ { ASSERT(SUCCEEDED(m_hrResult));
POSITION pos = m_oblFilters.GetHeadPosition();
while(pos) { CIISFilter * pFilter = (CIISFilter *)m_oblFilters.GetNext(pos);
if (pFilter->IsFlaggedForDeletion() || pFilter->IsDirty()) { return TRUE; } }
return FALSE; }
//
// Message Map
//
BEGIN_MESSAGE_MAP(CW3Sheet, CInetPropertySheet) //{{AFX_MSG_MAP(CInetPropertySheet)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CW3Sheet::CW3Sheet( LPCTSTR pszCaption, DWORD dwAttributes, LPCTSTR lpszServer, DWORD dwInstance, LPCTSTR lpszParent, LPCTSTR lpszAlias, CWnd * pParentWnd, LPARAM lParam, LONG_PTR handle, UINT iSelectPage ) /*++
Routine Description:
WWW Property sheet constructor
Arguments:
LPCTSTR pszCaption : Sheet caption LPCTSTR lpszServer : Server name DWORD dwInstance : Instance number LPCTSTR lpszParent : Parent path LPCTSTR lpszAlias : Alias name CWnd * pParentWnd : Parent window LPARAM lParam : Parameter for MMC console LONG_PTR handle : MMC console handle UINT iSelectPage : Initial page selected or -1
Return Value:
N/A
--*/ : CInetPropertySheet( pszCaption, lpszServer, g_cszSvc, dwInstance, lpszParent, lpszAlias, pParentWnd, lParam, handle, iSelectPage ), m_fNew(FALSE), m_dwAttributes(dwAttributes), m_ppropInst(NULL), m_ppropDir(NULL) { }
CW3Sheet::~CW3Sheet() /*++
Routine Description:
Sheet destructor
Arguments:
N/A
Return Value:
N/A
--*/ { FreeConfigurationParameters();
//
// Must be deleted by now
//
ASSERT(m_ppropInst == NULL); ASSERT(m_ppropDir == NULL); }
void CW3Sheet::WinHelp( IN DWORD dwData, IN UINT nCmd ) /*++
Routine Description:
WWW Property sheet help handler
Arguments:
DWORD dwData : WinHelp data (dialog ID) UINT nCmd : WinHelp command
Return Value:
None
Notes:
Replace the dialog ID if this is the directory tab. We have different help depending on virtual directory, home, file, directory.
--*/ { if (dwData == HIDD_DIRECTORY_PROPERTIES) { if (IS_FILE(m_dwAttributes)) { dwData = HIDD_FS_FILE_PROPERTIES; } else if (IS_DIR(m_dwAttributes)) { dwData = HIDD_FS_DIRECTORY_PROPERTIES; } else { ASSERT(IS_VROOT(m_dwAttributes)); ASSERT(m_ppropDir != NULL);
if (!::lstrcmpi(m_ppropDir->m_strAlias, g_cszRoot)) { //
// It's a home virtual directory -- change the ID
//
dwData = HIDD_HOME_DIRECTORY_PROPERTIES; } } }
CInetPropertySheet::WinHelp(dwData, nCmd); }
/* virtual */ HRESULT CW3Sheet::LoadConfigurationParameters() /*++
Routine Description:
Load configuration parameters information
Arguments:
None
Return Value:
HRESULT
--*/ { CError err;
if (m_ppropInst == NULL) { ASSERT(m_ppropDir == NULL);
m_ppropInst = new CW3InstanceProps(m_strServer, m_dwInstance); m_ppropDir = new CW3DirProps( m_strServer, m_dwInstance, m_strParent, m_strAlias );
if (!m_ppropInst || !m_ppropDir) { err = ERROR_NOT_ENOUGH_MEMORY; return err; }
err = m_ppropInst->LoadData();
if (err.Succeeded()) { err = m_ppropDir->LoadData(); } }
return err; }
/* virtual */ void CW3Sheet::FreeConfigurationParameters() /*++
Routine Description:
Clean up configuration data
Arguments:
None
Return Value:
None
--*/ { //
// Must be deleted by now
//
ASSERT(m_ppropInst != NULL); ASSERT(m_ppropDir != NULL);
SAFE_DELETE(m_ppropInst); SAFE_DELETE(m_ppropDir); }
//
// Global DLL instance
//
HINSTANCE hInstance;
//
// ISM API Functions
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
extern "C" DWORD APIENTRY ISMQueryServiceInfo( OUT ISMSERVICEINFO * psi ) /*++
Routine Description:
Return service-specific information back to to the application. This function is called by the service manager immediately after LoadLibary(); The size element must be set prior to calling this API.
Arguments:
ISMSERVICEINFO * psi : Service information returned.
Return Value:
Error return value
--*/ { AFX_MANAGE_STATE(AfxGetStaticModuleState() );
ASSERT(psi != NULL); ASSERT(psi->dwSize == ISMSERVICEINFO_SIZE);
psi->dwSize = ISMSERVICEINFO_SIZE; psi->dwVersion = ISM_VERSION;
psi->flServiceInfoFlags = 0 | ISMI_INETSLOCDISCOVER | ISMI_CANCONTROLSERVICE | ISMI_CANPAUSESERVICE | ISMI_UNDERSTANDINSTANCE | ISMI_NORMALTBMAPPING | ISMI_INSTANCES | ISMI_CHILDREN | ISMI_FILESYSTEM | ISMI_TASKPADS | ISMI_SECURITYWIZARD | ISMI_HASWEBPROTOCOL | ISMI_SUPPORTSMETABASE | ISMI_SUPPORTSMASTER ; /**/
ASSERT(::lstrlen(SERVICE_LONG_NAME) <= MAX_LNLEN); ASSERT(::lstrlen(SERVICE_SHORT_NAME) <= MAX_SNLEN);
psi->ullDiscoveryMask = INETSLOC_MASK; psi->rgbButtonBkMask = BUTTON_BMP_BACKGROUND; psi->nButtonBitmapID = BUTTON_BMP_ID; psi->rgbServiceBkMask = SERVICE_BMP_BACKGROUND; psi->nServiceBitmapID = SERVICE_BMP_ID; psi->rgbLargeServiceBkMask = SERVICE_BMP_BACKGROUND; psi->nLargeServiceBitmapID = SERVICE_BMP32_ID; ::lstrcpy(psi->atchShortName, SERVICE_SHORT_NAME); ::lstrcpy(psi->atchLongName, SERVICE_LONG_NAME);
//
// /* K2 */
//
psi->rgbChildBkMask = CHILD_BMP_BACKGROUND; psi->nChildBitmapID = CHILD_BMP_ID ; psi->rgbLargeChildBkMask = CHILD_BMP_BACKGROUND; psi->nLargeChildBitmapID = CHILD_BMP32_ID;
//
// IIS 5
//
ASSERT(::lstrlen(SERVICE_PROTOCOL) <= MAX_SNLEN); ASSERT(::lstrlen(g_cszSvc) <= MAX_SNLEN); ::lstrcpy(psi->atchProtocol, SERVICE_PROTOCOL); ::lstrcpy(psi->atchMetaBaseName, g_cszSvc);
return ERROR_SUCCESS; }
extern "C" DWORD APIENTRY ISMDiscoverServers( OUT ISMSERVERINFO * psi, IN DWORD * pdwBufferSize, IN OUT int * cServers ) /*++
Routine Description:
Discover machines running this service. This is only necessary for services not discovered with inetscloc (which don't give a mask)
Arguments:
ISMSERVERINFO * psi : Server info buffer. DWORD * pdwBufferSize : Size required/available. OUT int * cServers : Number of servers in buffer.
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(AfxGetStaticModuleState());
*cServers = 0; *pdwBufferSize = 0L;
//
// We're an inetsloc service
//
TRACEEOLID("Warning: service manager called bogus ISMDiscoverServers"); ASSERT(FALSE);
return ERROR_SUCCESS; }
extern "C" DWORD APIENTRY ISMQueryServerInfo( IN LPCTSTR lpszServerName, OUT ISMSERVERINFO * psi ) /*++
Routine Description:
Get information about a specific server with regards to this service.
Arguments:
LPCTSTR lpszServerName : Name of server. ISMSERVERINFO * psi : Server information returned.
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
ASSERT(psi != NULL); ASSERT(psi->dwSize == ISMSERVERINFO_SIZE); ASSERT(::lstrlen(lpszServerName) <= MAX_SERVERNAME_LEN);
psi->dwSize = ISMSERVERINFO_SIZE; ::lstrcpy(psi->atchServerName, lpszServerName);
//
// Start with NULL comment
//
*psi->atchComment = _T('\0');
//
// First look at the SC
//
CError err(::QueryInetServiceStatus( psi->atchServerName, SERVICE_SC_NAME, &(psi->nState) ));
if (err.Failed()) { psi->nState = INetServiceUnknown;
return err.Win32Error(); }
//
// Check the metabase to see if the service is installed
//
CMetaKey mk(lpszServerName, METADATA_PERMISSION_READ, g_cszSvc); err = mk.QueryResult();
if (err.Failed()) { if (err == REGDB_E_CLASSNOTREG) { //
// Ok, the service is there, but the metabase is not.
// This must be the old IIS 1-3 version of this service,
// which doesn't count as having the service installed.
//
return ERROR_SERVICE_DOES_NOT_EXIST; }
return err; }
//
// If not exist, return bogus acceptable error
//
return (err.Win32Error() == ERROR_PATH_NOT_FOUND) ? ERROR_SERVICE_DOES_NOT_EXIST : err; }
extern "C" DWORD APIENTRY ISMChangeServiceState( IN int nNewState, OUT int * pnCurrentState, IN DWORD dwInstance, IN LPCTSTR lpszServers ) /*++
Routine Description:
Change the service state of the servers (to paused/continue, started, stopped, etc)
Arguments:
int nNewState : INetService definition. int * pnCurrentState : Ptr to current state (will be changed DWORD dwInstance : Instance or 0 for the service itself LPCTSTR lpszServers : Double NULL terminated list of servers.
Return Value:
Error return code
--*/
{ AFX_MANAGE_STATE(AfxGetStaticModuleState() );
ASSERT(nNewState >= INetServiceStopped && nNewState <= INetServicePaused);
if (IS_MASTER_INSTANCE(dwInstance)) { return ChangeInetServiceState( lpszServers, SERVICE_SC_NAME, nNewState, pnCurrentState ); }
//
// Change the state of the instance
//
CInstanceProps inst(lpszServers, g_cszSvc, dwInstance); inst.LoadData();
CError err(inst.ChangeState(nNewState)); *pnCurrentState = inst.m_nISMState;
return err.Win32Error(); }
extern "C" DWORD APIENTRY ISMConfigureServers( IN HWND hWnd, IN DWORD dwInstance, IN LPCTSTR lpszServers ) /*++
Routine Description:
Display configuration property sheet.
Arguments:
HWND hWnd : Main app window handle DWORD dwInstance : Instance number LPCTSTR lpszServers : Double NULL terminated list of servers
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
DWORD err = ERROR_SUCCESS;
//
// Convert the list of servers to a
// more manageable CStringList.
//
CStringList strlServers; err = ConvertDoubleNullListToStringList(lpszServers, strlServers);
if (err != ERROR_SUCCESS) { TRACEEOLID("Error building server string list"); return err; }
CString strCaption;
if (strlServers.GetCount() == 1) { CString str; LPCTSTR lpComputer = PURE_COMPUTER_NAME(lpszServers);
if (IS_MASTER_INSTANCE(dwInstance)) { VERIFY(str.LoadString(IDS_CAPTION_DEFAULT)); strCaption.Format(str, lpComputer); } else { VERIFY(str.LoadString(IDS_CAPTION)); strCaption.Format(str, dwInstance, lpComputer); } } else // Multiple server caption
{ VERIFY(strCaption.LoadString(IDS_CAPTION_MULTIPLE)); }
ASSERT(strlServers.GetCount() == 1);
//
// Get the server name
//
LPCTSTR lpszServer = strlServers.GetHead(); DWORD dwAttributes = FILE_ATTRIBUTE_VIRTUAL_DIRECTORY;
CW3Sheet * pSheet = NULL;
try {
//
// Call the APIs and build the property pages
//
pSheet = new CW3Sheet( strCaption, dwAttributes, lpszServer, dwInstance, NULL, g_cszRoot, CWnd::FromHandlePermanent(hWnd) ); pSheet->AddRef();
if (SUCCEEDED(pSheet->QueryInstanceResult())) { //
// Add instance pages
//
pSheet->AddPage(new CW3ServicePage(pSheet));
if (pSheet->cap().HasOperatorList() && pSheet->HasAdminAccess()) { pSheet->AddPage(new CW3AccountsPage(pSheet)); }
pSheet->AddPage(new CW3PerfPage(pSheet)); pSheet->AddPage(new CW3FiltersPage(pSheet)); }
if (SUCCEEDED(pSheet->QueryDirectoryResult())) { //
// Add directory pages
//
pSheet->AddPage(new CW3DirectoryPage(pSheet, TRUE)); pSheet->AddPage(new CW3DocumentsPage(pSheet)); pSheet->AddPage(new CW3SecurityPage(pSheet, TRUE, dwAttributes)); pSheet->AddPage(new CW3HTTPPage(pSheet)); pSheet->AddPage(new CW3ErrorsPage(pSheet)); }
if(dwInstance == MASTER_INSTANCE) { pSheet->AddPage(new CDefWebSitePage(pSheet)); } } catch(CMemoryException * e) { TRACEEOLID("Aborting due to exception"); err = ERROR_NOT_ENOUGH_MEMORY; e->Delete(); }
if (err == ERROR_SUCCESS) { ASSERT(pSheet != NULL); pSheet->DoModal(); pSheet->Release(); }
//
// Sheet and pages clean themselves up
//
return err; }
//
// K2 Functions
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
HRESULT AddMMCPage( IN LPPROPERTYSHEETCALLBACK lpProvider, IN CPropertyPage * pg ) /*++
Routine Description:
Helper function to add MFC property page using callback provider to MMC.
Arguments:
LPPROPERTYSHEETCALLBACK lpProvider : Property sheet provider CPropertyPage * pg : MFC property page object
Return Value:
HRESULT
--*/ { ASSERT(pg != NULL);
//
// Patch MFC property page class.
//
MMCPropPageCallback(&pg->m_psp);
HPROPSHEETPAGE hPage = CreatePropertySheetPage( (LPCPROPSHEETPAGE)&pg->m_psp );
if (hPage == NULL) { return E_UNEXPECTED; }
lpProvider->AddPage(hPage);
return S_OK; }
extern "C" HRESULT APIENTRY ISMBind( IN LPCTSTR lpszServer, OUT HANDLE * phServer ) /*++
Routine Description:
Generate a handle for the server name.
Arguments:
LPCTSTR lpszServer : Server name HANDLE * phServer : Returns a handle
Return Value: HRESULT
--*/ { return COMDLL_ISMBind(lpszServer, phServer); }
extern "C" HRESULT APIENTRY ISMUnbind( IN HANDLE hServer ) /*++
Routine Description:
Free up the server handle
Arguments:
HANDLE hServer : Server handle
Return Value:
HRESULT
--*/ { return COMDLL_ISMUnbind(hServer); }
extern "C" HRESULT APIENTRY ISMMMCConfigureServers( IN HANDLE hServer, IN PVOID lpfnMMCCallbackProvider, IN LPARAM param, IN LONG_PTR handle, IN DWORD dwInstance ) /*++
Routine Description:
Display configuration property sheet.
Arguments:
HANDLE hServer : Server handle PVOID lpfnMMCCallbackProvider : MMC Callback provider LPARAM param : MMC LPARAM LONG_PTR handle : MMC Console handle DWORD dwInstance : Instance number
Return Value:
HRESULT
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CError err; LPPROPERTYSHEETCALLBACK lpProvider = (LPPROPERTYSHEETCALLBACK)lpfnMMCCallbackProvider;
LPCTSTR lpszServer = GetServerNameFromHandle(hServer); ASSERT(lpszServer != NULL);
CString str, strCaption; LPCTSTR lpszComputer = PURE_COMPUTER_NAME(lpszServer);
if(IS_MASTER_INSTANCE(dwInstance)) { VERIFY(str.LoadString(IDS_CAPTION_DEFAULT)); strCaption.Format(str, lpszComputer); } else { VERIFY(str.LoadString(IDS_CAPTION)); strCaption.Format(str, dwInstance, lpszComputer); }
DWORD dwAttributes = FILE_ATTRIBUTE_VIRTUAL_DIRECTORY;
CW3Sheet * pSheet = NULL;
try { //
// Call the APIs and build the property pages
//
pSheet = new CW3Sheet( strCaption, dwAttributes, lpszServer, dwInstance, NULL, g_cszRoot, NULL, param, handle );
pSheet->SetModeless();
if (SUCCEEDED(pSheet->QueryInstanceResult())) { //
// Add instance pages
//
AddMMCPage(lpProvider, new CW3ServicePage(pSheet));
if (pSheet->cap().HasOperatorList() && pSheet->HasAdminAccess()) { AddMMCPage(lpProvider, new CW3AccountsPage(pSheet)); }
AddMMCPage(lpProvider, new CW3PerfPage(pSheet)); AddMMCPage(lpProvider, new CW3FiltersPage(pSheet)); }
if (SUCCEEDED(pSheet->QueryDirectoryResult())) { //
// Add directory pages
//
AddMMCPage(lpProvider, new CW3DirectoryPage(pSheet, TRUE)); AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet)); AddMMCPage(lpProvider, new CW3SecurityPage(pSheet,TRUE, dwAttributes)); AddMMCPage(lpProvider, new CW3HTTPPage(pSheet)); AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet)); }
if(dwInstance == MASTER_INSTANCE) { AddMMCPage(lpProvider, new CDefWebSitePage(pSheet)); }
} catch(CMemoryException * e) { TRACEEOLID("Aborting due to exception"); err = ERROR_NOT_ENOUGH_MEMORY; e->Delete(); }
//
// Sheet and pages clean themselves up
//
return err; }
extern "C" HRESULT APIENTRY ISMMMCConfigureChild( IN HANDLE hServer, IN PVOID lpfnMMCCallbackProvider, IN LPARAM param, IN LONG_PTR handle, IN DWORD dwAttributes, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Display configuration property sheet for child object.
Arguments:
HANDLE hServer : Server handle PVOID lpfnMMCCallbackProvider : MMC Callback provider LPARAM param : MMC parameter passed to sheet LONG_PTR handle : MMC console handle DWORD dwAttributes : Must be FILE_ATTRIBUTE_VIRTUAL_DIRECTORY DWORD dwInstance : Parent instance number LPCTSTR lpszParent : Parent path LPCTSTR lpszAlias : Child to configure
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
CError err; LPPROPERTYSHEETCALLBACK lpProvider = (LPPROPERTYSHEETCALLBACK)lpfnMMCCallbackProvider;
CString strCaption; { CString str; VERIFY(str.LoadString(IDS_DIR_TITLE));
strCaption.Format(str, lpszAlias); }
CW3Sheet * pSheet = NULL;
try { pSheet = new CW3Sheet( strCaption, dwAttributes, lpszServer, dwInstance, lpszParent, lpszAlias, NULL, param, handle );
pSheet->SetModeless();
//
// Do not allow editing of a file/dir which is overridden
// by an alias.
//
#pragma message("Warning: file/vroot check stubbed out")
/*
if (!IS_VROOT(dwAttributes) && !pSheet->GetDirectoryProperties().IsPathInherited()) { ::AfxMessageBox(IDS_ERR_VROOT_OVERRIDE); pSheet->Release();
return S_OK; } */
//
// Call the APIs and build the property pages
//
if (SUCCEEDED(pSheet->QueryDirectoryResult())) { AddMMCPage(lpProvider, new CW3DirectoryPage(pSheet, FALSE, dwAttributes));
if (!IS_FILE(dwAttributes)) { AddMMCPage(lpProvider, new CW3DocumentsPage(pSheet)); }
AddMMCPage(lpProvider, new CW3SecurityPage(pSheet, FALSE, dwAttributes)); AddMMCPage(lpProvider, new CW3HTTPPage(pSheet)); AddMMCPage(lpProvider, new CW3ErrorsPage(pSheet)); } } catch(CMemoryException * e) { TRACEEOLID("Aborting due to exception"); err = ERROR_NOT_ENOUGH_MEMORY; e->Delete(); }
//
// Sheet and pages will delete themselves
//
return err; }
extern "C" HRESULT APIENTRY ISMEnumerateInstances( IN HANDLE hServer, OUT ISMINSTANCEINFO * pii, OUT IN HANDLE * phEnum ) /*++
Routine Description:
Enumerate Instances. First call with *phEnum == NULL.
Arguments:
HANDLE hServer : Server handle ISMINSTANCEINFO * pii : Instance info buffer HANDLE * phEnum : Enumeration handle.
Return Value:
Error return code
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CError err; CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer); ASSERT(pInterface != NULL);
BEGIN_ASSURE_BINDING_SECTION err = COMDLL_ISMEnumerateInstances( pInterface, pii, phEnum, g_cszSvc ); END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_NO_MORE_ITEMS)
return err; }
extern "C" HRESULT APIENTRY ISMAddInstance( IN HANDLE hServer, IN DWORD dwSourceInstance, OUT ISMINSTANCEINFO * pii, OPTIONAL IN DWORD dwBufferSize ) /*++
Routine Description:
Add an instance.
Arguments:
HANDLE hServer : Server handle DWORD dwSourceInstance : Source instance ID to clone ISMINSTANCEINFO * pii : Instance info buffer. May be NULL DWORD dwBufferSize : Size of buffer
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CIISWizardSheet sheet(IDB_WIZ_LEFT, IDB_WIZ_HEAD);
CIISWebWizSettings ws(hServer, g_cszSvc);
CIISWizardBookEnd pgWelcome( IDS_SITE_WELCOME, IDS_NEW_SITE_WIZARD, IDS_SITE_BODY );
CVDWPDescription pgDescr(&ws); CVDWPBindings pgBindings(&ws); CVDWPPath pgHome(&ws, FALSE); CVDWPUserName pgUserName(&ws, FALSE); CVDWPPermissions pgPerms(&ws, FALSE);
CIISWizardBookEnd pgCompletion( &ws.m_hrResult, IDS_SITE_SUCCESS, IDS_SITE_FAILURE, IDS_NEW_SITE_WIZARD );
sheet.AddPage(&pgWelcome); sheet.AddPage(&pgDescr); sheet.AddPage(&pgBindings); sheet.AddPage(&pgHome); sheet.AddPage(&pgUserName); sheet.AddPage(&pgPerms); sheet.AddPage(&pgCompletion);
if (sheet.DoModal() == IDCANCEL) { return CError::HResult(ERROR_CANCELLED); }
CError err(ws.m_hrResult);
if (err.Succeeded()) { //
// Get info on it to be returned.
//
ISMQueryInstanceInfo( hServer, WITHOUT_INHERITANCE, pii, ws.m_dwInstance ); }
return err; }
extern "C" HRESULT APIENTRY ISMDeleteInstance( IN HANDLE hServer, IN DWORD dwInstance ) /*++
Routine Description:
Delete an instance
Arguments:
HANDLE hServer : Server handle DWORD dwInstance : Instance to be deleted
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
CMetaKey * pKey = GetMetaKeyFromHandle(hServer); LPCTSTR lpszServer = GetServerNameFromHandle(hServer);
//
// First, attempt to delete the applications that might live
// here
//
CIISApplication app(lpszServer, g_cszSvc, dwInstance, g_cszRoot); CError err(app.QueryResult());
if(err.Succeeded()) { //
// Recursively delete all app info
//
err = app.DeleteRecoverable(TRUE); }
if (err.Succeeded()) { BEGIN_ASSURE_BINDING_SECTION err = CInstanceProps::Delete( pKey, g_cszSvc, dwInstance ); END_ASSURE_BINDING_SECTION(err, pKey, ERROR_CANCELLED);
if (err.Failed()) { //
// Failed to delete the instance -- recover application
// information recursively
//
app.Recover(TRUE); } }
return err; }
extern "C" HRESULT APIENTRY ISMEnumerateChildren( IN HANDLE hServer, OUT ISMCHILDINFO * pii, OUT IN HANDLE * phEnum, IN DWORD dwInstance, IN LPCTSTR lpszParent ) /*++
Routine Description:
Enumerate children. First call with *phEnum == NULL;
Arguments:
HANDLE hServer : Server handle ISMCHILDINFO * pii : Child info buffer HANDLE * phEnum : Enumeration handle. DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent path
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CError err; CMetaInterface * pInterface = GetMetaKeyFromHandle(hServer); ASSERT(pInterface != NULL);
BEGIN_ASSURE_BINDING_SECTION err = COMDLL_ISMEnumerateChildren( pInterface, pii, phEnum, g_cszSvc, dwInstance, lpszParent ); END_ASSURE_BINDING_SECTION(err, pInterface, ERROR_NO_MORE_ITEMS);
return err; }
extern "C" HRESULT APIENTRY ISMAddChild( IN HANDLE hServer, OUT ISMCHILDINFO * pii, IN DWORD dwBufferSize, IN DWORD dwInstance, IN LPCTSTR lpszParent ) /*++
Routine Description:
Add a child.
Arguments:
HANDLE hServer : Server handle ISMCHILDINFO * pii : Child info buffer. May be NULL DWORD dwBufferSize : Size of info buffer DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent path
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CIISWizardSheet sheet(IDB_WIZ_LEFT_DIR, IDB_WIZ_HEAD_DIR);
CIISWebWizSettings ws(hServer, g_cszSvc, dwInstance, lpszParent);
CIISWizardBookEnd pgWelcome( IDS_VDIR_WELCOME, IDS_NEW_VDIR_WIZARD, IDS_VDIR_BODY );
CVDWPAlias pgAlias(&ws); CVDWPPath pgPath(&ws, TRUE); CVDWPUserName pgUserName(&ws, TRUE); CVDWPPermissions pgPerms(&ws, TRUE);
CIISWizardBookEnd pgCompletion( &ws.m_hrResult, IDS_VDIR_SUCCESS, IDS_VDIR_FAILURE, IDS_NEW_VDIR_WIZARD );
sheet.AddPage(&pgWelcome); sheet.AddPage(&pgAlias); sheet.AddPage(&pgPath); sheet.AddPage(&pgUserName); sheet.AddPage(&pgPerms); sheet.AddPage(&pgCompletion);
if (sheet.DoModal() == IDCANCEL) { return ERROR_CANCELLED; }
CError err(ws.m_hrResult);
if (err.Succeeded()) { err = ISMQueryChildInfo( ws.m_pKey, WITH_INHERITANCE, pii, ws.m_dwInstance, ws.m_strParent, ws.m_strAlias ); }
return err; }
extern "C" HRESULT APIENTRY ISMDeleteChild( IN HANDLE hServer, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Delete a child.
Arguments:
HANDLE hServer : Server handle DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent path LPCTSTR lpszAlias : Alias of child to be deleted
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CMetaKey * pKey = GetMetaKeyFromHandle(hServer); LPCTSTR lpszServer = GetServerNameFromHandle(hServer); ASSERT(lpszServer != NULL);
//
// First, attempt to delete the applications that might live
// here.
//
CIISApplication app( lpszServer, g_cszSvc, dwInstance, lpszParent, lpszAlias );
CError err(app.QueryResult());
if (err.Succeeded()) { err = app.DeleteRecoverable(TRUE); }
if (err.Succeeded()) { BEGIN_ASSURE_BINDING_SECTION err = CChildNodeProps::Delete( pKey, g_cszSvc, dwInstance, lpszParent, lpszAlias ); END_ASSURE_BINDING_SECTION(err, pKey, ERROR_CANCELLED);
if (err.Failed()) { //
// Failed to delete the child node -- recover application
// information
//
app.Recover(TRUE); } }
return err; }
extern "C" HRESULT APIENTRY ISMRenameChild( IN HANDLE hServer, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias, IN LPCTSTR lpszNewName ) /*++
Routine Description:
Rename a child.
Arguments:
HANDLE hServer : Server handle DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent path LPCTSTR lpszAlias : Alias of child to be renamed LPCTSTR lpszNewName : New alias name
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState() );
CMetaKey * pKey = GetMetaKeyFromHandle(hServer); LPCTSTR lpszServer = GetServerNameFromHandle(hServer); ASSERT(lpszServer != NULL);
//
// First, attempt to delete the applications that might live
// here.
//
CIISApplication app( lpszServer, g_cszSvc, dwInstance, lpszParent, lpszAlias );
CError err(app.QueryResult());
if (err.Succeeded()) { //
// Delete recursively
//
err = app.DeleteRecoverable(TRUE); }
if (err.Succeeded()) { BEGIN_ASSURE_BINDING_SECTION err = CChildNodeProps::Rename( pKey, g_cszSvc, dwInstance, lpszParent, lpszAlias, lpszNewName ); END_ASSURE_BINDING_SECTION(err, pKey, ERROR_CANCELLED);
if (err.Succeeded()) { //
// Rename succeeded -- recover application information
// on the _new_ metabase path.
//
CIISApplication appNew( lpszServer, g_cszSvc, dwInstance, lpszParent, lpszNewName );
err = appNew.QueryResult();
if (err.Succeeded()) { err = appNew.Recover(TRUE); } } else { //
// Failed to delete the child node -- recover application
// information on the _old_ metabase path (don't disturb the
// error code).
//
app.Recover(TRUE); } }
return err; }
extern "C" HRESULT APIENTRY ISMQueryInstanceInfo( IN HANDLE hServer, IN BOOL fInherit, OUT ISMINSTANCEINFO * pii, IN DWORD dwInstance ) /*++
Routine Description:
Get instance specific information.
Arguments:
HANDLE hServer : Server handle BOOL fInherit : TRUE to inherit, FALSE otherwise ISMINSTANCEINFO * pii : Instance info buffer LPCTSTR lpszServer : A single server DWORD dwInstance : Instance number
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
ASSERT(pii != NULL);
CError err; CMetaKey * pKey = GetMetaKeyFromHandle(hServer); BEGIN_ASSURE_BINDING_SECTION CInstanceProps inst(pKey, g_cszSvc, dwInstance); err = inst.LoadData(); if (err.Succeeded()) { //
// Set the output structure
//
pii->dwSize = ISMINSTANCEINFO_SIZE; inst.FillInstanceInfo(pii); //
// Get properties on the home directory
//
CChildNodeProps home( &inst, g_cszSvc, dwInstance, NULL, g_cszRoot, fInherit, TRUE // Path only
);
err = home.LoadData(); home.FillInstanceInfo(pii); } END_ASSURE_BINDING_SECTION(err, pKey, err);
return err.Failed() ? err : S_OK; }
extern "C" HRESULT APIENTRY ISMQueryChildInfo( IN HANDLE hServer, IN BOOL fInherit, OUT ISMCHILDINFO * pii, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Get child-specific info.
Arguments:
HANDLE hServer : Server handle BOOL fInherit : TRUE to inherit, FALSE otherwise ISMCHILDINFO * pii : Child info buffer DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent Path ("" for root) LPCTSTR lpszAlias : Alias of child to be deleted
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
//
// Get all the inherited properties
//
CChildNodeProps node( GetMetaKeyFromHandle(hServer), g_cszSvc, dwInstance, lpszParent, lpszAlias, fInherit, FALSE // Everything
); CError err(node.LoadData());
//
// Set the output structure
//
pii->dwSize = ISMCHILDINFO_SIZE; node.FillChildInfo(pii);
return err; }
extern "C" HRESULT APIENTRY ISMConfigureChild( IN HANDLE hServer, IN HWND hWnd, IN DWORD dwAttributes, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Configure child.
Arguments:
HANDLE hServer : Server handle HWND hWnd : Main app window handle DWORD dwAttributes : File attributes DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent path LPCTSTR lpszAlias : Child to configure or NULL
Return Value:
Error return code.
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CMetaKey * pKey = GetMetaKeyFromHandle(hServer); LPCTSTR lpszServer = GetServerNameFromHandle(hServer); ASSERT(lpszServer != NULL);
CError err;
CString strCaption; { CString str; VERIFY(str.LoadString(IDS_DIR_TITLE));
strCaption.Format(str, lpszAlias); }
CW3Sheet * pSheet = NULL;
try { pSheet = new CW3Sheet( strCaption, dwAttributes, lpszServer, dwInstance, lpszParent, lpszAlias, CWnd::FromHandlePermanent(hWnd) );
pSheet->AddRef();
//
// Do not allow editing of a file/dir which is overridden
// by an alias.
//
if (!IS_VROOT(dwAttributes) && !pSheet->GetDirectoryProperties().IsPathInherited()) { ::AfxMessageBox(IDS_ERR_VROOT_OVERRIDE); pSheet->Release();
return S_OK; }
//
// Call the APIs and build the property pages
//
if (SUCCEEDED(pSheet->QueryDirectoryResult())) { pSheet->AddPage(new CW3DirectoryPage(pSheet, FALSE, dwAttributes));
if (!IS_FILE(dwAttributes)) { pSheet->AddPage(new CW3DocumentsPage(pSheet)); }
pSheet->AddPage(new CW3SecurityPage(pSheet, FALSE, dwAttributes)); pSheet->AddPage(new CW3HTTPPage(pSheet)); pSheet->AddPage(new CW3ErrorsPage(pSheet)); } } catch(CMemoryException * e) { TRACEEOLID("Aborting due to exception"); err = ERROR_NOT_ENOUGH_MEMORY; e->Delete(); }
if (err.Succeeded()) { ASSERT(pSheet != NULL); pSheet->DoModal(); pSheet->Release(); }
//
// Sheet and pages will delete themselves
//
return err; }
//
// Authentication bit strings
//
FLAGTOSTRING fsAuthentications[] = { { MD_AUTH_ANONYMOUS, IDS_AUTHENTICATION_ANONYMOUS, TRUE }, { MD_AUTH_ANONYMOUS, IDS_AUTHENTICATION_NO_ANONYMOUS, FALSE }, { MD_AUTH_BASIC, IDS_AUTHENTICATION_BASIC, TRUE }, { MD_AUTH_MD5, IDS_AUTHENTICATION_DIGEST, TRUE }, { MD_AUTH_NT, IDS_AUTHENTICATION_NT, TRUE }, };
class CWebSecurityTemplate : public CIISSecurityTemplate /*++
Class Description:
Web Security template class
Public Interface:
CWebSecurityTemplate : Constructor
ApplySettings : Apply template to destination path GenerateSummary : Generate text summary
--*/ { //
// Constructor
//
public: CWebSecurityTemplate( IN const CMetaKey * pKey, IN LPCTSTR lpszMDPath, IN BOOL fInherit );
public: //
// Apply settings to destination path
//
virtual HRESULT ApplySettings( IN BOOL fUseTemplates, IN LPCTSTR lpszServerName, IN LPCTSTR lpszService, IN DWORD dwInstance = MASTER_INSTANCE, IN LPCTSTR lpszParent = NULL, IN LPCTSTR lpszAlias = NULL );
virtual void GenerateSummary( IN BOOL fUseTemplates, IN LPCTSTR lpszServerName, IN LPCTSTR lpszService, IN DWORD dwInstance = MASTER_INSTANCE, IN LPCTSTR lpszParent = NULL, IN LPCTSTR lpszAlias = NULL );
protected: //
// Break out GetAllData() data to data fields
//
virtual void ParseFields();
public: MP_DWORD m_dwAuthentication; MP_DWORD m_dwDirBrowsing; };
CWebSecurityTemplate::CWebSecurityTemplate( IN const CMetaKey * pKey, IN LPCTSTR lpszMDPath, IN BOOL fInherit ) /*++
Routine Description:
Construct from open key
Arguments:
const CMetaKey * pKey : Open key LPCTSTR lpszMDPath : Path BOOL fInherit : TRUE to inherit values, FALSE if not
Return Value:
N/A
--*/ : CIISSecurityTemplate(pKey, lpszMDPath, fInherit), m_dwAuthentication(MD_AUTH_ANONYMOUS), m_dwDirBrowsing( MD_DIRBROW_SHOW_DATE | MD_DIRBROW_SHOW_TIME | MD_DIRBROW_SHOW_SIZE | MD_DIRBROW_SHOW_EXTENSION ) { //
// Managed Properties
//
m_dlProperties.AddTail(MD_AUTHORIZATION); // m_dlProperties.AddTail(MD_DIRECTORY_BROWSING); // out of IIS 5
}
/* virtual */ void CWebSecurityTemplate::ParseFields() /*++
Routine Description:
Break into fields.
Arguments:
None.
Return Value:
None.
--*/ { //
// Fetch base class values
//
CIISSecurityTemplate::ParseFields();
BEGIN_PARSE_META_RECORDS(m_dwNumEntries, m_pbMDData) HANDLE_META_RECORD(MD_AUTHORIZATION, m_dwAuthentication) //HANDLE_META_RECORD(MD_DIRECTORY_BROWSING, m_dwDirBrowsing) // Out of IIS 5
END_PARSE_META_RECORDS }
/* virtual */ HRESULT CWebSecurityTemplate::ApplySettings( IN BOOL fUseTemplate, IN LPCTSTR lpszServerName, IN LPCTSTR lpszService, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Apply the settings to the specified destination path
Arguments: BOOL fUseTemplates : TRUE if the source is from a template, FALSE if using inheritance. LPCTSTR lpszServerName : Server name LPCTSTR lpszService : Service name DWORD dwInstance : Instance LPCTSTR lpszParent : Parent path (or NULL) LPCTSTR lpszAlias : Alias name (or NULL)
Return Value:
HRESULT
--*/ { //
// Write base class properties
//
CError err(CIISSecurityTemplate::ApplySettings( fUseTemplate, lpszServerName, lpszService, dwInstance, lpszParent, lpszAlias ));
if (err.Failed()) { return err; }
BOOL fWriteProperties = TRUE;
CMetaKey mk( lpszServerName, METADATA_PERMISSION_WRITE, lpszService, dwInstance, lpszParent, lpszAlias );
err = mk.QueryResult();
if (err.Win32Error() == ERROR_PATH_NOT_FOUND) { if (!fUseTemplate) { //
// No need to delete properties; everything's already
// inherited. Note that this is the only legit failure
// case. If using a template, the base class must have
// created the path by now.
//
fWriteProperties = FALSE; err.Reset(); } }
if (fWriteProperties) { do { BREAK_ON_ERR_FAILURE(err); if (fUseTemplate) { //
// Write values from template
//
err = mk.SetValue( MD_AUTHORIZATION, m_dwAuthentication );
BREAK_ON_ERR_FAILURE(err);
//
// dir browsing out of iis 5
//
/*
err = mk.SetValue( MD_DIRECTORY_BROWSING, m_dwDirBrowsing ); BREAK_ON_ERR_FAILURE(err); */ }
//
// Nothing to do in the inheritance case, because the
// base class knows which properties should be deleted
//
} while(FALSE); }
return err; }
/* virtual */ void CWebSecurityTemplate::GenerateSummary( IN BOOL fUseTemplate, IN LPCTSTR lpszServerName, IN LPCTSTR lpszService, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Generate text summary of what's in the security template. Arguments are the same as ApplySettings(), so that the summary can reflect what will actually be set.
Arguments:
BOOL fUseTemplates : TRUE if the source is from a template, FALSE if using inheritance. LPCTSTR lpszServerName : Server name LPCTSTR lpszService : Service name DWORD dwInstance : Instance LPCTSTR lpszParent : Parent path (or NULL) LPCTSTR lpszAlias : Alias name (or NULL)
Return Value:
None --*/ { AddSummaryString(IDS_AUTHENTICATION_METHODS);
int i;
//
// Summarize Authentication Methods:
//
if (m_dwAuthentication == 0L) { AddSummaryString(IDS_SUMMARY_NONE, 1); } else { for (i = 0; i < ARRAY_SIZE(fsAuthentications); ++i) { if (IS_FLAG_SET( m_dwAuthentication, fsAuthentications[i].dwFlag ) == fsAuthentications[i].fSet) { AddSummaryString(fsAuthentications[i].nID, 1); } } }
//
// CODEWORK: Dir browsing settings in the security wizards are postponed
// to post IIS 5
//
/*
if (IS_FLAG_SET(m_dwDirBrowsing, MD_DIRBROW_ENABLED)) { AddSummaryString(IDS_DIR_BROWSE_ON, 1); } else { AddSummaryString(IDS_DIR_BROWSE_OFF, 1); }
if (IS_FLAG_SET(m_dwDirBrowsing, MD_DIRBROW_LOADDEFAULT)) { AddSummaryString(IDS_LOAD_DEFAULT_ON, 1); } else { AddSummaryString(IDS_LOAD_DEFAULT_OFF, 1); } */
//
// Add base class summary
//
CIISSecurityTemplate::GenerateSummary( fUseTemplate, lpszServerName, lpszService, dwInstance, lpszParent, lpszAlias ); }
CIISSecurityTemplate * AllocateSecurityTemplate( IN const CMetaKey * pKey, IN LPCTSTR lpszMDPath, IN BOOL fInherit ) /*++
Routine Description:
Security template allocator function
Arguments:
IN const CMetaKey * pKey : Open key IN LPCTSTR lpszMDPath : Path IN BOOL fInherit : TRUE to inherit properties
Return Value:
Pointer to newly allocated security object
--*/ { return new CWebSecurityTemplate(pKey, lpszMDPath, fInherit); }
extern "C" HRESULT APIENTRY ISMSecurityWizard( IN HANDLE hServer, IN DWORD dwInstance, IN LPCTSTR lpszParent, IN LPCTSTR lpszAlias ) /*++
Routine Description:
Launch the security wizard
Arguments:
HANDLE hServer : Server handle DWORD dwInstance : Parent instance LPCTSTR lpszParent : Parent path LPCTSTR lpszAlias : Child to configure or NULL
Return Value:
HRESULT
--*/ { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
return COMDLL_ISMSecurityWizard( &AllocateSecurityTemplate, GetMetaKeyFromHandle(hServer), IDB_WIZ_LEFT_SEC, IDB_WIZ_HEAD_SEC, g_cszSvc, dwInstance, lpszParent, lpszAlias ); }
//
// End of ISM API Functions
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DWORD IsSSLEnabledOnServer( IN LPCTSTR lpszServer, OUT BOOL & fInstalled, OUT BOOL & fEnabled ) /*++
Routine Description:
Determine if SSL is installed on the server.
Arguments:
LPCTSTR lpszServer : Server name BOOL & fInstalled : Returns TRUE if SSL is installed BOOL & fEnabled : Returns TRUE if SSL is enabled
Return Value:
Error return code.
--*/ { /*
LPW3_CONFIG_INFO lp = NULL; CString str; DWORD err = ::W3GetAdminInformation((LPTSTR)lpszServer, &lp); if (err != ERROR_SUCCESS) { TRACEEOLID("Failed to determine if SSL is installed");
return err; }
fInstalled = (lp->dwEncCaps & ENC_CAPS_NOT_INSTALLED) == 0; fEnabled = (lp->dwEncCaps & ENC_CAPS_DISABLED) == 0;
NETAPIBUFFERFREE(lp);
*/
//
// Above doesn't work for Beta I -- hack to assume true.
//
fInstalled = fEnabled = TRUE;
return ERROR_SUCCESS; }
BOOL IsCertInstalledOnServer( IN LPCTSTR lpszServerName, IN DWORD dwInstance ) /*++
Routine Description:
Check to see if a certificate is installed on this virtual server. This routine only checks that the cert metabase key was read in.
by boydm
Arguments:
None
Return Value:
TRUE if a certificate are installed, FALSE otherwise
--*/ { CError err; BOOL fCertInstalled = FALSE; CW3InstanceProps * ppropInst;
//
// Get the instance properties
//
ppropInst = new CW3InstanceProps(lpszServerName, dwInstance);
//
// If it succeeded, load the data, then check the answer
//
if (ppropInst) { err = ppropInst->LoadData();
if (err.Succeeded()) { //
// Get the specific data to a local holder
// weird. You have to declare and assign the blob
// on different lines. Otherwise it gets constructed
// wrong and it tries to free an invalid
// memory block and bad things happen.
//
CBlob blobHash; blobHash = ppropInst->m_CertHash;
// CString strStore = ppropInst->m_strCertStoreName;
//
// If the certificate hash is there,
// then we have a certificate
//
if (!blobHash.IsEmpty()) { fCertInstalled = TRUE; } } }
//
// Clean up since we don't really need the ppropInst after this.
//
if (ppropInst) { delete ppropInst; ppropInst = NULL; }
//
// If that test failed, we may be admining a downlevel IIS4 machine.
// Unfortunately we can't tell by examining the capability bits,
// so look to see if the old certs are there.
//
if (!fCertInstalled) { CString strKey; CMetaEnumerator me(lpszServerName, g_cszSvc); HRESULT err = me.Next(strKey, g_cszSSLKeys); fCertInstalled = SUCCEEDED(err); }
return fCertInstalled; }
void RunKeyManager( IN LPCTSTR lpszServer OPTIONAL ) /*++
Routine Description:
Helper function to run the key manager application.
Arguments:
None
Return Value:
None
Notes:
Key manager is run synchronously.
--*/ { //
// Want to start key manager. I'm assuming
// here that the keyring app will be in the
// same directory as w3scfg.dll (safe assumption
// for the near future at least)
//
// CODEWORK: Move this to a registry key, so
// it can be changed later.
//
CString strPath; CError err;
if (::GetModuleFileName(hInstance, strPath.GetBuffer(MAX_PATH), MAX_PATH)) { int nLen = strPath.ReverseFind(_T('\\'));
if (nLen == -1) { TRACEEOLID("Bad module path"); err = ERROR_PATH_NOT_FOUND; } else { strPath.ReleaseBuffer(nLen); strPath += _T("\\keyring.exe");
TRACEEOLID("Spawning " << strPath);
CString strParm;
if (lpszServer != NULL) { strParm.Format(_T("/remote:%s"), lpszServer); }
TRACEEOLID(strParm); TRACEEOLID(strPath);
if (_tspawnl(_P_WAIT, strPath, strPath, strParm, NULL) != 0) { err.GetLastWinError(); } } } else { err.GetLastWinError(); }
err.MessageBoxOnFailure(); }
void InitializeDLL() /*++
Routine Description:
Perform additional initialisation as necessary
Arguments:
None
Return Value:
None
*/ { #ifdef _DEBUG
afxMemDF |= checkAlwaysMemDF;
#endif // _DEBUG
#ifdef UNICODE
TRACEEOLID("Loading UNICODE w3scfg.dll");
#else
TRACEEOLID("Loading ANSI w3scfg.dll");
#endif UNICODE
::AfxEnableControlContainer();
#ifndef _COMSTATIC
//
// Initialize IISUI extension DLL
//
InitIISUIDll();
#endif // _COMSTATIC
}
CConfigDll NEAR theApp;
//
// Message Map
//
BEGIN_MESSAGE_MAP(CConfigDll, CWinApp) //{{AFX_MSG_MAP(CConfigDll)
//}}AFX_MSG_MAP
//
// Global Help Commands
//
ON_COMMAND(ID_HELP, CWinApp::OnHelp) ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp) END_MESSAGE_MAP()
BOOL CConfigDll::InitInstance() /*++
Routine Description:
Initialize the instance
Arguments:
None
Return Value:
TRUE for success, FALSE for failure
--*/ { BOOL bInit = CWinApp::InitInstance();
hInstance = ::AfxGetInstanceHandle(); ASSERT(hInstance);
InitializeDLL();
try { //
// Get the help path
//
ASSERT(m_pszHelpFilePath != NULL); m_lpOldHelpPath = m_pszHelpFilePath; CString strFile(_tcsrchr(m_pszHelpFilePath, _T('\\'))); CRMCRegKey rk(REG_KEY, SZ_PARAMETERS, KEY_READ); rk.QueryValue(SZ_HELPPATH, m_strHelpPath, EXPANSION_ON); m_strHelpPath += strFile; } catch(CException * e) { e->ReportError(); e->Delete(); }
if (!m_strHelpPath.IsEmpty()) { m_pszHelpFilePath = m_strHelpPath; }
return bInit; }
int CConfigDll::ExitInstance() /*++
Routine Description:
Exit instance handler
Arguments:
None
Return Value:
0 for success, or an error return code
--*/ { m_pszHelpFilePath = m_lpOldHelpPath;
return CWinApp::ExitInstance(); }
CConfigDll::CConfigDll( IN LPCTSTR pszAppName OPTIONAL ) /*++
Routine Description:
DLL CWinApp constructor
Arguments:
None
Return Value:
N/A
--*/ : CWinApp(pszAppName) { }
|