|
|
///////////////////////////////////////////////////////////////////////////////
//
// File: obj.cpp
//
// History: 16-Nov-00 markder Created.
//
// Desc: This file contains various member functions/constructors
// used by the SdbDatabase object model.
//
///////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "make.h"
////////////////////////////////////////////////////////////////////////////////////
//
// Func: ReadFromXML, WriteToSDB, WriteRefToSDB
//
// Desc: Each element that can be initialized from XML must implement
// ReadFromXML. Similarly, each object that can persist itself
// in an SDB file must implement WriteToSDB. A special case of
// WriteToSDB is when an object is written differently if it
// is a reference to an object in the LIBRARY, in which case
// the object must implement WriteRefToSDB.
//
BOOL SdbArrayElement::ReadFromXML( IXMLDOMNode* pNode, SdbDatabase* pDB) { SDBERROR(_T("ReadFromXML not implemented for this object")); return FALSE; }
BOOL SdbArrayElement::WriteToSDB(PDB pdb) { SDBERROR(_T("WriteToSDB not implemented for this object.")); return FALSE; }
BOOL SdbArrayElement::WriteRefToSDB(PDB pdb) { SDBERROR(_T("WriteRefToSDB not implemented for this object.")); return FALSE; }
void SdbArrayElement::PropagateFilter(DWORD dwFilter) { if (!(m_dwFilter & SDB_FILTER_OVERRIDE)) { m_dwFilter |= dwFilter; }
if (dwFilter == SDB_FILTER_EXCLUDE_ALL) { m_dwFilter = SDB_FILTER_EXCLUDE_ALL; }
if (m_csOSVersionSpec.GetLength() && m_pDB->m_pCurrentMakefile->m_flOSVersion != 0.0) { if (FilterOSVersion(m_pDB->m_pCurrentMakefile->m_flOSVersion, m_csOSVersionSpec, &m_dwSPMask)) {
m_dwFilter = SDB_FILTER_EXCLUDE_ALL; } } if (!(m_dwOSPlatform & m_pDB->m_pCurrentMakefile->m_dwOSPlatform)) { m_dwFilter = SDB_FILTER_EXCLUDE_ALL; } }
////////////////////////////////////////////////////////////////////////////////////
//
// Func: Compare
//
// Desc: Compare two elements - first compare the keys (m_ullKey member)
// then names, return < 0 if this element should precede pElement
// > 0 if this element should follow pElement
// = 0 if the elements are equal
//
int SdbArrayElement::Compare(const SdbArrayElement* pElement) {
//
// compare key first
//
if (m_ullKey < pElement->m_ullKey) { return -1; } //
// we are either greater or equal
//
if (m_ullKey > pElement->m_ullKey) { return 1; }
//
// equal keys, compare names
//
return m_csName.CompareNoCase(pElement->m_csName); }
int SdbExe::Compare(const SdbArrayElement* pElement) {
int nRet = SdbArrayElement::Compare(pElement);
if (nRet == 0) { //
// the keys are equal, but we want to put the additive one(s) before the non-additive
//
if (m_dwMatchMode == MATCH_ADDITIVE && ((SdbExe*)pElement)->m_dwMatchMode != MATCH_ADDITIVE) { nRet = -1; } else if (m_dwMatchMode != MATCH_ADDITIVE && ((SdbExe*)pElement)->m_dwMatchMode == MATCH_ADDITIVE) { nRet = 1; } } return nRet; }
////////////////////////////////////////////////////////////////////////////////////
//
// Func: SdbPatch::AddBlobBytes, SdbPatch::ClearBlob
//
// Desc: Helper functions to add to the SdbPatch 'blob', which is a series
// of opcodes and instructions that define how to match on memory
// and 'patch' it safely.
//
void SdbPatch::AddBlobBytes( LPVOID pBytes, DWORD dwSize ) { PBYTE pOldBuffer = NULL; DWORD dwOldBufferSize = 0;
if( m_pBlob == NULL ) { m_dwBlobMemSize = dwSize > 1000 ? dwSize : 1000; m_pBlob = new BYTE[m_dwBlobMemSize]; m_dwBlobSize = 0; }
if( dwSize > m_dwBlobMemSize - m_dwBlobSize ) { pOldBuffer = m_pBlob; dwOldBufferSize = m_dwBlobMemSize; m_dwBlobMemSize = ( m_dwBlobMemSize * 2 ) + dwSize; m_pBlob = new BYTE[m_dwBlobMemSize];
if( pOldBuffer ) { memcpy( m_pBlob, pOldBuffer, dwOldBufferSize ); delete pOldBuffer; } }
memcpy( (LPVOID) (m_pBlob + m_dwBlobSize ), pBytes, dwSize );
m_dwBlobSize += dwSize; }
void SdbPatch::ClearBlob() { if (m_pBlob != NULL) { delete m_pBlob; m_pBlob = NULL; } m_dwBlobMemSize = 0; m_dwBlobSize = 0; }
////////////////////////////////////////////////////////////////////////////////////
//
// Func: SdbData::SetValue, SdbData::Clear
//
// Desc: Accessor functions to set/clear the value of a data object.
// The object mimics the registry in the way that it can store
// DWORDs, strings or binary data.
//
BOOL SdbData::SetValue(SdbDataValueType DataType, LPCTSTR szValue) { Clear();
m_DataType = DataType; m_dwDataSize = 0;
switch(DataType) { case eValueDWORD: m_dwDataSize = sizeof(m_dwValue); m_dwValue = StringToDword(szValue); break;
case eValueQWORD: m_dwDataSize = sizeof(m_ullValue); m_ullValue = StringToQword(szValue); break;
case eValueBinary: m_dwDataSize = GetByteStringSize(szValue);
m_pBinValue = new BYTE[m_dwDataSize]; if (m_pBinValue == NULL) { return FALSE; }
GetBytesFromString(szValue, m_pBinValue, m_dwDataSize); break;
case eValueString:
m_szValue = new TCHAR[_tcslen(szValue) + 1]; if (m_szValue == NULL) { return FALSE; } StringCchCopy(m_szValue, _tcslen(szValue) + 1, szValue); break;
}
return TRUE; }
void SdbData::Clear() { switch(m_DataType) {
case eValueString: if (NULL != m_szValue) { delete[] m_szValue; } break;
case eValueBinary: if (NULL != m_pBinValue) { delete[] m_pBinValue; } break; }
m_DataType = eValueNone; }
BOOL SdbDatabase::IsStandardDatabase(VOID) { const GUID* rgpGUID[] = { &GUID_SYSMAIN_SDB, &GUID_APPHELP_SDB, &GUID_SYSTEST_SDB, &GUID_DRVMAIN_SDB, &GUID_MSIMAIN_SDB };
int i;
for (i = 0; i < ARRAYSIZE(rgpGUID); ++i) { if (*rgpGUID[i] == m_CurrentDBID) { return TRUE; } }
return FALSE; }
BOOL SdbDatabase::ReplaceFields(CString csXML, CString* pcsReturn, SdbRefArray<SdbMessageField>* prgFields) { BOOL bSuccess = FALSE; XMLNodeList XQL; IXMLDOMNodePtr cpTargetNode; IXMLDOMNodePtr cpCurrentNode; IXMLDOMNodePtr cpNewTextNode; IXMLDOMNodePtr cpParentNode; IXMLDOMNodePtr cpOldNode; IXMLDOMDocument* pDocument; CString csFieldName, csTempXML; CHAR* lpBuf; BSTR bsText = NULL; VARIANT vType; long i; SdbMessageField* pField;
VariantInit(&vType);
vType.vt = VT_I4; vType.lVal = NODE_TEXT;
#ifdef UNICODE
// lpBuf = (LPSTR) csTempXML.GetBuffer(10);
// lpBuf[0] = (CHAR) 0xFF;
// lpBuf[1] = (CHAR) 0xFE;
// lpBuf[2] = 0x00;
// lpBuf[3] = 0x00;
// csTempXML.ReleaseBuffer();
csTempXML += L"<?xml version=\"1.0\" encoding=\"UTF-16\"?>"; #else
csTempXML = "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"; #endif
csTempXML += _T("<_TARGET>"); csTempXML += csXML; csTempXML += _T("</_TARGET>");
//
// Replace all <, > and & in fields with ugly markers to be replaced later
//
for (i = 0; i < prgFields->GetSize(); i++) { pField = (SdbMessageField *) prgFields->GetAt(i);
pField->m_csValue.Replace(_T("<"), _T("____REAL_LESS_THAN____")); pField->m_csValue.Replace(_T(">"), _T("____REAL_GREATER_THAN____")); pField->m_csValue.Replace(_T("<"), _T("____LESS_THAN____")); pField->m_csValue.Replace(_T(">"), _T("____GREATER_THAN____")); pField->m_csValue.Replace(_T("&"), _T("____AMP____")); pField->m_csValue.Replace(_T(" "), _T("____NBSP____")); }
//
// Load the XML into the temporary DOM
//
if (!OpenXML(csTempXML, &m_cpTempXML, TRUE, &m_cpTempXMLDoc)) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.Query(m_cpTempXML, _T("_TARGET"))) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.GetItem(0, &cpTargetNode)) { SDBERROR_PROPOGATE(); goto eh; }
XQL.Query(cpTargetNode, _T("//*"));
for (i = 0; i < XQL.GetSize(); i++) {
if (!XQL.GetItem(i, &cpCurrentNode)) { SDBERROR_PROPOGATE(); goto eh; }
if (GetNodeName(cpCurrentNode) == _T("FIELD")) { GetAttribute(_T("NAME"), cpCurrentNode, &csFieldName);
pField = (SdbMessageField *) prgFields->LookupName(csFieldName);
if (pField != NULL) {
bsText = pField->m_csValue.AllocSysString();
if (FAILED(m_cpTempXML->get_ownerDocument(&pDocument))) { SDBERROR(_T("createNode failed while adding attribute")); goto eh; }
if (FAILED(m_cpTempXMLDoc->createNode(vType, NULL, NULL, &cpNewTextNode))) { SDBERROR(_T("createNode failed while adding attribute")); goto eh; }
if (FAILED(cpNewTextNode->put_text(bsText))) { SDBERROR(_T("Could not set text property of FIELD object.")); goto eh; }
if (FAILED(cpCurrentNode->get_parentNode(&cpParentNode))) { SDBERROR(_T("Could not retrieve parent node of FIELD object.")); goto eh; }
if (FAILED(cpParentNode->replaceChild(cpNewTextNode, cpCurrentNode, &cpOldNode))) { SDBERROR(_T("Could not replace <FIELD> node with text node.")); goto eh; }
cpNewTextNode = NULL; cpOldNode = NULL;
SysFreeString(bsText); bsText = NULL; } }
cpCurrentNode.Release(); }
*pcsReturn = GetInnerXML(cpTargetNode);
//
// Turn the ugly markers back to prettiness
//
pcsReturn->Replace(_T("____REAL_LESS_THAN____"), _T("<")); pcsReturn->Replace(_T("____REAL_GREATER_THAN____"), _T(">")); pcsReturn->Replace(_T("____LESS_THAN____"), _T("<")); pcsReturn->Replace(_T("____GREATER_THAN____"), _T(">")); pcsReturn->Replace(_T("____AMP____"), _T("&")); pcsReturn->Replace(_T("____NBSP____"), _T(" "));
bSuccess = TRUE;
eh: VariantClear(&vType);
if (bsText) { SysFreeString(bsText); }
return bSuccess; }
BOOL SdbDatabase::RedirectLinks(CString* pcsXML, LCID lcid, CString csRedirURL) { BOOL bSuccess = FALSE; XMLNodeList XQL; IXMLDOMNodePtr cpTargetNode; IXMLDOMNodePtr cpCurrentNode; CString csRedirID, csFinalRedirURL, csLCID; CString csTempXML; long i;
csLCID.Format(_T("%X"), lcid);
csTempXML = _T("<?xml version=\"1.0\"?><_TARGET>"); csTempXML += *pcsXML; csTempXML += _T("</_TARGET>");
if (!OpenXML(csTempXML, &m_cpTempXML, TRUE, &m_cpTempXMLDoc)) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.Query(m_cpTempXML, _T("_TARGET"))) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.GetItem(0, &cpTargetNode)) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.Query(m_cpTempXML, _T("//A"))) { SDBERROR_PROPOGATE(); goto eh; }
for (i = 0; i < XQL.GetSize(); i++) {
if (!XQL.GetItem(i, &cpCurrentNode)) { SDBERROR_PROPOGATE(); goto eh; }
if (!GetAttribute(_T("REDIR_ID"), cpCurrentNode, &csRedirID)) { SDBERROR_FORMAT((_T("REDIR_ID not found on <A> element:\n%s\n"), *pcsXML)); goto eh; }
csFinalRedirURL = csRedirURL; csFinalRedirURL.Replace(_T("$REDIR_ID$"), csRedirID); csFinalRedirURL.Replace(_T("$LCID$"), csLCID);
if (!AddAttribute(cpCurrentNode, _T("HREF"), csFinalRedirURL)) { SDBERROR_FORMAT((_T("Could not replace HREF attribute on <A> tag:\n%s\n"), *pcsXML)); goto eh; }
if (!AddAttribute(cpCurrentNode, _T("TARGET"), _T("_new"))) { SDBERROR_FORMAT((_T("Could not add TARGET=\"_new\" attribute on <A> tag:\n%s\n"), *pcsXML)); goto eh; }
if (!RemoveAttribute(_T("REDIR_ID"), cpCurrentNode)) { SDBERROR_FORMAT((_T("Could not remove REDIR_ID attribute on <A> tag:\n%s\n"), *pcsXML)); goto eh; }
}
*pcsXML = GetInnerXML(cpTargetNode);
bSuccess = TRUE;
eh:
return bSuccess; }
BOOL SdbDatabase::HTMLtoText(CString csXML, CString* pcsReturn) { BOOL bSuccess = FALSE; XMLNodeList XQL; IXMLDOMNodePtr cpTargetNode; IXMLDOMNodePtr cpCurrentNode; IXMLDOMDocument* pDocument; DOMNodeType NodeType; CString csTempXML; BSTR bsText = NULL; long i;
csTempXML = _T("<?xml version=\"1.0\"?><_TARGET>"); csTempXML += csXML; csTempXML += _T("</_TARGET>");
pcsReturn->Empty();
//
// Load the XML into the temporary DOM
//
if (!OpenXML(csTempXML, &m_cpTempXML, TRUE, &m_cpTempXMLDoc)) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.Query(m_cpTempXML, _T("_TARGET"))) { SDBERROR_PROPOGATE(); goto eh; }
if (!XQL.GetItem(0, &cpTargetNode)) { SDBERROR_PROPOGATE(); goto eh; }
XQL.Query(cpTargetNode, _T("//"));
for (i = 0; i < XQL.GetSize(); i++) {
if (!XQL.GetItem(i, &cpCurrentNode)) { SDBERROR_PROPOGATE(); goto eh; }
if (FAILED(cpCurrentNode->get_nodeType(&NodeType))) { SDBERROR(_T("Error retrieving nodeType attribute.")); goto eh; }
if (NodeType == NODE_TEXT) {
*pcsReturn += _T(" "); *pcsReturn += GetText(cpCurrentNode); *pcsReturn += _T(" ");
} else {
if (GetNodeName(cpCurrentNode) == _T("BR")) { *pcsReturn += _T("\n"); }
if (GetNodeName(cpCurrentNode) == _T("P")) { *pcsReturn += _T("\n\n"); } }
cpCurrentNode.Release(); }
bSuccess = TRUE;
eh: if (bsText) { SysFreeString(bsText); }
return bSuccess; }
CString SdbApp::GetLocalizedAppName() { return GetLocalizedAppName(m_pDB->m_pCurrentMakefile->m_csLangID); }
CString SdbApp::GetLocalizedAppName(CString csLangID) { CString csLookup(m_csName); SdbLocalizedString* pLocString = NULL;
csLookup.MakeUpper(); pLocString = (SdbLocalizedString *) m_pDB->m_rgLocalizedAppNames.LookupName(csLookup, csLangID); if (pLocString) { return pLocString->m_csValue; } else { return m_csName; } }
CString SdbApp::GetLocalizedVendorName() { return GetLocalizedVendorName(m_pDB->m_pCurrentMakefile->m_csLangID); }
CString SdbApp::GetLocalizedVendorName(CString csLangID) { CString csLookup(m_csVendor); SdbLocalizedString* pLocString = NULL;
csLookup.MakeUpper(); pLocString = (SdbLocalizedString *) m_pDB->m_rgLocalizedVendorNames.LookupName(csLookup, csLangID); if (pLocString) { return pLocString->m_csValue; } else { return m_csVendor; } }
BOOL SdbExe::IsValidForWin2k(CString csXML) { BOOL bReturn = FALSE;
SdbMatchingFile* pMFile;
if (!FilterOSVersion(5.0, m_csOSVersionSpec, &m_dwSPMask)) {
if (m_csName.GetLength() > 1 && m_csName.FindOneOf(_T("*?")) != -1) { SDBERROR_FORMAT(( _T("Wildcards not supported on Win2k. Add OS_VERSION=\"gte5.1\" to <EXE>:\n%s\n"), csXML)); goto eh; }
for (long i = 0; i < m_rgMatchingFiles.GetSize(); i++) { pMFile = (SdbMatchingFile *) m_rgMatchingFiles.GetAt(i);
if (!pMFile->IsValidForWin2k(csXML)) { SDBERROR_PROPOGATE(); goto eh; } } }
bReturn = TRUE;
eh:
return bReturn; }
BOOL SdbMatchingFile::IsValidForWin2k(CString csXML) { BOOL bReturn = FALSE;
if (m_bMatchLogicNot) { SDBERROR_FORMAT(( _T("LOGIC=\"NOT\" not supported on Win2k, add OS_VERSION=\"gte5.1\" to <EXE>:\n%s\n"), csXML)); goto eh; }
if (m_dwMask & (SDB_MATCHINGINFO_LINK_DATE | SDB_MATCHINGINFO_UPTO_LINK_DATE)) { SDBERROR_FORMAT(( _T("LINK_DATE and UPTO_LINK_DATE not supported on Win2k, add OS_VERSION=\"gte5.1\" to <EXE>:\n%s\n"), csXML)); goto eh; }
if (m_csCompanyName.FindOneOf(_T("*?")) != -1 || m_csProductName.FindOneOf(_T("*?")) != -1 || m_csProductVersion.FindOneOf(_T("*?")) != -1 || m_csFileDescription.FindOneOf(_T("*?")) != -1 || m_csFileVersion.FindOneOf(_T("*?")) != -1 || m_csOriginalFileName.FindOneOf(_T("*?")) != -1 || m_csInternalName.FindOneOf(_T("*?")) != -1 || m_csLegalCopyright.FindOneOf(_T("*?")) != -1 || m_cs16BitDescription.FindOneOf(_T("*?")) != -1 || m_cs16BitModuleName.FindOneOf(_T("*?")) != -1) { SDBERROR_FORMAT(( _T("Wildcards not supported on Win2k, add OS_VERSION=\"gte5.1\" to <EXE>:\n%s\n"), csXML)); goto eh; }
if ((m_ullBinFileVersion & 0x000000000000FFFF) == 0x000000000000FFFF || (m_ullBinProductVersion & 0x000000000000FFFF) == 0x000000000000FFFF) { SDBERROR_FORMAT(( _T("Non-exact matching on binary version not supported on Win2k, add OS_VERSION=\"gte5.1\" to <EXE>:\n%s\n"), csXML)); goto eh; }
bReturn = TRUE;
eh:
return bReturn; }
ULONGLONG SdbFlag::MakeMask(SdbRefArray<SdbFlag>* prgFlags, DWORD dwType) { SdbFlag* pFlag; long i; ULONGLONG ullMask = 0;
for (i = 0; i < prgFlags->GetSize(); i++) { pFlag = (SdbFlag *) prgFlags->GetAt(i);
if (pFlag->m_dwType == dwType) { ullMask |= pFlag->m_ullMask; } }
return ullMask; }
BOOL SdbFlag::SetType(CString csType) { csType.MakeUpper();
if (csType == _T("KERNEL")) { m_dwType = SDB_FLAG_KERNEL; } else if (csType == _T("USER")) { m_dwType = SDB_FLAG_USER; } else if (csType == _T("SHELL")) { m_dwType = SDB_FLAG_SHELL; } else if (csType == _T("FUSION")) { m_dwType = SDB_FLAG_FUSION; } else if (csType == _T("NTVDM1")) { m_dwType = SDB_FLAG_NTVDM1; } else if (csType == _T("NTVDM2")) { m_dwType = SDB_FLAG_NTVDM2; } else if (csType == _T("NTVDM3")) { m_dwType = SDB_FLAG_NTVDM3; } else { return FALSE; }
return TRUE; }
TAG SdbFlag::TagFromType(DWORD dwType) { TAG tReturn = TAG_NULL;
switch (dwType) {
case SDB_FLAG_KERNEL: tReturn = TAG_FLAG_MASK_KERNEL; break;
case SDB_FLAG_USER: tReturn = TAG_FLAG_MASK_USER; break;
case SDB_FLAG_SHELL: tReturn = TAG_FLAG_MASK_SHELL; break;
case SDB_FLAG_FUSION: tReturn = TAG_FLAG_MASK_FUSION; break;
case SDB_FLAG_NTVDM1: tReturn = TAG_FLAGS_NTVDM1; break;
case SDB_FLAG_NTVDM2: tReturn = TAG_FLAGS_NTVDM2; break;
case SDB_FLAG_NTVDM3: tReturn = TAG_FLAGS_NTVDM3; break;
default: break; }
return tReturn; }
|