//////////////////////////////////////////////////////////////////////////////////// // // File: read.cpp // // History: 16-Nov-00 markder Created. // 15-Jan-02 jdoherty Modified code to add ID to additional tags. // // Desc: This file contains all code needed to manipulate the MSXML // COM object, walk the document object model (DOM) for an XML // file, and populate the SdbDatabase internal C++ object. // //////////////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "xml.h" #include "make.h" #include "typeinfo.h" typedef struct tagAttrStringTableEntry { LPCTSTR pszName; DWORD dwValue; } ATTRSTRINGTABLEENTRY, *PATTRSTRINGTABLEENTRY; ATTRSTRINGTABLEENTRY g_rgStringSeverity[] = { { _T("HARDBLOCK" ), SDB_APPHELP_HARDBLOCK}, { _T("MINORPROBLEM"), SDB_APPHELP_MINORPROBLEM}, { _T("NOBLOCK" ), SDB_APPHELP_NOBLOCK}, { _T("REINSTALL" ), SDB_APPHELP_REINSTALL}, { _T("SHIM" ), SDB_APPHELP_SHIM}, { _T("VERSIONSUB" ), SDB_APPHELP_VERSIONSUB}, { _T("NONE" ), SDB_APPHELP_NONE} }; ATTRSTRINGTABLEENTRY g_rgStringModuleType[] = { { _T("NONE"), MT_UNKNOWN_MODULE}, { _T("UNKNOWN"), MT_UNKNOWN_MODULE}, { _T("WIN16"), MT_W16_MODULE}, { _T("WIN32"), MT_W32_MODULE}, { _T("DOS"), MT_DOS_MODULE}, }; ATTRSTRINGTABLEENTRY g_rgStringYesNo[] = { { _T("YES"), TRUE}, { _T("NO"), FALSE} }; ATTRSTRINGTABLEENTRY g_rgStringDataType[] = { { _T("DWORD"), eValueDWORD}, { _T("QWORD"), eValueQWORD}, { _T("STRING"), eValueString}, { _T("BINARY"), eValueBinary}, { _T("NONE"), eValueNone} }; ATTRSTRINGTABLEENTRY g_rgStringOSSKUType[] = { { _T("PER"), OS_SKU_PER}, { _T("PRO"), OS_SKU_PRO}, { _T("SRV"), OS_SKU_SRV}, { _T("ADS"), OS_SKU_ADS}, { _T("DTC"), OS_SKU_DTC}, { _T("BLA"), OS_SKU_BLA}, { _T("TAB"), OS_SKU_TAB}, { _T("MED"), OS_SKU_MED}, }; ATTRSTRINGTABLEENTRY g_rgStringOSPlatform[] = { { _T("I386"), OS_PLATFORM_I386}, { _T("IA64"), OS_PLATFORM_IA64} }; ATTRSTRINGTABLEENTRY g_rgStringRuntimePlatformType[] = { { _T("X86"), PROCESSOR_ARCHITECTURE_INTEL}, // x86 { _T("IA64"), PROCESSOR_ARCHITECTURE_IA64}, // ia64 { _T("AMD64"), PROCESSOR_ARCHITECTURE_AMD64}, // amd64 { _T("IA3264"), PROCESSOR_ARCHITECTURE_IA32_ON_WIN64} // this means running in wow on ia64 }; ATTRSTRINGTABLEENTRY g_rgStringFilter[] = { { _T("FIX"), SDB_FILTER_FIX}, { _T("APPHELP"), SDB_FILTER_APPHELP}, { _T("MSI"), SDB_FILTER_MSI}, { _T("DRIVER"), SDB_FILTER_DRIVER}, { _T("NTCOMPAT"), SDB_FILTER_NTCOMPAT}, { _T("CUSTOM"), SDB_FILTER_INCLUDE_ALL} }; ATTRSTRINGTABLEENTRY g_rgStringOutputType[] = { { _T("SDB"), SDB_OUTPUT_TYPE_SDB}, { _T("HTMLHELP"), SDB_OUTPUT_TYPE_HTMLHELP}, { _T("MIGDB_INX"), SDB_OUTPUT_TYPE_MIGDB_INX}, { _T("MIGDB_TXT"), SDB_OUTPUT_TYPE_MIGDB_TXT}, { _T("WIN2K_REGISTRY"), SDB_OUTPUT_TYPE_WIN2K_REGISTRY}, { _T("REDIR_MAP"), SDB_OUTPUT_TYPE_REDIR_MAP}, { _T("NTCOMPAT_INF"), SDB_OUTPUT_TYPE_NTCOMPAT_INF}, { _T("NTCOMPAT_MESSAGE_INF"), SDB_OUTPUT_TYPE_NTCOMPAT_MESSAGE_INF}, { _T("APPHELP_REPORT"), SDB_OUTPUT_TYPE_APPHELP_REPORT} }; ATTRSTRINGTABLEENTRY g_rgStringMatchModeType[] = { { _T("NORMAL"), MATCHMODE_NORMAL_SHIMDBC }, { _T("EXCLUSIVE"), MATCHMODE_EXCLUSIVE_SHIMDBC }, { _T("ADDITIVE"), MATCHMODE_ADDITIVE_SHIMDBC } }; LPCTSTR EncodeStringAttribute( DWORD dwValue, PATTRSTRINGTABLEENTRY pTable, int nSize) { static LPCTSTR pszUnknown = _T("UNKNOWN"); int i; for (i = 0; i < nSize; ++i, ++pTable) { if (dwValue == pTable->dwValue) { return(pTable->pszName); } } return pszUnknown; } BOOL DecodeStringAttribute( LPCTSTR lpszAttribute, PATTRSTRINGTABLEENTRY pTable, int nSize, DWORD* pdwValue) { int i; // // Find the indicator and return the flag // for (i = 0; i < nSize; ++i, ++pTable) { if (0 == _tcsicmp(lpszAttribute, pTable->pszName)) { if (NULL != pdwValue) { *pdwValue = pTable->dwValue; } break; } } return i < nSize; } LPCTSTR SeverityIndicatorToStr(SdbAppHelpType Severity) { return(EncodeStringAttribute((DWORD)Severity, g_rgStringSeverity, ARRAYSIZE(g_rgStringSeverity))); } LPCTSTR ModuleTypeIndicatorToStr(DWORD ModuleType) { return(EncodeStringAttribute(ModuleType, g_rgStringModuleType, ARRAYSIZE(g_rgStringModuleType))); } #define GetSeverityIndicator(lpszSeverity, pSeverity) \ DecodeStringAttribute(lpszSeverity, g_rgStringSeverity, ARRAYSIZE(g_rgStringSeverity), (DWORD*)pSeverity) #define GetModuleTypeIndicator(lpszModuleType, pModuleType) \ DecodeStringAttribute(lpszModuleType, g_rgStringModuleType, ARRAYSIZE(g_rgStringModuleType), pModuleType) #define GetVersionSubIndicator(lpszVersionSub, pVersionSub) \ DecodeStringAttribute(lpszVersionSub, g_rgStringVersionSub, ARRAYSIZE(g_rgStringVersionSub), pVersionSub) #define GetYesNoIndicator(lpszYesNo, pYesNo) \ DecodeStringAttribute(lpszYesNo, g_rgStringYesNo, ARRAYSIZE(g_rgStringYesNo), pYesNo) #define GetDataTypeIndicator(lpszDataType, pDataType) \ DecodeStringAttribute(lpszDataType, g_rgStringDataType, ARRAYSIZE(g_rgStringDataType), pDataType) DWORD GetOSSKUType(LPCTSTR szOSSKUType) { DWORD dwReturn = OS_SKU_NONE; DecodeStringAttribute(szOSSKUType, g_rgStringOSSKUType, ARRAYSIZE(g_rgStringOSSKUType), &dwReturn); return dwReturn; } DWORD GetOSPlatform(LPCTSTR szOSPlatform) { DWORD dwReturn = OS_PLATFORM_NONE; DecodeStringAttribute(szOSPlatform, g_rgStringOSPlatform, ARRAYSIZE(g_rgStringOSPlatform), &dwReturn); return dwReturn; } DWORD GetRuntimePlatformType(LPCTSTR szPlatformType) { DWORD dwReturn = PROCESSOR_ARCHITECTURE_UNKNOWN; DecodeStringAttribute(szPlatformType, g_rgStringRuntimePlatformType, ARRAYSIZE(g_rgStringRuntimePlatformType), &dwReturn); return dwReturn; } DWORD GetFilter(LPCTSTR szFilter) { DWORD dwReturn = SDB_FILTER_EXCLUDE_ALL; CString csFilter(szFilter); CString csFilterBit; DWORD dwFilterBit = 0; long i; for (i = 0; i <= csFilter.GetLength(); i++) { switch (csFilter.GetAt(i)) { case _T(' '): break; case _T('|'): case _T('\0'): DecodeStringAttribute(csFilterBit, g_rgStringFilter, ARRAYSIZE(g_rgStringFilter), &dwFilterBit); dwReturn |= dwFilterBit; csFilterBit.Empty(); break; default: csFilterBit += csFilter.GetAt(i); break; } } return dwReturn; } SdbOutputType GetOutputType(LPCTSTR szOutputType) { DWORD dwReturn = SDB_OUTPUT_TYPE_UNKNOWN; DecodeStringAttribute(szOutputType, g_rgStringOutputType, ARRAYSIZE(g_rgStringOutputType), &dwReturn); return (SdbOutputType) dwReturn; } ////////////////////////////////////////////////////////////////////////////////////// // // ProcureGuidIDAttribute // // retrieve Guid "ID" attribute for a given node, possibly update the source and // generate the attribute if it was not found // BOOL ProcureGuidIDAttribute( SdbDatabase* pDB, IXMLDOMNode* pNode, GUID* pGuid, CString* pcsGUID ) { CString csID; BOOL bSuccess = FALSE; if (!GetAttribute(_T("ID"), pNode, &csID)) { if (!GenerateIDAttribute(pNode, &csID, pGuid)) { SDBERROR_FORMAT((_T("Error generating ID attribute for the node\n%s\n"), GetXML(pNode))); goto eh; } pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE; } else { if (!GUIDFromString(csID, pGuid)) { // // This is the case when we cannot parse the guid and it appears to be // an invalid guid. // SDBERROR_FORMAT((_T("ID attribute is not a valid GUID\n%s\n"), csID)); goto eh; } } if (pcsGUID != NULL) { *pcsGUID = csID; } bSuccess = TRUE; eh: return bSuccess; } //////////////////////////////////////////////////////////////////////////////////// // // Func: GetNextSequentialID // // Desc: Determines the next available sequential to be generated. // DWORD SdbDatabase::GetNextSequentialID(CString csType) { CString csMaxID, csID; IXMLDOMNodePtr cpXMLAppHelp; DWORD dwMaxID = 0; DWORD dwMaxReportedID = 0; DWORD dwMaxEmpiricalID = 0; XMLNodeList XQL; long i; // // Determine largest ID // if (GetAttribute(_T("MAX_") + csType, m_cpCurrentDatabaseNode, &csMaxID)) { dwMaxReportedID = _ttol(csMaxID); } DWORD dwID = 0; if (!XQL.Query(m_cpCurrentDatabaseNode, _T("//@") + csType)) { SDBERROR_PROPOGATE(); goto eh; } for (i = 0; i < XQL.GetSize(); i++) { if (!XQL.GetItem(i, &cpXMLAppHelp)) { SDBERROR_PROPOGATE(); goto eh; } csID = GetText(cpXMLAppHelp); if (csID.GetLength()) { dwID = _ttol(csID); if (dwID > dwMaxEmpiricalID) { dwMaxEmpiricalID = dwID; } } cpXMLAppHelp.Release(); } if (dwMaxEmpiricalID > dwMaxReportedID) { dwMaxID = dwMaxEmpiricalID; } else { dwMaxID = dwMaxReportedID; } dwMaxID++; csMaxID.Format(_T("%d"), dwMaxID); if (!AddAttribute(m_cpCurrentDatabaseNode, _T("MAX_") + csType, csMaxID)) { } m_pCurrentInputFile->m_bSourceUpdated = TRUE; eh: return dwMaxID; } //////////////////////////////////////////////////////////////////////////////////// // // Func: ReadDatabase // // Desc: Opens an XML file and calls read on the database object. // BOOL ReadDatabase( SdbInputFile* pInputFile, SdbDatabase* pDatabase) { BOOL bSuccess = FALSE; IXMLDOMNodePtr cpRootNode; IXMLDOMNodePtr cpDatabase; XMLNodeList XQL; if (!OpenXML(pInputFile->m_csName, &cpRootNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetChild(_T("DATABASE"), cpRootNode, &cpDatabase)) { SDBERROR(_T(" object not found")); goto eh; } pDatabase->m_cpCurrentDatabaseNode = cpDatabase; if (!pDatabase->ReadFromXML(cpDatabase, pDatabase)) { SDBERROR_PROPOGATE(); goto eh; } if (pInputFile->m_bSourceUpdated) { // // We need to modify original XML file // if (!SaveXMLFile(pInputFile->m_csName, cpDatabase)) { SDBERROR_PROPOGATE(); goto eh; } } bSuccess = TRUE; eh: pDatabase->m_cpCurrentDatabaseNode = NULL; return bSuccess; } //////////////////////////////////////////////////////////////////////////////////// // // Func: ReadCallers // // Desc: Reads in all and child tags on node pNode and // adds them as SdbCaller objects to the array pointed to by prgCallers. // BOOL ReadCallers( SdbArray* prgCallers, SdbDatabase* pDB, IXMLDOMNode* pNode) { USES_CONVERSION; BOOL bSuccess = FALSE; long nIndex = 0; long nListLength = 0; IXMLDOMNodePtr cpCallerNode; XMLNodeList NodeList; SdbCaller* pSdbCaller = NULL; CString csNodeName, csTemp; if (!NodeList.GetChildNodes(pNode)) { // // No child nodes -- that's fine, return success. // bSuccess = TRUE; goto eh; } for (nIndex = 0; nIndex < NodeList.GetSize(); nIndex++) { if (!NodeList.GetItem(nIndex, &cpCallerNode)) { SDBERROR(_T("Could not retrieve INCLUDE/EXCLUDE item")); goto eh; } if (GetNodeName(cpCallerNode) == _T("INCLUDE") || GetNodeName(cpCallerNode) == _T("EXCLUDE")) { pSdbCaller = new SdbCaller(); if (pSdbCaller == NULL) { SDBERROR(_T("Error allocating SdbCaller object")); goto eh; } if (!pSdbCaller->ReadFromXML(cpCallerNode, pDB)) { SDBERROR_PROPOGATE(); delete pSdbCaller; pSdbCaller = NULL; goto eh; } // // Add in reverse order to help the Shim engine's logic // building code // prgCallers->InsertAt(0, pSdbCaller); pSdbCaller = NULL; } cpCallerNode.Release(); } bSuccess = TRUE; eh: return bSuccess; } BOOL ReadLocalizedNames( SdbArray* prgNames, CString csTag, SdbDatabase* pDB, IXMLDOMNode* pNode) { BOOL bSuccess = FALSE; IXMLDOMNodePtr cpTag; XMLNodeList XQL; CString csTemp, csLangID, csName; SdbLocalizedString* pLocString = NULL; long i; if (!XQL.Query(pNode, csTag)) { SDBERROR_PROPOGATE(); goto eh; } for (i = 0; i < XQL.GetSize(); i++) { CString csID; GUID ID = GUID_NULL; if (!XQL.GetItem(i, &cpTag)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("LANGID"), cpTag, &csLangID)) { if (!pDB->m_csCurrentLangID.GetLength()) { SDBERROR_FORMAT(( _T("LOCALIZED_NAME tag requires LANGID attribute if there is no LANGID on the DATABASE node\n%s\n"), GetXML(cpTag))); goto eh; } csLangID = pDB->m_csCurrentLangID; } if (!ProcureGuidIDAttribute(pDB, cpTag, &ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("NAME"), cpTag, &csName)) { SDBERROR_FORMAT(( _T("LOCALIZED_NAME tag requires NAME attribute:\n%s\n"), GetXML(cpTag))); goto eh; } pLocString = new SdbLocalizedString(); pLocString->m_csName = csName; pLocString->m_csLangID = csLangID; pLocString->m_csValue = GetInnerXML(cpTag); prgNames->Add(pLocString); } bSuccess = TRUE; eh: return bSuccess; } BOOL SdbDatabase::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; long i; long nListCount = 0; IXMLDOMNodePtr cpXMLLibrary; IXMLDOMNodePtr cpXMLAppHelp; IXMLDOMNodePtr cpXMLA; IXMLDOMNodePtr cpXMLHTMLHELPTemplate; IXMLDOMNodePtr cpXMLHTMLHELPFirstScreen; CString csHTMLHELPID, csXQL, csHistoryClause; CString csID, csRedirID, csRedirURL, csOSVersion; CString csTemplateName; DWORD dwHTMLHELPID = 0; XMLNodeList XQL; SdbLocalizedString* pRedir = NULL; SdbLocalizedString* pHTMLHelpTemplate = NULL; SdbLocalizedString* pHTMLHelpFirstScreen = NULL; // // Read the name of the database // ReadName(pNode, &m_csName); // // Read the LangID for this database file // m_csCurrentLangID = _T("---"); GetAttribute(_T("LANGID"), pNode, &m_csCurrentLangID); // // Read the default ID // if (!GetAttribute(_T("ID"), pNode, &csID)) { // // Guid was not found. We need to generate it. // if (!GenerateIDAttribute(pNode, &csID, &m_ID)) { SDBERROR_FORMAT((_T("Error generating ID attribute for the node\n%s\n"), GetXML(pNode))); goto eh; } pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE; } else if (!GUIDFromString(csID, &m_ID)) { // // This is the case when we cannot parse the guid and it appears to be // an invalid guid. // SDBERROR_FORMAT((_T("ID attribute is not a valid GUID\n%s\n"), csID)); goto eh; } // // Add REDIR_IDs to tags if necessary // if (!XQL.Query(pNode, _T("//A"))) { SDBERROR_PROPOGATE(); goto eh; } for (i = 0; i < XQL.GetSize(); i++) { if (!XQL.GetItem(i, &cpXMLA)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("REDIR_ID"), cpXMLA, &csRedirID)) { // // Not there, generate it. // csRedirID.Format(_T("%d"), GetNextSequentialID(_T("REDIR_ID"))); if (!AddAttribute(cpXMLA, _T("REDIR_ID"), csRedirID)) { SDBERROR_PROPOGATE(); goto eh; } } if (!GetAttribute(_T("HREF"), cpXMLA, &csRedirURL)) { // // No HREF attribute. Take the link from the display name. // csRedirURL = GetText(cpXMLA); } pRedir = (SdbLocalizedString *) m_rgRedirs.LookupName(csRedirID, m_csCurrentLangID); if (pRedir) { SDBERROR_FORMAT((_T("Non-unique REDIR_ID:\n%s\n"), GetXML(cpXMLA))); goto eh; } pRedir = new SdbLocalizedString(); pRedir->m_csName = csRedirID; pRedir->m_csLangID = m_csCurrentLangID; pRedir->m_csValue = csRedirURL; m_rgRedirs.Add(pRedir); cpXMLA = NULL; } // // Read HTMLHELP_TEMPLATE // if (!XQL.Query(pNode, _T("HTMLHELP_TEMPLATE"))) { SDBERROR_PROPOGATE(); goto eh; } for (i = 0; i < XQL.GetSize(); i++) { if (!XQL.GetItem(i, &cpXMLHTMLHELPTemplate)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("NAME"), cpXMLHTMLHELPTemplate, &csTemplateName)) { SDBERROR_FORMAT((_T("HTMLHELP_TEMPLATE requires NAME attribute:\n%s\n"), GetXML(cpXMLHTMLHELPTemplate))); goto eh; } pHTMLHelpTemplate = new SdbLocalizedString(); pHTMLHelpTemplate->m_csName = csTemplateName; pHTMLHelpTemplate->m_csLangID = m_csCurrentLangID; pHTMLHelpTemplate->m_csValue = GetInnerXML(cpXMLHTMLHELPTemplate); m_rgHTMLHelpTemplates.Add(pHTMLHelpTemplate); } // // Read HTMLHELP_FIRST_SCREEN // if (!XQL.Query(pNode, _T("HTMLHELP_FIRST_SCREEN"))) { SDBERROR_PROPOGATE(); goto eh; } if (XQL.GetSize() > 1) { SDBERROR(_T("More than one HTMLHELP_FIRST_SCREEN tags found:\n%s\n")); goto eh; } if (XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpXMLHTMLHELPFirstScreen)) { SDBERROR_PROPOGATE(); goto eh; } pHTMLHelpFirstScreen = new SdbLocalizedString(); pHTMLHelpFirstScreen->m_csName = _T("HTMLHELP_FIRST_SCREEN"); pHTMLHelpFirstScreen->m_csLangID = m_csCurrentLangID; pHTMLHelpFirstScreen->m_csValue = GetInnerXML(cpXMLHTMLHELPFirstScreen); m_rgHTMLHelpFirstScreens.Add(pHTMLHelpFirstScreen); } // // Read Library // if (!XQL.Query(pNode, _T("LIBRARY"))) { SDBERROR_PROPOGATE(); goto eh; } for (i = 0; i < XQL.GetSize(); i++) { if (!XQL.GetItem(i, &cpXMLLibrary)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_Library.ReadFromXML(cpXMLLibrary, this)) { SDBERROR_PROPOGATE(); goto eh; } cpXMLLibrary.Release(); } // // Action tags // if (!m_rgAction.ReadFromXML(_T("ACTION"), pDB, pNode, NULL)) { SDBERROR_PROPOGATE(); goto eh; } // // Construct XQL from m_prgHistoryKeywords // if (m_pCurrentMakefile->m_rgHistoryKeywords.GetSize() > 0) { for (i = 0; i < m_pCurrentMakefile->m_rgHistoryKeywords.GetSize(); i++) { if (i > 0) { csHistoryClause += _T(" or "); } csHistoryClause = _T("KEYWORD/@NAME = '") + m_pCurrentMakefile->m_rgHistoryKeywords.GetAt(i) + _T("'"); } csXQL = _T("APP[") + csHistoryClause + _T("]"); csXQL += _T(" | DRIVER[") + csHistoryClause + _T("]"); } else { csXQL = _T("APP | DRIVER"); } if (!m_rgApps.ReadFromXML(csXQL, pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = this; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbLibrary::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; if (!m_rgFiles.ReadFromXML(_T(".//FILE"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgShims.ReadFromXML(_T("SHIM"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgPatches.ReadFromXML(_T("PATCH"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgFlags.ReadFromXML(_T("FLAG"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgLayers.ReadFromXML(_T("LAYER"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgMsiTransforms.ReadFromXML(_T("MSI_TRANSFORM"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!pDB->m_rgContactInfo.ReadFromXML(_T("CONTACT_INFO"), pDB, pNode, NULL, FALSE, _T("VENDOR"))) { SDBERROR_PROPOGATE(); goto eh; } if (!pDB->m_rgMessageTemplates.ReadFromXML(_T("TEMPLATE"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!pDB->m_rgMessages.ReadFromXML(_T("MESSAGE"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!ReadCallers(&m_rgCallers, pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!ReadLocalizedNames( &(pDB->m_rgLocalizedAppNames), _T("LOCALIZED_APP_NAME"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!ReadLocalizedNames( &(pDB->m_rgLocalizedVendorNames), _T("LOCALIZED_VENDOR_NAME"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbFile::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csFilter; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (GetAttribute(_T("FILTER"), pNode, &csFilter)) { m_dwFilter = GetFilter(csFilter) | SDB_FILTER_OVERRIDE; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbShim::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; long i; CString csTemp, csID; IXMLDOMNodePtr cpDesc; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("FILE"), pNode, &m_csDllFile) && g_bStrict) { SDBERROR_FORMAT((_T(" requires FILE attribute:\n%s\n\n"), GetXML(pNode))); goto eh; } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) { m_csDesc = GetText(cpDesc); } csTemp.Empty(); if (GetAttribute(_T("PURPOSE"), pNode, &csTemp)) { if (csTemp == _T("GENERAL")) { m_Purpose = SDB_PURPOSE_GENERAL; } else { m_Purpose = SDB_PURPOSE_SPECIFIC; } } // // Check what OS PLATFORM this entry is meant for // csTemp.Empty(); if (GetAttribute(_T("OS_PLATFORM"), pNode, &csTemp)) { // // Decode it. This string is a semi-colon delimited set // of OS PLATFORMs. // if (!DecodeString(csTemp, &m_dwOSPlatform, GetOSPlatform)) { SDBERROR_FORMAT((_T("OS_PLATFORM attribute syntax error: %s"), csTemp)); goto eh; } } csTemp.Empty(); if (GetAttribute(_T("APPLY_ALL_SHIMS"), pNode, &csTemp)) { if (csTemp == _T("YES")) { m_bApplyAllShims = TRUE; } } if (!ReadCallers(&m_rgCallers, pDB, pNode)) { SDBERROR(_T("Could not read INCLUDE/EXCLUDE info of tag")); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbShimRef::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } m_pShim = (SdbShim *) pDB->m_Library.m_rgShims.LookupName(m_csName); if (m_pShim == NULL && g_bStrict) { SDBERROR_FORMAT((_T("SHIM \"%s\" not found in library:\n%s\n\n"), m_csName, GetXML(pNode))); goto eh; } GetAttribute(_T("COMMAND_LINE"), pNode, &m_csCommandLine); if (!ReadCallers(&m_rgCallers, pDB, pNode)) { SDBERROR(_T("Could not read INCLUDE/EXCLUDE info of tag")); goto eh; } // finally, read all the child data elements if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbPatch::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; PATCHOP PatchOp; PATCHWRITEDATA PatchWriteData; PATCHMATCHDATA PatchMatchData; XMLNodeList NodeList; IXMLDOMNodePtr cpOpNode; long i; CString csNodeName, csError; CString csModule, csOffset; CString csID; DWORD dwByteCount = 0; BYTE* pBytes = NULL; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } // // NOTE: We don't write the patch description in the binary database // so there's no point reading it either. // NodeList.GetChildNodes(pNode); for (i = 0; i < NodeList.GetSize(); i++) { if (!NodeList.GetItem(i, &cpOpNode)) { SDBERROR(_T("Could not retrieve PATCH instructions")); goto eh; } csNodeName = GetNodeName(cpOpNode); if (csNodeName == _T("MATCH_BYTES")) { if (!GetAttribute(_T("MODULE"), cpOpNode, &csModule)) { csError.Format(_T(" requires MODULE attribute:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } if (!GetAttribute(_T("OFFSET"), cpOpNode, &csOffset)) { csError.Format(_T(" requires OFFSET attribute:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } PatchOp.dwOpcode = PMAT; PatchMatchData.rva.address = StringToDword(csOffset); if (csModule.GetLength() >= sizeof(PatchMatchData.rva.moduleName)) { csError.Format(_T("MODULE attribute greater than %d characters:\n%s\n"), sizeof(PatchMatchData.rva.moduleName) - 1, GetXML(cpOpNode)); SDBERROR(csError); goto eh; } dwByteCount = GetByteStringSize(GetText(cpOpNode)); if (dwByteCount == 0xFFFFFFFF) { csError.Format(_T("Bad byte string for patch operation:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } PatchMatchData.dwSizeData = dwByteCount; if (csModule == _T("%EXE%")) { PatchMatchData.rva.moduleName[0] = _T('\0'); } else { StringCchCopy(PatchMatchData.rva.moduleName, ARRAYSIZE(PatchMatchData.rva.moduleName), csModule); } pBytes = (BYTE*) new BYTE[dwByteCount]; if (pBytes == NULL) { SDBERROR(_T("Error allocating memory for block.")); goto eh; } if (GetBytesFromString(GetText(cpOpNode), pBytes, dwByteCount) == 0xFFFFFFFF) { csError.Format(_T("Bad byte string for patch operation:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } PatchOp.dwNextOpcode = sizeof(DWORD) * 3 + sizeof(RELATIVE_MODULE_ADDRESS) + dwByteCount; AddBlobBytes(&PatchOp, sizeof(DWORD) * 2); AddBlobBytes(&PatchMatchData, sizeof(DWORD) + sizeof(RELATIVE_MODULE_ADDRESS)); AddBlobBytes(pBytes, dwByteCount); delete pBytes; pBytes = NULL; } else if (csNodeName == _T("WRITE_BYTES")) { if (!GetAttribute(_T("MODULE"), cpOpNode, &csModule)) { csError.Format(_T(" requires MODULE attribute:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } if (!GetAttribute(_T("OFFSET"), cpOpNode, &csOffset)) { csError.Format(_T(" requires OFFSET attribute:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } PatchOp.dwOpcode = PWD; PatchWriteData.rva.address = StringToDword(csOffset); if (csModule.GetLength() >= sizeof(PatchWriteData.rva.moduleName)) { csError.Format(_T("MODULE attribute greater than %d characters:\n%s\n"), sizeof(PatchWriteData.rva.moduleName) - 1, GetXML(cpOpNode)); SDBERROR(csError); goto eh; } dwByteCount = GetByteStringSize(GetText(cpOpNode)); if (dwByteCount == 0xFFFFFFFF) { csError.Format(_T("Bad byte string for patch operation:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } PatchWriteData.dwSizeData = dwByteCount; if (csModule == _T("%EXE%")) { PatchWriteData.rva.moduleName[0] = _T('\0'); } else { StringCchCopy(PatchWriteData.rva.moduleName, ARRAYSIZE(PatchWriteData.rva.moduleName), csModule); } pBytes = (BYTE*) new BYTE[dwByteCount]; if (pBytes == NULL) { SDBERROR(_T("Error allocating memory for block.")); goto eh; } if (GetBytesFromString(GetText(cpOpNode), pBytes, dwByteCount) == 0xFFFFFFFF) { csError.Format(_T("Bad byte string for patch operation:\n%s\n"), GetXML(cpOpNode)); SDBERROR(csError); goto eh; } PatchOp.dwNextOpcode = sizeof(DWORD) * 3 + sizeof(RELATIVE_MODULE_ADDRESS) + dwByteCount; AddBlobBytes(&PatchOp, sizeof(DWORD) * 2); AddBlobBytes(&PatchWriteData, sizeof(DWORD) + sizeof(RELATIVE_MODULE_ADDRESS)); AddBlobBytes(pBytes, dwByteCount); delete [] pBytes; pBytes = NULL; } cpOpNode.Release(); } // // Add terminating NULL bytes // ZeroMemory(&PatchOp, sizeof(DWORD) * 2); AddBlobBytes(&PatchOp, sizeof(DWORD) * 2); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbLayer::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csID; CString csTemp; IXMLDOMNodePtr cpDesc; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) { m_csDesc = GetText(cpDesc); } // // Check what OS PLATFORM this entry is meant for // if (GetAttribute(_T("OS_PLATFORM"), pNode, &csTemp)) { // // Decode it. This string is a semi-colon delimited set // of OS PLATFORMs. // if (!DecodeString(csTemp, &m_dwOSPlatform, GetOSPlatform)) { SDBERROR_FORMAT((_T("OS_PLATFORM attribute syntax error: %s"), csTemp)); goto eh; } } if (!m_rgShimRefs.ReadFromXML(_T("SHIM"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgFlagRefs.ReadFromXML(_T("FLAG"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } GetAttribute(_T("DISPLAY_NAME"), pNode, &m_csDisplayName); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbLayerRef::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } m_pLayer = (SdbLayer*) pDB->m_Library.m_rgLayers.LookupName(m_csName); // // finally, read all the child data elements // if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbCaller::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csNodeName, csTemp; csNodeName = GetNodeName(pNode); if (csNodeName == _T("INCLUDE")) { m_CallerType = SDB_CALLER_INCLUDE; } else if (csNodeName == _T("EXCLUDE")) { m_CallerType = SDB_CALLER_EXCLUDE; } if (!GetAttribute(_T("MODULE"), pNode, &csTemp)) { SDBERROR_FORMAT((_T(" or requires MODULE attribute:\n%s\n"), GetXML(pNode))); goto eh; } // // Convert %EXE% keyword to $ for optimization // if (csTemp.CompareNoCase(_T("%EXE%")) == 0) { csTemp = _T("$"); } m_csModule = csTemp; m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbFlag::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csMask; CString csType; CString csTemp; CString csID; IXMLDOMNodePtr cpDesc; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) { m_csDesc = GetText(cpDesc); } if (!GetAttribute(_T("TYPE"), pNode, &csType)) { // // By default the apphacks are for kernel. // SDBERROR_FORMAT((_T(" requires TYPE attribute:\n%s\n"), GetXML(pNode))); goto eh; } csTemp.Empty(); if (GetAttribute(_T("PURPOSE"), pNode, &csTemp)) { if (csTemp == _T("GENERAL")) { m_Purpose = SDB_PURPOSE_GENERAL; } else { m_Purpose = SDB_PURPOSE_SPECIFIC; } } if (!SetType(csType)) { SDBERROR_FORMAT((_T(" bad TYPE attribute:\n%s\n"), GetXML(pNode))); goto eh; } if (!GetAttribute(_T("MASK"), pNode, &csMask)) { SDBERROR_FORMAT((_T(" requires MASK attribute:\n%s\n"), GetXML(pNode))); goto eh; } m_ullMask = StringToQword(csMask); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbFlagRef::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } m_pFlag = (SdbFlag *) pDB->m_Library.m_rgFlags.LookupName(m_csName); if (m_pFlag == NULL && g_bStrict) { SDBERROR_FORMAT((_T("SHIM \"%s\" not found in library:\n%s\n\n"), m_csName, GetXML(pNode))); goto eh; } // // see if we have cmd line, applicable mostly to ntvdm flags // GetAttribute(_T("COMMAND_LINE"), pNode, &m_csCommandLine); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbApp::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; XMLNodeList XQL; IXMLDOMNodePtr cpHistoryNode; IXMLDOMNodePtr cpAppHelpNode; SdbAppHelpRef* pAppHelpRef1 = NULL; SdbAppHelpRef* pAppHelpRef2 = NULL; long i, j; CString csTemp, csTemp2, csTemp3, csID; COleDateTime odtLastRevision, odtCandidate; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } GetAttribute(_T("VENDOR"), pNode, &m_csVendor); GetAttribute(_T("VENDOR"), pNode, &m_csVendorXML, TRUE); GetAttribute(_T("VERSION"), pNode, &m_csVersion); if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (!XQL.Query(pNode, _T("HISTORY"))) { SDBERROR_PROPOGATE(); goto eh; } // // Set the default modified date to 01/01/2000 // odtLastRevision.ParseDateTime(_T("01/01/2001"), 0, 0x0409); for (i = 0; i < XQL.GetSize(); i++) { if (!XQL.GetItem(i, &cpHistoryNode)) { SDBERROR_PROPOGATE(); goto eh; } if (GetAttribute(_T("DATE"), cpHistoryNode, &csTemp)) { // // Validate format. It's important that the date format is // consistent to provide easy text searches. // if (!(_istdigit(csTemp[0]) && _istdigit(csTemp[1]) && csTemp[2] == _T('/') && _istdigit(csTemp[3]) && _istdigit(csTemp[4]) && csTemp[5] == _T('/') && _istdigit(csTemp[6]) && _istdigit(csTemp[7]) && _istdigit(csTemp[8]) && _istdigit(csTemp[9]) && csTemp[10] == _T('\0'))) { SDBERROR_FORMAT((_T("HISTORY DATE is not in format MM/DD/YYYY: \"%s\"\nFor app: \"%s\""), csTemp, m_csName)); goto eh; } if (!odtCandidate.ParseDateTime(csTemp, 0, 0x0409)) { SDBERROR_FORMAT((_T("HISTORY DATE is not in format MM/DD/YYYY: \"%s\"\nFor app: \"%s\""), csTemp, m_csName)); goto eh; } if (odtCandidate > odtLastRevision) { odtLastRevision = odtCandidate; } } if (GetAttribute(_T("KEYWORDS"), cpHistoryNode, &csTemp)) { m_csKeywords += csTemp; m_csKeywords += _T(";"); } cpHistoryNode.Release(); } m_dtLastRevision = odtLastRevision.m_dt; // // Set m_pCurrentApp so that new SdbExe objects can grab their m_pApp pointer // pDB->m_pCurrentApp = this; // // Add the EXEs as in an "ordered" fashion // // SYS is the driver XML version of EXE // if (!m_rgExes.ReadFromXML(_T("EXE | SYS"), pDB, pNode, NULL, TRUE)) { SDBERROR_PROPOGATE(); goto eh; } // // Add the WIN9X_MIGRATION entries // if (!m_rgWin9xMigEntries.ReadFromXML(_T("WIN9X_MIGRATION"), pDB, pNode, NULL, FALSE, NULL)) { SDBERROR_PROPOGATE(); goto eh; } // // Add the WINNT_UPGRADE entries // if (!m_rgWinNTUpgradeEntries.ReadFromXML(_T("WINNT_UPGRADE"), pDB, pNode, NULL, FALSE, NULL)) { SDBERROR_PROPOGATE(); goto eh; } // // Read MSI_PACKAGE tags, owner is this one (hence the NULL), add them ordered // if (!m_rgMsiPackages.ReadFromXML(_T("MSI_PACKAGE"), pDB, pNode, NULL, TRUE)) { SDBERROR_PROPOGATE(); goto eh; } // // Run through the AppHelpRefs to make sure // they all have HTMLHELPIDs // for (i = 0; i < m_rgAppHelpRefs.GetSize(); i++) { pAppHelpRef1 = (SdbAppHelpRef *) m_rgAppHelpRefs[i]; if (pAppHelpRef1->m_cpNode) { if (!pAppHelpRef1->ReadFromXML(pAppHelpRef1->m_cpNode, pDB)) { SDBERROR_PROPOGATE(); goto eh; } pAppHelpRef1->m_cpNode = NULL; } } if (g_bStrict) { for (i = 0; i < m_rgAppHelpRefs.GetSize(); i++) { pAppHelpRef1 = (SdbAppHelpRef *) m_rgAppHelpRefs[i]; for (j = 0; j < m_rgAppHelpRefs.GetSize(); j++) { pAppHelpRef2 = (SdbAppHelpRef *) m_rgAppHelpRefs[j]; if (pAppHelpRef1->m_pAppHelp->m_csName != pAppHelpRef2->m_pAppHelp->m_csName && pAppHelpRef1->m_pAppHelp->m_csMessage == pAppHelpRef2->m_pAppHelp->m_csMessage && pAppHelpRef1->m_pAppHelp->m_Type == pAppHelpRef2->m_pAppHelp->m_Type && pAppHelpRef1->m_pAppHelp->m_bBlockUpgrade == pAppHelpRef2->m_pAppHelp->m_bBlockUpgrade && pAppHelpRef1->m_pAppHelp->m_csURL == pAppHelpRef2->m_pAppHelp->m_csURL) { SDBERROR_FORMAT((_T("Different HTMLHELPIDs for same :\n%s\n"), GetXML(pNode))); goto eh; } } } } // // Set m_dtLastRevision for important children. // for (i = 0; i < m_rgExes.GetSize(); i++) { ((SdbArrayElement *) m_rgExes.GetAt(i))->m_dtLastRevision = m_dtLastRevision; } for (i = 0; i < this->m_rgAppHelpRefs.GetSize(); i++) { ((SdbAppHelpRef *) m_rgAppHelpRefs.GetAt(i))->m_pAppHelp->m_dtLastRevision = m_dtLastRevision; } for (i = 0; i < m_rgMsiPackages.GetSize(); i++) { ((SdbArrayElement *) m_rgMsiPackages.GetAt(i))->m_dtLastRevision = m_dtLastRevision; } for (i = 0; i < m_rgWin9xMigEntries.GetSize(); i++) { ((SdbArrayElement *) m_rgWin9xMigEntries.GetAt(i))->m_dtLastRevision = m_dtLastRevision; } for (i = 0; i < m_rgWinNTUpgradeEntries.GetSize(); i++) { ((SdbArrayElement *) m_rgWinNTUpgradeEntries.GetAt(i))->m_dtLastRevision = m_dtLastRevision; } m_pDB = pDB; bSuccess = TRUE; eh: pDB->m_pCurrentApp = NULL; return bSuccess; } BOOL CheckExeID( SdbDatabase* pDB, SdbArrayElement* pElement, LPCTSTR lpszID ) { SdbArrayElement* pOtherExe = NULL; LPCTSTR pszName = NULL; LPCTSTR pszTag = NULL; if (pDB->m_mapExeIDtoExe.Lookup(lpszID, (PVOID&)pOtherExe)) { // // see what kind of an object we caught with this duplicate id // const type_info& TypeInfoObj = typeid(*pOtherExe); if (typeid(SdbMsiPackage) == TypeInfoObj) { pszName = ((SdbMsiPackage*)pOtherExe)->m_pApp->m_csName; pszTag = _T("\n\tAnd also within %s\"%s\">\r\n"), lpszID, pszName, pszTag, pElement->m_csName)); return FALSE; } pDB->m_mapExeIDtoExe.SetAt(lpszID, pElement); return TRUE; } BOOL SdbExe::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; long i; CString csID, csTemp; BOOL bGenerateWinNTUpgrade = FALSE; XMLNodeList XQL; IXMLDOMNodePtr cpSXS; IXMLDOMNodePtr cpMessage; SdbMatchingFile* pMFile = NULL; SdbData* pData = NULL; SdbData* pPolicy = NULL; SdbWinNTUpgrade* pNTUpg = NULL; VARIANT vType; VARIANT vValue; IXMLDOMDocumentPtr cpDocument; IXMLDOMNodePtr cpNewNode; IXMLDOMNodePtr cpXMLNSNode; IXMLDOMNodeListPtr cpNodeList; IXMLDOMNamedNodeMapPtr cpAttrs; VariantInit(&vType); VariantInit(&vValue); m_pApp = pDB->m_pCurrentApp; if (!GetAttribute(_T("NAME"), pNode, &m_csName)) { if (GetAttribute(_T("MODULE_NAME"), pNode, &m_csName)) { m_bMatchOnModule = TRUE; } else { SDBERROR_FORMAT((_T("NAME or MODULE_NAME attribute required:\n%s\n\n"), GetXML(pNode))); goto eh; } } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (g_bStrict) { if (!CheckExeID(pDB, this, csID)) { SDBERROR_PROPOGATE(); goto eh; } } // // Look for a match mode entry // if (GetAttribute(_T("MATCH_MODE"), pNode, &csTemp)) { if (!DecodeStringAttribute(csTemp, g_rgStringMatchModeType, ARRAYSIZE(g_rgStringMatchModeType), &m_dwMatchMode)) { // // try to decode using the hex (direct) format // if (!StringToMask(&m_dwMatchMode, csTemp)) { SDBERROR_FORMAT((_T("MATCH_MODE attribute is invalid\n%s\n"), GetXML(pNode))); goto eh; } } } if (GetAttribute(_T("RUNTIME_PLATFORM"), pNode, &csTemp)) { if (!DecodeRuntimePlatformString(csTemp, &m_dwRuntimePlatform)) { SDBERROR_FORMAT((_T("RUNTIME_PLATFORM no in recognized format: \"%s\"\n%s\n"), (LPCTSTR)csTemp, GetXML(pNode))); goto eh; } } GetAttribute(_T("OS_VERSION"), pNode, &m_csOSVersionSpec); // // Check what OS SKU this entry is meant for // if (GetAttribute(_T("OS_SKU"), pNode, &csTemp)) { // // Decode it. This string is a semi-colon delimited set // of OS SKUs. // if (!DecodeString(csTemp, &m_dwOSSKU, GetOSSKUType)) { SDBERROR_FORMAT((_T("OS_SKU attribute syntax error: %s"), csTemp)); goto eh; } } // // Check what OS PLATFORM this entry is meant for // if (GetAttribute(_T("OS_PLATFORM"), pNode, &csTemp)) { // // Decode it. This string is a semi-colon delimited set // of OS PLATFORMs. // if (!DecodeString(csTemp, &m_dwOSPlatform, GetOSPlatform)) { SDBERROR_FORMAT((_T("OS_PLATFORM attribute syntax error: %s"), csTemp)); goto eh; } } // // Add EXE as matching file // pMFile = new SdbMatchingFile(); if (pMFile == NULL) { SDBERROR(_T("Error allocating SdbMatchingFile object")); goto eh; } m_rgMatchingFiles.Add(pMFile, pDB); if (!pMFile->ReadFromXML(pNode, pDB)) { SDBERROR_PROPOGATE(); goto eh; } // // Change name to "*" -- that is the alias for the EXE. This is done // to allow matching on a wildcard executable name. // pMFile->m_csName = _T("*"); if (!m_rgMatchingFiles.ReadFromXML(_T("MATCHING_FILE"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgShimRefs.ReadFromXML(_T("SHIM"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgLayerRefs.ReadFromXML(_T("LAYER"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgPatches.ReadFromXML(_T("PATCH"), pDB, pNode, &(pDB->m_Library.m_rgPatches))) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgFlagRefs.ReadFromXML(_T("FLAG"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } // // Data tags // if (!m_rgData.ReadFromXML(_T("(DATA | DRIVER_POLICY)"), pDB, pNode, NULL)) { SDBERROR_PROPOGATE(); goto eh; } // // Driver database 'hack': We look for CRITICAL="NO" on the SYS tag // and add a Policy = 0x1 element if found. This is to help // readability. // // // Check if policy already exists // for (i = 0; i < m_rgData.GetSize(); i++) { pData = (SdbData *) m_rgData.GetAt(i); if (pData->m_csName.CompareNoCase(_T("Policy")) == 0) { pPolicy = pData; break; } } if (GetAttribute(_T("CRITICAL"), pNode, &csTemp)) { if (csTemp.CompareNoCase(_T("NO")) == 0) { if (pPolicy == NULL) { pPolicy = new SdbData; pPolicy->m_csName = _T("Policy"); pPolicy->SetValue(eValueDWORD, _T("0x0")); m_rgData.Add(pPolicy, pDB); } pPolicy->m_dwValue |= 1; } } if (GetAttribute(_T("USER_MODE_BLOCK"), pNode, &csTemp)) { if (csTemp.CompareNoCase(_T("NO")) == 0) { if (pPolicy == NULL) { pPolicy = new SdbData; pPolicy->m_csName = _T("Policy"); pPolicy->SetValue(eValueDWORD, _T("0x0")); m_rgData.Add(pPolicy, pDB); } pPolicy->m_dwValue |= 2; } } // // Action tags // if (!m_rgAction.ReadFromXML(_T("ACTION"), pDB, pNode, NULL)) { SDBERROR_PROPOGATE(); goto eh; } // // Read APPHELP refs // if (!XQL.Query(pNode, _T("APPHELP"))) { SDBERROR_PROPOGATE(); goto eh; } if (XQL.GetSize() > 1) { SDBERROR_FORMAT((_T("Multiple tags per not allowed\n%s\n"), GetXML(pNode))); goto eh; } if (XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpMessage)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_AppHelpRef.ReadFromXML(cpMessage, pDB)) { SDBERROR_PROPOGATE(); goto eh; } if (m_rgShimRefs.GetSize() == 0 && m_rgPatches.GetSize() == 0 && m_rgFlagRefs.GetSize() == 0 && m_rgLayerRefs.GetSize() == 0) { m_AppHelpRef.m_bApphelpOnly = TRUE; } // // entries automatically get an entry // if (GetNodeName(pNode) == _T("SYS")) { bGenerateWinNTUpgrade = TRUE; if (GetAttribute(_T("GENERATE_UPGRADE_REPORT_ENTRY"), pNode, &csTemp)) { if (0 == csTemp.CompareNoCase(_T("NO"))) { bGenerateWinNTUpgrade = FALSE; } } if (bGenerateWinNTUpgrade) { pNTUpg = new SdbWinNTUpgrade; pNTUpg->m_pDB = pDB; pNTUpg->m_pApp = pDB->m_pCurrentApp; if (!pNTUpg->m_AppHelpRef.ReadFromXML(cpMessage, pDB)) { SDBERROR_PROPOGATE(); goto eh; } csTemp = m_csName; ReplaceStringNoCase(csTemp, _T(".SYS"), _T("")); pNTUpg->m_MatchingFile.m_csServiceName = csTemp; pNTUpg->m_MatchingFile.m_csName.Format(_T("%%SystemRoot%%\\System32\\Drivers\\%s"), m_csName); pNTUpg->m_MatchingFile.m_dwMask = pMFile->m_dwMask; pNTUpg->m_MatchingFile.m_ullBinProductVersion = pMFile->m_ullBinProductVersion; pNTUpg->m_MatchingFile.m_ullUpToBinProductVersion = pMFile->m_ullUpToBinProductVersion; pNTUpg->m_MatchingFile.m_timeLinkDate = pMFile->m_timeLinkDate; pNTUpg->m_MatchingFile.m_timeUpToLinkDate = pMFile->m_timeUpToLinkDate; m_pApp->m_rgWinNTUpgradeEntries.Add(pNTUpg, pDB); pDB->m_rgWinNTUpgradeEntries.Add(pNTUpg, pDB); } } } // // Read SXS manifest // if (!XQL.Query(pNode, _T("SXS"))) { SDBERROR_PROPOGATE(); goto eh; } if (XQL.GetSize() > 1) { SDBERROR_FORMAT((_T("Multiple tags per not allowed\n%s\n"), GetXML(pNode))); goto eh; } if (XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpSXS)) { SDBERROR_PROPOGATE(); goto eh; } m_csSXSManifest = TrimParagraph(GetInnerXML(cpSXS)); if (m_csSXSManifest.IsEmpty()) { SDBERROR_FORMAT((_T("Failed to read SXS manifest:\n%s\n"), GetXML(cpSXS))); goto eh; } } // // Check whether the EXE name contains a wildcard // m_bWildcardInName = (0 <= m_csName.FindOneOf(_T("*?"))); // // Differentiate between driver.xml entries and dbu.xml // if (GetNodeName(pNode) == _T("SYS")) { // // Set filter // m_dwFilter = SDB_FILTER_DRIVER | SDB_FILTER_OVERRIDE; if (m_bWildcardInName) { SDBERROR_FORMAT((_T("Wildcards not allowed in SYS entries:\n%s\n"), GetXML(pNode))); goto eh; } else { pDB->m_rgExes.Add(this, pDB, TRUE); } } else { // // Check if we're compiling for Win2k and make // sure Win2k supports all the matching operations. // if (g_bStrict) { if (!IsValidForWin2k(GetXML(pNode))) { if (GetAttribute(_T("OS_VERSION"), pNode, &csTemp)) { SDBERROR_PROPOGATE(); goto eh; } if (!AddAttribute(pNode, _T("OS_VERSION"), _T("gte5.1"))) { SDBERROR_PROPOGATE(); goto eh; } SDBERROR_CLEAR(); pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE; } } if (m_bWildcardInName) { pDB->m_rgWildcardExes.Add(this, pDB, TRUE); } else if (m_bMatchOnModule) { pDB->m_rgModuleExes.Add(this, pDB, TRUE); } else { pDB->m_rgExes.Add(this, pDB, TRUE); } } m_AppHelpRef.m_pDB = pDB; m_pDB = pDB; bSuccess = TRUE; eh: VariantClear(&vType); VariantClear(&vValue); return bSuccess; } //////////////////////////////////////////////////////////////////////// // // Read in MSI Package tag // // // // // SdbDatabase* CastDatabaseToFixDatabase(SdbDatabase* pDB) { const type_info& TypeInfoFixDB = typeid(SdbDatabase); const type_info& TypeInfoDB = typeid(*pDB); if (TypeInfoDB == TypeInfoFixDB) { return (SdbDatabase*)pDB; } // // bad error // SDBERROR_FORMAT((_T("Internal Compiler Error: Bad cast operation on Database object\n"))); return NULL; } BOOL SdbMsiPackage::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csID; CString csTemp; XMLNodeList XQL; IXMLDOMNodePtr cpMessage; SdbDatabase* pFixDB = CastDatabaseToFixDatabase(pDB); if (pFixDB == NULL) { SDBERROR_PROPOGATE(); goto eh; } m_pApp = pFixDB->m_pCurrentApp; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (g_bStrict) { if (!CheckExeID(pDB, this, csID)) { SDBERROR_PROPOGATE(); goto eh; } } if (!GetAttribute(_T("PRODUCT_CODE"), pNode, &csID)) { // // Guid was not found. We do not generate ids for packages -- they are // statically defined attributes provided to identify the package // SDBERROR_FORMAT((_T("MSI_PACKAGE requires PRODUCT_CODE attribute\n%s\n"), GetXML(pNode))); goto eh; } if (!GUIDFromString(csID, &m_MsiPackageID)) { // // This is the case when we cannot parse the guid and it appears to be // an invalid guid. // SDBERROR_FORMAT((_T("ID attribute is not a valid GUID\n%s\n"), csID)); goto eh; } // // procure RUNTIME_PLATFORM attribute // if (GetAttribute(_T("RUNTIME_PLATFORM"), pNode, &csTemp)) { if (!DecodeRuntimePlatformString(csTemp, &m_dwRuntimePlatform)) { SDBERROR_FORMAT((_T("RUNTIME_PLATFORM no in recognized format: \"%s\"\n%s\n"), (LPCTSTR)csTemp, GetXML(pNode))); goto eh; } } // // Check what OS SKU this entry is meant for // if (GetAttribute(_T("OS_SKU"), pNode, &csTemp)) { // // Decode it. This string is a semi-colon delimited set // of OS SKUs. // if (!DecodeString(csTemp, &m_dwOSSKU, GetOSSKUType)) { SDBERROR_FORMAT((_T("OS_SKU attribute syntax error: %s"), csTemp)); goto eh; } } // // read supplemental data for this object // if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } // // we have name, guid(id) and supplemental data, read fixes for this package // if (!m_rgMsiTransformRefs.ReadFromXML(_T("MSI_TRANSFORM"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgCustomActions.ReadFromXML(_T("CUSTOM_ACTION"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } // // Read APPHELP refs // if (!XQL.Query(pNode, _T("APPHELP"))) { SDBERROR_PROPOGATE(); goto eh; } if (XQL.GetSize() > 1) { SDBERROR_FORMAT((_T("Multiple tags per not allowed\n%s\n"), GetXML(pNode))); goto eh; } if (XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpMessage)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_AppHelpRef.ReadFromXML(cpMessage, pDB)) { SDBERROR_PROPOGATE(); goto eh; } } pDB->m_rgMsiPackages.Add(this, pDB, TRUE); m_AppHelpRef.m_pDB = pDB; m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbMsiCustomAction::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB ) { BOOL bSuccess = FALSE; if (!GetAttribute(_T("NAME"), pNode, &m_csName)) { SDBERROR_FORMAT((_T(" requires NAME attribute:\n%s\n\n"), GetXML(pNode))); goto eh; } if (!m_rgShimRefs.ReadFromXML(_T("SHIM"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgLayerRefs.ReadFromXML(_T("LAYER"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Read in MSI_TRANSFORM tag // // // blah blah blah // // // BOOL SdbMsiTransform::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; IXMLDOMNodePtr cpDesc, cpFile; XMLNodeList XQL; SdbDatabase* pFixDB = CastDatabaseToFixDatabase(pDB); if (pFixDB == NULL) { SDBERROR_PROPOGATE(); goto eh; } // read msi Transform from the library if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (!XQL.Query(pNode, _T("FILE"))) { SDBERROR_PROPOGATE(); goto eh; } if (XQL.GetSize() == 0 || XQL.GetSize() > 1) { SDBERROR_FORMAT((_T(" requires one and only one child:\n%s\n\n"), GetXML(pNode))); goto eh; } if (!XQL.GetItem(0, &cpFile)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("NAME"), cpFile, &m_csMsiTransformFile)) { SDBERROR_FORMAT((_T(" requires NAME attribute:\n%s\n\n"), GetXML(pNode))); goto eh; } if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) { GetNodeText(cpDesc, m_csDesc); } // // name should be unique for each of thesee transforms, enforce // if (pFixDB->m_Library.m_rgMsiTransforms.LookupName(m_csName) != NULL) { SDBERROR_FORMAT((_T("MSI_TRANSFORM NAME attribute is not unique\n%s\n\n"), GetXML(pNode))); goto eh; } // // find corresponding file object // if (m_csMsiTransformFile.GetLength()) { m_pSdbFile = (SdbFile*)pFixDB->m_Library.m_rgFiles.LookupName(m_csMsiTransformFile); if (g_bStrict && m_pSdbFile == NULL) { SDBERROR_FORMAT((_T(" // BOOL SdbMsiTransformRef::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; SdbDatabase* pFixDB = NULL; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } pFixDB = CastDatabaseToFixDatabase(pDB); if (pFixDB == NULL) { SDBERROR_PROPOGATE(); goto eh; } m_pMsiTransform = (SdbMsiTransform *) pFixDB->m_Library.m_rgMsiTransforms.LookupName(m_csName); if (m_pMsiTransform == NULL && g_bStrict) { SDBERROR_FORMAT((_T("MSI_TRANSFORM \"%s\" not found in library:\n%s\n\n"), m_csName, GetXML(pNode))); goto eh; } m_pDB = pDB; // set the root db pointer (why???) bSuccess = TRUE; eh: return bSuccess; } ///////////////////////////////////////////////////////////////////////////////////////////////// BOOL SdbMatchingFile::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csTemp; GetAttribute(_T("SERVICE_NAME"), pNode, &m_csServiceName); if (!GetAttribute(_T("NAME"), pNode, &m_csName)) { if (GetNodeName(pNode) == _T("EXE")) { m_csName = _T("*"); } else if (m_csServiceName.IsEmpty()) { SDBERROR_FORMAT((_T("NAME attribute required:\n%s\n\n"), GetXML(pNode))); goto eh; } } if (GetParentNodeName(pNode) == _T("WIN9X_MIGRATION") || GetNodeName(pNode) == _T("MATCH_ANY") || GetNodeName(pNode) == _T("MATCH_ALL")) { if (-1 != m_csName.Find(_T("\\"))) { SDBERROR_FORMAT((_T(" inside cannot contain relative paths:\n%s\n"), GetXML(pNode))); goto eh; } } m_dwMask = 0; if (GetAttribute(_T("SIZE"), pNode, &csTemp)) { m_dwSize = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_SIZE; } else { m_dwSize = 0; } if (GetAttribute(_T("CHECKSUM"), pNode, &csTemp)) { m_dwChecksum = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_CHECKSUM; } else m_dwChecksum = 0; if (GetAttribute(_T("COMPANY_NAME"), pNode, &(m_csCompanyName))) { m_dwMask |= SDB_MATCHINGINFO_COMPANY_NAME; } if (GetAttribute(_T("PRODUCT_NAME"), pNode, &(m_csProductName))) { m_dwMask |= SDB_MATCHINGINFO_PRODUCT_NAME; } if (GetAttribute(_T("PRODUCT_VERSION"), pNode, &(m_csProductVersion))) { m_dwMask |= SDB_MATCHINGINFO_PRODUCT_VERSION; } if (GetAttribute(_T("FILE_DESCRIPTION"), pNode, &(m_csFileDescription))) { m_dwMask |= SDB_MATCHINGINFO_FILE_DESCRIPTION; } if (GetAttribute(_T("BIN_FILE_VERSION"), pNode, &csTemp)) { if (!VersionToQword(csTemp, &m_ullBinFileVersion)) { SDBERROR_FORMAT((_T("Bad BIN_FILE_VERSION attribute:\n\n%s\n"), GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_BIN_FILE_VERSION; } if (GetAttribute(_T("BIN_PRODUCT_VERSION"), pNode, &csTemp)) { if (!VersionToQword(csTemp, &m_ullBinProductVersion)) { SDBERROR_FORMAT((_T("Bad BIN_PRODUCT_VERSION attribute:\n\n%s\n"), GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_BIN_PRODUCT_VERSION; } if (GetAttribute(_T("MODULE_TYPE"), pNode, &csTemp)) { if (!GetModuleTypeIndicator(csTemp, &m_dwModuleType)) { SDBERROR_FORMAT((_T(" MODULE_TYPE attribute unrecognized:\n%s\n"), GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_MODULE_TYPE; } if (GetAttribute(_T("VERFILEDATELO"), pNode, &csTemp)) { m_dwFileDateLS = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_VERFILEDATELO; } if (GetAttribute(_T("VERFILEDATEHI"), pNode, &csTemp)) { m_dwFileDateMS = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_VERFILEDATEHI; } if (GetAttribute(_T("VERFILEOS"), pNode, &csTemp)) { m_dwFileOS = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_VERFILEOS; } if (GetAttribute(_T("VERFILETYPE"), pNode, &csTemp)) { m_dwFileType = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_VERFILETYPE; } if (GetAttribute(_T("PE_CHECKSUM"), pNode, &csTemp)) { m_ulPECheckSum = StringToULong(csTemp); m_dwMask |= SDB_MATCHINGINFO_PE_CHECKSUM; } if (GetAttribute(_T("LINKER_VERSION"), pNode, &csTemp)) { m_dwLinkerVersion = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_LINKER_VERSION; } if (GetAttribute(_T("FILE_VERSION"), pNode, &m_csFileVersion)) { m_dwMask |= SDB_MATCHINGINFO_FILE_VERSION; } if (GetAttribute(_T("ORIGINAL_FILENAME"), pNode, &m_csOriginalFileName)) { m_dwMask |= SDB_MATCHINGINFO_ORIGINAL_FILENAME; } if (GetAttribute(_T("INTERNAL_NAME"), pNode, &m_csInternalName)) { m_dwMask |= SDB_MATCHINGINFO_INTERNAL_NAME; } if (GetAttribute(_T("LEGAL_COPYRIGHT"), pNode, &m_csLegalCopyright)) { m_dwMask |= SDB_MATCHINGINFO_LEGAL_COPYRIGHT; } if (GetAttribute(_T("S16BIT_DESCRIPTION"), pNode, &m_cs16BitDescription)) { m_dwMask |= SDB_MATCHINGINFO_16BIT_DESCRIPTION; } if (GetAttribute(_T("S16BIT_MODULE_NAME"), pNode, &m_cs16BitModuleName)) { m_dwMask |= SDB_MATCHINGINFO_16BIT_MODULE_NAME; } if (GetAttribute(_T("UPTO_BIN_PRODUCT_VERSION"), pNode, &csTemp)) { if (!VersionToQword(csTemp, &m_ullUpToBinProductVersion)) { SDBERROR_FORMAT((_T("Bad UPTO_BIN_PRODUCT_VERSION attribute:\n\n%s\n"), GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_UPTO_BIN_PRODUCT_VERSION; } if (GetAttribute(_T("UPTO_BIN_FILE_VERSION"), pNode, &csTemp)) { if (!VersionToQword(csTemp, &m_ullUpToBinFileVersion)) { SDBERROR_FORMAT((_T("Bad UPTO_BIN_FILE_VERSION attribute:\n\n%s\n"), GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_UPTO_BIN_FILE_VERSION; } if (GetAttribute(_T("PREVOSMAJORVERSION"), pNode, &csTemp)) { m_dwPrevOSMajorVersion = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_PREVOSMAJORVERSION; } if (GetAttribute(_T("PREVOSMINORVERSION"), pNode, &csTemp)) { m_dwPrevOSMinorVersion = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_PREVOSMINORVERSION; } if (GetAttribute(_T("PREVOSPLATFORMID"), pNode, &csTemp)) { m_dwPrevOSPlatformID = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_PREVOSPLATFORMID; } if (GetAttribute(_T("PREVOSBUILDNO"), pNode, &csTemp)) { m_dwPrevOSBuildNo = StringToDword(csTemp); m_dwMask |= SDB_MATCHINGINFO_PREVOSBUILDNO; } if (GetAttribute(_T("LINK_DATE"), pNode, &csTemp)) { if (!MakeUTCTime(csTemp, &m_timeLinkDate)) { SDBERROR_FORMAT((_T("LINK_DATE not in recognized time format: \"%s\"\n%s\n"), csTemp, GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_LINK_DATE; } if (GetAttribute(_T("UPTO_LINK_DATE"), pNode, &csTemp)) { if (!MakeUTCTime(csTemp, &m_timeUpToLinkDate)) { SDBERROR_FORMAT((_T("UPTO_LINK_DATE not in recognized time format: \"%s\"\n%s\n"), csTemp, GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_UPTO_LINK_DATE; } if (GetAttribute(_T("VER_LANGUAGE"), pNode, &csTemp)) { if (!ParseLanguageID(csTemp, &m_dwVerLanguage)) { SDBERROR_FORMAT((_T("VER_LANGUAGE not in recognized format: \"%s\"\n%s\n"), (LPCTSTR)csTemp, GetXML(pNode))); goto eh; } m_dwMask |= SDB_MATCHINGINFO_VER_LANGUAGE; } if (GetAttribute(_T("REGISTRY_ENTRY"), pNode, &m_csRegistryEntry)) { m_dwMask |= SDB_MATCHINGINFO_REGISTRY_ENTRY; } if (GetAttribute(_T("LOGIC"), pNode, &csTemp)) { if (0 == csTemp.CompareNoCase(_T("NOT"))) { m_bMatchLogicNot = TRUE; } } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbMatchingRegistryEntry::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csTemp; if (!GetAttribute(_T("KEY"), pNode, &m_csName)) { SDBERROR_FORMAT((_T(" requires KEY attribute:\n%s\n\n"), GetXML(pNode))); goto eh; } GetAttribute(_T("VALUE_NAME"), pNode, &m_csValueName); GetAttribute(_T("VALUE"), pNode, &m_csValue); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbAppHelpRef::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; SdbMessage* pMessage = NULL; SdbAppHelpRef* pAppHelpRef = NULL; BOOL bBlockUpgrade = FALSE; long i; CString csHTMLHELPID, csType, csURL, csMessage; IXMLDOMNodePtr cpParentNode; SdbAppHelpType Type = SDB_APPHELP_NOBLOCK; if (FAILED(pNode->get_parentNode(&cpParentNode))) { SDBERROR_FORMAT((_T("Error retrieving parent node of APPHELP: %s\n"), GetXML(pNode))); goto eh; } if (!GetAttribute(_T("MESSAGE"), pNode, &csMessage)) { SDBERROR_FORMAT((_T(" requires MESSAGE attribute:\n%s\n"), GetXML(pNode))); goto eh; } // // get a custom URL, if one is available // GetAttribute(_T("DETAILS_URL"), pNode, &csURL); // // Get BLOCK attribute // Type = SDB_APPHELP_NOBLOCK; if (GetAttribute(_T("BLOCK"), pNode, &csType)) { if (GetNodeName(cpParentNode) == _T("WINNT_UPGRADE") || GetNodeName(cpParentNode) == _T("SYS")) { SDBERROR_FORMAT((_T(" within or ") _T("cannot use BLOCK attribute. Use BLOCK_UPGRADE instead.\n\n%s\n"), GetXML(cpParentNode))); goto eh; } if (csType == _T("YES")) { Type = SDB_APPHELP_HARDBLOCK; } } if (GetAttribute(_T("BLOCK_UPGRADE"), pNode, &csType)) { if (GetNodeName(cpParentNode) != _T("WINNT_UPGRADE") && GetNodeName(cpParentNode) != _T("SYS")) { SDBERROR_FORMAT((_T(" not within or ") _T("cannot use BLOCK_UPGRADE attribute.\n\n%s\n"), GetXML(cpParentNode))); goto eh; } if (csType == _T("YES")) { bBlockUpgrade = TRUE; } } if (m_cpNode == NULL && !GetAttribute(_T("HTMLHELPID"), pNode, &csHTMLHELPID)) { // // Need to generate a new HTMLHELPID. Wait until // the rest of the tags for this app have // been parsed and then we'll pass over this again. // pDB->m_pCurrentApp->m_rgAppHelpRefs.Add(this); m_cpNode = pNode; bSuccess = TRUE; goto eh; } if (!GetAttribute(_T("HTMLHELPID"), pNode, &csHTMLHELPID)) { // // HTMLHELPID not found. Generate it. // for (i = 0; i < pDB->m_pCurrentApp->m_rgAppHelpRefs.GetSize(); i++) { pAppHelpRef = (SdbAppHelpRef *) pDB->m_pCurrentApp->m_rgAppHelpRefs.GetAt(i); if (pAppHelpRef->m_pAppHelp) { if (pAppHelpRef->m_pAppHelp->m_csMessage == csMessage && pAppHelpRef->m_pAppHelp->m_Type == Type && pAppHelpRef->m_pAppHelp->m_csURL == csURL && pAppHelpRef->m_pAppHelp->m_bBlockUpgrade == bBlockUpgrade) { csHTMLHELPID = pAppHelpRef->m_pAppHelp->m_csName; } } } if (csHTMLHELPID.IsEmpty()) { csHTMLHELPID.Format(_T("%d"), pDB->GetNextSequentialID(_T("HTMLHELPID"))); } if (!AddAttribute(pNode, _T("HTMLHELPID"), csHTMLHELPID)) { SDBERROR_PROPOGATE(); goto eh; } pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE; } // // Create an AppHelp entry if one isn't there // m_pAppHelp = (SdbAppHelp *) pDB->m_rgAppHelps.LookupName(csHTMLHELPID); if (m_pAppHelp == NULL) { m_pAppHelp = new SdbAppHelp; m_pAppHelp->m_csName = csHTMLHELPID; m_pAppHelp->m_csMessage = csMessage; m_pAppHelp->m_csURL = csURL; m_pAppHelp->m_pApp = pDB->m_pCurrentApp; m_pAppHelp->m_Type = Type; m_pAppHelp->m_bBlockUpgrade = bBlockUpgrade; pDB->m_rgAppHelps.Add(m_pAppHelp, pDB); } else { if (m_pAppHelp->m_pApp != pDB->m_pCurrentApp || m_pAppHelp->m_csMessage != csMessage || m_pAppHelp->m_Type != Type || m_pAppHelp->m_bBlockUpgrade != bBlockUpgrade || m_pAppHelp->m_csURL != csURL) { SDBERROR_FORMAT((_T("Duplicate HTMLHELPID with differing APP, MESSAGE, BLOCK or DETAILS_URL: %s\n"), csHTMLHELPID)); goto eh; } } pDB->m_pCurrentApp->m_rgAppHelpRefs.Add(this); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbMessage::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; IXMLDOMNodePtr cpChild; CString csTemplate, csID; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } m_csLangID = pDB->m_csCurrentLangID; if (GetAttribute(_T("TEMPLATE"), pNode, &csTemplate)) { m_pTemplate = (SdbMessageTemplate *) pDB->m_rgMessageTemplates.LookupName(csTemplate, m_csLangID); if (m_pTemplate == NULL) { SDBERROR_FORMAT((_T("Template \"%s\" not previously declared."), csTemplate)); goto eh; } } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (GetChild(_T("CONTACT_INFO"), pNode, &cpChild)) { m_csContactInfoXML = GetInnerXML(cpChild); cpChild.Release(); } if (GetChild(_T("SUMMARY"), pNode, &cpChild)) { m_csSummaryXML = GetInnerXML(cpChild); cpChild.Release(); } if (GetChild(_T("DETAILS"), pNode, &cpChild)) { m_csDetailsXML = GetInnerXML(cpChild); cpChild.Release(); } else { m_csDetailsXML = m_csSummaryXML; } if (!m_rgFields.ReadFromXML(_T("FIELD"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbMessageTemplate::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; IXMLDOMNodePtr cpChild; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } m_csLangID = pDB->m_csCurrentLangID; if (GetChild(_T("SUMMARY"), pNode, &cpChild)) { m_csSummaryXML = GetInnerXML(cpChild); cpChild.Release(); } if (GetChild(_T("DETAILS"), pNode, &cpChild)) { m_csDetailsXML = GetInnerXML(cpChild); cpChild.Release(); } else { m_csDetailsXML = m_csSummaryXML; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbContactInfo::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csID; if (!GetAttribute(_T("VENDOR"), pNode, &m_csName)) { SDBERROR_FORMAT((_T(" requires VENDOR attribute:\n%s\n"), GetXML(pNode))); goto eh; } m_csLangID = pDB->m_csCurrentLangID; if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } m_csXML = GetInnerXML(pNode); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbData::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csValueType; CString csValueAttr; CString csValueText; DWORD dwType; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } if (!GetAttribute(_T("VALUETYPE"), pNode, &csValueType)) { SDBERROR(_T(" requires VALUETYPE attribute.")); goto eh; } if (!GetDataTypeIndicator(csValueType, &dwType)) { SDBERROR_FORMAT((_T(" VALUETYPE \"%s\" not recognized."), csValueType)); goto eh; } GetNodeText(pNode, csValueText); GetAttribute(_T("VALUE"), pNode, &csValueAttr); if (csValueText.GetLength() && csValueAttr.GetLength()) { SDBERROR_FORMAT((_T(" cannot contain both VALUE attribute and inner text."), m_csName)); goto eh; } else if (csValueText.GetLength()) { SetValue((SdbDataValueType) dwType, csValueText); } else if (csValueAttr.GetLength()) { SetValue((SdbDataValueType) dwType, csValueAttr); } m_DataType = (SdbDataValueType) dwType; // finally, read all the child data elements if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbAction::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } GetAttribute(_T("TYPE"), pNode, &m_csType); if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbMessageField::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; if (!ReadName(pNode, &m_csName)) { SDBERROR_PROPOGATE(); goto eh; } m_csValue = GetInnerXML(pNode); m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbMatchOperation::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB ) { BOOL bSuccess = FALSE; if (GetNodeName(pNode) == _T("MATCH_ANY")) { m_Type = SDB_MATCH_ANY; } else { m_Type = SDB_MATCH_ALL; } if (!m_rgMatchingFiles.ReadFromXML(_T("MATCHING_FILE"), pDB, pNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_rgSubMatchOps.ReadFromXML(_T("MATCH_ALL | MATCH_ANY"), pDB, pNode, NULL, FALSE, NULL)) { SDBERROR_PROPOGATE(); goto eh; } bSuccess = TRUE; eh: return bSuccess; } BOOL SdbWin9xMigration::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; CString csID, csTemp; m_pApp = pDB->m_pCurrentApp; // grab app pointer from the db if (!GetAttribute(_T("SECTION"), pNode, &m_csSection)) { SDBERROR_FORMAT((_T(" tag requires SECTION attribute:\n%s\n"), GetXML(pNode))); goto eh; } GetAttribute(_T("MESSAGE"), pNode, &m_csMessage); if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } if (g_bStrict) { if (!CheckExeID(pDB, this, csID)) { SDBERROR_PROPOGATE(); goto eh; } } if (GetAttribute(_T("SHOW_IN_SIMPLIFIED_VIEW"), pNode, &csTemp)) { m_bShowInSimplifiedView = (csTemp.CompareNoCase(_T("YES")) == 0); } if (!m_MatchOp.ReadFromXML(pNode, pDB)) { SDBERROR_PROPOGATE(); goto eh; } m_pDB = pDB; bSuccess = TRUE; eh: return bSuccess; } BOOL SdbWinNTUpgrade::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { BOOL bSuccess = FALSE; BOOL bMF = FALSE; CString csType, csHTMLHELPID, csID; XMLNodeList XQL; IXMLDOMNodePtr cpNewNode, cpAppNode; m_pApp = pDB->m_pCurrentApp; // grab app pointer from the db XQL.Query(pNode, _T("APPHELP")); if (XQL.GetSize() > 1) { SDBERROR_FORMAT((_T(" blocks can only contain one entry:\n%s\n"), GetXML(pNode))); goto eh; } else if (XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpNewNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_AppHelpRef.ReadFromXML(cpNewNode, pDB)) { SDBERROR_PROPOGATE(); goto eh; } } if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) { SDBERROR_PROPOGATE(); goto eh; } XQL.Query(pNode, _T("MATCHING_FILE")); if (XQL.GetSize() > 1) { SDBERROR_FORMAT((_T(" blocks can only contain one entry:\n%s\n"), GetXML(pNode))); goto eh; } else if (XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpNewNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_MatchingFile.ReadFromXML(cpNewNode, pDB)) { SDBERROR_PROPOGATE(); goto eh; } bMF = TRUE; } XQL.Query(pNode, _T("MATCHING_REGISTRY_ENTRY")); if (XQL.GetSize() > 1 || (XQL.GetSize() == 1 && bMF)) { SDBERROR_FORMAT((_T(" blocks can only contain one entry:\n%s\n"), GetXML(pNode))); goto eh; } else if(XQL.GetSize() == 1) { if (!XQL.GetItem(0, &cpNewNode)) { SDBERROR_PROPOGATE(); goto eh; } if (!m_MatchingRegistryEntry.ReadFromXML(cpNewNode, pDB)) { SDBERROR_PROPOGATE(); goto eh; } bMF = TRUE; } m_AppHelpRef.m_pDB = pDB; m_pDB = pDB; pDB->m_rgWinNTUpgradeEntries.Add(this, pDB); bSuccess = TRUE; eh: return bSuccess; }