|
|
/******************************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name: main.cpp
Abstract: This file contains the Unit Test for Cabinet functions.
Revision History: Davide Massarenti (Dmassare) 09/03/99 created
******************************************************************************/
#include "stdafx.h"
#include <initguid.h>
#include "msscript.h"
#include "HelpServiceTypeLib.h"
#include "HelpServiceTypeLib_i.c"
#include "HelpCenterTypeLib.h"
#include "HelpCenterTypeLib_i.c"
////////////////////////////////////////////////////////////////////////////////
#define LOG__MPC_EXIT_IF_METHOD_FAILS(hr, cmd) \
{ \ if(FAILED(hr=cmd)) \ { \ l_FileLog.LogRecord( "!!ERROR: %08x %s %d\n", hr, #cmd, __LINE__ ); \ __MPC_TRACE_HRESULT(hr); __MPC_FUNC_LEAVE; \ } \ }
////////////////////////////////////////////////////////////////////////////////
static const DWORD c_dwVersion = 0x07494250; // PBI 07
static const WCHAR c_szNTTREE_BASE [] = L"HelpAndSupportServices"; static const WCHAR c_szNTTREE_INDEX [] = L"index.dat"; static const WCHAR c_szNTTREE_TMP [] = L"%TEMP%";
static const WCHAR c_szPackageDescription [] = L"package_description.xml";
static const WCHAR c_szHHT_rootTag [] = L"METADATA";
static const WCHAR c_szHHT_manual_STOPSIGN [] = L"STOPSIGN_ENTRIES"; static const WCHAR c_szHHT_manual_STOPWORD [] = L"STOPWORD_ENTRIES"; static const WCHAR c_szHHT_manual_OPERATOR [] = L"OPERATOR_ENTRIES";
static const WCHAR c_szHHT_synset_SYNTABLE [] = L"SYNTABLE";
static const WCHAR c_szHHT_loc_SCOPE [] = L"SCOPE_DEFINITION"; static const WCHAR c_szHHT_loc_TAXONOMY [] = L"TAXONOMY_ENTRIES";
static const WCHAR c_szHHT_noloc_FTS [] = L"FTS"; static const WCHAR c_szHHT_noloc_INDEX [] = L"INDEX"; static const WCHAR c_szHHT_noloc_HELPIMAGE [] = L"HELPIMAGE";
static const WCHAR c_szHHT_conv_SCOPE [] = L"SCOPE_DEFINITION/SCOPE"; static LPCWSTR const c_rgHHT_conv_SCOPE [] = { L"DISPLAYNAME" };
static const WCHAR c_szHHT_conv_TAXONOMY [] = L"TAXONOMY_ENTRIES/TAXONOMY_ENTRY"; static LPCWSTR const c_rgHHT_conv_TAXONOMY [] = { L"TITLE", L"DESCRIPTION" };
////////////////////////////////////////
static MPC::FileLog l_FileLog; static LPCWSTR l_szRoot = NULL; static LPCWSTR l_szLog = NULL; static LPCWSTR l_szDBLog = NULL; static int l_lMaxElements = 1000;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
struct SetupImageEntry; struct FileEntry; struct TaxonomyEntry; struct PackageEntry; struct PostBuildEntry;
////////////////////////////////////////////////////////////////////////////////
struct SetupImageEntry { MPC::wstring m_strSKU; MPC::wstring m_strLocalization; MPC::wstring m_strPurpose; MPC::wstring m_strSourceFile; MPC::wstring m_strTemporaryName; MPC::wstring m_strDestinationName; MPC::wstring m_strDestinationDir;
MPC::wstring m_strTemporaryFullPath; DATE m_lastModified; bool m_fUpdated;
SetupImageEntry() { m_lastModified = 0; m_fUpdated = false; }
friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ SetupImageEntry& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const SetupImageEntry& val );
HRESULT Import( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ); HRESULT Export( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot );
void FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ); };
////////////////////////////////////////////////////////////////////////////////
struct FileEntry { MPC::wstring m_strName; MPC::wstring m_strFullPath; DATE m_lastModified_HIGH; DATE m_lastModified_LOW; long m_lChunks; bool m_fUpdated;
FileEntry() { m_lastModified_HIGH = 0; m_lastModified_LOW = 0; m_lChunks = 0; m_fUpdated = false; }
friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ FileEntry& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const FileEntry& val );
void GenerateChunkName( /*[in]*/ long lChunk, /*[out]*/ MPC::wstring& strFile ) const;
void GetDate( /*[out]*/ DATE& date_HIGH, /*[out]*/ DATE& date_LOW ) const;
void SetDate ( /*[in]*/ bool fLookForChunks = false ); bool WasModified() const;
void FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot );
bool IsNewer( /*[in]*/ const FileEntry& fe ); bool IsNewer( /*[in]*/ DATE date ); };
typedef std::list< FileEntry > FileList; typedef FileList::iterator FileIter; typedef FileList::const_iterator FileIterConst;
////////////////////////////////////////////////////////////////////////////////
struct TaxonomyEntry { FileEntry m_fe; FileEntry m_feMANUAL; FileEntry m_feSYNSET; FileEntry m_feLOC; FileEntry m_feNOLOC; bool m_fUpdated;
FileEntry m_fe_New;
TaxonomyEntry() { m_fUpdated = false; }
friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ TaxonomyEntry& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const TaxonomyEntry& val );
HRESULT Import( /*[in]*/ PackageEntry& pe, /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ); HRESULT Export( /*[in]*/ PackageEntry& pe, /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot );
void FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ); };
typedef std::list< TaxonomyEntry > TaxonomyList; typedef TaxonomyList::iterator TaxonomyIter; typedef TaxonomyList::const_iterator TaxonomyIterConst;
////////////////////////////////////////////////////////////////////////////////
struct PackageEntry { MPC::wstring m_strDir; MPC::wstring m_strPackageDescription; FileList m_flSAF; FileList m_flINSTALL; TaxonomyList m_flHHT;
MPC::wstring m_strNew_Cabinet; MPC::wstring m_strNew_Database;
MPC::wstring m_DB_strSKU; long m_DB_lLCID; MPC::wstring m_DB_strDisplayName;
friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ PackageEntry& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const PackageEntry& val );
HRESULT OpenPackageDescription( /*[in/out]*/ MPC::XmlUtil& xml );
HRESULT Import( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ); HRESULT Export( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot );
HRESULT ProcessHHTFile( /*[in]*/ LPCWSTR szHHTFile, /*[in]*/ JetBlue::SessionHandle* handle, /*[in]*/ JetBlue::Database* db ); HRESULT CreateDatabase( /*[in]*/ const MPC::wstring& strTmp );
void FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ); };
////////////////////////////////////////////////////////////////////////////////
enum PostBuildType { POSTBUILDTYPE_NORMAL = 0, POSTBUILDTYPE_SAF , POSTBUILDTYPE_HHT , };
struct PostBuildEntry { PostBuildType m_pbt; SetupImageEntry m_entry; PackageEntry m_package;
friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ PostBuildEntry& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const PostBuildEntry& val );
void FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ); };
typedef std::list< PostBuildEntry > PostBuildList; typedef PostBuildList::iterator PostBuildIter; typedef PostBuildList::const_iterator PostBuildIterConst;
////////////////////////////////////////////////////////////////////////////////
struct SkuInformation { MPC::wstring m_strName; MPC::wstring m_strCabinet; MPC::wstring m_strProdFilt; bool m_fDesktop; bool m_fServer; bool m_fEmbedded;
SkuInformation() { m_fDesktop = false; m_fServer = false; m_fEmbedded = false; }
friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ SkuInformation& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const SkuInformation& val ); };
typedef std::list< SkuInformation > SkuInformationList; typedef SkuInformationList::iterator SkuInformationIter; typedef SkuInformationList::const_iterator SkuInformationIterConst;
////////////////////////////////////////////////////////////////////////////////
static void GetRootDirectory( /*[out]*/ MPC::wstring& strRoot ) { strRoot = l_szRoot ? l_szRoot : c_szNTTREE_TMP; MPC::SubstituteEnvVariables( strRoot ); }
static void GetLogFile( /*[out]*/ MPC::wstring& strLog ) { GetRootDirectory( strLog );
strLog += L"\\"; strLog += l_szLog ? l_szLog : L"hss.log"; }
static void GetDBLogFile( /*[out]*/ MPC::wstring& strDBLog ) { GetRootDirectory( strDBLog );
strDBLog += L"\\"; strDBLog += l_szDBLog ? l_szDBLog : L"createdb.log"; }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
static HRESULT ExtractFile( /*[in]*/ LPCWSTR szCabinet, /*[in]*/ LPCWSTR szDst, /*[in]*/ LPCWSTR szFile ) { __HCP_FUNC_ENTRY( "ExtractFile" );
HRESULT hr;
l_FileLog.LogRecord( L"Extracting '%s' from '%s'", szFile, szCabinet );
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DecompressFromCabinet( szCabinet, szDst, szFile ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static void RemoveDirectory( /*[in]*/ const MPC::wstring& strDir ) { MPC::FileSystemObject fso( strDir.c_str() );
(void)fso.DeleteChildren( true, false ); }
////////////////////
static HRESULT MoveDataIsland( /*[in ]*/ MPC::XmlUtil& xmlIN , /*[out]*/ MPC::XmlUtil& xmlOUT , /*[in ]*/ LPCWSTR szTAG ) { __HCP_FUNC_ENTRY( "MoveDataIsland" );
HRESULT hr; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn; CComPtr<IXMLDOMNode> xdnRoot;
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlOUT.GetRoot( &xdnRoot ));
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlIN.GetNodes( szTAG, &xdnl )); for(;SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { CComPtr<IXMLDOMNode> xdnReplaced;
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnRoot->appendChild( xdn, &xdnReplaced )); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT ConvertAttributesToElements( /*[in]*/ MPC::XmlUtil& xml , /*[in]*/ LPCWSTR szTAG , /*[in]*/ LPCWSTR const* rgATTRIB , /*[in]*/ int iATTRIB ) { __HCP_FUNC_ENTRY( "ConvertAttributesToElements" );
HRESULT hr; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNodes( szTAG, &xdnl )); for(;SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { for(int i=0; i<iATTRIB; i++) { LPCWSTR szATTRIB = rgATTRIB[i]; CComPtr<IXMLDOMAttribute> xdna; bool fFound;
//
// Move the value from the attribute to the element.
//
if(SUCCEEDED(xml.GetAttribute( NULL, szATTRIB, &xdna, fFound, xdn )) && xdna) { CComVariant vValue; CComPtr<IXMLDOMNode> xdnSUB;
__MPC_EXIT_IF_METHOD_FAILS(hr, xdna->get_value( &vValue ));
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( szATTRIB, &xdnSUB, xdn ));
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutValue( NULL, vValue, fFound, xdnSUB ));
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.RemoveAttribute( NULL, szATTRIB, xdn )); } } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT ConvertElementsToAttributes( /*[in]*/ MPC::XmlUtil& xml , /*[in]*/ LPCWSTR szTAG , /*[in]*/ LPCWSTR const* rgATTRIB , /*[in]*/ int iATTRIB ) { __HCP_FUNC_ENTRY( "ConvertElementsToAttributes" );
HRESULT hr; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNodes( szTAG, &xdnl )); for(;SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { for(int i=0; i<iATTRIB; i++) { LPCWSTR szATTRIB = rgATTRIB[i]; CComPtr<IXMLDOMNode> xdnSUB;
//
// Move the value from the attribute to the element.
//
if(SUCCEEDED(xdn->selectSingleNode( CComBSTR( szATTRIB ), &xdnSUB )) && xdnSUB) { CComVariant vValue; bool fFound;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, vValue, fFound, xdnSUB )); if(fFound) { CComPtr<IXMLDOMAttribute> xdna;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutAttribute( NULL, szATTRIB, &xdna, fFound, xdn )); if(xdna) { __MPC_EXIT_IF_METHOD_FAILS(hr, xdna->put_value( vValue )); } }
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.RemoveNode( NULL, xdnSUB )); } } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT SpreadToFiles( /*[in]*/ MPC::XmlUtil& xmlSrc , /*[in]*/ FileEntry& fe , /*[in]*/ long lLimit ) { __HCP_FUNC_ENTRY( "SpreadToFiles" );
HRESULT hr; MPC::XmlUtil xmlDst; MPC::wstring strFile; long lCount = 0; bool fCreate = true;
fe.m_lChunks = 0;
while(1) { CComPtr<IXMLDOMNode> xdnRootSrc; CComPtr<IXMLDOMNode> xdnRootDst; CComPtr<IXMLDOMNode> xdnSrc; CComPtr<IXMLDOMNode> xdnDst; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn; long lLength;
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlSrc.GetRoot( &xdnRootSrc )); if(fCreate) { fCreate = false;
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlDst.New( xdnRootSrc, /*fDeep*/false )); } __MPC_EXIT_IF_METHOD_FAILS(hr, xmlDst.GetRoot( &xdnRootDst ));
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnRootSrc->get_firstChild( &xdnSrc )); if(xdnSrc) { __MPC_EXIT_IF_METHOD_FAILS(hr, xdnSrc->get_childNodes( &xdnl )); __MPC_EXIT_IF_METHOD_FAILS(hr, xdnl ->get_length ( &lLength ));
if(lLength < lLimit) { __MPC_EXIT_IF_METHOD_FAILS(hr, xdnRootDst->appendChild( xdnSrc, &xdn ));
lCount += lLength; } else { __MPC_EXIT_IF_METHOD_FAILS(hr, xdnSrc ->cloneNode ( VARIANT_FALSE, &xdn )); __MPC_EXIT_IF_METHOD_FAILS(hr, xdnRootDst->appendChild( xdn, &xdnDst )); xdn.Release();
for(lCount = 0; lCount < lLimit && SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release(), lCount++) { CComPtr<IXMLDOMNode> xdn2;
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnDst->appendChild( xdn, &xdn2 )); } } }
if(xdnSrc == NULL || lCount >= lLimit) { fe.GenerateChunkName( fe.m_lChunks++, strFile );
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlDst.Save( strFile.c_str() ));
lCount = 0; fCreate = true; }
if(!xdnSrc) break; }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT CollateFromFiles( /*[in]*/ MPC::XmlUtil& xmlDst , /*[in]*/ LPCWSTR szRoot , /*[in]*/ FileEntry& fe ) { __HCP_FUNC_ENTRY( "CollateFromFiles" );
HRESULT hr; MPC::XmlUtil xmlSrc; MPC::wstring strFile; bool fCreated = false; bool fLoaded; bool fFound;
for(long l=0; l<fe.m_lChunks; l++) { fe.GenerateChunkName( l, strFile );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, (fCreated ? xmlSrc : xmlDst).Load( strFile.c_str(), szRoot, fLoaded, &fFound )); if(fLoaded == false || fFound == false ) { l_FileLog.LogRecord( L"Not a valid HHT: '%s'", strFile.c_str() ); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
if(fCreated) { CComPtr<IXMLDOMNode> xdnRootSrc; CComPtr<IXMLDOMNode> xdnRootDst; CComPtr<IXMLDOMNode> xdnSrc; CComPtr<IXMLDOMNode> xdnDst; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn; CComBSTR bstrTag;
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlSrc.GetRoot( &xdnRootSrc )); __MPC_EXIT_IF_METHOD_FAILS(hr, xmlDst.GetRoot( &xdnRootDst ));
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnRootSrc->get_firstChild( &xdnSrc )); if(!xdnSrc) continue;
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnSrc ->get_nodeName ( &bstrTag )); __MPC_EXIT_IF_METHOD_FAILS(hr, xdnRootDst->selectSingleNode( bstrTag, &xdnDst )); if(!xdnDst) { __MPC_EXIT_IF_METHOD_FAILS(hr, xdnRootDst->appendChild( xdnSrc, &xdn )); } else { __MPC_EXIT_IF_METHOD_FAILS(hr, xdnSrc->get_childNodes( &xdnl ));
for(; SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { CComPtr<IXMLDOMNode> xdn2;
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnDst->appendChild( xdn, &xdn2 )); } } } else { fCreated = true; } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////
static void FixString( /*[in/out]*/ MPC::wstring& strText, /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ) { if(!_wcsnicmp( strText.c_str(), strRootOld.c_str(), strRootOld.size() )) { strText.replace( 0, strRootOld.size(), strRoot ); } }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
HRESULT operator>>( /*[in ]*/ MPC::Serializer& stream , /*[out]*/ SetupImageEntry& val ) { __HCP_FUNC_ENTRY( "operator>> SetupImageEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strSKU ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strLocalization ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strPurpose ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strSourceFile ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strTemporaryName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strDestinationName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strDestinationDir ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_lastModified );
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strTemporaryFullPath);
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT operator<<( /*[in]*/ MPC::Serializer& stream , /*[in]*/ const SetupImageEntry& val ) { __HCP_FUNC_ENTRY( "operator<< SetupImageEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strSKU ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strLocalization ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strPurpose ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strSourceFile ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strTemporaryName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strDestinationName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strDestinationDir ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_lastModified );
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strTemporaryFullPath);
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT SetupImageEntry::Import( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ) { __HCP_FUNC_ENTRY( "SetupImageEntry::Import" );
HRESULT hr; DATE dFileSrc; DATE dFileDst;
m_strTemporaryFullPath = strRoot; m_strTemporaryFullPath += m_strLocalization; m_strTemporaryFullPath += L"\\"; m_strTemporaryFullPath += m_strTemporaryName;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::MakeDir( m_strTemporaryFullPath ));
dFileSrc = MPC::GetLastModifiedDate( m_strSourceFile ); dFileDst = MPC::GetLastModifiedDate( m_strTemporaryFullPath );
if(dFileSrc == 0) __MPC_SET_ERROR_AND_EXIT(hr, ERROR_FILE_NOT_FOUND);
if(dFileSrc > dFileDst) { l_FileLog.LogRecord( L"Copying file '%s' to '%s'", m_strSourceFile.c_str(), m_strTemporaryFullPath.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CopyFile( m_strSourceFile, m_strTemporaryFullPath ));
m_lastModified = MPC::GetLastModifiedDate( m_strTemporaryFullPath ); m_fUpdated = true; } else { m_lastModified = dFileDst; }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT SetupImageEntry::Export( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ) { return S_OK; }
void SetupImageEntry::FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ) { FixString( m_strTemporaryFullPath, strRootOld, strRoot ); }
////////////////////////////////////////
HRESULT operator>>( /*[in ]*/ MPC::Serializer& stream , /*[out]*/ FileEntry& val ) { __HCP_FUNC_ENTRY( "operator>> FileEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strFullPath ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_lastModified_HIGH); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_lastModified_LOW ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_lChunks );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT operator<<( /*[in]*/ MPC::Serializer& stream , /*[in]*/ const FileEntry& val ) { __HCP_FUNC_ENTRY( "operator<< FileEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strFullPath ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_lastModified_HIGH); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_lastModified_LOW ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_lChunks );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
void FileEntry::GenerateChunkName( /*[in]*/ long lChunk , /*[out]*/ MPC::wstring& strFile ) const { WCHAR rgTmp[64]; _snwprintf( rgTmp, MAXSTRLEN(rgTmp), L"_%ld", lChunk );
strFile = m_strFullPath; strFile.append( rgTmp ); }
void FileEntry::GetDate( /*[out]*/ DATE& dHIGH , /*[out]*/ DATE& dLOW ) const { if(m_lChunks == 0) { dHIGH = dLOW = MPC::GetLastModifiedDate( m_strFullPath ); } else { MPC::wstring strFile; DATE date; bool fNotExist = false;
dHIGH = 0; dLOW = 0;
for(long l = 0; l<m_lChunks; l++) { GenerateChunkName( l, strFile );
date = MPC::GetLastModifiedDate( strFile ); if(date) { if(!dHIGH || dHIGH < date) dHIGH = date; if(!dLOW || dLOW > date) dLOW = date; } else { fNotExist = true; } }
if(fNotExist) dLOW = 0; // In case one chunk doesn't exist, dLOW should reflect that.
} }
void FileEntry::SetDate( /*[in]*/ bool fLookForChunks ) { if(fLookForChunks && m_lChunks == 0) { MPC::wstring strFile;
while(1) { GenerateChunkName( m_lChunks, strFile );
if(!MPC::FileSystemObject::IsFile( strFile.c_str() )) break;
m_lChunks++; } }
GetDate( m_lastModified_HIGH, m_lastModified_LOW ); }
bool FileEntry::WasModified() const { DATE dHIGH; DATE dLOW;
GetDate( dHIGH, dLOW );
return (dHIGH == 0 || dHIGH > m_lastModified_HIGH); }
void FileEntry::FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ) { FixString( m_strFullPath, strRootOld, strRoot ); }
bool FileEntry::IsNewer( /*[in]*/ const FileEntry& fe ) { return IsNewer( fe.m_lastModified_LOW ); }
bool FileEntry::IsNewer( /*[in]*/ DATE date ) { return (m_lastModified_HIGH > date); }
////////////////////////////////////////
HRESULT operator>>( /*[in ]*/ MPC::Serializer& stream , /*[out]*/ TaxonomyEntry& val ) { __HCP_FUNC_ENTRY( "operator>> TaxonomyEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_fe ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_feMANUAL); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_feSYNSET); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_feLOC ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_feNOLOC );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT operator<<( /*[in]*/ MPC::Serializer& stream , /*[in]*/ const TaxonomyEntry& val ) { __HCP_FUNC_ENTRY( "operator<< TaxonomyEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_fe ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_feMANUAL); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_feSYNSET); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_feLOC ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_feNOLOC );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT TaxonomyEntry::Import( /*[in]*/ PackageEntry& pe, /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ) { __HCP_FUNC_ENTRY( "TaxonomyEntry::Import" );
HRESULT hr;
m_feMANUAL.m_strFullPath = m_fe.m_strFullPath; m_feMANUAL.m_strFullPath += L"_MANUAL"; m_feMANUAL.SetDate( ); m_feSYNSET.m_strFullPath = m_fe.m_strFullPath; m_feSYNSET.m_strFullPath += L"_SYNSET"; m_feSYNSET.SetDate( ); m_feLOC .m_strFullPath = m_fe.m_strFullPath; m_feLOC .m_strFullPath += L"_LOC"; m_feLOC .SetDate( /*fLookForChunks*/true ); m_feNOLOC .m_strFullPath = m_fe.m_strFullPath; m_feNOLOC .m_strFullPath += L"_NOLOC"; m_feNOLOC .SetDate( );
if(m_fe.IsNewer( m_feMANUAL ) || m_fe.IsNewer( m_feSYNSET ) || m_fe.IsNewer( m_feLOC ) || m_fe.IsNewer( m_feNOLOC ) ) { MPC::XmlUtil xml; bool fLoaded; bool fFound;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xml.Load( m_fe.m_strFullPath.c_str(), c_szHHT_rootTag, fLoaded, &fFound )); if(fLoaded == false || fFound == false ) { l_FileLog.LogRecord( L"Not a valid HHT: '%s'", m_fe.m_strFullPath.c_str() ); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
if(m_fe.IsNewer( m_feMANUAL )) { MPC::XmlUtil xmlMANUAL; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : MANUAL part", m_fe.m_strFullPath.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlMANUAL.New( c_szHHT_rootTag, L"UTF-16" ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlMANUAL, c_szHHT_manual_STOPSIGN )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlMANUAL, c_szHHT_manual_STOPWORD )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlMANUAL, c_szHHT_manual_OPERATOR ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xmlMANUAL.Save( m_feMANUAL.m_strFullPath.c_str() ));
m_feMANUAL.SetDate(); m_feMANUAL.m_fUpdated = true; }
if(m_fe.IsNewer( m_feSYNSET )) { MPC::XmlUtil xmlSYNSET; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : SYNSET part", m_fe.m_strFullPath.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlSYNSET.New( c_szHHT_rootTag, L"UTF-16" ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlSYNSET, c_szHHT_synset_SYNTABLE ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xmlSYNSET.Save( m_feSYNSET.m_strFullPath.c_str() ));
m_feSYNSET.SetDate(); m_feSYNSET.m_fUpdated = true; }
if(m_fe.IsNewer( m_feLOC )) { MPC::XmlUtil xmlLOC; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : LOC part", m_fe.m_strFullPath.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlLOC.New( c_szHHT_rootTag, L"UTF-16" ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlLOC, c_szHHT_loc_SCOPE )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlLOC, c_szHHT_loc_TAXONOMY ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, ConvertAttributesToElements( xmlLOC, c_szHHT_conv_SCOPE , c_rgHHT_conv_SCOPE , ARRAYSIZE(c_rgHHT_conv_SCOPE ) )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, ConvertAttributesToElements( xmlLOC, c_szHHT_conv_TAXONOMY, c_rgHHT_conv_TAXONOMY, ARRAYSIZE(c_rgHHT_conv_TAXONOMY) ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, SpreadToFiles( xmlLOC, m_feLOC, l_lMaxElements ));
m_feLOC.SetDate(); m_feLOC.m_fUpdated = true; }
if(m_fe.IsNewer( m_feNOLOC )) { MPC::XmlUtil xmlNOLOC; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : NOLOC part", m_fe.m_strFullPath.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, xmlNOLOC.New( c_szHHT_rootTag ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlNOLOC, c_szHHT_noloc_FTS )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlNOLOC, c_szHHT_noloc_INDEX )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xml, xmlNOLOC, c_szHHT_noloc_HELPIMAGE ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xmlNOLOC.Save( m_feNOLOC.m_strFullPath.c_str() ));
m_feNOLOC.SetDate(); m_feNOLOC.m_fUpdated = true; } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT TaxonomyEntry::Export( /*[in]*/ PackageEntry& pe, /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ) { __HCP_FUNC_ENTRY( "TaxonomyEntry::Export" );
HRESULT hr;
m_fe_New.m_strFullPath = m_fe.m_strFullPath; m_fe_New.m_strFullPath += L"_GEN";
m_feMANUAL.SetDate(); m_feSYNSET.SetDate(); m_feLOC .SetDate(); m_feNOLOC .SetDate(); m_fe_New .SetDate();
if(m_feMANUAL.IsNewer( m_fe_New ) || m_feSYNSET.IsNewer( m_fe_New ) || m_feLOC .IsNewer( m_fe_New ) || m_feNOLOC .IsNewer( m_fe_New ) ) { MPC::XmlUtil xml; bool fLoaded; bool fFound;
l_FileLog.LogRecord( L"Processing HHT '%s'", m_fe_New.m_strFullPath.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.New( c_szHHT_rootTag, L"UTF-16" ));
{ MPC::XmlUtil xmlMANUAL; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : MANUAL part", m_fe_New.m_strFullPath.c_str() );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xmlMANUAL.Load( m_feMANUAL.m_strFullPath.c_str(), c_szHHT_rootTag, fLoaded, &fFound )); if(fLoaded == false || fFound == false ) { l_FileLog.LogRecord( L"Not a valid HHT: '%s'", m_feMANUAL.m_strFullPath.c_str() ); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlMANUAL, xml, c_szHHT_manual_STOPSIGN )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlMANUAL, xml, c_szHHT_manual_STOPWORD )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlMANUAL, xml, c_szHHT_manual_OPERATOR )); }
{ MPC::XmlUtil xmlSYNSET; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : SYNSET part", m_fe_New.m_strFullPath.c_str() );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xmlSYNSET.Load( m_feSYNSET.m_strFullPath.c_str(), c_szHHT_rootTag, fLoaded, &fFound )); if(fLoaded == false || fFound == false ) { l_FileLog.LogRecord( L"Not a valid HHT: '%s'", m_feSYNSET.m_strFullPath.c_str() ); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlSYNSET, xml, c_szHHT_synset_SYNTABLE )); }
{ MPC::XmlUtil xmlLOC; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : LOC part", m_fe_New.m_strFullPath.c_str() );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, CollateFromFiles( xmlLOC, c_szHHT_rootTag, m_feLOC ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, ConvertElementsToAttributes( xmlLOC, c_szHHT_conv_SCOPE , c_rgHHT_conv_SCOPE , ARRAYSIZE(c_rgHHT_conv_SCOPE ) )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, ConvertElementsToAttributes( xmlLOC, c_szHHT_conv_TAXONOMY, c_rgHHT_conv_TAXONOMY, ARRAYSIZE(c_rgHHT_conv_TAXONOMY) ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlLOC, xml, c_szHHT_loc_SCOPE )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlLOC, xml, c_szHHT_loc_TAXONOMY )); }
{ MPC::XmlUtil xmlNOLOC; CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn;
l_FileLog.LogRecord( L"Processing HHT '%s' : NOLOC part", m_fe_New.m_strFullPath.c_str() );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xmlNOLOC.Load( m_feNOLOC.m_strFullPath.c_str(), c_szHHT_rootTag, fLoaded, &fFound )); if(fLoaded == false || fFound == false ) { l_FileLog.LogRecord( L"Not a valid HHT: '%s'", m_feNOLOC.m_strFullPath.c_str() ); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlNOLOC, xml, c_szHHT_noloc_FTS )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlNOLOC, xml, c_szHHT_noloc_INDEX )); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, MoveDataIsland( xmlNOLOC, xml, c_szHHT_noloc_HELPIMAGE )); }
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xml.Save( m_fe_New.m_strFullPath.c_str() )); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
void TaxonomyEntry::FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ) { m_fe .FixRoot( strRootOld, strRoot ); m_feMANUAL.FixRoot( strRootOld, strRoot ); m_feSYNSET.FixRoot( strRootOld, strRoot ); m_feLOC .FixRoot( strRootOld, strRoot ); m_feNOLOC .FixRoot( strRootOld, strRoot );
m_fe_New .FixRoot( strRootOld, strRoot ); }
////////////////////////////////////////
HRESULT operator>>( /*[in ]*/ MPC::Serializer& stream , /*[out]*/ PackageEntry& val ) { __HCP_FUNC_ENTRY( "operator>> PackageEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strDir ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strPackageDescription); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_flSAF ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_flINSTALL ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_flHHT );
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_DB_strSKU ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_DB_lLCID ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_DB_strDisplayName );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT operator<<( /*[in]*/ MPC::Serializer& stream , /*[in]*/ const PackageEntry& val ) { __HCP_FUNC_ENTRY( "operator<< PackageEntry" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strDir ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strPackageDescription); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_flSAF ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_flINSTALL ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_flHHT );
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_DB_strSKU ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_DB_lLCID ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_DB_strDisplayName );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT PackageEntry::Import( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ) { __HCP_FUNC_ENTRY( "PackageEntry::Import" );
HRESULT hr; MPC::Cabinet::List lst; MPC::wstring strFile; MPC::wstring strFile_Base; LPCWSTR szSourceFile; LPCWSTR szEnd; DATE dFile_PackageDescription;
strFile = pbe.m_entry.m_strTemporaryFullPath;
//
// Create temp dir from the file name.
//
szSourceFile = strFile.c_str(); szEnd = wcsrchr( szSourceFile, '.' ); if(szEnd) { m_strDir.assign( szSourceFile, szEnd ); } else { m_strDir = szSourceFile; }
m_strDir += L"\\";
if(pbe.m_entry.m_fUpdated) { RemoveDirectory( m_strDir );
m_flSAF .clear(); m_flINSTALL.clear(); m_flHHT .clear(); }
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::MakeDir( m_strDir ));
//
// Analyze Package_Description.xml
//
{ MPC::XmlUtil xml; bool fFound;
m_strPackageDescription = m_strDir; m_strPackageDescription += c_szPackageDescription;
dFile_PackageDescription = MPC::GetLastModifiedDate( m_strPackageDescription );
if(dFile_PackageDescription == 0 || pbe.m_entry.m_lastModified > dFile_PackageDescription) { LOG__MPC_EXIT_IF_METHOD_FAILS(hr, ExtractFile( szSourceFile, m_strPackageDescription.c_str(), c_szPackageDescription ));
dFile_PackageDescription = MPC::GetLastModifiedDate( m_strPackageDescription );; }
__MPC_EXIT_IF_METHOD_FAILS(hr, OpenPackageDescription( xml ));
//
// Parse the SAF section.
//
{ CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn; FileEntry fe;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNodes( L"CONFIG/SAF/@FILE", &xdnl )); for(;SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, fe.m_strName, fFound, xdn )); if(fFound) { fe.m_strFullPath = m_strDir; fe.m_strFullPath += fe.m_strName;
m_flSAF.push_back( fe ); } } }
//
// Parse the INSTALL section.
//
{ CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn; FileEntry fe;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNodes( L"INSTALL_CONTENT/FILE/@SOURCE", &xdnl )); for(;SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, fe.m_strName, fFound, xdn )); if(fFound) { fe.m_strFullPath = m_strDir; fe.m_strFullPath += fe.m_strName;
m_flINSTALL.push_back( fe ); } } }
//
// Parse the HHT section.
//
{ CComPtr<IXMLDOMNodeList> xdnl; CComPtr<IXMLDOMNode> xdn; TaxonomyEntry te;
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNodes( L"METADATA/HHT/@FILE", &xdnl )); for(;SUCCEEDED(hr = xdnl->nextNode( &xdn )) && xdn != NULL; xdn.Release()) { __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, te.m_fe.m_strName, fFound, xdn )); if(fFound) { te.m_fe.m_strFullPath = m_strDir; te.m_fe.m_strFullPath += te.m_fe.m_strName;
m_flHHT.push_back( te ); } } } }
//
// Extract all the required files.
//
{ MPC::WStringUCSet setDecompress; MPC::Cabinet cab; FileIter it1; FileIter it2; TaxonomyIter it3;
__MPC_EXIT_IF_METHOD_FAILS(hr, cab.put_CabinetFile( szSourceFile ));
for(it1=m_flSAF.begin(); it1!=m_flSAF.end(); it1++) { FileEntry& fe = *it1;
if(dFile_PackageDescription > MPC::GetLastModifiedDate( fe.m_strFullPath )) { if(setDecompress.find( fe.m_strName ) == setDecompress.end()) { setDecompress.insert( fe.m_strName );
l_FileLog.LogRecord( L"Extracting '%s' from '%s'", fe.m_strName.c_str(), szSourceFile ); __MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( fe.m_strFullPath.c_str(), fe.m_strName.c_str() ));
fe.m_fUpdated = true; } } }
for(it2=m_flINSTALL.begin(); it2!=m_flINSTALL.end(); it2++) { FileEntry& fe = *it2;
if(dFile_PackageDescription > MPC::GetLastModifiedDate( fe.m_strFullPath )) { if(setDecompress.find( fe.m_strName ) == setDecompress.end()) { setDecompress.insert( fe.m_strName );
l_FileLog.LogRecord( L"Extracting '%s' from '%s'", fe.m_strName.c_str(), szSourceFile ); __MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( fe.m_strFullPath.c_str(), fe.m_strName.c_str() ));
fe.m_fUpdated = true; } } }
for(it3=m_flHHT.begin(); it3!=m_flHHT.end(); it3++) { TaxonomyEntry& te = *it3;
if(dFile_PackageDescription > MPC::GetLastModifiedDate( te.m_fe.m_strFullPath )) { if(setDecompress.find( te.m_fe.m_strName ) == setDecompress.end()) { setDecompress.insert( te.m_fe.m_strName );
l_FileLog.LogRecord( L"Extracting '%s' from '%s'", te.m_fe.m_strName.c_str(), szSourceFile ); __MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( te.m_fe.m_strFullPath.c_str(), te.m_fe.m_strName.c_str() ));
te.m_fe.m_fUpdated = true; } } }
hr = cab.Decompress(); if(FAILED(hr)) { MPC::Cabinet::List lst; MPC::Cabinet::Iter it;
if(SUCCEEDED(cab.GetFiles( lst ))) { for(it=lst.begin(); it != lst.end(); it++) { if(it->m_fFound == false) { l_FileLog.LogRecord( L"!!ERROR: Missing %s \n", it->m_szName.c_str() ); } } }
__MPC_FUNC_LEAVE; }
for(it1=m_flSAF.begin(); it1!=m_flSAF.end(); it1++) { FileEntry& fe = *it1;
fe.SetDate(); }
for(it2=m_flINSTALL.begin(); it2!=m_flINSTALL.end(); it2++) { FileEntry& fe = *it2;
fe.SetDate(); }
for(it3=m_flHHT.begin(); it3!=m_flHHT.end(); it3++) { TaxonomyEntry& te = *it3;
te.m_fe.SetDate(); } }
//
// Process the HHTs.
//
{ for(TaxonomyIter it=m_flHHT.begin(); it!=m_flHHT.end(); it++) { TaxonomyEntry& te = *it;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, te.Import( *this, pbe, strRoot )); } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT PackageEntry::Export( /*[in]*/ PostBuildEntry& pbe, /*[in]*/ const MPC::wstring& strRoot ) { __HCP_FUNC_ENTRY( "PackageEntry::Export" );
HRESULT hr; DATE dFile_Cabinet; DATE dFile_PackageDescription;
m_strNew_Cabinet = pbe.m_entry.m_strTemporaryFullPath; m_strNew_Cabinet += L"_GEN";
dFile_Cabinet = MPC::GetLastModifiedDate( m_strNew_Cabinet ); dFile_PackageDescription = MPC::GetLastModifiedDate( m_strPackageDescription );
//
// Process the HHTs.
//
{ for(TaxonomyIter it=m_flHHT.begin(); it!=m_flHHT.end(); it++) { TaxonomyEntry& te = *it;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, te.Export( *this, pbe, strRoot )); } }
//
// Compress all the required files.
//
{ MPC::Cabinet cab; FileIter it1; FileIter it2; TaxonomyIter it3; bool fNew = false;
__MPC_EXIT_IF_METHOD_FAILS(hr, cab.put_CabinetFile( m_strNew_Cabinet.c_str() ));
__MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( m_strPackageDescription.c_str(), c_szPackageDescription )); if(dFile_PackageDescription > dFile_Cabinet) fNew = true;
for(it1=m_flSAF.begin(); it1!=m_flSAF.end(); it1++) { FileEntry& fe = *it1;
fe.SetDate(); if(fe.IsNewer( dFile_Cabinet )) fNew = true; __MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( fe.m_strFullPath.c_str(), fe.m_strName.c_str() )); }
for(it2=m_flINSTALL.begin(); it2!=m_flINSTALL.end(); it2++) { FileEntry& fe = *it2;
fe.SetDate(); if(fe.IsNewer( dFile_Cabinet )) fNew = true; __MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( fe.m_strFullPath.c_str(), fe.m_strName.c_str() )); }
for(it3=m_flHHT.begin(); it3!=m_flHHT.end(); it3++) { TaxonomyEntry& te = *it3;
te.m_fe_New.SetDate(); if(te.m_fe_New.IsNewer( dFile_Cabinet )) fNew = true; __MPC_EXIT_IF_METHOD_FAILS(hr, cab.AddFile( te.m_fe_New.m_strFullPath.c_str(), te.m_fe.m_strName.c_str() )); }
if(fNew) { l_FileLog.LogRecord( L"Compressing '%s'", m_strNew_Cabinet.c_str() );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, cab.Compress()); } }
if(pbe.m_pbt == POSTBUILDTYPE_HHT) { DATE dCabinet; DATE dDatabase;
m_strNew_Database = pbe.m_entry.m_strTemporaryFullPath; m_strNew_Database += L"_EDB";
{ MPC::XmlUtil xml;
__MPC_EXIT_IF_METHOD_FAILS(hr, OpenPackageDescription( xml )); }
dCabinet = MPC::GetLastModifiedDate( m_strNew_Cabinet ); dDatabase = MPC::GetLastModifiedDate( m_strNew_Database );
if(dDatabase == 0.0 || dCabinet > dDatabase) { MPC::wstring strTmp;
GetRootDirectory( strTmp ); strTmp += L"\\EDB_"; strTmp += m_DB_strSKU; strTmp += L"\\";
l_FileLog.LogRecord( L"Create database '%s'", m_strNew_Database.c_str() );
try { hr = CreateDatabase( strTmp ); } catch(...) { hr = E_FAIL; }
//
// Something JetBlue fails because of a bad checkpoint directory.
//
if(FAILED(hr)) { try { RemoveDirectory( strTmp );
hr = CreateDatabase( strTmp ); } catch(...) { hr = E_FAIL; } }
if(FAILED(hr)) { (void)MPC::DeleteFile( m_strNew_Database ); }
RemoveDirectory( strTmp );
__MPC_EXIT_IF_METHOD_FAILS(hr, hr); } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////
HRESULT PackageEntry::OpenPackageDescription( /*[in/out]*/ MPC::XmlUtil& xml ) { __HCP_FUNC_ENTRY( "PackageEntry::OpenPackageDescription" );
HRESULT hr; MPC::wstring strLanguage; bool fLoaded; bool fFound;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, xml.Load( m_strPackageDescription.c_str(), L"HELPCENTERPACKAGE", fLoaded, &fFound )); if(fLoaded == false || fFound == false ) { l_FileLog.LogRecord( L"Not a valid Package_Description: '%s'", m_strPackageDescription.c_str() ); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetAttribute( L"SKU", L"VALUE" , m_DB_strSKU , fFound )); __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetAttribute( L"SKU", L"DISPLAYNAME", m_DB_strDisplayName, fFound )); __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetAttribute( L"LANGUAGE", L"VALUE" , strLanguage , fFound )); if(fFound) m_DB_lLCID = _wtol( strLanguage.c_str() );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT PackageEntry::ProcessHHTFile( /*[in]*/ LPCWSTR szHHTFile , /*[in]*/ JetBlue::SessionHandle* handle , /*[in]*/ JetBlue::Database* db ) { __HCP_FUNC_ENTRY( "PackageEntry::ProcessHHTFile" );
HRESULT hr; CComPtr<HCUpdate::Engine> obj; MPC::wstring strDBLog; GetDBLogFile( strDBLog );
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &obj ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, obj->PopulateDatabase( m_strNew_Cabinet.c_str(), szHHTFile, strDBLog.c_str(), m_DB_strSKU.c_str(), m_DB_lLCID, *handle, db ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT PackageEntry::CreateDatabase( /*[in]*/ const MPC::wstring& strTmp ) { __HCP_FUNC_ENTRY( "PackageEntry::CreateDatabase" );
USES_CONVERSION;
HRESULT hr; JetBlue::SessionPool pool; JetBlue::SessionHandle handle; JetBlue::Database* db; long lMSFTid; bool fPool = false; bool fSession = false; bool fDatabase = false;
// if(g_fVerbose) wprintf( L"Creating database %s\n", szDatabase );
//
// Remove any old database.
//
(void)MPC::DeleteFile( m_strNew_Database );
////////////////////////////////////////////////////////////////////////////////
//
// Create new database.
//
RemoveDirectory( strTmp ); LOG__MPC_EXIT_IF_METHOD_FAILS(hr, pool.Init( strTmp.c_str() )); fPool = true;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, pool.GetSession( handle )); fSession = true;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, handle->GetDatabase( W2A( m_strNew_Database.c_str() ), db, /*fReadOnly*/false, /*fCreate*/true, /*fRepair*/false )) fDatabase = true;
////////////////////////////////////////////////////////////////////////////////
//
// Load the schema in the database.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, handle->BeginTransaction()); { LOG__MPC_EXIT_IF_METHOD_FAILS(hr, Taxonomy::CreateSchema( db )); } __MPC_EXIT_IF_METHOD_FAILS(hr, handle->CommitTransaction());
////////////////////////////////////////////////////////////////////////////////
{ Taxonomy::Settings ts( m_DB_strSKU.c_str(), m_DB_lLCID ); Taxonomy::Updater updater;
__MPC_EXIT_IF_METHOD_FAILS(hr, updater.Init( ts, db ));
//
// Generate content owner
//
__MPC_EXIT_IF_METHOD_FAILS(hr, handle->BeginTransaction()); { __MPC_EXIT_IF_METHOD_FAILS(hr, updater.CreateOwner( lMSFTid, HC_MICROSOFT_DN, /*fIsOEM*/true )); __MPC_EXIT_IF_METHOD_FAILS(hr, updater.LocateOwner( HC_MICROSOFT_DN )); } __MPC_EXIT_IF_METHOD_FAILS(hr, handle->CommitTransaction());
//
// Create the root and non-mapped node in the topic table
//
__MPC_EXIT_IF_METHOD_FAILS(hr, handle->BeginTransaction()); { Taxonomy::RS_Taxonomy* rs;
__MPC_EXIT_IF_METHOD_FAILS(hr, updater.GetTaxonomy( &rs ));
rs->m_ID_owner = lMSFTid; rs->m_strEntry = L"<ROOT>"; __MPC_EXIT_IF_METHOD_FAILS(hr, rs->Insert()); } __MPC_EXIT_IF_METHOD_FAILS(hr, handle->CommitTransaction());
//
// Create the system scope.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, handle->BeginTransaction()); { Taxonomy::RS_Scope* rs;
__MPC_EXIT_IF_METHOD_FAILS(hr, updater.GetScope( &rs ));
rs->m_ID_owner = lMSFTid; rs->m_strID = L"<SYSTEM>"; __MPC_EXIT_IF_METHOD_FAILS(hr, rs->Insert()); } __MPC_EXIT_IF_METHOD_FAILS(hr, handle->CommitTransaction());
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, updater.Close()); }
////////////////////////////////////////////////////////////////////////////////
//
// Process the HHT file, after closing the updater.
//
{ for(TaxonomyIter it=m_flHHT.begin(); it!=m_flHHT.end(); it++) { TaxonomyEntry& te = *it;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, ProcessHHTFile( te.m_fe_New.m_strFullPath.c_str(), &handle, db )); } }
////////////////////////////////////////////////////////////////////////////////
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(fDatabase) { ; } if(fSession ) { handle.Release(); } if(fPool ) { (void)pool.Close( true ); }
__HCP_FUNC_EXIT(hr); }
void PackageEntry::FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ) { FileIter it1; TaxonomyIter it2;
FixString( m_strDir , strRootOld, strRoot ); FixString( m_strPackageDescription, strRootOld, strRoot );
for(it1=m_flSAF .begin(); it1!=m_flSAF .end(); it1++) it1->FixRoot( strRootOld, strRoot ); for(it1=m_flINSTALL.begin(); it1!=m_flINSTALL.end(); it1++) it1->FixRoot( strRootOld, strRoot ); for(it2=m_flHHT .begin(); it2!=m_flHHT .end(); it2++) it2->FixRoot( strRootOld, strRoot );
FixString( m_strNew_Cabinet , strRootOld, strRoot ); FixString( m_strNew_Database, strRootOld, strRoot ); }
////////////////////////////////////////
HRESULT operator>>( /*[in ]*/ MPC::Serializer& stream , /*[out]*/ PostBuildEntry& val ) { __HCP_FUNC_ENTRY( "operator>> PostBuildEntry" );
HRESULT hr; long pbt;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> pbt ); val.m_pbt = (PostBuildType)pbt; __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_entry ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_package);
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT operator<<( /*[in]*/ MPC::Serializer& stream , /*[in]*/ const PostBuildEntry& val ) { __HCP_FUNC_ENTRY( "operator<< PostBuildEntry" );
HRESULT hr; long pbt = (long)val.m_pbt;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << pbt ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_entry ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_package);
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
void PostBuildEntry::FixRoot( /*[in]*/ const MPC::wstring& strRootOld, /*[in]*/ const MPC::wstring& strRoot ) { m_entry .FixRoot( strRootOld, strRoot ); m_package.FixRoot( strRootOld, strRoot ); }
////////////////////////////////////////
HRESULT operator>>( /*[in ]*/ MPC::Serializer& stream , /*[out]*/ SkuInformation& val ) { __HCP_FUNC_ENTRY( "operator>> SkuInformation" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strCabinet ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_strProdFilt); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_fDesktop ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_fServer ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream >> val.m_fEmbedded );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
HRESULT operator<<( /*[in]*/ MPC::Serializer& stream , /*[in]*/ const SkuInformation& val ) { __HCP_FUNC_ENTRY( "operator<< SkuInformation" );
HRESULT hr;
__MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strName ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strCabinet ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_strProdFilt); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_fDesktop ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_fServer ); __MPC_EXIT_IF_METHOD_FAILS(hr, stream << val.m_fEmbedded );
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
static void Usage() { wprintf( L"Usage: HssSetupTool <options> <command> <parameters>\n\n" ); wprintf( L"Available commands:\n\n" ); wprintf( L" BINPLACE <sku file> <setup image file> <root directory> <object directory>\n" ); wprintf( L" COMPILE <root directory> <sku>\n" ); wprintf( L" LIST <input cabinet>\n" ); wprintf( L" EXTRACT <input cabinet> <file>\n" ); wprintf( L" INSTALL <input cabinet>\n" ); wprintf( L"\n" ); wprintf( L" UNPACK <input cabinet> <directory>\n" ); wprintf( L" PACK <directory> <output cabinet>\n" ); }
#define CHECK_ARGS(argc,num) if(argc < num) { Usage(); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
////////////////////////////////////////
static bool LookupBoolean( /*[in] */ LPCWSTR szString ) { if(_wcsicmp( szString, L"TRUE" ) == 0 || _wcsicmp( szString, L"1" ) == 0 || _wcsicmp( szString, L"ON" ) == 0 ) { return true; }
return false; }
static bool ParseFile( /*[in ]*/ LPSTR szLine , /*[out]*/ SetupImageEntry& en ) { USES_CONVERSION;
HRESULT hr; LPSTR szEnd; std::vector<MPC::wstring> vec;
//
// Skip comments.
//
if(szLine[0] == '#') return false;
if((szEnd = strchr( szLine, '\r' ))) szEnd[0] = 0; if((szEnd = strchr( szLine, '\n' ))) szEnd[0] = 0;
MPC::SplitAtDelimiter( vec, A2W( szLine ), L"," ); if(vec.size() != 7) return false;
en.m_strSKU = vec[0]; en.m_strLocalization = vec[1]; en.m_strPurpose = vec[2]; en.m_strSourceFile = vec[3]; en.m_strTemporaryName = vec[4]; en.m_strDestinationName = vec[5]; en.m_strDestinationDir = vec[6];
return true; }
static bool ParseFile( /*[in ]*/ LPSTR szLine , /*[out]*/ SkuInformation& si ) { USES_CONVERSION;
HRESULT hr; LPSTR szEnd; std::vector<MPC::wstring> vec;
//
// Skip comments.
//
if(szLine[0] == '#') return false;
if((szEnd = strchr( szLine, '\r' ))) szEnd[0] = 0; if((szEnd = strchr( szLine, '\n' ))) szEnd[0] = 0;
MPC::SplitAtDelimiter( vec, A2W( szLine ), L" ", /*fDelimIsAString*/false, /*fSkipAdjacentDelims*/true ); if(vec.size() != 6) return false;
si.m_strName = vec[0]; si.m_strCabinet = vec[1]; si.m_strProdFilt = vec[2]; si.m_fDesktop = LookupBoolean( vec[3].c_str() ); si.m_fServer = LookupBoolean( vec[4].c_str() ); si.m_fEmbedded = LookupBoolean( vec[5].c_str() );
return true; }
static bool GetSetupImageFile( /*[in ]*/ SkuInformationList& sil , /*[in ]*/ LPCWSTR szSKU , /*[out]*/ MPC::wstring& strCabinet , /*[out]*/ Taxonomy::InstanceBase& data ) { if(!_wcsicmp( szSKU, L"NONE" )) { strCabinet = L"none.cab"; data.m_fDesktop = false; data.m_fServer = false; data.m_fEmbedded = false; return true; }
for(SkuInformationIter it=sil.begin(); it!=sil.end(); it++) { if(!_wcsicmp( szSKU, it->m_strName.c_str() )) { strCabinet = it->m_strCabinet; data.m_fDesktop = it->m_fDesktop ; data.m_fServer = it->m_fServer ; data.m_fEmbedded = it->m_fEmbedded ;
return true; } }
return false; }
static HRESULT OpenFile( /*[in ]*/ const MPC::wstring& strFile , /*[out]*/ FILE*& fh ) { __HCP_FUNC_ENTRY( "OpenFile" );
HRESULT hr;
fh = _wfopen( strFile.c_str(), L"r" ); if(fh == NULL) { DWORD dwRes = ::GetLastError();
l_FileLog.LogRecord( L"%08x: Can't open file '%s'", HRESULT_FROM_WIN32(dwRes), strFile.c_str() );
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////
static HRESULT Index_SAVE( /*[in]*/ const MPC::wstring& strRoot , /*[in]*/ PostBuildList& pbl , /*[in]*/ SkuInformationList& sil ) { __HCP_FUNC_ENTRY( "Index_SAVE" );
HRESULT hr; MPC::wstring strFileOut; HANDLE hFile = NULL;
strFileOut = strRoot; strFileOut += c_szNTTREE_INDEX;
//
// Create the new file.
//
__MPC_EXIT_IF_INVALID_HANDLE__CLEAN(hr, hFile, ::CreateFileW( strFileOut.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ));
//
// Dump to file.
//
{ MPC::Serializer_File streamReal( hFile ); MPC::Serializer_Buffering streamBuf ( streamReal );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf << c_dwVersion ); __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf << strRoot ); __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf << pbl ); __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf << sil );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf.Flush()); }
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hFile) ::CloseHandle( hFile );
__HCP_FUNC_EXIT(hr); }
static HRESULT Index_LOAD( /*[in]*/ const MPC::wstring& strRoot , /*[in]*/ PostBuildList& pbl , /*[in]*/ SkuInformationList& sil ) { __HCP_FUNC_ENTRY( "Index_LOAD" );
HRESULT hr; MPC::wstring strFileOut; HANDLE hFile = NULL;
strFileOut = strRoot; strFileOut += c_szNTTREE_INDEX;
pbl.clear();
__MPC_EXIT_IF_INVALID_HANDLE__CLEAN(hr, hFile, ::CreateFileW( strFileOut.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
{ MPC::Serializer_File streamReal( hFile ); MPC::Serializer_Buffering streamBuf ( streamReal ); MPC::wstring strRootOld; DWORD dwVer;
__MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf >> dwVer ); if(dwVer != c_dwVersion) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf >> strRootOld ); __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf >> pbl ); __MPC_EXIT_IF_METHOD_FAILS(hr, streamBuf >> sil );
if(strRootOld != strRoot) { for(PostBuildIter it=pbl.begin(); it!=pbl.end(); it++) { it->FixRoot( strRootOld, strRoot ); } } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hFile) ::CloseHandle( hFile );
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////
static HRESULT Binplace( /*[in]*/ LPCWSTR szSKUList , /*[in]*/ LPCWSTR szFileList , /*[in]*/ LPCWSTR szRoot , /*[in]*/ LPCWSTR szObject ) { __HCP_FUNC_ENTRY( "Binplace" );
HRESULT hr; FILE* in = NULL; char buf[1024]; MPC::wstring strFileList; MPC::wstring strRoot; PostBuildList pbl; SkuInformationList sil;
strFileList = szFileList; MPC::SubstituteEnvVariables( strFileList );
strRoot = szRoot; strRoot += L"\\"; strRoot += c_szNTTREE_BASE; strRoot += L"\\"; MPC::SubstituteEnvVariables( strRoot );
l_FileLog.LogRecord( L"\n==================\n" L"BINPLACE - start\n\n" );
////////////////////////////////////////
::SetEnvironmentVariableW( L"OBJECTDIR", szObject );
{ LOG__MPC_EXIT_IF_METHOD_FAILS(hr, OpenFile( szSKUList, in )); while(fgets( buf, 1024, in )) { SkuInformation si;
if(ParseFile( buf, si )) { sil.push_back( si );
l_FileLog.LogRecord( L"Found SKU: %-30s %-15s %-15s %s%s%s" , si.m_strName .c_str() , si.m_strCabinet .c_str() , si.m_strProdFilt.c_str() , si.m_fDesktop ? L"DESKTOP " : L"" , si.m_fServer ? L"SERVER " : L"" , si.m_fEmbedded ? L"EMBEDDED " : L"" ); } } fclose( in ); in = NULL;
l_FileLog.LogRecord( L"\n" ); }
{ __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::MakeDir( strRoot.c_str() ));
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, OpenFile( strFileList, in )); while(fgets( buf, 1024, in )) { SetupImageEntry en;
if(ParseFile( buf, en )) { PostBuildEntry& pbe = *( pbl.insert( pbl.end() ) );
MPC::SubstituteEnvVariables( en.m_strSourceFile ); pbe.m_entry = en;
//
// This copies the file if newer.
//
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, pbe.m_entry.Import( pbe, strRoot ));
if(!MPC::StrICmp( en.m_strLocalization, L"HHT" )) { //
// Expand the cabinet and process the HHTs.
//
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, pbe.m_package.Import( pbe, strRoot ));
pbe.m_pbt = POSTBUILDTYPE_HHT; } else if(!MPC::StrICmp( en.m_strLocalization, L"SAF" )) { //
// Expand the cabinet and process the channel.
//
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, pbe.m_package.Import( pbe, strRoot ));
pbe.m_pbt = POSTBUILDTYPE_SAF; } else { pbe.m_pbt = POSTBUILDTYPE_NORMAL; } } } fclose( in ); in = NULL;
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, Index_SAVE( strRoot, pbl, sil )); }
////////////////////////////////////////
hr = S_OK;
__HCP_FUNC_CLEANUP;
l_FileLog.LogRecord( L"\nBINPLACE - done\n" L"=================\n\n" );
if(in) fclose( in );
__HCP_FUNC_EXIT(hr); }
static HRESULT Compile( /*[in]*/ LPCWSTR szRoot , /*[in]*/ LPCWSTR szSKU ) { __HCP_FUNC_ENTRY( "Compile" );
HRESULT hr; Installer::Package pkg; Taxonomy::InstanceBase& data = pkg.GetData(); MPC::wstring strRoot; MPC::wstring strCabinet; MPC::wstring strFullPath; PostBuildList pbl; SkuInformationList sil; DATE dFile_SetupImage; bool fNew = false;
l_FileLog.LogRecord( L"\n==================\n" L"COMPILE - start\n\n" );
////////////////////////////////////////
strRoot = szRoot; strRoot += L"\\"; strRoot += c_szNTTREE_BASE; strRoot += L"\\"; MPC::SubstituteEnvVariables( strRoot );
LOG__MPC_EXIT_IF_METHOD_FAILS(hr, Index_LOAD( strRoot, pbl, sil ));
if(GetSetupImageFile( sil, szSKU, strCabinet, data ) == false) { l_FileLog.LogRecord( L"'%s' is not a valid SKU name!\n\n", szSKU );
__MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
strFullPath = szRoot; strFullPath += L"\\"; strFullPath += c_szNTTREE_BASE; strFullPath += L"\\"; strFullPath += strCabinet; MPC::SubstituteEnvVariables( strFullPath );
dFile_SetupImage = MPC::GetLastModifiedDate( strFullPath ); __MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init( strFullPath.c_str() ));
for(PostBuildIter itPB=pbl.begin(); itPB!=pbl.end(); itPB++) { PostBuildEntry& pbe = *itPB;
if(MPC::StrICmp( pbe.m_entry.m_strSKU, L"All" ) == 0 || MPC::StrICmp( pbe.m_entry.m_strSKU, szSKU ) == 0 ) { Installer::Iter itFile = pkg.NewFile(); MPC::wstring strFileSrc = pbe.m_entry.m_strTemporaryFullPath; MPC::wstring strFileDst = pbe.m_entry.m_strDestinationDir; strFileDst += L"\\"; strFileDst += pbe.m_entry.m_strDestinationName;
__MPC_EXIT_IF_METHOD_FAILS(hr, itFile->SetPurpose( pbe.m_entry.m_strPurpose.c_str() ));
itFile->m_strFileLocal = strFileSrc; itFile->m_strFileInner = pbe.m_entry.m_strTemporaryName; itFile->m_strFileLocation = strFileDst;
if(pbe.m_pbt == POSTBUILDTYPE_HHT || pbe.m_pbt == POSTBUILDTYPE_SAF ) { LOG__MPC_EXIT_IF_METHOD_FAILS(hr, pbe.m_package.Export( pbe, strRoot ));
itFile->m_strFileLocal = (pbe.m_pbt == POSTBUILDTYPE_SAF) ? pbe.m_package.m_strNew_Cabinet : pbe.m_package.m_strNew_Database; }
if(pbe.m_pbt == POSTBUILDTYPE_HHT) { data.m_ths.m_strSKU = pbe.m_package.m_DB_strSKU; data.m_ths.m_lLCID = pbe.m_package.m_DB_lLCID; data.m_strDisplayName = pbe.m_package.m_DB_strDisplayName; data.m_strProductID = L"Windows_XP"; data.m_strVersion = L"1.0.0.0"; }
if(FAILED(hr = itFile->UpdateSignature())) { l_FileLog.LogRecord( L"%08x: Can't locate '%s'\n", hr, strFileSrc.c_str() );
__HCP_FUNC_LEAVE; }
if(MPC::GetLastModifiedDate( itFile->m_strFileLocal ) > dFile_SetupImage) fNew = true; } }
if(fNew) { l_FileLog.LogRecord( L"Create setup image '%s'", strFullPath.c_str() );
//
// Create the output cabinet.
//
if(FAILED(hr = pkg.Save())) { l_FileLog.LogRecord( L"%08x: Can't create output file '%s'\n", strFullPath.c_str() );
__HCP_FUNC_LEAVE; } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
l_FileLog.LogRecord( L"\nCOMPILE - done\n" L"=================\n\n" );
__HCP_FUNC_EXIT(hr); }
static HRESULT List( /*[in]*/ LPCWSTR szInput ) { __HCP_FUNC_ENTRY( "List" );
HRESULT hr; Installer::Package pkg;
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init( szInput )); __MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Load());
{ Installer::Iter itBegin = pkg.GetBegin(); Installer::Iter itEnd = pkg.GetEnd ();
for(;itBegin != itEnd; itBegin++) { wprintf( L"%s -> %s\n", itBegin->m_strFileInner.c_str(), itBegin->m_strFileLocation.c_str() ); } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT Extract( /*[in]*/ LPCWSTR szInput , /*[in]*/ LPCWSTR szFile ) { __HCP_FUNC_ENTRY( "Extract" );
HRESULT hr; Installer::Package pkg;
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init( szInput )); __MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Load());
{ Installer::Iter itBegin = pkg.GetBegin(); Installer::Iter itEnd = pkg.GetEnd ();
for(;itBegin != itEnd; itBegin++) { if(!MPC::StrICmp( itBegin->m_strFileInner, szFile )) { itBegin->m_strFileLocal = szFile; // Extract the file in the current directory.
__MPC_EXIT_IF_METHOD_FAILS(hr, itBegin->Extract( szInput )); break; } } }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT Install( /*[in]*/ LPCWSTR szInput ) { __HCP_FUNC_ENTRY( "Install" );
HRESULT hr; Installer::Package pkg;
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init( szInput )); __MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Install());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
static HRESULT Unpack( /*[in]*/ LPCWSTR szInput , /*[in]*/ LPCWSTR szDir ) { __HCP_FUNC_ENTRY( "Unpack" );
HRESULT hr; Installer::Package pkg;
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init( szInput ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Unpack( szDir ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
static HRESULT Pack( /*[in]*/ LPCWSTR szDir , /*[in]*/ LPCWSTR szOutput ) { __HCP_FUNC_ENTRY( "Pack" );
HRESULT hr; Installer::Package pkg;
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Init( szOutput ));
__MPC_EXIT_IF_METHOD_FAILS(hr, pkg.Pack( szDir ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
static HRESULT ProcessArguments( int argc , LPCWSTR argv[] ) { __HCP_FUNC_ENTRY( "ProcessArguments" );
HRESULT hr;
argv++; argc--;
while(argc-->0) { LPCWSTR szArg = *argv++; int adv = -1;
if(szArg[0] == '-' || szArg[0] == '/' ) { szArg++;
if(argc >= 1) { LPCWSTR szArg2 = argv[0];
if(!_wcsicmp( szArg, L"ROOT" )) { l_szRoot = szArg2 ; adv = 1; } if(!_wcsicmp( szArg, L"LOG" )) { l_szLog = szArg2 ; adv = 1; } if(!_wcsicmp( szArg, L"DBLOG" )) { l_szDBLog = szArg2 ; adv = 1; } if(!_wcsicmp( szArg, L"MAXELEMENTS" )) { l_lMaxElements = _wtol( szArg2 ); adv = 1; } } } else { { MPC::wstring strLog;
GetLogFile( strLog );
l_FileLog.SetLocation( strLog.c_str() ); }
if(!_wcsicmp( szArg, L"BINPLACE" ) && argc >= 4) // <sku file> <setup image file> <root directory> <object directory>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, Binplace( argv[0], argv[1], argv[2], argv[3] )); adv = 4; } else if(!_wcsicmp( szArg, L"COMPILE" ) && argc >= 2) // <root directory> <sku>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, Compile( argv[0], argv[1] )); adv = 2; } else if(!_wcsicmp( szArg, L"LIST" ) && argc >= 1) // <input cabinet>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, List( argv[0] )); adv = 2; } else if(!_wcsicmp( szArg, L"EXTRACT" ) && argc >= 2) // <input cabinet> <file>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, Extract( argv[0], argv[1] )); adv = 2; } else if(!_wcsicmp( szArg, L"INSTALL" ) && argc >= 1) // <input cabinet>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, Install( argv[0] )); adv = 1; } else if(!_wcsicmp( szArg, L"UNPACK" ) && argc >= 2) // <input cabinet> <directory>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, Unpack( argv[0], argv[1] )); adv = 2; } else if(!_wcsicmp( szArg, L"PACK" ) && argc >= 2) // <directory> <output cabinet>
{ __MPC_EXIT_IF_METHOD_FAILS(hr, Pack( argv[0], argv[1] )); adv = 2; } }
if(adv == -1) { Usage(); __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); }
argv += adv; argc -= adv; }
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
int __cdecl wmain( int argc , LPCWSTR argv[] ) { HRESULT hr;
//DebugBreak();
//
// We need to be a single-threaded application, because we are hosting script engines and
// script engines don't like to be called from different threads...
//
if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ))) { if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL , -1 , // We don't care which authentication service we use.
NULL , NULL , RPC_C_AUTHN_LEVEL_CONNECT, // We want to identify the callers.
RPC_C_IMP_LEVEL_DELEGATE , // We want to be able to forward the caller's identity.
NULL , EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
NULL ))) { __MPC_TRACE_INIT();
//
// Process arguments.
//
try { hr = ProcessArguments( argc, argv ); } catch(...) { hr = E_FAIL; }
__MPC_TRACE_TERM(); }
::CoUninitialize(); }
return FAILED(hr) ? 10 : 0; }
|