150 lines
3.5 KiB
C++
150 lines
3.5 KiB
C++
|
/*============================================================================
|
||
|
CMake - Cross Platform Makefile Generator
|
||
|
Copyright 2014 Kitware, Inc.
|
||
|
|
||
|
Distributed under the OSI-approved BSD License (the "License");
|
||
|
see accompanying file Copyright.txt for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
See the License for more information.
|
||
|
============================================================================*/
|
||
|
|
||
|
#include "cmWIXAccessControlList.h"
|
||
|
|
||
|
#include <CPack/cmCPackGenerator.h>
|
||
|
|
||
|
#include <cmSystemTools.h>
|
||
|
|
||
|
cmWIXAccessControlList::cmWIXAccessControlList(
|
||
|
cmCPackLog *logger,
|
||
|
cmInstalledFile const& installedFile,
|
||
|
cmWIXSourceWriter &sourceWriter):
|
||
|
Logger(logger),
|
||
|
InstalledFile(installedFile),
|
||
|
SourceWriter(sourceWriter)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
bool cmWIXAccessControlList::Apply()
|
||
|
{
|
||
|
std::vector<std::string> entries;
|
||
|
this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
|
||
|
|
||
|
for(size_t i = 0; i < entries.size(); ++i)
|
||
|
{
|
||
|
this->CreatePermissionElement(entries[i]);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void cmWIXAccessControlList::CreatePermissionElement(
|
||
|
std::string const& entry)
|
||
|
{
|
||
|
std::string::size_type pos = entry.find('=');
|
||
|
if(pos == std::string::npos)
|
||
|
{
|
||
|
this->ReportError(entry, "Did not find mandatory '='");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
std::string user_and_domain = entry.substr(0, pos);
|
||
|
std::string permission_string = entry.substr(pos + 1);
|
||
|
|
||
|
pos = user_and_domain.find('@');
|
||
|
std::string user;
|
||
|
std::string domain;
|
||
|
if(pos != std::string::npos)
|
||
|
{
|
||
|
user = user_and_domain.substr(0, pos);
|
||
|
domain = user_and_domain.substr(pos + 1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
user = user_and_domain;
|
||
|
}
|
||
|
|
||
|
std::vector<std::string> permissions =
|
||
|
cmSystemTools::tokenize(permission_string, ",");
|
||
|
|
||
|
this->SourceWriter.BeginElement("Permission");
|
||
|
this->SourceWriter.AddAttribute("User", user);
|
||
|
if(domain.size())
|
||
|
{
|
||
|
this->SourceWriter.AddAttribute("Domain", domain);
|
||
|
}
|
||
|
for(size_t i = 0; i < permissions.size(); ++i)
|
||
|
{
|
||
|
this->EmitBooleanAttribute(entry,
|
||
|
cmSystemTools::TrimWhitespace(permissions[i]));
|
||
|
}
|
||
|
this->SourceWriter.EndElement("Permission");
|
||
|
}
|
||
|
|
||
|
void cmWIXAccessControlList::ReportError(
|
||
|
std::string const& entry,
|
||
|
std::string const& message)
|
||
|
{
|
||
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||
|
"Failed processing ACL entry '" << entry <<
|
||
|
"': " << message << std::endl);
|
||
|
}
|
||
|
|
||
|
bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name)
|
||
|
{
|
||
|
static const char* validAttributes[] =
|
||
|
{
|
||
|
"Append",
|
||
|
"ChangePermission",
|
||
|
"CreateChild",
|
||
|
"CreateFile",
|
||
|
"CreateLink",
|
||
|
"CreateSubkeys",
|
||
|
"Delete",
|
||
|
"DeleteChild",
|
||
|
"EnumerateSubkeys",
|
||
|
"Execute",
|
||
|
"FileAllRights",
|
||
|
"GenericAll",
|
||
|
"GenericExecute",
|
||
|
"GenericRead",
|
||
|
"GenericWrite",
|
||
|
"Notify",
|
||
|
"Read",
|
||
|
"ReadAttributes",
|
||
|
"ReadExtendedAttributes",
|
||
|
"ReadPermission",
|
||
|
"SpecificRightsAll",
|
||
|
"Synchronize",
|
||
|
"TakeOwnership",
|
||
|
"Traverse",
|
||
|
"Write",
|
||
|
"WriteAttributes",
|
||
|
"WriteExtendedAttributes",
|
||
|
0
|
||
|
};
|
||
|
|
||
|
size_t i = 0;
|
||
|
while(validAttributes[i])
|
||
|
{
|
||
|
if(name == validAttributes[i++]) return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void cmWIXAccessControlList::EmitBooleanAttribute(
|
||
|
std::string const& entry, std::string const& name)
|
||
|
{
|
||
|
if(!this->IsBooleanAttribute(name))
|
||
|
{
|
||
|
std::stringstream message;
|
||
|
message << "Unknown boolean attribute '" << name << "'";
|
||
|
this->ReportError(entry, message.str());
|
||
|
}
|
||
|
|
||
|
this->SourceWriter.AddAttribute(name, "yes");
|
||
|
}
|