1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_package.hxx" 30*cdf0e10cSrcweir #include <ZipPackageFolder.hxx> 31*cdf0e10cSrcweir #include <ZipFile.hxx> 32*cdf0e10cSrcweir #include <ZipOutputStream.hxx> 33*cdf0e10cSrcweir #include <ZipPackageStream.hxx> 34*cdf0e10cSrcweir #include <PackageConstants.hxx> 35*cdf0e10cSrcweir #include <ZipPackageFolderEnumeration.hxx> 36*cdf0e10cSrcweir #include <com/sun/star/packages/zip/ZipConstants.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/embed/StorageFormats.hpp> 38*cdf0e10cSrcweir #include <vos/diagnose.hxx> 39*cdf0e10cSrcweir #include <osl/time.h> 40*cdf0e10cSrcweir #include <rtl/digest.h> 41*cdf0e10cSrcweir #include <ContentInfo.hxx> 42*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp> 44*cdf0e10cSrcweir #include <EncryptedDataHeader.hxx> 45*cdf0e10cSrcweir #include <rtl/random.h> 46*cdf0e10cSrcweir #include <rtl/instance.hxx> 47*cdf0e10cSrcweir #include <memory> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir using namespace com::sun::star; 50*cdf0e10cSrcweir using namespace com::sun::star::packages::zip::ZipConstants; 51*cdf0e10cSrcweir using namespace com::sun::star::packages::zip; 52*cdf0e10cSrcweir using namespace com::sun::star::packages; 53*cdf0e10cSrcweir using namespace com::sun::star::container; 54*cdf0e10cSrcweir using namespace com::sun::star::beans; 55*cdf0e10cSrcweir using namespace com::sun::star::lang; 56*cdf0e10cSrcweir using namespace com::sun::star::io; 57*cdf0e10cSrcweir using namespace cppu; 58*cdf0e10cSrcweir using namespace std; 59*cdf0e10cSrcweir using namespace ::com::sun::star; 60*cdf0e10cSrcweir using vos::ORef; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir namespace { struct lcl_CachedImplId : public rtl::Static< uno::Sequence < sal_Int8 >, lcl_CachedImplId > {}; } 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir ZipPackageFolder::ZipPackageFolder ( const uno::Reference< XMultiServiceFactory >& xFactory, 65*cdf0e10cSrcweir sal_Int32 nFormat, 66*cdf0e10cSrcweir sal_Bool bAllowRemoveOnInsert ) 67*cdf0e10cSrcweir : m_xFactory( xFactory ) 68*cdf0e10cSrcweir , m_nFormat( nFormat ) 69*cdf0e10cSrcweir { 70*cdf0e10cSrcweir OSL_ENSURE( m_xFactory.is(), "No factory is provided to the package folder!" ); 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir SetFolder ( sal_True ); 75*cdf0e10cSrcweir aEntry.nVersion = -1; 76*cdf0e10cSrcweir aEntry.nFlag = 0; 77*cdf0e10cSrcweir aEntry.nMethod = STORED; 78*cdf0e10cSrcweir aEntry.nTime = -1; 79*cdf0e10cSrcweir aEntry.nCrc = 0; 80*cdf0e10cSrcweir aEntry.nCompressedSize = 0; 81*cdf0e10cSrcweir aEntry.nSize = 0; 82*cdf0e10cSrcweir aEntry.nOffset = -1; 83*cdf0e10cSrcweir uno::Sequence < sal_Int8 > &rCachedImplId = lcl_CachedImplId::get(); 84*cdf0e10cSrcweir if ( !rCachedImplId.getLength() ) 85*cdf0e10cSrcweir rCachedImplId = getImplementationId(); 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir ZipPackageFolder::~ZipPackageFolder() 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir sal_Bool ZipPackageFolder::LookForUnexpectedODF12Streams( const ::rtl::OUString& aPath ) 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir sal_Bool bHasUnexpected = sal_False; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end(); 98*cdf0e10cSrcweir !bHasUnexpected && aCI != aEnd; 99*cdf0e10cSrcweir aCI++) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir const ::rtl::OUString &rShortName = (*aCI).first; 102*cdf0e10cSrcweir const ContentInfo &rInfo = *(*aCI).second; 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir if ( rInfo.bFolder ) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir if ( aPath.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF/" ) ) ) ) 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir // META-INF is not allowed to contain subfolders 109*cdf0e10cSrcweir bHasUnexpected = sal_True; 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir else 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir ::rtl::OUString sOwnPath = aPath + rShortName + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) ); 114*cdf0e10cSrcweir bHasUnexpected = rInfo.pFolder->LookForUnexpectedODF12Streams( sOwnPath ); 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir } 117*cdf0e10cSrcweir else 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir if ( aPath.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF/" ) ) ) ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir if ( !rShortName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "manifest.xml" ) ) ) 122*cdf0e10cSrcweir && rShortName.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "signatures" ) ) ) == -1 ) 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir // a stream from META-INF with unexpected name 125*cdf0e10cSrcweir bHasUnexpected = sal_True; 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir // streams from META-INF with expected names are allowed not to be registered in manifest.xml 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir else if ( !rInfo.pStream->IsFromManifest() ) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir // the stream is not in META-INF and ist notregistered in manifest.xml, 133*cdf0e10cSrcweir // check whether it is an internal part of the package format 134*cdf0e10cSrcweir if ( aPath.getLength() 135*cdf0e10cSrcweir || !rShortName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "mimetype" ) ) ) ) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir // if it is not "mimetype" from the root it is not a part of the package 138*cdf0e10cSrcweir bHasUnexpected = sal_True; 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir return bHasUnexpected; 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir void ZipPackageFolder::setChildStreamsTypeByExtension( const beans::StringPair& aPair ) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir ::rtl::OUString aExt; 150*cdf0e10cSrcweir if ( aPair.First.toChar() == (sal_Unicode)'.' ) 151*cdf0e10cSrcweir aExt = aPair.First; 152*cdf0e10cSrcweir else 153*cdf0e10cSrcweir aExt = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) + aPair.First; 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end(); 156*cdf0e10cSrcweir aCI != aEnd; 157*cdf0e10cSrcweir aCI++) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir const ::rtl::OUString &rShortName = (*aCI).first; 160*cdf0e10cSrcweir const ContentInfo &rInfo = *(*aCI).second; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir if ( rInfo.bFolder ) 163*cdf0e10cSrcweir rInfo.pFolder->setChildStreamsTypeByExtension( aPair ); 164*cdf0e10cSrcweir else 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir sal_Int32 nPathLength = rShortName.getLength(); 167*cdf0e10cSrcweir sal_Int32 nExtLength = aExt.getLength(); 168*cdf0e10cSrcweir if ( nPathLength >= nExtLength && rShortName.match( aExt, nPathLength - nExtLength ) ) 169*cdf0e10cSrcweir rInfo.pStream->SetMediaType( aPair.Second ); 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir void ZipPackageFolder::copyZipEntry( ZipEntry &rDest, const ZipEntry &rSource) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir rDest.nVersion = rSource.nVersion; 177*cdf0e10cSrcweir rDest.nFlag = rSource.nFlag; 178*cdf0e10cSrcweir rDest.nMethod = rSource.nMethod; 179*cdf0e10cSrcweir rDest.nTime = rSource.nTime; 180*cdf0e10cSrcweir rDest.nCrc = rSource.nCrc; 181*cdf0e10cSrcweir rDest.nCompressedSize = rSource.nCompressedSize; 182*cdf0e10cSrcweir rDest.nSize = rSource.nSize; 183*cdf0e10cSrcweir rDest.nOffset = rSource.nOffset; 184*cdf0e10cSrcweir rDest.sPath = rSource.sPath; 185*cdf0e10cSrcweir rDest.nPathLen = rSource.nPathLen; 186*cdf0e10cSrcweir rDest.nExtraLen = rSource.nExtraLen; 187*cdf0e10cSrcweir } 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence < sal_Int8 >& ZipPackageFolder::static_getImplementationId() 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir return lcl_CachedImplId::get(); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir // XNameContainer 195*cdf0e10cSrcweir void SAL_CALL ZipPackageFolder::insertByName( const ::rtl::OUString& aName, const uno::Any& aElement ) 196*cdf0e10cSrcweir throw(IllegalArgumentException, ElementExistException, WrappedTargetException, uno::RuntimeException) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir if (hasByName(aName)) 199*cdf0e10cSrcweir throw ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 200*cdf0e10cSrcweir else 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir uno::Reference < XUnoTunnel > xRef; 203*cdf0e10cSrcweir aElement >>= xRef; 204*cdf0e10cSrcweir if ( ( aElement >>= xRef ) ) 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir sal_Int64 nTest; 207*cdf0e10cSrcweir ZipPackageEntry *pEntry; 208*cdf0e10cSrcweir if ( ( nTest = xRef->getSomething ( ZipPackageFolder::static_getImplementationId() ) ) != 0 ) 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir ZipPackageFolder *pFolder = reinterpret_cast < ZipPackageFolder * > ( nTest ); 211*cdf0e10cSrcweir pEntry = static_cast < ZipPackageEntry * > ( pFolder ); 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir else if ( ( nTest = xRef->getSomething ( ZipPackageStream::static_getImplementationId() ) ) != 0 ) 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir ZipPackageStream *pStream = reinterpret_cast < ZipPackageStream * > ( nTest ); 216*cdf0e10cSrcweir pEntry = static_cast < ZipPackageEntry * > ( pStream ); 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir else 219*cdf0e10cSrcweir throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir if (pEntry->getName() != aName ) 222*cdf0e10cSrcweir pEntry->setName (aName); 223*cdf0e10cSrcweir doInsertByName ( pEntry, sal_True ); 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir else 226*cdf0e10cSrcweir throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); 227*cdf0e10cSrcweir } 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir void SAL_CALL ZipPackageFolder::removeByName( const ::rtl::OUString& Name ) 230*cdf0e10cSrcweir throw(NoSuchElementException, WrappedTargetException, uno::RuntimeException) 231*cdf0e10cSrcweir { 232*cdf0e10cSrcweir ContentHash::iterator aIter = maContents.find ( Name ); 233*cdf0e10cSrcweir if ( aIter == maContents.end() ) 234*cdf0e10cSrcweir throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 235*cdf0e10cSrcweir maContents.erase( aIter ); 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir // XEnumerationAccess 238*cdf0e10cSrcweir uno::Reference< XEnumeration > SAL_CALL ZipPackageFolder::createEnumeration( ) 239*cdf0e10cSrcweir throw(uno::RuntimeException) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir return uno::Reference < XEnumeration> (new ZipPackageFolderEnumeration(maContents)); 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir // XElementAccess 244*cdf0e10cSrcweir uno::Type SAL_CALL ZipPackageFolder::getElementType( ) 245*cdf0e10cSrcweir throw(uno::RuntimeException) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir return ::getCppuType ((const uno::Reference< XUnoTunnel > *) 0); 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir sal_Bool SAL_CALL ZipPackageFolder::hasElements( ) 250*cdf0e10cSrcweir throw(uno::RuntimeException) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir return maContents.size() > 0; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir // XNameAccess 255*cdf0e10cSrcweir ContentInfo& ZipPackageFolder::doGetByName( const ::rtl::OUString& aName ) 256*cdf0e10cSrcweir throw(NoSuchElementException, WrappedTargetException, uno::RuntimeException) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir ContentHash::iterator aIter = maContents.find ( aName ); 259*cdf0e10cSrcweir if ( aIter == maContents.end()) 260*cdf0e10cSrcweir throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 261*cdf0e10cSrcweir return *(*aIter).second; 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir uno::Any SAL_CALL ZipPackageFolder::getByName( const ::rtl::OUString& aName ) 264*cdf0e10cSrcweir throw(NoSuchElementException, WrappedTargetException, uno::RuntimeException) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir return uno::makeAny ( doGetByName ( aName ).xTunnel ); 267*cdf0e10cSrcweir } 268*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > SAL_CALL ZipPackageFolder::getElementNames( ) 269*cdf0e10cSrcweir throw(uno::RuntimeException) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir sal_uInt32 i=0, nSize = maContents.size(); 272*cdf0e10cSrcweir uno::Sequence < ::rtl::OUString > aSequence ( nSize ); 273*cdf0e10cSrcweir for ( ContentHash::const_iterator aIterator = maContents.begin(), aEnd = maContents.end(); 274*cdf0e10cSrcweir aIterator != aEnd; 275*cdf0e10cSrcweir ++i, ++aIterator) 276*cdf0e10cSrcweir aSequence[i] = (*aIterator).first; 277*cdf0e10cSrcweir return aSequence; 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir sal_Bool SAL_CALL ZipPackageFolder::hasByName( const ::rtl::OUString& aName ) 280*cdf0e10cSrcweir throw(uno::RuntimeException) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir return maContents.find ( aName ) != maContents.end (); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir // XNameReplace 285*cdf0e10cSrcweir void SAL_CALL ZipPackageFolder::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement ) 286*cdf0e10cSrcweir throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, uno::RuntimeException) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir if ( hasByName( aName ) ) 289*cdf0e10cSrcweir removeByName( aName ); 290*cdf0e10cSrcweir else 291*cdf0e10cSrcweir throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 292*cdf0e10cSrcweir insertByName(aName, aElement); 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir static void ImplSetStoredData( ZipEntry & rEntry, uno::Reference< XInputStream> & rStream ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir // It's very annoying that we have to do this, but lots of zip packages 298*cdf0e10cSrcweir // don't allow data descriptors for STORED streams, meaning we have to 299*cdf0e10cSrcweir // know the size and CRC32 of uncompressed streams before we actually 300*cdf0e10cSrcweir // write them ! 301*cdf0e10cSrcweir CRC32 aCRC32; 302*cdf0e10cSrcweir rEntry.nMethod = STORED; 303*cdf0e10cSrcweir rEntry.nCompressedSize = rEntry.nSize = aCRC32.updateStream ( rStream ); 304*cdf0e10cSrcweir rEntry.nCrc = aCRC32.getValue(); 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir bool ZipPackageFolder::saveChild( const ::rtl::OUString &rShortName, const ContentInfo &rInfo, ::rtl::OUString &rPath, std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir bool bSuccess = true; 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir const ::rtl::OUString sMediaTypeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) ); 312*cdf0e10cSrcweir const ::rtl::OUString sVersionProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Version" ) ); 313*cdf0e10cSrcweir const ::rtl::OUString sFullPathProperty ( RTL_CONSTASCII_USTRINGPARAM ( "FullPath" ) ); 314*cdf0e10cSrcweir const ::rtl::OUString sInitialisationVectorProperty ( RTL_CONSTASCII_USTRINGPARAM ( "InitialisationVector" ) ); 315*cdf0e10cSrcweir const ::rtl::OUString sSaltProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Salt" ) ); 316*cdf0e10cSrcweir const ::rtl::OUString sIterationCountProperty ( RTL_CONSTASCII_USTRINGPARAM ( "IterationCount" ) ); 317*cdf0e10cSrcweir const ::rtl::OUString sSizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Size" ) ); 318*cdf0e10cSrcweir const ::rtl::OUString sDigestProperty ( RTL_CONSTASCII_USTRINGPARAM ( "Digest" ) ); 319*cdf0e10cSrcweir const ::rtl::OUString sEncryptionAlgProperty ( RTL_CONSTASCII_USTRINGPARAM ( "EncryptionAlgorithm" ) ); 320*cdf0e10cSrcweir const ::rtl::OUString sStartKeyAlgProperty ( RTL_CONSTASCII_USTRINGPARAM ( "StartKeyAlgorithm" ) ); 321*cdf0e10cSrcweir const ::rtl::OUString sDigestAlgProperty ( RTL_CONSTASCII_USTRINGPARAM ( "DigestAlgorithm" ) ); 322*cdf0e10cSrcweir const ::rtl::OUString sDerivedKeySizeProperty ( RTL_CONSTASCII_USTRINGPARAM ( "DerivedKeySize" ) ); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir uno::Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST); 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir OSL_ENSURE( ( rInfo.bFolder && rInfo.pFolder ) || ( !rInfo.bFolder && rInfo.pStream ), "A valid child object is expected!" ); 327*cdf0e10cSrcweir if ( rInfo.bFolder ) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir ::rtl::OUString sTempName = rPath + rShortName + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) ); 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir if ( rInfo.pFolder->GetMediaType().getLength() ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty; 334*cdf0e10cSrcweir aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pFolder->GetMediaType(); 335*cdf0e10cSrcweir aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty; 336*cdf0e10cSrcweir aPropSet[PKG_MNFST_VERSION].Value <<= rInfo.pFolder->GetVersion(); 337*cdf0e10cSrcweir aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty; 338*cdf0e10cSrcweir aPropSet[PKG_MNFST_FULLPATH].Value <<= sTempName; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir else 341*cdf0e10cSrcweir aPropSet.realloc( 0 ); 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir rInfo.pFolder->saveContents( sTempName, rManList, rZipOut, rEncryptionKey, rRandomPool); 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir else 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream 348*cdf0e10cSrcweir // and be deleted in the ZipOutputStream destructor 349*cdf0e10cSrcweir auto_ptr < ZipEntry > pAutoTempEntry ( new ZipEntry ); 350*cdf0e10cSrcweir ZipEntry* pTempEntry = pAutoTempEntry.get(); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir // In case the entry we are reading is also the entry we are writing, we will 353*cdf0e10cSrcweir // store the ZipEntry data in pTempEntry 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir ZipPackageFolder::copyZipEntry ( *pTempEntry, rInfo.pStream->aEntry ); 356*cdf0e10cSrcweir pTempEntry->sPath = rPath + rShortName; 357*cdf0e10cSrcweir pTempEntry->nPathLen = (sal_Int16)( ::rtl::OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() ); 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir sal_Bool bToBeEncrypted = rInfo.pStream->IsToBeEncrypted() && (rEncryptionKey.getLength() || rInfo.pStream->HasOwnKey()); 360*cdf0e10cSrcweir sal_Bool bToBeCompressed = bToBeEncrypted ? sal_True : rInfo.pStream->IsToBeCompressed(); 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty; 363*cdf0e10cSrcweir aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pStream->GetMediaType( ); 364*cdf0e10cSrcweir aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty; 365*cdf0e10cSrcweir aPropSet[PKG_MNFST_VERSION].Value <<= ::rtl::OUString(); // no version is stored for streams currently 366*cdf0e10cSrcweir aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty; 367*cdf0e10cSrcweir aPropSet[PKG_MNFST_FULLPATH].Value <<= pTempEntry->sPath; 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir OSL_ENSURE( rInfo.pStream->GetStreamMode() != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" ); 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir sal_Bool bRawStream = sal_False; 373*cdf0e10cSrcweir if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_DETECT ) 374*cdf0e10cSrcweir bRawStream = rInfo.pStream->ParsePackageRawStream(); 375*cdf0e10cSrcweir else if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_RAW ) 376*cdf0e10cSrcweir bRawStream = sal_True; 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir sal_Bool bTransportOwnEncrStreamAsRaw = sal_False; 379*cdf0e10cSrcweir // During the storing the original size of the stream can be changed 380*cdf0e10cSrcweir // TODO/LATER: get rid of this hack 381*cdf0e10cSrcweir sal_Int32 nOwnStreamOrigSize = bRawStream ? rInfo.pStream->GetMagicalHackSize() : rInfo.pStream->getSize(); 382*cdf0e10cSrcweir 383*cdf0e10cSrcweir sal_Bool bUseNonSeekableAccess = sal_False; 384*cdf0e10cSrcweir uno::Reference < XInputStream > xStream; 385*cdf0e10cSrcweir if ( !rInfo.pStream->IsPackageMember() && !bRawStream && !bToBeEncrypted && bToBeCompressed ) 386*cdf0e10cSrcweir { 387*cdf0e10cSrcweir // the stream is not a package member, not a raw stream, 388*cdf0e10cSrcweir // it should not be encrypted and it should be compressed, 389*cdf0e10cSrcweir // in this case nonseekable access can be used 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir xStream = rInfo.pStream->GetOwnStreamNoWrap(); 392*cdf0e10cSrcweir uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY ); 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir bUseNonSeekableAccess = ( xStream.is() && !xSeek.is() ); 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir if ( !bUseNonSeekableAccess ) 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir xStream = rInfo.pStream->getRawData(); 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir if ( !xStream.is() ) 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir VOS_ENSURE( 0, "ZipPackageStream didn't have a stream associated with it, skipping!" ); 404*cdf0e10cSrcweir bSuccess = false; 405*cdf0e10cSrcweir return bSuccess; 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY ); 409*cdf0e10cSrcweir try 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir if ( xSeek.is() ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir // If the stream is a raw one, then we should be positioned 414*cdf0e10cSrcweir // at the beginning of the actual data 415*cdf0e10cSrcweir if ( !bToBeCompressed || bRawStream ) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir // The raw stream can neither be encrypted nor connected 418*cdf0e10cSrcweir OSL_ENSURE( !bRawStream || !bToBeCompressed && !bToBeEncrypted, "The stream is already encrypted!\n" ); 419*cdf0e10cSrcweir xSeek->seek ( bRawStream ? rInfo.pStream->GetMagicalHackPos() : 0 ); 420*cdf0e10cSrcweir ImplSetStoredData ( *pTempEntry, xStream ); 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties! 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir else if ( bToBeEncrypted ) 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir // this is the correct original size 427*cdf0e10cSrcweir pTempEntry->nSize = static_cast < sal_Int32 > ( xSeek->getLength() ); 428*cdf0e10cSrcweir nOwnStreamOrigSize = pTempEntry->nSize; 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir xSeek->seek ( 0 ); 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir else 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir // Okay, we don't have an xSeekable stream. This is possibly bad. 436*cdf0e10cSrcweir // check if it's one of our own streams, if it is then we know that 437*cdf0e10cSrcweir // each time we ask for it we'll get a new stream that will be 438*cdf0e10cSrcweir // at position zero...otherwise, assert and skip this stream... 439*cdf0e10cSrcweir if ( rInfo.pStream->IsPackageMember() ) 440*cdf0e10cSrcweir { 441*cdf0e10cSrcweir // if the password has been changed than the stream should not be package member any more 442*cdf0e10cSrcweir if ( rInfo.pStream->IsEncrypted() && rInfo.pStream->IsToBeEncrypted() ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir // Should be handled close to the raw stream handling 445*cdf0e10cSrcweir bTransportOwnEncrStreamAsRaw = sal_True; 446*cdf0e10cSrcweir pTempEntry->nMethod = STORED; 447*cdf0e10cSrcweir 448*cdf0e10cSrcweir // TODO/LATER: get rid of this situation 449*cdf0e10cSrcweir // this size should be different from the one that will be stored in manifest.xml 450*cdf0e10cSrcweir // it is used in storing algorithms and after storing the correct size will be set 451*cdf0e10cSrcweir pTempEntry->nSize = pTempEntry->nCompressedSize; 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir else 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir bSuccess = false; 457*cdf0e10cSrcweir return bSuccess; 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir } 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir catch ( uno::Exception& ) 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir bSuccess = false; 464*cdf0e10cSrcweir return bSuccess; 465*cdf0e10cSrcweir } 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir if ( bToBeEncrypted || bRawStream || bTransportOwnEncrStreamAsRaw ) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw ) 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir uno::Sequence < sal_Int8 > aSalt( 16 ), aVector( rInfo.pStream->GetBlockSize() ); 472*cdf0e10cSrcweir rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 ); 473*cdf0e10cSrcweir rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() ); 474*cdf0e10cSrcweir sal_Int32 nIterationCount = 1024; 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir if ( !rInfo.pStream->HasOwnKey() ) 477*cdf0e10cSrcweir rInfo.pStream->setKey ( rEncryptionKey ); 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir rInfo.pStream->setInitialisationVector ( aVector ); 480*cdf0e10cSrcweir rInfo.pStream->setSalt ( aSalt ); 481*cdf0e10cSrcweir rInfo.pStream->setIterationCount ( nIterationCount ); 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir 484*cdf0e10cSrcweir // last property is digest, which is inserted later if we didn't have 485*cdf0e10cSrcweir // a magic header 486*cdf0e10cSrcweir aPropSet.realloc(PKG_SIZE_ENCR_MNFST); 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir aPropSet[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty; 489*cdf0e10cSrcweir aPropSet[PKG_MNFST_INIVECTOR].Value <<= rInfo.pStream->getInitialisationVector(); 490*cdf0e10cSrcweir aPropSet[PKG_MNFST_SALT].Name = sSaltProperty; 491*cdf0e10cSrcweir aPropSet[PKG_MNFST_SALT].Value <<= rInfo.pStream->getSalt(); 492*cdf0e10cSrcweir aPropSet[PKG_MNFST_ITERATION].Name = sIterationCountProperty; 493*cdf0e10cSrcweir aPropSet[PKG_MNFST_ITERATION].Value <<= rInfo.pStream->getIterationCount (); 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir // Need to store the uncompressed size in the manifest 496*cdf0e10cSrcweir OSL_ENSURE( nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" ); 497*cdf0e10cSrcweir aPropSet[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty; 498*cdf0e10cSrcweir aPropSet[PKG_MNFST_UCOMPSIZE].Value <<= nOwnStreamOrigSize; 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir if ( bRawStream || bTransportOwnEncrStreamAsRaw ) 501*cdf0e10cSrcweir { 502*cdf0e10cSrcweir ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData(); 503*cdf0e10cSrcweir if ( !xEncData.is() ) 504*cdf0e10cSrcweir throw uno::RuntimeException(); 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty; 507*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest(); 508*cdf0e10cSrcweir aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty; 509*cdf0e10cSrcweir aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg; 510*cdf0e10cSrcweir aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty; 511*cdf0e10cSrcweir aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID; 512*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty; 513*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg; 514*cdf0e10cSrcweir aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty; 515*cdf0e10cSrcweir aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize; 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir // If the entry is already stored in the zip file in the format we 521*cdf0e10cSrcweir // want for this write...copy it raw 522*cdf0e10cSrcweir if ( !bUseNonSeekableAccess 523*cdf0e10cSrcweir && ( bRawStream || bTransportOwnEncrStreamAsRaw 524*cdf0e10cSrcweir || ( rInfo.pStream->IsPackageMember() && !bToBeEncrypted 525*cdf0e10cSrcweir && ( ( rInfo.pStream->aEntry.nMethod == DEFLATED && bToBeCompressed ) 526*cdf0e10cSrcweir || ( rInfo.pStream->aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) ) 527*cdf0e10cSrcweir { 528*cdf0e10cSrcweir // If it's a PackageMember, then it's an unbuffered stream and we need 529*cdf0e10cSrcweir // to get a new version of it as we can't seek backwards. 530*cdf0e10cSrcweir if ( rInfo.pStream->IsPackageMember() ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir xStream = rInfo.pStream->getRawData(); 533*cdf0e10cSrcweir if ( !xStream.is() ) 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir // Make sure that we actually _got_ a new one ! 536*cdf0e10cSrcweir bSuccess = false; 537*cdf0e10cSrcweir return bSuccess; 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir try 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir if ( bRawStream ) 544*cdf0e10cSrcweir xStream->skipBytes( rInfo.pStream->GetMagicalHackPos() ); 545*cdf0e10cSrcweir 546*cdf0e10cSrcweir rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, sal_False ); 547*cdf0e10cSrcweir // the entry is provided to the ZipOutputStream that will delete it 548*cdf0e10cSrcweir pAutoTempEntry.release(); 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir uno::Sequence < sal_Int8 > aSeq ( n_ConstBufferSize ); 551*cdf0e10cSrcweir sal_Int32 nLength; 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir do 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir nLength = xStream->readBytes( aSeq, n_ConstBufferSize ); 556*cdf0e10cSrcweir rZipOut.rawWrite(aSeq, 0, nLength); 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir while ( nLength == n_ConstBufferSize ); 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir rZipOut.rawCloseEntry(); 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir catch ( ZipException& ) 563*cdf0e10cSrcweir { 564*cdf0e10cSrcweir bSuccess = false; 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir catch ( IOException& ) 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir bSuccess = false; 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir else 572*cdf0e10cSrcweir { 573*cdf0e10cSrcweir // This stream is defenitly not a raw stream 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir // If nonseekable access is used the stream should be at the beginning and 576*cdf0e10cSrcweir // is useless after the storing. Thus if the storing fails the package should 577*cdf0e10cSrcweir // be thrown away ( as actually it is done currently )! 578*cdf0e10cSrcweir // To allow to reuse the package after the error, the optimization must be removed! 579*cdf0e10cSrcweir 580*cdf0e10cSrcweir // If it's a PackageMember, then our previous reference held a 'raw' stream 581*cdf0e10cSrcweir // so we need to re-get it, unencrypted, uncompressed and positioned at the 582*cdf0e10cSrcweir // beginning of the stream 583*cdf0e10cSrcweir if ( rInfo.pStream->IsPackageMember() ) 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir xStream = rInfo.pStream->getInputStream(); 586*cdf0e10cSrcweir if ( !xStream.is() ) 587*cdf0e10cSrcweir { 588*cdf0e10cSrcweir // Make sure that we actually _got_ a new one ! 589*cdf0e10cSrcweir bSuccess = false; 590*cdf0e10cSrcweir return bSuccess; 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir if ( bToBeCompressed ) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir pTempEntry->nMethod = DEFLATED; 597*cdf0e10cSrcweir pTempEntry->nCrc = pTempEntry->nCompressedSize = pTempEntry->nSize = -1; 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir try 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, bToBeEncrypted); 603*cdf0e10cSrcweir // the entry is provided to the ZipOutputStream that will delete it 604*cdf0e10cSrcweir pAutoTempEntry.release(); 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir sal_Int32 nLength; 607*cdf0e10cSrcweir uno::Sequence < sal_Int8 > aSeq (n_ConstBufferSize); 608*cdf0e10cSrcweir do 609*cdf0e10cSrcweir { 610*cdf0e10cSrcweir nLength = xStream->readBytes(aSeq, n_ConstBufferSize); 611*cdf0e10cSrcweir rZipOut.write(aSeq, 0, nLength); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir while ( nLength == n_ConstBufferSize ); 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir rZipOut.closeEntry(); 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir catch ( ZipException& ) 618*cdf0e10cSrcweir { 619*cdf0e10cSrcweir bSuccess = false; 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir catch ( IOException& ) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir bSuccess = false; 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir if ( bToBeEncrypted ) 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData(); 629*cdf0e10cSrcweir if ( !xEncData.is() ) 630*cdf0e10cSrcweir throw uno::RuntimeException(); 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty; 633*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest(); 634*cdf0e10cSrcweir aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty; 635*cdf0e10cSrcweir aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg; 636*cdf0e10cSrcweir aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty; 637*cdf0e10cSrcweir aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID; 638*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty; 639*cdf0e10cSrcweir aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg; 640*cdf0e10cSrcweir aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty; 641*cdf0e10cSrcweir aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize; 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir rInfo.pStream->SetIsEncrypted ( sal_True ); 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir if( bSuccess ) 648*cdf0e10cSrcweir { 649*cdf0e10cSrcweir if ( !rInfo.pStream->IsPackageMember() ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir rInfo.pStream->CloseOwnStreamIfAny(); 652*cdf0e10cSrcweir rInfo.pStream->SetPackageMember ( sal_True ); 653*cdf0e10cSrcweir } 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir if ( bRawStream ) 656*cdf0e10cSrcweir { 657*cdf0e10cSrcweir // the raw stream was integrated and now behaves 658*cdf0e10cSrcweir // as usual encrypted stream 659*cdf0e10cSrcweir rInfo.pStream->SetToBeEncrypted( sal_True ); 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir // Remove hacky bit from entry flags 663*cdf0e10cSrcweir if ( pTempEntry->nFlag & ( 1 << 4 ) ) 664*cdf0e10cSrcweir { 665*cdf0e10cSrcweir pTempEntry->nFlag &= ~( 1 << 4 ); 666*cdf0e10cSrcweir pTempEntry->nMethod = STORED; 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir // Then copy it back afterwards... 670*cdf0e10cSrcweir ZipPackageFolder::copyZipEntry ( rInfo.pStream->aEntry, *pTempEntry ); 671*cdf0e10cSrcweir 672*cdf0e10cSrcweir // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving ) 673*cdf0e10cSrcweir if ( rInfo.pStream->IsEncrypted() ) 674*cdf0e10cSrcweir rInfo.pStream->setSize( nOwnStreamOrigSize ); 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir rInfo.pStream->aEntry.nOffset *= -1; 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir // folder can have a mediatype only in package format 681*cdf0e10cSrcweir if ( aPropSet.getLength() 682*cdf0e10cSrcweir && ( m_nFormat == embed::StorageFormats::PACKAGE || ( m_nFormat == embed::StorageFormats::OFOPXML && !rInfo.bFolder ) ) ) 683*cdf0e10cSrcweir rManList.push_back( aPropSet ); 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir return bSuccess; 686*cdf0e10cSrcweir } 687*cdf0e10cSrcweir 688*cdf0e10cSrcweir void ZipPackageFolder::saveContents( ::rtl::OUString &rPath, std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool ) 689*cdf0e10cSrcweir throw( uno::RuntimeException ) 690*cdf0e10cSrcweir { 691*cdf0e10cSrcweir bool bWritingFailed = false; 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir if ( maContents.begin() == maContents.end() && rPath.getLength() && m_nFormat != embed::StorageFormats::OFOPXML ) 694*cdf0e10cSrcweir { 695*cdf0e10cSrcweir // it is an empty subfolder, use workaround to store it 696*cdf0e10cSrcweir ZipEntry* pTempEntry = new ZipEntry(); 697*cdf0e10cSrcweir ZipPackageFolder::copyZipEntry ( *pTempEntry, aEntry ); 698*cdf0e10cSrcweir pTempEntry->nPathLen = (sal_Int16)( ::rtl::OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getLength() ); 699*cdf0e10cSrcweir pTempEntry->nExtraLen = -1; 700*cdf0e10cSrcweir pTempEntry->sPath = rPath; 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir try 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir rZipOut.putNextEntry( *pTempEntry, NULL, sal_False ); 705*cdf0e10cSrcweir rZipOut.rawCloseEntry(); 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir catch ( ZipException& ) 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir bWritingFailed = true; 710*cdf0e10cSrcweir } 711*cdf0e10cSrcweir catch ( IOException& ) 712*cdf0e10cSrcweir { 713*cdf0e10cSrcweir bWritingFailed = true; 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir } 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir bool bMimeTypeStreamStored = false; 718*cdf0e10cSrcweir ::rtl::OUString aMimeTypeStreamName( RTL_CONSTASCII_USTRINGPARAM( "mimetype" ) ); 719*cdf0e10cSrcweir if ( m_nFormat == embed::StorageFormats::ZIP && !rPath.getLength() ) 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir // let the "mimtype" stream in root folder be stored as the first stream if it is zip format 722*cdf0e10cSrcweir ContentHash::iterator aIter = maContents.find ( aMimeTypeStreamName ); 723*cdf0e10cSrcweir if ( aIter != maContents.end() && !(*aIter).second->bFolder ) 724*cdf0e10cSrcweir { 725*cdf0e10cSrcweir bMimeTypeStreamStored = true; 726*cdf0e10cSrcweir bWritingFailed = !saveChild( (*aIter).first, *(*aIter).second, rPath, rManList, rZipOut, rEncryptionKey, rRandomPool ); 727*cdf0e10cSrcweir } 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end(); 731*cdf0e10cSrcweir aCI != aEnd; 732*cdf0e10cSrcweir aCI++) 733*cdf0e10cSrcweir { 734*cdf0e10cSrcweir const ::rtl::OUString &rShortName = (*aCI).first; 735*cdf0e10cSrcweir const ContentInfo &rInfo = *(*aCI).second; 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir if ( !bMimeTypeStreamStored || !rShortName.equals( aMimeTypeStreamName ) ) 738*cdf0e10cSrcweir bWritingFailed = !saveChild( rShortName, rInfo, rPath, rManList, rZipOut, rEncryptionKey, rRandomPool ); 739*cdf0e10cSrcweir } 740*cdf0e10cSrcweir 741*cdf0e10cSrcweir if( bWritingFailed ) 742*cdf0e10cSrcweir throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 743*cdf0e10cSrcweir } 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir void ZipPackageFolder::releaseUpwardRef( void ) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir // Now it is possible that a package folder is disconnected from the package before removing of the folder. 748*cdf0e10cSrcweir // Such a scenario is used in storage implementation. When a new version of a folder is provided the old 749*cdf0e10cSrcweir // one is retrieved, removed from the package but preserved for the error handling. 750*cdf0e10cSrcweir // In this scenario the referencing to the parent is not really useful, since it requires disposing. 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir // Actually there is no need in having a reference to the parent, it even make things more complicated and 753*cdf0e10cSrcweir // requires disposing mechanics. Using of a simple pointer seems to be easier solution and also a safe enough. 754*cdf0e10cSrcweir 755*cdf0e10cSrcweir clearParent(); 756*cdf0e10cSrcweir 757*cdf0e10cSrcweir #if 0 758*cdf0e10cSrcweir for ( ContentHash::const_iterator aCI = maContents.begin(); 759*cdf0e10cSrcweir aCI!=maContents.end(); 760*cdf0e10cSrcweir aCI++) 761*cdf0e10cSrcweir { 762*cdf0e10cSrcweir ContentInfo &rInfo = * (*aCI).second; 763*cdf0e10cSrcweir if ( rInfo.bFolder )// && ! rInfo.pFolder->HasReleased () ) 764*cdf0e10cSrcweir rInfo.pFolder->releaseUpwardRef(); 765*cdf0e10cSrcweir else //if ( !rInfo.bFolder && !rInfo.pStream->HasReleased() ) 766*cdf0e10cSrcweir rInfo.pStream->clearParent(); 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir clearParent(); 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir VOS_ENSURE ( m_refCount == 1, "Ref-count is not 1!" ); 771*cdf0e10cSrcweir #endif 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir sal_Int64 SAL_CALL ZipPackageFolder::getSomething( const uno::Sequence< sal_Int8 >& aIdentifier ) 775*cdf0e10cSrcweir throw(uno::RuntimeException) 776*cdf0e10cSrcweir { 777*cdf0e10cSrcweir sal_Int64 nMe = 0; 778*cdf0e10cSrcweir if ( aIdentifier.getLength() == 16 && 779*cdf0e10cSrcweir 0 == rtl_compareMemory(static_getImplementationId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) 780*cdf0e10cSrcweir nMe = reinterpret_cast < sal_Int64 > ( this ); 781*cdf0e10cSrcweir return nMe; 782*cdf0e10cSrcweir } 783*cdf0e10cSrcweir void SAL_CALL ZipPackageFolder::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue ) 784*cdf0e10cSrcweir throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, uno::RuntimeException) 785*cdf0e10cSrcweir { 786*cdf0e10cSrcweir if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MediaType"))) 787*cdf0e10cSrcweir { 788*cdf0e10cSrcweir // TODO/LATER: activate when zip ucp is ready 789*cdf0e10cSrcweir // if ( m_nFormat != embed::StorageFormats::PACKAGE ) 790*cdf0e10cSrcweir // throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir aValue >>= sMediaType; 793*cdf0e10cSrcweir } 794*cdf0e10cSrcweir else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Version"))) 795*cdf0e10cSrcweir aValue >>= m_sVersion; 796*cdf0e10cSrcweir else if (aPropertyName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Size") ) ) 797*cdf0e10cSrcweir aValue >>= aEntry.nSize; 798*cdf0e10cSrcweir else 799*cdf0e10cSrcweir throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 800*cdf0e10cSrcweir } 801*cdf0e10cSrcweir uno::Any SAL_CALL ZipPackageFolder::getPropertyValue( const ::rtl::OUString& PropertyName ) 802*cdf0e10cSrcweir throw(UnknownPropertyException, WrappedTargetException, uno::RuntimeException) 803*cdf0e10cSrcweir { 804*cdf0e10cSrcweir if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) 805*cdf0e10cSrcweir { 806*cdf0e10cSrcweir // TODO/LATER: activate when zip ucp is ready 807*cdf0e10cSrcweir // if ( m_nFormat != embed::StorageFormats::PACKAGE ) 808*cdf0e10cSrcweir // throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir return uno::makeAny ( sMediaType ); 811*cdf0e10cSrcweir } 812*cdf0e10cSrcweir else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Version" ) ) ) 813*cdf0e10cSrcweir return uno::makeAny( m_sVersion ); 814*cdf0e10cSrcweir else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "Size" ) ) ) 815*cdf0e10cSrcweir return uno::makeAny ( aEntry.nSize ); 816*cdf0e10cSrcweir else 817*cdf0e10cSrcweir throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 818*cdf0e10cSrcweir } 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir void ZipPackageFolder::doInsertByName ( ZipPackageEntry *pEntry, sal_Bool bSetParent ) 821*cdf0e10cSrcweir throw(IllegalArgumentException, ElementExistException, WrappedTargetException, uno::RuntimeException) 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir try 824*cdf0e10cSrcweir { 825*cdf0e10cSrcweir if ( pEntry->IsFolder() ) 826*cdf0e10cSrcweir maContents[pEntry->getName()] = new ContentInfo ( static_cast < ZipPackageFolder *> ( pEntry ) ); 827*cdf0e10cSrcweir else 828*cdf0e10cSrcweir maContents[pEntry->getName()] = new ContentInfo ( static_cast < ZipPackageStream *> ( pEntry ) ); 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir catch(const uno::Exception& rEx) 831*cdf0e10cSrcweir { 832*cdf0e10cSrcweir (void)rEx; 833*cdf0e10cSrcweir throw; 834*cdf0e10cSrcweir } 835*cdf0e10cSrcweir if ( bSetParent ) 836*cdf0e10cSrcweir pEntry->setParent ( *this ); 837*cdf0e10cSrcweir } 838*cdf0e10cSrcweir ::rtl::OUString ZipPackageFolder::getImplementationName() 839*cdf0e10cSrcweir throw (uno::RuntimeException) 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir return ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "ZipPackageFolder" ) ); 842*cdf0e10cSrcweir } 843*cdf0e10cSrcweir 844*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > ZipPackageFolder::getSupportedServiceNames() 845*cdf0e10cSrcweir throw (uno::RuntimeException) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > aNames(1); 848*cdf0e10cSrcweir aNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.PackageFolder" ) ); 849*cdf0e10cSrcweir return aNames; 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir sal_Bool SAL_CALL ZipPackageFolder::supportsService( ::rtl::OUString const & rServiceName ) 852*cdf0e10cSrcweir throw (uno::RuntimeException) 853*cdf0e10cSrcweir { 854*cdf0e10cSrcweir return rServiceName == getSupportedServiceNames()[0]; 855*cdf0e10cSrcweir } 856