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.
 
 
 
 
 
 

1697 lines
49 KiB

/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
InstalledDatabaseStore.cpp
Abstract:
This file contains the implementation of the Taxonomy::InstalledInstanceStore class,
which controls the set of Topic Databases installed on the machine.
Revision History:
Davide Massarenti (Dmassare) 05/01/2000
created
******************************************************************************/
#include "stdafx.h"
#include <SAFLIB.h>
#include <SEConfig.h>
////////////////////////////////////////////////////////////////////////////////
static const WCHAR c_DB_BUGREPT [] = L"bugrept.cab";
static const WCHAR c_DB_RCBDY [] = L"rcBuddy.cab";
static const WCHAR c_DB_PSS [] = L"pss.cab";
static const WCHAR c_DB_NEWSGROUPS[] = L"newsgroups.cab";
static const WCHAR c_REG_BACKUP [] = L"PackageStore";
static const WCHAR c_REG_CRC [] = L"CRC_Disk";
static const WCHAR c_REG_CRC_BAK[] = L"CRC_Registry";
////////////////////////////////////////////////////////////////////////////////
LPCWSTR const Taxonomy::Strings::s_file_PackageDescription = L"package_description.xml";
LPCWSTR const Taxonomy::Strings::s_tag_root_PackageDescription = L"HELPCENTERPACKAGE";
LPCWSTR const Taxonomy::Strings::s_tag_root_HHT = L"METADATA";
LPCWSTR const Taxonomy::Strings::s_tag_root_SAF = L"SAFConfig";
////////////////////////////////////////////////////////////////////////////////
static void local_GetFileForCRC( /*[out]*/ MPC::wstring& strDest ,
/*[in]*/ LPCWSTR szValue )
{
strDest = HC_ROOT_HELPSVC_PKGSTORE L"\\";
strDest += szValue;
MPC::SubstituteEnvVariables( strDest );
}
static HRESULT local_OpenForRead( /*[in/out]*/ MPC::RegKey& rkBase )
{
__HCP_FUNC_ENTRY( "local_OpenForRead" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.SetRoot( HKEY_LOCAL_MACHINE ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.Attach ( HC_REGISTRY_HELPSVC L"\\Backup" ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static HRESULT local_OpenForWrite( /*[in/out]*/ MPC::RegKey& rkBase )
{
__HCP_FUNC_ENTRY( "local_OpenForWrite" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.SetRoot( HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.Attach ( HC_REGISTRY_HELPSVC L"\\Backup" ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.Create ( ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static HRESULT local_CreateCRC( /*[in]*/ MPC::RegKey* rkBase ,
/*[in]*/ LPCWSTR szValue ,
/*[in]*/ IStream* stream )
{
__HCP_FUNC_ENTRY( "local_CreateCRC" );
HRESULT hr;
LARGE_INTEGER li = { 0, 0 };
DWORD dwCRC; MPC::InitCRC( dwCRC );
__MPC_EXIT_IF_METHOD_FAILS(hr, stream->Seek( li, STREAM_SEEK_SET, NULL ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ComputeCRC( dwCRC, stream ));
if(rkBase)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase->Write( dwCRC, szValue ));
}
else
{
MPC::wstring strDest;
CComPtr<MPC::FileStream> stream2;
ULONG cb;
local_GetFileForCRC( strDest, szValue );
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Init( strDest.c_str(), stream2 ));
__MPC_EXIT_IF_METHOD_FAILS(hr, stream2->Write( &dwCRC, sizeof(dwCRC), &cb )); stream2.Release();
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Finalize( strDest.c_str(), stream2 ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static HRESULT local_CheckCRC( /*[in]*/ MPC::RegKey* rkBase ,
/*[in]*/ LPCWSTR szValue ,
/*[in]*/ IStream* stream )
{
__HCP_FUNC_ENTRY( "local_CheckCRC" );
HRESULT hr;
DWORD dwCRC;
bool fFound = false;
if(rkBase)
{
if(FAILED(rkBase->Read( dwCRC, fFound, szValue ))) fFound = false;
}
else
{
MPC::wstring strDest;
CComPtr<MPC::FileStream> stream2;
local_GetFileForCRC( strDest, szValue );
if(SUCCEEDED(SVC::SafeLoad( strDest.c_str(), stream2 )))
{
ULONG cb;
if(SUCCEEDED(stream2->Read( &dwCRC, sizeof(dwCRC), &cb )) && cb == sizeof(dwCRC))
{
fFound = true;
}
}
}
if(fFound)
{
LARGE_INTEGER li = { 0, 0 };
DWORD dwCRC2; MPC::InitCRC( dwCRC2 );
__MPC_EXIT_IF_METHOD_FAILS(hr, stream->Seek( li, STREAM_SEEK_SET, NULL ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ComputeCRC( dwCRC2, stream ));
if(dwCRC != dwCRC2)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////
static HRESULT local_AddPackage( /*[in ]*/ Taxonomy::InstalledInstanceStore* store ,
/*[in/out]*/ MPC::wstring& strTmp ,
/*[in ]*/ const MPC::wstring& strDir ,
/*[in ]*/ LPCWSTR szExtra ,
/*[in ]*/ const Taxonomy::HelpSet& ths )
{
__HCP_FUNC_ENTRY( "local_AddPackage" );
HRESULT hr;
Taxonomy::PackageIter it;
bool fFound;
strTmp = strDir; strTmp.append( szExtra );
__MPC_EXIT_IF_METHOD_FAILS(hr, store->Package_Add( strTmp.c_str(), NULL, &ths, /*fInsertAtTop*/true, fFound, it ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DeleteFile ( strTmp ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Taxonomy::Instance::InitializeFromBase( /*[in]*/ const InstanceBase& base, /*[in]*/ bool fSystem, /*[in]*/ bool fMUI )
{
__HCP_FUNC_ENTRY( "Taxonomy::Instance::InitializeFromBase" );
HRESULT hr;
Taxonomy::Settings ts( base.m_ths );
((InstanceBase&)*this) = base;
m_fSystem = fSystem;
m_fMUI = fMUI;
if(fSystem)
{
//
// Set machine-wide defaults.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::HelpSet::SetMachineInfo ( base ));
__MPC_EXIT_IF_METHOD_FAILS(hr, OfflineCache::Root::s_GLOBAL->SetMachineInfo( *this ));
}
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.BaseDir ( m_strSystem , /*fExpand*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.HelpFilesDir( m_strHelpFiles, /*fExpand*/false, /*fMUI*/m_fMUI ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.DatabaseDir ( m_strDatabaseDir ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.DatabaseFile( m_strDatabaseFile ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.IndexFile ( m_strIndexFile ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::Instance::Import( /*[in]*/ LPCWSTR szFile, /*[in/out]*/ DWORD* pdwCRC )
{
__HCP_FUNC_ENTRY( "Taxonomy::Instance::Import" );
HRESULT hr;
MPC::wstring strFileDst;
__MPC_EXIT_IF_METHOD_FAILS(hr, GetFileName ( strFileDst ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CopyFile( szFile, strFileDst.c_str() ));
::SetFileAttributesW( strFileDst.c_str(), FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM );
if(pdwCRC)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ComputeCRC( *pdwCRC, strFileDst.c_str() ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::Instance::Remove()
{
__HCP_FUNC_ENTRY( "Taxonomy::Instance::Remove" );
HRESULT hr;
MPC::wstring strFileDst;
__MPC_EXIT_IF_METHOD_FAILS(hr, GetFileName ( strFileDst ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DeleteFile( strFileDst ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
Taxonomy::InstalledInstance::InstalledInstance()
{
// Instance m_inst;
// ProcessedPackageList m_lst;
m_fInvalidated = false; // bool m_fInvalidated;
m_fRecreateCache = true; // bool m_fRecreateCache;
m_fCreateIndex = true; // bool m_fCreateIndex;
m_fCreateIndexForce = true; // bool m_fCreateIndexForce;
m_dwCRC = 0; // DWORD m_dwCRC;
//
m_dwRef = 0; // DWORD m_dwRef; // VOLATILE
}
HRESULT Taxonomy::operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ Taxonomy::InstalledInstance& val )
{
HRESULT hr;
if(SUCCEEDED(hr = (stream >> val.m_inst )) &&
SUCCEEDED(hr = (stream >> val.m_lst )) &&
SUCCEEDED(hr = (stream >> val.m_fInvalidated )) &&
SUCCEEDED(hr = (stream >> val.m_fRecreateCache )) &&
SUCCEEDED(hr = (stream >> val.m_fCreateIndex )) &&
SUCCEEDED(hr = (stream >> val.m_fCreateIndexForce)) &&
SUCCEEDED(hr = (stream >> val.m_dwCRC )) )
{
hr = S_OK;
}
return hr;
}
HRESULT Taxonomy::operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const Taxonomy::InstalledInstance& val )
{
HRESULT hr;
if(SUCCEEDED(hr = (stream << val.m_inst )) &&
SUCCEEDED(hr = (stream << val.m_lst )) &&
SUCCEEDED(hr = (stream << val.m_fInvalidated )) &&
SUCCEEDED(hr = (stream << val.m_fRecreateCache )) &&
SUCCEEDED(hr = (stream << val.m_fCreateIndex )) &&
SUCCEEDED(hr = (stream << val.m_fCreateIndexForce)) &&
SUCCEEDED(hr = (stream << val.m_dwCRC )) )
{
hr = S_OK;
}
return hr;
}
HRESULT Taxonomy::InstalledInstance::InstallFiles( /*[in]*/ bool fAlsoHelpFiles ,
/*[in]*/ InstalledInstanceStore* store )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstance::InstallFiles" );
HRESULT hr;
Taxonomy::Settings ts( m_inst.m_ths );
Installer::Package pkg;
MPC::wstring strDir_System;
MPC::wstring strDir_HelpFiles;
MPC::wstring strDir_Database;
MPC::wstring strFile_Database;
MPC::wstring strFile_SetupImage;
bool fReinstall = (store == NULL);
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.BaseDir ( strDir_System , /*fExpand*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.HelpFilesDir( strDir_HelpFiles, /*fExpand*/false, /*fMUI*/m_inst.m_fMUI ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.DatabaseDir ( strDir_Database ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.DatabaseFile( strFile_Database ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_DATABASE , /*fRemove*/true , /*fRecreate*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_INDEX , /*fRemove*/true , /*fRecreate*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_SYSTEM , /*fRemove*/true , /*fRecreate*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_SYSTEM_OEM, /*fRemove*/true , /*fRecreate*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_VENDORS , /*fRemove*/true , /*fRecreate*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_HELPFILES , /*fRemove*/fAlsoHelpFiles, /*fRecreate*/true ));
//
// Change the ACL for system directories.
//
{
CPCHSecurityDescriptorDirect sdd;
MPC::wstring strGroupName;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeString( IDS_HELPSVC_GROUPNAME, strGroupName ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.Initialize());
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.SetGroup( strGroupName.c_str() ));
//
// LOCAL SYSTEM, Admin, Admins : any access.
// Everyone : read and execute.
//
//
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.Add( (PSID)&sdd.s_SystemSid ,
ACCESS_ALLOWED_ACE_TYPE ,
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
FILE_ALL_ACCESS ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.Add( (PSID)&sdd.s_Alias_AdminsSid ,
ACCESS_ALLOWED_ACE_TYPE ,
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
FILE_ALL_ACCESS ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sdd.Add( (PSID)&sdd.s_EveryoneSid ,
ACCESS_ALLOWED_ACE_TYPE ,
OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
FILE_GENERIC_READ | FILE_GENERIC_EXECUTE ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System, HC_HELPSET_SUB_DATABASE ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System, HC_HELPSET_SUB_INDEX ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System, HC_HELPSET_SUB_SYSTEM ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System, HC_HELPSET_SUB_SYSTEM_OEM ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System, HC_HELPSET_SUB_VENDORS ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::ChangeSD( sdd, strDir_System, HC_HELPSET_SUB_HELPFILES ));
}
{
bool fReload = false;
__MPC_EXIT_IF_METHOD_FAILS(hr, m_inst.GetFileName( strFile_SetupImage ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init ( strFile_SetupImage.c_str() ));
if(m_dwCRC)
{
DWORD dwCRC;
if(FAILED(MPC::ComputeCRC( dwCRC, strFile_SetupImage.c_str() )) || m_dwCRC != dwCRC) fReload = true;
}
if(fReload == false)
{
if(FAILED(pkg.Load())) fReload = true;
}
//
// If the package has been corrupted, try to restore from BINARIES.
//
if(fReload)
{
MPC::WStringList lst;
MPC::WStringIter it;
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::LocateDataArchive( HC_ROOT_HELPSVC_BINARIES, lst ));
for(it = lst.begin(); it != lst.end(); it++)
{
if(SUCCEEDED(pkg.Init( it->c_str() )) &&
SUCCEEDED(pkg.Load( )) )
{
if(pkg.GetData().m_ths == m_inst.m_ths)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, m_inst.Import( it->c_str(), &m_dwCRC ));
break;
}
}
}
if(it == lst.end())
{
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_FILE_NOT_FOUND);
}
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Phase Two: install files.
//
{
static const Installer::PURPOSE c_allowedFull[] =
{
Installer::PURPOSE_DATABASE,
Installer::PURPOSE_PACKAGE ,
Installer::PURPOSE_UI ,
Installer::PURPOSE_INVALID ,
};
static const Installer::PURPOSE c_allowedReinstall[] =
{
Installer::PURPOSE_DATABASE,
////Installer::PURPOSE_PACKAGE , Don't extract system packages on a reinstall.
Installer::PURPOSE_UI ,
Installer::PURPOSE_INVALID ,
};
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Install( fReinstall ? c_allowedReinstall : c_allowedFull, m_inst.m_fSystem ? NULL : strDir_System.c_str() ));
}
if(m_inst.m_fSystem || m_inst.m_fMUI)
{
if(store)
{
MPC::wstring strTmp;
__MPC_EXIT_IF_METHOD_FAILS(hr, local_AddPackage( store, strTmp, strDir_Database, c_DB_NEWSGROUPS, m_inst.m_ths ));
__MPC_EXIT_IF_METHOD_FAILS(hr, local_AddPackage( store, strTmp, strDir_Database, c_DB_PSS , m_inst.m_ths ));
// No Remote Assistence on IA64
#ifndef WIN64
__MPC_EXIT_IF_METHOD_FAILS(hr, local_AddPackage( store, strTmp, strDir_Database, c_DB_RCBDY , m_inst.m_ths ));
#endif
// Only available on Beta releases.
#if 0
__MPC_EXIT_IF_METHOD_FAILS(hr, local_AddPackage( store, strTmp, strDir_Database, c_DB_BUGREPT , m_inst.m_ths ));
#endif
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstance::UninstallFiles( /*[in]*/ bool fAlsoHelpFiles )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstance::UninstallFiles" );
USES_CONVERSION;
HRESULT hr;
Taxonomy::Settings ts( m_inst.m_ths );
MPC::wstring strDir_System;
MPC::wstring strFile_Database;
SearchEngine::Config cfg;
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.BaseDir ( strDir_System , /*fExpand*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ts.DatabaseFile( strFile_Database ));
__MPC_EXIT_IF_METHOD_FAILS(hr, JetBlue::SessionPool::s_GLOBAL->ReleaseDatabase( W2A( strFile_Database.c_str() ) ));
__MPC_EXIT_IF_METHOD_FAILS(hr, CSAFReg:: s_GLOBAL->RemoveSKU ( m_inst.m_ths ));
__MPC_EXIT_IF_METHOD_FAILS(hr, cfg . ResetSKU ( m_inst.m_ths ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_DATABASE , /*fRemove*/true, /*fRecreate*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_INDEX , /*fRemove*/true, /*fRecreate*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_SYSTEM , /*fRemove*/true, /*fRecreate*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_SYSTEM_OEM, /*fRemove*/true, /*fRecreate*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_VENDORS , /*fRemove*/true, /*fRecreate*/false ));
if(fAlsoHelpFiles)
{
if(!m_inst.m_fMUI)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, HC_HELPSET_SUB_HELPFILES, /*fRemove*/true, /*fRecreate*/false ));
}
if(!m_inst.m_fSystem)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::RemoveAndRecreateDirectory( strDir_System, NULL, /*fRemove*/true, /*fRecreate*/false ));
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
Taxonomy::LockingHandle::LockingHandle()
{
m_main = NULL; // InstalledInstanceStore* m_main;
m_logPrevious = NULL; // Logger* m_logPrevious;
}
Taxonomy::LockingHandle::~LockingHandle()
{
Release();
}
void Taxonomy::LockingHandle::Attach( /*[in]*/ InstalledInstanceStore* main ,
/*[in]*/ Logger* log )
{
Release();
main->Lock();
m_main = main;
m_logPrevious = main->m_log;
if(log) main->m_log = log;
}
void Taxonomy::LockingHandle::Release()
{
if(m_main)
{
m_main->m_log = m_logPrevious; m_logPrevious = NULL;
m_main->Unlock(); m_main = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////
Taxonomy::InstalledInstanceStore::InstalledInstanceStore()
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::InstalledInstanceStore" );
// InstanceList m_lstInstances;
// PackageList m_lstPackages;
// InstalledInstanceList m_lstSKUs;
//
//
MPC::SubstituteEnvVariables( m_strStore = HC_HELPSVC_STORE_SKUS ); // MPC::wstring m_strStore;
m_fLoaded = false; // bool m_fLoaded;
m_fDirty = false; // bool m_fDirty;
m_log = NULL; // Logger* m_log;
//
m_dwRecurse = 0; // DWORD m_dwRecurse;
//
m_fShutdown = false; // bool m_fShutdown;
}
Taxonomy::InstalledInstanceStore::~InstalledInstanceStore()
{
(void)EnsureInSync();
}
////////////////////
Taxonomy::InstalledInstanceStore* Taxonomy::InstalledInstanceStore::s_GLOBAL( NULL );
HRESULT Taxonomy::InstalledInstanceStore::InitializeSystem()
{
if(s_GLOBAL == NULL)
{
s_GLOBAL = new Taxonomy::InstalledInstanceStore;
}
return s_GLOBAL ? S_OK : E_OUTOFMEMORY;
}
void Taxonomy::InstalledInstanceStore::FinalizeSystem()
{
if(s_GLOBAL)
{
delete s_GLOBAL; s_GLOBAL = NULL;
}
}
////////////////////////////////////////
void Taxonomy::InstalledInstanceStore::Shutdown()
{
LockingHandle handle;
m_fShutdown = true;
if(SUCCEEDED(GrabControl( handle, NULL ))) // This will wait until the rest of the system has release the object.
{
(void)EnsureInSync();
}
}
void Taxonomy::InstalledInstanceStore::Clean()
{
m_lstInstances.clear();
m_lstPackages .clear();
m_lstSKUs .clear();
}
HRESULT Taxonomy::InstalledInstanceStore::Load()
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::Load" );
HRESULT hr;
bool fSystemSet = false;
if(FAILED(LoadFromDisk ( m_strStore.c_str() )) &&
FAILED(LoadFromRegistry( )) )
{
__MPC_SET_ERROR_AND_EXIT(hr, S_FALSE);
}
for(InstalledInstanceIter it = m_lstSKUs.begin(); it != m_lstSKUs.end(); it++)
{
Taxonomy::Instance& data = it->m_inst;
if(data.m_fSystem)
{
if(fSystemSet)
{
data.m_fSystem = false; // No other sku can be SYSTEM!!
}
else
{
__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::Settings::SetMachineInfo( data ));
fSystemSet = true;
}
}
}
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::LoadFromDisk( /*[in]*/ LPCWSTR szFile )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::LoadFromDisk" );
HRESULT hr;
CComPtr<MPC::FileStream> stream;
Clean();
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeLoad ( szFile, stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFromStream( stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, local_CheckCRC( NULL, c_REG_CRC, stream ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::LoadFromRegistry()
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::LoadFromRegistry" );
HRESULT hr;
MPC::RegKey rkBase;
CComPtr<IStream> stream;
CComVariant v;
bool fFound;
Clean();
__MPC_EXIT_IF_METHOD_FAILS(hr, local_OpenForRead( rkBase ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.get_Value( v, fFound, c_REG_BACKUP ));
if(!fFound)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertVariantToIStream( &v, &stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFromStream ( stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, local_CheckCRC( &rkBase, c_REG_CRC_BAK, stream ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::LoadFromStream( /*[in]*/ IStream* stream )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::LoadFromStream" );
HRESULT hr;
MPC::Serializer_IStream streamGen ( stream );
MPC::Serializer_Buffering streamGen2( streamGen );
DWORD dwVer;
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 >> dwVer); if(dwVer != s_dwVersion) __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 >> m_lstInstances);
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 >> m_lstPackages );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 >> m_lstSKUs );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////
HRESULT Taxonomy::InstalledInstanceStore::Save()
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::Save" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveToDisk( m_strStore.c_str() ));
//
// Ignore failures on backup.
//
(void)SaveToRegistry();
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::SaveToDisk( /*[in]*/ LPCWSTR szFile )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::SaveToDisk" );
HRESULT hr;
CComPtr<MPC::FileStream> stream;
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Init ( szFile, stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveToStream ( stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Finalize( szFile, stream ));
if(SUCCEEDED(SVC::SafeLoad( szFile, stream )))
{
(void)local_CreateCRC( NULL, c_REG_CRC, stream );
}
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::SaveToRegistry()
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::SaveToRegistry" );
HRESULT hr;
MPC::RegKey rkBase;
CComPtr<IStream> stream;
CComVariant v;
__MPC_EXIT_IF_METHOD_FAILS(hr, local_OpenForWrite( rkBase ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateStreamOnHGlobal ( NULL, TRUE, &stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveToStream ( stream ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertIStreamToVariant( stream, v ));
__MPC_EXIT_IF_METHOD_FAILS(hr, rkBase.put_Value ( v, c_REG_BACKUP ));
__MPC_EXIT_IF_METHOD_FAILS(hr, local_CreateCRC( &rkBase, c_REG_CRC_BAK, stream ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::SaveToStream( /*[in]*/ IStream* stream )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::SaveToStream" );
HRESULT hr;
MPC::Serializer_IStream streamGen ( stream );
MPC::Serializer_Buffering streamGen2( streamGen );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << s_dwVersion);
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << m_lstInstances);
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << m_lstPackages );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << m_lstSKUs );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2.Flush());
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
////////////////////
HRESULT Taxonomy::InstalledInstanceStore::EnsureInSync()
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::EnsureInSync" );
HRESULT hr;
if(m_fLoaded == false)
{
m_fLoaded = true;
if(FAILED(Load()))
{
Clean();
}
}
if(m_fDirty == true)
{
m_fDirty = false;
__MPC_EXIT_IF_METHOD_FAILS(hr, Save());
}
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Taxonomy::InstalledInstanceStore::InUse_Lock( /*[in]*/ const Taxonomy::HelpSet& ths )
{
__HCP_BEGIN_PROPERTY_PUT( "Taxonomy::InstalledInstanceStore::InUse_Lock", hr );
InstalledInstanceIter it;
bool fFound;
__MPC_EXIT_IF_METHOD_FAILS(hr, SKU_Find( ths, fFound, it ));
if(fFound)
{
it->m_dwRef++;
}
__HCP_END_PROPERTY(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::InUse_Unlock( /*[in]*/ const Taxonomy::HelpSet& ths )
{
__HCP_BEGIN_PROPERTY_PUT( "Taxonomy::InstalledInstanceStore::InUse_Unlock", hr );
InstalledInstanceIter it;
bool fFound;
__MPC_EXIT_IF_METHOD_FAILS(hr, SKU_Find( ths, fFound, it ));
if(fFound && it->m_dwRef)
{
it->m_dwRef--;
}
__HCP_END_PROPERTY(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::GrabControl( /*[in]*/ LockingHandle& handle,
/*[in]*/ Logger* log )
{
HRESULT hr;
handle.Attach( this, log );
if(FAILED(hr = EnsureInSync()))
{
handle.Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Taxonomy::InstalledInstanceStore::Instance_GetList( /*[out]*/ InstanceIterConst& itBegin, /*[out]*/ InstanceIterConst& itEnd )
{
itBegin = m_lstInstances.begin();
itEnd = m_lstInstances.end ();
return S_OK;
}
HRESULT Taxonomy::InstalledInstanceStore::Package_GetList( /*[out]*/ PackageIterConst& itBegin, /*[out]*/ PackageIterConst& itEnd )
{
itBegin = m_lstPackages.begin();
itEnd = m_lstPackages.end ();
return S_OK;
}
HRESULT Taxonomy::InstalledInstanceStore::SKU_GetList( /*[out]*/ InstalledInstanceIterConst& itBegin, /*[out]*/ InstalledInstanceIterConst& itEnd )
{
itBegin = m_lstSKUs.begin();
itEnd = m_lstSKUs.end ();
return S_OK;
}
////////////////////
HRESULT Taxonomy::InstalledInstanceStore::Instance_Find( /*[in ]*/ const Taxonomy::HelpSet& ths ,
/*[out]*/ bool& fFound ,
/*[out]*/ InstanceIter& it )
{
fFound = false;
for(it = m_lstInstances.begin(); it != m_lstInstances.end(); it++)
{
if(it->m_ths == ths)
{
fFound = true;
break;
}
}
return S_OK;
}
HRESULT Taxonomy::InstalledInstanceStore::Instance_Add( /*[in ]*/ LPCWSTR szFile ,
/*[in ]*/ const Instance& data ,
/*[out]*/ bool& fFound ,
/*[out]*/ InstanceIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::Instance_Add" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, Instance_Find( data.m_ths, fFound, it ));
if(!fFound)
{
it = m_lstInstances.insert( m_lstInstances.end(), data ); it->SetTimeStamp();
__MPC_EXIT_IF_METHOD_FAILS(hr, it->Import( szFile, NULL ));
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::Instance_Remove( /*[in]*/ InstanceIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::Instance_Remove" );
HRESULT hr;
MPC::wstring strFileDst;
bool fFound;
//
// Uninstall SKU.
//
{
InstalledInstanceIter itSKU;
__MPC_EXIT_IF_METHOD_FAILS(hr, SKU_Find( it->m_ths, fFound, itSKU ));
if(fFound)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, SKU_Remove( itSKU ));
}
}
//
// Remove any built-in package from this instance.
//
{
Logger logTmp;
Logger* log = (m_log ? m_log : &logTmp);
PackageIter itPackage;
for(itPackage = m_lstPackages.begin(); itPackage != m_lstPackages.end(); )
{
PackageIter itPackage2 = itPackage++; // Copy iterator to protect against deletion.
Package& pkg = *itPackage2;
if(pkg.m_fBuiltin && it->Match( pkg ))
{
(void)pkg.Remove( *log );
m_lstPackages.erase( itPackage2 );
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
}
}
__MPC_EXIT_IF_METHOD_FAILS(hr, it->Remove());
m_lstInstances.erase( it );
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Taxonomy::InstalledInstanceStore::Package_Find( /*[in ]*/ const Package& pkg ,
/*[out]*/ bool& fFound ,
/*[out]*/ PackageIter& it )
{
fFound = false;
for(it = m_lstPackages.begin(); it != m_lstPackages.end(); it++)
{
if(it->Compare( pkg ) == 0)
{
fFound = true;
break;
}
}
return S_OK;
}
HRESULT Taxonomy::InstalledInstanceStore::Package_Add( /*[in ]*/ LPCWSTR szFile ,
/*[in ]*/ MPC::Impersonation* imp ,
/*[in ]*/ const Taxonomy::HelpSet* ths ,
/*[in ]*/ bool fInsertAtTop ,
/*[out]*/ bool& fFound ,
/*[out]*/ PackageIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::Package_Add" );
HRESULT hr;
Logger logTmp;
Logger* log = (m_log ? m_log : &logTmp);
Package pkg;
long lSequence = 1;
if(ths)
{
WCHAR rgLCID[64];
pkg.m_fBuiltin = true;
pkg.m_strSKU = ths->GetSKU ();
pkg.m_strLanguage = _ltow( ths->GetLanguage(), rgLCID, 10 );
}
//
// Found a suitable sequence number.
//
for(it = m_lstPackages.begin(); it != m_lstPackages.end(); it++)
{
if(lSequence <= it->m_lSequence) lSequence = it->m_lSequence + 1;
}
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Import ( *log, szFile, lSequence, imp ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Authenticate( *log ));
__MPC_EXIT_IF_METHOD_FAILS(hr, Package_Find( pkg, fFound, it ));
if(fFound)
{
if(it->m_dwCRC != pkg.m_dwCRC) // CRC differs, different package?
{
__MPC_EXIT_IF_METHOD_FAILS(hr, Package_Remove( it ));
fFound = false;
}
}
if(fFound)
{
pkg.m_fTemporary = true; // Delete the copy...
}
else
{
if (fInsertAtTop)
{
it = m_lstPackages.insert( m_lstPackages.begin(), pkg );
}
else
{
it = m_lstPackages.insert( m_lstPackages.end(), pkg );
}
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
//
// Check if have an installed SKU that actually matches this package.
//
{
InstalledInstanceIter itSKU;
for(itSKU = m_lstSKUs.begin(); itSKU != m_lstSKUs.end(); itSKU++)
{
InstalledInstance& sku = *itSKU;
if(sku.m_inst.Match( *it ))
{
break;
}
}
if(itSKU == m_lstSKUs.end())
{
log->WriteLog( -1, L"\nWARNING: the package cannot be applied to any of the installed SKUs\n\n" );
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::Package_Remove( /*[in]*/ PackageIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::Package_Remove" );
HRESULT hr;
Logger logTmp;
Logger* log = (m_log ? m_log : &logTmp);
bool fFound;
__MPC_EXIT_IF_METHOD_FAILS(hr, it->Remove( *log ));
__MPC_EXIT_IF_METHOD_FAILS(hr, State_InvalidatePackage( it->m_lSequence ));
m_lstPackages.erase( it );
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////
HRESULT Taxonomy::InstalledInstanceStore::SKU_Find( /*[in ]*/ const Taxonomy::HelpSet& ths ,
/*[out]*/ bool& fFound ,
/*[out]*/ InstalledInstanceIter& it )
{
fFound = false;
for(it = m_lstSKUs.begin(); it != m_lstSKUs.end(); it++)
{
if(it->m_inst.m_ths == ths)
{
fFound = true;
break;
}
}
return S_OK;
}
HRESULT Taxonomy::InstalledInstanceStore::SKU_Add( /*[in ]*/ const Instance& data ,
/*[out]*/ bool& fFound ,
/*[out]*/ InstalledInstanceIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::SKU_Add" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, SKU_Find( data.m_ths, fFound, it ));
if(!fFound)
{
it = m_lstSKUs.insert( m_lstSKUs.end() );
it->m_inst = data; it->m_inst.SetTimeStamp();
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
__MPC_EXIT_IF_METHOD_FAILS(hr, it->InstallFiles( /*fAlsoHelpFiles*/true, this ));
//
// Propagate change to the offline cache.
//
if(SUCCEEDED(OfflineCache::Root::s_GLOBAL->Import( it->m_inst )))
{
(void)OfflineCache::Root::s_GLOBAL->Flush();
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::SKU_Updated( /*[in]*/ InstalledInstanceIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::SKU_Updated" );
HRESULT hr;
bool fFound;
it->m_inst.SetTimeStamp();
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
//
// Propagate change to the offline cache.
//
{
if(SUCCEEDED(OfflineCache::Root::s_GLOBAL->Import( it->m_inst )))
{
(void)OfflineCache::Root::s_GLOBAL->Flush();
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::SKU_Remove( /*[in]*/ InstalledInstanceIter& it )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::SKU_Remove" );
HRESULT hr;
if(m_dwRef)
{
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_BUSY);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, it->UninstallFiles( /*fAlsoHelpFiles*/true ));
//
// Propagate change to the offline cache.
//
{
if(SUCCEEDED(OfflineCache::Root::s_GLOBAL->Remove( it->m_inst.m_ths )))
{
(void)OfflineCache::Root::s_GLOBAL->Flush();
}
}
m_lstSKUs.erase( it );
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Taxonomy::InstalledInstanceStore::State_InvalidateSKU( /*[in]*/ const Taxonomy::HelpSet& ths, /*[in]*/ bool fAlsoDatabase )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::State_InvalidateSKU" );
HRESULT hr;
InstalledInstanceIter itSKU;
for(itSKU = m_lstSKUs.begin(); itSKU != m_lstSKUs.end(); itSKU++)
{
InstalledInstance& sku = *itSKU;
if(sku.m_inst.m_ths == ths)
{
ProcessedPackageIter itProcessedPackage;
if(fAlsoDatabase) sku.m_fInvalidated = true;
for(itProcessedPackage = sku.m_lst.begin(); itProcessedPackage != sku.m_lst.end(); itProcessedPackage++)
{
itProcessedPackage->m_fProcessed = false;
}
}
}
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT Taxonomy::InstalledInstanceStore::State_InvalidatePackage( /*[in]*/ long lSequence )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::State_InvalidatePackage" );
HRESULT hr;
InstalledInstanceIter itSKU;
for(itSKU = m_lstSKUs.begin(); itSKU != m_lstSKUs.end(); itSKU++)
{
InstalledInstance& sku = *itSKU;
ProcessedPackageIter itProcessedPackage;
for(itProcessedPackage = sku.m_lst.begin(); itProcessedPackage != sku.m_lst.end(); itProcessedPackage++)
{
if(itProcessedPackage->m_lSequence == lSequence) break;
}
if(itProcessedPackage != sku.m_lst.end())
{
sku.m_lst.erase( itProcessedPackage );
sku.m_fInvalidated = true;
for(itProcessedPackage = sku.m_lst.begin(); itProcessedPackage != sku.m_lst.end(); itProcessedPackage++)
{
itProcessedPackage->m_fProcessed = false;
}
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT Taxonomy::InstalledInstanceStore::MakeReady( /*[in]*/ InstallationEngine& engine, /*[in]*/ bool fNoOp, /*[in]*/ bool& fWorkToProcess )
{
__HCP_FUNC_ENTRY( "Taxonomy::InstalledInstanceStore::MakeReady" );
HRESULT hr;
int iRepeat = 0;
bool fRepeat = true;
bool fRecurse = false;
//
// Already processing the list of packages.
//
if(m_dwRecurse)
{
__MPC_SET_ERROR_AND_EXIT(hr, S_FALSE);
}
fRecurse = true;
m_dwRecurse++;
__MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
fWorkToProcess = false;
while(fRepeat && IsShutdown() == false)
{
InstalledInstanceIter itSKU;
// If we are rebuilding too many times, abort the process, to protect against endless looping.
if(iRepeat++ >= 5) break;
fRepeat = false;
for(itSKU = m_lstSKUs.begin(); itSKU != m_lstSKUs.end() && IsShutdown() == false; itSKU++)
{
InstalledInstance& sku = *itSKU;
bool fProcessedSomething = false;
engine.ResetModificationFlags();
if(sku.m_fInvalidated)
{
if(fNoOp)
{
fWorkToProcess = true;
}
else
{
if(m_log)
{
m_log->WriteLog( -1, L"\nRestoring original database for %s (Language: %d)\n\n", sku.m_inst.m_ths.GetSKU(), sku.m_inst.m_ths.GetLanguage() );
}
__MPC_EXIT_IF_METHOD_FAILS(hr, sku.UninstallFiles( /*fAlsoHelpFiles*/false ));
__MPC_EXIT_IF_METHOD_FAILS(hr, sku.InstallFiles ( /*fAlsoHelpFiles*/false, NULL ));
sku.m_fInvalidated = false;
sku.m_fRecreateCache = true;
sku.m_fCreateIndex = true;
sku.m_fCreateIndexForce = true;
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
fRepeat = true;
}
}
else
{
PackageIter itPackage;
for(itPackage = m_lstPackages.begin(); itPackage != m_lstPackages.end(); itPackage++)
{
Package& pkg = *itPackage;
if(sku.m_inst.Match( pkg ))
{
ProcessedPackageIter itProcessedPackage;
for(itProcessedPackage = sku.m_lst.begin(); itProcessedPackage != sku.m_lst.end(); itProcessedPackage++)
{
if(itProcessedPackage->m_lSequence == pkg.m_lSequence) break;
}
if(itProcessedPackage == sku.m_lst.end())
{
itProcessedPackage = sku.m_lst.insert( sku.m_lst.end() );
itProcessedPackage->m_lSequence = pkg.m_lSequence;
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
{
ProcessedPackage& ppkg = *itProcessedPackage;
if(ppkg.m_fDisabled ) continue;
if(ppkg.m_fProcessed) continue;
if(fNoOp)
{
fWorkToProcess = true;
}
else
{
hr = engine.ProcessPackage( sku, pkg );
if(FAILED(hr))
{
if(IsShutdown())
{
State_InvalidateSKU( sku.m_inst.m_ths, /*fAlsoDatabase*/true );
__MPC_SET_ERROR_AND_EXIT(hr, S_OK);
}
if(sku.m_fInvalidated)
{
; // Already invalidated.
}
else
{
ppkg.m_fDisabled = true;
sku.m_fInvalidated = true;
iRepeat = 0; // Reset repeat counter on a bad package.
for(itProcessedPackage = sku.m_lst.begin(); itProcessedPackage != sku.m_lst.end(); itProcessedPackage++)
{
itProcessedPackage->m_fProcessed = false;
}
}
fRepeat = true;
}
else
{
if(engine.m_fTaxonomyModified)
{
//
// Update the timestamp.
//
sku.m_inst.SetTimeStamp();
}
ppkg.m_fProcessed = true;
fProcessedSomething = true;
}
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
}
}
if(fRepeat) break;
}
}
if(!sku.m_fInvalidated)
{
if(engine.m_fTaxonomyModified)
{
sku.m_fRecreateCache = true;
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
if(fProcessedSomething)
{
sku.m_fCreateIndex = true;
sku.m_fCreateIndexForce = engine.m_fRecreateIndex;
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
}
if(fRepeat) break;
////////////////////
if(sku.m_fCreateIndex)
{
if(FAILED(hr = engine.RecreateIndex( sku, sku.m_fCreateIndexForce )))
{
;
}
sku.m_fCreateIndex = false;
sku.m_fCreateIndexForce = false;
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
if(sku.m_fRecreateCache)
{
if(SUCCEEDED(Taxonomy::Cache::s_GLOBAL->Erase ( sku.m_inst.m_ths )) &&
SUCCEEDED(Taxonomy::Cache::s_GLOBAL->PrePopulate( sku.m_inst.m_ths )) )
{
;
}
//
// Propagate settings to the offline cache.
//
if(SUCCEEDED(OfflineCache::Root::s_GLOBAL->SetReady( true )))
{
(void)OfflineCache::Root::s_GLOBAL->Flush();
}
sku.m_fRecreateCache = false;
m_fDirty = true; __MPC_EXIT_IF_METHOD_FAILS(hr, EnsureInSync());
}
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(fRecurse) m_dwRecurse--;
__HCP_FUNC_EXIT(hr);
}