mirror of
https://github.com/august-alt/gpui.git
synced 2025-03-14 12:58:39 +03:00
Merge branch 'august-alt:master' into scripts-title-fix
This commit is contained in:
commit
5224892a8d
@ -438,10 +438,10 @@ void AdministrativeTemplatesSnapIn::onShutdown()
|
||||
|
||||
void AdministrativeTemplatesSnapIn::onDataLoad(const std::string &policyPath, const std::string &locale)
|
||||
{
|
||||
Q_UNUSED(locale);
|
||||
|
||||
if (!policyPath.empty())
|
||||
{
|
||||
QString localeName = QString::fromStdString(locale);
|
||||
|
||||
d->policyPath = policyPath;
|
||||
|
||||
d->userRegistryPath = QString::fromStdString(policyPath) + "/User/Registry.pol";
|
||||
@ -464,8 +464,8 @@ void AdministrativeTemplatesSnapIn::onDataLoad(const std::string &policyPath, co
|
||||
d->proxyModel->setMachineRegistrySource(d->machineRegistrySource.get());
|
||||
d->filterModel->setMachineRegistrySource(d->machineRegistrySource.get());
|
||||
|
||||
d->machineCommentsModel->load(QString::fromStdString(policyPath) + "/Machine/comment.cmtx");
|
||||
d->userCommentsModel->load(QString::fromStdString(policyPath) + "/User/comment.cmtx");
|
||||
d->machineCommentsModel->load(QString::fromStdString(policyPath) + "/Machine/comment.cmtx", localeName);
|
||||
d->userCommentsModel->load(QString::fromStdString(policyPath) + "/User/comment.cmtx", localeName);
|
||||
|
||||
d->proxyModel->setMachineCommentModel(d->machineCommentsModel.get());
|
||||
d->proxyModel->setUserCommentModel(d->userCommentsModel.get());
|
||||
@ -486,11 +486,14 @@ void AdministrativeTemplatesSnapIn::setMenuItemNames()
|
||||
|
||||
void AdministrativeTemplatesSnapIn::onRetranslateUI(const std::string &locale)
|
||||
{
|
||||
QString localeName = QString::fromStdString(locale);
|
||||
d->localeName = locale;
|
||||
d->policyBundleLoad();
|
||||
setMenuItemNames();
|
||||
d->filterDialog->onLanguageChanged();
|
||||
d->updateFilter();
|
||||
d->machineCommentsModel->load(d->machineCommentsPath + "/comment.cmtx", localeName);
|
||||
d->userCommentsModel->load(d->userCommentsPath + "/comment.cmtx", localeName);
|
||||
setRootNode(static_cast<QAbstractItemModel *>(d->filterModel.get()));
|
||||
}
|
||||
|
||||
|
@ -160,11 +160,9 @@ void savePolicies(const QString &pluginName, const QString &fileName, std::share
|
||||
delete format;
|
||||
}
|
||||
|
||||
QString constructCMTLFileName(const QFileInfo &fileName)
|
||||
QString constructCMTLFileName(const QFileInfo &fileName, const QString &localeName)
|
||||
{
|
||||
QString admlFileName = fileName.filePath();
|
||||
admlFileName.replace(admlFileName.length() - 4, 4, "cmtl");
|
||||
|
||||
QString admlFileName = fileName.absoluteDir().path() + "/" + localeName + "/" + fileName.baseName() + ".cmtl";
|
||||
return admlFileName;
|
||||
}
|
||||
|
||||
@ -192,8 +190,9 @@ std::string constructPolicyRef(const std::string& id)
|
||||
return id.substr(4);
|
||||
}
|
||||
|
||||
void CommentsModel::load(const QString &cmtxFileName)
|
||||
void CommentsModel::load(const QString &cmtxFileName, const QString &localeName)
|
||||
{
|
||||
this->clear();
|
||||
auto commentDefinitions
|
||||
= loadPolicies<io::PolicyCommentsFile, io::PolicyFileFormat<io::PolicyCommentsFile>>("cmtx", cmtxFileName);
|
||||
if (!commentDefinitions.get())
|
||||
@ -203,9 +202,10 @@ void CommentsModel::load(const QString &cmtxFileName)
|
||||
}
|
||||
|
||||
bool noCMTL = false;
|
||||
QString cmtlFileName = constructCMTLFileName(cmtxFileName);
|
||||
QString cmtlFileName = constructCMTLFileName(cmtxFileName, localeName);
|
||||
auto commentTranslations
|
||||
= loadPolicies<io::CommentResourcesFile, io::PolicyFileFormat<io::CommentResourcesFile>>("cmtl", cmtlFileName);
|
||||
|
||||
if (!commentTranslations.get())
|
||||
{
|
||||
qWarning() << "File not found: " << cmtlFileName;
|
||||
@ -298,7 +298,7 @@ void CommentsModel::save(const QString &path, const QString& localeName)
|
||||
|
||||
commentDefinitions->resources = std::make_unique<LocalizationResourceReference>();
|
||||
|
||||
bool enableLocalizedComments = localeName != "en-US";
|
||||
bool englishLocalization = localeName != "en-US";
|
||||
|
||||
for (const auto& comment : comments)
|
||||
{
|
||||
@ -322,40 +322,7 @@ void CommentsModel::save(const QString &path, const QString& localeName)
|
||||
|
||||
commentDefinitions->comments.push_back(currentComment);
|
||||
|
||||
commentDefinitions->resources->stringTable.emplace_back((enableLocalizedComments
|
||||
? ""
|
||||
: comment.second.toStdString()),
|
||||
resourceName);
|
||||
}
|
||||
|
||||
if (enableLocalizedComments)
|
||||
{
|
||||
auto cmtlFileName = path + "comment.cmtl";
|
||||
|
||||
std::shared_ptr<comments::CommentDefinitionResources> commentResources
|
||||
= std::make_shared<comments::CommentDefinitionResources>();
|
||||
|
||||
for (const auto& comment : comments)
|
||||
{
|
||||
namespaceIndex = 0;
|
||||
|
||||
for (const auto& currentNamespace : commentDefinitions->policyNamespaces.using_)
|
||||
{
|
||||
if (comment.namespace_.compare(currentNamespace.namespace_.c_str()) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
namespaceIndex++;
|
||||
}
|
||||
|
||||
commentResources->stringTable.emplace_back(comment.second.toStdString(),
|
||||
"ns" + std::to_string(namespaceIndex)
|
||||
+ "_" + comment.first.toStdString());
|
||||
}
|
||||
|
||||
savePolicies<io::CommentResourcesFile, comments::CommentDefinitionResources>("cmtl", cmtlFileName,
|
||||
commentResources);
|
||||
commentDefinitions->resources->stringTable.emplace_back((comment.second.toStdString()), resourceName);
|
||||
}
|
||||
|
||||
auto cmtxFileName = path + "comment.cmtx";
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
public:
|
||||
CommentsModel(QObject* parent = nullptr);
|
||||
|
||||
void load(const QString& path);
|
||||
void load(const QString& path, const QString &localeName);
|
||||
void save(const QString &path, const QString &localeName);
|
||||
|
||||
QModelIndex indexFromItemReference(const QString &itemRef);
|
||||
|
@ -48,8 +48,12 @@ public:
|
||||
virtual void markValueForDeletion(const std::string &key, const std::string &valueName) = 0;
|
||||
virtual bool undeleteValue(const std::string &key, const std::string &valueName) = 0;
|
||||
virtual bool isValueMarkedForDeletion(const std::string &key, const std::string &valueName) const = 0;
|
||||
|
||||
virtual std::vector<std::string> getNonSpecialValueNames(const std::string &key) const = 0;
|
||||
virtual std::vector<std::string> getValueNames(const std::string &key) const = 0;
|
||||
|
||||
virtual void markKeyForDeletion(const std::string &key) = 0;
|
||||
|
||||
virtual std::vector<std::string> getValueNames(const std::string &key) const = 0;
|
||||
virtual void clearKey(const std::string &key) = 0;
|
||||
virtual void clearValue(const std::string &key, const std::string &valueName) = 0;
|
||||
|
||||
|
@ -207,7 +207,30 @@ std::vector<std::string> PolRegistrySource::getValueNames(const std::string &key
|
||||
return result;
|
||||
}
|
||||
|
||||
void PolRegistrySource::clearKey(const std::string &key)
|
||||
static bool isSpecialValueName(const std::string &str)
|
||||
{
|
||||
// TODO: make case-insensitive
|
||||
// TODO: check for others
|
||||
return (str == "**deletevalues") ||
|
||||
(str == "**delvals.") ||
|
||||
(str == "**deletekeys") ||
|
||||
(str == "**securekey") ||
|
||||
(str.length() >= 6 && strncmp(str.c_str(), "**del.", 6)) ||
|
||||
(str.length() >= 7 && strncmp(str.c_str(), "**soft.", 7));
|
||||
}
|
||||
|
||||
std::vector<std::string> PolRegistrySource::getNonSpecialValueNames(const std::string &key) const
|
||||
{
|
||||
std::vector<std::string> result = getValueNames(key);
|
||||
|
||||
result.erase(std::remove_if(result.begin(),
|
||||
result.end(),
|
||||
&isSpecialValueName),
|
||||
result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
void PolRegistrySource::markKeyForDeletion(const std::string &key)
|
||||
{
|
||||
std::vector<std::string> values = getValueNames(key);
|
||||
for (const auto &value : values)
|
||||
@ -216,6 +239,15 @@ void PolRegistrySource::clearKey(const std::string &key)
|
||||
}
|
||||
}
|
||||
|
||||
void PolRegistrySource::clearKey(const std::string &key)
|
||||
{
|
||||
std::vector<std::string> values = getValueNames(key);
|
||||
for (const auto &value : values)
|
||||
{
|
||||
clearValue(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PolRegistrySource::clearValue(const std::string &key, const std::string &valueName)
|
||||
{
|
||||
auto &entries = d->registry->registryEntries;
|
||||
|
@ -55,7 +55,10 @@ public:
|
||||
bool undeleteValue(const std::string &key, const std::string &valueName) override final;
|
||||
bool isValueMarkedForDeletion(const std::string &key, const std::string &valueName) const override final;
|
||||
|
||||
std::vector<std::string> getNonSpecialValueNames(const std::string &key) const override final;
|
||||
std::vector<std::string> getValueNames(const std::string &key) const override final;
|
||||
void markKeyForDeletion(const std::string &key) override final;
|
||||
|
||||
void clearKey(const std::string &key) override final;
|
||||
void clearValue(const std::string &key, const std::string &valueName) override final;
|
||||
|
||||
|
@ -262,7 +262,10 @@ void AdministrativeTemplatesWidget::setModelIndex(const QModelIndex &index)
|
||||
{
|
||||
ui->okPushButton->disconnect();
|
||||
ui->cancelPushButton->disconnect();
|
||||
}
|
||||
|
||||
if (commentsModel && policy)
|
||||
{
|
||||
auto gui = this->ui;
|
||||
|
||||
connect(ui->okPushButton, &QPushButton::clicked, [commentsModel, gui, policy]() -> void
|
||||
@ -275,7 +278,10 @@ void AdministrativeTemplatesWidget::setModelIndex(const QModelIndex &index)
|
||||
commentsModel->setComment(commentText, QString::fromStdString(policy->name),
|
||||
QString::fromStdString(policy->namespace_));
|
||||
});
|
||||
}
|
||||
|
||||
if (presentation && policy)
|
||||
{
|
||||
auto layout = PresentationBuilder::build(
|
||||
{*presentation, *policy, *source, *ui->okPushButton, d->dataChanged, d->stateEnabled});
|
||||
connectDialogBoxSignals();
|
||||
|
@ -107,6 +107,93 @@ QHBoxLayout *createCaptions()
|
||||
return horizontalLayout;
|
||||
}
|
||||
|
||||
QMap<std::string, QString> loadListFromRegistry(AbstractRegistrySource &source, const std::string &key, const std::string &prefix)
|
||||
{
|
||||
QMap<std::string, QString> items;
|
||||
std::vector<std::string> valueNames = source.getNonSpecialValueNames(key);
|
||||
|
||||
if(!prefix.empty())
|
||||
{
|
||||
// remove all valueNames(from return result), that doesn't have `prefix` prefix
|
||||
valueNames.erase(std::remove_if(valueNames.begin(), valueNames.end(),
|
||||
[&prefix](const std::string& str)
|
||||
{
|
||||
return !(str.length() > prefix.length() &&
|
||||
strncmp(str.c_str(), prefix.c_str(), prefix.length()));
|
||||
}), valueNames.end());
|
||||
}
|
||||
|
||||
for (auto &valueName : valueNames) {
|
||||
items[valueName] =
|
||||
source.getValue(key, valueName).value<QString>();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
void cleanUpListInRegistry(AbstractRegistrySource &source, const std::string &key, const std::string &prefix = "")
|
||||
{
|
||||
// small optimization
|
||||
if (prefix.empty())
|
||||
{
|
||||
source.clearKey(key);
|
||||
}
|
||||
|
||||
std::vector<std::string> valueNames = source.getNonSpecialValueNames(key);
|
||||
|
||||
// TODO: make case-insensitive.
|
||||
// clean-up all values that contain `prefix` prefix (case-sensitive)
|
||||
for (auto &value : valueNames) {
|
||||
if (value.size() > prefix.size() &&
|
||||
strncmp(value.c_str(), prefix.c_str(), prefix.size()) == 0)
|
||||
{
|
||||
source.clearValue(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeListIntoRegistry(AbstractRegistrySource &source, QMap<std::string, QString> valueList, const std::string &key, bool explicitValue, bool expandable, std::string &prefix)
|
||||
{
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc731025(v=ws.10)
|
||||
// explicitValue cannot be used with the valuePrefix attribute.
|
||||
if (explicitValue && !prefix.empty())
|
||||
{
|
||||
qWarning() << "Presentation builder::save: attempt to use explicitValue with the valuePrefix attribute";
|
||||
}
|
||||
|
||||
if (valueList.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc770327(v=ws.10)
|
||||
// true represents expandable string type (REG_EXPAND_SZ) and false represents string type (REG_SZ)
|
||||
auto type = expandable ? REG_EXPAND_SZ : REG_SZ;
|
||||
|
||||
if (explicitValue)
|
||||
{
|
||||
for (auto begin = valueList.begin(), end = valueList.end(); begin != end; ++begin)
|
||||
{
|
||||
if (!begin.value().trimmed().isEmpty())
|
||||
{
|
||||
source.setValue(key, begin.key(), type, begin.value());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gpreg/57226664-ce00-4487-994e-a6b3820f3e49
|
||||
// for non explicit values. Non-explicit value will be ignored.
|
||||
source.setValue(key, "**delvals.", REG_SZ, " ");
|
||||
|
||||
size_t index = 1;
|
||||
for (auto begin = valueList.begin(), end = valueList.end(); begin != end; ++begin, ++index)
|
||||
{
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc772195(v=ws.10)
|
||||
// valuePrefix represents the text string to be prepended to the incremented integer for registry subkey creation.
|
||||
source.setValue(key, prefix + std::to_string(index), type, begin.value());
|
||||
}
|
||||
}
|
||||
|
||||
bool *m_dataChanged = nullptr;
|
||||
bool *m_stateEnabled = nullptr;
|
||||
|
||||
@ -445,145 +532,49 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc731025(v=ws.10)
|
||||
// explicitValue cannot be used with the valuePrefix attribute.
|
||||
if (listElement->valuePrefix.size() > 0 && listElement->explicitValue)
|
||||
{
|
||||
qWarning() << "Unable to get valid policy listElement (explicitValue cannot be used with the valuePrefix attribute).";
|
||||
return;
|
||||
}
|
||||
|
||||
RegistryEntryType registryEntryType = listElement->expandable ? RegistryEntryType::REG_EXPAND_SZ
|
||||
: RegistryEntryType::REG_SZ;
|
||||
|
||||
if (listElement->explicitValue)
|
||||
{
|
||||
{
|
||||
QMap<std::string, QString> items;
|
||||
// Create two column widget.
|
||||
auto valueNames = m_source->getValueNames(listElement->key);
|
||||
for (const auto &valueName : valueNames)
|
||||
{
|
||||
items[valueName] = m_source->getValue(listElement->key, valueName).toString();
|
||||
}
|
||||
listBox->setItems(items);
|
||||
}
|
||||
|
||||
listBox->connect(listBox,
|
||||
&gpui::ListBoxDialog::itemsEditingFinished,
|
||||
[=](QMap<std::string, QString> currentItems) {
|
||||
if (!(*m_stateEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
qWarning() << "Items debug: " << currentItems.values();
|
||||
// clean-up registry values.
|
||||
auto valueNames = m_source->getValueNames(listElement->key);
|
||||
for (const auto &valueName : valueNames)
|
||||
{
|
||||
m_source->clearValue(listElement->key, valueName);
|
||||
}
|
||||
// set-up current values.
|
||||
for (const auto &valueName : currentItems.keys())
|
||||
{
|
||||
auto value = currentItems.value(valueName);
|
||||
if (!value.trimmed().isEmpty())
|
||||
{
|
||||
m_source->setValue(elementInfo.key,
|
||||
valueName,
|
||||
registryEntryType,
|
||||
value);
|
||||
}
|
||||
}
|
||||
*m_dataChanged = true;
|
||||
});
|
||||
// two collumn ListBox
|
||||
listBox->setItems(loadListFromRegistry(*m_source, listElement->key, listElement->valuePrefix));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// Create one column widget.
|
||||
QStringList items;
|
||||
|
||||
if (listElement->valuePrefix.size() > 0)
|
||||
{
|
||||
// If there is a prefix then use prefix to load values.
|
||||
{
|
||||
auto valueNames = m_source->getValueNames(listElement->key);
|
||||
size_t index = 1;
|
||||
auto valueName = listElement->valuePrefix + std::to_string(index);
|
||||
while (m_source->isValuePresent(listElement->key, valueName))
|
||||
{
|
||||
items.append(m_source->getValue(listElement->key, valueName).toString());
|
||||
valueName = listElement->valuePrefix + std::to_string(++index);
|
||||
}
|
||||
}
|
||||
|
||||
listBox->connect(listBox,
|
||||
&gpui::ListBoxDialog::itemsEditingFinished,
|
||||
[=](QMap<std::string, QString> currentItems) {
|
||||
if (!(*m_stateEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
qWarning() << "Items debug: " << currentItems.values();
|
||||
size_t index = 1;
|
||||
// clean-up registry values.
|
||||
auto registryValueName = listElement->valuePrefix
|
||||
+ std::to_string(index);
|
||||
while (m_source->isValuePresent(listElement->key, registryValueName))
|
||||
{
|
||||
m_source->clearValue(listElement->key, registryValueName);
|
||||
registryValueName = listElement->valuePrefix
|
||||
+ std::to_string(++index);
|
||||
}
|
||||
// set-up current values.
|
||||
for (const auto &item : currentItems.values())
|
||||
{
|
||||
if (!item.trimmed().isEmpty())
|
||||
{
|
||||
auto valueName = listElement->valueName
|
||||
+ std::to_string(index);
|
||||
m_source->setValue(elementInfo.key,
|
||||
valueName,
|
||||
registryEntryType,
|
||||
item);
|
||||
}
|
||||
}
|
||||
*m_dataChanged = true;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
auto valueNames = m_source->getValueNames(listElement->key);
|
||||
for (const auto &valueName : valueNames)
|
||||
{
|
||||
items.append(m_source->getValue(listElement->key, valueName).toString());
|
||||
}
|
||||
|
||||
listBox->connect(listBox,
|
||||
&gpui::ListBoxDialog::itemsEditingFinished,
|
||||
[=](QMap<std::string, QString> currentItems) {
|
||||
if (!(*m_stateEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
qWarning() << "Items debug: " << currentItems.values();
|
||||
// clean-up registry values.
|
||||
auto registryValueNames = m_source->getValueNames(listElement->key);
|
||||
for (const auto &valueName : registryValueNames)
|
||||
{
|
||||
m_source->clearValue(listElement->key, valueName);
|
||||
}
|
||||
// set-up current values.
|
||||
for (const auto &item : currentItems.values())
|
||||
{
|
||||
if (!item.trimmed().isEmpty())
|
||||
{
|
||||
m_source->setValue(elementInfo.key,
|
||||
item.toStdString(),
|
||||
registryEntryType,
|
||||
item);
|
||||
}
|
||||
}
|
||||
*m_dataChanged = true;
|
||||
});
|
||||
}
|
||||
|
||||
qWarning() << "Items debug: " << items;
|
||||
listBox->setItems(items);
|
||||
// one collumn ListBox
|
||||
listBox->setItems(loadListFromRegistry(*m_source, listElement->key, listElement->valuePrefix).values());
|
||||
}
|
||||
|
||||
listBox->connect(listBox,
|
||||
&gpui::ListBoxDialog::itemsEditingFinished,
|
||||
[=](QMap<std::string, QString> currentItems) {
|
||||
if (!(*m_stateEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
qWarning() << "Items debug: " << currentItems.values();
|
||||
|
||||
cleanUpListInRegistry(*m_source, listElement->key, listElement->valuePrefix);
|
||||
|
||||
writeListIntoRegistry(*m_source,
|
||||
currentItems,
|
||||
listElement->key,
|
||||
listElement->explicitValue,
|
||||
listElement->expandable,
|
||||
listElement->valuePrefix);
|
||||
|
||||
*m_dataChanged = true;
|
||||
});
|
||||
|
||||
listBox->show();
|
||||
};
|
||||
|
||||
|
@ -28,11 +28,11 @@ namespace pol {
|
||||
|
||||
/*!
|
||||
* \brief Valid POL Registery file header. Binary equal valid header.
|
||||
* leToNative is used because the entry 0x5052656701000000 is
|
||||
* leToNative is used because the entry 0x0167655250 is
|
||||
* equivalent to the header in case uint64_t stores a number in LittleEndian.
|
||||
* BigEndian - 0x00 0x00 0x00 0x01 0x67 0x65 0x52 0x50
|
||||
* BigEndian - 0x00 0x00 0x00 0x01 0x67 0x65 0x52 0x50 (bytes must be swaped)
|
||||
*/
|
||||
static const uint64_t valid_header = leToNative<uint64_t>(0x5052656701000000);
|
||||
static const uint64_t valid_header = leToNative<uint64_t>(0x0167655250);
|
||||
|
||||
/*!
|
||||
* \brief Match regex `[\x20-\x7E]`
|
||||
@ -66,12 +66,8 @@ GPUI_SYMBOL_EXPORT PolicyFile PRegParser::parse(std::istream &stream)
|
||||
GPUI_SYMBOL_EXPORT bool PRegParser::write(std::ostream &stream, const PolicyFile &file)
|
||||
{
|
||||
writeHeader(stream);
|
||||
for (const auto &[key, records] : file.instructions) {
|
||||
for (const auto &[value, array] : records) {
|
||||
for (const auto &instruction : array) {
|
||||
writeInstruction(stream, instruction, key, value);
|
||||
}
|
||||
}
|
||||
for (const auto &instruction : file.instructions) {
|
||||
writeInstruction(stream, instruction, instruction.key, instruction.value);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -249,11 +245,11 @@ void PRegParser::insertInstruction(std::istream &stream, PolicyTree &tree)
|
||||
|
||||
check_sym(stream, '[');
|
||||
|
||||
std::string keyPath = getKeypath(stream);
|
||||
instruction.key = getKeypath(stream);
|
||||
|
||||
check_sym(stream, ';');
|
||||
|
||||
std::string value = getValue(stream);
|
||||
instruction.value = getValue(stream);
|
||||
|
||||
try {
|
||||
check_sym(stream, ';');
|
||||
@ -270,19 +266,13 @@ void PRegParser::insertInstruction(std::istream &stream, PolicyTree &tree)
|
||||
|
||||
check_sym(stream, ']');
|
||||
|
||||
if (tree.find(keyPath) == tree.end()) {
|
||||
tree[keyPath] = {};
|
||||
}
|
||||
if (tree[keyPath].find(value) == tree[keyPath].end()) {
|
||||
tree[keyPath][value] = {};
|
||||
}
|
||||
tree[keyPath][value].emplace_back(std::move(instruction));
|
||||
tree.emplace_back(std::move(instruction));
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
throw std::runtime_error(std::string(e.what()) + "\nLINE: " + std::to_string(__LINE__)
|
||||
+ ", FILE: " + __FILE__
|
||||
+ ", Error was encountered wile parsing instruction with key: "
|
||||
+ keyPath + ", value: " + value);
|
||||
+ instruction.key + ", value: " + instruction.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,20 +70,20 @@ typedef struct PolicyInstruction
|
||||
{
|
||||
inline bool operator==(const PolicyInstruction &other) const
|
||||
{
|
||||
return type == other.type && data == other.data;
|
||||
return key == other.key && value == other.value && type == other.type && data == other.data;
|
||||
}
|
||||
inline bool operator!=(const PolicyInstruction &other) const
|
||||
{
|
||||
return type != other.type && data != other.data;
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
PolicyRegType type{};
|
||||
PolicyData data{};
|
||||
std::string key{};
|
||||
std::string value{};
|
||||
} PolicyInstruction;
|
||||
|
||||
typedef std::unordered_map<std::string,
|
||||
std::unordered_map<std::string, std::vector<PolicyInstruction>>>
|
||||
PolicyTree;
|
||||
typedef std::vector<PolicyInstruction> PolicyTree;
|
||||
|
||||
typedef struct PolicyFile
|
||||
{
|
||||
|
@ -43,15 +43,8 @@ public:
|
||||
{
|
||||
pol::PolicyInstruction instruction;
|
||||
|
||||
auto key = entry->key.toStdString();
|
||||
auto value = entry->value.toStdString();
|
||||
|
||||
if (tree.find(key) == tree.end()) {
|
||||
tree[key] = {};
|
||||
}
|
||||
if (tree[key].find(value) == tree[key].end()) {
|
||||
tree[key][value] = {};
|
||||
}
|
||||
instruction.key = entry->key.toStdString();
|
||||
instruction.value = entry->value.toStdString();
|
||||
|
||||
switch (entry->type) {
|
||||
case model::registry::RegistryEntryType::REG_SZ: {
|
||||
@ -117,7 +110,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
tree[key][value].emplace_back(instruction);
|
||||
tree.emplace_back(instruction);
|
||||
}
|
||||
|
||||
static std::unique_ptr<model::registry::AbstractRegistryEntry>
|
||||
@ -240,14 +233,10 @@ bool PolFormat::read(std::istream &input, io::RegistryFile *file)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &[key, record] : result.instructions) {
|
||||
for (const auto &[value, array] : record) {
|
||||
for(const auto &entry : array) {
|
||||
auto registryEntry = RegistryEntryAdapter::create(entry, key, value);
|
||||
if (registryEntry.get()) {
|
||||
registry->registryEntries.push_back(std::move(registryEntry));
|
||||
}
|
||||
}
|
||||
for(const auto &entry : result.instructions) {
|
||||
auto registryEntry = RegistryEntryAdapter::create(entry, entry.key, entry.value);
|
||||
if (registryEntry) {
|
||||
registry->registryEntries.push_back(std::move(registryEntry));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,9 @@ pol::PolicyFile generateCase(size_t seed = -1)
|
||||
pol::PolicyInstruction instruction;
|
||||
instruction.type = generateRandomType(gen);
|
||||
instruction.data = generateRandomData(instruction.type, gen);
|
||||
data.instructions[generateRandomKeypath(gen)][generateRandomValue(gen)] = { instruction };
|
||||
instruction.key = generateRandomKeypath(gen);
|
||||
instruction.value = generateRandomValue(gen);
|
||||
data.instructions.emplace_back(instruction);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -53,8 +53,8 @@ void PolTest::endianness()
|
||||
void PolTest::bufferToIntegralLe()
|
||||
{
|
||||
std::stringstream buffer;
|
||||
char tmp[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
const uint32_t &num = *reinterpret_cast<uint32_t *>(&tmp[0]);
|
||||
char tmp[4] = { 0x78, 0x56, 0x34, 0x12 };
|
||||
const uint32_t num = (pol::getEndianess() == pol::Endian::LittleEndian) ? 0x12345678 : 0x78563412;
|
||||
|
||||
buffer.write(tmp, 4);
|
||||
buffer.seekg(0);
|
||||
@ -68,15 +68,14 @@ void PolTest::bufferToIntegralBe()
|
||||
{
|
||||
std::stringstream buffer;
|
||||
char tmp[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
const uint32_t &num = *reinterpret_cast<uint32_t *>(&tmp[0]);
|
||||
const uint32_t num = (pol::getEndianess() == pol::Endian::LittleEndian) ? 0x12345678 : 0x78563412;
|
||||
uint32_t result;
|
||||
|
||||
buffer.write(reinterpret_cast<const char *>(&num), 4);
|
||||
buffer.write(tmp, 4);
|
||||
buffer.seekg(0);
|
||||
|
||||
result = pol::readIntegralFromBuffer<uint32_t, false>(buffer);
|
||||
|
||||
std::reverse(tmp, tmp + 4);
|
||||
QCOMPARE(result, num);
|
||||
}
|
||||
|
||||
@ -133,6 +132,21 @@ void PolTest::autogenerateCases(size_t seed)
|
||||
auto test = parser->parse(file);
|
||||
QCOMPARE(policyFile, test);
|
||||
}
|
||||
|
||||
void PolTest::testPRegHeader()
|
||||
{
|
||||
std::stringstream stream;
|
||||
pol::PolicyFile file;
|
||||
auto parser = pol::createPregParser();
|
||||
|
||||
parser->write(stream, file);
|
||||
|
||||
std::vector<uint8_t> result(8), expected = { 0x50, 0x52, 0x65, 0x67, 0x01, 0x00, 0x00, 0x00};
|
||||
|
||||
stream.read(reinterpret_cast<char*>(result.data()), 8);
|
||||
QCOMPARE(result, expected);
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
|
||||
QTEST_MAIN(tests::PolTest)
|
||||
|
@ -39,6 +39,8 @@ private slots:
|
||||
|
||||
void testCase(QString filename);
|
||||
void autogenerateCases(size_t seed);
|
||||
|
||||
void testPRegHeader();
|
||||
};
|
||||
} // namespace tests
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user