Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1020 lines
26 KiB

/*
Copyright (c) Microsoft Corporation
*/
#include "stdinc.h"
#include "fusionbuffer.h"
#include "fusionhash.h"
#include "csecuritymetadata.h"
#include "strongname.h"
#include "hashfile.h"
typedef CCaseInsensitiveSimpleUnicodeStringTableIter<CFusionByteArray, CFileHashTableHelper> CFileHashTableIter;
//
// We should try to remove this.
//
BOOL
CFileInformationTableHelper::UpdateValue(
const CMetaDataFileElement &vin,
CMetaDataFileElement &stored
)
{
FN_PROLOG_WIN32
ASSERT( FALSE );
FN_EPILOG
}
CMetaDataFileElement::CMetaDataFileElement()
{
}
BOOL
CMetaDataFileElement::WriteToRegistry( CRegKey & hkThisFileNode ) const
{
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
FN_PROLOG_WIN32
const CFileHashTable &rfileHashTable = *this;
CFileHashTableIter TableIterator( const_cast<CFileHashTable&>(rfileHashTable) );
for ( TableIterator.Reset(); TableIterator.More(); TableIterator.Next() )
{
const PCWSTR &rcbuffAlgName = TableIterator.GetKey();
const CFusionByteArray &rbbuffHashData = TableIterator.GetValue();
IFW32FALSE_EXIT( hkThisFileNode.SetValue(
rcbuffAlgName,
REG_BINARY,
rbbuffHashData.GetArrayPtr(),
rbbuffHashData.GetSize() ) );
}
FN_EPILOG
}
BOOL
CMetaDataFileElement::ReadFromRegistry(
CRegKey& hkThisFileNode
)
{
/*
Here we take a few shortcuts. We know there is a list of "valid" hash
alg name strings, so we only query for them in the registry. If anything
else is in there, then too bad for them.
*/
FN_PROLOG_WIN32
DWORD dwIndex = 0;
DWORD dwLastError = 0;
CFusionByteArray baHashValue;
CSmallStringBuffer buffHashAlgName;
IFW32FALSE_EXIT(baHashValue.Win32Initialize());
while ( true )
{
BOOL fNoMoreItems = FALSE;
buffHashAlgName.Clear();
IFW32FALSE_EXIT( ::SxspEnumKnownHashTypes( dwIndex++, buffHashAlgName, fNoMoreItems ) );
//
// There's no more hash types to be enumerated...
//
if (fNoMoreItems)
break;
//
// Get the hash data out of the registry
//
IFW32FALSE_EXIT(
::FusionpRegQueryBinaryValueEx(
FUSIONP_REG_QUERY_BINARY_NO_FAIL_IF_NON_BINARY,
hkThisFileNode,
buffHashAlgName,
baHashValue,
dwLastError,
2,
ERROR_PATH_NOT_FOUND,
ERROR_FILE_NOT_FOUND));
//
// ISSUE: jonwis 3/12/2002 - Someone could put non-binary data here in the registry
// and so we'll fail when we try to compare the hash against what's on the
// filesystem. This isn't necessarily bad, since we do compare binary-wise,
// but maybe we should validate here to ensure that the type is binary, and
// not add the hash data if it isn't.
//
if (dwLastError == ERROR_SUCCESS)
IFW32FALSE_EXIT(this->PutHashData(buffHashAlgName, baHashValue));
}
FN_EPILOG
}
BOOL
CMetaDataFileElement::Initialize()
{
FN_PROLOG_WIN32
IFW32FALSE_EXIT( CFileHashTable::Initialize() );
FN_EPILOG
}
BOOL
CMetaDataFileElement::GetHashDataForKind(
IN const ALG_ID aid,
OUT CFusionByteArray& arrHashData,
OUT BOOL &rfHadSuchData
) const
{
FN_PROLOG_WIN32
CSmallStringBuffer buffAlgName;
IFW32FALSE_EXIT( ::SxspHashStringFromAlg(aid, buffAlgName) );
IFW32FALSE_EXIT( this->GetHashDataForKind( buffAlgName, arrHashData, rfHadSuchData ) );
FN_EPILOG
}
BOOL
CMetaDataFileElement::GetHashDataForKind(
IN const CBaseStringBuffer& buffId,
OUT CFusionByteArray& arrHashData,
OUT BOOL &rfHadSuchData
) const
{
// NTRAID#NTBUG9 - 556341 - jonwis - 2002/4/25 - Always set the output param
FN_PROLOG_WIN32
CFusionByteArray *pFoundData = NULL;
rfHadSuchData = FALSE;
IFW32FALSE_EXIT( arrHashData.Win32Reset() );
IFW32FALSE_EXIT( this->Find( buffId, pFoundData ) );
if ( pFoundData != NULL )
{
IFW32FALSE_EXIT(pFoundData->Win32Clone(arrHashData));
rfHadSuchData = TRUE;
}
FN_EPILOG
}
BOOL
CMetaDataFileElement::PutHashData(
IN const ALG_ID aid,
IN const CFusionByteArray& arrHashData
)
{
FN_PROLOG_WIN32
CSmallStringBuffer buffTempAlgId;
IFW32FALSE_EXIT( ::SxspHashStringFromAlg( aid, buffTempAlgId ) );
IFW32FALSE_EXIT( this->PutHashData( buffTempAlgId, arrHashData ) );
FN_EPILOG
}
BOOL
CMetaDataFileElement::PutHashData(
IN const CBaseStringBuffer& buffId,
IN const CFusionByteArray& arrHashData
)
{
FN_PROLOG_WIN32
CFusionByteArray *pStoredValue = NULL;
BOOL bFound = FALSE;
IFW32FALSE_EXIT( this->FindOrInsertIfNotPresent(
buffId,
arrHashData,
&pStoredValue,
&bFound ) );
if ( bFound )
{
ASSERT( pStoredValue != NULL );
IFW32FALSE_EXIT(arrHashData.Win32Clone(*pStoredValue));
}
FN_EPILOG
}
BOOL
CSecurityMetaData::GetFileMetaData(
const CBaseStringBuffer& buffFileName,
const CMetaDataFileElement* &pElementData
) const
{
FN_PROLOG_WIN32
IFW32FALSE_EXIT( m_fitFileDataTable.Find(buffFileName, pElementData) );
FN_EPILOG
}
BOOL
CSecurityMetaData::Initialize()
{
FN_PROLOG_WIN32
IFW32FALSE_EXIT(m_cilCodebases.Win32Initialize());
IFW32FALSE_EXIT(m_baSignerPublicKeyToken.Win32Initialize());
IFW32FALSE_EXIT(m_baManifestSha1Hash.Win32Initialize());
IFW32FALSE_EXIT(m_fitFileDataTable.Initialize());
m_buffShortNameOnDisk.Clear();
m_buffShortCatalogName.Clear();
m_buffShortManifestName.Clear();
FN_EPILOG
}
BOOL
CSecurityMetaData::Initialize(
const CSecurityMetaData &other
)
{
FN_PROLOG_WIN32
//
// ISSUE: jonwis 3/12/2002 - Ick. Use 'Win32Assign' to assign from one string to another... Don't
// bother doing the cast operator and calling Cch!
// - PS: This style of doing copying is gross... either make it so that it only takes the
// name of the thing to copy, or do the verbose thing of IFW32FALSE_EXIT(...).
//
#define CLONEFUSIONARRAY( src, dst ) IFW32FALSE_EXIT( (src).Win32Clone( dst ) )
#define CLONESTRING( dst, src ) IFW32FALSE_EXIT( (dst).Win32Assign( (src), (src).Cch() ) )
IFW32FALSE_EXIT( this->Initialize() );
CLONEFUSIONARRAY(other.m_cilCodebases, this->m_cilCodebases);
CLONEFUSIONARRAY(other.m_baSignerPublicKeyToken, this->m_baSignerPublicKeyToken);
CLONEFUSIONARRAY(other.m_baManifestSha1Hash, this->m_baManifestSha1Hash);
CLONESTRING(this->m_buffShortNameOnDisk, other.m_buffShortNameOnDisk);
CLONESTRING(this->m_buffTextualAssemblyIdentity, other.m_buffTextualAssemblyIdentity);
CLONESTRING(this->m_buffShortManifestName, other.m_buffShortManifestName);
CLONESTRING(this->m_buffShortCatalogName, other.m_buffShortCatalogName);
//
// Copy file information table over
//
{
CFileInformationTableIter Iter(const_cast<CFileInformationTable&>(other.m_fitFileDataTable));
for (Iter.Reset(); Iter.More(); Iter.Next())
IFW32FALSE_EXIT( this->m_fitFileDataTable.Insert( Iter.GetKey(), Iter.GetValue() ) );
}
FN_EPILOG
}
BOOL
CSecurityMetaData::AddFileMetaData(
const CBaseStringBuffer &rbuffFileName,
CMetaDataFileElement &rElementData,
CSecurityMetaData::FileAdditionDisposition dispHowToAdd
)
{
FN_PROLOG_WIN32
if (dispHowToAdd == CSecurityMetaData::eFailIfAlreadyExists)
{
IFW32FALSE_EXIT(m_fitFileDataTable.Insert(rbuffFileName, rElementData));
}
else if (dispHowToAdd == CSecurityMetaData::eReplaceIfAlreadyExists)
{
bool fAlreadyExists = false;
IFW32FALSE_EXIT_UNLESS(
m_fitFileDataTable.Insert(rbuffFileName, rElementData),
(::FusionpGetLastWin32Error() == ERROR_ALREADY_EXISTS),
fAlreadyExists);
if (fAlreadyExists)
{
IFW32FALSE_EXIT(m_fitFileDataTable.Remove(rbuffFileName));
IFW32FALSE_EXIT(m_fitFileDataTable.Insert(rbuffFileName, rElementData));
}
}
else if (dispHowToAdd == CSecurityMetaData::eMergeIfAlreadyExists)
{
IFW32FALSE_EXIT(
m_fitFileDataTable.InsertOrUpdateIf<CSecurityMetaData>(
rbuffFileName,
rElementData,
this,
&CSecurityMetaData::MergeFileDataElement));
}
FN_EPILOG
}
BOOL
CSecurityMetaData::SetSignerPublicKeyTokenBits(
const CFusionByteArray & rcbuffSignerPublicKeyBits
)
{
FN_PROLOG_WIN32
IFW32FALSE_EXIT(rcbuffSignerPublicKeyBits.Win32Clone(this->m_baSignerPublicKeyToken));
FN_EPILOG
}
//
// ISSUE: jonwis 3/12/2002 - Performance here sucks. We should look in the file table and get
// the one that's already present rather than doing a merge... Mostly we're wasting stack,
// but I'm sure we'd gain something in perf as well.
//
BOOL
CSecurityMetaData::QuickAddFileHash(
const CBaseStringBuffer &rcbuffFileName,
ALG_ID aidHashAlg,
const CBaseStringBuffer &rcbuffHashValue
)
{
FN_PROLOG_WIN32
CMetaDataFileElement Element;
CFusionByteArray baHashBytes;
//
// Build the element
//
IFW32FALSE_EXIT(Element.Initialize());
IFW32FALSE_EXIT(::SxspHashStringToBytes(rcbuffHashValue, rcbuffHashValue.Cch(), baHashBytes));
IFW32FALSE_EXIT(Element.PutHashData(aidHashAlg, baHashBytes));
//
// And merge it in
//
IFW32FALSE_EXIT(
this->AddFileMetaData(
rcbuffFileName,
Element,
eMergeIfAlreadyExists));
FN_EPILOG
}
BOOL
CSecurityMetaData::WritePrimaryAssemblyInfoIntoRegistryKey(
ULONG Flags,
const CRegKey &rhkRegistryNode
) const
{
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
FN_PROLOG_WIN32
//
// ISSUE: jonwis 3/12/2002 - Consider moving hkCodebases into the scope in which
// it belongs, and putting the FusionDbgPrintEx's under DBG.
//
CRegKey hkFilesKey;
CRegKey hkCodebases;
::FusionpDbgPrintEx(
FUSION_DBG_LEVEL_INSTALLATION,
"SXS: %s - starting\n",
__FUNCTION__);
PARAMETER_CHECK((Flags & ~(SXSP_WRITE_PRIMARY_ASSEMBLY_INFO_INTO_REGISTRY_KEY_FLAG_REFRESH)) == 0);
IFW32FALSE_EXIT(
rhkRegistryNode.SetValue(
CSMD_TOPLEVEL_IDENTITY,
this->GetTextualIdentity()));
IFW32FALSE_EXIT( rhkRegistryNode.SetValue(
CSMD_TOPLEVEL_CATALOG,
static_cast<DWORD>(1)));
IFW32FALSE_EXIT( rhkRegistryNode.SetValue(
CSMD_TOPLEVEL_MANIFESTHASH,
REG_BINARY,
this->m_baManifestSha1Hash.GetArrayPtr(),
this->m_baManifestSha1Hash.GetSize() ) );
IFW32FALSE_EXIT(
rhkRegistryNode.OpenOrCreateSubKey(
hkFilesKey,
CSMD_TOPLEVEL_FILES,
KEY_WRITE));
IFW32FALSE_EXIT(this->WriteFilesIntoKey(hkFilesKey));
//
// Write keys into this codebase node
//
if ((Flags & SXSP_WRITE_PRIMARY_ASSEMBLY_INFO_INTO_REGISTRY_KEY_FLAG_REFRESH) == 0)
{
IFW32FALSE_EXIT(
rhkRegistryNode.OpenOrCreateSubKey(
hkCodebases,
CSMD_TOPLEVEL_CODEBASES,
KEY_WRITE));
for (ULONG ulI = 0; ulI < this->m_cilCodebases.GetSize(); ulI++)
{
CRegKey hkSingleCodebaseKey;
const CCodebaseInformation &rcCodebase = m_cilCodebases[ulI];
// Don't attempt to write blank (Darwin) referenced codebases to the
// registry.
if ( rcCodebase.GetReference().Cch() == 0 )
continue;
IFW32FALSE_EXIT(
hkCodebases.OpenOrCreateSubKey(
hkSingleCodebaseKey,
rcCodebase.GetReference(),
KEY_WRITE));
IFW32FALSE_EXIT(rcCodebase.WriteToRegistryKey(hkSingleCodebaseKey));
}
}
#if DBG
else
{
::FusionpDbgPrintEx(
FUSION_DBG_LEVEL_WFP | FUSION_DBG_LEVEL_INSTALLATION,
"SXS.DLL: %s - recovery, not writing codebase and codebase prompt\n",
__FUNCTION__);
}
#endif
FN_EPILOG
}
BOOL
CSecurityMetaData::WriteSecondaryAssemblyInfoIntoRegistryKey(
const CRegKey &rhkRegistryNode
) const
{
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
FN_PROLOG_WIN32
IFW32FALSE_EXIT(rhkRegistryNode.SetValue(CSMD_TOPLEVEL_SHORTNAME, this->GetInstalledDirShortName()));
IFW32FALSE_EXIT(rhkRegistryNode.SetValue(CSMD_TOPLEVEL_SHORTCATALOG, this->GetShortCatalogPath()));
IFW32FALSE_EXIT(rhkRegistryNode.SetValue(CSMD_TOPLEVEL_SHORTMANIFEST, this->GetShortManifestPath()));
IFW32FALSE_EXIT(
rhkRegistryNode.SetValue(
CSMD_TOPLEVEL_PUBLIC_KEY_TOKEN,
REG_BINARY,
this->m_baSignerPublicKeyToken.GetArrayPtr(),
this->m_baSignerPublicKeyToken.GetSize()));
FN_EPILOG
}
BOOL
CSecurityMetaData::WriteFilesIntoKey(
CRegKey & rhkFilesKey
) const
{
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
FN_PROLOG_WIN32
CFileInformationTableIter FilesIterator( const_cast<CFileInformationTable&>(m_fitFileDataTable) );
ULONG uliIndex = 0;
for ( FilesIterator.Reset(); FilesIterator.More(); FilesIterator.Next() )
{
const PCWSTR pcwszFileName = FilesIterator.GetKey();
const CMetaDataFileElement& rcmdfeFileData = FilesIterator.GetValue();
CRegKey hkFileSubKey;
CSmallStringBuffer buffKeySubname;
//
// The trick here is that you can't simply create the subkey off this node,
// as it might be "foo\bar\bas\zip.ding".
//
IFW32FALSE_EXIT( buffKeySubname.Win32Format( L"%ld", uliIndex++ ) );
IFW32FALSE_EXIT( rhkFilesKey.OpenOrCreateSubKey(
hkFileSubKey,
buffKeySubname,
KEY_ALL_ACCESS ) );
//
// So instead, we set the default value of the key to be the name of the file.
//
IFW32FALSE_EXIT( buffKeySubname.Win32Assign( pcwszFileName, lstrlenW(pcwszFileName) ) );
IFW32FALSE_EXIT( hkFileSubKey.SetValue(
NULL,
buffKeySubname ) );
IFW32FALSE_EXIT( rcmdfeFileData.WriteToRegistry( hkFileSubKey ) );
}
FN_EPILOG
}
/*
[name of full assembly]
v : Codebase = [meta-url] <string>
v : Catalog = 1 <dword>
v : Shortname = [shortname generated during installation] <string>
v : ManifestHash = [...] <binary>
v : PublicKeyToken = [...] <binary>
k : Files
k : [Filename]
v : SHA1 = [...] <binary>
v : MD5 = [...] <binary>
k : [Filename]
...
k : Codebases
k : [reference-string]
v : PromptString = [...] <string>
v : Url = [meta-url] <string>
*/
BOOL
CSecurityMetaData::LoadFromRegistryKey(
const CRegKey &rhkRegistryNode
)
{
FN_PROLOG_WIN32
CRegKey hkTempStuff;
DWORD dwHasCatalog = 0;
IFW32FALSE_EXIT(
::FusionpRegQueryDwordValueEx(
0,
rhkRegistryNode,
CSMD_TOPLEVEL_CATALOG,
&dwHasCatalog,
0));
// NTRAID#NTBUG9 - 556327 - jonwis - 2002/04/25 - Remove this assert, make it deal better with zero values
ASSERT(dwHasCatalog != 0);
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
rhkRegistryNode,
CSMD_TOPLEVEL_IDENTITY,
this->m_buffTextualAssemblyIdentity));
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
rhkRegistryNode,
CSMD_TOPLEVEL_SHORTNAME,
this->m_buffShortNameOnDisk));
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
rhkRegistryNode,
CSMD_TOPLEVEL_SHORTCATALOG,
this->m_buffShortCatalogName));
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
rhkRegistryNode,
CSMD_TOPLEVEL_SHORTMANIFEST,
this->m_buffShortManifestName));
IFW32FALSE_EXIT(
::FusionpRegQueryBinaryValueEx(
0,
rhkRegistryNode,
CSMD_TOPLEVEL_MANIFESTHASH,
this->m_baManifestSha1Hash));
IFW32FALSE_EXIT(
::FusionpRegQueryBinaryValueEx(
0,
rhkRegistryNode,
CSMD_TOPLEVEL_PUBLIC_KEY_TOKEN,
this->m_baSignerPublicKeyToken));
IFW32FALSE_EXIT(rhkRegistryNode.OpenSubKey(hkTempStuff, CSMD_TOPLEVEL_CODEBASES, KEY_READ));
if (hkTempStuff != CRegKey::GetInvalidValue())
{
IFW32FALSE_EXIT(this->LoadCodebasesFromKey(hkTempStuff));
IFW32FALSE_EXIT(hkTempStuff.Win32Close());
}
IFW32FALSE_EXIT( rhkRegistryNode.OpenSubKey(hkTempStuff, CSMD_TOPLEVEL_FILES, KEY_READ));
if (hkTempStuff != CRegKey::GetInvalidValue())
{
IFW32FALSE_EXIT(this->LoadFilesFromKey(hkTempStuff));
IFW32FALSE_EXIT(hkTempStuff.Win32Close());
}
FN_EPILOG
}
BOOL
CSecurityMetaData::LoadFilesFromKey(
CRegKey &hkTopLevelFileKey
)
{
FN_PROLOG_WIN32
CSmallStringBuffer buffNextKeyName;
DWORD dwIndex = 0;
while ( true )
{
BOOL fNoMoreItems = FALSE;
CRegKey hkIterator;
buffNextKeyName.Clear();
IFW32FALSE_EXIT(hkTopLevelFileKey.EnumKey(
dwIndex++,
buffNextKeyName,
NULL,
&fNoMoreItems ) );
if ( fNoMoreItems )
{
break;
}
IFW32FALSE_EXIT( hkTopLevelFileKey.OpenSubKey(
hkIterator,
buffNextKeyName,
KEY_READ ) );
if ( hkIterator != CRegKey::GetInvalidValue() )
{
CMetaDataFileElement SingleFileElement;
IFW32FALSE_EXIT( SingleFileElement.Initialize() );
IFW32FALSE_EXIT( SingleFileElement.ReadFromRegistry( hkIterator ) );
//
// Now read the name of the file from the default
//
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
0,
hkIterator,
NULL,
buffNextKeyName));
IFW32FALSE_EXIT(this->AddFileMetaData( buffNextKeyName, SingleFileElement));
}
}
FN_EPILOG
}
class CSecurityMetaDataLoadCodebasesFromKeyLocals
{
public:
CStringBuffer buffKeyNameTemp;
CCodebaseInformation Codebase;
};
BOOL
CSecurityMetaData::LoadCodebasesFromKey(
IN CRegKey& hkCodebaseSubkey
)
{
FN_PROLOG_WIN32
DWORD dwMaxKeyLength = 0;
DWORD dwNextIndex = 0;
CSmartPtr<CSecurityMetaDataLoadCodebasesFromKeyLocals> Locals;
IFW32FALSE_EXIT(Locals.Win32Allocate(__FILE__, __LINE__));
CStringBuffer &buffKeyNameTemp = Locals->buffKeyNameTemp;
//
// Find out how big the largest subkey string is, then reset our iterator temp
// to be that big.
//
IFW32FALSE_EXIT(hkCodebaseSubkey.LargestSubItemLengths(&dwMaxKeyLength, NULL));
IFW32FALSE_EXIT(buffKeyNameTemp.Win32ResizeBuffer(dwMaxKeyLength + 1, eDoNotPreserveBufferContents));
//
// Codebases are stored as subkeys and then values under them.
//
for (;;)
{
BOOL fNoMoreItems = FALSE;
IFW32FALSE_EXIT(
hkCodebaseSubkey.EnumKey(
dwNextIndex++,
buffKeyNameTemp,
NULL,
&fNoMoreItems));
if (fNoMoreItems)
break;
CRegKey hkSingleCodebaseKey;
IFW32FALSE_EXIT(
hkCodebaseSubkey.OpenSubKey(
hkSingleCodebaseKey,
buffKeyNameTemp,
KEY_READ));
if (hkSingleCodebaseKey == CRegKey::GetInvalidValue())
continue;
CCodebaseInformation &Codebase = Locals->Codebase;
IFW32FALSE_EXIT(Codebase.Initialize());
IFW32FALSE_EXIT(Codebase.SetReference(buffKeyNameTemp));
#if DBG
::FusionpDbgPrintEx(
FUSION_DBG_LEVEL_INSTALLATION,
"SXS: %s - read codebase %ls %ls\n",
__FUNCTION__,
static_cast<PCWSTR>(buffKeyNameTemp),
static_cast<PCWSTR>(Codebase.GetCodebase())
);
#endif
IFW32FALSE_EXIT(Codebase.ReadFromRegistryKey(hkSingleCodebaseKey));
IFW32FALSE_EXIT(this->m_cilCodebases.Win32Append(Codebase));
}
FN_EPILOG
}
BOOL
CMetaDataFileElement::Initialize(
const CMetaDataFileElement &other
)
{
FN_PROLOG_WIN32
// The lack of a const iterator here is disturbing, so I have to const_cast
// the metadatafileelement
CFileHashTableIter InputTableIter( const_cast<CMetaDataFileElement&>(other) );
//
// Why is this not a bool??
//
this->ClearNoCallback();
for(InputTableIter.Reset(); InputTableIter.More(); InputTableIter.Next())
{
IFW32FALSE_EXIT( this->Insert( InputTableIter.GetKey(), InputTableIter.GetValue() ) );
}
FN_EPILOG
}
BOOL
CCodebaseInformation::Initialize()
{
this->m_Codebase.Clear();
this->m_PromptText.Clear();
this->m_Reference.Clear();
this->m_Type = CODEBASE_RESOLVED_URLHEAD_UNKNOWN;
return TRUE;
}
BOOL
CCodebaseInformation::Initialize(
const CCodebaseInformation &other
)
{
FN_PROLOG_WIN32
IFW32FALSE_EXIT(this->SetCodebase(other.GetCodebase()));
IFW32FALSE_EXIT(this->SetPromptText(other.GetPromptText()));
IFW32FALSE_EXIT(this->SetReference(other.GetReference()));
this->m_Type = other.m_Type;
FN_EPILOG
}
BOOL
CCodebaseInformation::WriteToRegistryKey(
const CRegKey &rhkCodebaseKey
) const
{
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
FN_PROLOG_WIN32
if (m_PromptText.Cch() != 0)
{
IFW32FALSE_EXIT(
rhkCodebaseKey.SetValue(
CSMD_CODEBASES_PROMPTSTRING,
this->m_PromptText));
}
IFW32FALSE_EXIT(
rhkCodebaseKey.SetValue(
CSMD_CODEBASES_URL,
this->m_Codebase));
FN_EPILOG
}
BOOL
CCodebaseInformation::ReadFromRegistryKey(
const CRegKey &rhkSingleCodebaseKey
)
{
FN_PROLOG_WIN32
//
// Missing prompt is OK
//
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
rhkSingleCodebaseKey,
CSMD_CODEBASES_PROMPTSTRING,
m_PromptText));
//
// We don't want to fail just because someone messed up the registry...
//
IFW32FALSE_EXIT(
::FusionpRegQuerySzValueEx(
FUSIONP_REG_QUERY_SZ_VALUE_EX_MISSING_GIVES_NULL_STRING,
rhkSingleCodebaseKey,
CSMD_CODEBASES_URL,
m_Codebase));
FN_EPILOG
}
BOOL
CCodebaseInformationList::FindCodebase(
const CBaseStringBuffer &rbuffReference,
CCodebaseInformation *&rpCodebaseInformation
)
{
FN_PROLOG_WIN32
bool fMatches = false;
SIZE_T i = 0;
rpCodebaseInformation = NULL;
for (i=0; i < m_cElements; i++)
{
IFW32FALSE_EXIT(m_prgtElements[i].GetReference().Win32Equals(rbuffReference, fMatches, true));
if (fMatches)
break;
}
if (fMatches)
{
INTERNAL_ERROR_CHECK(i < m_cElements);
rpCodebaseInformation = &m_prgtElements[i];
}
FN_EPILOG
}
BOOL
CCodebaseInformationList::RemoveCodebase(
const CBaseStringBuffer &rbuffReference,
bool &rfRemoved
)
{
FN_PROLOG_WIN32
bool fMatches = false;
SIZE_T i = 0;
rfRemoved = false;
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
for (i=0; i < m_cElements; i++)
{
IFW32FALSE_EXIT(m_prgtElements[i].GetReference().Win32Equals(rbuffReference, fMatches, true));
if (fMatches)
{
IFW32FALSE_EXIT(this->Win32Remove(i));
rfRemoved = true;
break;
}
}
FN_EPILOG
}
BOOL
SxspValidateAllFileHashes(
IN const CMetaDataFileElement &rmdfeElement,
IN const CBaseStringBuffer &rbuffFileName,
OUT HashValidateResult &rResult
)
{
FN_PROLOG_WIN32
DWORD dwIndex = 0;
CSmallStringBuffer buffHashName;
BOOL fAllHashesMatch = TRUE;
CFusionByteArray baFileHashData;
rResult = HashValidate_OtherProblems;
while ( true && fAllHashesMatch )
{
BOOL fTemp;
ALG_ID aid = 0;
HashValidateResult Results = HashValidate_OtherProblems;
IFW32FALSE_EXIT(
::SxspEnumKnownHashTypes(
dwIndex++,
buffHashName,
fTemp));
if (fTemp)
break;
IFW32FALSE_EXIT( SxspHashAlgFromString( buffHashName, aid ) );
//
// Did the file element have this type of hash data in it?
//
IFW32FALSE_EXIT( rmdfeElement.GetHashDataForKind(
buffHashName,
baFileHashData,
fTemp ));
if ( !fTemp )
{
continue;
}
IFW32FALSE_EXIT( ::SxspVerifyFileHash(
SVFH_RETRY_LOGIC_SIMPLE,
rbuffFileName,
baFileHashData,
aid,
Results ) );
if ( Results != HashValidate_Matches )
{
fAllHashesMatch = FALSE;
}
}
if ( fAllHashesMatch )
{
rResult = HashValidate_Matches;
}
FN_EPILOG
}
BOOL
CSecurityMetaData::RemoveCodebase(
const CBaseStringBuffer &rbuffReference,
bool &rfRemoved
)
{
if (SXS_AVOID_WRITING_REGISTRY)
return TRUE;
return m_cilCodebases.RemoveCodebase(rbuffReference, rfRemoved);
}