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.
1321 lines
33 KiB
1321 lines
33 KiB
/*++
|
|
|
|
Copyright (c) 2002 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
restrlst.cxx
|
|
|
|
Abstract:
|
|
|
|
Classes that are used to modify the restriction list and application
|
|
dependency list in the metabase
|
|
|
|
Author:
|
|
|
|
Christopher Achille (cachille)
|
|
|
|
Project:
|
|
|
|
Internet Services Setup
|
|
|
|
Revision History:
|
|
|
|
April 2002: Created
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "restrlst.hxx"
|
|
#include "xmlupgrade.hxx"
|
|
|
|
// Constructor
|
|
//
|
|
CApplicationDependencies::CApplicationDependencies()
|
|
{
|
|
m_bMetabaseOpened = FALSE;
|
|
}
|
|
|
|
// InitMetabase
|
|
//
|
|
// Open the metabase, at the correct location for the Application Dependecies,
|
|
// so that we can read and write to it
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::InitMetabase()
|
|
{
|
|
if ( m_bMetabaseOpened )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
m_bMetabaseOpened = SUCCEEDED( m_Metabase.OpenNode( METABASEPATH_WWW_ROOT, TRUE ) );
|
|
|
|
return m_bMetabaseOpened;
|
|
}
|
|
|
|
// LoadCurrentSettings
|
|
//
|
|
// Load the current settings from the metabase
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::LoadCurrentSettings()
|
|
{
|
|
CMDValue mbValue;
|
|
BOOL bRet = TRUE;
|
|
|
|
if ( !InitMetabase() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !m_Metabase.GetData( mbValue, MD_APP_DEPENDENCIES ) )
|
|
{
|
|
m_mstrDependencies.Empty();
|
|
}
|
|
else
|
|
{
|
|
if ( ( mbValue.GetDataType() != MULTISZ_METADATA ) ||
|
|
!m_mstrDependencies.Copy( (LPWSTR) mbValue.GetData() )
|
|
)
|
|
{
|
|
// Either wrong type, or the copy failed
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// SaveSettings
|
|
//
|
|
// Save the settings to the metabase
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::SaveSettings()
|
|
{
|
|
CMDValue mbValue;
|
|
|
|
if ( !InitMetabase() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !mbValue.SetValue( MD_APP_DEPENDENCIES, // Metabase property
|
|
0, // Attributes
|
|
IIS_MD_UT_SERVER, // User Type
|
|
MULTISZ_METADATA, // Data Type
|
|
m_mstrDependencies.QueryLen() * sizeof(TCHAR), // Length
|
|
(LPVOID) m_mstrDependencies.QueryMultiSz() ) ) // Data
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return m_Metabase.SetData( mbValue, MD_APP_DEPENDENCIES );
|
|
}
|
|
|
|
// AddUnattendSettings
|
|
//
|
|
// Read the unattend settings from the file, and
|
|
// put them in the list
|
|
//
|
|
// It expects the lines in the unattend to be in the form
|
|
// [InternetServer]
|
|
// ApplicationDependency=CommerceServer,ASP60,INDEX99
|
|
// ApplicationDependency=ExchangeServer,ASP60
|
|
// ApplicationDependency=MyApp,ASPNET20
|
|
//
|
|
// And will product in the m_mstrDependencies:
|
|
// CommerceServer;ASP60,INDEX99\0
|
|
// ExchangeServer;ASP60\0
|
|
// MyApp;ASPNET20\0
|
|
// \0
|
|
//
|
|
// Return:
|
|
// TRUE - Successfully imported all settings
|
|
// FAILED - Failed to import settings
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::AddUnattendSettings()
|
|
{
|
|
BOOL bContinue;
|
|
INFCONTEXT Context;
|
|
TSTR strLine;
|
|
DWORD dwRequiredSize;
|
|
LPTSTR szFirstComma;
|
|
|
|
if ( g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
// Since there is no unattend file, return success
|
|
return TRUE;
|
|
}
|
|
|
|
bContinue = SetupFindFirstLine( g_pTheApp->m_hUnattendFile,
|
|
UNATTEND_FILE_SECTION,
|
|
UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
|
|
&Context);
|
|
|
|
while ( bContinue )
|
|
{
|
|
if ( !SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
|
|
strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
|
|
{
|
|
// Need to resize for larger buffer
|
|
if ( ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) ||
|
|
( dwRequiredSize <= strLine.QuerySize() ) ||
|
|
!strLine.Resize( dwRequiredSize ) ||
|
|
!SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
|
|
strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
|
|
{
|
|
// Failure to either resize, or read in data
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
szFirstComma = _tcschr( strLine.QueryStr(), ',' );
|
|
|
|
if ( !szFirstComma )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR,
|
|
_T("Failed to import Application Dependencies unattend \
|
|
setting '%s=%s' because it is in the wrong format"),
|
|
UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
|
|
strLine.QueryStr() ) );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// Change the first comma to a ';', since the format in the unattend file,
|
|
//and the metabase are different
|
|
*szFirstComma = _T(';');
|
|
|
|
// Remove the old line, if one existed for this Application
|
|
if ( !RemoveOldAppDendency( strLine.QueryStr() ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !m_mstrDependencies.Add( strLine.QueryStr() ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
bContinue = SetupFindNextMatchLine( &Context,
|
|
UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
|
|
&Context);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// RemoveOldAppDendency
|
|
//
|
|
// Since a New Application Dependency line is being added, make sure to
|
|
// remove anylines that are already in the list for an Application
|
|
// with the same name
|
|
//
|
|
// Parameters:
|
|
// szNewLine - The New line to be added
|
|
//
|
|
// Return
|
|
// TRUE - It was removed if necessary
|
|
// FALSE - Failure to remove old Line
|
|
BOOL
|
|
CApplicationDependencies::RemoveOldAppDendency( LPTSTR szNewLine )
|
|
{
|
|
LPTSTR szDelimeter = _tcschr( szNewLine, _T(';') );
|
|
DWORD dwLength;
|
|
DWORD dwCurrent;
|
|
LPTSTR szCurrent;
|
|
|
|
if ( !szDelimeter )
|
|
{
|
|
// This should be in the correct format by the time it gets to us
|
|
ASSERT( szDelimeter );
|
|
return FALSE;
|
|
}
|
|
|
|
// The length on the name, including the ';'
|
|
dwLength = (DWORD) ( szDelimeter + 1 - szNewLine );
|
|
|
|
for ( dwCurrent = 0;
|
|
( szCurrent = m_mstrDependencies.QueryString( dwCurrent ) ) != NULL;
|
|
dwCurrent++ )
|
|
{
|
|
// Compare Strings
|
|
if ( _tcsnicmp( szCurrent, szNewLine, dwLength ) == 0 )
|
|
{
|
|
// This already exists in the list. If the list is correct then
|
|
// it can only be in the list once, so return
|
|
return m_mstrDependencies.Remove( szCurrent, TRUE );
|
|
}
|
|
}
|
|
|
|
// Not found, so no need to remove
|
|
return TRUE;
|
|
}
|
|
|
|
// DoUnattendSettingsExist
|
|
//
|
|
// Do a simple check to see if unattend settings for this
|
|
// property exist. Because if they don't, there is nothing
|
|
// to do.
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::DoUnattendSettingsExist()
|
|
{
|
|
INFCONTEXT Context;
|
|
|
|
if ( g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return SetupFindFirstLine( g_pTheApp->m_hUnattendFile,
|
|
UNATTEND_FILE_SECTION,
|
|
UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
|
|
&Context);
|
|
}
|
|
|
|
// FindApplication
|
|
//
|
|
// Find the application in the list
|
|
//
|
|
// Parameters:
|
|
// szApplicationName [in] - The name of the application to look for
|
|
//
|
|
// Return Values:
|
|
// NULL - Not found
|
|
// pointer - Pointer to item in list
|
|
//
|
|
LPTSTR
|
|
CApplicationDependencies::FindApplication( LPTSTR szApplicationName )
|
|
{
|
|
DWORD dwCurrent;
|
|
LPTSTR szCurrent;
|
|
DWORD dwLength = _tcslen( szApplicationName );
|
|
|
|
ASSERT( szApplicationName );
|
|
|
|
for ( dwCurrent = 0;
|
|
( szCurrent = m_mstrDependencies.QueryString( dwCurrent ) ) != NULL;
|
|
dwCurrent++ )
|
|
{
|
|
// Compare Strings
|
|
if ( ( _tcsnicmp( szCurrent, szApplicationName, dwLength ) == 0 ) &&
|
|
( ( *( szCurrent + dwLength ) == _T('\0') ) ||
|
|
( *( szCurrent + dwLength ) == _T(';') )
|
|
)
|
|
)
|
|
{
|
|
// It has been found
|
|
return szCurrent;
|
|
}
|
|
}
|
|
|
|
// Not found
|
|
return NULL;
|
|
}
|
|
|
|
// DoesApplicationExist
|
|
//
|
|
// Determine if the application extst in the list
|
|
//
|
|
// Parameters:
|
|
// szApplicationName [in] - The name of the application to look for
|
|
//
|
|
// Return Values:
|
|
// TRUE - It exists
|
|
// FALSE - It does not exist
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::DoesApplicationExist( LPTSTR szApplicationName )
|
|
{
|
|
return ( FindApplication( szApplicationName ) != NULL );
|
|
}
|
|
|
|
// AddApplication
|
|
//
|
|
// Add an application to the Application Dependencies list
|
|
//
|
|
// Parameters:
|
|
// szApplication [in] - The name of the Application
|
|
// (ie. "Active Server Pages")
|
|
// Should contain no ';' or ','
|
|
// szDependencies [in] - The dependencies seperated by comma's
|
|
// bReplaceExisting [in] - If an application by the same name is in the
|
|
// list, should we replace it?
|
|
BOOL
|
|
CApplicationDependencies::AddApplication( LPTSTR szApplication,
|
|
LPTSTR szDependencies,
|
|
BOOL bReplaceExisting )
|
|
{
|
|
LPTSTR szOldApplication;
|
|
TSTR strNewApplication;
|
|
|
|
ASSERT( szApplication );
|
|
ASSERT( szDependencies );
|
|
|
|
szOldApplication = FindApplication( szApplication );
|
|
|
|
if ( szOldApplication )
|
|
{
|
|
if ( bReplaceExisting )
|
|
{
|
|
// Remove old item
|
|
if ( !m_mstrDependencies.Remove( szOldApplication, TRUE ) )
|
|
{
|
|
// Failed to remove old item
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Since we don't want to replace, lets exit
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if ( !strNewApplication.Copy( szApplication ) ||
|
|
!strNewApplication.Append( _T(";") ) ||
|
|
!strNewApplication.Append( szDependencies ) ||
|
|
!m_mstrDependencies.Add( strNewApplication.QueryStr() )
|
|
)
|
|
{
|
|
// Failed to construct name, and add it
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// AddDefaults
|
|
//
|
|
// Add the defaults to the list
|
|
//
|
|
BOOL
|
|
CApplicationDependencies::AddDefaults()
|
|
{
|
|
DWORD dwCurrent;
|
|
TSTR strApplicationName;
|
|
|
|
for ( dwCurrent = 0;
|
|
dwCurrent < EXTENSION_ENDOFLIST;
|
|
dwCurrent ++)
|
|
{
|
|
if ( !strApplicationName.LoadString( g_OurExtensions[dwCurrent].dwProductName ) )
|
|
{
|
|
// Failed to add application
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !AddApplication( strApplicationName.QueryStr(),
|
|
g_OurExtensions[dwCurrent].szNotLocalizedGroupName,
|
|
FALSE ) )
|
|
{
|
|
// Failed to add defaults
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Constructor
|
|
//
|
|
CRestrictionList::CRestrictionList()
|
|
{
|
|
m_bMetabaseOpened = FALSE;
|
|
}
|
|
|
|
// InitMetabase
|
|
//
|
|
// Open the metabase, at the correct location for the Restriction List,
|
|
// so that we can read and write to it
|
|
//
|
|
BOOL
|
|
CRestrictionList::InitMetabase()
|
|
{
|
|
if ( m_bMetabaseOpened )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
m_bMetabaseOpened = SUCCEEDED( m_Metabase.OpenNode( METABASEPATH_WWW_ROOT, TRUE ) );
|
|
|
|
return m_bMetabaseOpened;
|
|
}
|
|
|
|
// LoadMSZFromPhysicalMetabase
|
|
//
|
|
// Load a multisz from the physical metabase at /lm/w3svc node
|
|
//
|
|
BOOL
|
|
CRestrictionList::LoadMSZFromPhysicalMetabase( TSTR_MSZ *pmszProperty,
|
|
LPCTSTR szPropertyName )
|
|
{
|
|
TSTR_PATH strMbPath;
|
|
CXMLEdit XMLFile;
|
|
TSTR strTemp;
|
|
|
|
if ( !strMbPath.RetrieveSystemDir() ||
|
|
!strMbPath.PathAppend( CXMLBASE_METABASEPATH ) )
|
|
{
|
|
// Could not construct path, fail
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !XMLFile.Open( strMbPath.QueryStr(), FALSE ) )
|
|
{
|
|
// Could not open file, this might be okay, since
|
|
// it might be a IIS 6.0 upgrade before XML was used
|
|
return TRUE;
|
|
}
|
|
|
|
while ( XMLFile.MovetoNextItem() )
|
|
{
|
|
// Find the IISWeb service node with Location=/LM/W3SVC
|
|
if ( XMLFile.IsEqualItem( METABASE_PHYS_RESTR_UPG_NODETYPE ) &&
|
|
XMLFile.MovetoFirstProperty() &&
|
|
XMLFile.IsEqualProperty( METABASE_PHYS_RESTR_UPG_PROPTYPE ) &&
|
|
XMLFile.IsEqualValue( METABASE_PHYS_RESTR_UPG_PROPVALUE ) )
|
|
{
|
|
// We found it, now lets get the read property
|
|
XMLFile.MovetoFirstProperty();
|
|
|
|
do
|
|
{
|
|
if ( XMLFile.IsEqualProperty( szPropertyName ) )
|
|
{
|
|
// We found the right property, now lets get the value
|
|
if ( !XMLFile.RetrieveCurrentValue( &strTemp ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return LoadMSZFromMultiLineSz( pmszProperty, (LPTSTR) strTemp.QueryStr() );
|
|
}
|
|
} while ( XMLFile.MovetoNextProperty() );
|
|
|
|
// We found the right node, but it did not exist, that is okay, we will just
|
|
// ignore it
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
XMLFile.Close();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// LoadMSZFromMultiLineSz
|
|
//
|
|
// Load a MultiSZ from a Multi Line String with either \r\n or \r
|
|
// seperating them
|
|
//
|
|
BOOL
|
|
CRestrictionList::LoadMSZFromMultiLineSz( TSTR_MSZ *pmszProperty, LPTSTR szSource )
|
|
{
|
|
LPTSTR szCurrent = szSource;
|
|
LPTSTR szTemp;
|
|
TCHAR cTempChar;
|
|
|
|
while ( *szCurrent != '\0' )
|
|
{
|
|
// Skip Spaces at begining
|
|
while ( ( *szCurrent == ' ' ) ||
|
|
( *szCurrent == '\t' ) )
|
|
{
|
|
szCurrent++;
|
|
}
|
|
|
|
szTemp = szCurrent;
|
|
|
|
while ( ( *szTemp != '\0' ) &&
|
|
( *szTemp != '\r' ) &&
|
|
( *szTemp != '\n' ) )
|
|
{
|
|
szTemp++;
|
|
}
|
|
|
|
// Temprorarily NULL Terminate
|
|
cTempChar = *szTemp;
|
|
*szTemp = '\0';
|
|
|
|
if ( !pmszProperty->Add( szCurrent ) )
|
|
{
|
|
// Failed to construct list
|
|
return FALSE;
|
|
}
|
|
|
|
*szTemp = cTempChar;
|
|
if ( ( *szTemp == '\r' ) &&
|
|
( *(szTemp+1) == '\n' ) )
|
|
{
|
|
// Move past \n
|
|
szTemp++;
|
|
}
|
|
|
|
if ( *szTemp != '\0' )
|
|
{
|
|
// Increment one char, to get to next line
|
|
szTemp++;
|
|
}
|
|
|
|
// Start at new line
|
|
szCurrent = szTemp;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// LoadMSZFromMetabase
|
|
//
|
|
// Load a multisz from the metabase
|
|
//
|
|
// Parameters:
|
|
// [out] pmszProperty - The Property that is being extracted
|
|
// [in] dwPropertyID - The ID of the property to be retrieved
|
|
// [in] szMBPath - The sub path to look in
|
|
//
|
|
// Return Values:
|
|
// FALSE - Failed to retrieve
|
|
// TRUE - Retrieved successfully, or it did not exist and we are returning
|
|
// an empty list
|
|
//
|
|
BOOL
|
|
CRestrictionList::LoadMSZFromMetabase( TSTR_MSZ *pmszProperty, DWORD dwPropertyID, LPWSTR szMBPath )
|
|
{
|
|
CMDValue mbValue;
|
|
BOOL bRet = TRUE;
|
|
|
|
if ( !InitMetabase() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !m_Metabase.GetData( mbValue, dwPropertyID, szMBPath ) )
|
|
{
|
|
pmszProperty->Empty();
|
|
}
|
|
else
|
|
{
|
|
if ( ( mbValue.GetDataType() != MULTISZ_METADATA ) ||
|
|
!pmszProperty->Copy( (LPWSTR) mbValue.GetData() )
|
|
)
|
|
{
|
|
// Either wrong type, or the copy failed
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// LoadCurrentSettings
|
|
//
|
|
// Load the current Restriction List Properties.
|
|
//
|
|
// Note: This loads them from the new location, not the old
|
|
// ISAPIRestrictionLiad and CGIRestrictionList locations.
|
|
// There is a seperate function to merge those in.
|
|
//
|
|
BOOL
|
|
CRestrictionList::LoadCurrentSettings()
|
|
{
|
|
return LoadMSZFromMetabase( &m_mstrRestrictionList,
|
|
MD_WEB_SVC_EXT_RESTRICTION_LIST );
|
|
|
|
}
|
|
|
|
// LoadOldFormatSettings
|
|
//
|
|
// Load the old CGIRestrictionList and ISAPIRestrictionList and import
|
|
// them into our new variable
|
|
//
|
|
BOOL
|
|
CRestrictionList::LoadOldFormatSettings( TSTR_MSZ *pmstrCgiRestList, TSTR_MSZ *pmstrIsapiRestList )
|
|
{
|
|
// Load old metabase values
|
|
if ( !LoadMSZFromPhysicalMetabase( pmstrCgiRestList,
|
|
METABASE_PHYS_RESTR_CGI ) ||
|
|
!LoadMSZFromPhysicalMetabase( pmstrIsapiRestList,
|
|
METABASE_PHYS_RESTR_ISAPI ) )
|
|
{
|
|
// Could not load errors
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ImportOldLists
|
|
//
|
|
// Import the Old Restriction Lists into the new list
|
|
// This is only needed for IIS6->IIS6 upgrades, where
|
|
// the old settings were in the CGI/ISAPIRestrictionList
|
|
BOOL
|
|
CRestrictionList::ImportOldLists( TSTR_MSZ &mstrCgiRestList, TSTR_MSZ &mstrIsapiRestList )
|
|
{
|
|
// Import old values into new list
|
|
if ( !ImportOldList( mstrCgiRestList,
|
|
TRUE ) ||
|
|
!ImportOldList( mstrIsapiRestList,
|
|
FALSE )
|
|
)
|
|
{
|
|
// Could not import new values
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// SaveSettings
|
|
//
|
|
// Save the settings to the metabase
|
|
//
|
|
BOOL
|
|
CRestrictionList::SaveSettings()
|
|
{
|
|
CMDValue mbValue;
|
|
|
|
if ( !InitMetabase() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !mbValue.SetValue( MD_WEB_SVC_EXT_RESTRICTION_LIST, // Metabase property
|
|
0, // Attributes
|
|
IIS_MD_UT_SERVER, // User Type
|
|
MULTISZ_METADATA, // Data Type
|
|
m_mstrRestrictionList.QueryLen() * sizeof(TCHAR), // Length
|
|
(LPVOID) m_mstrRestrictionList.QueryMultiSz() ) ) // Data
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return m_Metabase.SetData( mbValue, MD_WEB_SVC_EXT_RESTRICTION_LIST );
|
|
}
|
|
|
|
// AddItem
|
|
//
|
|
// Add an Item to the list
|
|
//
|
|
// Parameters:
|
|
// szInfo [in] - The line containing all the info for the path
|
|
// Format: ExtensionFile=access,path,<UI deleteable>,
|
|
// <short description>,<long description>
|
|
// ie: 1,%windir%\system32\testisapi.dll,TRUE,Test Isapi,My Test Isapi for Foo.com
|
|
// bReplaceExistiing - Should we replace existing
|
|
//
|
|
BOOL
|
|
CRestrictionList::AddItem( LPTSTR szInfo, BOOL bReplaceExisting)
|
|
{
|
|
TSTR strCopy( MAX_PATH );
|
|
LPTSTR pPhysicalPath = NULL;
|
|
LPTSTR pShortDescription = NULL;
|
|
LPTSTR pLongDescription = NULL;
|
|
LPTSTR pCurrent;
|
|
BOOL bAllow = FALSE;
|
|
BOOL bUIDeletable = TRUE; // Different default for Unattend
|
|
|
|
if ( !strCopy.Copy( szInfo ) )
|
|
{
|
|
// Could not copy line
|
|
return FALSE;
|
|
}
|
|
|
|
pCurrent = strCopy.QueryStr();
|
|
|
|
// Set access
|
|
bAllow = ( *( pCurrent ) == _T('1') ) &&
|
|
( *( pCurrent + 1 ) == _T(',') );
|
|
pCurrent = _tcschr( pCurrent, _T(',') );
|
|
|
|
if ( !pCurrent )
|
|
{
|
|
// Without even a path, there is nothing we can do
|
|
return FALSE;
|
|
}
|
|
|
|
// Set Physcial Path
|
|
pCurrent++; // Move past ','
|
|
pPhysicalPath = pCurrent;
|
|
|
|
// Find UI deletable
|
|
pCurrent = _tcschr( pCurrent, _T(',') );
|
|
|
|
if ( pCurrent )
|
|
{
|
|
// Found UI Deletable
|
|
// Null terminate path
|
|
*(pCurrent++) = _T('\0');
|
|
bUIDeletable = ( *( pCurrent ) == _T('1') ) &&
|
|
( *( pCurrent + 1 ) == _T(',') );
|
|
|
|
// Jump to next field
|
|
pCurrent = _tcschr( pCurrent, _T(',') );
|
|
}
|
|
|
|
if ( pCurrent )
|
|
{
|
|
// Found Short Description
|
|
pCurrent++;
|
|
pShortDescription = pCurrent;
|
|
|
|
// Jump to next field
|
|
pCurrent = _tcschr( pCurrent, _T(',') );
|
|
}
|
|
|
|
if ( pCurrent )
|
|
{
|
|
// Found Long Description
|
|
// Null terminal Short Description
|
|
*(pCurrent++) = _T('\0');
|
|
pLongDescription = pCurrent;
|
|
}
|
|
|
|
return AddItem( pPhysicalPath,
|
|
pShortDescription,
|
|
pLongDescription,
|
|
bAllow,
|
|
bUIDeletable,
|
|
bReplaceExisting );
|
|
}
|
|
|
|
// RetrieveDefaultsifKnow
|
|
//
|
|
// Retrieve defaults for the physical image if they are known
|
|
//
|
|
BOOL
|
|
CRestrictionList::RetrieveDefaultsifKnow( LPTSTR szPhysicalPath,
|
|
LPTSTR *pszGroupId,
|
|
TSTR *pstrDescription,
|
|
LPBOOL pbDeleteable )
|
|
{
|
|
DWORD dwIndex;
|
|
TSTR_PATH strFullPath( MAX_PATH );
|
|
|
|
ASSERT( szPhysicalPath );
|
|
ASSERT( pszGroupId );
|
|
ASSERT( pstrDescription );
|
|
ASSERT( pbDeleteable );
|
|
|
|
for ( dwIndex = 0;
|
|
dwIndex < EXTENSION_ENDOFLIST;
|
|
dwIndex++ )
|
|
{
|
|
if ( !strFullPath.Copy( g_pTheApp->m_csPathInetsrv.GetBuffer(0) ) ||
|
|
!strFullPath.PathAppend( g_OurExtensions[dwIndex].szFileName ) )
|
|
{
|
|
// Failed to create full path, so skip to next one
|
|
continue;
|
|
}
|
|
|
|
if ( strFullPath.IsEqual( szPhysicalPath, FALSE ) )
|
|
{
|
|
*pszGroupId = g_OurExtensions[dwIndex].szNotLocalizedGroupName;
|
|
*pbDeleteable = g_OurExtensions[dwIndex].bUIDeletable;
|
|
|
|
if ( !pstrDescription->LoadString( g_OurExtensions[dwIndex].dwProductName ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Done seaching
|
|
return TRUE;
|
|
}
|
|
|
|
} // for ( dwIndex = ...
|
|
|
|
// Return TRUE because we didn't fail
|
|
return TRUE;
|
|
} // RetrieveDefaultsifKnow
|
|
|
|
// AddItem
|
|
//
|
|
// Add an item to the list.
|
|
//
|
|
// Parameters:
|
|
// szPhysicalPath - The path of the executable
|
|
// szGroupId - The group name
|
|
// szDescription - The description for the executable
|
|
// bAllow - TRUE==allow, FALSE==deny
|
|
// bDeleteable - TRUE==UI deletable, FALSE==not UI deletable
|
|
// bReplaceExisting - If it is already in the list, do we update it?
|
|
//
|
|
BOOL
|
|
CRestrictionList::AddItem( LPTSTR szPhysicalPath,
|
|
LPTSTR szGroupId,
|
|
LPTSTR szDescription,
|
|
BOOL bAllow,
|
|
BOOL bDeleteable,
|
|
BOOL bReplaceExisting)
|
|
{
|
|
LPTSTR szCurrentItem;
|
|
LPTSTR szCurentPath;
|
|
DWORD dwCurrentIndex = 0;
|
|
TSTR strNewItem;
|
|
TSTR_PATH strPhysicalPath;
|
|
TSTR strDescription;
|
|
|
|
ASSERT( szPhysicalPath );
|
|
|
|
if ( !strPhysicalPath.Copy( szPhysicalPath ) ||
|
|
!strPhysicalPath.ExpandEnvironmentVariables() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( szDescription &&
|
|
!strDescription.Copy( szDescription) )
|
|
{
|
|
// Failed to do copy
|
|
return FALSE;
|
|
}
|
|
|
|
// Fill in the Default valus if this is one of our isapi's
|
|
if ( !RetrieveDefaultsifKnow( szPhysicalPath, &szGroupId, &strDescription, &bDeleteable ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
while ( ( szCurrentItem =
|
|
m_mstrRestrictionList.QueryString( dwCurrentIndex++ ) ) != NULL )
|
|
{
|
|
szCurentPath = _tcschr( szCurrentItem, L',' );
|
|
|
|
if ( szCurentPath == NULL )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
szCurentPath++;
|
|
|
|
if ( ( _tcsnicmp( szCurentPath,
|
|
strPhysicalPath.QueryStr(),
|
|
strPhysicalPath.QueryLen() ) == 0 ) &&
|
|
( ( *( szCurentPath + strPhysicalPath.QueryLen() ) == ',' ) ||
|
|
( *( szCurentPath + strPhysicalPath.QueryLen() ) == '\0' ) )
|
|
)
|
|
{
|
|
if ( bReplaceExisting )
|
|
{
|
|
if ( !m_mstrRestrictionList.Remove( szCurrentItem, TRUE ) )
|
|
{
|
|
// Failed to remove item
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// It succeeded, because we didn't want to replace existing
|
|
return TRUE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
} // while ( ... )
|
|
|
|
// Copy <allow/deny>,<physical path>,<ui deletable>
|
|
if ( !strNewItem.Copy( bAllow ? _T("1") : _T("0") ) ||
|
|
!strNewItem.Append( _T(",") ) ||
|
|
!strNewItem.Append( strPhysicalPath.QueryStr() ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Append Group
|
|
if ( ( szGroupId || ( strDescription.QueryLen() != 0 ) ) &&
|
|
( !strNewItem.Append( _T(",") ) ||
|
|
!strNewItem.Append( bDeleteable ? _T("1") : _T("0") ) ||
|
|
!strNewItem.Append( _T(",") ) ||
|
|
!strNewItem.Append( szGroupId ? szGroupId : _T("") )
|
|
)
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Append Description
|
|
if ( ( strDescription.QueryLen() != 0 ) &&
|
|
( !strNewItem.Append( _T(",") ) ||
|
|
!strNewItem.Append( strDescription.QueryStr() )
|
|
)
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Add it to the list
|
|
return m_mstrRestrictionList.Add( strNewItem.QueryStr() );
|
|
}
|
|
|
|
// ImportOldList
|
|
//
|
|
// Import settings from the old format to the new format
|
|
//
|
|
// Old Format:
|
|
// AllowDenyFlagforAll - Inidcates if default is to allow or deny
|
|
// ExtensionPhysicalPath - Exe to do opposite of default
|
|
// ExtensionPhysicalPath - Exe to do opposite of default
|
|
//
|
|
// New Format:
|
|
// AllowDenyFlag,*.dll
|
|
// AllowDenyFlag,*.exe
|
|
// AllowDenyFlag,ExtensionPhysicalPath,UIDeletableFlag,GroupID,Description
|
|
//
|
|
// AllowDenyFlag - 0 or 1 depending on allowed (1) or not allowed (0)
|
|
// ExtensionPhysicalPath - Physical Path to dll
|
|
// UIDeletableFlag - 0 for not ui deletable, 1 for UI deletable
|
|
// GroupID - Id of the group
|
|
// Descrition - Locallized Description
|
|
//
|
|
BOOL
|
|
CRestrictionList::ImportOldList( TSTR_MSZ &mstrOldStyleRestrictionList,
|
|
BOOL bCgiList)
|
|
{
|
|
LPTSTR szCurrentItem;
|
|
DWORD dwIndex = 1;
|
|
BOOL bDefaultAllow = TRUE;
|
|
LPTSTR szDefault;
|
|
|
|
// Take the first string as the default
|
|
szDefault = mstrOldStyleRestrictionList.QueryString( 0 );
|
|
bDefaultAllow = szDefault ? ( *szDefault == '1' ? TRUE : FALSE ) : FALSE;
|
|
|
|
if ( *szDefault == '\0' )
|
|
{
|
|
// There is nothing to import since the list is empty,
|
|
// so lets quit
|
|
return TRUE;
|
|
}
|
|
|
|
if ( !AddItem( bCgiList ? _T("*.exe") : _T("*.dll"),
|
|
NULL, NULL, bDefaultAllow, FALSE, FALSE ) )
|
|
{
|
|
// Could not set default for Restriction List
|
|
return FALSE;
|
|
}
|
|
|
|
// Start importing starting at item[1]
|
|
while ( ( szCurrentItem =
|
|
mstrOldStyleRestrictionList.QueryString( dwIndex++ ) ) != NULL )
|
|
{
|
|
if ( *szCurrentItem == _T('\0') )
|
|
{
|
|
// Empty line
|
|
continue;
|
|
}
|
|
|
|
if ( !AddItem( szCurrentItem, // Path
|
|
NULL, // Group
|
|
NULL, // Description
|
|
!bDefaultAllow, // bAllow
|
|
TRUE,
|
|
FALSE ) )
|
|
{
|
|
// Failed to add item
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if ( !bCgiList )
|
|
{
|
|
// Since we have imported all the ones we can. We should now add all IIS's
|
|
// defaults, or they will be added later with the wrong default
|
|
// BUGBUG:: Right now this assumes the defaults are all ISAPI's, which they
|
|
// are for now
|
|
if ( !AddDefaults( bDefaultAllow ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// AddDefaults
|
|
//
|
|
// Add the defaults to the restriction list
|
|
// If we fail, then try to add as many as possible
|
|
//
|
|
// Parameters
|
|
// bAllOthersDefault - Should *.dll and *.exe be allowed or
|
|
// denied by default?
|
|
//
|
|
BOOL
|
|
CRestrictionList::AddDefaults( BOOL bAllOthersDefault )
|
|
{
|
|
DWORD dwIndex;
|
|
BOOL bRet = TRUE;
|
|
TSTR_PATH strFullPath;
|
|
|
|
if ( !AddItem( _T("*.dll"), NULL, NULL, bAllOthersDefault,
|
|
FALSE, FALSE ) ||
|
|
!AddItem( _T("*.exe"), NULL, NULL, bAllOthersDefault,
|
|
FALSE, FALSE ) )
|
|
{
|
|
// Failed to add dll and exe defaults
|
|
bRet = FALSE;
|
|
}
|
|
|
|
for ( dwIndex = 0;
|
|
dwIndex < EXTENSION_ENDOFLIST;
|
|
dwIndex++ )
|
|
{
|
|
if ( !strFullPath.Copy( g_pTheApp->m_csPathInetsrv.GetBuffer(0) ) ||
|
|
!strFullPath.PathAppend( g_OurExtensions[dwIndex].szFileName ) )
|
|
{
|
|
// Failed to create full path, so skip to next one
|
|
bRet = FALSE;
|
|
continue;
|
|
}
|
|
|
|
// The Group and Description are sent in as NULL, because they will
|
|
// be filled in automatically by AddItem
|
|
if ( !AddItem( strFullPath.QueryStr(), // Physical Path
|
|
NULL, // Group Name
|
|
NULL, // Description
|
|
bAllOthersDefault, // Allowed/Denied
|
|
FALSE, // Not UI Deletable
|
|
FALSE ) ) // Do not replace existing
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// IsEmpty
|
|
//
|
|
// Is the restrictionList Empty?
|
|
//
|
|
BOOL
|
|
CRestrictionList::IsEmpty()
|
|
{
|
|
return m_mstrRestrictionList.QueryLen() == 1;
|
|
}
|
|
|
|
// AddUnattendSettings
|
|
//
|
|
// Read the unattend settings from the file, and
|
|
// put them in the list
|
|
//
|
|
// It expects the lines in the unattend to be in the form
|
|
// [InternetServer]
|
|
// ExtensionFile=0,*.dll
|
|
// ExtensionFile=1,*.exe
|
|
// ExtensionFile=1,%windir%\system32\testisapi.dll,0,Test Isapi,My Test Isapi for Foo.com
|
|
//
|
|
// And will product in the m_mstrDependencies:
|
|
// 0,*.dll\0
|
|
// 1,*,exe\0
|
|
// d:\whistler\system32\testisapi.dll,TRUE,Test Isapi,My Test Isapi for Foo.com\0
|
|
// \0
|
|
//
|
|
// Return:
|
|
// TRUE - Successfully imported all settings
|
|
// FAILED - Failed to import settings
|
|
//
|
|
BOOL
|
|
CRestrictionList::AddUnattendSettings()
|
|
{
|
|
BOOL bContinue;
|
|
INFCONTEXT Context;
|
|
TSTR strLine;
|
|
DWORD dwRequiredSize;
|
|
|
|
if ( g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
// Since there is no unattend file, return success
|
|
return TRUE;
|
|
}
|
|
|
|
bContinue = SetupFindFirstLine( g_pTheApp->m_hUnattendFile,
|
|
UNATTEND_FILE_SECTION,
|
|
UNATTEND_INETSERVER_EXTENSIONRESTRICTIONLIST,
|
|
&Context);
|
|
|
|
while ( bContinue )
|
|
{
|
|
if ( !SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
|
|
strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
|
|
{
|
|
// Need to resize for larger buffer
|
|
if ( ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) ||
|
|
( dwRequiredSize <= strLine.QuerySize() ) ||
|
|
!strLine.Resize( dwRequiredSize ) ||
|
|
!SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
|
|
strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
|
|
{
|
|
// Failure to either resize, or read in data
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if ( !AddItem( strLine.QueryStr(), TRUE ) )
|
|
{
|
|
// Failed to add item
|
|
return FALSE;
|
|
}
|
|
|
|
bContinue = SetupFindNextMatchLine( &Context,
|
|
UNATTEND_INETSERVER_EXTENSIONRESTRICTIONLIST,
|
|
&Context);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// UpdateItem
|
|
//
|
|
// Update an Item with the right value
|
|
//
|
|
BOOL
|
|
CRestrictionList::UpdateItem( LPTSTR szPhysicalPath,
|
|
LPTSTR szGroupId,
|
|
LPTSTR szDescription,
|
|
BOOL bAllow,
|
|
BOOL bDeleteable )
|
|
{
|
|
return AddItem( szPhysicalPath, szGroupId, szDescription,
|
|
bAllow, bDeleteable, TRUE );
|
|
}
|
|
|
|
// FindItemByGroup
|
|
//
|
|
// Find an Item by the Group ID
|
|
//
|
|
LPTSTR
|
|
CRestrictionList::FindItemByGroup( LPTSTR szGroupId )
|
|
{
|
|
LPTSTR szCurrent;
|
|
LPTSTR szCurrentItem;
|
|
DWORD dwLength;
|
|
DWORD dwCurrentIndex = 0;
|
|
|
|
dwLength = _tcslen( szGroupId );
|
|
|
|
while ( ( szCurrentItem =
|
|
m_mstrRestrictionList.QueryString( dwCurrentIndex++ ) ) != NULL )
|
|
{
|
|
// Get Physical Path
|
|
szCurrent = _tcschr( szCurrentItem, L',' );
|
|
|
|
if ( szCurrent )
|
|
{
|
|
// Get UI Deletable
|
|
szCurrent++;
|
|
szCurrent = _tcschr( szCurrent, L',' );
|
|
}
|
|
|
|
if ( szCurrent )
|
|
{
|
|
// Get Group ID
|
|
szCurrent++;
|
|
szCurrent = _tcschr( szCurrent, L',' );
|
|
}
|
|
|
|
if ( szCurrent )
|
|
{
|
|
// Since we found the group id, lets compare
|
|
szCurrent++;
|
|
if ( ( _tcsnicmp( szGroupId,
|
|
szCurrent,
|
|
dwLength ) == 0 ) &&
|
|
( ( *( szCurrent + dwLength ) == ',' ) ||
|
|
( *( szCurrent + dwLength ) == '\0' ) )
|
|
)
|
|
{
|
|
// Found a match, return the item
|
|
return szCurrentItem;
|
|
}
|
|
}
|
|
} // while ( ... )
|
|
|
|
// Could not find
|
|
return NULL;
|
|
}
|
|
|
|
// Find an item
|
|
LPTSTR
|
|
CRestrictionList::FindItemByPhysicalPath( LPTSTR szPhysicalPath )
|
|
{
|
|
LPTSTR szCurrent;
|
|
LPTSTR szCurrentItem;
|
|
DWORD dwLength;
|
|
DWORD dwCurrentIndex = 0;
|
|
|
|
dwLength = _tcslen( szPhysicalPath );
|
|
|
|
while ( ( szCurrentItem =
|
|
m_mstrRestrictionList.QueryString( dwCurrentIndex++ ) ) != NULL )
|
|
{
|
|
// Get Physical Path
|
|
szCurrent = _tcschr( szCurrentItem, L',' );
|
|
|
|
if ( szCurrent )
|
|
{
|
|
// Since we found the group id, lets compare
|
|
szCurrent++;
|
|
if ( ( _tcsnicmp( szPhysicalPath,
|
|
szCurrent,
|
|
dwLength ) == 0 ) &&
|
|
( ( *( szCurrent + dwLength ) == ',' ) ||
|
|
( *( szCurrent + dwLength ) == '\0' ) )
|
|
)
|
|
{
|
|
// Found a match, return the item
|
|
return szCurrentItem;
|
|
}
|
|
}
|
|
} // while ( ... )
|
|
|
|
// Could not find
|
|
return NULL;
|
|
}
|
|
|
|
// IsEnabled
|
|
//
|
|
// Check to see if the particular item is enabled
|
|
// Note: Only works for dll's right now
|
|
//
|
|
// Return Values:
|
|
// TRUE - It is enabled
|
|
// FALSE - Not enabled ( default if could not determine )
|
|
//
|
|
// Note: Since Core defaults to denied, we init bEnabled to FALSE
|
|
//
|
|
BOOL
|
|
CRestrictionList::IsEnabled( LPTSTR szGroupId, LPBOOL pbIsEnabled )
|
|
{
|
|
BOOL bEnabled = FALSE;
|
|
LPTSTR szItem = FindItemByGroup( szGroupId );
|
|
|
|
if ( szItem )
|
|
{
|
|
// See if that item is enabled
|
|
bEnabled = ( *szItem == _T('1') );
|
|
}
|
|
else
|
|
{
|
|
// Since this item was not found, lets take the default
|
|
szItem = FindItemByPhysicalPath( _T("*.dll") );
|
|
|
|
if ( szItem )
|
|
{
|
|
bEnabled = ( *szItem == _T('1') );
|
|
}
|
|
}
|
|
|
|
*pbIsEnabled = bEnabled;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|