Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3142 lines
84 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: read.cpp
  4. //
  5. // History: 16-Nov-00 markder Created.
  6. // 15-Jan-02 jdoherty Modified code to add ID to additional tags.
  7. //
  8. // Desc: This file contains all code needed to manipulate the MSXML
  9. // COM object, walk the document object model (DOM) for an XML
  10. // file, and populate the SdbDatabase internal C++ object.
  11. //
  12. ////////////////////////////////////////////////////////////////////////////////////
  13. #include "StdAfx.h"
  14. #include "xml.h"
  15. #include "make.h"
  16. #include "typeinfo.h"
  17. typedef struct tagAttrStringTableEntry {
  18. LPCTSTR pszName;
  19. DWORD dwValue;
  20. } ATTRSTRINGTABLEENTRY, *PATTRSTRINGTABLEENTRY;
  21. ATTRSTRINGTABLEENTRY g_rgStringSeverity[] = {
  22. { _T("HARDBLOCK" ), SDB_APPHELP_HARDBLOCK},
  23. { _T("MINORPROBLEM"), SDB_APPHELP_MINORPROBLEM},
  24. { _T("NOBLOCK" ), SDB_APPHELP_NOBLOCK},
  25. { _T("REINSTALL" ), SDB_APPHELP_REINSTALL},
  26. { _T("SHIM" ), SDB_APPHELP_SHIM},
  27. { _T("VERSIONSUB" ), SDB_APPHELP_VERSIONSUB},
  28. { _T("NONE" ), SDB_APPHELP_NONE}
  29. };
  30. ATTRSTRINGTABLEENTRY g_rgStringModuleType[] = {
  31. { _T("NONE"), MT_UNKNOWN_MODULE},
  32. { _T("UNKNOWN"), MT_UNKNOWN_MODULE},
  33. { _T("WIN16"), MT_W16_MODULE},
  34. { _T("WIN32"), MT_W32_MODULE},
  35. { _T("DOS"), MT_DOS_MODULE},
  36. };
  37. ATTRSTRINGTABLEENTRY g_rgStringYesNo[] = {
  38. { _T("YES"), TRUE},
  39. { _T("NO"), FALSE}
  40. };
  41. ATTRSTRINGTABLEENTRY g_rgStringDataType[] = {
  42. { _T("DWORD"), eValueDWORD},
  43. { _T("QWORD"), eValueQWORD},
  44. { _T("STRING"), eValueString},
  45. { _T("BINARY"), eValueBinary},
  46. { _T("NONE"), eValueNone}
  47. };
  48. ATTRSTRINGTABLEENTRY g_rgStringOSSKUType[] = {
  49. { _T("PER"), OS_SKU_PER},
  50. { _T("PRO"), OS_SKU_PRO},
  51. { _T("SRV"), OS_SKU_SRV},
  52. { _T("ADS"), OS_SKU_ADS},
  53. { _T("DTC"), OS_SKU_DTC},
  54. { _T("BLA"), OS_SKU_BLA},
  55. { _T("TAB"), OS_SKU_TAB},
  56. { _T("MED"), OS_SKU_MED},
  57. };
  58. ATTRSTRINGTABLEENTRY g_rgStringOSPlatform[] = {
  59. { _T("I386"), OS_PLATFORM_I386},
  60. { _T("IA64"), OS_PLATFORM_IA64}
  61. };
  62. ATTRSTRINGTABLEENTRY g_rgStringRuntimePlatformType[] = {
  63. { _T("X86"), PROCESSOR_ARCHITECTURE_INTEL}, // x86
  64. { _T("IA64"), PROCESSOR_ARCHITECTURE_IA64}, // ia64
  65. { _T("AMD64"), PROCESSOR_ARCHITECTURE_AMD64}, // amd64
  66. { _T("IA3264"), PROCESSOR_ARCHITECTURE_IA32_ON_WIN64} // this means running in wow on ia64
  67. };
  68. ATTRSTRINGTABLEENTRY g_rgStringFilter[] = {
  69. { _T("FIX"), SDB_FILTER_FIX},
  70. { _T("APPHELP"), SDB_FILTER_APPHELP},
  71. { _T("MSI"), SDB_FILTER_MSI},
  72. { _T("DRIVER"), SDB_FILTER_DRIVER},
  73. { _T("NTCOMPAT"), SDB_FILTER_NTCOMPAT},
  74. { _T("CUSTOM"), SDB_FILTER_INCLUDE_ALL}
  75. };
  76. ATTRSTRINGTABLEENTRY g_rgStringOutputType[] = {
  77. { _T("SDB"), SDB_OUTPUT_TYPE_SDB},
  78. { _T("HTMLHELP"), SDB_OUTPUT_TYPE_HTMLHELP},
  79. { _T("MIGDB_INX"), SDB_OUTPUT_TYPE_MIGDB_INX},
  80. { _T("MIGDB_TXT"), SDB_OUTPUT_TYPE_MIGDB_TXT},
  81. { _T("WIN2K_REGISTRY"), SDB_OUTPUT_TYPE_WIN2K_REGISTRY},
  82. { _T("REDIR_MAP"), SDB_OUTPUT_TYPE_REDIR_MAP},
  83. { _T("NTCOMPAT_INF"), SDB_OUTPUT_TYPE_NTCOMPAT_INF},
  84. { _T("NTCOMPAT_MESSAGE_INF"), SDB_OUTPUT_TYPE_NTCOMPAT_MESSAGE_INF},
  85. { _T("APPHELP_REPORT"), SDB_OUTPUT_TYPE_APPHELP_REPORT}
  86. };
  87. ATTRSTRINGTABLEENTRY g_rgStringMatchModeType[] = {
  88. { _T("NORMAL"), MATCHMODE_NORMAL_SHIMDBC },
  89. { _T("EXCLUSIVE"), MATCHMODE_EXCLUSIVE_SHIMDBC },
  90. { _T("ADDITIVE"), MATCHMODE_ADDITIVE_SHIMDBC }
  91. };
  92. LPCTSTR EncodeStringAttribute(
  93. DWORD dwValue,
  94. PATTRSTRINGTABLEENTRY pTable,
  95. int nSize)
  96. {
  97. static LPCTSTR pszUnknown = _T("UNKNOWN");
  98. int i;
  99. for (i = 0; i < nSize; ++i, ++pTable) {
  100. if (dwValue == pTable->dwValue) {
  101. return(pTable->pszName);
  102. }
  103. }
  104. return pszUnknown;
  105. }
  106. BOOL DecodeStringAttribute(
  107. LPCTSTR lpszAttribute,
  108. PATTRSTRINGTABLEENTRY pTable,
  109. int nSize,
  110. DWORD* pdwValue)
  111. {
  112. int i;
  113. //
  114. // Find the indicator and return the flag
  115. //
  116. for (i = 0; i < nSize; ++i, ++pTable) {
  117. if (0 == _tcsicmp(lpszAttribute, pTable->pszName)) {
  118. if (NULL != pdwValue) {
  119. *pdwValue = pTable->dwValue;
  120. }
  121. break;
  122. }
  123. }
  124. return i < nSize;
  125. }
  126. LPCTSTR SeverityIndicatorToStr(SdbAppHelpType Severity)
  127. {
  128. return(EncodeStringAttribute((DWORD)Severity, g_rgStringSeverity, ARRAYSIZE(g_rgStringSeverity)));
  129. }
  130. LPCTSTR ModuleTypeIndicatorToStr(DWORD ModuleType)
  131. {
  132. return(EncodeStringAttribute(ModuleType, g_rgStringModuleType, ARRAYSIZE(g_rgStringModuleType)));
  133. }
  134. #define GetSeverityIndicator(lpszSeverity, pSeverity) \
  135. DecodeStringAttribute(lpszSeverity, g_rgStringSeverity, ARRAYSIZE(g_rgStringSeverity), (DWORD*)pSeverity)
  136. #define GetModuleTypeIndicator(lpszModuleType, pModuleType) \
  137. DecodeStringAttribute(lpszModuleType, g_rgStringModuleType, ARRAYSIZE(g_rgStringModuleType), pModuleType)
  138. #define GetVersionSubIndicator(lpszVersionSub, pVersionSub) \
  139. DecodeStringAttribute(lpszVersionSub, g_rgStringVersionSub, ARRAYSIZE(g_rgStringVersionSub), pVersionSub)
  140. #define GetYesNoIndicator(lpszYesNo, pYesNo) \
  141. DecodeStringAttribute(lpszYesNo, g_rgStringYesNo, ARRAYSIZE(g_rgStringYesNo), pYesNo)
  142. #define GetDataTypeIndicator(lpszDataType, pDataType) \
  143. DecodeStringAttribute(lpszDataType, g_rgStringDataType, ARRAYSIZE(g_rgStringDataType), pDataType)
  144. DWORD GetOSSKUType(LPCTSTR szOSSKUType)
  145. {
  146. DWORD dwReturn = OS_SKU_NONE;
  147. DecodeStringAttribute(szOSSKUType, g_rgStringOSSKUType, ARRAYSIZE(g_rgStringOSSKUType), &dwReturn);
  148. return dwReturn;
  149. }
  150. DWORD GetOSPlatform(LPCTSTR szOSPlatform)
  151. {
  152. DWORD dwReturn = OS_PLATFORM_NONE;
  153. DecodeStringAttribute(szOSPlatform, g_rgStringOSPlatform, ARRAYSIZE(g_rgStringOSPlatform), &dwReturn);
  154. return dwReturn;
  155. }
  156. DWORD GetRuntimePlatformType(LPCTSTR szPlatformType)
  157. {
  158. DWORD dwReturn = PROCESSOR_ARCHITECTURE_UNKNOWN;
  159. DecodeStringAttribute(szPlatformType, g_rgStringRuntimePlatformType, ARRAYSIZE(g_rgStringRuntimePlatformType), &dwReturn);
  160. return dwReturn;
  161. }
  162. DWORD GetFilter(LPCTSTR szFilter)
  163. {
  164. DWORD dwReturn = SDB_FILTER_EXCLUDE_ALL;
  165. CString csFilter(szFilter);
  166. CString csFilterBit;
  167. DWORD dwFilterBit = 0;
  168. long i;
  169. for (i = 0; i <= csFilter.GetLength(); i++) {
  170. switch (csFilter.GetAt(i)) {
  171. case _T(' '):
  172. break;
  173. case _T('|'):
  174. case _T('\0'):
  175. DecodeStringAttribute(csFilterBit, g_rgStringFilter, ARRAYSIZE(g_rgStringFilter), &dwFilterBit);
  176. dwReturn |= dwFilterBit;
  177. csFilterBit.Empty();
  178. break;
  179. default:
  180. csFilterBit += csFilter.GetAt(i);
  181. break;
  182. }
  183. }
  184. return dwReturn;
  185. }
  186. SdbOutputType GetOutputType(LPCTSTR szOutputType)
  187. {
  188. DWORD dwReturn = SDB_OUTPUT_TYPE_UNKNOWN;
  189. DecodeStringAttribute(szOutputType, g_rgStringOutputType, ARRAYSIZE(g_rgStringOutputType), &dwReturn);
  190. return (SdbOutputType) dwReturn;
  191. }
  192. //////////////////////////////////////////////////////////////////////////////////////
  193. //
  194. // ProcureGuidIDAttribute
  195. //
  196. // retrieve Guid "ID" attribute for a given node, possibly update the source and
  197. // generate the attribute if it was not found
  198. //
  199. BOOL ProcureGuidIDAttribute(
  200. SdbDatabase* pDB,
  201. IXMLDOMNode* pNode,
  202. GUID* pGuid,
  203. CString* pcsGUID
  204. )
  205. {
  206. CString csID;
  207. BOOL bSuccess = FALSE;
  208. if (!GetAttribute(_T("ID"), pNode, &csID)) {
  209. if (!GenerateIDAttribute(pNode, &csID, pGuid)) {
  210. SDBERROR_FORMAT((_T("Error generating ID attribute for the node\n%s\n"),
  211. GetXML(pNode)));
  212. goto eh;
  213. }
  214. pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE;
  215. } else {
  216. if (!GUIDFromString(csID, pGuid)) {
  217. //
  218. // This is the case when we cannot parse the guid and it appears to be
  219. // an invalid guid.
  220. //
  221. SDBERROR_FORMAT((_T("ID attribute is not a valid GUID\n%s\n"), csID));
  222. goto eh;
  223. }
  224. }
  225. if (pcsGUID != NULL) {
  226. *pcsGUID = csID;
  227. }
  228. bSuccess = TRUE;
  229. eh:
  230. return bSuccess;
  231. }
  232. ////////////////////////////////////////////////////////////////////////////////////
  233. //
  234. // Func: GetNextSequentialID
  235. //
  236. // Desc: Determines the next available sequential to be generated.
  237. //
  238. DWORD SdbDatabase::GetNextSequentialID(CString csType)
  239. {
  240. CString csMaxID, csID;
  241. IXMLDOMNodePtr cpXMLAppHelp;
  242. DWORD dwMaxID = 0;
  243. DWORD dwMaxReportedID = 0;
  244. DWORD dwMaxEmpiricalID = 0;
  245. XMLNodeList XQL;
  246. long i;
  247. //
  248. // Determine largest ID
  249. //
  250. if (GetAttribute(_T("MAX_") + csType,
  251. m_cpCurrentDatabaseNode,
  252. &csMaxID)) {
  253. dwMaxReportedID = _ttol(csMaxID);
  254. }
  255. DWORD dwID = 0;
  256. if (!XQL.Query(m_cpCurrentDatabaseNode, _T("//@") + csType)) {
  257. SDBERROR_PROPOGATE();
  258. goto eh;
  259. }
  260. for (i = 0; i < XQL.GetSize(); i++) {
  261. if (!XQL.GetItem(i, &cpXMLAppHelp)) {
  262. SDBERROR_PROPOGATE();
  263. goto eh;
  264. }
  265. csID = GetText(cpXMLAppHelp);
  266. if (csID.GetLength()) {
  267. dwID = _ttol(csID);
  268. if (dwID > dwMaxEmpiricalID) {
  269. dwMaxEmpiricalID = dwID;
  270. }
  271. }
  272. cpXMLAppHelp.Release();
  273. }
  274. if (dwMaxEmpiricalID > dwMaxReportedID) {
  275. dwMaxID = dwMaxEmpiricalID;
  276. } else {
  277. dwMaxID = dwMaxReportedID;
  278. }
  279. dwMaxID++;
  280. csMaxID.Format(_T("%d"), dwMaxID);
  281. if (!AddAttribute(m_cpCurrentDatabaseNode,
  282. _T("MAX_") + csType, csMaxID)) {
  283. }
  284. m_pCurrentInputFile->m_bSourceUpdated = TRUE;
  285. eh:
  286. return dwMaxID;
  287. }
  288. ////////////////////////////////////////////////////////////////////////////////////
  289. //
  290. // Func: ReadDatabase
  291. //
  292. // Desc: Opens an XML file and calls read on the database object.
  293. //
  294. BOOL ReadDatabase(
  295. SdbInputFile* pInputFile,
  296. SdbDatabase* pDatabase)
  297. {
  298. BOOL bSuccess = FALSE;
  299. IXMLDOMNodePtr cpRootNode;
  300. IXMLDOMNodePtr cpDatabase;
  301. XMLNodeList XQL;
  302. if (!OpenXML(pInputFile->m_csName, &cpRootNode)) {
  303. SDBERROR_PROPOGATE();
  304. goto eh;
  305. }
  306. if (!GetChild(_T("DATABASE"), cpRootNode, &cpDatabase)) {
  307. SDBERROR(_T("<DATABASE> object not found"));
  308. goto eh;
  309. }
  310. pDatabase->m_cpCurrentDatabaseNode = cpDatabase;
  311. if (!pDatabase->ReadFromXML(cpDatabase, pDatabase)) {
  312. SDBERROR_PROPOGATE();
  313. goto eh;
  314. }
  315. if (pInputFile->m_bSourceUpdated) {
  316. //
  317. // We need to modify original XML file
  318. //
  319. if (!SaveXMLFile(pInputFile->m_csName, cpDatabase)) {
  320. SDBERROR_PROPOGATE();
  321. goto eh;
  322. }
  323. }
  324. bSuccess = TRUE;
  325. eh:
  326. pDatabase->m_cpCurrentDatabaseNode = NULL;
  327. return bSuccess;
  328. }
  329. ////////////////////////////////////////////////////////////////////////////////////
  330. //
  331. // Func: ReadCallers
  332. //
  333. // Desc: Reads in all <INCLUDE> and <EXCLUDE> child tags on node pNode and
  334. // adds them as SdbCaller objects to the array pointed to by prgCallers.
  335. //
  336. BOOL ReadCallers(
  337. SdbArray<SdbCaller>* prgCallers,
  338. SdbDatabase* pDB,
  339. IXMLDOMNode* pNode)
  340. {
  341. USES_CONVERSION;
  342. BOOL bSuccess = FALSE;
  343. long nIndex = 0;
  344. long nListLength = 0;
  345. IXMLDOMNodePtr cpCallerNode;
  346. XMLNodeList NodeList;
  347. SdbCaller* pSdbCaller = NULL;
  348. CString csNodeName, csTemp;
  349. if (!NodeList.GetChildNodes(pNode)) {
  350. //
  351. // No child nodes -- that's fine, return success.
  352. //
  353. bSuccess = TRUE;
  354. goto eh;
  355. }
  356. for (nIndex = 0; nIndex < NodeList.GetSize(); nIndex++) {
  357. if (!NodeList.GetItem(nIndex, &cpCallerNode)) {
  358. SDBERROR(_T("Could not retrieve INCLUDE/EXCLUDE item"));
  359. goto eh;
  360. }
  361. if (GetNodeName(cpCallerNode) == _T("INCLUDE") ||
  362. GetNodeName(cpCallerNode) == _T("EXCLUDE")) {
  363. pSdbCaller = new SdbCaller();
  364. if (pSdbCaller == NULL) {
  365. SDBERROR(_T("Error allocating SdbCaller object"));
  366. goto eh;
  367. }
  368. if (!pSdbCaller->ReadFromXML(cpCallerNode, pDB)) {
  369. SDBERROR_PROPOGATE();
  370. delete pSdbCaller;
  371. pSdbCaller = NULL;
  372. goto eh;
  373. }
  374. //
  375. // Add in reverse order to help the Shim engine's logic
  376. // building code
  377. //
  378. prgCallers->InsertAt(0, pSdbCaller);
  379. pSdbCaller = NULL;
  380. }
  381. cpCallerNode.Release();
  382. }
  383. bSuccess = TRUE;
  384. eh:
  385. return bSuccess;
  386. }
  387. BOOL ReadLocalizedNames(
  388. SdbArray<SdbLocalizedString>* prgNames,
  389. CString csTag,
  390. SdbDatabase* pDB,
  391. IXMLDOMNode* pNode)
  392. {
  393. BOOL bSuccess = FALSE;
  394. IXMLDOMNodePtr cpTag;
  395. XMLNodeList XQL;
  396. CString csTemp, csLangID, csName;
  397. SdbLocalizedString* pLocString = NULL;
  398. long i;
  399. if (!XQL.Query(pNode, csTag)) {
  400. SDBERROR_PROPOGATE();
  401. goto eh;
  402. }
  403. for (i = 0; i < XQL.GetSize(); i++) {
  404. CString csID;
  405. GUID ID = GUID_NULL;
  406. if (!XQL.GetItem(i, &cpTag)) {
  407. SDBERROR_PROPOGATE();
  408. goto eh;
  409. }
  410. if (!GetAttribute(_T("LANGID"), cpTag, &csLangID)) {
  411. if (!pDB->m_csCurrentLangID.GetLength())
  412. {
  413. SDBERROR_FORMAT((
  414. _T("LOCALIZED_NAME tag requires LANGID attribute if there is no LANGID on the DATABASE node\n%s\n"),
  415. GetXML(cpTag)));
  416. goto eh;
  417. }
  418. csLangID = pDB->m_csCurrentLangID;
  419. }
  420. if (!ProcureGuidIDAttribute(pDB, cpTag, &ID, &csID)) {
  421. SDBERROR_PROPOGATE();
  422. goto eh;
  423. }
  424. if (!GetAttribute(_T("NAME"), cpTag, &csName)) {
  425. SDBERROR_FORMAT((
  426. _T("LOCALIZED_NAME tag requires NAME attribute:\n%s\n"),
  427. GetXML(cpTag)));
  428. goto eh;
  429. }
  430. pLocString = new SdbLocalizedString();
  431. pLocString->m_csName = csName;
  432. pLocString->m_csLangID = csLangID;
  433. pLocString->m_csValue = GetInnerXML(cpTag);
  434. prgNames->Add(pLocString);
  435. }
  436. bSuccess = TRUE;
  437. eh:
  438. return bSuccess;
  439. }
  440. BOOL SdbDatabase::ReadFromXML(
  441. IXMLDOMNode* pNode,
  442. SdbDatabase* pDB)
  443. {
  444. BOOL bSuccess = FALSE;
  445. long i;
  446. long nListCount = 0;
  447. IXMLDOMNodePtr cpXMLLibrary;
  448. IXMLDOMNodePtr cpXMLAppHelp;
  449. IXMLDOMNodePtr cpXMLA;
  450. IXMLDOMNodePtr cpXMLHTMLHELPTemplate;
  451. IXMLDOMNodePtr cpXMLHTMLHELPFirstScreen;
  452. CString csHTMLHELPID, csXQL, csHistoryClause;
  453. CString csID, csRedirID, csRedirURL, csOSVersion;
  454. CString csTemplateName;
  455. DWORD dwHTMLHELPID = 0;
  456. XMLNodeList XQL;
  457. SdbLocalizedString* pRedir = NULL;
  458. SdbLocalizedString* pHTMLHelpTemplate = NULL;
  459. SdbLocalizedString* pHTMLHelpFirstScreen = NULL;
  460. //
  461. // Read the name of the database
  462. //
  463. ReadName(pNode, &m_csName);
  464. //
  465. // Read the LangID for this database file
  466. //
  467. m_csCurrentLangID = _T("---");
  468. GetAttribute(_T("LANGID"), pNode, &m_csCurrentLangID);
  469. //
  470. // Read the default ID
  471. //
  472. if (!GetAttribute(_T("ID"), pNode, &csID)) {
  473. //
  474. // Guid was not found. We need to generate it.
  475. //
  476. if (!GenerateIDAttribute(pNode, &csID, &m_ID)) {
  477. SDBERROR_FORMAT((_T("Error generating ID attribute for the node\n%s\n"),
  478. GetXML(pNode)));
  479. goto eh;
  480. }
  481. pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE;
  482. } else if (!GUIDFromString(csID, &m_ID)) {
  483. //
  484. // This is the case when we cannot parse the guid and it appears to be
  485. // an invalid guid.
  486. //
  487. SDBERROR_FORMAT((_T("ID attribute is not a valid GUID\n%s\n"), csID));
  488. goto eh;
  489. }
  490. //
  491. // Add REDIR_IDs to <A> tags if necessary
  492. //
  493. if (!XQL.Query(pNode, _T("//A"))) {
  494. SDBERROR_PROPOGATE();
  495. goto eh;
  496. }
  497. for (i = 0; i < XQL.GetSize(); i++) {
  498. if (!XQL.GetItem(i, &cpXMLA)) {
  499. SDBERROR_PROPOGATE();
  500. goto eh;
  501. }
  502. if (!GetAttribute(_T("REDIR_ID"), cpXMLA, &csRedirID)) {
  503. //
  504. // Not there, generate it.
  505. //
  506. csRedirID.Format(_T("%d"), GetNextSequentialID(_T("REDIR_ID")));
  507. if (!AddAttribute(cpXMLA, _T("REDIR_ID"), csRedirID)) {
  508. SDBERROR_PROPOGATE();
  509. goto eh;
  510. }
  511. }
  512. if (!GetAttribute(_T("HREF"), cpXMLA, &csRedirURL)) {
  513. //
  514. // No HREF attribute. Take the link from the display name.
  515. //
  516. csRedirURL = GetText(cpXMLA);
  517. }
  518. pRedir = (SdbLocalizedString *) m_rgRedirs.LookupName(csRedirID, m_csCurrentLangID);
  519. if (pRedir) {
  520. SDBERROR_FORMAT((_T("Non-unique REDIR_ID:\n%s\n"), GetXML(cpXMLA)));
  521. goto eh;
  522. }
  523. pRedir = new SdbLocalizedString();
  524. pRedir->m_csName = csRedirID;
  525. pRedir->m_csLangID = m_csCurrentLangID;
  526. pRedir->m_csValue = csRedirURL;
  527. m_rgRedirs.Add(pRedir);
  528. cpXMLA = NULL;
  529. }
  530. //
  531. // Read HTMLHELP_TEMPLATE
  532. //
  533. if (!XQL.Query(pNode, _T("HTMLHELP_TEMPLATE"))) {
  534. SDBERROR_PROPOGATE();
  535. goto eh;
  536. }
  537. for (i = 0; i < XQL.GetSize(); i++) {
  538. if (!XQL.GetItem(i, &cpXMLHTMLHELPTemplate)) {
  539. SDBERROR_PROPOGATE();
  540. goto eh;
  541. }
  542. if (!GetAttribute(_T("NAME"), cpXMLHTMLHELPTemplate, &csTemplateName)) {
  543. SDBERROR_FORMAT((_T("HTMLHELP_TEMPLATE requires NAME attribute:\n%s\n"),
  544. GetXML(cpXMLHTMLHELPTemplate)));
  545. goto eh;
  546. }
  547. pHTMLHelpTemplate = new SdbLocalizedString();
  548. pHTMLHelpTemplate->m_csName = csTemplateName;
  549. pHTMLHelpTemplate->m_csLangID = m_csCurrentLangID;
  550. pHTMLHelpTemplate->m_csValue = GetInnerXML(cpXMLHTMLHELPTemplate);
  551. m_rgHTMLHelpTemplates.Add(pHTMLHelpTemplate);
  552. }
  553. //
  554. // Read HTMLHELP_FIRST_SCREEN
  555. //
  556. if (!XQL.Query(pNode, _T("HTMLHELP_FIRST_SCREEN"))) {
  557. SDBERROR_PROPOGATE();
  558. goto eh;
  559. }
  560. if (XQL.GetSize() > 1) {
  561. SDBERROR(_T("More than one HTMLHELP_FIRST_SCREEN tags found:\n%s\n"));
  562. goto eh;
  563. }
  564. if (XQL.GetSize() == 1) {
  565. if (!XQL.GetItem(0, &cpXMLHTMLHELPFirstScreen)) {
  566. SDBERROR_PROPOGATE();
  567. goto eh;
  568. }
  569. pHTMLHelpFirstScreen = new SdbLocalizedString();
  570. pHTMLHelpFirstScreen->m_csName = _T("HTMLHELP_FIRST_SCREEN");
  571. pHTMLHelpFirstScreen->m_csLangID = m_csCurrentLangID;
  572. pHTMLHelpFirstScreen->m_csValue = GetInnerXML(cpXMLHTMLHELPFirstScreen);
  573. m_rgHTMLHelpFirstScreens.Add(pHTMLHelpFirstScreen);
  574. }
  575. //
  576. // Read Library
  577. //
  578. if (!XQL.Query(pNode, _T("LIBRARY"))) {
  579. SDBERROR_PROPOGATE();
  580. goto eh;
  581. }
  582. for (i = 0; i < XQL.GetSize(); i++) {
  583. if (!XQL.GetItem(i, &cpXMLLibrary)) {
  584. SDBERROR_PROPOGATE();
  585. goto eh;
  586. }
  587. if (!m_Library.ReadFromXML(cpXMLLibrary, this)) {
  588. SDBERROR_PROPOGATE();
  589. goto eh;
  590. }
  591. cpXMLLibrary.Release();
  592. }
  593. //
  594. // Action tags
  595. //
  596. if (!m_rgAction.ReadFromXML(_T("ACTION"), pDB, pNode, NULL)) {
  597. SDBERROR_PROPOGATE();
  598. goto eh;
  599. }
  600. //
  601. // Construct XQL from m_prgHistoryKeywords
  602. //
  603. if (m_pCurrentMakefile->m_rgHistoryKeywords.GetSize() > 0) {
  604. for (i = 0; i < m_pCurrentMakefile->m_rgHistoryKeywords.GetSize(); i++) {
  605. if (i > 0) {
  606. csHistoryClause += _T(" or ");
  607. }
  608. csHistoryClause = _T("KEYWORD/@NAME = '") +
  609. m_pCurrentMakefile->m_rgHistoryKeywords.GetAt(i) + _T("'");
  610. }
  611. csXQL = _T("APP[") + csHistoryClause + _T("]");
  612. csXQL += _T(" | DRIVER[") + csHistoryClause + _T("]");
  613. } else {
  614. csXQL = _T("APP | DRIVER");
  615. }
  616. if (!m_rgApps.ReadFromXML(csXQL, pDB, pNode)) {
  617. SDBERROR_PROPOGATE();
  618. goto eh;
  619. }
  620. m_pDB = this;
  621. bSuccess = TRUE;
  622. eh:
  623. return bSuccess;
  624. }
  625. BOOL SdbLibrary::ReadFromXML(
  626. IXMLDOMNode* pNode,
  627. SdbDatabase* pDB)
  628. {
  629. BOOL bSuccess = FALSE;
  630. if (!m_rgFiles.ReadFromXML(_T(".//FILE"), pDB, pNode)) {
  631. SDBERROR_PROPOGATE();
  632. goto eh;
  633. }
  634. if (!m_rgShims.ReadFromXML(_T("SHIM"), pDB, pNode)) {
  635. SDBERROR_PROPOGATE();
  636. goto eh;
  637. }
  638. if (!m_rgPatches.ReadFromXML(_T("PATCH"), pDB, pNode)) {
  639. SDBERROR_PROPOGATE();
  640. goto eh;
  641. }
  642. if (!m_rgFlags.ReadFromXML(_T("FLAG"), pDB, pNode)) {
  643. SDBERROR_PROPOGATE();
  644. goto eh;
  645. }
  646. if (!m_rgLayers.ReadFromXML(_T("LAYER"), pDB, pNode)) {
  647. SDBERROR_PROPOGATE();
  648. goto eh;
  649. }
  650. if (!m_rgMsiTransforms.ReadFromXML(_T("MSI_TRANSFORM"), pDB, pNode)) {
  651. SDBERROR_PROPOGATE();
  652. goto eh;
  653. }
  654. if (!pDB->m_rgContactInfo.ReadFromXML(_T("CONTACT_INFO"), pDB, pNode, NULL, FALSE, _T("VENDOR"))) {
  655. SDBERROR_PROPOGATE();
  656. goto eh;
  657. }
  658. if (!pDB->m_rgMessageTemplates.ReadFromXML(_T("TEMPLATE"), pDB, pNode)) {
  659. SDBERROR_PROPOGATE();
  660. goto eh;
  661. }
  662. if (!pDB->m_rgMessages.ReadFromXML(_T("MESSAGE"), pDB, pNode)) {
  663. SDBERROR_PROPOGATE();
  664. goto eh;
  665. }
  666. if (!ReadCallers(&m_rgCallers, pDB, pNode)) {
  667. SDBERROR_PROPOGATE();
  668. goto eh;
  669. }
  670. if (!ReadLocalizedNames(
  671. &(pDB->m_rgLocalizedAppNames), _T("LOCALIZED_APP_NAME"), pDB, pNode)) {
  672. SDBERROR_PROPOGATE();
  673. goto eh;
  674. }
  675. if (!ReadLocalizedNames(
  676. &(pDB->m_rgLocalizedVendorNames), _T("LOCALIZED_VENDOR_NAME"), pDB, pNode)) {
  677. SDBERROR_PROPOGATE();
  678. goto eh;
  679. }
  680. m_pDB = pDB;
  681. bSuccess = TRUE;
  682. eh:
  683. return bSuccess;
  684. }
  685. BOOL SdbFile::ReadFromXML(
  686. IXMLDOMNode* pNode,
  687. SdbDatabase* pDB)
  688. {
  689. BOOL bSuccess = FALSE;
  690. CString csFilter;
  691. if (!ReadName(pNode, &m_csName)) {
  692. SDBERROR_PROPOGATE();
  693. goto eh;
  694. }
  695. if (GetAttribute(_T("FILTER"), pNode, &csFilter)) {
  696. m_dwFilter = GetFilter(csFilter) | SDB_FILTER_OVERRIDE;
  697. }
  698. m_pDB = pDB;
  699. bSuccess = TRUE;
  700. eh:
  701. return bSuccess;
  702. }
  703. BOOL SdbShim::ReadFromXML(
  704. IXMLDOMNode* pNode,
  705. SdbDatabase* pDB)
  706. {
  707. BOOL bSuccess = FALSE;
  708. long i;
  709. CString csTemp, csID;
  710. IXMLDOMNodePtr cpDesc;
  711. if (!ReadName(pNode, &m_csName)) {
  712. SDBERROR_PROPOGATE();
  713. goto eh;
  714. }
  715. if (!GetAttribute(_T("FILE"), pNode, &m_csDllFile) && g_bStrict) {
  716. SDBERROR_FORMAT((_T("<SHIM> requires FILE attribute:\n%s\n\n"),
  717. GetXML(pNode)));
  718. goto eh;
  719. }
  720. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  721. SDBERROR_PROPOGATE();
  722. goto eh;
  723. }
  724. if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) {
  725. m_csDesc = GetText(cpDesc);
  726. }
  727. csTemp.Empty();
  728. if (GetAttribute(_T("PURPOSE"), pNode, &csTemp)) {
  729. if (csTemp == _T("GENERAL")) {
  730. m_Purpose = SDB_PURPOSE_GENERAL;
  731. } else {
  732. m_Purpose = SDB_PURPOSE_SPECIFIC;
  733. }
  734. }
  735. //
  736. // Check what OS PLATFORM this entry is meant for
  737. //
  738. csTemp.Empty();
  739. if (GetAttribute(_T("OS_PLATFORM"), pNode, &csTemp)) {
  740. //
  741. // Decode it. This string is a semi-colon delimited set
  742. // of OS PLATFORMs.
  743. //
  744. if (!DecodeString(csTemp, &m_dwOSPlatform, GetOSPlatform)) {
  745. SDBERROR_FORMAT((_T("OS_PLATFORM attribute syntax error: %s"), csTemp));
  746. goto eh;
  747. }
  748. }
  749. csTemp.Empty();
  750. if (GetAttribute(_T("APPLY_ALL_SHIMS"), pNode, &csTemp)) {
  751. if (csTemp == _T("YES")) {
  752. m_bApplyAllShims = TRUE;
  753. }
  754. }
  755. if (!ReadCallers(&m_rgCallers, pDB, pNode)) {
  756. SDBERROR(_T("Could not read INCLUDE/EXCLUDE info of <SHIM> tag"));
  757. goto eh;
  758. }
  759. m_pDB = pDB;
  760. bSuccess = TRUE;
  761. eh:
  762. return bSuccess;
  763. }
  764. BOOL SdbShimRef::ReadFromXML(
  765. IXMLDOMNode* pNode,
  766. SdbDatabase* pDB)
  767. {
  768. BOOL bSuccess = FALSE;
  769. if (!ReadName(pNode, &m_csName)) {
  770. SDBERROR_PROPOGATE();
  771. goto eh;
  772. }
  773. m_pShim = (SdbShim *) pDB->m_Library.m_rgShims.LookupName(m_csName);
  774. if (m_pShim == NULL && g_bStrict) {
  775. SDBERROR_FORMAT((_T("SHIM \"%s\" not found in library:\n%s\n\n"),
  776. m_csName, GetXML(pNode)));
  777. goto eh;
  778. }
  779. GetAttribute(_T("COMMAND_LINE"), pNode, &m_csCommandLine);
  780. if (!ReadCallers(&m_rgCallers, pDB, pNode)) {
  781. SDBERROR(_T("Could not read INCLUDE/EXCLUDE info of <SHIM> tag"));
  782. goto eh;
  783. }
  784. // finally, read all the child data elements
  785. if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) {
  786. SDBERROR_PROPOGATE();
  787. goto eh;
  788. }
  789. m_pDB = pDB;
  790. bSuccess = TRUE;
  791. eh:
  792. return bSuccess;
  793. }
  794. BOOL SdbPatch::ReadFromXML(
  795. IXMLDOMNode* pNode,
  796. SdbDatabase* pDB)
  797. {
  798. BOOL bSuccess = FALSE;
  799. PATCHOP PatchOp;
  800. PATCHWRITEDATA PatchWriteData;
  801. PATCHMATCHDATA PatchMatchData;
  802. XMLNodeList NodeList;
  803. IXMLDOMNodePtr cpOpNode;
  804. long i;
  805. CString csNodeName, csError;
  806. CString csModule, csOffset;
  807. CString csID;
  808. DWORD dwByteCount = 0;
  809. BYTE* pBytes = NULL;
  810. if (!ReadName(pNode, &m_csName)) {
  811. SDBERROR_PROPOGATE();
  812. goto eh;
  813. }
  814. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  815. SDBERROR_PROPOGATE();
  816. goto eh;
  817. }
  818. //
  819. // NOTE: We don't write the patch description in the binary database
  820. // so there's no point reading it either.
  821. //
  822. NodeList.GetChildNodes(pNode);
  823. for (i = 0; i < NodeList.GetSize(); i++) {
  824. if (!NodeList.GetItem(i, &cpOpNode)) {
  825. SDBERROR(_T("Could not retrieve PATCH instructions"));
  826. goto eh;
  827. }
  828. csNodeName = GetNodeName(cpOpNode);
  829. if (csNodeName == _T("MATCH_BYTES")) {
  830. if (!GetAttribute(_T("MODULE"), cpOpNode, &csModule)) {
  831. csError.Format(_T("<MATCH_BYTES> requires MODULE attribute:\n%s\n"),
  832. GetXML(cpOpNode));
  833. SDBERROR(csError);
  834. goto eh;
  835. }
  836. if (!GetAttribute(_T("OFFSET"), cpOpNode, &csOffset)) {
  837. csError.Format(_T("<MATCH_BYTES> requires OFFSET attribute:\n%s\n"),
  838. GetXML(cpOpNode));
  839. SDBERROR(csError);
  840. goto eh;
  841. }
  842. PatchOp.dwOpcode = PMAT;
  843. PatchMatchData.rva.address = StringToDword(csOffset);
  844. if (csModule.GetLength() >= sizeof(PatchMatchData.rva.moduleName)) {
  845. csError.Format(_T("MODULE attribute greater than %d characters:\n%s\n"),
  846. sizeof(PatchMatchData.rva.moduleName) - 1,
  847. GetXML(cpOpNode));
  848. SDBERROR(csError);
  849. goto eh;
  850. }
  851. dwByteCount = GetByteStringSize(GetText(cpOpNode));
  852. if (dwByteCount == 0xFFFFFFFF) {
  853. csError.Format(_T("Bad byte string for patch operation:\n%s\n"),
  854. GetXML(cpOpNode));
  855. SDBERROR(csError);
  856. goto eh;
  857. }
  858. PatchMatchData.dwSizeData = dwByteCount;
  859. if (csModule == _T("%EXE%")) {
  860. PatchMatchData.rva.moduleName[0] = _T('\0');
  861. } else {
  862. StringCchCopy(PatchMatchData.rva.moduleName,
  863. ARRAYSIZE(PatchMatchData.rva.moduleName),
  864. csModule);
  865. }
  866. pBytes = (BYTE*) new BYTE[dwByteCount];
  867. if (pBytes == NULL) {
  868. SDBERROR(_T("Error allocating memory for <PATCH> block."));
  869. goto eh;
  870. }
  871. if (GetBytesFromString(GetText(cpOpNode), pBytes, dwByteCount) == 0xFFFFFFFF) {
  872. csError.Format(_T("Bad byte string for patch operation:\n%s\n"),
  873. GetXML(cpOpNode));
  874. SDBERROR(csError);
  875. goto eh;
  876. }
  877. PatchOp.dwNextOpcode = sizeof(DWORD) * 3
  878. + sizeof(RELATIVE_MODULE_ADDRESS)
  879. + dwByteCount;
  880. AddBlobBytes(&PatchOp, sizeof(DWORD) * 2);
  881. AddBlobBytes(&PatchMatchData, sizeof(DWORD) + sizeof(RELATIVE_MODULE_ADDRESS));
  882. AddBlobBytes(pBytes, dwByteCount);
  883. delete pBytes;
  884. pBytes = NULL;
  885. } else if (csNodeName == _T("WRITE_BYTES")) {
  886. if (!GetAttribute(_T("MODULE"), cpOpNode, &csModule)) {
  887. csError.Format(_T("<WRITE_BYTES> requires MODULE attribute:\n%s\n"),
  888. GetXML(cpOpNode));
  889. SDBERROR(csError);
  890. goto eh;
  891. }
  892. if (!GetAttribute(_T("OFFSET"), cpOpNode, &csOffset)) {
  893. csError.Format(_T("<WRITE_BYTES> requires OFFSET attribute:\n%s\n"),
  894. GetXML(cpOpNode));
  895. SDBERROR(csError);
  896. goto eh;
  897. }
  898. PatchOp.dwOpcode = PWD;
  899. PatchWriteData.rva.address = StringToDword(csOffset);
  900. if (csModule.GetLength() >= sizeof(PatchWriteData.rva.moduleName)) {
  901. csError.Format(_T("MODULE attribute greater than %d characters:\n%s\n"),
  902. sizeof(PatchWriteData.rva.moduleName) - 1,
  903. GetXML(cpOpNode));
  904. SDBERROR(csError);
  905. goto eh;
  906. }
  907. dwByteCount = GetByteStringSize(GetText(cpOpNode));
  908. if (dwByteCount == 0xFFFFFFFF) {
  909. csError.Format(_T("Bad byte string for patch operation:\n%s\n"),
  910. GetXML(cpOpNode));
  911. SDBERROR(csError);
  912. goto eh;
  913. }
  914. PatchWriteData.dwSizeData = dwByteCount;
  915. if (csModule == _T("%EXE%")) {
  916. PatchWriteData.rva.moduleName[0] = _T('\0');
  917. } else {
  918. StringCchCopy(PatchWriteData.rva.moduleName,
  919. ARRAYSIZE(PatchWriteData.rva.moduleName),
  920. csModule);
  921. }
  922. pBytes = (BYTE*) new BYTE[dwByteCount];
  923. if (pBytes == NULL) {
  924. SDBERROR(_T("Error allocating memory for <PATCH> block."));
  925. goto eh;
  926. }
  927. if (GetBytesFromString(GetText(cpOpNode), pBytes, dwByteCount) == 0xFFFFFFFF) {
  928. csError.Format(_T("Bad byte string for patch operation:\n%s\n"),
  929. GetXML(cpOpNode));
  930. SDBERROR(csError);
  931. goto eh;
  932. }
  933. PatchOp.dwNextOpcode = sizeof(DWORD) * 3
  934. + sizeof(RELATIVE_MODULE_ADDRESS)
  935. + dwByteCount;
  936. AddBlobBytes(&PatchOp, sizeof(DWORD) * 2);
  937. AddBlobBytes(&PatchWriteData, sizeof(DWORD) + sizeof(RELATIVE_MODULE_ADDRESS));
  938. AddBlobBytes(pBytes, dwByteCount);
  939. delete [] pBytes;
  940. pBytes = NULL;
  941. }
  942. cpOpNode.Release();
  943. }
  944. //
  945. // Add terminating NULL bytes
  946. //
  947. ZeroMemory(&PatchOp, sizeof(DWORD) * 2);
  948. AddBlobBytes(&PatchOp, sizeof(DWORD) * 2);
  949. m_pDB = pDB;
  950. bSuccess = TRUE;
  951. eh:
  952. return bSuccess;
  953. }
  954. BOOL SdbLayer::ReadFromXML(
  955. IXMLDOMNode* pNode,
  956. SdbDatabase* pDB)
  957. {
  958. BOOL bSuccess = FALSE;
  959. CString csID;
  960. CString csTemp;
  961. IXMLDOMNodePtr cpDesc;
  962. if (!ReadName(pNode, &m_csName)) {
  963. SDBERROR_PROPOGATE();
  964. goto eh;
  965. }
  966. if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) {
  967. m_csDesc = GetText(cpDesc);
  968. }
  969. //
  970. // Check what OS PLATFORM this entry is meant for
  971. //
  972. if (GetAttribute(_T("OS_PLATFORM"), pNode, &csTemp)) {
  973. //
  974. // Decode it. This string is a semi-colon delimited set
  975. // of OS PLATFORMs.
  976. //
  977. if (!DecodeString(csTemp, &m_dwOSPlatform, GetOSPlatform)) {
  978. SDBERROR_FORMAT((_T("OS_PLATFORM attribute syntax error: %s"), csTemp));
  979. goto eh;
  980. }
  981. }
  982. if (!m_rgShimRefs.ReadFromXML(_T("SHIM"), pDB, pNode)) {
  983. SDBERROR_PROPOGATE();
  984. goto eh;
  985. }
  986. if (!m_rgFlagRefs.ReadFromXML(_T("FLAG"), pDB, pNode)) {
  987. SDBERROR_PROPOGATE();
  988. goto eh;
  989. }
  990. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  991. SDBERROR_PROPOGATE();
  992. goto eh;
  993. }
  994. GetAttribute(_T("DISPLAY_NAME"), pNode, &m_csDisplayName);
  995. m_pDB = pDB;
  996. bSuccess = TRUE;
  997. eh:
  998. return bSuccess;
  999. }
  1000. BOOL SdbLayerRef::ReadFromXML(
  1001. IXMLDOMNode* pNode,
  1002. SdbDatabase* pDB)
  1003. {
  1004. BOOL bSuccess = FALSE;
  1005. if (!ReadName(pNode, &m_csName)) {
  1006. SDBERROR_PROPOGATE();
  1007. goto eh;
  1008. }
  1009. m_pLayer = (SdbLayer*) pDB->m_Library.m_rgLayers.LookupName(m_csName);
  1010. //
  1011. // finally, read all the child data elements
  1012. //
  1013. if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) {
  1014. SDBERROR_PROPOGATE();
  1015. goto eh;
  1016. }
  1017. m_pDB = pDB;
  1018. bSuccess = TRUE;
  1019. eh:
  1020. return bSuccess;
  1021. }
  1022. BOOL SdbCaller::ReadFromXML(
  1023. IXMLDOMNode* pNode,
  1024. SdbDatabase* pDB)
  1025. {
  1026. BOOL bSuccess = FALSE;
  1027. CString csNodeName, csTemp;
  1028. csNodeName = GetNodeName(pNode);
  1029. if (csNodeName == _T("INCLUDE")) {
  1030. m_CallerType = SDB_CALLER_INCLUDE;
  1031. } else if (csNodeName == _T("EXCLUDE")) {
  1032. m_CallerType = SDB_CALLER_EXCLUDE;
  1033. }
  1034. if (!GetAttribute(_T("MODULE"), pNode, &csTemp)) {
  1035. SDBERROR_FORMAT((_T("<INCLUDE> or <EXCLUDE> requires MODULE attribute:\n%s\n"),
  1036. GetXML(pNode)));
  1037. goto eh;
  1038. }
  1039. //
  1040. // Convert %EXE% keyword to $ for optimization
  1041. //
  1042. if (csTemp.CompareNoCase(_T("%EXE%")) == 0) {
  1043. csTemp = _T("$");
  1044. }
  1045. m_csModule = csTemp;
  1046. m_pDB = pDB;
  1047. bSuccess = TRUE;
  1048. eh:
  1049. return bSuccess;
  1050. }
  1051. BOOL SdbFlag::ReadFromXML(
  1052. IXMLDOMNode* pNode,
  1053. SdbDatabase* pDB)
  1054. {
  1055. BOOL bSuccess = FALSE;
  1056. CString csMask;
  1057. CString csType;
  1058. CString csTemp;
  1059. CString csID;
  1060. IXMLDOMNodePtr cpDesc;
  1061. if (!ReadName(pNode, &m_csName)) {
  1062. SDBERROR_PROPOGATE();
  1063. goto eh;
  1064. }
  1065. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  1066. SDBERROR_PROPOGATE();
  1067. goto eh;
  1068. }
  1069. if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) {
  1070. m_csDesc = GetText(cpDesc);
  1071. }
  1072. if (!GetAttribute(_T("TYPE"), pNode, &csType)) {
  1073. //
  1074. // By default the apphacks are for kernel.
  1075. //
  1076. SDBERROR_FORMAT((_T("<FLAG> requires TYPE attribute:\n%s\n"),
  1077. GetXML(pNode)));
  1078. goto eh;
  1079. }
  1080. csTemp.Empty();
  1081. if (GetAttribute(_T("PURPOSE"), pNode, &csTemp)) {
  1082. if (csTemp == _T("GENERAL")) {
  1083. m_Purpose = SDB_PURPOSE_GENERAL;
  1084. } else {
  1085. m_Purpose = SDB_PURPOSE_SPECIFIC;
  1086. }
  1087. }
  1088. if (!SetType(csType)) {
  1089. SDBERROR_FORMAT((_T("<FLAG> bad TYPE attribute:\n%s\n"),
  1090. GetXML(pNode)));
  1091. goto eh;
  1092. }
  1093. if (!GetAttribute(_T("MASK"), pNode, &csMask)) {
  1094. SDBERROR_FORMAT((_T("<FLAG> requires MASK attribute:\n%s\n"),
  1095. GetXML(pNode)));
  1096. goto eh;
  1097. }
  1098. m_ullMask = StringToQword(csMask);
  1099. m_pDB = pDB;
  1100. bSuccess = TRUE;
  1101. eh:
  1102. return bSuccess;
  1103. }
  1104. BOOL SdbFlagRef::ReadFromXML(
  1105. IXMLDOMNode* pNode,
  1106. SdbDatabase* pDB)
  1107. {
  1108. BOOL bSuccess = FALSE;
  1109. if (!ReadName(pNode, &m_csName)) {
  1110. SDBERROR_PROPOGATE();
  1111. goto eh;
  1112. }
  1113. m_pFlag = (SdbFlag *) pDB->m_Library.m_rgFlags.LookupName(m_csName);
  1114. if (m_pFlag == NULL && g_bStrict) {
  1115. SDBERROR_FORMAT((_T("SHIM \"%s\" not found in library:\n%s\n\n"),
  1116. m_csName, GetXML(pNode)));
  1117. goto eh;
  1118. }
  1119. //
  1120. // see if we have cmd line, applicable mostly to ntvdm flags
  1121. //
  1122. GetAttribute(_T("COMMAND_LINE"), pNode, &m_csCommandLine);
  1123. m_pDB = pDB;
  1124. bSuccess = TRUE;
  1125. eh:
  1126. return bSuccess;
  1127. }
  1128. BOOL SdbApp::ReadFromXML(
  1129. IXMLDOMNode* pNode,
  1130. SdbDatabase* pDB)
  1131. {
  1132. BOOL bSuccess = FALSE;
  1133. XMLNodeList XQL;
  1134. IXMLDOMNodePtr cpHistoryNode;
  1135. IXMLDOMNodePtr cpAppHelpNode;
  1136. SdbAppHelpRef* pAppHelpRef1 = NULL;
  1137. SdbAppHelpRef* pAppHelpRef2 = NULL;
  1138. long i, j;
  1139. CString csTemp, csTemp2, csTemp3, csID;
  1140. COleDateTime odtLastRevision, odtCandidate;
  1141. if (!ReadName(pNode, &m_csName)) {
  1142. SDBERROR_PROPOGATE();
  1143. goto eh;
  1144. }
  1145. GetAttribute(_T("VENDOR"), pNode, &m_csVendor);
  1146. GetAttribute(_T("VENDOR"), pNode, &m_csVendorXML, TRUE);
  1147. GetAttribute(_T("VERSION"), pNode, &m_csVersion);
  1148. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  1149. SDBERROR_PROPOGATE();
  1150. goto eh;
  1151. }
  1152. if (!XQL.Query(pNode, _T("HISTORY"))) {
  1153. SDBERROR_PROPOGATE();
  1154. goto eh;
  1155. }
  1156. //
  1157. // Set the default modified date to 01/01/2000
  1158. //
  1159. odtLastRevision.ParseDateTime(_T("01/01/2001"), 0, 0x0409);
  1160. for (i = 0; i < XQL.GetSize(); i++) {
  1161. if (!XQL.GetItem(i, &cpHistoryNode)) {
  1162. SDBERROR_PROPOGATE();
  1163. goto eh;
  1164. }
  1165. if (GetAttribute(_T("DATE"), cpHistoryNode, &csTemp)) {
  1166. //
  1167. // Validate format. It's important that the date format is
  1168. // consistent to provide easy text searches.
  1169. //
  1170. if (!(_istdigit(csTemp[0]) && _istdigit(csTemp[1]) &&
  1171. csTemp[2] == _T('/') && _istdigit(csTemp[3]) &&
  1172. _istdigit(csTemp[4]) && csTemp[5] == _T('/') &&
  1173. _istdigit(csTemp[6]) && _istdigit(csTemp[7]) &&
  1174. _istdigit(csTemp[8]) && _istdigit(csTemp[9]) &&
  1175. csTemp[10] == _T('\0'))) {
  1176. SDBERROR_FORMAT((_T("HISTORY DATE is not in format MM/DD/YYYY: \"%s\"\nFor app: \"%s\""),
  1177. csTemp, m_csName));
  1178. goto eh;
  1179. }
  1180. if (!odtCandidate.ParseDateTime(csTemp, 0, 0x0409))
  1181. {
  1182. SDBERROR_FORMAT((_T("HISTORY DATE is not in format MM/DD/YYYY: \"%s\"\nFor app: \"%s\""),
  1183. csTemp, m_csName));
  1184. goto eh;
  1185. }
  1186. if (odtCandidate > odtLastRevision)
  1187. {
  1188. odtLastRevision = odtCandidate;
  1189. }
  1190. }
  1191. if (GetAttribute(_T("KEYWORDS"), cpHistoryNode, &csTemp)) {
  1192. m_csKeywords += csTemp;
  1193. m_csKeywords += _T(";");
  1194. }
  1195. cpHistoryNode.Release();
  1196. }
  1197. m_dtLastRevision = odtLastRevision.m_dt;
  1198. //
  1199. // Set m_pCurrentApp so that new SdbExe objects can grab their m_pApp pointer
  1200. //
  1201. pDB->m_pCurrentApp = this;
  1202. //
  1203. // Add the EXEs as in an "ordered" fashion
  1204. //
  1205. // SYS is the driver XML version of EXE
  1206. //
  1207. if (!m_rgExes.ReadFromXML(_T("EXE | SYS"), pDB, pNode, NULL, TRUE)) {
  1208. SDBERROR_PROPOGATE();
  1209. goto eh;
  1210. }
  1211. //
  1212. // Add the WIN9X_MIGRATION entries
  1213. //
  1214. if (!m_rgWin9xMigEntries.ReadFromXML(_T("WIN9X_MIGRATION"), pDB, pNode, NULL, FALSE, NULL)) {
  1215. SDBERROR_PROPOGATE();
  1216. goto eh;
  1217. }
  1218. //
  1219. // Add the WINNT_UPGRADE entries
  1220. //
  1221. if (!m_rgWinNTUpgradeEntries.ReadFromXML(_T("WINNT_UPGRADE"), pDB, pNode, NULL, FALSE, NULL)) {
  1222. SDBERROR_PROPOGATE();
  1223. goto eh;
  1224. }
  1225. //
  1226. // Read MSI_PACKAGE tags, owner is this one (hence the NULL), add them ordered
  1227. //
  1228. if (!m_rgMsiPackages.ReadFromXML(_T("MSI_PACKAGE"), pDB, pNode, NULL, TRUE)) {
  1229. SDBERROR_PROPOGATE();
  1230. goto eh;
  1231. }
  1232. //
  1233. // Run through the AppHelpRefs to make sure
  1234. // they all have HTMLHELPIDs
  1235. //
  1236. for (i = 0; i < m_rgAppHelpRefs.GetSize(); i++) {
  1237. pAppHelpRef1 = (SdbAppHelpRef *) m_rgAppHelpRefs[i];
  1238. if (pAppHelpRef1->m_cpNode) {
  1239. if (!pAppHelpRef1->ReadFromXML(pAppHelpRef1->m_cpNode,
  1240. pDB)) {
  1241. SDBERROR_PROPOGATE();
  1242. goto eh;
  1243. }
  1244. pAppHelpRef1->m_cpNode = NULL;
  1245. }
  1246. }
  1247. if (g_bStrict) {
  1248. for (i = 0; i < m_rgAppHelpRefs.GetSize(); i++) {
  1249. pAppHelpRef1 = (SdbAppHelpRef *) m_rgAppHelpRefs[i];
  1250. for (j = 0; j < m_rgAppHelpRefs.GetSize(); j++) {
  1251. pAppHelpRef2 = (SdbAppHelpRef *) m_rgAppHelpRefs[j];
  1252. if (pAppHelpRef1->m_pAppHelp->m_csName != pAppHelpRef2->m_pAppHelp->m_csName &&
  1253. pAppHelpRef1->m_pAppHelp->m_csMessage == pAppHelpRef2->m_pAppHelp->m_csMessage &&
  1254. pAppHelpRef1->m_pAppHelp->m_Type == pAppHelpRef2->m_pAppHelp->m_Type &&
  1255. pAppHelpRef1->m_pAppHelp->m_bBlockUpgrade == pAppHelpRef2->m_pAppHelp->m_bBlockUpgrade &&
  1256. pAppHelpRef1->m_pAppHelp->m_csURL == pAppHelpRef2->m_pAppHelp->m_csURL) {
  1257. SDBERROR_FORMAT((_T("Different HTMLHELPIDs for same <APPHELP MESSAGE BLOCK BLOCK_UPGRADE DETAILS_URL>:\n%s\n"),
  1258. GetXML(pNode)));
  1259. goto eh;
  1260. }
  1261. }
  1262. }
  1263. }
  1264. //
  1265. // Set m_dtLastRevision for important children.
  1266. //
  1267. for (i = 0; i < m_rgExes.GetSize(); i++)
  1268. {
  1269. ((SdbArrayElement *) m_rgExes.GetAt(i))->m_dtLastRevision = m_dtLastRevision;
  1270. }
  1271. for (i = 0; i < this->m_rgAppHelpRefs.GetSize(); i++)
  1272. {
  1273. ((SdbAppHelpRef *) m_rgAppHelpRefs.GetAt(i))->m_pAppHelp->m_dtLastRevision = m_dtLastRevision;
  1274. }
  1275. for (i = 0; i < m_rgMsiPackages.GetSize(); i++)
  1276. {
  1277. ((SdbArrayElement *) m_rgMsiPackages.GetAt(i))->m_dtLastRevision = m_dtLastRevision;
  1278. }
  1279. for (i = 0; i < m_rgWin9xMigEntries.GetSize(); i++)
  1280. {
  1281. ((SdbArrayElement *) m_rgWin9xMigEntries.GetAt(i))->m_dtLastRevision = m_dtLastRevision;
  1282. }
  1283. for (i = 0; i < m_rgWinNTUpgradeEntries.GetSize(); i++)
  1284. {
  1285. ((SdbArrayElement *) m_rgWinNTUpgradeEntries.GetAt(i))->m_dtLastRevision = m_dtLastRevision;
  1286. }
  1287. m_pDB = pDB;
  1288. bSuccess = TRUE;
  1289. eh:
  1290. pDB->m_pCurrentApp = NULL;
  1291. return bSuccess;
  1292. }
  1293. BOOL
  1294. CheckExeID(
  1295. SdbDatabase* pDB,
  1296. SdbArrayElement* pElement,
  1297. LPCTSTR lpszID
  1298. )
  1299. {
  1300. SdbArrayElement* pOtherExe = NULL;
  1301. LPCTSTR pszName = NULL;
  1302. LPCTSTR pszTag = NULL;
  1303. if (pDB->m_mapExeIDtoExe.Lookup(lpszID, (PVOID&)pOtherExe)) {
  1304. //
  1305. // see what kind of an object we caught with this duplicate id
  1306. //
  1307. const type_info& TypeInfoObj = typeid(*pOtherExe);
  1308. if (typeid(SdbMsiPackage) == TypeInfoObj) {
  1309. pszName = ((SdbMsiPackage*)pOtherExe)->m_pApp->m_csName;
  1310. pszTag = _T("<MSI_PACKAGE NAME=");
  1311. } else if (typeid(SdbExe) == TypeInfoObj) {
  1312. pszName = ((SdbExe*)pOtherExe)->m_pApp->m_csName;
  1313. pszTag = _T("<EXE NAME=");
  1314. } else {
  1315. // deep poop - we don't know what this is
  1316. pszName = _T("???");
  1317. pszTag = _T("<???");
  1318. }
  1319. SDBERROR_FORMAT((_T("EXE ID %s is not unique\n")
  1320. _T("\tNested within <APP NAME=\"%s\">\n\tAnd also within %s\"%s\">\r\n"),
  1321. lpszID, pszName, pszTag, pElement->m_csName));
  1322. return FALSE;
  1323. }
  1324. pDB->m_mapExeIDtoExe.SetAt(lpszID, pElement);
  1325. return TRUE;
  1326. }
  1327. BOOL SdbExe::ReadFromXML(
  1328. IXMLDOMNode* pNode,
  1329. SdbDatabase* pDB)
  1330. {
  1331. BOOL bSuccess = FALSE;
  1332. long i;
  1333. CString csID, csTemp;
  1334. BOOL bGenerateWinNTUpgrade = FALSE;
  1335. XMLNodeList XQL;
  1336. IXMLDOMNodePtr cpSXS;
  1337. IXMLDOMNodePtr cpMessage;
  1338. SdbMatchingFile* pMFile = NULL;
  1339. SdbData* pData = NULL;
  1340. SdbData* pPolicy = NULL;
  1341. SdbWinNTUpgrade* pNTUpg = NULL;
  1342. VARIANT vType;
  1343. VARIANT vValue;
  1344. IXMLDOMDocumentPtr cpDocument;
  1345. IXMLDOMNodePtr cpNewNode;
  1346. IXMLDOMNodePtr cpXMLNSNode;
  1347. IXMLDOMNodeListPtr cpNodeList;
  1348. IXMLDOMNamedNodeMapPtr cpAttrs;
  1349. VariantInit(&vType);
  1350. VariantInit(&vValue);
  1351. m_pApp = pDB->m_pCurrentApp;
  1352. if (!GetAttribute(_T("NAME"), pNode, &m_csName)) {
  1353. if (GetAttribute(_T("MODULE_NAME"), pNode, &m_csName)) {
  1354. m_bMatchOnModule = TRUE;
  1355. } else {
  1356. SDBERROR_FORMAT((_T("NAME or MODULE_NAME attribute required:\n%s\n\n"),
  1357. GetXML(pNode)));
  1358. goto eh;
  1359. }
  1360. }
  1361. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  1362. SDBERROR_PROPOGATE();
  1363. goto eh;
  1364. }
  1365. if (g_bStrict) {
  1366. if (!CheckExeID(pDB, this, csID)) {
  1367. SDBERROR_PROPOGATE();
  1368. goto eh;
  1369. }
  1370. }
  1371. //
  1372. // Look for a match mode entry
  1373. //
  1374. if (GetAttribute(_T("MATCH_MODE"), pNode, &csTemp)) {
  1375. if (!DecodeStringAttribute(csTemp,
  1376. g_rgStringMatchModeType,
  1377. ARRAYSIZE(g_rgStringMatchModeType),
  1378. &m_dwMatchMode)) {
  1379. //
  1380. // try to decode using the hex (direct) format
  1381. //
  1382. if (!StringToMask(&m_dwMatchMode, csTemp)) {
  1383. SDBERROR_FORMAT((_T("MATCH_MODE attribute is invalid\n%s\n"),
  1384. GetXML(pNode)));
  1385. goto eh;
  1386. }
  1387. }
  1388. }
  1389. if (GetAttribute(_T("RUNTIME_PLATFORM"), pNode, &csTemp)) {
  1390. if (!DecodeRuntimePlatformString(csTemp, &m_dwRuntimePlatform)) {
  1391. SDBERROR_FORMAT((_T("RUNTIME_PLATFORM no in recognized format: \"%s\"\n%s\n"),
  1392. (LPCTSTR)csTemp, GetXML(pNode)));
  1393. goto eh;
  1394. }
  1395. }
  1396. GetAttribute(_T("OS_VERSION"), pNode, &m_csOSVersionSpec);
  1397. //
  1398. // Check what OS SKU this entry is meant for
  1399. //
  1400. if (GetAttribute(_T("OS_SKU"), pNode, &csTemp)) {
  1401. //
  1402. // Decode it. This string is a semi-colon delimited set
  1403. // of OS SKUs.
  1404. //
  1405. if (!DecodeString(csTemp, &m_dwOSSKU, GetOSSKUType)) {
  1406. SDBERROR_FORMAT((_T("OS_SKU attribute syntax error: %s"), csTemp));
  1407. goto eh;
  1408. }
  1409. }
  1410. //
  1411. // Check what OS PLATFORM this entry is meant for
  1412. //
  1413. if (GetAttribute(_T("OS_PLATFORM"), pNode, &csTemp)) {
  1414. //
  1415. // Decode it. This string is a semi-colon delimited set
  1416. // of OS PLATFORMs.
  1417. //
  1418. if (!DecodeString(csTemp, &m_dwOSPlatform, GetOSPlatform)) {
  1419. SDBERROR_FORMAT((_T("OS_PLATFORM attribute syntax error: %s"), csTemp));
  1420. goto eh;
  1421. }
  1422. }
  1423. //
  1424. // Add EXE as matching file
  1425. //
  1426. pMFile = new SdbMatchingFile();
  1427. if (pMFile == NULL) {
  1428. SDBERROR(_T("Error allocating SdbMatchingFile object"));
  1429. goto eh;
  1430. }
  1431. m_rgMatchingFiles.Add(pMFile, pDB);
  1432. if (!pMFile->ReadFromXML(pNode, pDB)) {
  1433. SDBERROR_PROPOGATE();
  1434. goto eh;
  1435. }
  1436. //
  1437. // Change name to "*" -- that is the alias for the EXE. This is done
  1438. // to allow matching on a wildcard executable name.
  1439. //
  1440. pMFile->m_csName = _T("*");
  1441. if (!m_rgMatchingFiles.ReadFromXML(_T("MATCHING_FILE"), pDB, pNode)) {
  1442. SDBERROR_PROPOGATE();
  1443. goto eh;
  1444. }
  1445. if (!m_rgShimRefs.ReadFromXML(_T("SHIM"), pDB, pNode)) {
  1446. SDBERROR_PROPOGATE();
  1447. goto eh;
  1448. }
  1449. if (!m_rgLayerRefs.ReadFromXML(_T("LAYER"), pDB, pNode)) {
  1450. SDBERROR_PROPOGATE();
  1451. goto eh;
  1452. }
  1453. if (!m_rgPatches.ReadFromXML(_T("PATCH"), pDB, pNode, &(pDB->m_Library.m_rgPatches))) {
  1454. SDBERROR_PROPOGATE();
  1455. goto eh;
  1456. }
  1457. if (!m_rgFlagRefs.ReadFromXML(_T("FLAG"), pDB, pNode)) {
  1458. SDBERROR_PROPOGATE();
  1459. goto eh;
  1460. }
  1461. //
  1462. // Data tags
  1463. //
  1464. if (!m_rgData.ReadFromXML(_T("(DATA | DRIVER_POLICY)"), pDB, pNode, NULL)) {
  1465. SDBERROR_PROPOGATE();
  1466. goto eh;
  1467. }
  1468. //
  1469. // Driver database 'hack': We look for CRITICAL="NO" on the SYS tag
  1470. // and add a Policy = 0x1 <DATA> element if found. This is to help
  1471. // readability.
  1472. //
  1473. //
  1474. // Check if policy already exists
  1475. //
  1476. for (i = 0; i < m_rgData.GetSize(); i++) {
  1477. pData = (SdbData *) m_rgData.GetAt(i);
  1478. if (pData->m_csName.CompareNoCase(_T("Policy")) == 0) {
  1479. pPolicy = pData;
  1480. break;
  1481. }
  1482. }
  1483. if (GetAttribute(_T("CRITICAL"), pNode, &csTemp)) {
  1484. if (csTemp.CompareNoCase(_T("NO")) == 0) {
  1485. if (pPolicy == NULL) {
  1486. pPolicy = new SdbData;
  1487. pPolicy->m_csName = _T("Policy");
  1488. pPolicy->SetValue(eValueDWORD, _T("0x0"));
  1489. m_rgData.Add(pPolicy, pDB);
  1490. }
  1491. pPolicy->m_dwValue |= 1;
  1492. }
  1493. }
  1494. if (GetAttribute(_T("USER_MODE_BLOCK"), pNode, &csTemp)) {
  1495. if (csTemp.CompareNoCase(_T("NO")) == 0) {
  1496. if (pPolicy == NULL) {
  1497. pPolicy = new SdbData;
  1498. pPolicy->m_csName = _T("Policy");
  1499. pPolicy->SetValue(eValueDWORD, _T("0x0"));
  1500. m_rgData.Add(pPolicy, pDB);
  1501. }
  1502. pPolicy->m_dwValue |= 2;
  1503. }
  1504. }
  1505. //
  1506. // Action tags
  1507. //
  1508. if (!m_rgAction.ReadFromXML(_T("ACTION"), pDB, pNode, NULL)) {
  1509. SDBERROR_PROPOGATE();
  1510. goto eh;
  1511. }
  1512. //
  1513. // Read APPHELP refs
  1514. //
  1515. if (!XQL.Query(pNode, _T("APPHELP"))) {
  1516. SDBERROR_PROPOGATE();
  1517. goto eh;
  1518. }
  1519. if (XQL.GetSize() > 1) {
  1520. SDBERROR_FORMAT((_T("Multiple <APPHELP> tags per <EXE> not allowed\n%s\n"),
  1521. GetXML(pNode)));
  1522. goto eh;
  1523. }
  1524. if (XQL.GetSize() == 1) {
  1525. if (!XQL.GetItem(0, &cpMessage)) {
  1526. SDBERROR_PROPOGATE();
  1527. goto eh;
  1528. }
  1529. if (!m_AppHelpRef.ReadFromXML(cpMessage, pDB)) {
  1530. SDBERROR_PROPOGATE();
  1531. goto eh;
  1532. }
  1533. if (m_rgShimRefs.GetSize() == 0 &&
  1534. m_rgPatches.GetSize() == 0 &&
  1535. m_rgFlagRefs.GetSize() == 0 &&
  1536. m_rgLayerRefs.GetSize() == 0) {
  1537. m_AppHelpRef.m_bApphelpOnly = TRUE;
  1538. }
  1539. //
  1540. // <SYS> entries automatically get an <WINNT_UPGRADE> entry
  1541. //
  1542. if (GetNodeName(pNode) == _T("SYS")) {
  1543. bGenerateWinNTUpgrade = TRUE;
  1544. if (GetAttribute(_T("GENERATE_UPGRADE_REPORT_ENTRY"), pNode, &csTemp)) {
  1545. if (0 == csTemp.CompareNoCase(_T("NO"))) {
  1546. bGenerateWinNTUpgrade = FALSE;
  1547. }
  1548. }
  1549. if (bGenerateWinNTUpgrade) {
  1550. pNTUpg = new SdbWinNTUpgrade;
  1551. pNTUpg->m_pDB = pDB;
  1552. pNTUpg->m_pApp = pDB->m_pCurrentApp;
  1553. if (!pNTUpg->m_AppHelpRef.ReadFromXML(cpMessage, pDB)) {
  1554. SDBERROR_PROPOGATE();
  1555. goto eh;
  1556. }
  1557. csTemp = m_csName;
  1558. ReplaceStringNoCase(csTemp, _T(".SYS"), _T(""));
  1559. pNTUpg->m_MatchingFile.m_csServiceName = csTemp;
  1560. pNTUpg->m_MatchingFile.m_csName.Format(_T("%%SystemRoot%%\\System32\\Drivers\\%s"), m_csName);
  1561. pNTUpg->m_MatchingFile.m_dwMask = pMFile->m_dwMask;
  1562. pNTUpg->m_MatchingFile.m_ullBinProductVersion = pMFile->m_ullBinProductVersion;
  1563. pNTUpg->m_MatchingFile.m_ullUpToBinProductVersion = pMFile->m_ullUpToBinProductVersion;
  1564. pNTUpg->m_MatchingFile.m_timeLinkDate = pMFile->m_timeLinkDate;
  1565. pNTUpg->m_MatchingFile.m_timeUpToLinkDate = pMFile->m_timeUpToLinkDate;
  1566. m_pApp->m_rgWinNTUpgradeEntries.Add(pNTUpg, pDB);
  1567. pDB->m_rgWinNTUpgradeEntries.Add(pNTUpg, pDB);
  1568. }
  1569. }
  1570. }
  1571. //
  1572. // Read SXS manifest
  1573. //
  1574. if (!XQL.Query(pNode, _T("SXS"))) {
  1575. SDBERROR_PROPOGATE();
  1576. goto eh;
  1577. }
  1578. if (XQL.GetSize() > 1) {
  1579. SDBERROR_FORMAT((_T("Multiple <SXS> tags per <EXE> not allowed\n%s\n"),
  1580. GetXML(pNode)));
  1581. goto eh;
  1582. }
  1583. if (XQL.GetSize() == 1) {
  1584. if (!XQL.GetItem(0, &cpSXS)) {
  1585. SDBERROR_PROPOGATE();
  1586. goto eh;
  1587. }
  1588. m_csSXSManifest = TrimParagraph(GetInnerXML(cpSXS));
  1589. if (m_csSXSManifest.IsEmpty()) {
  1590. SDBERROR_FORMAT((_T("Failed to read SXS manifest:\n%s\n"),
  1591. GetXML(cpSXS)));
  1592. goto eh;
  1593. }
  1594. }
  1595. //
  1596. // Check whether the EXE name contains a wildcard
  1597. //
  1598. m_bWildcardInName = (0 <= m_csName.FindOneOf(_T("*?")));
  1599. //
  1600. // Differentiate between driver.xml entries and dbu.xml
  1601. //
  1602. if (GetNodeName(pNode) == _T("SYS")) {
  1603. //
  1604. // Set filter
  1605. //
  1606. m_dwFilter = SDB_FILTER_DRIVER | SDB_FILTER_OVERRIDE;
  1607. if (m_bWildcardInName) {
  1608. SDBERROR_FORMAT((_T("Wildcards not allowed in SYS entries:\n%s\n"),
  1609. GetXML(pNode)));
  1610. goto eh;
  1611. } else {
  1612. pDB->m_rgExes.Add(this, pDB, TRUE);
  1613. }
  1614. } else {
  1615. //
  1616. // Check if we're compiling for Win2k and make
  1617. // sure Win2k supports all the matching operations.
  1618. //
  1619. if (g_bStrict) {
  1620. if (!IsValidForWin2k(GetXML(pNode))) {
  1621. if (GetAttribute(_T("OS_VERSION"), pNode, &csTemp)) {
  1622. SDBERROR_PROPOGATE();
  1623. goto eh;
  1624. }
  1625. if (!AddAttribute(pNode, _T("OS_VERSION"), _T("gte5.1"))) {
  1626. SDBERROR_PROPOGATE();
  1627. goto eh;
  1628. }
  1629. SDBERROR_CLEAR();
  1630. pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE;
  1631. }
  1632. }
  1633. if (m_bWildcardInName) {
  1634. pDB->m_rgWildcardExes.Add(this, pDB, TRUE);
  1635. } else if (m_bMatchOnModule) {
  1636. pDB->m_rgModuleExes.Add(this, pDB, TRUE);
  1637. } else {
  1638. pDB->m_rgExes.Add(this, pDB, TRUE);
  1639. }
  1640. }
  1641. m_AppHelpRef.m_pDB = pDB;
  1642. m_pDB = pDB;
  1643. bSuccess = TRUE;
  1644. eh:
  1645. VariantClear(&vType);
  1646. VariantClear(&vValue);
  1647. return bSuccess;
  1648. }
  1649. ////////////////////////////////////////////////////////////////////////
  1650. //
  1651. // Read in MSI Package tag
  1652. // <MSI_PACKAGE NAME="my msi package" ID="{xxxxx}">
  1653. // <DATA NAME="Additional Data" VALUETYPE="DWORD" VALUE="0x233"/>
  1654. // <MSI_TRANSFORM NAME="Apply Me for a fix"/>
  1655. // </MSI_PACKAGE>
  1656. //
  1657. SdbDatabase* CastDatabaseToFixDatabase(SdbDatabase* pDB)
  1658. {
  1659. const type_info& TypeInfoFixDB = typeid(SdbDatabase);
  1660. const type_info& TypeInfoDB = typeid(*pDB);
  1661. if (TypeInfoDB == TypeInfoFixDB) {
  1662. return (SdbDatabase*)pDB;
  1663. }
  1664. //
  1665. // bad error
  1666. //
  1667. SDBERROR_FORMAT((_T("Internal Compiler Error: Bad cast operation on Database object\n")));
  1668. return NULL;
  1669. }
  1670. BOOL SdbMsiPackage::ReadFromXML(
  1671. IXMLDOMNode* pNode,
  1672. SdbDatabase* pDB)
  1673. {
  1674. BOOL bSuccess = FALSE;
  1675. CString csID;
  1676. CString csTemp;
  1677. XMLNodeList XQL;
  1678. IXMLDOMNodePtr cpMessage;
  1679. SdbDatabase* pFixDB = CastDatabaseToFixDatabase(pDB);
  1680. if (pFixDB == NULL) {
  1681. SDBERROR_PROPOGATE();
  1682. goto eh;
  1683. }
  1684. m_pApp = pFixDB->m_pCurrentApp;
  1685. if (!ReadName(pNode, &m_csName)) {
  1686. SDBERROR_PROPOGATE();
  1687. goto eh;
  1688. }
  1689. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  1690. SDBERROR_PROPOGATE();
  1691. goto eh;
  1692. }
  1693. if (g_bStrict) {
  1694. if (!CheckExeID(pDB, this, csID)) {
  1695. SDBERROR_PROPOGATE();
  1696. goto eh;
  1697. }
  1698. }
  1699. if (!GetAttribute(_T("PRODUCT_CODE"), pNode, &csID)) {
  1700. //
  1701. // Guid was not found. We do not generate ids for packages -- they are
  1702. // statically defined attributes provided to identify the package
  1703. //
  1704. SDBERROR_FORMAT((_T("MSI_PACKAGE requires PRODUCT_CODE attribute\n%s\n"),
  1705. GetXML(pNode)));
  1706. goto eh;
  1707. }
  1708. if (!GUIDFromString(csID, &m_MsiPackageID)) {
  1709. //
  1710. // This is the case when we cannot parse the guid and it appears to be
  1711. // an invalid guid.
  1712. //
  1713. SDBERROR_FORMAT((_T("ID attribute is not a valid GUID\n%s\n"), csID));
  1714. goto eh;
  1715. }
  1716. //
  1717. // procure RUNTIME_PLATFORM attribute
  1718. //
  1719. if (GetAttribute(_T("RUNTIME_PLATFORM"), pNode, &csTemp)) {
  1720. if (!DecodeRuntimePlatformString(csTemp, &m_dwRuntimePlatform)) {
  1721. SDBERROR_FORMAT((_T("RUNTIME_PLATFORM no in recognized format: \"%s\"\n%s\n"),
  1722. (LPCTSTR)csTemp, GetXML(pNode)));
  1723. goto eh;
  1724. }
  1725. }
  1726. //
  1727. // Check what OS SKU this entry is meant for
  1728. //
  1729. if (GetAttribute(_T("OS_SKU"), pNode, &csTemp)) {
  1730. //
  1731. // Decode it. This string is a semi-colon delimited set
  1732. // of OS SKUs.
  1733. //
  1734. if (!DecodeString(csTemp, &m_dwOSSKU, GetOSSKUType)) {
  1735. SDBERROR_FORMAT((_T("OS_SKU attribute syntax error: %s"), csTemp));
  1736. goto eh;
  1737. }
  1738. }
  1739. //
  1740. // read supplemental data for this object
  1741. //
  1742. if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) {
  1743. SDBERROR_PROPOGATE();
  1744. goto eh;
  1745. }
  1746. //
  1747. // we have name, guid(id) and supplemental data, read fixes for this package
  1748. //
  1749. if (!m_rgMsiTransformRefs.ReadFromXML(_T("MSI_TRANSFORM"), pDB, pNode)) {
  1750. SDBERROR_PROPOGATE();
  1751. goto eh;
  1752. }
  1753. if (!m_rgCustomActions.ReadFromXML(_T("CUSTOM_ACTION"), pDB, pNode)) {
  1754. SDBERROR_PROPOGATE();
  1755. goto eh;
  1756. }
  1757. //
  1758. // Read APPHELP refs
  1759. //
  1760. if (!XQL.Query(pNode, _T("APPHELP"))) {
  1761. SDBERROR_PROPOGATE();
  1762. goto eh;
  1763. }
  1764. if (XQL.GetSize() > 1) {
  1765. SDBERROR_FORMAT((_T("Multiple <APPHELP> tags per <MSI_PACKAGE> not allowed\n%s\n"),
  1766. GetXML(pNode)));
  1767. goto eh;
  1768. }
  1769. if (XQL.GetSize() == 1) {
  1770. if (!XQL.GetItem(0, &cpMessage)) {
  1771. SDBERROR_PROPOGATE();
  1772. goto eh;
  1773. }
  1774. if (!m_AppHelpRef.ReadFromXML(cpMessage, pDB)) {
  1775. SDBERROR_PROPOGATE();
  1776. goto eh;
  1777. }
  1778. }
  1779. pDB->m_rgMsiPackages.Add(this, pDB, TRUE);
  1780. m_AppHelpRef.m_pDB = pDB;
  1781. m_pDB = pDB;
  1782. bSuccess = TRUE;
  1783. eh:
  1784. return bSuccess;
  1785. }
  1786. BOOL
  1787. SdbMsiCustomAction::ReadFromXML(
  1788. IXMLDOMNode* pNode,
  1789. SdbDatabase* pDB
  1790. )
  1791. {
  1792. BOOL bSuccess = FALSE;
  1793. if (!GetAttribute(_T("NAME"), pNode, &m_csName)) {
  1794. SDBERROR_FORMAT((_T("<CUSTOM_ACTION> requires NAME attribute:\n%s\n\n"),
  1795. GetXML(pNode)));
  1796. goto eh;
  1797. }
  1798. if (!m_rgShimRefs.ReadFromXML(_T("SHIM"), pDB, pNode)) {
  1799. SDBERROR_PROPOGATE();
  1800. goto eh;
  1801. }
  1802. if (!m_rgLayerRefs.ReadFromXML(_T("LAYER"), pDB, pNode)) {
  1803. SDBERROR_PROPOGATE();
  1804. goto eh;
  1805. }
  1806. m_pDB = pDB;
  1807. bSuccess = TRUE;
  1808. eh:
  1809. return bSuccess;
  1810. }
  1811. /////////////////////////////////////////////////////////////////////////////////////////////////
  1812. //
  1813. // Read in MSI_TRANSFORM tag
  1814. // <MSI_TRANSFORM NAME="This is transform name" FILE="This is filename.foo">
  1815. // <DESCRIPTION>
  1816. // blah blah blah
  1817. // </DESCRIPTION>
  1818. // </MSI_TRANSFORM>
  1819. //
  1820. BOOL SdbMsiTransform::ReadFromXML(
  1821. IXMLDOMNode* pNode,
  1822. SdbDatabase* pDB)
  1823. {
  1824. BOOL bSuccess = FALSE;
  1825. IXMLDOMNodePtr cpDesc, cpFile;
  1826. XMLNodeList XQL;
  1827. SdbDatabase* pFixDB = CastDatabaseToFixDatabase(pDB);
  1828. if (pFixDB == NULL) {
  1829. SDBERROR_PROPOGATE();
  1830. goto eh;
  1831. }
  1832. // read msi Transform from the library
  1833. if (!ReadName(pNode, &m_csName)) {
  1834. SDBERROR_PROPOGATE();
  1835. goto eh;
  1836. }
  1837. if (!XQL.Query(pNode, _T("FILE"))) {
  1838. SDBERROR_PROPOGATE();
  1839. goto eh;
  1840. }
  1841. if (XQL.GetSize() == 0 ||
  1842. XQL.GetSize() > 1) {
  1843. SDBERROR_FORMAT((_T("<MSI_TRANSFORM> requires one and only one <FILE> child:\n%s\n\n"),
  1844. GetXML(pNode)));
  1845. goto eh;
  1846. }
  1847. if (!XQL.GetItem(0, &cpFile)) {
  1848. SDBERROR_PROPOGATE();
  1849. goto eh;
  1850. }
  1851. if (!GetAttribute(_T("NAME"), cpFile, &m_csMsiTransformFile)) {
  1852. SDBERROR_FORMAT((_T("<FILE> requires NAME attribute:\n%s\n\n"),
  1853. GetXML(pNode)));
  1854. goto eh;
  1855. }
  1856. if (GetChild(_T("DESCRIPTION"), pNode, &cpDesc)) {
  1857. GetNodeText(cpDesc, m_csDesc);
  1858. }
  1859. //
  1860. // name should be unique for each of thesee transforms, enforce
  1861. //
  1862. if (pFixDB->m_Library.m_rgMsiTransforms.LookupName(m_csName) != NULL) {
  1863. SDBERROR_FORMAT((_T("MSI_TRANSFORM NAME attribute is not unique\n%s\n\n"),
  1864. GetXML(pNode)));
  1865. goto eh;
  1866. }
  1867. //
  1868. // find corresponding file object
  1869. //
  1870. if (m_csMsiTransformFile.GetLength()) {
  1871. m_pSdbFile = (SdbFile*)pFixDB->m_Library.m_rgFiles.LookupName(m_csMsiTransformFile);
  1872. if (g_bStrict && m_pSdbFile == NULL) {
  1873. SDBERROR_FORMAT((_T("<MSI_TRANSFORM specifies FILE which is not available in the library\n%s\n\n"),
  1874. GetXML(pNode)));
  1875. goto eh;
  1876. }
  1877. }
  1878. bSuccess = TRUE;
  1879. eh:
  1880. return bSuccess;
  1881. }
  1882. /////////////////////////////////////////////////////////////////////////////////////////////////
  1883. //
  1884. // Read the reference to the transform object
  1885. // <MSI_TRANSFORM NAME="name-reference-to the transform in library"/>
  1886. //
  1887. BOOL SdbMsiTransformRef::ReadFromXML(
  1888. IXMLDOMNode* pNode,
  1889. SdbDatabase* pDB)
  1890. {
  1891. BOOL bSuccess = FALSE;
  1892. SdbDatabase* pFixDB = NULL;
  1893. if (!ReadName(pNode, &m_csName)) {
  1894. SDBERROR_PROPOGATE();
  1895. goto eh;
  1896. }
  1897. pFixDB = CastDatabaseToFixDatabase(pDB);
  1898. if (pFixDB == NULL) {
  1899. SDBERROR_PROPOGATE();
  1900. goto eh;
  1901. }
  1902. m_pMsiTransform = (SdbMsiTransform *) pFixDB->m_Library.m_rgMsiTransforms.LookupName(m_csName);
  1903. if (m_pMsiTransform == NULL && g_bStrict) {
  1904. SDBERROR_FORMAT((_T("MSI_TRANSFORM \"%s\" not found in library:\n%s\n\n"),
  1905. m_csName, GetXML(pNode)));
  1906. goto eh;
  1907. }
  1908. m_pDB = pDB; // set the root db pointer (why???)
  1909. bSuccess = TRUE;
  1910. eh:
  1911. return bSuccess;
  1912. }
  1913. /////////////////////////////////////////////////////////////////////////////////////////////////
  1914. BOOL SdbMatchingFile::ReadFromXML(
  1915. IXMLDOMNode* pNode,
  1916. SdbDatabase* pDB)
  1917. {
  1918. BOOL bSuccess = FALSE;
  1919. CString csTemp;
  1920. GetAttribute(_T("SERVICE_NAME"), pNode, &m_csServiceName);
  1921. if (!GetAttribute(_T("NAME"), pNode, &m_csName)) {
  1922. if (GetNodeName(pNode) == _T("EXE")) {
  1923. m_csName = _T("*");
  1924. } else if (m_csServiceName.IsEmpty()) {
  1925. SDBERROR_FORMAT((_T("NAME attribute required:\n%s\n\n"),
  1926. GetXML(pNode)));
  1927. goto eh;
  1928. }
  1929. }
  1930. if (GetParentNodeName(pNode) == _T("WIN9X_MIGRATION") ||
  1931. GetNodeName(pNode) == _T("MATCH_ANY") ||
  1932. GetNodeName(pNode) == _T("MATCH_ALL")) {
  1933. if (-1 != m_csName.Find(_T("\\"))) {
  1934. SDBERROR_FORMAT((_T("<MATCHING_FILE> inside <WIN9X_MIGRATION> cannot contain relative paths:\n%s\n"),
  1935. GetXML(pNode)));
  1936. goto eh;
  1937. }
  1938. }
  1939. m_dwMask = 0;
  1940. if (GetAttribute(_T("SIZE"), pNode, &csTemp)) {
  1941. m_dwSize = StringToDword(csTemp);
  1942. m_dwMask |= SDB_MATCHINGINFO_SIZE;
  1943. } else {
  1944. m_dwSize = 0;
  1945. }
  1946. if (GetAttribute(_T("CHECKSUM"), pNode, &csTemp)) {
  1947. m_dwChecksum = StringToDword(csTemp);
  1948. m_dwMask |= SDB_MATCHINGINFO_CHECKSUM;
  1949. } else
  1950. m_dwChecksum = 0;
  1951. if (GetAttribute(_T("COMPANY_NAME"), pNode, &(m_csCompanyName))) {
  1952. m_dwMask |= SDB_MATCHINGINFO_COMPANY_NAME;
  1953. }
  1954. if (GetAttribute(_T("PRODUCT_NAME"), pNode, &(m_csProductName))) {
  1955. m_dwMask |= SDB_MATCHINGINFO_PRODUCT_NAME;
  1956. }
  1957. if (GetAttribute(_T("PRODUCT_VERSION"), pNode, &(m_csProductVersion))) {
  1958. m_dwMask |= SDB_MATCHINGINFO_PRODUCT_VERSION;
  1959. }
  1960. if (GetAttribute(_T("FILE_DESCRIPTION"), pNode, &(m_csFileDescription))) {
  1961. m_dwMask |= SDB_MATCHINGINFO_FILE_DESCRIPTION;
  1962. }
  1963. if (GetAttribute(_T("BIN_FILE_VERSION"), pNode, &csTemp)) {
  1964. if (!VersionToQword(csTemp, &m_ullBinFileVersion)) {
  1965. SDBERROR_FORMAT((_T("Bad BIN_FILE_VERSION attribute:\n\n%s\n"), GetXML(pNode)));
  1966. goto eh;
  1967. }
  1968. m_dwMask |= SDB_MATCHINGINFO_BIN_FILE_VERSION;
  1969. }
  1970. if (GetAttribute(_T("BIN_PRODUCT_VERSION"), pNode, &csTemp)) {
  1971. if (!VersionToQword(csTemp, &m_ullBinProductVersion)) {
  1972. SDBERROR_FORMAT((_T("Bad BIN_PRODUCT_VERSION attribute:\n\n%s\n"), GetXML(pNode)));
  1973. goto eh;
  1974. }
  1975. m_dwMask |= SDB_MATCHINGINFO_BIN_PRODUCT_VERSION;
  1976. }
  1977. if (GetAttribute(_T("MODULE_TYPE"), pNode, &csTemp)) {
  1978. if (!GetModuleTypeIndicator(csTemp, &m_dwModuleType)) {
  1979. SDBERROR_FORMAT((_T("<MATCHING_FILE> MODULE_TYPE attribute unrecognized:\n%s\n"),
  1980. GetXML(pNode)));
  1981. goto eh;
  1982. }
  1983. m_dwMask |= SDB_MATCHINGINFO_MODULE_TYPE;
  1984. }
  1985. if (GetAttribute(_T("VERFILEDATELO"), pNode, &csTemp)) {
  1986. m_dwFileDateLS = StringToDword(csTemp);
  1987. m_dwMask |= SDB_MATCHINGINFO_VERFILEDATELO;
  1988. }
  1989. if (GetAttribute(_T("VERFILEDATEHI"), pNode, &csTemp)) {
  1990. m_dwFileDateMS = StringToDword(csTemp);
  1991. m_dwMask |= SDB_MATCHINGINFO_VERFILEDATEHI;
  1992. }
  1993. if (GetAttribute(_T("VERFILEOS"), pNode, &csTemp)) {
  1994. m_dwFileOS = StringToDword(csTemp);
  1995. m_dwMask |= SDB_MATCHINGINFO_VERFILEOS;
  1996. }
  1997. if (GetAttribute(_T("VERFILETYPE"), pNode, &csTemp)) {
  1998. m_dwFileType = StringToDword(csTemp);
  1999. m_dwMask |= SDB_MATCHINGINFO_VERFILETYPE;
  2000. }
  2001. if (GetAttribute(_T("PE_CHECKSUM"), pNode, &csTemp)) {
  2002. m_ulPECheckSum = StringToULong(csTemp);
  2003. m_dwMask |= SDB_MATCHINGINFO_PE_CHECKSUM;
  2004. }
  2005. if (GetAttribute(_T("LINKER_VERSION"), pNode, &csTemp)) {
  2006. m_dwLinkerVersion = StringToDword(csTemp);
  2007. m_dwMask |= SDB_MATCHINGINFO_LINKER_VERSION;
  2008. }
  2009. if (GetAttribute(_T("FILE_VERSION"), pNode, &m_csFileVersion)) {
  2010. m_dwMask |= SDB_MATCHINGINFO_FILE_VERSION;
  2011. }
  2012. if (GetAttribute(_T("ORIGINAL_FILENAME"), pNode, &m_csOriginalFileName)) {
  2013. m_dwMask |= SDB_MATCHINGINFO_ORIGINAL_FILENAME;
  2014. }
  2015. if (GetAttribute(_T("INTERNAL_NAME"), pNode, &m_csInternalName)) {
  2016. m_dwMask |= SDB_MATCHINGINFO_INTERNAL_NAME;
  2017. }
  2018. if (GetAttribute(_T("LEGAL_COPYRIGHT"), pNode, &m_csLegalCopyright)) {
  2019. m_dwMask |= SDB_MATCHINGINFO_LEGAL_COPYRIGHT;
  2020. }
  2021. if (GetAttribute(_T("S16BIT_DESCRIPTION"), pNode, &m_cs16BitDescription)) {
  2022. m_dwMask |= SDB_MATCHINGINFO_16BIT_DESCRIPTION;
  2023. }
  2024. if (GetAttribute(_T("S16BIT_MODULE_NAME"), pNode, &m_cs16BitModuleName)) {
  2025. m_dwMask |= SDB_MATCHINGINFO_16BIT_MODULE_NAME;
  2026. }
  2027. if (GetAttribute(_T("UPTO_BIN_PRODUCT_VERSION"), pNode, &csTemp)) {
  2028. if (!VersionToQword(csTemp, &m_ullUpToBinProductVersion)) {
  2029. SDBERROR_FORMAT((_T("Bad UPTO_BIN_PRODUCT_VERSION attribute:\n\n%s\n"), GetXML(pNode)));
  2030. goto eh;
  2031. }
  2032. m_dwMask |= SDB_MATCHINGINFO_UPTO_BIN_PRODUCT_VERSION;
  2033. }
  2034. if (GetAttribute(_T("UPTO_BIN_FILE_VERSION"), pNode, &csTemp)) {
  2035. if (!VersionToQword(csTemp, &m_ullUpToBinFileVersion)) {
  2036. SDBERROR_FORMAT((_T("Bad UPTO_BIN_FILE_VERSION attribute:\n\n%s\n"), GetXML(pNode)));
  2037. goto eh;
  2038. }
  2039. m_dwMask |= SDB_MATCHINGINFO_UPTO_BIN_FILE_VERSION;
  2040. }
  2041. if (GetAttribute(_T("PREVOSMAJORVERSION"), pNode, &csTemp)) {
  2042. m_dwPrevOSMajorVersion = StringToDword(csTemp);
  2043. m_dwMask |= SDB_MATCHINGINFO_PREVOSMAJORVERSION;
  2044. }
  2045. if (GetAttribute(_T("PREVOSMINORVERSION"), pNode, &csTemp)) {
  2046. m_dwPrevOSMinorVersion = StringToDword(csTemp);
  2047. m_dwMask |= SDB_MATCHINGINFO_PREVOSMINORVERSION;
  2048. }
  2049. if (GetAttribute(_T("PREVOSPLATFORMID"), pNode, &csTemp)) {
  2050. m_dwPrevOSPlatformID = StringToDword(csTemp);
  2051. m_dwMask |= SDB_MATCHINGINFO_PREVOSPLATFORMID;
  2052. }
  2053. if (GetAttribute(_T("PREVOSBUILDNO"), pNode, &csTemp)) {
  2054. m_dwPrevOSBuildNo = StringToDword(csTemp);
  2055. m_dwMask |= SDB_MATCHINGINFO_PREVOSBUILDNO;
  2056. }
  2057. if (GetAttribute(_T("LINK_DATE"), pNode, &csTemp)) {
  2058. if (!MakeUTCTime(csTemp, &m_timeLinkDate)) {
  2059. SDBERROR_FORMAT((_T("LINK_DATE not in recognized time format: \"%s\"\n%s\n"),
  2060. csTemp,
  2061. GetXML(pNode)));
  2062. goto eh;
  2063. }
  2064. m_dwMask |= SDB_MATCHINGINFO_LINK_DATE;
  2065. }
  2066. if (GetAttribute(_T("UPTO_LINK_DATE"), pNode, &csTemp)) {
  2067. if (!MakeUTCTime(csTemp, &m_timeUpToLinkDate)) {
  2068. SDBERROR_FORMAT((_T("UPTO_LINK_DATE not in recognized time format: \"%s\"\n%s\n"),
  2069. csTemp,
  2070. GetXML(pNode)));
  2071. goto eh;
  2072. }
  2073. m_dwMask |= SDB_MATCHINGINFO_UPTO_LINK_DATE;
  2074. }
  2075. if (GetAttribute(_T("VER_LANGUAGE"), pNode, &csTemp)) {
  2076. if (!ParseLanguageID(csTemp, &m_dwVerLanguage)) {
  2077. SDBERROR_FORMAT((_T("VER_LANGUAGE not in recognized format: \"%s\"\n%s\n"),
  2078. (LPCTSTR)csTemp,
  2079. GetXML(pNode)));
  2080. goto eh;
  2081. }
  2082. m_dwMask |= SDB_MATCHINGINFO_VER_LANGUAGE;
  2083. }
  2084. if (GetAttribute(_T("REGISTRY_ENTRY"), pNode, &m_csRegistryEntry)) {
  2085. m_dwMask |= SDB_MATCHINGINFO_REGISTRY_ENTRY;
  2086. }
  2087. if (GetAttribute(_T("LOGIC"), pNode, &csTemp)) {
  2088. if (0 == csTemp.CompareNoCase(_T("NOT"))) {
  2089. m_bMatchLogicNot = TRUE;
  2090. }
  2091. }
  2092. m_pDB = pDB;
  2093. bSuccess = TRUE;
  2094. eh:
  2095. return bSuccess;
  2096. }
  2097. BOOL SdbMatchingRegistryEntry::ReadFromXML(
  2098. IXMLDOMNode* pNode,
  2099. SdbDatabase* pDB)
  2100. {
  2101. BOOL bSuccess = FALSE;
  2102. CString csTemp;
  2103. if (!GetAttribute(_T("KEY"), pNode, &m_csName)) {
  2104. SDBERROR_FORMAT((_T("<MATCHING_REGISTRY_ENTRY> requires KEY attribute:\n%s\n\n"),
  2105. GetXML(pNode)));
  2106. goto eh;
  2107. }
  2108. GetAttribute(_T("VALUE_NAME"), pNode, &m_csValueName);
  2109. GetAttribute(_T("VALUE"), pNode, &m_csValue);
  2110. m_pDB = pDB;
  2111. bSuccess = TRUE;
  2112. eh:
  2113. return bSuccess;
  2114. }
  2115. BOOL SdbAppHelpRef::ReadFromXML(
  2116. IXMLDOMNode* pNode,
  2117. SdbDatabase* pDB)
  2118. {
  2119. BOOL bSuccess = FALSE;
  2120. SdbMessage* pMessage = NULL;
  2121. SdbAppHelpRef* pAppHelpRef = NULL;
  2122. BOOL bBlockUpgrade = FALSE;
  2123. long i;
  2124. CString csHTMLHELPID, csType, csURL, csMessage;
  2125. IXMLDOMNodePtr cpParentNode;
  2126. SdbAppHelpType Type = SDB_APPHELP_NOBLOCK;
  2127. if (FAILED(pNode->get_parentNode(&cpParentNode))) {
  2128. SDBERROR_FORMAT((_T("Error retrieving parent node of APPHELP: %s\n"),
  2129. GetXML(pNode)));
  2130. goto eh;
  2131. }
  2132. if (!GetAttribute(_T("MESSAGE"), pNode, &csMessage)) {
  2133. SDBERROR_FORMAT((_T("<APPHELP> requires MESSAGE attribute:\n%s\n"),
  2134. GetXML(pNode)));
  2135. goto eh;
  2136. }
  2137. //
  2138. // get a custom URL, if one is available
  2139. //
  2140. GetAttribute(_T("DETAILS_URL"), pNode, &csURL);
  2141. //
  2142. // Get BLOCK attribute
  2143. //
  2144. Type = SDB_APPHELP_NOBLOCK;
  2145. if (GetAttribute(_T("BLOCK"), pNode, &csType)) {
  2146. if (GetNodeName(cpParentNode) == _T("WINNT_UPGRADE") ||
  2147. GetNodeName(cpParentNode) == _T("SYS")) {
  2148. SDBERROR_FORMAT((_T("<APPHELP> within <WINNT_UPGRADE> or <SYS> ")
  2149. _T("cannot use BLOCK attribute. Use BLOCK_UPGRADE instead.\n\n%s\n"),
  2150. GetXML(cpParentNode)));
  2151. goto eh;
  2152. }
  2153. if (csType == _T("YES")) {
  2154. Type = SDB_APPHELP_HARDBLOCK;
  2155. }
  2156. }
  2157. if (GetAttribute(_T("BLOCK_UPGRADE"), pNode, &csType)) {
  2158. if (GetNodeName(cpParentNode) != _T("WINNT_UPGRADE") &&
  2159. GetNodeName(cpParentNode) != _T("SYS")) {
  2160. SDBERROR_FORMAT((_T("<APPHELP> not within <WINNT_UPGRADE> or <SYS> ")
  2161. _T("cannot use BLOCK_UPGRADE attribute.\n\n%s\n"),
  2162. GetXML(cpParentNode)));
  2163. goto eh;
  2164. }
  2165. if (csType == _T("YES")) {
  2166. bBlockUpgrade = TRUE;
  2167. }
  2168. }
  2169. if (m_cpNode == NULL &&
  2170. !GetAttribute(_T("HTMLHELPID"), pNode, &csHTMLHELPID)) {
  2171. //
  2172. // Need to generate a new HTMLHELPID. Wait until
  2173. // the rest of the <APPHELP> tags for this app have
  2174. // been parsed and then we'll pass over this again.
  2175. //
  2176. pDB->m_pCurrentApp->m_rgAppHelpRefs.Add(this);
  2177. m_cpNode = pNode;
  2178. bSuccess = TRUE;
  2179. goto eh;
  2180. }
  2181. if (!GetAttribute(_T("HTMLHELPID"), pNode, &csHTMLHELPID)) {
  2182. //
  2183. // HTMLHELPID not found. Generate it.
  2184. //
  2185. for (i = 0; i < pDB->m_pCurrentApp->m_rgAppHelpRefs.GetSize(); i++) {
  2186. pAppHelpRef = (SdbAppHelpRef *) pDB->m_pCurrentApp->m_rgAppHelpRefs.GetAt(i);
  2187. if (pAppHelpRef->m_pAppHelp) {
  2188. if (pAppHelpRef->m_pAppHelp->m_csMessage == csMessage &&
  2189. pAppHelpRef->m_pAppHelp->m_Type == Type &&
  2190. pAppHelpRef->m_pAppHelp->m_csURL == csURL &&
  2191. pAppHelpRef->m_pAppHelp->m_bBlockUpgrade == bBlockUpgrade) {
  2192. csHTMLHELPID = pAppHelpRef->m_pAppHelp->m_csName;
  2193. }
  2194. }
  2195. }
  2196. if (csHTMLHELPID.IsEmpty()) {
  2197. csHTMLHELPID.Format(_T("%d"), pDB->GetNextSequentialID(_T("HTMLHELPID")));
  2198. }
  2199. if (!AddAttribute(pNode, _T("HTMLHELPID"), csHTMLHELPID)) {
  2200. SDBERROR_PROPOGATE();
  2201. goto eh;
  2202. }
  2203. pDB->m_pCurrentInputFile->m_bSourceUpdated = TRUE;
  2204. }
  2205. //
  2206. // Create an AppHelp entry if one isn't there
  2207. //
  2208. m_pAppHelp = (SdbAppHelp *) pDB->m_rgAppHelps.LookupName(csHTMLHELPID);
  2209. if (m_pAppHelp == NULL) {
  2210. m_pAppHelp = new SdbAppHelp;
  2211. m_pAppHelp->m_csName = csHTMLHELPID;
  2212. m_pAppHelp->m_csMessage = csMessage;
  2213. m_pAppHelp->m_csURL = csURL;
  2214. m_pAppHelp->m_pApp = pDB->m_pCurrentApp;
  2215. m_pAppHelp->m_Type = Type;
  2216. m_pAppHelp->m_bBlockUpgrade = bBlockUpgrade;
  2217. pDB->m_rgAppHelps.Add(m_pAppHelp, pDB);
  2218. } else {
  2219. if (m_pAppHelp->m_pApp != pDB->m_pCurrentApp ||
  2220. m_pAppHelp->m_csMessage != csMessage ||
  2221. m_pAppHelp->m_Type != Type ||
  2222. m_pAppHelp->m_bBlockUpgrade != bBlockUpgrade ||
  2223. m_pAppHelp->m_csURL != csURL) {
  2224. SDBERROR_FORMAT((_T("Duplicate HTMLHELPID with differing APP, MESSAGE, BLOCK or DETAILS_URL: %s\n"),
  2225. csHTMLHELPID));
  2226. goto eh;
  2227. }
  2228. }
  2229. pDB->m_pCurrentApp->m_rgAppHelpRefs.Add(this);
  2230. m_pDB = pDB;
  2231. bSuccess = TRUE;
  2232. eh:
  2233. return bSuccess;
  2234. }
  2235. BOOL SdbMessage::ReadFromXML(
  2236. IXMLDOMNode* pNode,
  2237. SdbDatabase* pDB)
  2238. {
  2239. BOOL bSuccess = FALSE;
  2240. IXMLDOMNodePtr cpChild;
  2241. CString csTemplate, csID;
  2242. if (!ReadName(pNode, &m_csName)) {
  2243. SDBERROR_PROPOGATE();
  2244. goto eh;
  2245. }
  2246. m_csLangID = pDB->m_csCurrentLangID;
  2247. if (GetAttribute(_T("TEMPLATE"), pNode, &csTemplate)) {
  2248. m_pTemplate = (SdbMessageTemplate *)
  2249. pDB->m_rgMessageTemplates.LookupName(csTemplate, m_csLangID);
  2250. if (m_pTemplate == NULL) {
  2251. SDBERROR_FORMAT((_T("Template \"%s\" not previously declared."), csTemplate));
  2252. goto eh;
  2253. }
  2254. }
  2255. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  2256. SDBERROR_PROPOGATE();
  2257. goto eh;
  2258. }
  2259. if (GetChild(_T("CONTACT_INFO"), pNode, &cpChild)) {
  2260. m_csContactInfoXML = GetInnerXML(cpChild);
  2261. cpChild.Release();
  2262. }
  2263. if (GetChild(_T("SUMMARY"), pNode, &cpChild)) {
  2264. m_csSummaryXML = GetInnerXML(cpChild);
  2265. cpChild.Release();
  2266. }
  2267. if (GetChild(_T("DETAILS"), pNode, &cpChild)) {
  2268. m_csDetailsXML = GetInnerXML(cpChild);
  2269. cpChild.Release();
  2270. } else {
  2271. m_csDetailsXML = m_csSummaryXML;
  2272. }
  2273. if (!m_rgFields.ReadFromXML(_T("FIELD"), pDB, pNode)) {
  2274. SDBERROR_PROPOGATE();
  2275. goto eh;
  2276. }
  2277. m_pDB = pDB;
  2278. bSuccess = TRUE;
  2279. eh:
  2280. return bSuccess;
  2281. }
  2282. BOOL SdbMessageTemplate::ReadFromXML(
  2283. IXMLDOMNode* pNode,
  2284. SdbDatabase* pDB)
  2285. {
  2286. BOOL bSuccess = FALSE;
  2287. IXMLDOMNodePtr cpChild;
  2288. if (!ReadName(pNode, &m_csName)) {
  2289. SDBERROR_PROPOGATE();
  2290. goto eh;
  2291. }
  2292. m_csLangID = pDB->m_csCurrentLangID;
  2293. if (GetChild(_T("SUMMARY"), pNode, &cpChild)) {
  2294. m_csSummaryXML = GetInnerXML(cpChild);
  2295. cpChild.Release();
  2296. }
  2297. if (GetChild(_T("DETAILS"), pNode, &cpChild)) {
  2298. m_csDetailsXML = GetInnerXML(cpChild);
  2299. cpChild.Release();
  2300. } else {
  2301. m_csDetailsXML = m_csSummaryXML;
  2302. }
  2303. m_pDB = pDB;
  2304. bSuccess = TRUE;
  2305. eh:
  2306. return bSuccess;
  2307. }
  2308. BOOL SdbContactInfo::ReadFromXML(
  2309. IXMLDOMNode* pNode,
  2310. SdbDatabase* pDB)
  2311. {
  2312. BOOL bSuccess = FALSE;
  2313. CString csID;
  2314. if (!GetAttribute(_T("VENDOR"), pNode, &m_csName)) {
  2315. SDBERROR_FORMAT((_T("<CONTACT_INFO> requires VENDOR attribute:\n%s\n"), GetXML(pNode)));
  2316. goto eh;
  2317. }
  2318. m_csLangID = pDB->m_csCurrentLangID;
  2319. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  2320. SDBERROR_PROPOGATE();
  2321. goto eh;
  2322. }
  2323. m_csXML = GetInnerXML(pNode);
  2324. m_pDB = pDB;
  2325. bSuccess = TRUE;
  2326. eh:
  2327. return bSuccess;
  2328. }
  2329. BOOL SdbData::ReadFromXML(
  2330. IXMLDOMNode* pNode,
  2331. SdbDatabase* pDB)
  2332. {
  2333. BOOL bSuccess = FALSE;
  2334. CString csValueType;
  2335. CString csValueAttr;
  2336. CString csValueText;
  2337. DWORD dwType;
  2338. if (!ReadName(pNode, &m_csName)) {
  2339. SDBERROR_PROPOGATE();
  2340. goto eh;
  2341. }
  2342. if (!GetAttribute(_T("VALUETYPE"), pNode, &csValueType)) {
  2343. SDBERROR(_T("<DATA> requires VALUETYPE attribute."));
  2344. goto eh;
  2345. }
  2346. if (!GetDataTypeIndicator(csValueType, &dwType)) {
  2347. SDBERROR_FORMAT((_T("<DATA> VALUETYPE \"%s\" not recognized."), csValueType));
  2348. goto eh;
  2349. }
  2350. GetNodeText(pNode, csValueText);
  2351. GetAttribute(_T("VALUE"), pNode, &csValueAttr);
  2352. if (csValueText.GetLength() && csValueAttr.GetLength()) {
  2353. SDBERROR_FORMAT((_T("<DATA NAME=\"%s\"> cannot contain both VALUE attribute and inner text."), m_csName));
  2354. goto eh;
  2355. } else if (csValueText.GetLength()) {
  2356. SetValue((SdbDataValueType) dwType, csValueText);
  2357. } else if (csValueAttr.GetLength()) {
  2358. SetValue((SdbDataValueType) dwType, csValueAttr);
  2359. }
  2360. m_DataType = (SdbDataValueType) dwType;
  2361. // finally, read all the child data elements
  2362. if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) {
  2363. SDBERROR_PROPOGATE();
  2364. goto eh;
  2365. }
  2366. m_pDB = pDB;
  2367. bSuccess = TRUE;
  2368. eh:
  2369. return bSuccess;
  2370. }
  2371. BOOL SdbAction::ReadFromXML(
  2372. IXMLDOMNode* pNode,
  2373. SdbDatabase* pDB)
  2374. {
  2375. BOOL bSuccess = FALSE;
  2376. if (!ReadName(pNode, &m_csName)) {
  2377. SDBERROR_PROPOGATE();
  2378. goto eh;
  2379. }
  2380. GetAttribute(_T("TYPE"), pNode, &m_csType);
  2381. if (!m_rgData.ReadFromXML(_T("DATA"), pDB, pNode)) {
  2382. SDBERROR_PROPOGATE();
  2383. goto eh;
  2384. }
  2385. m_pDB = pDB;
  2386. bSuccess = TRUE;
  2387. eh:
  2388. return bSuccess;
  2389. }
  2390. BOOL SdbMessageField::ReadFromXML(
  2391. IXMLDOMNode* pNode,
  2392. SdbDatabase* pDB)
  2393. {
  2394. BOOL bSuccess = FALSE;
  2395. if (!ReadName(pNode, &m_csName)) {
  2396. SDBERROR_PROPOGATE();
  2397. goto eh;
  2398. }
  2399. m_csValue = GetInnerXML(pNode);
  2400. m_pDB = pDB;
  2401. bSuccess = TRUE;
  2402. eh:
  2403. return bSuccess;
  2404. }
  2405. BOOL SdbMatchOperation::ReadFromXML(
  2406. IXMLDOMNode* pNode,
  2407. SdbDatabase* pDB
  2408. )
  2409. {
  2410. BOOL bSuccess = FALSE;
  2411. if (GetNodeName(pNode) == _T("MATCH_ANY")) {
  2412. m_Type = SDB_MATCH_ANY;
  2413. } else {
  2414. m_Type = SDB_MATCH_ALL;
  2415. }
  2416. if (!m_rgMatchingFiles.ReadFromXML(_T("MATCHING_FILE"), pDB, pNode)) {
  2417. SDBERROR_PROPOGATE();
  2418. goto eh;
  2419. }
  2420. if (!m_rgSubMatchOps.ReadFromXML(_T("MATCH_ALL | MATCH_ANY"), pDB, pNode, NULL, FALSE, NULL)) {
  2421. SDBERROR_PROPOGATE();
  2422. goto eh;
  2423. }
  2424. bSuccess = TRUE;
  2425. eh:
  2426. return bSuccess;
  2427. }
  2428. BOOL SdbWin9xMigration::ReadFromXML(
  2429. IXMLDOMNode* pNode,
  2430. SdbDatabase* pDB)
  2431. {
  2432. BOOL bSuccess = FALSE;
  2433. CString csID, csTemp;
  2434. m_pApp = pDB->m_pCurrentApp; // grab app pointer from the db
  2435. if (!GetAttribute(_T("SECTION"), pNode, &m_csSection)) {
  2436. SDBERROR_FORMAT((_T("<WIN9X_MIGRATION> tag requires SECTION attribute:\n%s\n"),
  2437. GetXML(pNode)));
  2438. goto eh;
  2439. }
  2440. GetAttribute(_T("MESSAGE"), pNode, &m_csMessage);
  2441. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  2442. SDBERROR_PROPOGATE();
  2443. goto eh;
  2444. }
  2445. if (g_bStrict) {
  2446. if (!CheckExeID(pDB, this, csID)) {
  2447. SDBERROR_PROPOGATE();
  2448. goto eh;
  2449. }
  2450. }
  2451. if (GetAttribute(_T("SHOW_IN_SIMPLIFIED_VIEW"), pNode, &csTemp)) {
  2452. m_bShowInSimplifiedView = (csTemp.CompareNoCase(_T("YES")) == 0);
  2453. }
  2454. if (!m_MatchOp.ReadFromXML(pNode, pDB)) {
  2455. SDBERROR_PROPOGATE();
  2456. goto eh;
  2457. }
  2458. m_pDB = pDB;
  2459. bSuccess = TRUE;
  2460. eh:
  2461. return bSuccess;
  2462. }
  2463. BOOL SdbWinNTUpgrade::ReadFromXML(
  2464. IXMLDOMNode* pNode,
  2465. SdbDatabase* pDB)
  2466. {
  2467. BOOL bSuccess = FALSE;
  2468. BOOL bMF = FALSE;
  2469. CString csType, csHTMLHELPID, csID;
  2470. XMLNodeList XQL;
  2471. IXMLDOMNodePtr cpNewNode, cpAppNode;
  2472. m_pApp = pDB->m_pCurrentApp; // grab app pointer from the db
  2473. XQL.Query(pNode, _T("APPHELP"));
  2474. if (XQL.GetSize() > 1) {
  2475. SDBERROR_FORMAT((_T("<WINNT_UPGRADE> blocks can only contain one <APPHELP> entry:\n%s\n"),
  2476. GetXML(pNode)));
  2477. goto eh;
  2478. } else if (XQL.GetSize() == 1) {
  2479. if (!XQL.GetItem(0, &cpNewNode)) {
  2480. SDBERROR_PROPOGATE();
  2481. goto eh;
  2482. }
  2483. if (!m_AppHelpRef.ReadFromXML(cpNewNode, pDB)) {
  2484. SDBERROR_PROPOGATE();
  2485. goto eh;
  2486. }
  2487. }
  2488. if (!ProcureGuidIDAttribute(pDB, pNode, &m_ID, &csID)) {
  2489. SDBERROR_PROPOGATE();
  2490. goto eh;
  2491. }
  2492. XQL.Query(pNode, _T("MATCHING_FILE"));
  2493. if (XQL.GetSize() > 1) {
  2494. SDBERROR_FORMAT((_T("<WINNT_UPGRADE> blocks can only contain one <MATCHING_xxx> entry:\n%s\n"),
  2495. GetXML(pNode)));
  2496. goto eh;
  2497. } else if (XQL.GetSize() == 1) {
  2498. if (!XQL.GetItem(0, &cpNewNode)) {
  2499. SDBERROR_PROPOGATE();
  2500. goto eh;
  2501. }
  2502. if (!m_MatchingFile.ReadFromXML(cpNewNode, pDB)) {
  2503. SDBERROR_PROPOGATE();
  2504. goto eh;
  2505. }
  2506. bMF = TRUE;
  2507. }
  2508. XQL.Query(pNode, _T("MATCHING_REGISTRY_ENTRY"));
  2509. if (XQL.GetSize() > 1 ||
  2510. (XQL.GetSize() == 1 && bMF)) {
  2511. SDBERROR_FORMAT((_T("<WINNT_UPGRADE> blocks can only contain one <MATCHING_xxx> entry:\n%s\n"),
  2512. GetXML(pNode)));
  2513. goto eh;
  2514. } else if(XQL.GetSize() == 1) {
  2515. if (!XQL.GetItem(0, &cpNewNode)) {
  2516. SDBERROR_PROPOGATE();
  2517. goto eh;
  2518. }
  2519. if (!m_MatchingRegistryEntry.ReadFromXML(cpNewNode, pDB)) {
  2520. SDBERROR_PROPOGATE();
  2521. goto eh;
  2522. }
  2523. bMF = TRUE;
  2524. }
  2525. m_AppHelpRef.m_pDB = pDB;
  2526. m_pDB = pDB;
  2527. pDB->m_rgWinNTUpgradeEntries.Add(this, pDB);
  2528. bSuccess = TRUE;
  2529. eh:
  2530. return bSuccess;
  2531. }