|
|
/********************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name: pkgdesc.cpp
Abstract: Functions related to package description file processing
Revision History:
Ghim-Sim Chua (gschua) 07/07/99 - created
********************************************************************/
#include "stdafx.h"
#include <strsafe.h>
////////////////////////////////////////////////////////////////////////////////
const LPCWSTR HCUpdate::Engine::s_ActionText[] = { L"ADD", L"DELETE" };
////////////////////////////////////////////////////////////////////////////////
long HCUpdate::Engine::CountNodes( /*[in]*/ IXMLDOMNodeList* poNodeList ) { long lCount = 0;
if(poNodeList) { (void)poNodeList->get_length( &lCount ); }
return lCount; }
////////////////////////////////////////////////////////////////////////////////
void HCUpdate::Engine::DeleteTempFile( /*[in/out]*/ MPC::wstring& szFile ) { if(FAILED(MPC::RemoveTemporaryFile( szFile ))) { WriteLog( HRESULT_FROM_WIN32(ERROR_CAN_NOT_COMPLETE), L"Error cannot delete temporary file" ); } }
HRESULT HCUpdate::Engine::PrepareTempFile( /*[in/out]*/ MPC::wstring& szFile ) { DeleteTempFile( szFile );
return MPC::GetTemporaryFileName( szFile ); }
HRESULT HCUpdate::Engine::LookupAction( /*[in] */ LPCWSTR szAction , /*[out]*/ Action& id ) { if(szAction) { if(_wcsicmp( szAction, L"ADD" ) == 0) { id = ACTION_ADD; return S_OK; }
if(_wcsicmp( szAction, L"DEL" ) == 0) { id = ACTION_DELETE; return S_OK; } }
return WriteLog( HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION), L"Error Unknown action used to install trusted content" ); }
HRESULT HCUpdate::Engine::LookupBoolean( /*[in] */ LPCWSTR szString , /*[out]*/ bool& fVal , /*[in] */ bool fDefault ) { if(szString[0] == 0) { fVal = fDefault; return S_OK; }
if(_wcsicmp( szString, L"TRUE" ) == 0 || _wcsicmp( szString, L"1" ) == 0 || _wcsicmp( szString, L"ON" ) == 0 ) { fVal = true; return S_OK; }
if(_wcsicmp( szString, L"FALSE" ) == 0 || _wcsicmp( szString, L"0" ) == 0 || _wcsicmp( szString, L"OFF" ) == 0 ) { fVal = false; return S_OK; }
fVal = false; return S_OK; }
HRESULT HCUpdate::Engine::LookupNavModel( /*[in] */ LPCWSTR szString , /*[out]*/ long& lVal , /*[in] */ long lDefault ) { if(_wcsicmp( szString, L"DEFAULT" ) == 0) { lVal = QR_DEFAULT; return S_OK; } if(_wcsicmp( szString, L"DESKTOP" ) == 0) { lVal = QR_DESKTOP; return S_OK; } if(_wcsicmp( szString, L"SERVER" ) == 0) { lVal = QR_SERVER ; return S_OK; }
lVal = lDefault; return S_OK; }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************
* * FUNCTION : AppendVendorDir * * DESCRIPTION : Checks to see if it is a URL, if not, appends the correct path in front * * INPUTS : * * RETURNS : * * COMMENTS : Rules : * 1. Apply environment variable (%env%) changes to URI string * 2. Check if it has a '://' substring, if so it is a URL, do nothing and return
* 3. Check if there is a ':\' or ':/' substring, if so it has a fixed path, do nothing and return * 4. Assume it is a relative path, prefix with vendor directory and return * *****************************************************************************/ HRESULT HCUpdate::Engine::AppendVendorDir( /*[in] */ LPCWSTR szURL , /*[in] */ LPCWSTR szOwnerID , /*[in] */ LPCWSTR szWinDir , /*[out]*/ LPWSTR szDest , /*[in] */ int iMaxLen ) { __HCP_FUNC_ENTRY( "HCUpdate::Engine::AppendVendorDir" );
HRESULT hr; LPWSTR rgTemp = NULL; LPWSTR rgTemp2 = NULL;
__MPC_EXIT_IF_ALLOC_FAILS(hr, rgTemp, new WCHAR[iMaxLen]); StringCchCopyW( rgTemp, iMaxLen, szURL );
//
// Check for :/ or :\ substring. If so, ignore.
//
if(_wcsnicmp( rgTemp, L"app:", 4 ) == 0 || wcsstr ( rgTemp, L":/" ) || wcsstr ( rgTemp, L":\\" ) ) { StringCchCopyW( szDest, iMaxLen, rgTemp ); // Just copy straight since it is either a URL or fixed path.
} else // Assume relative path.
{ int i = 0;
//
// Skip the initial slashes.
//
while(rgTemp[i] == '\\' || rgTemp[i] == '/' ) { i++; }
//
// If 'szWinDir' is not null, then a straight file path is required, otherwise a URL is required.
//
if(szWinDir) { MPC::wstring strRoot;
__MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.BaseDir( strRoot )); strRoot.append( HC_HELPSET_SUB_VENDORS );
StringCchPrintfW( szDest, iMaxLen-1, L"%s\\%s\\%s", strRoot.c_str(), szOwnerID, &rgTemp[i] ); szDest[iMaxLen-1] = 0;
//
// Replace all / with \ character.
//
while(szDest[0]) { if(szDest[0] == '/') { szDest[0] = '\\'; } szDest++; } } else { const int iSizeMax = INTERNET_MAX_PATH_LENGTH; DWORD dwSize = iMaxLen-1;
__MPC_EXIT_IF_ALLOC_FAILS(hr, rgTemp2, new WCHAR[iSizeMax]);
StringCchPrintfW( rgTemp2, iSizeMax-1, PCH_STR_VENDOR_URL, szOwnerID, &rgTemp[i] ); rgTemp2[iSizeMax-1] = 0;
::InternetCanonicalizeUrlW( rgTemp2, szDest, &dwSize, ICU_ENCODE_SPACES_ONLY );
//
// Replace all \ with / character.
//
while(szDest[0]) { if(szDest[0] == _T('\\')) { szDest[0] = _T('/'); } szDest++; } } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
delete [] rgTemp; delete [] rgTemp2;
__HCP_FUNC_EXIT(hr); }
/*****************************************************************************
* * FUNCTION : RegisterContentIsValidProtocol * * DESCRIPTION : Check if the registered trusted content is a * valid protocol (hcp:, ms-its:, http:, https:, file:) * *****************************************************************************/ static HRESULT RegisterContentIsValidProtocol( /*[in]*/ LPCWSTR szURL ) { __HCP_FUNC_ENTRY( "RegisterContentIsValidProtocol" );
HRESULT hr = E_FAIL;
// Allow hcp: and ms-its:
if (!_wcsnicmp(szURL, L"hcp:", 4) || !_wcsnicmp(szURL, L"ms-its:", 7)) { hr = S_OK; } else { // Check URL scheme
MPC::URL url; INTERNET_SCHEME scheme;
if(SUCCEEDED(url.put_URL ( szURL )) && SUCCEEDED(url.get_Scheme( scheme )) ) { // Allow http:, https: and file:
switch(scheme) { case INTERNET_SCHEME_HTTP : case INTERNET_SCHEME_HTTPS : case INTERNET_SCHEME_FILE : hr = S_OK; } } }
__HCP_FUNC_EXIT(hr); }
/*****************************************************************************
* * FUNCTION : ProcessRegisterContent * * DESCRIPTION : Registers trusted content with the content store * * INPUTS : * * RETURNS : * * COMMENTS : * *****************************************************************************/ HRESULT HCUpdate::Engine::ProcessRegisterContent( /*[in]*/ Action idAction , /*[in]*/ LPCWSTR szURI ) { __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessRegisterContent" );
HRESULT hr; HRESULT hr2; WCHAR rgDestPath[MAX_PATH]; bool fCSLocked = false;
PCH_MACRO_CHECK_STRINGW(hr, szURI, L"Error missing URI attribute");
//
// Get the complete URL for the link.
//
AppendVendorDir( szURI, m_pkg->m_strVendorID.c_str(), NULL, rgDestPath, MAXSTRLEN(rgDestPath) );
WriteLog( S_OK, L"Registering trusted content : %s", s_ActionText[idAction] );
//
// Initialize the content store for processing.
//
if(FAILED(hr = CPCHContentStore::s_GLOBAL->Acquire())) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error initializing the content store" )); } fCSLocked = true;
if(idAction == ACTION_ADD) { //
// Check if URL is an allowed protocol
//
if(FAILED(hr = RegisterContentIsValidProtocol(rgDestPath))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Trusted content is not an allowed protocol" )); } if(FAILED(hr = CPCHContentStore::s_GLOBAL->Add( rgDestPath, m_pkg->m_strVendorID.c_str(), m_pkg->m_strVendorName.c_str() ))) { if(hr == E_PCH_URI_EXISTS) { PCH_MACRO_DEBUG( L"Trusted content already registered" ); } else { PCH_MACRO_DEBUG( L"Error Register trusted content failed" ); } } else { PCH_MACRO_DEBUG( L"Trusted content registered" ); } } else if(idAction == ACTION_DELETE) { if(FAILED(hr = CPCHContentStore::s_GLOBAL->Remove( rgDestPath, m_pkg->m_strVendorID.c_str(), m_pkg->m_strVendorName.c_str() ))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error Remove trusted content failed" )); }
PCH_MACRO_DEBUG( L"Trusted content removed" ); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(fCSLocked) { if(FAILED(hr2 = CPCHContentStore::s_GLOBAL->Release( true ))) { WriteLog( hr2, L"Error committing into Content Store" ); } }
if(FAILED(hr)) { WriteLog( hr, L"Error processing registered content" ); }
__HCP_FUNC_EXIT(hr); }
/*****************************************************************************
* * FUNCTION : ProcessInstallFile * * DESCRIPTION : Extracts files to be installed and moves them to the vendor's * private directory * * INPUTS : * * RETURNS : * * COMMENTS : * *****************************************************************************/ HRESULT HCUpdate::Engine::ProcessInstallFile( /*[in]*/ Action idAction , /*[in]*/ LPCWSTR szSource , /*[in]*/ LPCWSTR szDestination , /*[in]*/ bool fSys , /*[in]*/ bool fSysHelp ) { __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessInstallFile" );
HRESULT hr; WCHAR rgDestPath[MAX_PATH]; MPC::wstring strRoot; MPC::wstring strDestination;
if(m_updater.IsOEM() != true) { if(fSys == true || fSysHelp == true ) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( S_OK, L"Ignoring install file : %s because certificate does not have enough priviliges to install into Sys or SysHelp locations.", szDestination )); } }
WriteLog( S_OK, L"Installing file : %s : %s", s_ActionText[idAction], szDestination );
PCH_MACRO_CHECK_STRINGW(hr, szDestination, L"Error missing URI attribute");
//
// Canonicalize szDestination.
//
if(FAILED(hr = MPC::GetCanonialPathName(strDestination, szDestination))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), L"Error install file has a destination that is not allowed." )); }
// Check if system file modification.
if(fSys || fSysHelp) { if(fSys) { //
// Only Microsoft can actually write to the SYSTEM directory, OEMs write to the SYSTEM_OEM one.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, m_ts.BaseDir( strRoot )); strRoot.append( IsMicrosoft() ? HC_HELPSET_SUB_SYSTEM : HC_HELPSET_SUB_SYSTEM_OEM ); }
if(fSysHelp) { if(FAILED(hr = AcquireDatabase())) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error finding database to update" )); }
strRoot = m_updater.GetHelpLocation();
ReleaseDatabase(); } }
if(fSys || fSysHelp) { MPC::SubstituteEnvVariables( strRoot );
//
// If system folder.
//
StringCchPrintfW( rgDestPath, MAXSTRLEN(rgDestPath), L"%s\\%s", strRoot.c_str(), strDestination.c_str() ); rgDestPath[MAXSTRLEN(rgDestPath)] = 0; } else { //
// If regular vendor folder.
//
AppendVendorDir( strDestination.c_str(), m_pkg->m_strVendorID.c_str(), m_strWinDir.c_str(), rgDestPath, MAXSTRLEN(rgDestPath) ); }
// Change the mode to read/write so that file can be replaced.
(void)::SetFileAttributesW( rgDestPath, FILE_ATTRIBUTE_NORMAL );
if(idAction == ACTION_ADD) { // Source must not be empty.
if(!STRINGISPRESENT( szSource )) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), L"Error - missing SOURCE attribute" )); }
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FailOnLowDiskSpace( HC_ROOT, PCH_SAFETYMARGIN ));
// Create the directory if it hasn't been created already
if(FAILED(hr = MPC::MakeDir( rgDestPath ))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error creating directory for %s", rgDestPath )); }
// Extract the file and store it in the vendor's private storage area
__MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractFile( m_log, rgDestPath, szSource )); } else { MPC::FileSystemObject fso( rgDestPath );
if(fso.IsDirectory()) { if(fSys || fSysHelp) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( S_OK, L"Ignoring directory delete command on '%s', it only works for Vendor's directories.", rgDestPath )); } }
if(FAILED(fso.Delete( /*fForce*/true, /*fComplain*/true ))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( -2, L"Error deleting installation file: %s", rgDestPath )); } }
PCH_MACRO_DEBUG( L"Installed file" );
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(FAILED(hr)) { WriteLog( hr, L"Error processing installation file" ); }
__HCP_FUNC_EXIT(hr); }
/*****************************************************************************
* * FUNCTION : ProcessSAFFile * * DESCRIPTION : Hand the SAF file over to the SAF lib for registration or removal * * INPUTS : * * RETURNS : * * COMMENTS : * *****************************************************************************/ HRESULT HCUpdate::Engine::ProcessSAFFile( /*[in]*/ Action idAction , /*[in]*/ LPCWSTR szSAFName , /*[in]*/ MPC::XmlUtil& oXMLUtil ) { __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessSAFFile" );
HRESULT hr; CSAFChannelRecord cr;
WriteLog( S_OK, L"Processing SAF file : %s : %s. OwnerName : %s, Owner ID : %s", s_ActionText[idAction], szSAFName, m_pkg->m_strVendorName.c_str(), m_pkg->m_strVendorID.c_str() );
cr.m_ths = m_ts; cr.m_bstrVendorID = m_pkg->m_strVendorID .c_str(); cr.m_bstrVendorName = m_pkg->m_strVendorName.c_str();
if(idAction == ACTION_ADD) { if(FAILED(hr = CSAFReg::s_GLOBAL->RegisterSupportChannel( cr, oXMLUtil ))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error RegisterSupportChannel on SAF file failed" )); }
WriteLog( S_OK, L"SAF file registered" ); } else if(idAction == ACTION_DELETE) { if(FAILED(hr = CSAFReg::s_GLOBAL->RemoveSupportChannel( cr, oXMLUtil ))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error RemoveSupportChannel on SAF file failed" )); }
WriteLog( S_OK, L"SAF file removed" ); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(FAILED(hr)) { WriteLog( hr, L"Error processing SAF file" ); }
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/*****************************************************************************
* * FUNCTION : ProcessPackage * * DESCRIPTION : Reads the help_description package and processes the various sections * * INPUTS : * * RETURNS : * * COMMENTS : * *****************************************************************************/ HRESULT HCUpdate::Engine::ProcessPackage( /*[in]*/ Taxonomy::InstalledInstance& sku , /*[in]*/ Taxonomy::Package& pkg ) { __HCP_FUNC_ENTRY( "HCUpdate::Engine::ProcessPackage" );
HRESULT hr; MPC::XmlUtil oXMLUtil; bool fIsMachineHelp = (sku.m_inst.m_fSystem || sku.m_inst.m_fMUI); bool fDB = false; bool fFound;
////////////////////////////////////////////////////////////////////////////////
//
// Now let's validate that we have enough disk space on the drive
//
{ ULARGE_INTEGER liFree; ULARGE_INTEGER liTotal; bool fEnoughSpace = false;
if(SUCCEEDED(MPC::GetDiskSpace( m_strWinDir, liFree, liTotal ))) { fEnoughSpace = (liFree.QuadPart > (ULONGLONG)10e6); }
if(fEnoughSpace == false) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( STG_E_MEDIUMFULL, L"Error insufficient disk space for update operation." )); } }
//
// We cannot process a generic package if a database is already in use!!
//
if(m_sess || m_db) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( E_FAIL, L"Recursive invocation of HCUpdate!" )); }
m_ts = sku.m_inst.m_ths; m_sku = &sku; m_pkg = &pkg;
WriteLog( -1, L"\nProcessing package %s [%s] (Vendor: %s) from package store, %s/%d\n\n", pkg.m_strProductID.c_str() , pkg.m_strVersion .c_str() , pkg.m_strVendorID .c_str() , m_ts.GetSKU() , m_ts.GetLanguage() );
////////////////////////////////////////////////////////////////////////////////
//
// Check if it is OEM owner
//
{ __MPC_EXIT_IF_METHOD_FAILS(hr, AcquireDatabase()); fDB = true;
__MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.LocateOwner( m_pkg->m_strVendorID.c_str() ));
if(m_updater.GetOwner() == -1) { long idOwner;
// Create the owner without OEM privs
__MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.CreateOwner( idOwner, m_pkg->m_strVendorID.c_str(), /*fIsOEM*/false )); __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.LocateOwner( m_pkg->m_strVendorID.c_str() )); } }
if(m_updater.IsOEM()) { WriteLog( S_OK, L"Update package has OEM credentials of %s", m_pkg->m_strVendorID.c_str() ); }
__MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractPkgDesc( m_log, oXMLUtil ));
////////////////////////////////////////////////////////////////////////////////
//
// Insert OEMs
//
if(m_updater.IsOEM()) { CComPtr<IXMLDOMNodeList> poNodeList;
if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_OEM, &poNodeList ))) { PCH_MACRO_DEBUG( L"Error processing package_description xml" ); } else if(CountNodes(poNodeList) > 0) { JetBlue::TransactionHandle transaction; CComPtr<IXMLDOMNode> poNode; MPC::wstring strDN; long ID_owner;
//
// Process all the nodes.
//
HCUPDATE_BEGIN_TRANSACTION(hr,transaction); for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release()) { HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_OEM_DN, strDN, fFound, poNode );
PCH_MACRO_CHECK_ABORT(hr);
if(strDN.size() > 0) { WriteLog( S_OK, L"Registering '%s' as OEM", strDN.c_str() );
// insert it into the content owner's table, making it an OEM.
__MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.CreateOwner( ID_owner, strDN.c_str(), true )); } } HCUPDATE_COMMIT_TRANSACTION(hr,transaction); } }
////////////////////////////////////////////////////////////////////////////////
//
// Insert Search Engines
//
if(fIsMachineHelp && m_updater.IsOEM()) { CComPtr<IXMLDOMNodeList> poNodeList;
if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_SE, &poNodeList ))) { PCH_MACRO_DEBUG( L"Error processing package_description xml" ); } else if(CountNodes(poNodeList) > 0) { CComPtr<IXMLDOMNode> poNode; CComPtr<IXMLDOMNode> poDataNode; Action idAction; MPC::wstring strAction; MPC::wstring strCLSID; MPC::wstring strID; CComBSTR bstrData; SearchEngine::Config cfg;
//
// Process all the nodes.
//
for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release()) { PCH_MACRO_CHECK_ABORT(hr);
HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_ACTION , strAction, fFound, poNode ); HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_SE_ID , strID , fFound, poNode ); HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_SE_CLSID, strCLSID , fFound, poNode );
//
// Get the data element
//
if(FAILED(poNode->selectSingleNode( PCH_TAG_SE_DATA, &poDataNode ))) { PCH_MACRO_DEBUG2( L"Error getting data for search engine %s", strID.c_str()); } if(FAILED(poDataNode->get_xml(&bstrData))) { PCH_MACRO_DEBUG2( L"Error extracting xml data for search engine %s", strID.c_str()); }
__MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction( strAction.c_str(), idAction ));
//
// Check if it is adding search engines
//
if(idAction == ACTION_ADD) { WriteLog( S_OK, L"Adding Search Engine : Name : %s, CLSID : %s", strID.c_str(), strCLSID.c_str() );
// register the search engine
__MPC_EXIT_IF_METHOD_FAILS(hr, cfg.RegisterWrapper( m_ts, strID.c_str(), m_pkg->m_strVendorID.c_str(), strCLSID.c_str(), bstrData )); } else if(idAction == ACTION_DELETE) { WriteLog( S_OK, L"Deleting Search Engine : Name : %s, CLSID : %s", strID.c_str(), strCLSID.c_str() );
// unregister the search engine
__MPC_EXIT_IF_METHOD_FAILS(hr, cfg.UnRegisterWrapper( m_ts, strID.c_str(), m_pkg->m_strVendorID.c_str() )); } } } }
////////////////////////////////////////////////////////////////////////////////
//
// Search & process saf config files
//
if(fIsMachineHelp && m_updater.IsOEM()) { CComPtr<IXMLDOMNodeList> poNodeList;
if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_SAF, &poNodeList ))) { PCH_MACRO_DEBUG( L"Error processing package_description xml" ); } else if(CountNodes(poNodeList) > 0) { CComPtr<IXMLDOMNode> poNode; Action idAction; MPC::wstring strAction; MPC::wstring strFilename;
//
// Process all the nodes.
//
for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release()) { MPC::XmlUtil xmlSAF;
PCH_MACRO_CHECK_ABORT(hr);
HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_ACTION, strAction , fFound, poNode); HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_FILE , strFilename, fFound, poNode);
__MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction( strAction.c_str(), idAction ));
// Extract the SAF file into the temp directory
__MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractXMLFile( m_log, xmlSAF, Taxonomy::Strings::s_tag_root_SAF, strFilename.c_str() ));
// process the SAF file
__MPC_EXIT_IF_METHOD_FAILS(hr, ProcessSAFFile( idAction, strFilename.c_str(), xmlSAF )); } } }
////////////////////////////////////////////////////////////////////////////////
//
// Search & install help content
//
{ CComPtr<IXMLDOMNodeList> poNodeList;
if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_INSTALLFILE, &poNodeList ))) { PCH_MACRO_DEBUG( L"Error processing package_description xml" ); } else if(CountNodes(poNodeList) > 0) { CComPtr<IXMLDOMNode> poNode; Action idAction; MPC::wstring strAction; MPC::wstring strSource; MPC::wstring strDest; MPC::wstring strSys; MPC::wstring strSysHelp; bool fSys; bool fSysHelp;
//
// Process all the nodes.
//
for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release()) { PCH_MACRO_CHECK_ABORT(hr);
HCUPDATE_GETATTRIBUTE (hr, oXMLUtil, PCH_TAG_ACTION , strAction , fFound, poNode); HCUPDATE_GETATTRIBUTE_OPT(hr, oXMLUtil, PCH_TAG_SOURCE , strSource , fFound, poNode); HCUPDATE_GETATTRIBUTE (hr, oXMLUtil, PCH_TAG_URI , strDest , fFound, poNode); HCUPDATE_GETATTRIBUTE_OPT(hr, oXMLUtil, PCH_TAG_SYS , strSys , fFound, poNode); HCUPDATE_GETATTRIBUTE_OPT(hr, oXMLUtil, PCH_TAG_SYSHELP, strSysHelp, fFound, poNode);
__MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction ( strAction .c_str(), idAction )); __MPC_EXIT_IF_METHOD_FAILS(hr, LookupBoolean( strSys .c_str(), fSys , false )); __MPC_EXIT_IF_METHOD_FAILS(hr, LookupBoolean( strSysHelp.c_str(), fSysHelp, false ));
//
// If the package is not the machine SKU, you don't want to install contents other than System Help Files.
//
if(fIsMachineHelp == false) { if(fSys == true ) continue; if(fSysHelp == false) continue; }
// install the file
__MPC_EXIT_IF_METHOD_FAILS(hr, ProcessInstallFile( idAction, strSource.c_str(), strDest.c_str(), fSys, fSysHelp )); } } }
////////////////////////////////////////////////////////////////////////////////
//
// Search & register trusted content
//
if(fIsMachineHelp && m_updater.IsOEM()) { CComPtr<IXMLDOMNodeList> poNodeList;
if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_TRUSTED, &poNodeList ))) { PCH_MACRO_DEBUG( L"Error processing package_description xml" ); } else if(CountNodes(poNodeList) > 0) { CComPtr<IXMLDOMNode> poNode; Action idAction; MPC::wstring strAction; MPC::wstring strURI;
//
// Process all the nodes.
//
for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release()) { PCH_MACRO_CHECK_ABORT(hr);
HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_ACTION, strAction, fFound, poNode); HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_URI , strURI , fFound, poNode);
__MPC_EXIT_IF_METHOD_FAILS(hr, LookupAction( strAction.c_str(), idAction ));
// register the content
__MPC_EXIT_IF_METHOD_FAILS(hr, ProcessRegisterContent( idAction, strURI.c_str() )); } } }
////////////////////////////////////////////////////////////////////////////////
//
// Search & process hht files
//
{ CComPtr<IXMLDOMNodeList> poNodeList;
if(FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_HHT, &poNodeList))) { PCH_MACRO_DEBUG( L"Error processing package_description xml" ); } else if(CountNodes(poNodeList) > 0) { CComPtr<IXMLDOMNode> poNode; MPC::wstring strFilename;
//
// Process all the nodes.
//
for(;SUCCEEDED(hr = poNodeList->nextNode( &poNode )) && poNode != NULL; poNode.Release()) { MPC::XmlUtil xmlHHT;
PCH_MACRO_CHECK_ABORT(hr);
// get the filename
HCUPDATE_GETATTRIBUTE(hr, oXMLUtil, PCH_TAG_FILE, strFilename, fFound, poNode);
// Extract the HHT file into the temp directory
__MPC_EXIT_IF_METHOD_FAILS(hr, m_pkg->ExtractXMLFile( m_log, xmlHHT, Taxonomy::Strings::s_tag_root_HHT, strFilename.c_str() ));
// process the HHT file
__MPC_EXIT_IF_METHOD_FAILS(hr, ProcessHHTFile( strFilename.c_str(), xmlHHT )); } } }
////////////////////////////////////////////////////////////////////////////////
//
// Search and add News content
//
if(m_updater.IsOEM()) { CComPtr<IXMLDOMNodeList> poNodeList;
if (FAILED(hr = oXMLUtil.GetNodes( PCH_XQL_NEWSROOT, &poNodeList))) { PCH_MACRO_DEBUG( L"Error processing package_description.xml" ); } else { if(CountNodes(poNodeList) > 0) { CComPtr<IXMLDOMNode> poNodeHeadline; MPC::wstring strCurrentSKU; LPCWSTR szCurrentSKU = m_ts.GetSKU (); long lCurrentLCID = m_ts.GetLanguage(); News::UpdateHeadlines uhUpdate; MPC::wstring strIcon; MPC::wstring strTitle; MPC::wstring strLink; MPC::wstring strDescription; MPC::wstring strExpiryDate; CComBSTR strTimeOutDays; int nTimeOutDays; DATE dExpiryDate; long lIndex;
// Strip off the number from the SKU
{ LPCWSTR szEnd = wcschr( szCurrentSKU, '_' ); size_t len = szEnd ? szEnd - szCurrentSKU : wcslen( szCurrentSKU );
strCurrentSKU.assign( szCurrentSKU, len ); }
// Get all the news items and return them in the reverse order
__MPC_EXIT_IF_METHOD_FAILS(hr, poNodeList->get_length( &lIndex )); for(--lIndex; lIndex >= 0; --lIndex) { if(SUCCEEDED(hr = poNodeList->get_item( lIndex, &poNodeHeadline )) && poNodeHeadline != NULL) { PCH_MACRO_CHECK_ABORT(hr);
//// Quick fix for 357806 - ignore the ICON attribute
////__MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_ICON , strIcon , fFound, poNodeHeadline));
__MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_TITLE , strTitle , fFound, poNodeHeadline)); __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_LINK , strLink , fFound, poNodeHeadline)); __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_DESCRIPTION, strDescription, fFound, poNodeHeadline)); __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_TIMEOUT , strTimeOutDays, fFound, poNodeHeadline)); __MPC_EXIT_IF_METHOD_FAILS(hr, oXMLUtil.GetAttribute(NULL, PCH_TAG_NEWS_EXPIRYDATE , strExpiryDate , fFound, poNodeHeadline));
// Make the necessary conversions
if(FAILED(hr = MPC::ConvertStringToDate( strExpiryDate, dExpiryDate, /*fGMT*/false, /*fCIM*/false, -1 ))) { dExpiryDate = 0; }
if(strTimeOutDays.Length() > 0) { nTimeOutDays = _wtoi(strTimeOutDays); } else { nTimeOutDays = 0; }
// Finally add the headlines - make sure that the title and link are not empty strings
if(strTitle.length() > 0 && strLink.length() > 0) { __MPC_EXIT_IF_METHOD_FAILS(hr, uhUpdate.Add( lCurrentLCID, strCurrentSKU, strIcon, strTitle, strLink, strDescription, nTimeOutDays, dExpiryDate )); } else { WriteLog(S_OK, L"Skipping headlines no. %d because attribute TITLE or attribute LINK was not found", lIndex + 1); }
poNodeHeadline.Release(); } } WriteLog(S_OK, L"Headlines were successfully processed"); } else { WriteLog(S_OK, L"No headlines items found"); } } }
hr = S_OK;
////////////////////////////////////////////////////////////////////////////////
__HCP_FUNC_CLEANUP;
if(fDB) { ReleaseDatabase(); }
////////////////////
__HCP_FUNC_EXIT(hr); }
HRESULT HCUpdate::Engine::RecreateIndex( /*[in]*/ Taxonomy::InstalledInstance& sku, /*[in]*/ bool fForce ) { __HCP_FUNC_ENTRY( "HCUpdate::Engine::RecreateIndex" );
HRESULT hr;
m_ts = sku.m_inst.m_ths; m_sku = &sku; m_pkg = NULL;
if(FAILED(hr = InternalCreateIndex( fForce ? VARIANT_TRUE : VARIANT_FALSE ))) { __MPC_SET_ERROR_AND_EXIT(hr, WriteLog( hr, L"Error merging index" )); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
|