Browse Source

Merge topic 'wix-acl'

975dc871 Help: Add notes for topic 'wix-acl'
12418f5c CPackWIX: Implement CPACK_WIX_ACL (Access Control List) property
Brad King 11 years ago
parent
commit
401d82b3db

+ 1 - 0
Help/manual/cmake-properties.7.rst

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

+ 17 - 0
Help/prop_inst/CPACK_WIX_ACL.rst

@@ -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

+ 6 - 0
Help/release/dev/wix-acl.rst

@@ -0,0 +1,6 @@
+wix-acl
+-------
+
+* The :manual:`cpack(1)` ``WiX`` generator learned to support
+  a :prop_inst:`CPACK_WIX_ACL` installed file property to
+  specify an Access Control List.

+ 3 - 2
Source/CMakeLists.txt

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

+ 149 - 0
Source/CPack/WiX/cmWIXAccessControlList.cxx

@@ -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");
+}

+ 46 - 0
Source/CPack/WiX/cmWIXAccessControlList.h

@@ -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

+ 7 - 0
Source/CPack/WiX/cmWIXFilesSourceWriter.cxx

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

+ 3 - 2
Source/CPack/WiX/cmWIXSourceWriter.h

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

+ 11 - 0
Source/cmInstalledFile.cxx

@@ -111,3 +111,14 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
   bool isSet = this->GetProperty(prop, value);
   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);
+}

+ 3 - 0
Source/cmInstalledFile.h

@@ -66,6 +66,9 @@ public:
 
   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);
 
   std::string const& GetName() const;