CPackWIX: Implement CPACK_WIX_ACL (Access Control List) property

This commit is contained in:
Nils Gladitz 2014-08-09 14:50:49 +02:00
parent a99b42a410
commit 12418f5c26
9 changed files with 240 additions and 4 deletions

View File

@ -312,6 +312,7 @@ Properties on Installed Files
/prop_inst/CPACK_NEVER_OVERWRITE.rst /prop_inst/CPACK_NEVER_OVERWRITE.rst
/prop_inst/CPACK_PERMANENT.rst /prop_inst/CPACK_PERMANENT.rst
/prop_inst/CPACK_WIX_ACL.rst
Deprecated Properties on Directories Deprecated Properties on Directories

View File

@ -0,0 +1,17 @@
CPACK_WIX_ACL
-------------
Specifies access permissions for files installed by a WiX installer.
The property can contain multiple list entries,
each of which has to match the following format.
::
<user>[@<domain>]=<permission>[,<permission>]
``<user>`` and ``<domain>`` specify the windows user and domain for which the
``<Permission>`` element should be generated.
``<permission>`` is any of the YesNoType attributes listed here:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/permission.html

View File

@ -604,13 +604,14 @@ endif()
if(WIN32) if(WIN32)
set(CPACK_SRCS ${CPACK_SRCS} set(CPACK_SRCS ${CPACK_SRCS}
CPack/WiX/cmCPackWIXGenerator.cxx CPack/WiX/cmCPackWIXGenerator.cxx
CPack/WiX/cmWIXSourceWriter.cxx CPack/WiX/cmWIXAccessControlList.cxx
CPack/WiX/cmWIXDirectoriesSourceWriter.cxx CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
CPack/WiX/cmWIXFeaturesSourceWriter.cxx CPack/WiX/cmWIXFeaturesSourceWriter.cxx
CPack/WiX/cmWIXFilesSourceWriter.cxx CPack/WiX/cmWIXFilesSourceWriter.cxx
CPack/WiX/cmWIXRichTextFormatWriter.cxx
CPack/WiX/cmWIXPatch.cxx CPack/WiX/cmWIXPatch.cxx
CPack/WiX/cmWIXPatchParser.cxx CPack/WiX/cmWIXPatchParser.cxx
CPack/WiX/cmWIXRichTextFormatWriter.cxx
CPack/WiX/cmWIXSourceWriter.cxx
) )
endif() endif()

View File

@ -0,0 +1,149 @@
/*============================================================================
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");
}

View File

@ -0,0 +1,46 @@
/*============================================================================
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.
============================================================================*/
#ifndef cmWIXAccessControlList_h
#define cmWIXAccessControlList_h
#include <cmInstalledFile.h>
#include <CPack/cmCPackLog.h>
#include "cmWIXSourceWriter.h"
class cmWIXAccessControlList
{
public:
cmWIXAccessControlList(
cmCPackLog *logger,
cmInstalledFile const& installedFile,
cmWIXSourceWriter &sourceWriter);
bool Apply();
private:
void CreatePermissionElement(std::string const& entry);
void ReportError(std::string const& entry, std::string const& message);
bool IsBooleanAttribute(std::string const& name);
void EmitBooleanAttribute(
std::string const& entry, std::string const& name);
cmCPackLog* Logger;
cmInstalledFile const& InstalledFile;
cmWIXSourceWriter &SourceWriter;
};
#endif

View File

@ -11,6 +11,7 @@
============================================================================*/ ============================================================================*/
#include "cmWIXFilesSourceWriter.h" #include "cmWIXFilesSourceWriter.h"
#include "cmWIXAccessControlList.h"
#include <cmInstalledFile.h> #include <cmInstalledFile.h>
@ -175,6 +176,12 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
AddAttribute("ReadOnly", "yes"); AddAttribute("ReadOnly", "yes");
} }
if(installedFile)
{
cmWIXAccessControlList acl(Logger, *installedFile, *this);
acl.Apply();
}
patch.ApplyFragment(fileId, *this); patch.ApplyFragment(fileId, *this);
EndElement("File"); EndElement("File");

View File

@ -45,6 +45,9 @@ public:
static std::string WindowsCodepageToUtf8(std::string const& value); static std::string WindowsCodepageToUtf8(std::string const& value);
protected:
cmCPackLog* Logger;
private: private:
enum State enum State
{ {
@ -58,8 +61,6 @@ private:
static std::string EscapeAttributeValue(std::string const& value); static std::string EscapeAttributeValue(std::string const& value);
cmCPackLog* Logger;
cmsys::ofstream File; cmsys::ofstream File;
State State; State State;

View File

@ -111,3 +111,14 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
bool isSet = this->GetProperty(prop, value); bool isSet = this->GetProperty(prop, value);
return isSet && cmSystemTools::IsOn(value.c_str()); return isSet && cmSystemTools::IsOn(value.c_str());
} }
//----------------------------------------------------------------------------
void cmInstalledFile::GetPropertyAsList(const std::string& prop,
std::vector<std::string>& list) const
{
std::string value;
this->GetProperty(prop, value);
list.clear();
cmSystemTools::ExpandListArgument(value, list);
}

View File

@ -66,6 +66,9 @@ public:
bool GetPropertyAsBool(const std::string& prop) const; bool GetPropertyAsBool(const std::string& prop) const;
void GetPropertyAsList(const std::string& prop,
std::vector<std::string>& list) const;
void SetName(cmMakefile* mf, const std::string& name); void SetName(cmMakefile* mf, const std::string& name);
std::string const& GetName() const; std::string const& GetName() const;