void CreateDatabasesUnitTests::Test_CreateDatabases_SQLServer() { AppSecInc::Msi::MsiShim hInstall; std::wstring testdatapath = AppSecInc::File::GetModuleDirectoryW() + L"\\TestData_DataSourceUnitTests"; for each(const std::wstring& idtfile in AppSecInc::File::GetFiles(testdatapath, L"*.idt")) { std::wstring idtfile_name = AppSecInc::File::GetFileNameW(idtfile); std::wcout << std::endl << L" Importing \"" << idtfile_name << L"\""; hInstall.Import(testdatapath, idtfile_name); } AppSecInc::Msi::MsiInstall msiInstall(hInstall); std::wstring databasename = AppSecInc::Com::GenerateGUIDStringW(); AppSecInc::StringUtils::lrtrim(databasename, L"{}"); std::wcout << std::endl << L"Database: " << databasename; msiInstall.SetProperty(L"MSSQL_DATABASE_NAME", databasename); msiInstall.SetProperty(L"INSTALLLOCATION", AppSecInc::File::GetSpecialFolderPath(CSIDL_COMMON_APPDATA) + L"\\"); AppSecInc::Xml::XmlDocument xml; CPPUNIT_ASSERT(ERROR_SUCCESS == hInstall.ExecuteCA(L"DataSource.dll", L"CreateDatabases_SQLServer_Immediate")); xml.LoadXml(msiInstall.GetProperty(L"CreateDatabases_SQLServer_Deferred_Install")); // two databases, both have create actions, one is checkIfExists CPPUNIT_ASSERT(2 == xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase")->length); CPPUNIT_ASSERT(2 == xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase[@actions='create']")->length); CPPUNIT_ASSERT(1 == xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase[@checkIfExists='false']")->length); CPPUNIT_ASSERT(1 == xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase[@checkIfExists='true']")->length); // only the first database has options, but each have two file specs CPPUNIT_ASSERT(1 == xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase/MSSQLDatabaseOptions/MSSQLDatabaseOption")->length); CPPUNIT_ASSERT(4 == xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase/MSSQLDatabaseFileSpecs/MSSQLDatabaseFileSpec")->length); // connection strings must be encrypted MSXML2::IXMLDOMNodeListPtr connectionStrings = xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase/ConnectionString/text()"); for (int i = 0; i < connectionStrings->length; i++) { std::wstring encrypted = StringUtils::mb2wc(StringUtils::bstr2mb(connectionStrings->item[i]->text)); AppSecInc::Crypt::DPAPIImpl::UnProtect(encrypted); // Fails if input string is not encrypted } // create the databases msiInstall.SetProperty(L"CustomActionData", msiInstall.GetProperty(L"CreateDatabases_SQLServer_Deferred_Install")); CPPUNIT_ASSERT(ERROR_SUCCESS == hInstall.ExecuteCA(L"DataSource.dll", L"CreateDatabases_SQLServer_Deferred")); // check that both databases exist AppSecInc::Databases::MSSQL::MSSQLConnectionInfo connection_info; connection_info.SetIPAddress(L"localhost"); AppSecInc::Databases::MSSQL::MSSQLDatabase database(connection_info); database.Connect(); // check the first database database.SetName(databasename); CPPUNIT_ASSERT(database.Exists()); // check the second database database.SetName(databasename + L"2"); CPPUNIT_ASSERT(database.Exists()); // drop the created databases MSXML2::IXMLDOMNodePtr mssqldatabase_node; MSXML2::IXMLDOMNodeListPtr mssqldatabase_nodes = xml.SelectNodes(L"/MSSQLDatabases/MSSQLDatabase"); while(NULL != (mssqldatabase_node = mssqldatabase_nodes->nextNode())) xml.SetAttribute(L"actions", L"drop", mssqldatabase_node); msiInstall.SetProperty(L"CustomActionData", xml.GetXml()); CPPUNIT_ASSERT(ERROR_SUCCESS == hInstall.ExecuteCA(L"DataSource.dll", L"CreateDatabases_SQLServer_Deferred")); }
MSXML2::IXMLDOMNodePtr AccessDatabase::Save(AppSecInc::Xml::XmlDocument& xmldoc, MSXML2::IXMLDOMNodePtr parent) const { MSXML2::IXMLDOMNodePtr root = xmldoc.AppendChild(L"AccessDatabase", parent); xmldoc.AppendChild(L"DBQ", root)->text = _bstr_t(_dbq.c_str()); xmldoc.AppendChild(L"ConnectionString", root)->text = _bstr_t(AppSecInc::Crypt::DPAPIImpl::Protect(_connection_string).c_str()); return root; }
void MsiDatabaseUnitTests::testExecute() { std::wstring filename = AppSecInc::File::GetTemporaryFileNameW(); std::wcout << std::endl << L"Creating " << filename; MsiDatabase database; database.Create(filename); std::wcout << std::endl << L"Database handle " << std::hex << (MSIHANDLE) database; std::wstring path = File::GetModuleDirectoryW() + L"\\TestData_MsiUnitTests"; database.Execute(L"CREATE TABLE `Property` (`Property` CHAR(72) NOT NULL, `Value` CHAR(0) NOT NULL LOCALIZABLE PRIMARY KEY `Property`)"); database.Execute(L"INSERT INTO `Property` (`Property`, `Value`) VALUES ('ProductCode', '{72B62622-57A8-46ac-A12A-7669772D35DA}')"); database.Commit(); database.Close(); MsiPackage package(filename); MsiInstall install(package); AppSecInc::Xml::XmlDocument xmlDoc; xmlDoc.LoadXml(install.GetViewData(L"SELECT `Value` FROM `Property` WHERE `Property`='ProductCode'")); std::wstring value = xmlDoc.GetNodeValue(L"/Table/Row/Data[@Column=\"Value\"]"); std::wcout << std::endl << L"Data: " << value; CPPUNIT_ASSERT(value == L"{72B62622-57A8-46ac-A12A-7669772D35DA}"); package.Close(); AppSecInc::File::FileDelete(filename); }
void XmlDocumentUnitTests::testSelectNodes() { struct testSelectNodes_TestData { LPCWSTR xpath; long count; }; testSelectNodes_TestData testdata[] = { { L"/bookstore", 1 }, { L"/bookstore/book", 2 } }; std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); std::wcout << std::endl << L"Xml: " << xmlfile; AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); for (int i = 0; i < ARRAYSIZE(testdata); i++) { MSXML2::IXMLDOMNodeListPtr nodes = xml.SelectNodes(testdata[i].xpath); std::wcout << std::endl << testdata[i].xpath << L": " << nodes->length; CPPUNIT_ASSERT(testdata[i].count == nodes->length); } }
CA_API UINT __stdcall Xml_DeleteNodes(MSIHANDLE hInstall) { MSI_EXCEPTION_HANDLER_PROLOG; MsiInstall msiInstall(hInstall); std::wstring filename = msiInstall.GetProperty(L"XML_FILENAME"); AppSecInc::Xml::XmlDocument doc; doc.Load(filename); std::wstring xpath = msiInstall.GetProperty(L"XML_XPATH"); MSXML2::IXMLDOMNodeListPtr nodes = doc.FindNodes(xpath); int count = 0; if (NULL != nodes) { MSXML2::IXMLDOMNodePtr node = NULL; while (NULL != (node = nodes->nextNode())) { node->parentNode->removeChild(node); count++; } } if (count > 0) { CHECK_HR(doc->save(CComVariant(filename.c_str())), L"Error saving '" << filename << L"'"); } msiInstall.SetProperty(L"XML_DELETED", AppSecInc::StringUtils::toWString(count)); MSI_EXCEPTION_HANDLER_EPILOG; return ERROR_SUCCESS; }
void XmlDocumentUnitTests::testGetNodeBoolValue() { struct testGetNodeBoolValue_TestData { LPCWSTR xpath; 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); testGetNodeBoolValue_TestData testdata[] = { { L"/bookstore/book[@id=1]/read", false }, { L"/bookstore/book[@id=2]/read", true }, }; for (int i = 0; i < ARRAYSIZE(testdata); i++) { // value bool result_value = xml.GetNodeBoolValue(testdata[i].xpath); 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 MsiDatabaseUnitTests::testImport() { std::wstring filename = AppSecInc::File::GetTemporaryFileNameW(); std::wcout << std::endl << L"Creating " << filename; MsiDatabase database; database.Create(filename); std::wcout << std::endl << L"Database handle " << std::hex << (MSIHANDLE) database; std::wstring path = File::GetModuleDirectoryW() + L"\\TestData_MsiUnitTests"; database.Import(path, L"Property.idt"); database.Import(path, L"ComboBox.idt"); database.Commit(); database.Close(); MsiPackage package(filename); MsiInstall install(package); AppSecInc::Xml::XmlDocument xmlDoc; xmlDoc.LoadXml(install.GetViewData(L"SELECT * FROM `ComboBox`")); std::wstring value = xmlDoc.GetNodeValue(L"/Table/Row/Data[@Column=\"Property\"]"); std::wcout << std::endl << L"Data: " << value; CPPUNIT_ASSERT(value == L"DATABASE_SERVER"); package.Close(); AppSecInc::File::FileDelete(filename); }
void XmlDocumentUnitTests::testGetNodeValue() { struct testGetNodeValue_TestData { LPCWSTR xpath; LPCWSTR result; LPCWSTR xml; }; std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); std::wcout << std::endl << L"Xml: " << xmlfile; AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); testGetNodeValue_TestData testdata[] = { { L"/bookstore/book[@id=1]/title", L"'Emma'", L"<title xmlns=\"http://www.lucernepublishing.com\">'Emma'</title>" } }; for (int i = 0; i < ARRAYSIZE(testdata); i++) { // default value std::wstring default_value = xml.GetNodeValue(L"/invalid/xpath", NULL, L"default"); std::wcout << std::endl << L"Value: " << default_value; CPPUNIT_ASSERT(L"default" == default_value); // value std::wstring result_value = xml.GetNodeValue(testdata[i].xpath); std::wcout << std::endl << L"Value: " << result_value; CPPUNIT_ASSERT(testdata[i].result == result_value); // xml std::wstring result_xml = xml.GetNodeXml(testdata[i].xpath); std::wcout << std::endl << L"Xml: " << result_xml; CPPUNIT_ASSERT(testdata[i].xml == result_xml); } }
void XmlDocumentUnitTests::testGetNodeXml() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); std::wstring data = xml.GetNodeXml(L"/bookstore/book[@id=1]"); CPPUNIT_ASSERT(AppSecInc::StringUtils::startsWith(data, L"<book")); }
void XmlDocumentUnitTests::testFindNodes() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); CPPUNIT_ASSERT(NULL != xml.FindNodes(L"/bookstore/book[@id=1]")); CPPUNIT_ASSERT(NULL == xml.FindNodes(L"/bookstore/book[@id=1]/invalid/")); }
void XmlDocumentUnitTests::testHasNode() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); CPPUNIT_ASSERT(xml.HasNode(L"/bookstore/book[@id=1]/title")); CPPUNIT_ASSERT(! xml.HasNode(L"/bookstore/book[@id=1]/invalid")); }
void XmlDocumentUnitTests::testCreate() { AppSecInc::Xml::XmlDocument xml; xml.LoadXml(L"<xml />"); CPPUNIT_ASSERT(! xml.GetXml().empty()); xml.Create(); CPPUNIT_ASSERT(xml.GetXml().empty()); }
void CreateDatabasesUnitTests::Test_CreateDatabases_Access() { AppSecInc::Msi::MsiShim hInstall; std::wstring testdatapath = AppSecInc::File::GetModuleDirectoryW() + L"\\TestData_DataSourceUnitTests"; for each(const std::wstring& idtfile in AppSecInc::File::GetFiles(testdatapath, L"*.idt")) { std::wstring idtfile_name = AppSecInc::File::GetFileNameW(idtfile); std::wcout << std::endl << L" Importing \"" << idtfile_name << L"\""; hInstall.Import(testdatapath, idtfile_name); } AppSecInc::Msi::MsiInstall msiInstall(hInstall); std::wstring dbq = AppSecInc::File::DirectoryCombine( AppSecInc::File::GetTemporaryDirectoryW(), AppSecInc::Com::GenerateGUIDStringW() + L".dbq"); std::wcout << std::endl << L"DBQ: " << dbq; msiInstall.SetProperty(L"ACCESS_DATABASE_DBQ", dbq); msiInstall.SetProperty(L"INSTALLLOCATION", AppSecInc::File::GetSpecialFolderPath(CSIDL_COMMON_APPDATA) + L"\\"); AppSecInc::Xml::XmlDocument xml; CPPUNIT_ASSERT(ERROR_SUCCESS == hInstall.ExecuteCA(L"DataSource.dll", L"CreateDatabases_Access_Immediate")); xml.LoadXml(msiInstall.GetProperty(L"CreateDatabases_Access_Deferred_Install")); // two databases, both have create actions, one is checkIfExists CPPUNIT_ASSERT(1 == xml.SelectNodes(L"/AccessDatabases/AccessDatabase")->length); CPPUNIT_ASSERT(1 == xml.SelectNodes(L"/AccessDatabases/AccessDatabase[@actions='create']")->length); CPPUNIT_ASSERT(1 == xml.SelectNodes(L"/AccessDatabases/AccessDatabase[@checkIfExists='false']")->length); CPPUNIT_ASSERT(0 == xml.SelectNodes(L"/AccessDatabases/AccessDatabase[@checkIfExists='true']")->length); // connection strings must be encrypted MSXML2::IXMLDOMNodeListPtr connectionStrings = xml.SelectNodes(L"/AccessDatabases/AccessDatabase/ConnectionString/text()"); for (int i = 0; i < connectionStrings->length; i++) { std::wstring encrypted = StringUtils::mb2wc(StringUtils::bstr2mb(connectionStrings->item[i]->text)); AppSecInc::Crypt::DPAPIImpl::UnProtect(encrypted); // Fails if input string is not encrypted } // create the databases msiInstall.SetProperty(L"CustomActionData", msiInstall.GetProperty(L"CreateDatabases_Access_Deferred_Install")); CPPUNIT_ASSERT(ERROR_SUCCESS == hInstall.ExecuteCA(L"DataSource.dll", L"CreateDatabases_Access_Deferred")); // check that the database exists AppSecInc::Databases::Access::AccessDatabase database; database.SetDBQ(dbq); CPPUNIT_ASSERT(database.Exists()); // drop the created databases MSXML2::IXMLDOMNodePtr Accessdatabase_node; MSXML2::IXMLDOMNodeListPtr Accessdatabase_nodes = xml.SelectNodes(L"/AccessDatabases/AccessDatabase"); while(NULL != (Accessdatabase_node = Accessdatabase_nodes->nextNode())) xml.SetAttribute(L"actions", L"drop", Accessdatabase_node); msiInstall.SetProperty(L"CustomActionData", xml.GetXml()); CPPUNIT_ASSERT(ERROR_SUCCESS == hInstall.ExecuteCA(L"DataSource.dll", L"CreateDatabases_Access_Deferred")); }
void XmlDocumentUnitTests::testLoad() { 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); CPPUNIT_ASSERT(AppSecInc::StringUtils::startsWith(xml.GetXml(), L"<bookstore xmlns=\"http://www.lucernepublishing.com\">")); }
CA_API UINT __stdcall TemplateFiles_Deferred(MSIHANDLE hInstall) { MSI_EXCEPTION_HANDLER_PROLOG; MsiInstall msiInstall(hInstall); AppSecInc::Xml::XmlDocument xmlDocument; xmlDocument.LoadXml(msiInstall.GetActionData()); MSXML2::IXMLDOMNodeListPtr rows = xmlDocument.SelectNodes(L"//TemplateFile[@execute='true']"); // \todo //Row[@rollback='false'] MSXML2::IXMLDOMNodePtr row = NULL; while (NULL != (row = rows->nextNode())) { std::wstring id = xmlDocument.GetAttributeValue(L"id", row); std::wstring source = xmlDocument.GetNodeValue(L"Source", row); std::wstring target = xmlDocument.GetNodeValue(L"Target", row, source); msiInstall.LogInfo(L"TemplateFiles_Deferred", source + L" => " + target); std::map<std::wstring, std::wstring> properties; { MSXML2::IXMLDOMNodeListPtr property_rows = xmlDocument.SelectNodes(L"Properties/Property", row); MSXML2::IXMLDOMNodePtr property_row = NULL; while (NULL != (property_row = property_rows->nextNode())) { std::wstring name = xmlDocument.GetAttributeValue(L"name", property_row); std::wstring value = xmlDocument.GetAttributeValue(L"value", property_row); long escape = AppSecInc::StringUtils::stringToLong(xmlDocument.GetAttributeValue(L"escape", property_row, L"0")); properties[name] = escape == 1 ? AppSecInc::StringUtils::escape(value) : value; } } std::wstring data; bool utf8 = AppSecInc::File::ReadAndConvertToEnd(source, data); data = AppSecInc::Formatter::FormatTemplate(data, properties); std::string char_data; if (utf8) { char_data = AppSecInc::StringUtils::wc2utf8(data); char_data.insert(0, std::string(reinterpret_cast<char *>(AppSecInc::File::utf8_bom))); } else { char_data = AppSecInc::StringUtils::wc2mb(data); } std::vector<char> binary_data; binary_data.assign(char_data.begin(), char_data.end()); AppSecInc::File::FileWrite(target, binary_data); } MSI_EXCEPTION_HANDLER_EPILOG; return ERROR_SUCCESS; }
void XmlDocumentUnitTests::testGetXml() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); std::wcout << std::endl << L"Xml: " << xmlfile; AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile); std::wstring outerxml = xml.GetXml(); CPPUNIT_ASSERT(! outerxml.empty()); //! \todo read the file with File::ReadToEnd (implement) and compare data }
void XmlDocumentUnitTests::testGetAttributeValue() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); std::wcout << std::endl << L"Xml: " << xmlfile; AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile); std::wstring result = xml.GetAttributeValue(L"/bookstore/book", L"id"); std::wcout << std::endl << L"Value: " << result; CPPUNIT_ASSERT(result == L"1"); }
void XmlDocumentUnitTests::testSelectNode() { std::wstring xmlfile = GetLocalFileLocation(L"store.xml"); AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile, CLSID_DOMDocument); CPPUNIT_ASSERT(xml.SelectNode(L"/bookstore/book[@id=1]/title") != NULL); try { xml.SelectNode(L"/bookstore/book[@id=1]/invalid"); throw "expected std::exception"; } catch(std::exception& e) { std::cout << std::endl << "Expected exception: " << e.what(); } }
CA_API UINT __stdcall Xml_SelectNodeValue(MSIHANDLE hInstall) { MSI_EXCEPTION_HANDLER_PROLOG; MsiInstall msiInstall(hInstall); std::wstring filename = msiInstall.GetProperty(L"XML_FILENAME"); AppSecInc::Xml::XmlDocument doc; doc.Load(filename); std::wstring xpath = msiInstall.GetProperty(L"XML_XPATH"); std::wstring value = doc.GetNodeValue(xpath); msiInstall.SetProperty(L"XML_NODEVALUE", value); MSI_EXCEPTION_HANDLER_EPILOG; return ERROR_SUCCESS; }
void AccessDatabaseUnitTests::testLoadSave() { AccessDatabase database1; database1.SetDBQ(L"test"); AppSecInc::Xml::XmlDocument doc; doc.Create(); MSXML2::IXMLDOMNodePtr root = doc.AppendChild(L"Databases"); MSXML2::IXMLDOMNodePtr database_root = database1.Save(doc, root); std::wcout << std::endl << doc.GetXml(); AccessDatabase database2; database2.Load(doc, database_root); CPPUNIT_ASSERT(database2.GetDBQ() == database1.GetDBQ()); }
void XmlDocumentUnitTests::testXslTransform() { // check test xml file std::wstring xmlfile = GetLocalFileLocation(L"simple.xml"); std::wcout << std::endl << L"Xml: " << xmlfile; CPPUNIT_ASSERT(File::FileExists(xmlfile)); // check test xsl file std::wstring xslfile = GetLocalFileLocation(L"simple.xsl"); std::wcout << std::endl << L"Xsl: " << xslfile; CPPUNIT_ASSERT(File::FileExists(xslfile)); // transform AppSecInc::Xml::XmlDocument xml; xml.Load(xmlfile); AppSecInc::Xml::XmlDocument transformedXml; std::wstring transformResult = xml.XslTransform(xslfile); transformedXml.LoadXml(transformResult); // load the result CPPUNIT_ASSERT(transformResult.length() > 0); }
CA_API UINT __stdcall Xml_XslTransform(MSIHANDLE hInstall) { MSI_EXCEPTION_HANDLER_PROLOG; MsiInstall msiInstall(hInstall); std::wstring filename = msiInstall.GetProperty(L"XML_FILENAME"); AppSecInc::Xml::XmlDocument doc; doc.Load(filename); std::wstring xslt_filename = msiInstall.GetProperty(L"XSLT_FILENAME"); std::wstring xslt_result_filename = msiInstall.GetProperty(L"XSLT_RESULT_FILENAME"); std::wstring transformedData = doc.XslTransform(xslt_filename); std::string char_data = AppSecInc::StringUtils::wc2mb(transformedData); std::vector<char> binary_data; binary_data.assign(char_data.begin(), char_data.end()); AppSecInc::File::FileWrite(xslt_result_filename, binary_data); MSI_EXCEPTION_HANDLER_EPILOG; return ERROR_SUCCESS; }
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::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; }
void AccessDatabase::Load(AppSecInc::Xml::XmlDocument& xmldoc, MSXML2::IXMLDOMNodePtr root) { _dbq = xmldoc.GetNodeValue(L"DBQ", root); _connection_string = AppSecInc::Crypt::DPAPIImpl::UnProtect(xmldoc.GetNodeValue(L"ConnectionString", root, L"")); }
CA_API UINT __stdcall LocalGroupMembers_Deferred(MSIHANDLE hInstall) { MSI_EXCEPTION_HANDLER_PROLOG; MsiInstall msiInstall(hInstall); AppSecInc::Xml::XmlDocument xmlDocument; xmlDocument.LoadXml(msiInstall.GetActionData()); MSXML2::IXMLDOMNodeListPtr rows = xmlDocument.SelectNodes(L"/LocalGroupMembers/LocalGroupMember"); MSXML2::IXMLDOMNodePtr row = NULL; while (NULL != (row = rows->nextNode())) { std::wstring id = xmlDocument.GetAttributeValue(L"id", row); std::wstring username = xmlDocument.GetNodeValue(L"Username", row); std::wstring groupname = xmlDocument.GetNodeValue(L"Group", row, L""); bool add_member = xmlDocument.GetAttributeBoolValue(L"add", row); bool remove_member = xmlDocument.GetAttributeBoolValue(L"remove", row); bool check = xmlDocument.GetAttributeBoolValue(L"check", row); if (remove_member && (! check || AppSecInc::LSA::LocalGroup::IsMember(groupname, username))) { msiInstall.LogInfo(_T(__FUNCTION__), L"Removing \"" + username + L"\" from \"" + groupname + L"\""); AppSecInc::LSA::LocalGroup::DeleteMember(groupname, username); } if (add_member && (! check || ! AppSecInc::LSA::LocalGroup::IsMember(groupname, username))) { msiInstall.LogInfo(_T(__FUNCTION__), L"Adding \"" + username + L"\" to \"" + groupname + L"\""); AppSecInc::LSA::LocalGroup::AddMember(groupname, username); } } MSI_EXCEPTION_HANDLER_EPILOG; return ERROR_SUCCESS; }