diff options
-rw-r--r-- | configmgr/Library_configmgr.mk | 5 | ||||
-rw-r--r-- | configmgr/source/components.cxx | 23 | ||||
-rw-r--r-- | configmgr/source/winreg.cxx | 174 | ||||
-rw-r--r-- | configmgr/source/winreg.hxx | 22 | ||||
-rw-r--r-- | configmgr/source/writemodfile.cxx | 5 | ||||
-rw-r--r-- | configmgr/source/writemodfile.hxx | 4 | ||||
-rw-r--r-- | scp2/source/ooo/common_brand.scp | 4 |
7 files changed, 230 insertions, 7 deletions
diff --git a/configmgr/Library_configmgr.mk b/configmgr/Library_configmgr.mk index 791782da89da..2243350c5d49 100644 --- a/configmgr/Library_configmgr.mk +++ b/configmgr/Library_configmgr.mk @@ -36,6 +36,7 @@ $(eval $(call gb_Library_add_exception_objects,configmgr, \ configmgr/source/type \ configmgr/source/update \ configmgr/source/valueparser \ + $(if $(filter $(OS),WNT), configmgr/source/winreg ) \ configmgr/source/writemodfile \ configmgr/source/xcdparser \ configmgr/source/xcsparser \ @@ -54,8 +55,8 @@ $(eval $(call gb_Library_use_libraries,configmgr, \ sal \ salhelper \ xmlreader \ - i18nlangtag \ - $(gb_UWINAPI) \ + i18nlangtag \ + $(gb_UWINAPI) \ )) $(eval $(call gb_Library_set_componentfile,configmgr,configmgr/source/configmgr)) diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx index 4a1b71984ab7..b5b38b5b9371 100644 --- a/configmgr/source/components.cxx +++ b/configmgr/source/components.cxx @@ -66,6 +66,9 @@ #include "xcdparser.hxx" #include "xcuparser.hxx" #include "xcsparser.hxx" +#ifdef WNT +#include "winreg.hxx" +#endif namespace configmgr { @@ -541,7 +544,25 @@ Components::Components( } modificationFileUrl_ = url; parseModificationLayer(url); - } else { + } +#ifdef WNT + else if ( type == "winreg" ) + { + if (!url.isEmpty()) { + SAL_WARN( + "configmgr", + "winreg URL is not empty, URL handling is not implemented for winreg"); + } + OUString aTempFileURL; + if ( dumpWindowsRegistry(&aTempFileURL) ) + { + parseFileLeniently(&parseXcuFile, aTempFileURL, layer, data_, 0, 0, 0); + layer++; + osl::File::remove(aTempFileURL); + } + } +#endif + else { throw css::uno::RuntimeException( "CONFIGURATION_LAYERS: unknown layer type \"" + type + "\"", css::uno::Reference< css::uno::XInterface >()); diff --git a/configmgr/source/winreg.cxx b/configmgr/source/winreg.cxx new file mode 100644 index 000000000000..b68b9d2e9464 --- /dev/null +++ b/configmgr/source/winreg.cxx @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <cwchar> +#ifdef _MSC_VER +#pragma warning(push, 1) /* disable warnings within system headers */ +#endif +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <msiquery.h> +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/XInterface.hpp" +#include "rtl/ustring.hxx" +#include "osl/file.h" +#include "osl/file.hxx" +#include "winreg.hxx" +#include "writemodfile.hxx" + +#define MAX_KEY_LENGTH 255 + +namespace configmgr { + +namespace { +// This is not a generic registry reader. We assume the following structure: +// Last element of Key becomes prop, first part is the path. +// Values can be the following: Value (string) and Final (dword, optional) +// For example the following registry setting: +// [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\LibreOffice\org.openoffice.UserProfile\Data\o] +// "Value"="Example Corp." +// "Final"=dword:00000001 +// becomes the following in configuration: +// <item oor:path="/org.openoffice.UserProfile/Data"> +// <prop oor:name="o" oor:finalized="true"> +// <value>Example Corp.</value> +// </prop> +// </item> +void dumpWindowsRegistryKey(HKEY hKey, OUString aKeyName, oslFileHandle aFileHandle) +{ + HKEY hCurKey; + + if(RegOpenKeyExW(hKey, aKeyName.getStr(), 0, KEY_READ, &hCurKey) == ERROR_SUCCESS) + { + DWORD nSubKeys = 0; + DWORD nValues = 0; + DWORD nLongestValueNameLen, nLongestValueLen; + // Query the number of subkeys + RegQueryInfoKeyW(hCurKey, NULL, NULL, NULL, &nSubKeys, NULL, NULL, &nValues, &nLongestValueNameLen, &nLongestValueLen, NULL, NULL); + if(nSubKeys) + { + //Look for subkeys in this key + for(DWORD i = 0; i < nSubKeys; i++) + { + wchar_t buffKeyName[MAX_KEY_LENGTH]; + buffKeyName[0] = '\0'; + DWORD buffSize=MAX_KEY_LENGTH; + OUString aSubkeyName; + //Get subkey name + RegEnumKeyExW(hCurKey, i, buffKeyName, &buffSize, NULL, NULL, NULL, NULL); + + //Make up full key name + if(aKeyName.isEmpty()) + aSubkeyName = aKeyName + OUString(buffKeyName); + else + aSubkeyName = aKeyName + "\\" + OUString(buffKeyName); + + //Recursion, until no more subkeys are found + dumpWindowsRegistryKey(hKey, aSubkeyName, aFileHandle); + } + } + else if(nValues) + { + // No more subkeys, we are at a leaf + wchar_t* pValueName = new wchar_t[nLongestValueNameLen + 1]; + wchar_t* pValue = new wchar_t[nLongestValueLen + 1]; + + if(pValueName && pValue) + { + bool bFinal = false; + OUString aValue; + + for(DWORD i = 0; i < nValues; ++i) + { + DWORD nValueNameLen = nLongestValueNameLen + 1; + DWORD nValueLen = nLongestValueLen + 1; + + RegEnumValueW(hCurKey, i, pValueName, &nValueNameLen, NULL, NULL, (LPBYTE)pValue, &nValueLen); + const wchar_t wsValue[] = L"Value"; + const wchar_t wsFinal[] = L"Final"; + + if(!wcscmp(pValueName, wsValue)) + aValue = OUString(pValue); + if(!wcscmp(pValueName, wsFinal) && *(DWORD*)pValue == 1) + bFinal = true; + } + sal_Int32 aLastSeparator = aKeyName.lastIndexOf('\\'); + OUString aPath = aKeyName.replaceAll("\\","/").copy(0, aLastSeparator); + OUString aProp = aKeyName.copy(aLastSeparator + 1); + + writeData(aFileHandle, "<item oor:path=\"/"); + writeAttributeValue(aFileHandle, aPath); + writeData(aFileHandle, "\"><prop oor:name=\""); + writeAttributeValue(aFileHandle, aProp); + writeData(aFileHandle, "\""); + if(bFinal) + writeData(aFileHandle, " oor:finalized=\"true\""); + writeData(aFileHandle, "><value>"); + writeValueContent(aFileHandle, aValue); + writeData(aFileHandle, "</value></prop></item>\n"); + delete[] pValueName; + delete[] pValue; + } + } + RegCloseKey(hCurKey); + } +} +} + +bool dumpWindowsRegistry(OUString* pFileURL) +{ + HKEY hKey; + if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\LibreOffice", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + { + SAL_INFO( + "configmgr", + ("Windows registry settings do not exist in HKLM\\SOFTWARE\\Policies\\LibreOffice")); + return false; + } + + oslFileHandle aFileHandle; + switch (osl::FileBase::createTempFile(0, &aFileHandle, pFileURL)) { + case osl::FileBase::E_None: + break; + case osl::FileBase::E_ACCES: + SAL_INFO( + "configmgr", + ("cannot create temp Windows registry dump (E_ACCES)")); + return false; + default: + throw css::uno::RuntimeException( + "cannot create temporary file", + css::uno::Reference< css::uno::XInterface >()); + } + writeData( + aFileHandle, + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<oor:items" + " xmlns:oor=\"http://openoffice.org/2001/registry\"" + " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"); + dumpWindowsRegistryKey(hKey, "", aFileHandle); + writeData(aFileHandle, "</oor:items>"); + oslFileError e = osl_closeFile(aFileHandle); + if (e != osl_File_E_None) + SAL_WARN("configmgr", "osl_closeFile failed with " << +e); + RegCloseKey(hKey); + return true; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/configmgr/source/winreg.hxx b/configmgr/source/winreg.hxx new file mode 100644 index 000000000000..020977262beb --- /dev/null +++ b/configmgr/source/winreg.hxx @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#ifndef INCLUDED_CONFIGMGR_SOURCE_WINREG_HXX +#define INCLUDED_CONFIGMGR_SOURCE_WINREG_HXX + +namespace configmgr { + +bool dumpWindowsRegistry(OUString* pFileURL); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/configmgr/source/writemodfile.cxx b/configmgr/source/writemodfile.cxx index f099acfc7fd9..82d62404cfd2 100644 --- a/configmgr/source/writemodfile.cxx +++ b/configmgr/source/writemodfile.cxx @@ -21,7 +21,6 @@ #include <cassert> -#include "boost/noncopyable.hpp" #include "com/sun/star/uno/Any.hxx" #include "com/sun/star/uno/Reference.hxx" #include "com/sun/star/uno/RuntimeException.hpp" @@ -102,6 +101,8 @@ TempFile::~TempFile() { } } +} + void writeData(oslFileHandle handle, char const * begin, sal_Int32 length) { assert(length >= 0); sal_uInt64 n; @@ -512,8 +513,6 @@ void writeModifications( } } -} - void writeModFile( Components & components, OUString const & url, Data const & data) { diff --git a/configmgr/source/writemodfile.hxx b/configmgr/source/writemodfile.hxx index e8c81b21d47c..727ab9f31250 100644 --- a/configmgr/source/writemodfile.hxx +++ b/configmgr/source/writemodfile.hxx @@ -22,12 +22,14 @@ #include "sal/config.h" - namespace configmgr { class Components; struct Data; +void writeData(oslFileHandle handle, OString const & text); +void writeAttributeValue(oslFileHandle handle, OUString const & value); +void writeValueContent(oslFileHandle handle, OUString const & value); void writeModFile( Components & components, OUString const & url, Data const & data); diff --git a/scp2/source/ooo/common_brand.scp b/scp2/source/ooo/common_brand.scp index 9692776c159c..cf59e9dd5d73 100644 --- a/scp2/source/ooo/common_brand.scp +++ b/scp2/source/ooo/common_brand.scp @@ -1280,7 +1280,11 @@ ProfileItem gid_Brand_Profileitem_Fundamental_Configuration_Layers ModuleID = gid_Module_Root_Brand; Section = "Bootstrap"; Key = "CONFIGURATION_LAYERS"; +#if defined WNT + Value = "xcsxcu:${BRAND_BASE_DIR}/" LIBO_SHARE_FOLDER "/registry winreg: res:${BRAND_BASE_DIR}/" LIBO_SHARE_FOLDER "/registry bundledext:${${BRAND_BASE_DIR}/" LIBO_ETC_FOLDER "/" PROFILENAME(uno) ":BUNDLED_EXTENSIONS_USER}/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/configmgr.ini sharedext:${${BRAND_BASE_DIR}/" LIBO_ETC_FOLDER "/" PROFILENAME(uno) ":SHARED_EXTENSIONS_USER}/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/configmgr.ini userext:${${BRAND_BASE_DIR}/" LIBO_ETC_FOLDER "/" PROFILENAME(uno) ":UNO_USER_PACKAGES_CACHE}/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/configmgr.ini user:${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" PROFILENAME(bootstrap) ":UserInstallation}/user/registrymodifications.xcu"; +#else Value = "xcsxcu:${BRAND_BASE_DIR}/" LIBO_SHARE_FOLDER "/registry res:${BRAND_BASE_DIR}/" LIBO_SHARE_FOLDER "/registry bundledext:${${BRAND_BASE_DIR}/" LIBO_ETC_FOLDER "/" PROFILENAME(uno) ":BUNDLED_EXTENSIONS_USER}/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/configmgr.ini sharedext:${${BRAND_BASE_DIR}/" LIBO_ETC_FOLDER "/" PROFILENAME(uno) ":SHARED_EXTENSIONS_USER}/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/configmgr.ini userext:${${BRAND_BASE_DIR}/" LIBO_ETC_FOLDER "/" PROFILENAME(uno) ":UNO_USER_PACKAGES_CACHE}/registry/com.sun.star.comp.deployment.configuration.PackageRegistryBackend/configmgr.ini user:${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" PROFILENAME(bootstrap) ":UserInstallation}/user/registrymodifications.xcu"; +#endif End #if !defined MACOSX |