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.
1057 lines
27 KiB
1057 lines
27 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
metabase.cxx
|
|
|
|
Abstract:
|
|
|
|
Class that is used to modify the metabase
|
|
|
|
Author:
|
|
|
|
Christopher Achille (cachille)
|
|
|
|
Project:
|
|
|
|
Internet Services Setup
|
|
|
|
Revision History:
|
|
|
|
June 2001: Created
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "iadm.h"
|
|
#include "iiscnfgp.h"
|
|
#include "mdkey.h"
|
|
#include "mdentry.h"
|
|
#include "metabase.hxx"
|
|
#include "iiscnfg.h"
|
|
#include "strfn.h"
|
|
|
|
// function: GetSizeBasedOnMetaType
|
|
//
|
|
// Returns the DataSize for an object based on its type
|
|
//
|
|
DWORD
|
|
CMetaBase::GetSizeBasedOnMetaType(DWORD dwDataType,LPTSTR szString)
|
|
{
|
|
DWORD dwRet = 0;
|
|
|
|
switch (dwDataType)
|
|
{
|
|
case DWORD_METADATA:
|
|
dwRet = 4;
|
|
break;
|
|
case STRING_METADATA:
|
|
case EXPANDSZ_METADATA:
|
|
if (szString == NULL)
|
|
{
|
|
dwRet = 0;
|
|
}
|
|
else
|
|
{
|
|
dwRet = (_tcslen((LPTSTR)szString) + 1) * sizeof(TCHAR);
|
|
}
|
|
break;
|
|
case MULTISZ_METADATA:
|
|
if (szString == NULL)
|
|
{
|
|
dwRet = 0;
|
|
}
|
|
else
|
|
{
|
|
dwRet = GetMultiStrSize((LPTSTR)szString) * sizeof(TCHAR);
|
|
}
|
|
break;
|
|
case BINARY_METADATA:
|
|
break;
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
// function: FindStringinMultiSz
|
|
//
|
|
// Finds a string inside of a MultiSz
|
|
//
|
|
// Parameters:
|
|
// szMultiSz - The MultiSz to search
|
|
// szSearchString - The String to find
|
|
//
|
|
// Return:
|
|
// True - It was found
|
|
// False - It was not found
|
|
BOOL
|
|
CMetaBase::FindStringinMultiSz(LPTSTR szMultiSz, LPTSTR szSearchString)
|
|
{
|
|
LPTSTR szSearchCurrent;
|
|
|
|
do
|
|
{
|
|
szSearchCurrent = szSearchString;
|
|
while ( ( *szMultiSz != '\0' ) &&
|
|
( *szSearchCurrent != '\0' ) &&
|
|
( *szMultiSz == *szSearchCurrent ))
|
|
{
|
|
// While the strings are the same, and they do not hit a null terminator
|
|
szMultiSz++;
|
|
szSearchCurrent++;
|
|
}
|
|
|
|
if ( ( *szMultiSz == '\0' ) &&
|
|
( *szMultiSz == *szSearchCurrent )
|
|
)
|
|
{
|
|
// The strings matched
|
|
return TRUE;
|
|
}
|
|
|
|
while ( *szMultiSz != '\0' )
|
|
{
|
|
// Go to the end of this string
|
|
szMultiSz++;
|
|
}
|
|
|
|
// Step right past the string terminator
|
|
szMultiSz++;
|
|
} while (*szMultiSz);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: VerifyParameters
|
|
//
|
|
// Verify the parameters are correct
|
|
//
|
|
BOOL
|
|
CMetaBase_SetValue::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
if ( ( ( ciParams.GetNumberOfItems() == 7 ) ||
|
|
( ( ciParams.GetNumberOfItems() == 8 ) && ciParams.IsNumber(7) )
|
|
)
|
|
&&
|
|
ciParams.IsNumber(1) &&
|
|
ciParams.IsNumber(2) &&
|
|
ciParams.IsNumber(3) &&
|
|
ciParams.IsNumber(4) &&
|
|
ciParams.IsNumber(5)
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// funtion: DoInternalWork
|
|
//
|
|
// Set a value in the metabase
|
|
//
|
|
// Parameters:
|
|
// ciList - Parameters for OpenNode, they are the following:
|
|
// 0 -Location
|
|
// 1- Id
|
|
// 2- Inheritable
|
|
// 3- UserType
|
|
// 4- DataType
|
|
// 5- Len
|
|
// 6- Value
|
|
// 7- bDontReplace - Should we replace the value if one already exists? (default==false)
|
|
BOOL
|
|
CMetaBase_SetValue::DoInternalWork(CItemList &ciParams)
|
|
{
|
|
CMDKey cmdKey;
|
|
CMDValue cmdMetaValue;
|
|
DWORD dwSize = ciParams.GetNumber(5);
|
|
BOOL bRet = TRUE;
|
|
|
|
if ( FAILED(cmdKey.OpenNode(ciParams.GetItem(0) ) ) )
|
|
{
|
|
// Could not open the key, so we fail
|
|
return FALSE;
|
|
}
|
|
|
|
if (dwSize == 0)
|
|
{
|
|
dwSize = GetSizeBasedOnMetaType(ciParams.GetNumber(4),ciParams.GetItem(6));
|
|
}
|
|
|
|
if ( ( ciParams.GetNumberOfItems() == 8 ) && ( ciParams.GetNumber(7) == 1 ) )
|
|
{
|
|
// Make sure the value does not exist yet, because we don't want to replace the old one
|
|
bRet = !cmdKey.GetData( cmdMetaValue, ciParams.GetNumber(1) );
|
|
}
|
|
|
|
if ( bRet )
|
|
{
|
|
// Set the value for this node
|
|
cmdMetaValue.SetValue(ciParams.GetNumber(1),
|
|
ciParams.GetNumber(2),
|
|
ciParams.GetNumber(3),
|
|
ciParams.GetNumber(4),
|
|
dwSize,
|
|
(LPTSTR) ciParams.GetItem(6));
|
|
|
|
bRet = cmdKey.SetData(cmdMetaValue, ciParams.GetNumber(1));
|
|
}
|
|
|
|
cmdKey.Close();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
// Return the Method Name for this Class
|
|
//
|
|
LPTSTR
|
|
CMetaBase_SetValue::GetMethodName()
|
|
{
|
|
return _T("Metabase_SetValue");
|
|
}
|
|
|
|
// function: VerifyParameters
|
|
//
|
|
// Verify the parameters are correct
|
|
//
|
|
BOOL
|
|
CMetaBase_DelIDOnEverySite::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
if ( ( ciParams.GetNumberOfItems() == 2 ) &&
|
|
ciParams.IsNumber(0) &&
|
|
ciParams.IsNumber(1)
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// funtion: DoInternalWork
|
|
//
|
|
// Set a value in the metabase
|
|
//
|
|
// Parameters:
|
|
// ciList - Parameters for OpenNode, they are the following:
|
|
// 0 - Id
|
|
// 1 - Metabase Data Type
|
|
BOOL
|
|
CMetaBase_DelIDOnEverySite::DoInternalWork(CItemList &ciParams)
|
|
{
|
|
CMDKey cmdKey;
|
|
DWORD dwId = ciParams.GetNumber(0);
|
|
DWORD dwType = ciParams.GetNumber(1);
|
|
BOOL bRet;
|
|
CStringList cslpathList;
|
|
POSITION pos;
|
|
CString csPath;
|
|
WCHAR wchKeyPath[_MAX_PATH];
|
|
LPWSTR szwKeyPath = wchKeyPath;
|
|
CString csBasePath = _T("LM/W3SVC");
|
|
|
|
if ( FAILED( cmdKey.OpenNode( csBasePath ) ) )
|
|
{
|
|
// Could not open the key, so we fail
|
|
return FALSE;
|
|
}
|
|
|
|
// get datapaths on the specified ID.
|
|
if (FAILED( cmdKey.GetDataPaths( dwId, dwType, cslpathList) ))
|
|
{
|
|
// Could not GetDataPaths for this value
|
|
return FALSE;
|
|
}
|
|
|
|
// close it so that we can open the various
|
|
// other nodes that returned and delete the values from them
|
|
cmdKey.Close();
|
|
|
|
pos = cslpathList.GetHeadPosition();
|
|
while ( NULL != pos )
|
|
{
|
|
bRet = TRUE;
|
|
csPath = cslpathList.GetNext( pos );
|
|
//iisDebugOut((LOG_TYPE_TRACE,_T("%s"),csPath));
|
|
|
|
#if defined(UNICODE) || defined(_UNICODE)
|
|
szwKeyPath = csPath.GetBuffer(0);
|
|
#else
|
|
if (MultiByteToWideChar(CP_ACP, 0, (LPCSTR)csPath.GetBuffer(0), -1, (LPWSTR)wchKeyPath, _MAX_PATH)==0)
|
|
{
|
|
// We could not convert the string to wide, so lets skip this one
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
// make a special case of the "/" path
|
|
if ( wcscmp( szwKeyPath, L"/" ) != 0 )
|
|
{
|
|
//iisDebugOut((LOG_TYPE_TRACE,_T("%s -- del"),csPath));
|
|
CString csNewPath;
|
|
csNewPath = csBasePath + szwKeyPath;
|
|
|
|
if ( SUCCEEDED(cmdKey.OpenNode(csNewPath) ) )
|
|
{
|
|
if ( FAILED(cmdKey.DeleteData(dwId, dwType) ) )
|
|
{
|
|
// i guess we don't need to report it..
|
|
}
|
|
cmdKey.Close();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
// Return the Method Name for this Class
|
|
//
|
|
LPTSTR
|
|
CMetaBase_DelIDOnEverySite::GetMethodName()
|
|
{
|
|
return _T("CMetaBase_DelIDOnEverySite");
|
|
}
|
|
|
|
// function: VerifyParameters
|
|
//
|
|
// Verify the parameters are correct
|
|
//
|
|
BOOL
|
|
CMetaBase_IsAnotherSiteonPort80::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
return ( ciParams.GetNumberOfItems() == 0 );
|
|
}
|
|
|
|
// function: FindSiteUsing80
|
|
//
|
|
// Find a Site that is using port80
|
|
//
|
|
// Parameters:
|
|
// cmdKey - The key to the metabase node
|
|
// dwId - The id of the item to find.
|
|
//
|
|
// Return
|
|
// TRUE - It has been found
|
|
// FALSE - It has not been found
|
|
BOOL
|
|
CMetaBase_IsAnotherSiteonPort80::SearchMultiSzforPort80(CMDKey &cmdKey, DWORD dwId)
|
|
{
|
|
CStringList cslpathList;
|
|
POSITION pos;
|
|
CString csPath;
|
|
CMDValue cmdValue;
|
|
WCHAR wchKeyPath[_MAX_PATH];
|
|
LPWSTR szwKeyPath = wchKeyPath;
|
|
|
|
if (FAILED( cmdKey.GetDataPaths( dwId, MULTISZ_METADATA, cslpathList) ))
|
|
{
|
|
// Could not GetDataPaths for this value
|
|
return FALSE;
|
|
}
|
|
|
|
pos = cslpathList.GetHeadPosition();
|
|
|
|
while ( NULL != pos )
|
|
{
|
|
csPath = cslpathList.GetNext( pos );
|
|
|
|
#if defined(UNICODE) || defined(_UNICODE)
|
|
szwKeyPath = csPath.GetBuffer(0);
|
|
#else
|
|
if (MultiByteToWideChar(CP_ACP, 0, (LPCSTR)csPath.GetBuffer(0), -1, (LPWSTR)wchKeyPath, _MAX_PATH)==0)
|
|
{
|
|
// We could not convert the string to wide, so lets skip this one
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
if ( ( wcscmp( szwKeyPath, L"/1/" ) != 0 ) &&
|
|
( cmdKey.GetData( cmdValue, dwId, szwKeyPath ) ) &&
|
|
( cmdValue.GetDataType() == MULTISZ_METADATA ) &&
|
|
( FindStringinMultiSz( (LPTSTR) cmdValue.GetData(), _T(":80:") ) )
|
|
)
|
|
{
|
|
if ( ( !cmdKey.GetData( cmdValue, MD_SERVER_AUTOSTART, szwKeyPath ) ) ||
|
|
( !cmdValue.IsEqual( DWORD_METADATA, 4, (DWORD) 0 ) )
|
|
)
|
|
{
|
|
// If GetData failed, or it succedded and the value is not 0, then we
|
|
// have found a match.
|
|
return TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: IsAnotherSiteonPort80
|
|
//
|
|
// Reports back whether another site besides /W3SVC/1 is configured to bind to port 80
|
|
// AND has AutoStart set to True
|
|
//
|
|
// Parameters
|
|
// None
|
|
//
|
|
// Return
|
|
// TRUE - Another site is running on port 80
|
|
// FALSE - No other site is running on port 80
|
|
BOOL
|
|
CMetaBase_IsAnotherSiteonPort80::DoInternalWork(CItemList &ciList)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
CMDKey cmdKey;
|
|
|
|
if ( FAILED( cmdKey.OpenNode( _T("LM/W3SVC") ) ) )
|
|
{
|
|
// Could not open the w3svc node
|
|
return FALSE;
|
|
}
|
|
|
|
if ( SearchMultiSzforPort80( cmdKey, MD_SERVER_BINDINGS) ||
|
|
SearchMultiSzforPort80( cmdKey, MD_SECURE_BINDINGS)
|
|
)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
cmdKey.Close();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
// Return the Method Name for this Class
|
|
//
|
|
LPTSTR
|
|
CMetaBase_IsAnotherSiteonPort80::GetMethodName()
|
|
{
|
|
return _T("Metabase_IsAnotherSiteonPort80");
|
|
}
|
|
|
|
|
|
// function: VerifyParameters
|
|
//
|
|
// Verify the parameters are correct
|
|
//
|
|
BOOL
|
|
CMetaBase_VerifyValue::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
if ( ( ciParams.GetNumberOfItems() == 5 ) &&
|
|
ciParams.IsNumber(1) &&
|
|
ciParams.IsNumber(2)
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
// Return the Method Name for this Class
|
|
//
|
|
LPTSTR
|
|
CMetaBase_VerifyValue::GetMethodName()
|
|
{
|
|
return _T("Metabase_VerifyValue");
|
|
}
|
|
|
|
// function: VerifyValue::DoWork
|
|
//
|
|
// Verify that the value in the particular metabase location, matches the
|
|
// value in param[4]. If it does, return true.
|
|
//
|
|
// Parameters
|
|
// 0 - Metabase Location
|
|
// 1 - Metabase Id
|
|
// 2 - Metabase Data Type
|
|
// 3 - Data Length = 0 (default value is 0 (must calculate))
|
|
// 4 - Metabase Value
|
|
//
|
|
// Return
|
|
// TRUE - The values match
|
|
// FALSE - The values do not match
|
|
BOOL
|
|
CMetaBase_VerifyValue::DoInternalWork(CItemList &ciList)
|
|
{
|
|
CMDKey cmdKey;
|
|
CMDValue cmdValue;
|
|
DWORD dwSize = ciList.GetNumber(3);
|
|
BOOL bRet = FALSE;
|
|
|
|
if ( FAILED( cmdKey.OpenNode( ciList.GetItem(0) ) ) )
|
|
{
|
|
// Could not open the w3svc node
|
|
return FALSE;
|
|
}
|
|
|
|
if (dwSize == 0)
|
|
{
|
|
dwSize = GetSizeBasedOnMetaType(ciList.GetNumber(2),ciList.GetItem(4));
|
|
}
|
|
|
|
if ( cmdKey.GetData( cmdValue, ciList.GetNumber(1) ) )
|
|
{
|
|
if ( ( ( ciList.GetNumber(2) == DWORD_METADATA ) &&
|
|
( cmdValue.IsEqual( ciList.GetNumber(2), dwSize, (DWORD) ciList.GetNumber(4) ) )
|
|
) ||
|
|
( ( ciList.GetNumber(2) != DWORD_METADATA ) &&
|
|
( cmdValue.IsEqual( ciList.GetNumber(2), dwSize, (LPVOID) ciList.GetItem(4) ) )
|
|
)
|
|
)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
cmdKey.Close();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
// Return the Method Name for this Class
|
|
//
|
|
LPTSTR
|
|
CMetaBase_ImportRestrictionList::GetMethodName()
|
|
{
|
|
return _T("Metabase_ImportRestrictionList");
|
|
}
|
|
|
|
// function: VerifyParameters
|
|
//
|
|
// Verify the parameters are correct
|
|
//
|
|
BOOL
|
|
CMetaBase_ImportRestrictionList::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
return ( (ciParams.GetNumberOfItems() == 3) &&
|
|
( ciParams.IsNumber(1) )
|
|
);
|
|
}
|
|
|
|
// function: CreateMultiSzFromList
|
|
//
|
|
// Create a MultiSz from a List of comman delim items. So, take
|
|
// <deny/allow>,<CGI Executable>,<CGI Executable>,... (ie. "0","c:\inetpub\scripts\mycgi.exe","c:\inetpub\scripts\pagecount.exe")
|
|
// and convert to
|
|
// <0/1>\0<CGI Executable>\0<CGI Executable>\0\0 (ie. 0\0c:\inetpub\scripts\mycgi.exe\0c:\inetpub\scripts\pagecount.exe\0\0)
|
|
//
|
|
// Parameters:
|
|
// pBuff [out] - BUFFER class that is used to store the multisz
|
|
// pdwRetSize [out] - The size of the multisz that was created (in Bytes, not chars)
|
|
// szItems [in] - List of Items to put in MultiSz
|
|
// cDelimeter [in[ - The delimeter for the list
|
|
//
|
|
// Return Values
|
|
// TRUE - Successfull
|
|
// FALSE - It failed to construct MultiSz
|
|
BOOL
|
|
CMetaBase_ImportRestrictionList::CreateMultiSzFromList(BUFFER *pBuff, DWORD *pdwRetSize, LPTSTR szItems, TCHAR cDelimeter)
|
|
{
|
|
LPTSTR szSource;
|
|
LPTSTR szDest;
|
|
BOOL bInQuotes = FALSE;
|
|
|
|
// Fail if we don't have a string, or can not get a big enought buffer
|
|
if ( ( !szItems ) ||
|
|
( !pBuff->Resize( ( _tcslen( szItems ) + 2 ) * sizeof(TCHAR) ) ) // Add 2, one for string term, and one for multisz term
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
szSource = szItems;
|
|
szDest = (LPTSTR) pBuff->QueryPtr();
|
|
|
|
while ( *szSource )
|
|
{
|
|
if ( *szSource == '"' )
|
|
{
|
|
bInQuotes = !bInQuotes;
|
|
}
|
|
else if ( ( *szSource == cDelimeter ) && !bInQuotes )
|
|
{
|
|
if ( ( szDest != pBuff->QueryPtr() ) &&
|
|
( *(szDest - 1) != '\0')
|
|
)
|
|
{
|
|
*szDest = '\0';
|
|
szDest++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*szDest = *szSource;
|
|
szDest++;
|
|
}
|
|
|
|
szSource++;
|
|
}
|
|
|
|
// Lets make sure that the last string was terminated.
|
|
if ( ( szDest != pBuff->QueryPtr() ) &&
|
|
( *(szDest - 1) != '\0')
|
|
)
|
|
{
|
|
// Terminate last string
|
|
*szDest = '\0';
|
|
szDest++;
|
|
}
|
|
|
|
// Terminate MultiSz, and calc length
|
|
*szDest++ = '\0';
|
|
*pdwRetSize = (DWORD) (DWORD_PTR) (((LPBYTE) szDest) - ((LPBYTE) pBuff->QueryPtr()));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CMetaBase_ImportRestrictionList::ExpandEnvVar(BUFFER *pBuff)
|
|
{
|
|
BUFFER buffOriginal;
|
|
DWORD dwLength;
|
|
|
|
if ( _tcsstr( (LPTSTR) pBuff->QueryPtr(), _T("%") ) == NULL )
|
|
{
|
|
// There are no environment variables, so we can return
|
|
return TRUE;
|
|
}
|
|
|
|
if ( !buffOriginal.Resize( pBuff->QuerySize() ) )
|
|
{
|
|
// Could not resize oringal big enough
|
|
return FALSE;
|
|
}
|
|
memcpy(buffOriginal.QueryPtr(), pBuff->QueryPtr(), pBuff->QuerySize());
|
|
|
|
dwLength = ExpandEnvironmentStrings( (LPTSTR) buffOriginal.QueryPtr(), NULL, 0);
|
|
|
|
if ( ( dwLength == 0 ) ||
|
|
( !pBuff->Resize( dwLength * sizeof(TCHAR) ) )
|
|
)
|
|
{
|
|
// Something failed in ExpandEnvironmentStrings
|
|
return FALSE;
|
|
}
|
|
|
|
dwLength = ExpandEnvironmentStrings( (LPTSTR) buffOriginal.QueryPtr(), (LPTSTR) pBuff->QueryPtr() , pBuff->QuerySize() );
|
|
|
|
if ( (dwLength != 0) && (dwLength <= pBuff->QuerySize() ) )
|
|
{
|
|
// It worked
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: DoInternalWork
|
|
//
|
|
// Import the RestrictionList
|
|
//
|
|
// Parameters:
|
|
// 0 - The name of the item in the inf
|
|
// 1 - The id
|
|
// 2 - The Default value (MultiSz with ';' as seperator)
|
|
//
|
|
BOOL
|
|
CMetaBase_ImportRestrictionList::DoInternalWork(CItemList &ciParams)
|
|
{
|
|
CMDKey cmdKey;
|
|
CMDValue cmdMetaValue;
|
|
BUFFER buffImportList;
|
|
DWORD dwImportList;
|
|
LPTSTR szList = NULL;
|
|
INFCONTEXT Context;
|
|
BOOL bRet = FALSE;
|
|
BOOL bForceSetting = FALSE;
|
|
|
|
if (g_pTheApp->m_fUnattended)
|
|
{
|
|
// If unattended, then look in unattend file for correct line
|
|
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hUnattendFile, UNATTEND_FILE_SECTION, ciParams.GetItem(0), &Context) )
|
|
{
|
|
DWORD dwRequiredSize = 0;
|
|
BUFFER buffUnattend;
|
|
BUFFER buffUnattendExpanded;
|
|
|
|
if ( SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL, NULL, 0, &dwRequiredSize) )
|
|
{
|
|
if ( ( buffUnattend.Resize( ( dwRequiredSize + 1 ) * sizeof(TCHAR) ) ) &&
|
|
( SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL, (LPTSTR) buffUnattend.QueryPtr(), buffUnattend.QuerySize()/sizeof(TCHAR), NULL) ) &&
|
|
( ExpandEnvVar( &buffUnattend ) ) &&
|
|
( CreateMultiSzFromList( &buffImportList, &dwImportList, (LPTSTR) buffUnattend.QueryPtr(), RESTRICTIONLIST_DELIMITER ) )
|
|
)
|
|
{
|
|
szList = (LPTSTR) buffImportList.QueryPtr();
|
|
bForceSetting = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !szList )
|
|
{
|
|
// If it could not be retrieved, set it to the default.
|
|
if ( ( buffImportList.Resize(( _tcslen( ciParams.GetItem(2) ) + 2 ) * sizeof(TCHAR) ) ) &&
|
|
( CreateMultiSzFromList( &buffImportList, &dwImportList, ciParams.GetItem(2), RESTRICTIONLIST_DELIMITER) )
|
|
)
|
|
{
|
|
szList = (LPTSTR) buffImportList.QueryPtr();
|
|
}
|
|
}
|
|
|
|
if ( szList == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Set Value
|
|
if ( FAILED(cmdKey.OpenNode( _T("LM/W3SVC") ) ) )
|
|
{
|
|
// Could not open the key, so we fail
|
|
return FALSE;
|
|
}
|
|
|
|
if ( bForceSetting ||
|
|
!cmdKey.GetData(cmdMetaValue, ciParams.GetNumber(1) )
|
|
)
|
|
{
|
|
// Set the value for this node
|
|
if ( cmdMetaValue.SetValue( ciParams.GetNumber(1), // ID
|
|
0x0, // Attributes (Not inheritable)
|
|
IIS_MD_UT_SERVER, // UType
|
|
MULTISZ_METADATA, // DType
|
|
dwImportList, // Size
|
|
(LPTSTR) szList)
|
|
)
|
|
{
|
|
bRet = cmdKey.SetData(cmdMetaValue, ciParams.GetNumber(1));
|
|
}
|
|
}
|
|
|
|
cmdKey.Close();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// function: GetMethodName
|
|
//
|
|
// Return the Method Name for this Class
|
|
//
|
|
LPTSTR
|
|
CMetaBase_UpdateCustomDescList::GetMethodName()
|
|
{
|
|
return _T("Metabase_UpdateCustomDescList");
|
|
}
|
|
|
|
// function: VerifyParameters
|
|
//
|
|
// Verify the parameters are correct
|
|
//
|
|
BOOL
|
|
CMetaBase_UpdateCustomDescList::VerifyParameters(CItemList &ciParams)
|
|
{
|
|
return ( (ciParams.GetNumberOfItems() == 3) &&
|
|
( ciParams.IsNumber(1) )
|
|
);
|
|
}
|
|
|
|
// function: CreateMultiSzFromList
|
|
//
|
|
// Create a MultiSz from a List of comman delim items. So, take
|
|
// <deleteable/not deleteable>,<description>,<filepath>,... (ie. "1","asp scripts","c:\winnt\system32\inetsrv\asp.dll")
|
|
// and convert to
|
|
// <0/1>\0<description>\0<filepath>\0\0 (ie. 1\0asp scripts\0c:\winnt\system32\inetsrv\asp.dll\0\0)
|
|
//
|
|
// Parameters:
|
|
// pBuff [out] - BUFFER class that is used to store the multisz
|
|
// pdwRetSize [out] - The size of the multisz that was created (in Bytes, not chars)
|
|
// szItems [in] - List of Items to put in MultiSz
|
|
// cDelimeter [in[ - The delimeter for the list
|
|
//
|
|
// Return Values
|
|
// TRUE - Successfull
|
|
// FALSE - It failed to construct MultiSz
|
|
BOOL
|
|
CMetaBase_UpdateCustomDescList::CreateMultiSzFromList(BUFFER *pBuff, DWORD *pdwRetSize, LPTSTR szItems, TCHAR cDelimeter)
|
|
{
|
|
LPTSTR szSource;
|
|
LPTSTR szDest;
|
|
BOOL bInQuotes = FALSE;
|
|
|
|
// Fail if we don't have a string, or can not get a big enought buffer
|
|
if ( ( !szItems ) ||
|
|
( !pBuff->Resize( ( _tcslen( szItems ) + 2 ) * sizeof(TCHAR) ) ) // Add 2, one for string term, and one for multisz term
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
szSource = szItems;
|
|
szDest = (LPTSTR) pBuff->QueryPtr();
|
|
|
|
while ( *szSource )
|
|
{
|
|
if ( *szSource == '"' )
|
|
{
|
|
bInQuotes = !bInQuotes;
|
|
}
|
|
else if ( ( *szSource == cDelimeter ) && !bInQuotes )
|
|
{
|
|
if ( ( szDest != pBuff->QueryPtr() ) &&
|
|
( *(szDest - 1) != '\0')
|
|
)
|
|
{
|
|
*szDest = '\0';
|
|
szDest++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*szDest = *szSource;
|
|
szDest++;
|
|
}
|
|
|
|
szSource++;
|
|
}
|
|
|
|
// Lets make sure that the last string was terminated.
|
|
if ( ( szDest != pBuff->QueryPtr() ) &&
|
|
( *(szDest - 1) != '\0')
|
|
)
|
|
{
|
|
// Terminate last string
|
|
*szDest = '\0';
|
|
szDest++;
|
|
}
|
|
|
|
// Terminate MultiSz, and calc length
|
|
*szDest++ = '\0';
|
|
*pdwRetSize = (DWORD) (DWORD_PTR) (((LPBYTE) szDest) - ((LPBYTE) pBuff->QueryPtr()));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CMetaBase_UpdateCustomDescList::ExpandEnvVar(BUFFER *pBuff)
|
|
{
|
|
BUFFER buffOriginal;
|
|
DWORD dwLength;
|
|
|
|
if ( _tcsstr( (LPTSTR) pBuff->QueryPtr(), _T("%") ) == NULL )
|
|
{
|
|
// There are no environment variables, so we can return
|
|
return TRUE;
|
|
}
|
|
|
|
if ( !buffOriginal.Resize( pBuff->QuerySize() ) )
|
|
{
|
|
// Could not resize oringal big enough
|
|
return FALSE;
|
|
}
|
|
memcpy(buffOriginal.QueryPtr(), pBuff->QueryPtr(), pBuff->QuerySize());
|
|
|
|
dwLength = ExpandEnvironmentStrings( (LPTSTR) buffOriginal.QueryPtr(), NULL, 0);
|
|
|
|
if ( ( dwLength == 0 ) ||
|
|
( !pBuff->Resize( dwLength * sizeof(TCHAR) ) )
|
|
)
|
|
{
|
|
// Something failed in ExpandEnvironmentStrings
|
|
return FALSE;
|
|
}
|
|
|
|
dwLength = ExpandEnvironmentStrings( (LPTSTR) buffOriginal.QueryPtr(), (LPTSTR) pBuff->QueryPtr() , pBuff->QuerySize()/sizeof(TCHAR) );
|
|
|
|
if ( (dwLength != 0) &&
|
|
(dwLength <= ( pBuff->QuerySize()/sizeof(TCHAR) ) ) )
|
|
{
|
|
// It worked
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// function: DoInternalWork
|
|
//
|
|
// Import the RestrictionList
|
|
//
|
|
// Parameters:
|
|
// 0 - The name of the item in the inf
|
|
// 1 - The id
|
|
// 2 - The Default value (MultiSz with ';' as seperator)
|
|
//
|
|
BOOL
|
|
CMetaBase_UpdateCustomDescList::DoInternalWork(CItemList &ciParams)
|
|
{
|
|
CMDKey cmdKey;
|
|
CMDValue cmdMetaValue;
|
|
BUFFER buffMyList;
|
|
DWORD dwMyList;
|
|
LPTSTR szList = NULL;
|
|
INFCONTEXT Context;
|
|
BOOL bRet = FALSE;
|
|
BOOL bForceSetting = FALSE;
|
|
|
|
if (g_pTheApp->m_fUnattended)
|
|
{
|
|
// If unattended, then look in unattend file for correct line
|
|
if ( SetupFindFirstLine_Wrapped(g_pTheApp->m_hUnattendFile, UNATTEND_FILE_SECTION, ciParams.GetItem(0), &Context) )
|
|
{
|
|
DWORD dwRequiredSize = 0;
|
|
BUFFER buffUnattend;
|
|
BUFFER buffUnattendExpanded;
|
|
|
|
if ( SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL, NULL, 0, &dwRequiredSize) )
|
|
{
|
|
if ( ( buffUnattend.Resize( ( dwRequiredSize + 1 ) * sizeof(TCHAR) ) ) &&
|
|
( SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL, (LPTSTR) buffUnattend.QueryPtr(), buffUnattend.QuerySize()/sizeof(TCHAR), NULL) ) &&
|
|
( ExpandEnvVar( &buffUnattend ) ) &&
|
|
( CreateMultiSzFromList( &buffMyList, &dwMyList, (LPTSTR) buffUnattend.QueryPtr(), CUSTOMDESCLIST_DELIMITER ) )
|
|
)
|
|
{
|
|
szList = (LPTSTR) buffMyList.QueryPtr();
|
|
bForceSetting = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !szList )
|
|
{
|
|
// If it could not be retrieved, set it to the default.
|
|
if ( ( buffMyList.Resize(( _tcslen( ciParams.GetItem(2) ) + 2 ) * sizeof(TCHAR) ) ) &&
|
|
( CreateMultiSzFromList( &buffMyList, &dwMyList, ciParams.GetItem(2), CUSTOMDESCLIST_DELIMITER) )
|
|
)
|
|
{
|
|
szList = (LPTSTR) buffMyList.QueryPtr();
|
|
}
|
|
}
|
|
|
|
if ( szList == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Set Value
|
|
if ( FAILED(cmdKey.OpenNode( _T("LM/W3SVC") ) ) )
|
|
{
|
|
// Could not open the key, so we fail
|
|
return FALSE;
|
|
}
|
|
|
|
// See if there is an existing value...
|
|
// if there is then update the value with this one...
|
|
// otherwise set it.
|
|
|
|
CStringList cslMyNewAdditions;
|
|
if (ERROR_SUCCESS != ConvertDoubleNullListToStringList(szList,cslMyNewAdditions,-1))
|
|
{
|
|
bForceSetting = TRUE;
|
|
}
|
|
|
|
// get the data
|
|
DWORD dwAttributes = 0;
|
|
DWORD dwMDDataType = MULTISZ_METADATA;
|
|
CStringList cslMyOriginalList;
|
|
if (bForceSetting || FAILED(cmdKey.GetMultiSzAsStringList(ciParams.GetNumber(1),&dwMDDataType,&dwAttributes,cslMyOriginalList)))
|
|
{
|
|
// do a fresh entry...
|
|
// Set the value for this node
|
|
if ( cmdMetaValue.SetValue(ciParams.GetNumber(1), // ID
|
|
0x0, // Attributes (Not inheritable)
|
|
IIS_MD_UT_SERVER, // UType
|
|
MULTISZ_METADATA, // DType
|
|
dwMyList, // Size
|
|
(LPTSTR) szList)
|
|
)
|
|
{
|
|
bRet = cmdKey.SetData(cmdMetaValue, ciParams.GetNumber(1));
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// able to get it...so let's update it.
|
|
// loop thru it and see if our entry is already in it...
|
|
CString csNewEntryPart1;
|
|
CString csNewEntryPart2;
|
|
CString csNewEntryPart3;
|
|
CString csExistingFilePath;
|
|
BOOL bItsInTheListAlready = FALSE;
|
|
BOOL bSomethingChanged = FALSE;
|
|
|
|
POSITION pos = cslMyNewAdditions.GetHeadPosition();
|
|
POSITION pos2 = NULL;
|
|
while (pos)
|
|
{
|
|
bItsInTheListAlready = FALSE;
|
|
|
|
// get the next value
|
|
csNewEntryPart1 = cslMyNewAdditions.GetNext(pos);
|
|
if (!pos){break;}
|
|
csNewEntryPart2 = cslMyNewAdditions.GetNext(pos);
|
|
if (!pos){break;}
|
|
csNewEntryPart3 = cslMyNewAdditions.GetNext(pos);
|
|
|
|
// see if this value is in our list...
|
|
pos2 = cslMyOriginalList.GetHeadPosition();
|
|
while (pos2)
|
|
{
|
|
// get the next value
|
|
cslMyOriginalList.GetNext(pos2);
|
|
if (!pos2){break;}
|
|
csExistingFilePath = cslMyOriginalList.GetNext(pos2);
|
|
if (!pos2){break;}
|
|
|
|
// compare with other value
|
|
//iisDebugOut((LOG_TYPE_TRACE,_T("UpdateCustomDescList:%s,%s"),csNewEntryPart2,csExistingFilePath));
|
|
if (0 == _tcsicmp(csNewEntryPart2,csExistingFilePath))
|
|
{
|
|
// it's found in there!
|
|
bItsInTheListAlready = TRUE;
|
|
break;
|
|
}
|
|
cslMyOriginalList.GetNext(pos2);
|
|
}
|
|
|
|
if (FALSE == bItsInTheListAlready)
|
|
{
|
|
// Add it to the end of the list
|
|
cslMyOriginalList.AddTail(csNewEntryPart1);
|
|
cslMyOriginalList.AddTail(csNewEntryPart2);
|
|
cslMyOriginalList.AddTail(csNewEntryPart3);
|
|
bSomethingChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
if (TRUE == bSomethingChanged)
|
|
{
|
|
bRet = FALSE;
|
|
if (ERROR_SUCCESS == cmdKey.SetMultiSzAsStringList(ciParams.GetNumber(1),MULTISZ_METADATA,0x0,cslMyOriginalList))
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
cmdKey.Close();
|
|
return bRet;
|
|
}
|