1021 lines
29 KiB
C++
1021 lines
29 KiB
C++
/*++
|
|
|
|
Copyright (c) 1994-1998 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
massupdt.cpp
|
|
|
|
Abstract:
|
|
|
|
functions to udpate bunches of properties at once
|
|
|
|
Author:
|
|
|
|
Boyd Multerer (boydm)
|
|
|
|
Project:
|
|
|
|
IIS Setup
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
//
|
|
// Include Files
|
|
//
|
|
#include "stdafx.h"
|
|
#include <iis64.h>
|
|
#include "iadmw.h"
|
|
#include "iiscnfg.h"
|
|
#include "strfn.h"
|
|
#include "mdkey.h"
|
|
#include "mdentry.h"
|
|
#include "massupdt.h"
|
|
|
|
|
|
//============================================================
|
|
// first the Abstract CMassPropertyUpdater class
|
|
|
|
|
|
//============================================================
|
|
//=================== CMassPropertyUpdater ===================
|
|
//============================================================
|
|
|
|
//------------------------------------------------------------
|
|
CMassPropertyUpdater::CMassPropertyUpdater(
|
|
DWORD dwMDIdentifier,
|
|
DWORD dwMDDataType ) :
|
|
m_dwMDIdentifier( dwMDIdentifier ),
|
|
m_dwMDDataType( dwMDDataType )
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
CMassPropertyUpdater::~CMassPropertyUpdater()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CMassPropertyUpdater::Update(
|
|
LPCTSTR strStartNode,
|
|
BOOL fStopOnErrors OPTIONAL )
|
|
{
|
|
HRESULT hRes;
|
|
CString szPath;
|
|
POSITION pos;
|
|
LPWSTR pwstr;
|
|
|
|
// start by getting the list of nodes with script maps on them
|
|
// first open the node that we will start searching on
|
|
hRes = OpenNode( strStartNode );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CMassPropertyUpdater::Update()-OpenNode failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
// get the sub-paths that have the data on them
|
|
hRes = GetDataPaths( m_dwMDIdentifier, m_dwMDDataType, m_pathList );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CMassPropertyUpdater::Update()-GetDataPaths failed. err=%x.\n"), hRes));
|
|
goto cleanup;
|
|
}
|
|
|
|
// we now have the cstringlist of paths that need to be updated. Loop through the
|
|
// list and update them all.
|
|
// get the list's head position
|
|
pos = m_pathList.GetHeadPosition();
|
|
while ( NULL != pos )
|
|
{
|
|
// get the next path in question
|
|
szPath = m_pathList.GetNext( pos );
|
|
|
|
// make a special case of the "/" path
|
|
if ( szPath == _T("/") )
|
|
szPath.Empty();
|
|
|
|
// drat. ANSI stuff is a mess so deal with it here
|
|
#ifdef UNICODE
|
|
pwstr = (LPWSTR)(LPCTSTR)szPath;
|
|
#else
|
|
pwstr = AllocWideString( szPath );
|
|
#endif
|
|
|
|
// operate on it
|
|
hRes = UpdateOne( pwstr );
|
|
|
|
#ifndef UNICODE
|
|
FreeMem( pwstr );
|
|
#endif
|
|
|
|
// if we are stopping of failures, then check
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CMassPropertyUpdater::Update():FAILED: update path =%s.\n"), szPath));
|
|
|
|
//if requested to stop the loop, then do so
|
|
if ( fStopOnErrors )
|
|
break;
|
|
}
|
|
}
|
|
|
|
// cleanup - close the node once and for all
|
|
cleanup:
|
|
Close();
|
|
|
|
// return the answer
|
|
return hRes;
|
|
}
|
|
|
|
|
|
|
|
//============================================================
|
|
//==================== CInvertScriptMaps =====================
|
|
//============================================================
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CInvertScriptMaps::UpdateOne( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes;
|
|
POSITION pos;
|
|
POSITION posCurrent;
|
|
CString szMap;
|
|
|
|
DWORD dwattributes = 0;
|
|
|
|
CStringList cslScriptMaps;
|
|
|
|
// get the full script map in question.
|
|
hRes = GetMultiSzAsStringList (
|
|
m_dwMDIdentifier,
|
|
&m_dwMDDataType,
|
|
&dwattributes,
|
|
cslScriptMaps,
|
|
strPath );
|
|
|
|
|
|
//iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne() GetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
// HACK. The first thing we need to do is make sure we haven't already inverted this script
|
|
// map during a previous build-to-build upgrade. If we invert it twice, then we are back
|
|
// to an exclusion list and that would not be desirable. The way to detect this is to see
|
|
// if the GET verb is listed for the ASP script map or not. If it is there, then it has been
|
|
// inverted. This will only be a problem when doing build-to-build upgrades in IIS5.
|
|
pos = cslScriptMaps.GetHeadPosition();
|
|
while ( NULL != pos )
|
|
{
|
|
// get the next path in question
|
|
szMap = cslScriptMaps.GetNext( pos );
|
|
|
|
// if it is the .asp scriptmap, then finish the test
|
|
if ( szMap.Left(4) == _T(".asp") )
|
|
{
|
|
if ( szMap.Find(_T("GET")) >= 0 )
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// we now have the cstringlist of paths that need to be updated. Loop through the
|
|
// list and update them all.
|
|
// get the list's head position
|
|
pos = cslScriptMaps.GetHeadPosition();
|
|
while ( NULL != pos )
|
|
{
|
|
// store the current position
|
|
posCurrent = pos;
|
|
|
|
// get the next path in question
|
|
szMap = cslScriptMaps.GetNext( pos );
|
|
|
|
// operate on it
|
|
hRes = InvertOneScriptMap( szMap );
|
|
|
|
// if that worked, put it back in place
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
cslScriptMaps.SetAt ( posCurrent, szMap );
|
|
}
|
|
}
|
|
|
|
//iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne() SetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
|
|
|
|
// Put it back.
|
|
hRes = SetMultiSzAsStringList (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
dwattributes,
|
|
cslScriptMaps,
|
|
strPath );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CInvertScriptMaps::InvertOneScriptMap( CString& csMap )
|
|
{
|
|
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CInvertScriptMaps::InvertOneScriptMap():%s.start.\n"), csMap));
|
|
// the script mapping is yet another list. This time seperated
|
|
// by commas. The first 4 items are standard and don't get messed
|
|
// with. The n last items are all verbs that need to be inverted.
|
|
int numParts;
|
|
int numVerbs;
|
|
|
|
CStringList cslMapParts;
|
|
CStringList cslVerbs;
|
|
CString szComma = _T(",");
|
|
CString szVerb;
|
|
|
|
POSITION posMap;
|
|
POSITION posVerb;
|
|
|
|
// break the source map into a string list
|
|
numParts = ConvertSepLineToStringList(
|
|
csMap,
|
|
cslMapParts,
|
|
szComma
|
|
);
|
|
|
|
CString szAllVerbs;
|
|
if (!GetScriptMapAllInclusionVerbs(szAllVerbs))
|
|
{
|
|
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetScriptMapAllInclusionVerbs():FAIL.WARNING.UseDefaults\n")));
|
|
szAllVerbs = SZ_INVERT_ALL_VERBS;
|
|
}
|
|
|
|
|
|
// start by making a string list with all the verbs to invert against
|
|
numVerbs = ConvertSepLineToStringList(
|
|
SZ_INVERT_ALL_VERBS,
|
|
cslVerbs,
|
|
szComma
|
|
);
|
|
|
|
// start with the 3rd indexed item in the source list. This should be the
|
|
// first verb in the old "exclusion" list. Then use it and scan
|
|
// the new "Inclusion" list of verbs. If it is there, rememove it.
|
|
posMap = cslMapParts.FindIndex( 3 );
|
|
while ( NULL != posMap )
|
|
{
|
|
// set to the next verb in the map list
|
|
szVerb = cslMapParts.GetNext( posMap );
|
|
|
|
// make sure the verb is normalized to capitals and
|
|
// no whitespace before or after
|
|
szVerb.MakeUpper();
|
|
szVerb.TrimLeft();
|
|
szVerb.TrimRight();
|
|
|
|
// try to find the verb in the invertion list
|
|
posVerb = cslVerbs.Find( szVerb );
|
|
|
|
// if we found it, remove it
|
|
if ( NULL != posVerb )
|
|
{
|
|
cslVerbs.RemoveAt( posVerb );
|
|
}
|
|
}
|
|
|
|
// strip all the verbs off the source list
|
|
while ( cslMapParts.GetCount() > 3 )
|
|
{
|
|
cslMapParts.RemoveTail();
|
|
}
|
|
|
|
// combine the lists
|
|
cslMapParts.AddTail( &cslVerbs );
|
|
|
|
// put it back into the comma list
|
|
ConvertStringListToSepLine(
|
|
cslMapParts,
|
|
csMap,
|
|
szComma
|
|
);
|
|
|
|
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CInvertScriptMaps::InvertOneScriptMap():%s.End.\n"), csMap));
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
//============================================================
|
|
//================= CIPSecPhysicalPathFixer ==================
|
|
//============================================================
|
|
|
|
|
|
//------------------------------------------------------------
|
|
CPhysicalPathFixer::CPhysicalPathFixer( CString& szOldSysPath, CString &szNewSysPath ):
|
|
CMassPropertyUpdater(0, 0), // bad values on purpose - see Update below...
|
|
m_szOldSysPath( szOldSysPath ),
|
|
m_szNewSysPath( szNewSysPath )
|
|
{
|
|
m_szOldSysPath.MakeUpper();
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CPhysicalPathFixer::Update( LPCTSTR strStartNode, BOOL fStopOnErrors )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
// vrpath -- should we do this too? yes.
|
|
m_dwMDIdentifier = MD_VR_PATH;
|
|
m_dwMDDataType = STRING_METADATA;
|
|
hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
|
|
|
|
// inproc isapi apps.
|
|
m_dwMDIdentifier = MD_IN_PROCESS_ISAPI_APPS;
|
|
m_dwMDDataType = MULTISZ_METADATA;
|
|
hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
|
|
|
|
// prepare and update the scriptmappings multi sz strings
|
|
m_dwMDIdentifier = MD_SCRIPT_MAPS;
|
|
m_dwMDDataType = MULTISZ_METADATA;
|
|
hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
|
|
|
|
// prepare to update the FilterImagePath multi sz strings
|
|
m_dwMDIdentifier = MD_FILTER_IMAGE_PATH;
|
|
m_dwMDDataType = STRING_METADATA;
|
|
hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
|
|
|
|
// prepare to update the FilterImagePath multi sz strings
|
|
m_dwMDIdentifier = MD_LOGFILE_DIRECTORY;
|
|
m_dwMDDataType = EXPANDSZ_METADATA;
|
|
hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
|
|
|
|
return hRes;
|
|
}
|
|
|
|
//MD_FILTER_LOAD_ORDER
|
|
// in process isapi apps
|
|
// custom errors
|
|
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CPhysicalPathFixer2::Update( LPCTSTR strStartNode, BOOL fStopOnErrors )
|
|
{
|
|
HRESULT hRes;
|
|
// prepare and update the scriptmappings multi sz strings
|
|
m_dwMDIdentifier = MD_CUSTOM_ERROR;
|
|
m_dwMDDataType = MULTISZ_METADATA;
|
|
hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CPhysicalPathFixer::UpdateOne( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes = 0xFFFFFFFF;
|
|
|
|
if ( m_dwMDDataType == STRING_METADATA )
|
|
{
|
|
hRes = UpdateOneSTRING_DATA( strPath );
|
|
}
|
|
else if ( m_dwMDDataType == MULTISZ_METADATA )
|
|
{
|
|
hRes = UpdateOneMULTISZ_DATA( strPath );
|
|
}
|
|
else if ( m_dwMDDataType == EXPANDSZ_METADATA )
|
|
{
|
|
hRes = UpdateOneSTRING_DATA_EXPAND( strPath );
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CPhysicalPathFixer::UpdateOneMULTISZ_DATA( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes;
|
|
POSITION pos;
|
|
POSITION posCurrent;
|
|
CString csPath;
|
|
|
|
CStringList cslPaths;
|
|
BOOL fSomethingChanged = FALSE;
|
|
|
|
DWORD dwattributes = 0;
|
|
|
|
// get the full script map in question.
|
|
hRes = GetMultiSzAsStringList (
|
|
m_dwMDIdentifier,
|
|
&m_dwMDDataType,
|
|
&dwattributes,
|
|
cslPaths,
|
|
strPath );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
// we now have the cstringlist of paths that need to be updated. Loop through the
|
|
// list and update them all.
|
|
// get the list's head position
|
|
pos = cslPaths.GetHeadPosition();
|
|
while ( NULL != pos )
|
|
{
|
|
// store the current position
|
|
posCurrent = pos;
|
|
|
|
// get the next path in question
|
|
csPath = cslPaths.GetNext( pos );
|
|
|
|
// operate on it
|
|
hRes = UpdateOnePath( csPath );
|
|
|
|
// if that worked, put it back in place
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
cslPaths.SetAt ( posCurrent, csPath );
|
|
fSomethingChanged = TRUE;
|
|
}
|
|
// if there was nothing to update..
|
|
if (hRes == 0xFFFFFFFF)
|
|
{hRes = ERROR_SUCCESS;}
|
|
}
|
|
|
|
// Put it back. - unless nothing changed
|
|
if ( fSomethingChanged )
|
|
{
|
|
hRes = SetMultiSzAsStringList (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
dwattributes,
|
|
cslPaths,
|
|
strPath );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CPhysicalPathFixer::UpdateOneSTRING_DATA_EXPAND( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes;
|
|
CString csPath;
|
|
BOOL fSomethingChanged = FALSE;
|
|
|
|
// get the full script map in question.
|
|
hRes = GetStringAsCString (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
NULL,
|
|
csPath,
|
|
strPath,
|
|
1);
|
|
|
|
if ( MD_ERROR_DATA_NOT_FOUND == hRes)
|
|
{
|
|
hRes = ERROR_SUCCESS;
|
|
return hRes;
|
|
}
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
//iisDebugOut((LOG_TYPE_TRACE, _T("GetStringAsCString:Read.%S\n"), csPath));
|
|
|
|
// operate on it
|
|
hRes = UpdateOnePath( csPath );
|
|
|
|
// if that worked, put it back in place
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
fSomethingChanged = TRUE;
|
|
}
|
|
|
|
// if there was nothing to update..
|
|
if (hRes == 0xFFFFFFFF)
|
|
{hRes = ERROR_SUCCESS;}
|
|
|
|
// Put it back. - unless nothing changed
|
|
if ( fSomethingChanged )
|
|
{
|
|
//iisDebugOut((LOG_TYPE_TRACE, _T("GetStringAsCString:write.%S\n"), csPath));
|
|
hRes = SetCStringAsString (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
NULL,
|
|
csPath,
|
|
strPath,
|
|
1);
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CPhysicalPathFixer::UpdateOneSTRING_DATA( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes;
|
|
CString csPath;
|
|
BOOL fSomethingChanged = FALSE;
|
|
|
|
// get the full script map in question.
|
|
hRes = GetStringAsCString (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
NULL,
|
|
csPath,
|
|
strPath,
|
|
0);
|
|
|
|
if ( MD_ERROR_DATA_NOT_FOUND == hRes)
|
|
{
|
|
hRes = ERROR_SUCCESS;
|
|
return hRes;
|
|
}
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
|
|
// operate on it
|
|
hRes = UpdateOnePath( csPath );
|
|
|
|
// if that worked, put it back in place
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
fSomethingChanged = TRUE;
|
|
}
|
|
|
|
// if there was nothing to update..
|
|
if (hRes == 0xFFFFFFFF)
|
|
{hRes = ERROR_SUCCESS;}
|
|
|
|
// Put it back. - unless nothing changed
|
|
if ( fSomethingChanged )
|
|
{
|
|
hRes = SetCStringAsString (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
NULL,
|
|
csPath,
|
|
strPath,
|
|
0);
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
// note: returns 0xFFFFFFFF if nothing changed
|
|
HRESULT CPhysicalPathFixer::UpdateOnePath( CString& csPath )
|
|
{
|
|
// buffer the incoming string and make it upper case for the find
|
|
CString csUpper = csPath;
|
|
csUpper.MakeUpper();
|
|
|
|
|
|
// first, find the old syspath in the csPath
|
|
int iOldPath = csUpper.Find( m_szOldSysPath );
|
|
|
|
// if it wasn't there, then return with 0xFFFFFFFF
|
|
if ( iOldPath == -1 )
|
|
{
|
|
return 0xFFFFFFFF;
|
|
}
|
|
|
|
// the plan is the build a new string from the old one.
|
|
CString csNewPath;
|
|
|
|
// start by copying everything to the left of the substring
|
|
csNewPath = csPath.Left( iOldPath );
|
|
|
|
// now add to it the new path
|
|
csNewPath += m_szNewSysPath;
|
|
|
|
// now add to that the rest of the string
|
|
csNewPath += csPath.Right( csPath.GetLength() - (iOldPath + m_szOldSysPath.GetLength()) );
|
|
|
|
// finally, put the new string into place
|
|
csPath = csNewPath;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//============================================================
|
|
//==================== CIPSecRefBitAdder =====================
|
|
//============================================================
|
|
|
|
//------------------------------------------------------------
|
|
//MD_IP_SEC, BINARY_METADATA
|
|
// Unfortunately, at this time there is no way to directly manipulate the
|
|
// attribuites on a property in the metabase without reading in
|
|
// the actual property data. This could be made much simpler if a IADM level
|
|
// method to do this is added to the metabase interface at some point in the
|
|
// future.
|
|
HRESULT CIPSecRefBitAdder::UpdateOne( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes = ERROR_SUCCESS;
|
|
METADATA_RECORD mdrData;
|
|
DWORD cbBuffer;
|
|
|
|
|
|
// get the ipsec data. The loop accounts for a buffer that is too small...
|
|
DWORD dwMDBufferSize = 1024;
|
|
PWCHAR pwchBuffer = NULL;
|
|
do
|
|
{
|
|
if ( pwchBuffer )
|
|
{
|
|
delete pwchBuffer;
|
|
pwchBuffer = NULL;
|
|
}
|
|
|
|
pwchBuffer = new WCHAR[dwMDBufferSize];
|
|
if (pwchBuffer == NULL)
|
|
{
|
|
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
|
|
// prepare the metadata parameter block
|
|
MD_SET_DATA_RECORD(&mdrData, MD_IP_SEC, 0,
|
|
IIS_MD_UT_FILE, BINARY_METADATA, dwMDBufferSize, pwchBuffer);
|
|
|
|
// make the call to get the data
|
|
// If the buffer is too small, the correct size will be put into dwMDBufferSize
|
|
hRes = m_pcCom->GetData(
|
|
m_hKey,
|
|
strPath,
|
|
&mdrData,
|
|
&dwMDBufferSize
|
|
);
|
|
}
|
|
while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
// if there were any failures, go to the cleanup code now...
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
// at this point we can check to see if the reference bit is part of the attributes.
|
|
// if it is, then we can just clean up. If it isn't, we should add it and write it
|
|
// back out.
|
|
if ( (mdrData.dwMDAttributes & METADATA_REFERENCE) == 0 )
|
|
{
|
|
// the attributes flag is not set. Set it.
|
|
mdrData.dwMDAttributes |= METADATA_REFERENCE;
|
|
|
|
// write it back out to the metabase
|
|
hRes = m_pcCom->SetData(
|
|
m_hKey,
|
|
strPath,
|
|
&mdrData
|
|
);
|
|
}
|
|
}
|
|
|
|
// clean up
|
|
if ( pwchBuffer )
|
|
delete pwchBuffer;
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecRefBitAdder::UpdateOne() failed. err=%x.\n"), hRes));
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
|
|
//============================================================
|
|
//==================== CFixCustomErrors ======================
|
|
//============================================================
|
|
|
|
HRESULT CustomErrorProcessOneLine(CString& csInputOneBlobEntry)
|
|
{
|
|
HRESULT hReturn = E_FAIL;
|
|
CStringList cslBlobEntryParts;
|
|
CString csComma = _T(",");
|
|
|
|
TCHAR szDrive_only[_MAX_DRIVE];
|
|
TCHAR szPath_only[_MAX_PATH];
|
|
TCHAR szPath_only2[_MAX_PATH];
|
|
TCHAR szFilename_only[_MAX_PATH];
|
|
TCHAR szFilename_ext_only[_MAX_EXT];
|
|
|
|
CString csFilePath;
|
|
CString csFilePathNew;
|
|
CString csFilePath2;
|
|
|
|
CString csEntry;
|
|
CString csEntry0;
|
|
CString csEntry1;
|
|
CString csEntry2;
|
|
CString csEntry3;
|
|
|
|
TCHAR szNewFileName[_MAX_PATH];
|
|
|
|
POSITION pos;
|
|
|
|
//"500,15,FILE,D:\WINNT\help\iisHelp\common\500-15.htm"
|
|
//"500,100,URL,/iisHelp/common/500-100.asp"
|
|
|
|
// break the source map into a string list
|
|
ConvertSepLineToStringList(csInputOneBlobEntry,cslBlobEntryParts,csComma);
|
|
|
|
// we now have the cstringlist. Loop through the list
|
|
// which should look like this:
|
|
// 0:500
|
|
// 1:15
|
|
// 2:FILE
|
|
// 3:D:\WINNT\help\iisHelp\common\500-15.htm
|
|
pos = cslBlobEntryParts.GetHeadPosition();
|
|
if (!pos) {goto CustomErrorProcessOneLine_Exit;}
|
|
|
|
// 0:500
|
|
csEntry = cslBlobEntryParts.GetAt(pos);
|
|
csEntry0 = csEntry;
|
|
if (!pos) {goto CustomErrorProcessOneLine_Exit;}
|
|
|
|
// 1:15
|
|
cslBlobEntryParts.GetNext(pos);
|
|
if (!pos) {goto CustomErrorProcessOneLine_Exit;}
|
|
csEntry = cslBlobEntryParts.GetAt(pos);
|
|
csEntry1 = csEntry;
|
|
if (!pos) {goto CustomErrorProcessOneLine_Exit;}
|
|
|
|
// 2:FILE
|
|
// Check to make sure this is the "file" type
|
|
// that we will act upon. if it's not then get out
|
|
cslBlobEntryParts.GetNext(pos);
|
|
if (!pos) {goto CustomErrorProcessOneLine_Exit;}
|
|
csEntry = cslBlobEntryParts.GetAt(pos);
|
|
if ( csEntry.Left(4) != _T("FILE") )
|
|
{goto CustomErrorProcessOneLine_Exit;}
|
|
csEntry2 = csEntry;
|
|
|
|
// 3:D:\WINNT\help\iisHelp\common\500-15.htm
|
|
cslBlobEntryParts.GetNext(pos);
|
|
if (!pos) {goto CustomErrorProcessOneLine_Exit;}
|
|
csEntry = cslBlobEntryParts.GetAt(pos);
|
|
csEntry3 = csEntry;
|
|
|
|
// KOOL, this is one we need to process.
|
|
// D:\WINNT\help\iisHelp\common\500-15.htm
|
|
|
|
// Get the filename
|
|
// Trim off the filename and return only the path
|
|
_tsplitpath(csEntry, szDrive_only, szPath_only, szFilename_only, szFilename_ext_only);
|
|
|
|
// Check if the path points to the old place...
|
|
csFilePath.Format(_T("%s\\help\\common\\fakefile"), g_pTheApp->m_csWinDir);
|
|
_tsplitpath( csFilePath, NULL, szPath_only2, NULL, NULL);
|
|
if (_tcsicmp(szPath_only, szPath_only2) != 0)
|
|
{
|
|
// nope this one does not point to the old place so we can get out
|
|
goto CustomErrorProcessOneLine_Exit;
|
|
}
|
|
|
|
// yes, it points to the old place.
|
|
// let's see if it exists in the new place first...
|
|
csFilePathNew.Format(_T("%s\\help\\iishelp\\common"), g_pTheApp->m_csWinDir);
|
|
csFilePath.Format(_T("%s\\%s%s"), csFilePathNew, szFilename_only, szFilename_ext_only);
|
|
if (IsFileExist(csFilePath))
|
|
{
|
|
// yes, it does, then let's replace it.
|
|
csInputOneBlobEntry.Format(_T("%s,%s,%s,%s\\%s%s"), csEntry0, csEntry1, csEntry2, csFilePathNew, szFilename_only, szFilename_ext_only);
|
|
// return
|
|
hReturn = ERROR_SUCCESS;
|
|
goto CustomErrorProcessOneLine_Exit;
|
|
}
|
|
|
|
// no it does not exist...
|
|
// see if there is a *.bak file with that name...
|
|
csFilePath2 = csFilePath;
|
|
csFilePath2 += _T(".bak");
|
|
if (IsFileExist(csFilePath2))
|
|
{
|
|
// yes, it does, then let's replace it.
|
|
csInputOneBlobEntry.Format(_T("%s,%s,%s,%s\\%s%s.bak"), csEntry0, csEntry1, csEntry2, csFilePathNew, szFilename_only, szFilename_ext_only);
|
|
// return
|
|
hReturn = ERROR_SUCCESS;
|
|
goto CustomErrorProcessOneLine_Exit;
|
|
}
|
|
|
|
// They must be pointing to some other file which we don't have.
|
|
// let's try to copy the old file from the old directory...
|
|
|
|
// rename file to *.bak and move it to the new location..
|
|
_stprintf(szNewFileName, _T("%s\\%s%s"), csFilePathNew, szFilename_only, szFilename_ext_only);
|
|
// move it
|
|
if (IsFileExist(csEntry3))
|
|
{
|
|
//iisDebugOut((LOG_TYPE_TRACE, _T("CustomErrorProcessOneLine: MoveFileEx:%s,%s.\n"),csEntry3, szNewFileName));
|
|
if (MoveFileEx(csEntry3, szNewFileName, MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH|MOVEFILE_REPLACE_EXISTING))
|
|
{
|
|
// yes, it does, then let's replace it.
|
|
csInputOneBlobEntry.Format(_T("%s,%s,%s,%s"), csEntry0, csEntry1, csEntry2, szNewFileName);
|
|
hReturn = ERROR_SUCCESS;
|
|
}
|
|
// we were not able to move it so don't make it poiint to the new place.
|
|
}
|
|
else
|
|
{
|
|
// Check if the file was renamed...
|
|
// rename file to *.bak and move it to the new location..
|
|
_stprintf(szNewFileName, _T("%s\\%s%s.bak"), csFilePathNew, szFilename_only, szFilename_ext_only);
|
|
// yes, it does, then let's replace it.
|
|
if (IsFileExist(szNewFileName))
|
|
{
|
|
csInputOneBlobEntry.Format(_T("%s,%s,%s,%s"), csEntry0, csEntry1, csEntry2, szNewFileName);
|
|
hReturn = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
// they must be pointing to some other file which we don't install.
|
|
// so don't change this entry...
|
|
}
|
|
}
|
|
|
|
CustomErrorProcessOneLine_Exit:
|
|
if (hReturn == ERROR_SUCCESS)
|
|
{
|
|
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CustomErrorProcessOneLine:End.value=%s.\n"),csInputOneBlobEntry));
|
|
}
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------
|
|
HRESULT CFixCustomErrors::UpdateOne( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes = ERROR_SUCCESS;
|
|
POSITION pos;
|
|
POSITION posCurrent;
|
|
CString szMap;
|
|
|
|
DWORD dwattributes = 0;
|
|
|
|
CStringList cslScriptMaps;
|
|
|
|
//iisDebugOut((LOG_TYPE_TRACE, _T("CFixCustomErrors::UpdateOne() %s.\n"), strPath));
|
|
|
|
CString csTheNode;
|
|
csTheNode = _T("LM/W3SVC");
|
|
csTheNode += strPath;
|
|
|
|
// get the full script map in question.
|
|
hRes = GetMultiSzAsStringList (
|
|
m_dwMDIdentifier,
|
|
&m_dwMDDataType,
|
|
&dwattributes,
|
|
cslScriptMaps,
|
|
strPath );
|
|
|
|
//iisDebugOut((LOG_TYPE_TRACE, _T("CFixCustomErrors::UpdateOne() GetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
// we now have the cstringlist of paths that need to be updated. Loop through the
|
|
// list and update them all.
|
|
// get the list's head position
|
|
pos = cslScriptMaps.GetHeadPosition();
|
|
while ( NULL != pos )
|
|
{
|
|
// store the current position
|
|
posCurrent = pos;
|
|
|
|
// get the next path in question
|
|
szMap = cslScriptMaps.GetNext( pos );
|
|
|
|
// print it out to the screen for debug purposes
|
|
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CFixCustomErrors::UpdateOne().Data=%s.\n"), szMap));
|
|
|
|
// operate on it
|
|
hRes = CustomErrorProcessOneLine( szMap );
|
|
|
|
// if that worked, put it back in place
|
|
if ( SUCCEEDED(hRes) ){cslScriptMaps.SetAt ( posCurrent, szMap );}
|
|
}
|
|
|
|
//iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne() SetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
|
|
|
|
// Put it back.
|
|
hRes = SetMultiSzAsStringList (
|
|
m_dwMDIdentifier,
|
|
m_dwMDDataType,
|
|
dwattributes,
|
|
cslScriptMaps,
|
|
strPath );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
return hRes;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT CEnforceMaxConnection::UpdateOne( LPWSTR strPath )
|
|
{
|
|
HRESULT hRes = 0xFFFFFFFF;
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne(%s).start\n"), strPath));
|
|
|
|
DWORD theDword;
|
|
BOOL fSomethingChanged = FALSE;
|
|
|
|
if ( m_dwMDDataType == DWORD_METADATA )
|
|
{
|
|
// Get the value into a dword
|
|
// get the full script map in question.
|
|
hRes = GetDword(m_dwMDIdentifier,m_dwMDDataType,NULL,theDword,strPath);
|
|
if ( MD_ERROR_DATA_NOT_FOUND == hRes)
|
|
{
|
|
hRes = ERROR_SUCCESS;
|
|
return hRes;
|
|
}
|
|
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne()-GetDword failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
|
|
if (theDword > 10)
|
|
{
|
|
theDword = 10;
|
|
fSomethingChanged = TRUE;
|
|
}
|
|
else
|
|
{
|
|
hRes = ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
// Put it back. - unless nothing changed
|
|
if ( fSomethingChanged )
|
|
{
|
|
//hRes = SetDword(m_dwMDIdentifier,m_dwMDDataType,NULL,theDword,strPath);
|
|
if ( FAILED(hRes) )
|
|
{
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne()-GetDword failed. err=%x.\n"), hRes));
|
|
return hRes;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hRes = ERROR_SUCCESS;
|
|
}
|
|
|
|
iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne(%s).End.ret=0x%x\n"), strPath,hRes));
|
|
return hRes;
|
|
}
|