forked from amazingfate/loongoffice
...as obsoleted by ef533553559fe09b4afab651fc692885d1acf4ed "Rudimentary support for dynamic_cast on UNO proxy objects". This reverts all of: 4cfcc9ac37b90ce64c8402a41eb4638adb185b5c "loplugin:unocast (framework::Desktop)" 03efbf72f4ddf7a84aa8aabef348331bd4b75e8a "loplugin:unocast (vclcanvas::TextLayout)" 80099fdd51a69eaa6c36ca88ef772810e4a777fa "loplugin:unocast (SalGtkXWindow)" cc147f576d8687fb79c77d47d41dc4ba1678a469 "loplugin:unocast (sdext::presenter::CachablePresenterView)" 40db42be1d8fd0f9c6c8c5ba3767ddb9ee2034c2 "loplugin:unocast (vclcanvas::CanvasFont)" 2d1e7995eae29e2826449eb5179f5fae181794a5 "loplugin:unocast (CairoColorSpace)" 4c0bbe4bd97636207cf71a6aa120c67698891da9 "loplugin:unocast (canvas::ParametricPolyPolygon)" 89803666621c07d1b1ac9d3bd883f0ca192a91a0 "loplugin:unocast (vclcanas::CanvasBitmap)" d5e0c2c8db71878d21c2a7255af08cf5f9a6dd04 "loplugin:unocast (sfx2::DigitalSignatures)" c0c4519e0d5b555f59bbc04cc616454edfd1f4ce "loplugin:unocast (VCLXAccessibleComponent)" feb8b833a6245d42400f42a0bc789dc84594ee6f "loplugin:unocast (VCLXDialog)" 1fa58cc6cc9c3849753342a5d9a6ddfa461b5e66 "loplugin:unocast (VCLXMultiPage)" f481f036deb1b1b46f3038074c4659f3a91b9c6c "loplugin:unocast (DocumentSettingsSerializer)" 73df933f5fa5932f94e5a1b338a3eda00a9ce354 "loplugin:unocast (css::embed::EmbeddedUpdate)" 420165ab0ef03c0467f9d17f504de2d2fc78f0e6 "loplugin:unocast (canvas::tools' StandardColorSpace, StandardNoAlphaColorSpace)" 9abe8ee067e6c00f19d8a13346d53c4641c27166 "loplugin:unocast (MutableTreeNode)" 9f3022ceb036f23b4b0994c3e2fbd1001bff225a "loplugin:unocast (VCLXTabPage)" 1be70dda02c12a60778b7607cff2520ae1aa611e "loplugin:unocast (vcl::unotools::VclCanvasBitmap)" d6a70bb641b96e8e5616448c2378131ed62658b4 "loplugin:unocast (basegfx::unotools::UnoPolyPolygon)" 5a14f009e6782c077463c8cbb8e9cea3d7950107 "loplugin:unocast (xmlsecurity::Certificate)" 99009c9535dfa3e0d838989ccc7d84bfa2320ff4 "loplugin:unocast (sd::Annotation)" 0c7585c5fa78887e5459885ed744e8044fd76137 "loplugin:unocast (sd::TextApiObject)" 24e14afd1bfcaed6c200ab081973fba7e47267ca "loplugin:unocast (SignatureVerifierImpl)" 1a7ad0c10d286ce9ae2700ceb2fd50eed1fb43a4 "loplugin:unocast (pcr::PropertyEventTranslation)" a97e2d2702d9a6f37775ccee2c08c4f3b2479c4b "loplugin:unocast (RangePageBreaks)" 19dfdf86ad1f5b08041d8b7a9f196caf881231ab "iloplugin:unocast (pcr::OFormattedNumericControl)" f9785ea595fd8e911f6370e836fa579225b9e571 "loplugin:unocast (frm::OInterfaceContainer)" 5e5f40a4a92a31b0932c690219d002fcf18598cf "loplugin:unocast (ScVbaShapes)" 27b35b2c215b4832d4378ec3a7ecbba926552d06 "loplugin:unocast (ScVbaShapeRange)" cb3108f860065928552a86cf8acc4b3a95718ecf "cid#1517812 Dereference null return value" feba0ddb1521d1142560fe54b7d7696ee910237f "loplugin:unocast (weld::TransportAsXWindow)" 4d6c23216559eb48f9943bb49d6e475a6d64ba15 "loplugin:unocast (oox::ForumlaImExportBase)" 4844c096a8ab6a9a620c410a0949d4499f12a504 "loplugin:unocast (cairocanvas::SurfaceProvider)" 9a0b523e0a84d403b9092176ccec4b3e3efe42d0 "loplugin:unocast (cairocanvas::CanvasBitmap)" 8a5648d8e59b4b007dbbf3824777c19a21efc61e "loplugin:unocast (cairocanvas::TextLayout)" 28c27a0623bc78a0590858f97d03b620985bc84c "loplugin:unocast (cairocanvas::CanvasFont)" 53bc223cb3288e32a417696ee61c29e5f01f209d "loplugin:unocast (cairocanvas::RepaintTarget)" 5f70b0b9f6bc4ab145ddbd9155590ed4a3b1b9ec "loplugin:unocast (SvXMLImport)" 068187a898cdd2e26e9b16c348ecc1ed2dee3f29 "loplugin:unocast (VCLXWindow)" 88b4f966202717cd4ad38a30a8eda22c3e69ed35 "loplugin:unocast (sfx2::sidebar::SidebarController)" f1b7a69b280aefe2f1b3b0f32193494fd765f2bd "loplugin:unocast (SvxLineStyleToolBoxControl)" ba76f0ba7e8de4d2953739c952004b7d9af47197 "loplugin:unocast (i18npool::Calendar_gregorian)" 840154daf934d8df52ead1cb7acd798c4d30f007 "loplugin:unocast (framework::AddonsToolBarWrapper)" b0e9c4c5f063cefa9557810e3349bdb9c7493091 "loplugin:unocast (GrammarCheckingIterator)" 8ee6cfc9655ce9de4617cea1a0d9cb9d7a4fbfac "loplugin:unocast (ucb::ucp::ext::Content)" 5b8cd77c112bc8c0e92b8fec215c3c8e802bbc0a "loplugin:unocast (basic::SfxScriptLibraryContainer)" 9e73ff9fce12e102bb3c3cea8d8bb96c88f2c9ad "loplugin:unocast (sdext::presenter::PresenterNotesView)" a98acca8fbc38d3fd5600ae5056a8e42b6d8a40d "loplugin:unocast (SelectionChangeHandler)" c0b59ad6e35b0cb0dea0821e95f95569739078c1 "Consistently use comphelper::getSomethingImpl<I>(aIdentifier, this)" 276e3ccbdd3259ec3daf8a1a98fa7f406b14e21c "loplugin:unocast (vclcanvas::RepaintTarget)" Change-Id: I37c73e3422a5154bf6cb647640d2d3f23db8bc34 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145063 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
1243 lines
45 KiB
C++
1243 lines
45 KiB
C++
/* -*- 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/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <scriptcont.hxx>
|
|
#include <com/sun/star/packages/WrongPasswordException.hpp>
|
|
#include <com/sun/star/xml/sax/Parser.hpp>
|
|
#include <com/sun/star/xml/sax/InputSource.hpp>
|
|
#include <com/sun/star/xml/sax/Writer.hpp>
|
|
#include <com/sun/star/io/XTruncate.hpp>
|
|
#include <com/sun/star/embed/ElementModes.hpp>
|
|
#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/embed/XTransactedObject.hpp>
|
|
#include <com/sun/star/task/ErrorCodeIOException.hpp>
|
|
#include <com/sun/star/script/ModuleType.hpp>
|
|
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
|
#include <comphelper/storagehelper.hxx>
|
|
#include <unotools/ucbstreamhelper.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <sot/storage.hxx>
|
|
|
|
// For password functionality
|
|
#include <tools/urlobj.hxx>
|
|
|
|
|
|
#include <svtools/sfxecode.hxx>
|
|
#include <svtools/ehdl.hxx>
|
|
#include <basic/basmgr.hxx>
|
|
#include <basic/sbmod.hxx>
|
|
#include <basic/modsizeexceeded.hxx>
|
|
#include <xmlscript/xmlmod_imexp.hxx>
|
|
#include <com/sun/star/util/VetoException.hpp>
|
|
#include <memory>
|
|
|
|
namespace basic
|
|
{
|
|
|
|
using namespace com::sun::star::document;
|
|
using namespace com::sun::star::container;
|
|
using namespace com::sun::star::io;
|
|
using namespace com::sun::star::uno;
|
|
using namespace com::sun::star::ucb;
|
|
using namespace com::sun::star::lang;
|
|
using namespace com::sun::star::script;
|
|
using namespace com::sun::star::xml::sax;
|
|
using namespace com::sun::star;
|
|
using namespace cppu;
|
|
using namespace osl;
|
|
|
|
|
|
// Implementation class SfxScriptLibraryContainer
|
|
|
|
OUString SfxScriptLibraryContainer::getInfoFileName() const
|
|
{
|
|
static constexpr OUStringLiteral script = u"script";
|
|
return script;
|
|
}
|
|
OUString SfxScriptLibraryContainer::getOldInfoFileName() const
|
|
{
|
|
static constexpr OUStringLiteral script = u"script";
|
|
return script;
|
|
}
|
|
OUString SfxScriptLibraryContainer::getLibElementFileExtension() const
|
|
{
|
|
static constexpr OUStringLiteral xba = u"xba";
|
|
return xba;
|
|
}
|
|
OUString SfxScriptLibraryContainer::getLibrariesDir() const
|
|
{
|
|
static constexpr OUStringLiteral sBasic = u"Basic";
|
|
return sBasic;
|
|
}
|
|
|
|
void SfxScriptLibraryContainer::setLibraryPassword( const OUString& rLibraryName, const OUString& rPassword )
|
|
{
|
|
try
|
|
{
|
|
SfxLibrary* pImplLib = getImplLib( rLibraryName );
|
|
if( !rPassword.isEmpty() )
|
|
{
|
|
pImplLib->mbDoc50Password = true;
|
|
pImplLib->mbPasswordProtected = true;
|
|
pImplLib->maPassword = rPassword;
|
|
SfxScriptLibrary *const pSL(dynamic_cast<SfxScriptLibrary *>(pImplLib));
|
|
if (pSL && pSL->mbLoaded)
|
|
{
|
|
pSL->mbLoadedSource = true; // must store source code now!
|
|
}
|
|
}
|
|
}
|
|
catch(const NoSuchElementException& ) {}
|
|
}
|
|
|
|
// Ctor for service
|
|
SfxScriptLibraryContainer::SfxScriptLibraryContainer()
|
|
{
|
|
// all initialisation has to be done
|
|
// by calling XInitialization::initialize
|
|
}
|
|
|
|
SfxScriptLibraryContainer::SfxScriptLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
|
|
{
|
|
init( OUString(), xStorage );
|
|
}
|
|
|
|
// Methods to get library instances of the correct type
|
|
rtl::Reference<SfxLibrary> SfxScriptLibraryContainer::implCreateLibrary( const OUString& )
|
|
{
|
|
return new SfxScriptLibrary( maModifiable, mxSFI );
|
|
}
|
|
|
|
rtl::Reference<SfxLibrary> SfxScriptLibraryContainer::implCreateLibraryLink( const OUString&,
|
|
const OUString& aLibInfoFileURL,
|
|
const OUString& StorageURL,
|
|
bool ReadOnly )
|
|
{
|
|
return new SfxScriptLibrary( maModifiable, mxSFI,
|
|
aLibInfoFileURL, StorageURL, ReadOnly );
|
|
}
|
|
|
|
Any SfxScriptLibraryContainer::createEmptyLibraryElement()
|
|
{
|
|
Any aRetAny;
|
|
aRetAny <<= OUString();
|
|
return aRetAny;
|
|
}
|
|
|
|
bool SfxScriptLibraryContainer::isLibraryElementValid(const Any& rElement) const
|
|
{
|
|
return SfxScriptLibrary::containsValidModule(rElement);
|
|
}
|
|
|
|
void SfxScriptLibraryContainer::writeLibraryElement( const Reference < XNameContainer >& xLib,
|
|
const OUString& aElementName,
|
|
const Reference< XOutputStream >& xOutput)
|
|
{
|
|
// Create sax writer
|
|
Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
|
|
|
|
Reference< XTruncate > xTruncate( xOutput, UNO_QUERY );
|
|
OSL_ENSURE( xTruncate.is(), "Currently only the streams that can be truncated are expected!" );
|
|
if ( xTruncate.is() )
|
|
{
|
|
xTruncate->truncate();
|
|
}
|
|
xWriter->setOutputStream( xOutput );
|
|
|
|
xmlscript::ModuleDescriptor aMod;
|
|
aMod.aName = aElementName;
|
|
aMod.aLanguage = "StarBasic";
|
|
Any aElement = xLib->getByName( aElementName );
|
|
aElement >>= aMod.aCode;
|
|
|
|
Reference< script::vba::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY );
|
|
if( xModInfo.is() && xModInfo->hasModuleInfo( aElementName ) )
|
|
{
|
|
script::ModuleInfo aModInfo = xModInfo->getModuleInfo( aElementName );
|
|
switch( aModInfo.ModuleType )
|
|
{
|
|
case ModuleType::NORMAL:
|
|
aMod.aModuleType = "normal";
|
|
break;
|
|
case ModuleType::CLASS:
|
|
aMod.aModuleType ="class";
|
|
break;
|
|
case ModuleType::FORM:
|
|
aMod.aModuleType = "form";
|
|
break;
|
|
case ModuleType::DOCUMENT:
|
|
aMod.aModuleType = "document";
|
|
break;
|
|
case ModuleType::UNKNOWN:
|
|
// nothing
|
|
break;
|
|
}
|
|
}
|
|
|
|
xmlscript::exportScriptModule( xWriter, aMod );
|
|
}
|
|
|
|
|
|
Any SfxScriptLibraryContainer::importLibraryElement
|
|
( const Reference < XNameContainer >& xLib,
|
|
const OUString& aElementName, const OUString& aFile,
|
|
const uno::Reference< io::XInputStream >& xInStream )
|
|
{
|
|
Any aRetAny;
|
|
|
|
Reference< XParser > xParser = xml::sax::Parser::create( mxContext );
|
|
|
|
// Read from storage?
|
|
bool bStorage = xInStream.is();
|
|
Reference< XInputStream > xInput;
|
|
|
|
if( bStorage )
|
|
{
|
|
xInput = xInStream;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
xInput = mxSFI->openFileRead( aFile );
|
|
}
|
|
catch(const Exception& )
|
|
//catch( Exception& e )
|
|
{
|
|
// TODO:
|
|
//throw WrappedTargetException( e );
|
|
}
|
|
}
|
|
|
|
if( !xInput.is() )
|
|
return aRetAny;
|
|
|
|
InputSource source;
|
|
source.aInputStream = xInput;
|
|
source.sSystemId = aFile;
|
|
|
|
// start parsing
|
|
xmlscript::ModuleDescriptor aMod;
|
|
|
|
try
|
|
{
|
|
xParser->setDocumentHandler( ::xmlscript::importScriptModule( aMod ) );
|
|
xParser->parseStream( source );
|
|
}
|
|
catch(const Exception& )
|
|
{
|
|
SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
|
|
ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
|
|
}
|
|
|
|
aRetAny <<= aMod.aCode;
|
|
|
|
// TODO: Check language
|
|
// aMod.aLanguage
|
|
// aMod.aName ignored
|
|
if( !aMod.aModuleType.isEmpty() )
|
|
{
|
|
/* If in VBA compatibility mode, force creation of the VBA Globals
|
|
object. Each application will create an instance of its own
|
|
implementation and store it in its Basic manager. Implementations
|
|
will do all necessary additional initialization, such as
|
|
registering the global "This***Doc" UNO constant, starting the
|
|
document events processor etc.
|
|
*/
|
|
if( getVBACompatibilityMode() ) try
|
|
{
|
|
Reference< frame::XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
|
|
Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
|
|
xFactory->createInstance("ooo.vba.VBAGlobals");
|
|
}
|
|
catch(const Exception& )
|
|
{
|
|
}
|
|
|
|
script::ModuleInfo aModInfo;
|
|
aModInfo.ModuleType = ModuleType::UNKNOWN;
|
|
if( aMod.aModuleType == "normal" )
|
|
{
|
|
aModInfo.ModuleType = ModuleType::NORMAL;
|
|
}
|
|
else if( aMod.aModuleType == "class" )
|
|
{
|
|
aModInfo.ModuleType = ModuleType::CLASS;
|
|
}
|
|
else if( aMod.aModuleType == "form" )
|
|
{
|
|
aModInfo.ModuleType = ModuleType::FORM;
|
|
aModInfo.ModuleObject = mxOwnerDocument;
|
|
}
|
|
else if( aMod.aModuleType == "document" )
|
|
{
|
|
aModInfo.ModuleType = ModuleType::DOCUMENT;
|
|
|
|
// #163691# use the same codename access instance for all document modules
|
|
if( !mxCodeNameAccess.is() ) try
|
|
{
|
|
Reference<frame::XModel > xModel( mxOwnerDocument );
|
|
Reference< XMultiServiceFactory> xSF( xModel, UNO_QUERY_THROW );
|
|
mxCodeNameAccess.set( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), UNO_QUERY );
|
|
}
|
|
catch(const Exception& ) {}
|
|
|
|
if( mxCodeNameAccess.is() )
|
|
{
|
|
try
|
|
{
|
|
aModInfo.ModuleObject.set( mxCodeNameAccess->getByName( aElementName), uno::UNO_QUERY );
|
|
}
|
|
catch(const uno::Exception&)
|
|
{
|
|
SAL_WARN("basic", "Failed to get document object for " << aElementName );
|
|
}
|
|
}
|
|
}
|
|
|
|
Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
|
|
if( xVBAModuleInfo.is() )
|
|
{
|
|
if( xVBAModuleInfo->hasModuleInfo( aElementName ) )
|
|
{
|
|
xVBAModuleInfo->removeModuleInfo( aElementName );
|
|
}
|
|
xVBAModuleInfo->insertModuleInfo( aElementName, aModInfo );
|
|
}
|
|
}
|
|
|
|
return aRetAny;
|
|
}
|
|
|
|
rtl::Reference<SfxLibraryContainer> SfxScriptLibraryContainer::createInstanceImpl()
|
|
{
|
|
return new SfxScriptLibraryContainer();
|
|
}
|
|
|
|
void SfxScriptLibraryContainer::importFromOldStorage( const OUString& aFile )
|
|
{
|
|
// TODO: move loading from old storage to binary filters?
|
|
auto xStorage = tools::make_ref<SotStorage>( false, aFile );
|
|
if( xStorage->GetError() == ERRCODE_NONE )
|
|
{
|
|
auto pBasicManager = std::make_unique<BasicManager> ( *xStorage, aFile );
|
|
|
|
// Set info
|
|
LibraryContainerInfo aInfo( this, nullptr, this );
|
|
pBasicManager->SetLibraryContainerInfo( aInfo );
|
|
}
|
|
}
|
|
|
|
|
|
// Storing with password encryption
|
|
|
|
// Methods XLibraryContainerPassword
|
|
sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordProtected( const OUString& Name )
|
|
{
|
|
LibraryContainerMethodGuard aGuard( *this );
|
|
SfxLibrary* pImplLib = getImplLib( Name );
|
|
bool bRet = pImplLib->mbPasswordProtected;
|
|
return bRet;
|
|
}
|
|
|
|
sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordVerified( const OUString& Name )
|
|
{
|
|
LibraryContainerMethodGuard aGuard( *this );
|
|
SfxLibrary* pImplLib = getImplLib( Name );
|
|
if( !pImplLib->mbPasswordProtected )
|
|
{
|
|
throw IllegalArgumentException("!passwordProtected", static_cast<cppu::OWeakObject*>(this), 1);
|
|
}
|
|
bool bRet = pImplLib->mbPasswordVerified;
|
|
return bRet;
|
|
}
|
|
|
|
sal_Bool SAL_CALL SfxScriptLibraryContainer::verifyLibraryPassword
|
|
( const OUString& Name, const OUString& Password )
|
|
{
|
|
LibraryContainerMethodGuard aGuard( *this );
|
|
SfxLibrary* pImplLib = getImplLib( Name );
|
|
if( !pImplLib->mbPasswordProtected || pImplLib->mbPasswordVerified )
|
|
{
|
|
throw IllegalArgumentException("!PasswordProtected || PasswordVerified", static_cast<cppu::OWeakObject*>(this), 1);
|
|
}
|
|
// Test password
|
|
bool bSuccess = false;
|
|
if( pImplLib->mbDoc50Password )
|
|
{
|
|
bSuccess = ( Password == pImplLib->maPassword );
|
|
if( bSuccess )
|
|
{
|
|
pImplLib->mbPasswordVerified = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pImplLib->maPassword = Password;
|
|
bSuccess = implLoadPasswordLibrary( pImplLib, Name, true );
|
|
if( bSuccess )
|
|
{
|
|
// The library gets modified by verifying the password, because other-
|
|
// wise for saving the storage would be copied and that doesn't work
|
|
// with mtg's storages when the password is verified
|
|
pImplLib->implSetModified( true );
|
|
pImplLib->mbPasswordVerified = true;
|
|
|
|
// Reload library to get source
|
|
if( pImplLib->mbLoaded )
|
|
{
|
|
implLoadPasswordLibrary( pImplLib, Name );
|
|
}
|
|
}
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
void SAL_CALL SfxScriptLibraryContainer::changeLibraryPassword( const OUString& Name,
|
|
const OUString& OldPassword,
|
|
const OUString& NewPassword )
|
|
{
|
|
LibraryContainerMethodGuard aGuard( *this );
|
|
SfxLibrary* pImplLib = getImplLib( Name );
|
|
if( OldPassword == NewPassword )
|
|
{
|
|
return;
|
|
}
|
|
bool bOldPassword = !OldPassword.isEmpty();
|
|
bool bNewPassword = !NewPassword.isEmpty();
|
|
bool bStorage = mxStorage.is() && !pImplLib->mbLink;
|
|
|
|
if( pImplLib->mbReadOnly || (bOldPassword && !pImplLib->mbPasswordProtected) )
|
|
{
|
|
throw IllegalArgumentException();
|
|
}
|
|
// Library must be loaded
|
|
loadLibrary( Name );
|
|
|
|
bool bKillCryptedFiles = false;
|
|
bool bKillUnencryptedFiles = false;
|
|
|
|
// Remove or change password?
|
|
if( bOldPassword )
|
|
{
|
|
if( isLibraryPasswordVerified( Name ) )
|
|
{
|
|
if( pImplLib->maPassword != OldPassword )
|
|
{
|
|
throw IllegalArgumentException();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( !verifyLibraryPassword( Name, OldPassword ) )
|
|
{
|
|
throw IllegalArgumentException();
|
|
}
|
|
// Reload library to get source
|
|
// Should be done in verifyLibraryPassword loadLibrary( Name );
|
|
}
|
|
|
|
if( !bNewPassword )
|
|
{
|
|
pImplLib->mbPasswordProtected = false;
|
|
pImplLib->mbPasswordVerified = false;
|
|
pImplLib->maPassword.clear();
|
|
|
|
maModifiable.setModified( true );
|
|
pImplLib->implSetModified( true );
|
|
|
|
if( !bStorage && !pImplLib->mbDoc50Password )
|
|
{
|
|
// Store application basic unencrypted
|
|
uno::Reference< embed::XStorage > xStorage;
|
|
storeLibraries_Impl( xStorage, false );
|
|
bKillCryptedFiles = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set new password?
|
|
if( bNewPassword )
|
|
{
|
|
pImplLib->mbPasswordProtected = true;
|
|
pImplLib->mbPasswordVerified = true;
|
|
pImplLib->maPassword = NewPassword;
|
|
SfxScriptLibrary *const pSL(dynamic_cast<SfxScriptLibrary *>(pImplLib));
|
|
if (pSL && pSL->mbLoaded)
|
|
{
|
|
pSL->mbLoadedSource = true; // must store source code now!
|
|
}
|
|
|
|
maModifiable.setModified( true );
|
|
pImplLib->implSetModified( true );
|
|
|
|
if( !bStorage && !pImplLib->mbDoc50Password )
|
|
{
|
|
// Store application basic crypted
|
|
uno::Reference< embed::XStorage > xStorage;
|
|
storeLibraries_Impl( xStorage, false );
|
|
bKillUnencryptedFiles = true;
|
|
}
|
|
}
|
|
|
|
if( !(bKillCryptedFiles || bKillUnencryptedFiles) )
|
|
return;
|
|
|
|
Sequence< OUString > aElementNames = pImplLib->getElementNames();
|
|
sal_Int32 nNameCount = aElementNames.getLength();
|
|
const OUString* pNames = aElementNames.getConstArray();
|
|
OUString aLibDirPath = createAppLibraryFolder( pImplLib, Name );
|
|
try
|
|
{
|
|
for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
|
|
{
|
|
OUString aElementName = pNames[ i ];
|
|
|
|
INetURLObject aElementInetObj( aLibDirPath );
|
|
aElementInetObj.insertName( aElementName, false,
|
|
INetURLObject::LAST_SEGMENT,
|
|
INetURLObject::EncodeMechanism::All );
|
|
if( bKillUnencryptedFiles )
|
|
{
|
|
aElementInetObj.setExtension( maLibElementFileExtension );
|
|
}
|
|
else
|
|
{
|
|
aElementInetObj.setExtension( u"pba" );
|
|
}
|
|
OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
|
|
|
|
if( mxSFI->exists( aElementPath ) )
|
|
{
|
|
mxSFI->kill( aElementPath );
|
|
}
|
|
}
|
|
}
|
|
catch(const Exception& ) {}
|
|
}
|
|
|
|
|
|
static void setStreamKey( const uno::Reference< io::XStream >& xStream, const OUString& aPass )
|
|
{
|
|
uno::Reference< embed::XEncryptionProtectedSource > xEncrStream( xStream, uno::UNO_QUERY );
|
|
if ( xEncrStream.is() )
|
|
{
|
|
xEncrStream->setEncryptionPassword( aPass );
|
|
}
|
|
}
|
|
|
|
|
|
// Impl methods
|
|
bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib,
|
|
const OUString& aName,
|
|
const uno::Reference< embed::XStorage >& xStorage,
|
|
const css::uno::Reference< css::task::XInteractionHandler >& xHandler )
|
|
{
|
|
Reference< XSimpleFileAccess3 > xDummySFA;
|
|
return implStorePasswordLibrary( pLib, aName, xStorage, OUString(), xDummySFA, xHandler );
|
|
}
|
|
|
|
bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, const OUString& aName,
|
|
const css::uno::Reference< css::embed::XStorage >& xStorage,
|
|
const OUString& aTargetURL,
|
|
const Reference< XSimpleFileAccess3 >& rToUseSFI,
|
|
const css::uno::Reference< css::task::XInteractionHandler >& xHandler )
|
|
{
|
|
bool bExport = !aTargetURL.isEmpty();
|
|
|
|
BasicManager* pBasicMgr = getBasicManager();
|
|
OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implStorePasswordLibrary: cannot do this without a BasicManager!" );
|
|
if ( !pBasicMgr )
|
|
{
|
|
return false;
|
|
}
|
|
// Only need to handle the export case here,
|
|
// save/saveas etc are handled in sfxbasemodel::storeSelf &
|
|
// sfxbasemodel::impl_store
|
|
std::vector<OUString> aNames;
|
|
if ( bExport && pBasicMgr->LegacyPsswdBinaryLimitExceeded(aNames) )
|
|
{
|
|
if ( xHandler.is() )
|
|
{
|
|
rtl::Reference<ModuleSizeExceeded> pReq = new ModuleSizeExceeded( aNames );
|
|
xHandler->handle( pReq );
|
|
if ( pReq->isAbort() )
|
|
{
|
|
throw util::VetoException();
|
|
}
|
|
}
|
|
}
|
|
|
|
StarBASIC* pBasicLib = pBasicMgr->GetLib( aName );
|
|
if( !pBasicLib )
|
|
{
|
|
return false;
|
|
}
|
|
Sequence< OUString > aElementNames = pLib->getElementNames();
|
|
sal_Int32 nNameCount = aElementNames.getLength();
|
|
const OUString* pNames = aElementNames.getConstArray();
|
|
|
|
bool bLink = pLib->mbLink;
|
|
bool bStorage = xStorage.is() && !bLink;
|
|
if( bStorage )
|
|
{
|
|
for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
|
|
{
|
|
OUString aElementName = pNames[ i ];
|
|
|
|
// Write binary image stream
|
|
SbModule* pMod = pBasicLib->FindModule( aElementName );
|
|
if( pMod )
|
|
{
|
|
OUString aCodeStreamName = aElementName + ".bin";
|
|
try
|
|
{
|
|
uno::Reference< io::XStream > xCodeStream = xStorage->openStreamElement(
|
|
aCodeStreamName,
|
|
embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
|
|
|
|
if ( !xCodeStream.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from openStreamElement");
|
|
}
|
|
SvMemoryStream aMemStream;
|
|
/*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream );
|
|
|
|
sal_Int32 const nSize = aMemStream.Tell();
|
|
if (nSize < 0) { abort(); }
|
|
Sequence< sal_Int8 > aBinSeq( nSize );
|
|
sal_Int8* pData = aBinSeq.getArray();
|
|
memcpy( pData, aMemStream.GetData(), nSize );
|
|
|
|
Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
|
|
if ( !xOut.is() )
|
|
{
|
|
throw io::IOException(); // access denied because the stream is readonly
|
|
}
|
|
xOut->writeBytes( aBinSeq );
|
|
xOut->closeOutput();
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
// TODO: handle error
|
|
}
|
|
}
|
|
|
|
if( pLib->mbPasswordVerified || pLib->mbDoc50Password )
|
|
{
|
|
if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
|
|
{
|
|
SAL_WARN( "basic", "invalid library element '" << aElementName << "'.");
|
|
continue;
|
|
}
|
|
|
|
OUString aSourceStreamName = aElementName + ".xml";
|
|
try
|
|
{
|
|
uno::Reference< io::XStream > xSourceStream = xStorage->openStreamElement(
|
|
aSourceStreamName,
|
|
embed::ElementModes::READWRITE );
|
|
uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY_THROW );
|
|
xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
|
|
|
|
// Set encryption key
|
|
setStreamKey( xSourceStream, pLib->maPassword );
|
|
|
|
Reference< XOutputStream > xOutput = xSourceStream->getOutputStream();
|
|
Reference< XNameContainer > xLib( pLib );
|
|
writeLibraryElement( xLib, aElementName, xOutput );
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
OSL_FAIL( "Problem on storing of password library!" );
|
|
// TODO: error handling
|
|
}
|
|
}
|
|
else // !mbPasswordVerified
|
|
{
|
|
// TODO
|
|
// What to do if not verified?! In any case it's already loaded here
|
|
}
|
|
}
|
|
|
|
}
|
|
// Application libraries have only to be saved if the password
|
|
// is verified because otherwise they can't be modified
|
|
else if( pLib->mbPasswordVerified || bExport )
|
|
{
|
|
try
|
|
{
|
|
Reference< XSimpleFileAccess3 > xSFI = mxSFI;
|
|
if( rToUseSFI.is() )
|
|
{
|
|
xSFI = rToUseSFI;
|
|
}
|
|
OUString aLibDirPath;
|
|
if( bExport )
|
|
{
|
|
INetURLObject aInetObj( aTargetURL );
|
|
aInetObj.insertName( aName, true, INetURLObject::LAST_SEGMENT,
|
|
INetURLObject::EncodeMechanism::All );
|
|
aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
|
|
|
if( !xSFI->isFolder( aLibDirPath ) )
|
|
{
|
|
xSFI->createFolder( aLibDirPath );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
aLibDirPath = createAppLibraryFolder( pLib, aName );
|
|
}
|
|
|
|
for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
|
|
{
|
|
OUString aElementName = pNames[ i ];
|
|
|
|
INetURLObject aElementInetObj( aLibDirPath );
|
|
aElementInetObj.insertName( aElementName, false,
|
|
INetURLObject::LAST_SEGMENT,
|
|
INetURLObject::EncodeMechanism::All );
|
|
aElementInetObj.setExtension( u"pba" );
|
|
OUString aElementPath = aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
|
|
|
if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
|
|
{
|
|
SAL_WARN( "basic", "invalid library element '" << aElementName << "'.");
|
|
continue;
|
|
}
|
|
|
|
try
|
|
{
|
|
uno::Reference< embed::XStorage > xElementRootStorage =
|
|
::comphelper::OStorageHelper::GetStorageFromURL(
|
|
aElementPath,
|
|
embed::ElementModes::READWRITE );
|
|
if ( !xElementRootStorage.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from GetStorageFromURL");
|
|
}
|
|
// Write binary image stream
|
|
SbModule* pMod = pBasicLib->FindModule( aElementName );
|
|
if( pMod )
|
|
{
|
|
uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
|
|
"code.bin",
|
|
embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
|
|
|
|
SvMemoryStream aMemStream;
|
|
/*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream );
|
|
|
|
sal_Int32 const nSize = aMemStream.Tell();
|
|
if (nSize < 0) { abort(); }
|
|
Sequence< sal_Int8 > aBinSeq( nSize );
|
|
sal_Int8* pData = aBinSeq.getArray();
|
|
memcpy( pData, aMemStream.GetData(), nSize );
|
|
|
|
Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
|
|
if ( xOut.is() )
|
|
{
|
|
xOut->writeBytes( aBinSeq );
|
|
xOut->closeOutput();
|
|
}
|
|
}
|
|
|
|
// Write encrypted source stream
|
|
OUString aSourceStreamName( "source.xml" );
|
|
|
|
uno::Reference< io::XStream > xSourceStream;
|
|
try
|
|
{
|
|
xSourceStream = xElementRootStorage->openStreamElement(
|
|
aSourceStreamName,
|
|
embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
|
|
|
|
// #87671 Allow encryption
|
|
uno::Reference< embed::XEncryptionProtectedSource > xEncr( xSourceStream, uno::UNO_QUERY_THROW );
|
|
xEncr->setEncryptionPassword( pLib->maPassword );
|
|
}
|
|
catch(const css::packages::WrongPasswordException& )
|
|
{
|
|
xSourceStream = xElementRootStorage->openEncryptedStreamElement(
|
|
aSourceStreamName,
|
|
embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE,
|
|
pLib->maPassword );
|
|
}
|
|
|
|
uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY_THROW );
|
|
xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
|
|
|
|
Reference< XOutputStream > xOut = xSourceStream->getOutputStream();
|
|
Reference< XNameContainer > xLib( pLib );
|
|
writeLibraryElement( xLib, aElementName, xOut );
|
|
// i50568: sax writer already closes stream
|
|
// xOut->closeOutput();
|
|
|
|
uno::Reference< embed::XTransactedObject > xTransact( xElementRootStorage, uno::UNO_QUERY_THROW );
|
|
xTransact->commit();
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
// TODO: handle error
|
|
}
|
|
|
|
}
|
|
}
|
|
catch(const Exception& )
|
|
{
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool SfxScriptLibraryContainer::implLoadPasswordLibrary
|
|
( SfxLibrary* pLib, const OUString& Name, bool bVerifyPasswordOnly )
|
|
{
|
|
bool bRet = true;
|
|
|
|
bool bLink = pLib->mbLink;
|
|
bool bStorage = mxStorage.is() && !bLink;
|
|
|
|
// Already loaded? Then only verifiedPassword can change something
|
|
SfxScriptLibrary* pScriptLib = static_cast< SfxScriptLibrary* >( pLib );
|
|
if( pScriptLib->mbLoaded )
|
|
{
|
|
if( pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly &&
|
|
(pScriptLib->mbLoadedSource || !pLib->mbPasswordVerified) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
StarBASIC* pBasicLib = nullptr;
|
|
bool bLoadBinary = false;
|
|
if( !pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly && !pLib->mbPasswordVerified )
|
|
{
|
|
BasicManager* pBasicMgr = getBasicManager();
|
|
OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implLoadPasswordLibrary: cannot do this without a BasicManager!" );
|
|
bool bLoaded = pScriptLib->mbLoaded;
|
|
pScriptLib->mbLoaded = true; // Necessary to get lib
|
|
pBasicLib = pBasicMgr ? pBasicMgr->GetLib( Name ) : nullptr;
|
|
pScriptLib->mbLoaded = bLoaded; // Restore flag
|
|
if( !pBasicLib )
|
|
{
|
|
return false;
|
|
}
|
|
bLoadBinary = true;
|
|
pScriptLib->mbLoadedBinary = true;
|
|
}
|
|
|
|
bool bLoadSource = false;
|
|
if( !pScriptLib->mbLoadedSource && pLib->mbPasswordVerified && !bVerifyPasswordOnly )
|
|
{
|
|
bLoadSource = true;
|
|
pScriptLib->mbLoadedSource = true;
|
|
}
|
|
|
|
Sequence< OUString > aElementNames = pLib->getElementNames();
|
|
sal_Int32 nNameCount = aElementNames.getLength();
|
|
const OUString* pNames = aElementNames.getConstArray();
|
|
|
|
if( bStorage )
|
|
{
|
|
uno::Reference< embed::XStorage > xLibrariesStor;
|
|
uno::Reference< embed::XStorage > xLibraryStor;
|
|
try {
|
|
xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
|
|
if ( !xLibrariesStor.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from openStorageElement");
|
|
}
|
|
xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
|
|
if ( !xLibraryStor.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from openStorageElement");
|
|
}
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
OSL_FAIL( "### couldn't open sub storage for library" );
|
|
return false;
|
|
}
|
|
|
|
for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
|
|
{
|
|
OUString aElementName = pNames[ i ];
|
|
|
|
// Load binary
|
|
if( bLoadBinary )
|
|
{
|
|
SbModule* pMod = pBasicLib->FindModule( aElementName );
|
|
if( !pMod )
|
|
{
|
|
pMod = pBasicLib->MakeModule( aElementName, OUString() );
|
|
pBasicLib->SetModified( false );
|
|
}
|
|
|
|
OUString aCodeStreamName= aElementName + ".bin";
|
|
try
|
|
{
|
|
uno::Reference< io::XStream > xCodeStream = xLibraryStor->openStreamElement(
|
|
aCodeStreamName,
|
|
embed::ElementModes::READ );
|
|
if ( !xCodeStream.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from openStreamElement");
|
|
}
|
|
std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( xCodeStream ));
|
|
if ( !pStream || pStream->GetError() )
|
|
{
|
|
sal_uInt32 nError = sal_uInt32(pStream ? pStream->GetError() : ERRCODE_IO_GENERAL);
|
|
throw task::ErrorCodeIOException(
|
|
("utl::UcbStreamHelper::CreateStream failed for \""
|
|
+ aCodeStreamName + "\": 0x"
|
|
+ OUString::number(nError, 16)),
|
|
uno::Reference< uno::XInterface >(), nError);
|
|
}
|
|
|
|
/*sal_Bool bRet = */pMod->LoadBinaryData( *pStream );
|
|
// TODO: Check return value
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
// TODO: error handling
|
|
}
|
|
}
|
|
|
|
// Load source
|
|
if( bLoadSource || bVerifyPasswordOnly )
|
|
{
|
|
// Access encrypted source stream
|
|
OUString aSourceStreamName = aElementName + ".xml";
|
|
try
|
|
{
|
|
uno::Reference< io::XStream > xSourceStream = xLibraryStor->openEncryptedStreamElement(
|
|
aSourceStreamName,
|
|
embed::ElementModes::READ,
|
|
pLib->maPassword );
|
|
if ( !xSourceStream.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from openEncryptedStreamElement");
|
|
}
|
|
// if this point is reached then the password is correct
|
|
if ( !bVerifyPasswordOnly )
|
|
{
|
|
uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
|
|
if ( !xInStream.is() )
|
|
{
|
|
throw io::IOException(); // read access denied, seems to be impossible
|
|
}
|
|
Reference< XNameContainer > xLib( pLib );
|
|
Any aAny = importLibraryElement( xLib,
|
|
aElementName, aSourceStreamName,
|
|
xInStream );
|
|
if( pLib->hasByName( aElementName ) )
|
|
{
|
|
if( aAny.hasValue() )
|
|
{
|
|
pLib->maNameContainer->replaceByName( aElementName, aAny );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pLib->maNameContainer->insertByName( aElementName, aAny );
|
|
}
|
|
}
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
bRet = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
OUString aLibDirPath = createAppLibraryFolder( pLib, Name );
|
|
|
|
for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
|
|
{
|
|
OUString aElementName = pNames[ i ];
|
|
|
|
INetURLObject aElementInetObj( aLibDirPath );
|
|
aElementInetObj.insertName( aElementName, false,
|
|
INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
|
|
aElementInetObj.setExtension( u"pba" );
|
|
OUString aElementPath = aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
|
|
|
uno::Reference< embed::XStorage > xElementRootStorage;
|
|
try
|
|
{
|
|
xElementRootStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
|
|
aElementPath,
|
|
embed::ElementModes::READ );
|
|
} catch(const uno::Exception& )
|
|
{
|
|
// TODO: error handling
|
|
}
|
|
|
|
if ( xElementRootStorage.is() )
|
|
{
|
|
// Load binary
|
|
if( bLoadBinary )
|
|
{
|
|
SbModule* pMod = pBasicLib->FindModule( aElementName );
|
|
if( !pMod )
|
|
{
|
|
pMod = pBasicLib->MakeModule( aElementName, OUString() );
|
|
pBasicLib->SetModified( false );
|
|
}
|
|
|
|
try
|
|
{
|
|
uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
|
|
"code.bin",
|
|
embed::ElementModes::READ );
|
|
|
|
std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( xCodeStream ));
|
|
if ( !pStream || pStream->GetError() )
|
|
{
|
|
sal_uInt32 nError = sal_uInt32(pStream ? pStream->GetError() : ERRCODE_IO_GENERAL);
|
|
throw task::ErrorCodeIOException(
|
|
("utl::UcbStreamHelper::CreateStream failed"
|
|
" for code.bin: 0x"
|
|
+ OUString::number(nError, 16)),
|
|
uno::Reference< uno::XInterface >(),
|
|
nError);
|
|
}
|
|
|
|
/*sal_Bool bRet = */pMod->LoadBinaryData( *pStream );
|
|
// TODO: Check return value
|
|
}
|
|
catch(const uno::Exception& )
|
|
{
|
|
// TODO: error handling
|
|
}
|
|
}
|
|
|
|
// Load source
|
|
if( bLoadSource || bVerifyPasswordOnly )
|
|
{
|
|
// Access encrypted source stream
|
|
try
|
|
{
|
|
OUString aSourceStreamName( "source.xml" );
|
|
uno::Reference< io::XStream > xSourceStream = xElementRootStorage->openEncryptedStreamElement(
|
|
aSourceStreamName,
|
|
embed::ElementModes::READ,
|
|
pLib->maPassword );
|
|
if ( !xSourceStream.is() )
|
|
{
|
|
throw uno::RuntimeException("null returned from openEncryptedStreamElement");
|
|
}
|
|
if ( !bVerifyPasswordOnly )
|
|
{
|
|
uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
|
|
if ( !xInStream.is() )
|
|
{
|
|
throw io::IOException(); // read access denied, seems to be impossible
|
|
}
|
|
Reference< XNameContainer > xLib( pLib );
|
|
Any aAny = importLibraryElement( xLib,
|
|
aElementName,
|
|
aSourceStreamName,
|
|
xInStream );
|
|
if( pLib->hasByName( aElementName ) )
|
|
{
|
|
if( aAny.hasValue() )
|
|
{
|
|
pLib->maNameContainer->replaceByName( aElementName, aAny );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pLib->maNameContainer->insertByName( aElementName, aAny );
|
|
}
|
|
}
|
|
}
|
|
catch (const uno::Exception& )
|
|
{
|
|
bRet = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch(const Exception& )
|
|
{
|
|
// TODO
|
|
//throw e;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
void SfxScriptLibraryContainer::onNewRootStorage()
|
|
{
|
|
}
|
|
|
|
sal_Bool SAL_CALL SfxScriptLibraryContainer:: HasExecutableCode( const OUString& Library )
|
|
{
|
|
BasicManager* pBasicMgr = getBasicManager();
|
|
OSL_ENSURE( pBasicMgr, "we need a basicmanager, really we do" );
|
|
if ( pBasicMgr )
|
|
{
|
|
return pBasicMgr->HasExeCode( Library ); // need to change this to take name
|
|
}
|
|
// default to it has code if we can't decide
|
|
return true;
|
|
}
|
|
|
|
|
|
// Service
|
|
OUString SAL_CALL SfxScriptLibraryContainer::getImplementationName( )
|
|
{
|
|
return "com.sun.star.comp.sfx2.ScriptLibraryContainer";
|
|
}
|
|
|
|
Sequence< OUString > SAL_CALL SfxScriptLibraryContainer::getSupportedServiceNames( )
|
|
{
|
|
return {"com.sun.star.script.DocumentScriptLibraryContainer",
|
|
"com.sun.star.script.ScriptLibraryContainer"}; // for compatibility
|
|
}
|
|
|
|
// Implementation class SfxScriptLibrary
|
|
|
|
// Ctor
|
|
SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
|
|
const Reference< XSimpleFileAccess3 >& xSFI )
|
|
: SfxLibrary( _rModifiable, cppu::UnoType<OUString>::get(), xSFI )
|
|
, mbLoadedSource( false )
|
|
, mbLoadedBinary( false )
|
|
{
|
|
}
|
|
|
|
SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
|
|
const Reference< XSimpleFileAccess3 >& xSFI,
|
|
const OUString& aLibInfoFileURL,
|
|
const OUString& aStorageURL,
|
|
bool ReadOnly )
|
|
: SfxLibrary( _rModifiable, cppu::UnoType<OUString>::get(), xSFI,
|
|
aLibInfoFileURL, aStorageURL, ReadOnly)
|
|
, mbLoadedSource( false )
|
|
, mbLoadedBinary( false )
|
|
{
|
|
}
|
|
|
|
bool SfxScriptLibrary::isLoadedStorable()
|
|
{
|
|
// note: mbLoadedSource can only be true for password-protected lib!
|
|
return SfxLibrary::isLoadedStorable() && (!mbPasswordProtected || mbLoadedSource);
|
|
}
|
|
|
|
// Provide modify state including resources
|
|
bool SfxScriptLibrary::isModified()
|
|
{
|
|
return implIsModified(); // No resources
|
|
}
|
|
|
|
void SfxScriptLibrary::storeResources()
|
|
{
|
|
// No resources
|
|
}
|
|
|
|
void SfxScriptLibrary::storeResourcesToURL( const OUString&,
|
|
const Reference< task::XInteractionHandler >& )
|
|
{}
|
|
|
|
void SfxScriptLibrary::storeResourcesAsURL
|
|
( const OUString&, const OUString& )
|
|
{}
|
|
|
|
void SfxScriptLibrary::storeResourcesToStorage( const css::uno::Reference
|
|
< css::embed::XStorage >& )
|
|
{
|
|
// No resources
|
|
}
|
|
|
|
bool SfxScriptLibrary::containsValidModule(const Any& rElement)
|
|
{
|
|
OUString sModuleText;
|
|
rElement >>= sModuleText;
|
|
return ( !sModuleText.isEmpty() );
|
|
}
|
|
|
|
bool SfxScriptLibrary::isLibraryElementValid(const css::uno::Any& rElement) const
|
|
{
|
|
return SfxScriptLibrary::containsValidModule(rElement);
|
|
}
|
|
|
|
IMPLEMENT_FORWARD_XINTERFACE2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE );
|
|
IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE );
|
|
|
|
script::ModuleInfo SAL_CALL SfxScriptLibrary::getModuleInfo( const OUString& ModuleName )
|
|
{
|
|
if ( !hasModuleInfo( ModuleName ) )
|
|
{
|
|
throw NoSuchElementException();
|
|
}
|
|
return mModuleInfo[ ModuleName ];
|
|
}
|
|
|
|
sal_Bool SAL_CALL SfxScriptLibrary::hasModuleInfo( const OUString& ModuleName )
|
|
{
|
|
bool bRes = false;
|
|
ModuleInfoMap::iterator it = mModuleInfo.find( ModuleName );
|
|
|
|
if ( it != mModuleInfo.end() )
|
|
{
|
|
bRes = true;
|
|
}
|
|
return bRes;
|
|
}
|
|
|
|
void SAL_CALL SfxScriptLibrary::insertModuleInfo( const OUString& ModuleName, const script::ModuleInfo& ModuleInfo )
|
|
{
|
|
if ( hasModuleInfo( ModuleName ) )
|
|
{
|
|
throw ElementExistException();
|
|
}
|
|
mModuleInfo[ ModuleName ] = ModuleInfo;
|
|
}
|
|
|
|
void SAL_CALL SfxScriptLibrary::removeModuleInfo( const OUString& ModuleName )
|
|
{
|
|
// #FIXME add NoSuchElementException to the spec
|
|
if ( mModuleInfo.erase( ModuleName ) == 0 )
|
|
throw NoSuchElementException();
|
|
}
|
|
|
|
} // namespace basic
|
|
|
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
|
|
com_sun_star_comp_sfx2_ScriptLibraryContainer_get_implementation(css::uno::XComponentContext*,
|
|
css::uno::Sequence<css::uno::Any> const &)
|
|
{
|
|
return cppu::acquire(new basic::SfxScriptLibraryContainer());
|
|
}
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|