void XmlDocumentUnitTests::testHasAttribute() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); CPPUNIT_ASSERT(xml.HasAttribute(L"id", xml.SelectNode(L"/bookstore/book[@id=1]"))); CPPUNIT_ASSERT(! xml.HasAttribute(L"iddoesntexist", xml.SelectNode(L"/bookstore/book[@id=1]"))); }
void XmlDocumentUnitTests::testSelectAttribute() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); CPPUNIT_ASSERT(NULL != xml.SelectAttribute(L"id", xml.SelectNode(L"/bookstore/book[@id=1]"))); try { xml.SelectAttribute(L"iddoesntexist", xml.SelectNode(L"/bookstore/book[@id=1]")); throw "expected std::exception"; } catch(std::exception& e) { std::cout << std::endl << "Expected exception: " << e.what(); } }
void XmlDocumentUnitTests::testGetAttributeBoolValue() { struct testGetAttributeBoolValue_TestData { LPCWSTR xpath; LPCWSTR name; bool result; }; std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); std::wcout << std::endl << L"Xml: " << xmlfile.c_str(); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); testGetAttributeBoolValue_TestData testdata[] = { { L"/bookstore/book[@id=1]", L"returned", false }, { L"/bookstore/book[@id=2]", L"returned", true }, }; for (int i = 0; i < ARRAYSIZE(testdata); i++) { MSXML2::IXMLDOMNodePtr node = xml.SelectNode(testdata[i].xpath); // value bool result_value = xml.GetAttributeBoolValue(testdata[i].name, node); std::wcout << std::endl << L"Value: " << result_value; CPPUNIT_ASSERT(testdata[i].result == result_value); } }
void XmlDocumentUnitTests::testGetAttributeValueXPath() { struct testGetAttributeValue_TestData { LPCWSTR xpath; LPCWSTR name; LPCWSTR result; }; std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); std::wcout << std::endl << L"Xml: " << xmlfile; AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); testGetAttributeValue_TestData testdata[] = { { L"/bookstore/book[@id=1]", L"id", L"1" } }; for (int i = 0; i < ARRAYSIZE(testdata); i++) { MSXML2::IXMLDOMNodePtr node = xml.SelectNode(testdata[i].xpath); // default value std::wstring default_value = xml.GetAttributeValue(L"invalid", node, L"default"); std::wcout << std::endl << L"Value: " << default_value; CPPUNIT_ASSERT(L"default" == default_value); // value std::wstring result_value = xml.GetAttributeValue(testdata[i].name, node); std::wcout << std::endl << L"Value: " << result_value; CPPUNIT_ASSERT(testdata[i].result == result_value); } }
void XmlDocumentUnitTests::testSetAttribute() { AppSecInc::Xml::XmlDocument xml; xml.Create(); xml.AppendChild(L"xml"); { xml.SetAttribute(L"name", L"value", xml.SelectNode(L"/xml")); std::wstring data = xml.GetXml(); AppSecInc::StringUtils::lrtrim(data, L"\r\n"); std::wcout << std::endl << data; CPPUNIT_ASSERT(data == L"<xml name=\"value\"/>"); } }
void XmlDocumentUnitTests::testAppendChild() { AppSecInc::Xml::XmlDocument xml; xml.Create(); xml.AppendChild(L"xml"); { std::wstring data = xml.GetXml(); AppSecInc::StringUtils::lrtrim(data, L"\r\n"); std::wcout << std::endl << data; CPPUNIT_ASSERT(! data.empty()); CPPUNIT_ASSERT(data == L"<xml/>"); } { xml.AppendChild(L"node", xml.SelectNode(L"/xml")); std::wstring data = xml.GetXml(); AppSecInc::StringUtils::lrtrim(data, L"\r\n"); std::wcout << std::endl << data; CPPUNIT_ASSERT(! data.empty()); CPPUNIT_ASSERT(data == L"<xml><node/></xml>"); } }
CA_API UINT __stdcall TemplateFiles_Immediate(MSIHANDLE hInstall) { MSI_EXCEPTION_HANDLER_PROLOG; MsiInstall msiInstall(hInstall); // combined xml document AppSecInc::Xml::XmlDocument combined_xml_document; combined_xml_document.Create(); MSXML2::IXMLDOMNodePtr combined_xml_root = combined_xml_document.AppendChild(L"TemplateFiles"); std::wstring xml = msiInstall.GetViewData(L"SELECT * FROM `TemplateFiles`"); AppSecInc::Xml::XmlDocument xmlDocument; xmlDocument.LoadXml(xml); { MSXML2::IXMLDOMNodeListPtr rows = xmlDocument.SelectNodes(L"//Row"); MSXML2::IXMLDOMNodePtr row = NULL; while (NULL != (row = rows->nextNode())) { // id std::wstring templatefile_id = xmlDocument.GetNodeValue(L"Data[@Column=\"Id\"]", row, L""); // component id std::wstring component_id = xmlDocument.GetNodeValue(L"Data[@Column=\"ComponentId\"]", row, L""); // node condition std::wstring condition = xmlDocument.GetNodeValue(L"Data[@Column=\"Condition\"]", row); // operational attributes long attributes = AppSecInc::StringUtils::stringToLong(xmlDocument.GetNodeValue(L"Data[@Column=\"Attributes\"]", row)); // no condition (executes by default) or condition evaluates to true bool execute_per_condition = condition.empty() || msiInstall.EvaluateCondition(condition); if (! condition.empty()) { // set the evaluated value for debugging purposes xmlDocument.SelectNode(L"Data[@Column=\"Condition\"]", row)->text = _bstr_t(execute_per_condition ? L"1" : L"0"); } // execute on install bool execute_per_component_install = (component_id.empty() || msiInstall.IsComponentInstalling(component_id)); // execute on uninstall bool execute_per_component_uninstall = (component_id.empty() || msiInstall.IsComponentUnInstalling(component_id)); // execute on reinstall bool execute_per_component_reinstall = (component_id.empty() || msiInstall.IsComponentReInstalling(component_id)); bool execute = execute_per_condition && ( (execute_per_component_install && (attributes & ExecuteOnInstall) && msiInstall.IsInstalling()) || (execute_per_component_uninstall && (attributes & ExecuteOnUnInstall) && msiInstall.IsUnInstalling()) || (execute_per_component_reinstall && (attributes & ExecuteOnReInstall) && msiInstall.IsReInstalling()) ); MSXML2::IXMLDOMNodePtr templatefile_node = combined_xml_document.AppendChild(L"TemplateFile", combined_xml_root); combined_xml_document.SetAttribute(L"id", templatefile_id, templatefile_node); std::wstring source = xmlDocument.GetNodeValue(L"Data[@Column=\"Source\"]", row); std::wstring target = xmlDocument.GetNodeValue(L"Data[@Column=\"Target\"]", row, source); combined_xml_document.AppendChild(L"Source", templatefile_node)->text = _bstr_t(source.c_str()); combined_xml_document.AppendChild(L"Target", templatefile_node)->text = _bstr_t(target.c_str()); combined_xml_document.SetAttribute(L"execute", execute ? L"true" : L"false", templatefile_node); MSXML2::IXMLDOMNodePtr properties_node = combined_xml_document.AppendChild(L"Properties", templatefile_node); // append built-in properties { AppSecInc::Xml::XmlDocument xmlPropertiesDocument; xmlPropertiesDocument.LoadXml(msiInstall.GetViewData(L"SELECT * FROM `Property`")); MSXML2::IXMLDOMNodeListPtr property_rows = xmlPropertiesDocument.SelectNodes(L"//Row"); MSXML2::IXMLDOMNodePtr property_row = NULL; while (NULL != (property_row = property_rows->nextNode())) { std::wstring name = xmlPropertiesDocument.GetNodeValue(L"Data[@Column=\"Property\"]", property_row); std::wstring value = xmlPropertiesDocument.GetNodeValue(L"Data[@Column=\"Value\"]", property_row); MSXML2::IXMLDOMNodePtr property_node = combined_xml_document.AppendChild(L"Property", properties_node); combined_xml_document.SetAttribute(L"name", name, property_node); combined_xml_document.SetAttribute(L"value", value, property_node); } } // append properties from this TemplateFile { AppSecInc::Xml::XmlDocument xmlPropertiesDocument; xmlPropertiesDocument.LoadXml(msiInstall.GetViewData(L"SELECT * FROM `TemplateFileProperties`")); MSXML2::IXMLDOMNodeListPtr property_rows = xmlPropertiesDocument.SelectNodes(L"//Row"); MSXML2::IXMLDOMNodePtr property_row = NULL; while (NULL != (property_row = property_rows->nextNode())) { // \todo Change XPATH to fetch only rows that match ID std::wstring id = xmlPropertiesDocument.GetNodeValue(L"Data[@Column=\"TemplateFileId\"]", property_row); if (id != templatefile_id) continue; std::wstring name = xmlPropertiesDocument.GetNodeValue(L"Data[@Column=\"Name\"]", property_row); std::wstring value = xmlPropertiesDocument.GetNodeValue(L"Data[@Column=\"Value\"]", property_row); std::wstring escape = xmlPropertiesDocument.GetNodeValue(L"Data[@Column=\"Escape\"]", property_row); MSXML2::IXMLDOMNodePtr property_node = combined_xml_document.AppendChild(L"Property", properties_node); combined_xml_document.SetAttribute(L"name", name, property_node); combined_xml_document.SetAttribute(L"value", value, property_node); combined_xml_document.SetAttribute(L"escape", escape, property_node); } } } } msiInstall.SetActionData(L"TemplateFiles_Deferred", combined_xml_document.GetXml()); MSI_EXCEPTION_HANDLER_EPILOG; return ERROR_SUCCESS; }