11#include <rtl/ustring.hxx>
12#include <rtl/bootstrap.hxx>
14#include <osl/file.hxx>
27#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
28#include <com/sun/star/ucb/CommandAbortedException.hpp>
29#include <com/sun/star/ucb/CommandFailedException.hpp>
30#include <com/sun/star/uno/Sequence.hxx>
31#include <com/sun/star/uno/Reference.hxx>
32#include <com/sun/star/deployment/DeploymentException.hpp>
33#include <com/sun/star/deployment/ExtensionManager.hpp>
34#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
35#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
36#include <com/sun/star/xml/dom/XElement.hpp>
37#include <com/sun/star/xml/dom/XNodeList.hpp>
38#include <com/sun/star/xml/dom/XText.hpp>
39#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
40#include <com/sun/star/xml/sax/Writer.hpp>
41#include <com/sun/star/xml/sax/XWriter.hpp>
42#include <com/sun/star/io/XStream.hpp>
43#include <com/sun/star/io/TempFile.hpp>
44#include <com/sun/star/io/XOutputStream.hpp>
45#include <com/sun/star/beans/XPropertySet.hpp>
50using namespace css::xml::dom;
58 sal_uInt32 createCrc32(
FileSharedPtr const & rCandidate, sal_uInt32 nOffset)
62 if (rCandidate && osl::File::E_None == rCandidate->open(osl_File_OpenFlag_Read))
65 sal_uInt64 nBytesTransfer(0);
68 rCandidate->getSize(nSize);
73 if (osl::File::E_None == rCandidate->setPos(osl_Pos_Absolut, sal_Int64(nOffset)))
79 if (osl::File::E_None == rCandidate->read(
static_cast<void*
>(aArray), nToTransfer, nBytesTransfer) && nBytesTransfer == nToTransfer)
82 nCrc32 = rtl_crc32(nCrc32,
static_cast<void*
>(aArray),
static_cast<sal_uInt32
>(nBytesTransfer));
102 sal_uInt64 nBaseRead(0);
105 if (osl::File::E_None == rFile->read(
static_cast<void*
>(aArray), 4, nBaseRead) && 4 == nBaseRead)
107 rTarget = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
114 bool write_sal_uInt32(oslFileHandle& rHandle, sal_uInt32 nSource)
117 sal_uInt64 nBaseWritten(0);
120 aArray[0] =
sal_uInt8((nSource & 0xff000000) >> 24);
121 aArray[1] =
sal_uInt8((nSource & 0x00ff0000) >> 16);
122 aArray[2] =
sal_uInt8((nSource & 0x0000ff00) >> 8);
123 aArray[3] =
sal_uInt8(nSource & 0x000000ff);
125 return osl_File_E_None == osl_writeFile(rHandle,
static_cast<const void*
>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten;
132 if (!read_sal_uInt32(rFile,
nLength))
138 if (osl::File::E_None != rFile->getPos(
nPos))
142 if (osl::File::E_None != rFile->getSize(nSize))
145 const auto nRemainingSize = nSize -
nPos;
149 std::vector<char> aTarget(
nLength);
150 sal_uInt64 nBaseRead(0);
153 if (osl::File::E_None == rFile->read(
static_cast<void*
>(aTarget.data()),
nLength, nBaseRead) &&
nLength == nBaseRead)
155 rTarget = OString(aTarget.data(),
static_cast<sal_Int32
>(nBaseRead));
162 bool write_OString(oslFileHandle& rHandle,
const OString& rSource)
164 const sal_uInt32
nLength(rSource.getLength());
166 if (!write_sal_uInt32(rHandle,
nLength))
171 sal_uInt64 nBaseWritten(0);
173 return osl_File_E_None == osl_writeFile(rHandle,
static_cast<const void*
>(rSource.getStr()),
nLength, &nBaseWritten) &&
nLength == nBaseWritten;
176 OUString createFileURL(
177 std::u16string_view rURL, std::u16string_view rName, std::u16string_view rExt)
181 if (!rURL.empty() && !rName.empty())
183 aRetval = OUString::Concat(rURL) +
"/" + rName;
187 aRetval += OUString::Concat(
".") + rExt;
194 OUString createPackURL(std::u16string_view rURL, std::u16string_view rName)
198 if (!rURL.empty() && !rName.empty())
200 aRetval = OUString::Concat(rURL) +
"/" + rName +
".pack";
209 enum PackageRepository {
USER,
SHARED, BUNDLED };
211 class ExtensionInfoEntry
215 PackageRepository maRepository;
220 : maRepository(
USER),
225 ExtensionInfoEntry(OString aName,
bool bEnabled)
232 ExtensionInfoEntry(
const uno::Reference< deployment::XPackage >& rxPackage)
238 const OString aRepName(
OUStringToOString(rxPackage->getRepositoryName(), RTL_TEXTENCODING_ASCII_US));
240 if (aRepName ==
"shared")
244 else if (aRepName ==
"bundled")
246 maRepository = BUNDLED;
250 const beans::Optional< beans::Ambiguous< sal_Bool > >
option(
251 rxPackage->isRegistered(uno::Reference< task::XAbortChannel >(),
252 uno::Reference< ucb::XCommandEnvironment >()));
256 ::beans::Ambiguous< sal_Bool >
const& reg =
option.Value;
258 if (!reg.IsAmbiguous)
260 mbEnabled = reg.Value;
265 bool isSameExtension(
const ExtensionInfoEntry& rComp)
const
267 return (maRepository == rComp.maRepository && maName == rComp.maName);
270 bool operator<(
const ExtensionInfoEntry& rComp)
const
272 if (maRepository == rComp.maRepository)
274 if (maName == rComp.maName)
276 return mbEnabled < rComp.mbEnabled;
280 return 0 >
maName.compareTo(rComp.maName);
285 return maRepository < rComp.maRepository;
292 if (!read_OString(rFile, maName))
300 if (read_sal_uInt32(rFile, nState))
302 maRepository =
static_cast< PackageRepository
>(
nState);
310 if (read_sal_uInt32(rFile, nState))
312 mbEnabled =
static_cast< bool >(
nState);
322 bool write_entry(oslFileHandle& rHandle)
const
325 if (!write_OString(rHandle, maName))
331 sal_uInt32
nState(maRepository);
333 if (!write_sal_uInt32(rHandle, nState))
339 nState =
static_cast< sal_uInt32
>(mbEnabled);
341 return write_sal_uInt32(rHandle, nState);
344 const OString& getName()
const
349 bool isEnabled()
const
355 typedef std::vector< ExtensionInfoEntry > ExtensionInfoEntryVector;
357 constexpr OUStringLiteral gaRegPath {
u"/registry/com.sun.star.comp.deployment.bundle.PackageRegistryBackend/backenddb.xml" };
362 ExtensionInfoEntryVector maEntries;
369 const ExtensionInfoEntryVector& getExtensionInfoEntryVector()
const
380 void createUsingXExtensionManager()
386 uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
388 uno::Reference< deployment::XExtensionManager > m_xExtensionManager = deployment::ExtensionManager::get(xContext);
392 xAllPackages = m_xExtensionManager->getAllExtensions(uno::Reference< task::XAbortChannel >(),
393 uno::Reference< ucb::XCommandEnvironment >());
395 catch (
const deployment::DeploymentException &)
399 catch (
const ucb::CommandFailedException &)
403 catch (
const ucb::CommandAbortedException &)
407 catch (
const lang::IllegalArgumentException & e)
410 throw css::lang::WrappedTargetRuntimeException( e.Message,
414 for (
const uno::Sequence< uno::Reference< deployment::XPackage > > & xPackageList : std::as_const(xAllPackages))
416 for (
const uno::Reference< deployment::XPackage > & xPackage : xPackageList)
420 maEntries.emplace_back(xPackage);
425 if (!maEntries.empty())
428 std::sort(maEntries.begin(), maEntries.end());
433 void visitNodesXMLRead(
const uno::Reference< xml::dom::XElement >& rElement)
438 const OUString aTagName(rElement->getTagName());
440 if (aTagName ==
"extension")
442 OUString aAttrUrl(rElement->getAttribute(
"url"));
443 const OUString aAttrRevoked(rElement->getAttribute(
"revoked"));
445 if (!aAttrUrl.isEmpty())
447 const sal_Int32
nIndex(aAttrUrl.lastIndexOf(
'/'));
449 if (nIndex > 0 && aAttrUrl.getLength() > nIndex + 1)
451 aAttrUrl = aAttrUrl.copy(nIndex + 1);
454 const bool bEnabled(aAttrRevoked.isEmpty() || !aAttrRevoked.toBoolean());
455 maEntries.emplace_back(
462 uno::Reference< xml::dom::XNodeList > aList = rElement->getChildNodes();
466 const sal_Int32
nLength(aList->getLength());
470 const uno::Reference< xml::dom::XElement > aChild(aList->item(a), uno::UNO_QUERY);
474 visitNodesXMLRead(aChild);
482 void createUserExtensionRegistryEntriesFromXML(std::u16string_view rUserConfigWorkURL)
484 const OUString aPath(
485 OUString::Concat(rUserConfigWorkURL) +
"/uno_packages/cache" + gaRegPath);
486 createExtensionRegistryEntriesFromXML(aPath);
489 void createSharedExtensionRegistryEntriesFromXML(std::u16string_view rUserConfigWorkURL)
491 const OUString aPath(
492 OUString::Concat(rUserConfigWorkURL) +
"/extensions/shared" + gaRegPath);
493 createExtensionRegistryEntriesFromXML(aPath);
496 void createBundledExtensionRegistryEntriesFromXML(std::u16string_view rUserConfigWorkURL)
498 const OUString aPath(
499 OUString::Concat(rUserConfigWorkURL) +
"/extensions/bundled" + gaRegPath);
500 createExtensionRegistryEntriesFromXML(aPath);
504 void createExtensionRegistryEntriesFromXML(
const OUString& aPath)
506 if (DirectoryHelper::fileExists(aPath))
509 uno::Reference< xml::dom::XDocumentBuilder > xBuilder(xml::dom::DocumentBuilder::create(xContext));
510 uno::Reference< xml::dom::XDocument >
aDocument = xBuilder->parseURI(aPath);
514 visitNodesXMLRead(
aDocument->getDocumentElement());
518 if (!maEntries.empty())
521 std::sort(maEntries.begin(), maEntries.end());
526 static bool visitNodesXMLChange(
527 const OUString& rTagToSearch,
528 const uno::Reference< xml::dom::XElement >& rElement,
529 const ExtensionInfoEntryVector& rToBeEnabled,
530 const ExtensionInfoEntryVector& rToBeDisabled)
532 bool bChanged(
false);
536 const OUString aTagName(rElement->getTagName());
538 if (aTagName == rTagToSearch)
540 const OString aAttrUrl(
OUStringToOString(rElement->getAttribute(
"url"), RTL_TEXTENCODING_ASCII_US));
541 const OUString aAttrRevoked(rElement->getAttribute(
"revoked"));
542 const bool bEnabled(aAttrRevoked.isEmpty() || !aAttrRevoked.toBoolean());
544 if (!aAttrUrl.isEmpty())
546 for (
const auto& enable : rToBeEnabled)
548 if (-1 != aAttrUrl.indexOf(enable.getName()))
553 rElement->removeAttribute(
"revoked");
559 for (
const auto& disable : rToBeDisabled)
561 if (-1 != aAttrUrl.indexOf(disable.getName()))
566 rElement->setAttribute(
"revoked",
"true");
575 uno::Reference< xml::dom::XNodeList > aList = rElement->getChildNodes();
579 const sal_Int32
nLength(aList->getLength());
583 const uno::Reference< xml::dom::XElement > aChild(aList->item(a), uno::UNO_QUERY);
587 bChanged |= visitNodesXMLChange(
601 static void visitNodesXMLChangeOneCase(
602 const OUString& rUnoPackagReg,
603 const OUString& rTagToSearch,
604 const ExtensionInfoEntryVector& rToBeEnabled,
605 const ExtensionInfoEntryVector& rToBeDisabled)
607 if (!DirectoryHelper::fileExists(rUnoPackagReg))
611 uno::Reference< xml::dom::XDocumentBuilder > xBuilder = xml::dom::DocumentBuilder::create(xContext);
612 uno::Reference< xml::dom::XDocument >
aDocument = xBuilder->parseURI(rUnoPackagReg);
617 if (!visitNodesXMLChange(
625 uno::Reference< xml::sax::XSAXSerializable > xSerializer(aDocument, uno::UNO_QUERY);
627 if (!xSerializer.is())
631 uno::Reference< xml::sax::XWriter >
const xSaxWriter = xml::sax::Writer::create(xContext);
632 uno::Reference< io::XTempFile > xTempFile = io::TempFile::create(xContext);
633 uno::Reference< io::XOutputStream > xOutStrm = xTempFile->getOutputStream();
636 xSaxWriter->setOutputStream(xOutStrm);
637 xSerializer->serialize(xSaxWriter, uno::Sequence< beans::StringPair >());
640 OUString aTempURL = xTempFile->getUri();
643 if (aTempURL.isEmpty() || !DirectoryHelper::fileExists(aTempURL))
646 if (DirectoryHelper::fileExists(rUnoPackagReg))
651#if OSL_DEBUG_LEVEL > 1
652 SAL_WARN_IF(osl::FileBase::E_None != osl::File::move(aTempURL, rUnoPackagReg),
"comphelper.backupfilehelper",
"could not copy back modified Extension configuration file");
654 osl::File::move(aTempURL, rUnoPackagReg);
659 static void changeEnableDisableStateInXML(
660 std::u16string_view rUserConfigWorkURL,
661 const ExtensionInfoEntryVector& rToBeEnabled,
662 const ExtensionInfoEntryVector& rToBeDisabled)
664 static constexpr OUStringLiteral aRegPathFront(u
"/uno_packages/cache/registry/com.sun.star.comp.deployment.");
665 static constexpr OUStringLiteral aRegPathBack(u
".PackageRegistryBackend/backenddb.xml");
668 const OUString aUnoPackagReg(OUString::Concat(rUserConfigWorkURL) + aRegPathFront +
"bundle" + aRegPathBack);
670 visitNodesXMLChangeOneCase(
679 const OUString aUnoPackagReg(OUString::Concat(rUserConfigWorkURL) + aRegPathFront +
"configuration" + aRegPathBack);
681 visitNodesXMLChangeOneCase(
690 const OUString aUnoPackagReg(OUString::Concat(rUserConfigWorkURL) + aRegPathFront +
"script" + aRegPathBack);
692 visitNodesXMLChangeOneCase(
703 sal_uInt32 nExtEntries(0);
705 if (!read_sal_uInt32(rFile, nExtEntries))
712 sal_uInt64 nFileSize(0);
713 rFile->getSize(nFileSize);
714 if (nFileSize < nExtEntries)
717 for (sal_uInt32
a(0);
a < nExtEntries;
a++)
719 ExtensionInfoEntry aNewEntry;
721 if (aNewEntry.read_entry(rFile))
723 maEntries.push_back(aNewEntry);
734 bool write_entries(oslFileHandle& rHandle)
const
736 const sal_uInt32 nExtEntries(maEntries.size());
738 if (!write_sal_uInt32(rHandle, nExtEntries))
743 for (
const auto& a : maEntries)
745 if (!
a.write_entry(rHandle))
754 bool createTempFile(OUString& rTempFileName)
756 oslFileHandle aHandle;
760 if (maEntries.empty())
762 createUsingXExtensionManager();
766 if (osl::File::E_None == osl::FileBase::createTempFile(
nullptr, &aHandle, &rTempFileName))
768 bRetval = write_entries(aHandle);
771 osl_closeFile(aHandle);
777 bool areThereEnabledExtensions()
const
779 for (
const auto& a : maEntries)
794 class PackedFileEntry
797 sal_uInt32 mnFullFileSize;
798 sal_uInt32 mnPackFileSize;
802 bool const mbDoCompress;
804 bool copy_content_straight(oslFileHandle& rTargetHandle)
806 if (!maFile || osl::File::E_None != maFile->open(osl_File_OpenFlag_Read))
810 sal_uInt64 nBytesTransfer(0);
811 sal_uInt64 nSize(getPackFileSize());
814 if (osl::File::E_None == maFile->setPos(osl_Pos_Absolut, sal_Int64(getOffset())))
820 if (osl::File::E_None != maFile->read(
static_cast<void*
>(aArray), nToTransfer, nBytesTransfer) || nBytesTransfer != nToTransfer)
825 if (osl_File_E_None != osl_writeFile(rTargetHandle,
static_cast<const void*
>(aArray), nToTransfer, &nBytesTransfer) || nBytesTransfer != nToTransfer)
830 nSize -= nToTransfer;
838 bool copy_content_compress(oslFileHandle& rTargetHandle)
840 if (!maFile || osl::File::E_None != maFile->open(osl_File_OpenFlag_Read))
845 sal_uInt64 nBytesTransfer(0);
846 sal_uInt64 nSize(getPackFileSize());
848 memset(&zstream, 0,
sizeof(zstream));
850 if (Z_OK == deflateInit(&zstream, Z_BEST_COMPRESSION))
853 if (osl::File::E_None == maFile->setPos(osl_Pos_Absolut, sal_Int64(getOffset())))
857 while (bOkay && nSize != 0)
861 if (osl::File::E_None != maFile->read(
static_cast<void*
>(aArray), nToTransfer, nBytesTransfer) || nBytesTransfer != nToTransfer)
866 zstream.avail_in = nToTransfer;
867 zstream.next_in =
reinterpret_cast<unsigned char*
>(aArray);
871 zstream.next_out =
reinterpret_cast<unsigned char*
>(
aBuffer);
873 const sal_Int64 nRetval(deflate(&zstream, nSize == nToTransfer ? Z_FINISH : Z_NO_FLUSH));
875 const sal_Int64 nRetval(z_deflate(&zstream, nSize == nToTransfer ? Z_FINISH : Z_NO_FLUSH));
877 if (Z_STREAM_ERROR == nRetval)
885 if (osl_File_E_None != osl_writeFile(rTargetHandle,
static_cast<const void*
>(aBuffer), nAvailable, &nBytesTransfer) || nBytesTransfer != nAvailable)
890 }
while (bOkay && 0 == zstream.avail_out);
897 nSize -= nToTransfer;
901 deflateEnd(&zstream);
903 z_deflateEnd(&zstream);
911 if (mnFullFileSize == mnPackFileSize && mnFullFileSize == zstream.total_in)
913 mnPackFileSize = zstream.total_out;
919 bool copy_content_uncompress(oslFileHandle& rTargetHandle)
921 if (!maFile || osl::File::E_None != maFile->open(osl_File_OpenFlag_Read))
926 sal_uInt64 nBytesTransfer(0);
927 sal_uInt64 nSize(getPackFileSize());
929 memset(&zstream, 0,
sizeof(zstream));
931 if (Z_OK == inflateInit(&zstream))
934 if (osl::File::E_None == maFile->setPos(osl_Pos_Absolut, sal_Int64(getOffset())))
938 while (bOkay && nSize != 0)
942 if (osl::File::E_None != maFile->read(
static_cast<void*
>(aArray), nToTransfer, nBytesTransfer) || nBytesTransfer != nToTransfer)
947 zstream.avail_in = nToTransfer;
948 zstream.next_in =
reinterpret_cast<unsigned char*
>(aArray);
952 zstream.next_out =
reinterpret_cast<unsigned char*
>(
aBuffer);
954 const sal_Int64 nRetval(inflate(&zstream, Z_NO_FLUSH));
956 const sal_Int64 nRetval(z_inflate(&zstream, Z_NO_FLUSH));
958 if (Z_STREAM_ERROR == nRetval)
966 if (osl_File_E_None != osl_writeFile(rTargetHandle,
static_cast<const void*
>(aBuffer), nAvailable, &nBytesTransfer) || nBytesTransfer != nAvailable)
971 }
while (bOkay && 0 == zstream.avail_out);
978 nSize -= nToTransfer;
982 deflateEnd(&zstream);
984 z_deflateEnd(&zstream);
997 sal_uInt32 nFullFileSize,
1001 : mnFullFileSize(nFullFileSize),
1002 mnPackFileSize(nFullFileSize),
1005 maFile(
std::move(xFile)),
1006 mbDoCompress(bDoCompress)
1012 : mnFullFileSize(0),
1020 sal_uInt32 getFullFileSize()
const
1022 return mnFullFileSize;
1025 sal_uInt32 getPackFileSize()
const
1027 return mnPackFileSize;
1030 sal_uInt32 getOffset()
const
1035 void setOffset(sal_uInt32 nOffset)
1040 static sal_uInt32 getEntrySize()
1045 sal_uInt32 getCrc32()
const
1060 if (!read_sal_uInt32(rFile, mnFullFileSize))
1066 if (!read_sal_uInt32(rFile, mnCrc32))
1072 if (!read_sal_uInt32(rFile, mnPackFileSize))
1080 bool write_header(oslFileHandle& rHandle)
const
1083 if (!write_sal_uInt32(rHandle, mnFullFileSize))
1089 if (!write_sal_uInt32(rHandle, mnCrc32))
1095 if (!write_sal_uInt32(rHandle, mnPackFileSize))
1103 bool copy_content(oslFileHandle& rTargetHandle,
bool bUncompress)
1107 if (getFullFileSize() == getPackFileSize())
1110 return copy_content_straight(rTargetHandle);
1115 return copy_content_uncompress(rTargetHandle);
1118 else if (0 == getOffset())
1123 return copy_content_compress(rTargetHandle);
1128 return copy_content_straight(rTargetHandle);
1133 return copy_content_straight(rTargetHandle);
1144 const OUString
maURL;
1145 std::deque< PackedFileEntry >
1146 maPackedFileEntryVector;
1150 PackedFile(
const OUString& rURL)
1154 FileSharedPtr aSourceFile = std::make_shared<osl::File>(rURL);
1156 if (osl::File::E_None == aSourceFile->open(osl_File_OpenFlag_Read))
1158 sal_uInt64 nBaseLen(0);
1159 aSourceFile->getSize(nBaseLen);
1165 sal_uInt64 nBaseRead(0);
1168 if (osl::File::E_None == aSourceFile->read(
static_cast< void*
>(aArray), 4, nBaseRead) && 4 == nBaseRead)
1170 if (
'P' == aArray[0] &&
'A' == aArray[1] &&
'C' == aArray[2] &&
'K' == aArray[3])
1173 if (osl::File::E_None == aSourceFile->read(
static_cast<void*
>(aArray), 4, nBaseRead) && 4 == nBaseRead)
1175 sal_uInt32 nEntries((sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]));
1178 if (nEntries >= 1 && nEntries <= 10)
1180 for (sal_uInt32
a(0);
a < nEntries;
a++)
1184 PackedFileEntry aEntry;
1186 if (aEntry.read_header(aSourceFile))
1189 maPackedFileEntryVector.push_back(aEntry);
1201 maPackedFileEntryVector.clear();
1206 sal_uInt32 nHeaderSize(8);
1208 nHeaderSize += maPackedFileEntryVector.size() * PackedFileEntry::getEntrySize();
1210 sal_uInt32 nOffset(nHeaderSize);
1212 for (
auto& b : maPackedFileEntryVector)
1214 b.setOffset(nOffset);
1215 nOffset += b.getPackFileSize();
1224 aSourceFile->close();
1227 if (maPackedFileEntryVector.empty())
1238 if (maPackedFileEntryVector.empty())
1247 oslFileHandle aHandle =
nullptr;
1251 if (osl::File::E_None == osl::FileBase::createTempFile(
nullptr, &aHandle, &aTempURL))
1254 sal_uInt64 nBaseWritten(0);
1262 if (osl_File_E_None == osl_writeFile(aHandle,
static_cast<const void*
>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten)
1264 const sal_uInt32 nSize(maPackedFileEntryVector.size());
1267 if (write_sal_uInt32(aHandle, nSize))
1273 sal_uInt32 nWriteSize(0);
1275 nWriteSize += maPackedFileEntryVector.size() * PackedFileEntry::getEntrySize();
1277 aArray[0] = aArray[1] = aArray[2] = aArray[3] = 0;
1279 for (sal_uInt32
a(0); bRetval &&
a < nWriteSize;
a++)
1281 if (osl_File_E_None != osl_writeFile(aHandle,
static_cast<const void*
>(aArray), 1, &nBaseWritten) || 1 != nBaseWritten)
1291 for (
auto& candidate : maPackedFileEntryVector)
1293 if (!candidate.copy_content(aHandle,
false))
1304 if (osl_File_E_None != osl_setFilePos(aHandle, osl_Pos_Absolut, sal_Int64(8)))
1313 for (
const auto& candidate : maPackedFileEntryVector)
1315 if (!candidate.write_header(aHandle))
1328 osl_closeFile(aHandle);
1335 osl::File::move(aTempURL, maURL);
1343 bool tryPush(
FileSharedPtr const & rFileCandidate,
bool bCompress)
1345 sal_uInt64 nFileSize(0);
1347 if (rFileCandidate && osl::File::E_None == rFileCandidate->open(osl_File_OpenFlag_Read))
1349 rFileCandidate->getSize(nFileSize);
1350 rFileCandidate->close();
1359 bool bNeedToAdd(
false);
1360 sal_uInt32 nCrc32(0);
1362 if (maPackedFileEntryVector.empty())
1370 const PackedFileEntry& aLastEntry = maPackedFileEntryVector.back();
1373 if (aLastEntry.getFullFileSize() !=
static_cast<sal_uInt32
>(nFileSize))
1381 nCrc32 = createCrc32(rFileCandidate, 0);
1383 if (nCrc32 != aLastEntry.getCrc32())
1396 nCrc32 = createCrc32(rFileCandidate, 0);
1401 maPackedFileEntryVector.emplace_back(
1402 static_cast< sal_uInt32
>(nFileSize),
1413 bool tryPop(oslFileHandle& rHandle)
1415 if (maPackedFileEntryVector.empty())
1419 PackedFileEntry& aLastEntry = maPackedFileEntryVector.back();
1424 bool bRetval = aLastEntry.copy_content(rHandle,
true);
1428 maPackedFileEntryVector.pop_back();
1435 void tryReduceToNumBackups(sal_uInt16 nNumBackups)
1437 while (maPackedFileEntryVector.size() > nNumBackups)
1439 maPackedFileEntryVector.pop_front();
1446 return maPackedFileEntryVector.empty();
1468 OUString conf(
"${CONFIGURATION_LAYERS}");
1469 rtl::Bootstrap::expandMacros(conf);
1470 static constexpr OUStringLiteral aTokenUser(
u"user:");
1471 sal_Int32 nStart(conf.indexOf(aTokenUser));
1475 nStart += aTokenUser.getLength();
1476 sal_Int32 nEnd(conf.indexOf(
' ', nStart));
1480 nEnd = conf.getLength();
1515 static const OUString aSafeMode(
"SafeMode");
1530 if (rtl::Bootstrap::get(
"SecureUserConfig", sTokenOut))
1544 if (
mbActive && rtl::Bootstrap::get(
"SecureUserConfigNumCopies", sTokenOut))
1546 const sal_uInt16 nConfigNumCopies(
static_cast<sal_uInt16
>(sTokenOut.toUInt32()));
1552 if (
mbActive && rtl::Bootstrap::get(
"SecureUserConfigMode", sTokenOut))
1554 const sal_uInt16 nMode(
static_cast<sal_uInt16
>(sTokenOut.toUInt32()));
1557 mnMode = std::min(nMode, sal_uInt16(2));
1560 if (
mbActive && rtl::Bootstrap::get(
"SecureUserConfigExtensions", sTokenOut))
1565 if (
mbActive && rtl::Bootstrap::get(
"SecureUserConfigCompress", sTokenOut))
1593 std::set< OUString > aExcludeList;
1617 std::set< OUString > aExcludeList;
1668 bool bPopPossible(
false);
1688 return bPopPossible;
1696 bool bDidPop(
false);
1721 bool bPopPossible(
false);
1730 return bPopPossible;
1738 bool bDidPop(
false);
1755 class ExtensionInfo aExtensionInfo;
1759 return aExtensionInfo.areThereEnabledExtensions();
1767 ExtensionInfo aCurrentExtensionInfo;
1768 const ExtensionInfoEntryVector aToBeEnabled{};
1769 ExtensionInfoEntryVector aToBeDisabled;
1773 const ExtensionInfoEntryVector& rCurrentVector = aCurrentExtensionInfo.getExtensionInfoEntryVector();
1775 for (
const auto& rCurrentInfo : rCurrentVector)
1777 if (rCurrentInfo.isEnabled())
1779 aToBeDisabled.push_back(rCurrentInfo);
1783 ExtensionInfo::changeEnableDisableStateInXML(
maUserConfigWorkURL, aToBeEnabled, aToBeDisabled);
1789 class ExtensionInfo aExtensionInfo;
1793 return !aExtensionInfo.getExtensionInfoEntryVector().empty();
1805 class ExtensionInfo aExtensionInfo;
1809 return !aExtensionInfo.getExtensionInfoEntryVector().empty();
1821 class ExtensionInfo aExtensionInfo;
1825 return !aExtensionInfo.getExtensionInfoEntryVector().empty();
1836 static std::vector< OUString > aDirNames =
1851 static std::vector< OUString > aFileNames =
1853 "registrymodifications.xcu"
1860 uno::Reference<XElement> lcl_getConfigElement(
const uno::Reference<XDocument>& xDocument,
const OUString& rPath,
1861 const OUString& rKey,
const OUString& rValue)
1863 uno::Reference< XElement > itemElement = xDocument->createElement(
"item");
1864 itemElement->setAttribute(
"oor:path", rPath);
1866 uno::Reference< XElement > propElement = xDocument->createElement(
"prop");
1867 propElement->setAttribute(
"oor:name", rKey);
1868 propElement->setAttribute(
"oor:op",
"replace");
1870 uno::Reference< XElement > valueElement = xDocument->createElement(
"value");
1871 uno::Reference< XText > textElement = xDocument->createTextNode(rValue);
1873 valueElement->appendChild(textElement);
1874 propElement->appendChild(valueElement);
1875 itemElement->appendChild(propElement);
1883 const OUString aRegistryModifications(
maUserConfigWorkURL +
"/registrymodifications.xcu");
1888 uno::Reference< XDocumentBuilder > xBuilder = DocumentBuilder::create(xContext);
1889 uno::Reference< XDocument > xDocument = xBuilder->parseURI(aRegistryModifications);
1890 uno::Reference< XElement > xRootElement = xDocument->getDocumentElement();
1892 xRootElement->appendChild(lcl_getConfigElement(xDocument,
"/org.openoffice.Office.Common/VCL",
1893 "DisableOpenGL",
"true"));
1894 xRootElement->appendChild(lcl_getConfigElement(xDocument,
"/org.openoffice.Office.Common/Misc",
1895 "UseOpenCL",
"false"));
1897 xRootElement->appendChild(lcl_getConfigElement(xDocument,
"/org.openoffice.Office.Common/VCL",
1898 "ForceSkia",
"false"));
1899 xRootElement->appendChild(lcl_getConfigElement(xDocument,
"/org.openoffice.Office.Common/VCL",
1900 "ForceSkiaRaster",
"true"));
1907 uno::Reference< xml::sax::XSAXSerializable > xSerializer(xDocument, uno::UNO_QUERY);
1909 if (!xSerializer.is())
1913 uno::Reference< xml::sax::XWriter >
const xSaxWriter = xml::sax::Writer::create(xContext);
1914 uno::Reference< io::XTempFile > xTempFile = io::TempFile::create(xContext);
1915 xTempFile->setRemoveFile(
false);
1916 uno::Reference< io::XOutputStream > xOutStrm = xTempFile->getOutputStream();
1919 xSaxWriter->setOutputStream(xOutStrm);
1920 xSerializer->serialize(xSaxWriter, uno::Sequence< beans::StringPair >());
1923 aTempURL = xTempFile->getUri();
1935 int result = osl::File::move(aTempURL, aRegistryModifications);
1936 SAL_WARN_IF(
result != osl::FileBase::E_None,
"comphelper.backupfilehelper",
"could not copy back modified Extension configuration file");
1944 for (
const auto&
a : rDirs)
1954 for (
const auto& b : rFiles)
1970 for (
const auto&
a : rDirs)
1977 for (
const auto& b : rFiles)
2009 const std::set< OUString >& rDirs,
2010 const std::set< std::pair< OUString, OUString > >& rFiles,
2011 std::u16string_view rSourceURL,
2012 const OUString& rTargetURL
2015 bool bDidPush(
false);
2016 osl::Directory::createPath(rTargetURL);
2019 for (
const auto& file : rFiles)
2029 for (
const auto& dir : rDirs)
2031 OUString aNewSourceURL(OUString::Concat(rSourceURL) +
"/" + dir);
2032 OUString aNewTargetURL(rTargetURL +
"/" + dir);
2033 std::set< OUString > aNewDirs;
2034 std::set< std::pair< OUString, OUString > > aNewFiles;
2041 if (!aNewDirs.empty() || !aNewFiles.empty())
2061 std::u16string_view rSourceURL,
2062 std::u16string_view rTargetURL,
2063 std::u16string_view rName,
2064 std::u16string_view rExt
2067 const OUString aFileURL(createFileURL(rSourceURL, rName, rExt));
2071 const OUString aPackURL(createPackURL(rTargetURL, rName));
2072 PackedFile aPackedFile(aPackURL);
2073 FileSharedPtr aBaseFile = std::make_shared<osl::File>(aFileURL);
2075 if (aPackedFile.tryPush(aBaseFile,
mbCompress))
2079 aPackedFile.flush();
2091 const std::set< OUString >& rDirs,
2092 const std::set< std::pair< OUString, OUString > >& rFiles,
2093 std::u16string_view rSourceURL,
2094 std::u16string_view rTargetURL
2097 bool bPopPossible(
false);
2100 for (
const auto& file : rFiles)
2110 for (
const auto& dir : rDirs)
2112 OUString aNewSourceURL(OUString::Concat(rSourceURL) +
"/" + dir);
2113 OUString aNewTargetURL(OUString::Concat(rTargetURL) +
"/" + dir);
2114 std::set< OUString > aNewDirs;
2115 std::set< std::pair< OUString, OUString > > aNewFiles;
2122 if (!aNewDirs.empty() || !aNewFiles.empty())
2132 return bPopPossible;
2136 std::u16string_view rSourceURL,
2137 std::u16string_view rTargetURL,
2138 std::u16string_view rName,
2139 std::u16string_view rExt
2142 const OUString aFileURL(createFileURL(rSourceURL, rName, rExt));
2146 const OUString aPackURL(createPackURL(rTargetURL, rName));
2147 PackedFile aPackedFile(aPackURL);
2149 return !aPackedFile.empty();
2158 const std::set< OUString >& rDirs,
2159 const std::set< std::pair< OUString, OUString > >& rFiles,
2160 std::u16string_view rSourceURL,
2161 const OUString& rTargetURL
2164 bool bDidPop(
false);
2167 for (
const auto& file : rFiles)
2177 for (
const auto& dir : rDirs)
2179 OUString aNewSourceURL(OUString::Concat(rSourceURL) +
"/" + dir);
2180 OUString aNewTargetURL(rTargetURL +
"/" + dir);
2181 std::set< OUString > aNewDirs;
2182 std::set< std::pair< OUString, OUString > > aNewFiles;
2189 if (!aNewDirs.empty() || !aNewFiles.empty())
2209 std::u16string_view rSourceURL,
2210 std::u16string_view rTargetURL,
2211 std::u16string_view rName,
2212 std::u16string_view rExt
2215 const OUString aFileURL(createFileURL(rSourceURL, rName, rExt));
2221 const OUString aPackURL(createPackURL(rTargetURL, rName));
2222 PackedFile aPackedFile(aPackURL);
2224 if (aPackedFile.empty())
2227 oslFileHandle aHandle;
2231 if (osl::File::E_None != osl::FileBase::createTempFile(
nullptr, &aHandle, &aTempURL))
2234 bool bRetval(aPackedFile.tryPop(aHandle));
2237 osl_closeFile(aHandle);
2244 osl::File::move(aTempURL, aFileURL);
2248 aPackedFile.flush();
2260 std::u16string_view rTargetURL
2263 ExtensionInfo aExtensionInfo;
2265 bool bRetval(
false);
2268 if (aExtensionInfo.createTempFile(aTempURL))
2270 const OUString aPackURL(createPackURL(rTargetURL,
u"ExtensionInfo"));
2271 PackedFile aPackedFile(aPackURL);
2272 FileSharedPtr aBaseFile = std::make_shared<osl::File>(aTempURL);
2274 if (aPackedFile.tryPush(aBaseFile,
mbCompress))
2278 aPackedFile.flush();
2289 std::u16string_view rTargetURL
2293 const OUString aPackURL(createPackURL(rTargetURL,
u"ExtensionInfo"));
2294 PackedFile aPackedFile(aPackURL);
2296 return !aPackedFile.empty();
2300 std::u16string_view rTargetURL
2304 const OUString aPackURL(createPackURL(rTargetURL,
u"ExtensionInfo"));
2305 PackedFile aPackedFile(aPackURL);
2307 if (aPackedFile.empty())
2310 oslFileHandle aHandle;
2314 if (osl::File::E_None != osl::FileBase::createTempFile(
nullptr, &aHandle, &aTempURL))
2317 bool bRetval(aPackedFile.tryPop(aHandle));
2320 osl_closeFile(aHandle);
2325 ExtensionInfo aLoadedExtensionInfo;
2326 FileSharedPtr aBaseFile = std::make_shared<osl::File>(aTempURL);
2328 if (osl::File::E_None == aBaseFile->open(osl_File_OpenFlag_Read))
2330 if (aLoadedExtensionInfo.read_entries(aBaseFile))
2333 ExtensionInfo aCurrentExtensionInfo;
2340 const ExtensionInfoEntryVector& aUserEntries = aCurrentExtensionInfo.getExtensionInfoEntryVector();
2341 const ExtensionInfoEntryVector& rLoadedVector = aLoadedExtensionInfo.getExtensionInfoEntryVector();
2342 ExtensionInfoEntryVector aToBeDisabled;
2343 ExtensionInfoEntryVector aToBeEnabled;
2345 for (
const auto& rCurrentInfo : aUserEntries)
2347 const ExtensionInfoEntry* pLoadedInfo =
nullptr;
2349 for (
const auto& rLoadedInfo : rLoadedVector)
2351 if (rCurrentInfo.isSameExtension(rLoadedInfo))
2353 pLoadedInfo = &rLoadedInfo;
2358 if (
nullptr != pLoadedInfo)
2361 const bool bCurrentEnabled(rCurrentInfo.isEnabled());
2362 const bool bLoadedEnabled(pLoadedInfo->isEnabled());
2364 if (bCurrentEnabled && !bLoadedEnabled)
2366 aToBeDisabled.push_back(rCurrentInfo);
2368 else if (!bCurrentEnabled && bLoadedEnabled)
2370 aToBeEnabled.push_back(rCurrentInfo);
2377 if (rCurrentInfo.isEnabled())
2379 aToBeDisabled.push_back(rCurrentInfo);
2384 if (!aToBeDisabled.empty() || !aToBeEnabled.empty())
2386 ExtensionInfo::changeEnableDisableStateInXML(
maUserConfigWorkURL, aToBeEnabled, aToBeDisabled);
2395 aPackedFile.flush();
2438 maDirs.insert(
"autocorr");
2441 maDirs.insert(
"autotext");
2450 maDirs.insert(
"database");
2453 maDirs.insert(
"registry");
2456 maDirs.insert(
"Scripts");
2459 maDirs.insert(
"template");
2462 maDirs.insert(
"wordbook");
2484 maDirs.erase(
"SafeMode");
const sal_uInt32 BACKUP_FILE_HELPER_BLOCK_SIZE
static OUString getPackURL()
static void tryResetSharedExtensions()
void tryPush()
tries to create a new backup, if there is none yet, or if the last differs from the base file.
static bool mbSafeModeDirExists
static bool getExitWasCalled()
static void tryResetBundledExtensions()
static bool isTryResetCustomizationsPossible()
resets User-Customizations like Settings and UserInterface modifications
static OUString maRegModName
static void reactOnSafeMode(bool bSafeMode)
static const OUString & getUserProfileWorkURL()
Return the url of the backed up profile (when in safe mode)
static bool isTryDisableAllExtensionsPossible()
tries to iterate the extensions and to disable all of them
static OUString maUserConfigWorkURL
static const OUString & getInitialBaseURL()
static bool isTryResetBundledExtensionsPossible()
Reset bundled Extensions.
static OUString maUserConfigBaseURL
static void tryDisableHWAcceleration()
Disables OpenGL and OpenCL.
static void tryDisableAllExtensions()
static bool mbExitWasCalled
bool isPopPossibleExtensionInfo() const
static void tryDeinstallUserExtensions()
static bool isPopPossible_extensionInfo(std::u16string_view rTargetURL)
bool tryPush_file(std::u16string_view rSourceURL, std::u16string_view rTargetURL, std::u16string_view rName, std::u16string_view rExt)
BackupFileHelper()
Constructor to handle Backups of the given file, will internally detect configuration values and URL ...
static void tryResetUserProfile()
resets the whole UserProfile
void tryPopExtensionInfo()
static bool isTryResetSharedExtensionsPossible()
Reset shared Extensions.
void tryPushExtensionInfo()
std::set< std::pair< OUString, OUString > > maFiles
bool tryPop_files(const std::set< OUString > &rDirs, const std::set< std::pair< OUString, OUString > > &rFiles, std::u16string_view rSourceURL, const OUString &rTargetURL)
bool tryPush_Files(const std::set< OUString > &rDirs, const std::set< std::pair< OUString, OUString > > &rFiles, std::u16string_view rSourceURL, const OUString &rTargetURL)
static sal_uInt16 mnMaxAllowedBackups
void tryPop()
tries to execute a restore.
static const OUString & getSafeModeName()
bool tryPush_extensionInfo(std::u16string_view rTargetURL)
static OUString maInitialBaseURL
static const std::vector< OUString > & getCustomizationDirNames()
static void setExitWasCalled()
static const OUString & getUserProfileURL()
Return the profile url.
static bool isTryDeinstallUserExtensionsPossible()
Deinstall all User Extensions (installed for User only)
bool tryPop_file(std::u16string_view rSourceURL, std::u16string_view rTargetURL, std::u16string_view rName, std::u16string_view rExt)
bool tryPop_extensionInfo(std::u16string_view rTargetURL)
bool isPopPossible_files(const std::set< OUString > &rDirs, const std::set< std::pair< OUString, OUString > > &rFiles, std::u16string_view rSourceURL, std::u16string_view rTargetURL)
std::set< OUString > maDirs
static const std::vector< OUString > & getCustomizationFileNames()
bool isPopPossible()
finds out if a restore is possible
static bool isPopPossible_file(std::u16string_view rSourceURL, std::u16string_view rTargetURL, std::u16string_view rName, std::u16string_view rExt)
static void tryResetCustomizations()
static std::u16string_view splitAtLastToken(std::u16string_view rSrc, sal_Unicode aToken, OUString &rRight)
static bool deleteDirRecursively(const OUString &rDirURL)
static bool dirExists(const OUString &rDirURL)
static void scanDirsAndFiles(const OUString &rDirURL, std::set< OUString > &rDirs, std::set< std::pair< OUString, OUString > > &rFiles)
static bool moveDirContent(const OUString &rSourceDirURL, std::u16string_view rTargetDirURL, const std::set< OUString > &rExcludeList)
static bool fileExists(const OUString &rBaseURL)
#define SAL_WARN_IF(condition, area, stream)
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
Removes all occurrences of a character from within the source string.
std::shared_ptr< osl::File > FileSharedPtr
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.
Any SAL_CALL getCaughtException()
constexpr OUStringLiteral USER
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::unique_ptr< char[]> aBuffer
bool operator<(const wwFont &r1, const wwFont &r2)