xref: /AOO41X/main/package/source/xstor/xstorage.cxx (revision a38728232e8c39f9058a1a2aa8ee4e6db7b8ca34)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_package.hxx"
26 #include <com/sun/star/beans/PropertyValue.hpp>
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <com/sun/star/embed/UseBackupException.hpp>
29 #include <com/sun/star/embed/StorageFormats.hpp>
30 #include <com/sun/star/ucb/XProgressHandler.hpp>
31 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
32 #include <com/sun/star/container/XEnumerationAccess.hpp>
33 #include <com/sun/star/container/XNamed.hpp>
34 #include <com/sun/star/util/XChangesBatch.hpp>
35 #include <com/sun/star/util/XCloneable.hpp>
36 
37 
38 #include <com/sun/star/lang/XUnoTunnel.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/lang/DisposedException.hpp>
41 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
42 #include <com/sun/star/beans/NamedValue.hpp>
43 
44 #include <PackageConstants.hxx>
45 
46 #include <cppuhelper/typeprovider.hxx>
47 #include <cppuhelper/exc_hlp.hxx>
48 #include <rtl/logfile.hxx>
49 #include <rtl/instance.hxx>
50 
51 #include <comphelper/processfactory.hxx>
52 #include <comphelper/componentcontext.hxx>
53 #include <comphelper/storagehelper.hxx>
54 #include <comphelper/ofopxmlhelper.hxx>
55 
56 #include "xstorage.hxx"
57 #include "owriteablestream.hxx"
58 #include "disposelistener.hxx"
59 #include "switchpersistencestream.hxx"
60 #include "ohierarchyholder.hxx"
61 
62 using namespace ::com::sun::star;
63 
64 //=========================================================
65 
66 typedef ::std::list< uno::WeakReference< lang::XComponent > > WeakComponentList;
67 
68 struct StorInternalData_Impl
69 {
70     SotMutexHolderRef m_rSharedMutexRef;
71     ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer; // list of listeners
72     ::cppu::OTypeCollection* m_pTypeCollection;
73     sal_Bool m_bIsRoot;
74     sal_Int32 m_nStorageType; // the mode in wich the storage is used
75     sal_Bool m_bReadOnlyWrap;
76 
77     OChildDispListener_Impl* m_pSubElDispListener;
78 
79     WeakComponentList m_aOpenSubComponentsList;
80 
81     ::rtl::Reference< OHierarchyHolder_Impl > m_rHierarchyHolder;
82 
83     // the mutex reference MUST NOT be empty
StorInternalData_ImplStorInternalData_Impl84     StorInternalData_Impl( const SotMutexHolderRef& rMutexRef, sal_Bool bRoot, sal_Int32 nStorageType, sal_Bool bReadOnlyWrap )
85     : m_rSharedMutexRef( rMutexRef )
86     , m_aListenersContainer( rMutexRef->GetMutex() )
87     , m_pTypeCollection( NULL )
88     , m_bIsRoot( bRoot )
89     , m_nStorageType( nStorageType )
90     , m_bReadOnlyWrap( bReadOnlyWrap )
91     , m_pSubElDispListener( NULL )
92     {}
93 
94     ~StorInternalData_Impl();
95 };
96 
97 //=========================================================
98 ::rtl::OUString GetNewTempFileURL( const uno::Reference< lang::XMultiServiceFactory > xFactory );
99 
100 // static
completeStorageStreamCopy_Impl(const uno::Reference<io::XStream> & xSource,const uno::Reference<io::XStream> & xDest,sal_Int32 nStorageType,const uno::Sequence<uno::Sequence<beans::StringPair>> & aRelInfo)101 void OStorage_Impl::completeStorageStreamCopy_Impl(
102                             const uno::Reference< io::XStream >& xSource,
103                             const uno::Reference< io::XStream >& xDest,
104                             sal_Int32 nStorageType,
105                             const uno::Sequence< uno::Sequence< beans::StringPair > >& aRelInfo )
106 {
107         uno::Reference< beans::XPropertySet > xSourceProps( xSource, uno::UNO_QUERY );
108         uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY );
109         if ( !xSourceProps.is() || !xDestProps.is() )
110             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
111 
112         uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
113         if ( !xDestOutStream.is() )
114             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
115 
116         uno::Reference< io::XInputStream > xSourceInStream = xSource->getInputStream();
117         if ( !xSourceInStream.is() )
118             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
119 
120         // TODO: headers of encripted streams should be copied also
121         ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream, xDestOutStream );
122 
123         uno::Sequence< ::rtl::OUString > aPropNames( 1 );
124         aPropNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
125 
126         if ( nStorageType == embed::StorageFormats::PACKAGE )
127         {
128             aPropNames.realloc( 3 );
129             aPropNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
130             aPropNames[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
131         }
132         else if ( nStorageType == embed::StorageFormats::OFOPXML )
133         {
134             // TODO/LATER: in future it might make sence to provide the stream if there is one
135             uno::Reference< embed::XRelationshipAccess > xRelAccess( xDest, uno::UNO_QUERY_THROW );
136             xRelAccess->clearRelationships();
137             xRelAccess->insertRelationships( aRelInfo, sal_False );
138 
139             aPropNames.realloc( 2 );
140             aPropNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
141         }
142 
143         for ( int ind = 0; ind < aPropNames.getLength(); ind++ )
144             xDestProps->setPropertyValue( aPropNames[ind], xSourceProps->getPropertyValue( aPropNames[ind] ) );
145 }
146 
GetSeekableTempCopy(uno::Reference<io::XInputStream> xInStream,uno::Reference<lang::XMultiServiceFactory> xFactory)147 uno::Reference< io::XInputStream > GetSeekableTempCopy( uno::Reference< io::XInputStream > xInStream,
148                                                         uno::Reference< lang::XMultiServiceFactory > xFactory )
149 {
150     uno::Reference < io::XOutputStream > xTempOut(
151                         xFactory->createInstance ( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
152                         uno::UNO_QUERY );
153     uno::Reference < io::XInputStream > xTempIn( xTempOut, uno::UNO_QUERY );
154 
155     if ( !xTempOut.is() || !xTempIn.is() )
156         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
157 
158     ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
159     xTempOut->closeOutput();
160 
161     return xTempIn;
162 }
163 
~StorInternalData_Impl()164 StorInternalData_Impl::~StorInternalData_Impl()
165 {
166     if ( m_pTypeCollection )
167         delete m_pTypeCollection;
168 }
169 
170 
SotElement_Impl(const::rtl::OUString & rName,sal_Bool bStor,sal_Bool bNew)171 SotElement_Impl::SotElement_Impl( const ::rtl::OUString& rName, sal_Bool bStor, sal_Bool bNew )
172 : m_aName( rName )
173 , m_aOriginalName( rName )
174 , m_bIsRemoved( sal_False )
175 , m_bIsInserted( bNew )
176 , m_bIsStorage( bStor )
177 , m_pStorage( NULL )
178 , m_pStream( NULL )
179 {
180 }
181 
~SotElement_Impl()182 SotElement_Impl::~SotElement_Impl()
183 {
184     if ( m_pStorage )
185         delete m_pStorage;
186 
187     if ( m_pStream )
188         delete m_pStream;
189 }
190 
191 //-----------------------------------------------
192 // most of properties are holt by the storage but are not used
OStorage_Impl(uno::Reference<io::XInputStream> xInputStream,sal_Int32 nMode,uno::Sequence<beans::PropertyValue> xProperties,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)193 OStorage_Impl::OStorage_Impl(   uno::Reference< io::XInputStream > xInputStream,
194                                 sal_Int32 nMode,
195                                 uno::Sequence< beans::PropertyValue > xProperties,
196                                 uno::Reference< lang::XMultiServiceFactory > xFactory,
197                                 sal_Int32 nStorageType )
198 : m_rMutexRef( new SotMutexHolder )
199 , m_pAntiImpl( NULL )
200 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
201 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
202 , m_bBroadcastModified( sal_False )
203 , m_bCommited( sal_False )
204 , m_bIsRoot( sal_True )
205 , m_bListCreated( sal_False )
206 , m_xFactory( xFactory )
207 , m_xProperties( xProperties )
208 , m_bHasCommonEncryptionData( sal_False )
209 , m_pParent( NULL )
210 , m_bControlMediaType( sal_False )
211 , m_bMTFallbackUsed( sal_False )
212 , m_bControlVersion( sal_False )
213 , m_pSwitchStream( NULL )
214 , m_nStorageType( nStorageType )
215 , m_pRelStorElement( NULL )
216 , m_nRelInfoStatus( RELINFO_NO_INIT )
217 {
218     // all the checks done below by assertion statements must be done by factory
219     OSL_ENSURE( xInputStream.is(), "No input stream is provided!\n" );
220 
221     m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory, xInputStream );
222     m_xInputStream = m_pSwitchStream->getInputStream();
223 
224     if ( m_nStorageMode & embed::ElementModes::WRITE )
225     {
226         // check that the stream allows to write
227         OSL_ENSURE( sal_False, "No stream for writing is provided!\n" );
228     }
229 }
230 
231 //-----------------------------------------------
232 // most of properties are holt by the storage but are not used
OStorage_Impl(uno::Reference<io::XStream> xStream,sal_Int32 nMode,uno::Sequence<beans::PropertyValue> xProperties,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)233 OStorage_Impl::OStorage_Impl(   uno::Reference< io::XStream > xStream,
234                                 sal_Int32 nMode,
235                                 uno::Sequence< beans::PropertyValue > xProperties,
236                                 uno::Reference< lang::XMultiServiceFactory > xFactory,
237                                 sal_Int32 nStorageType )
238 : m_rMutexRef( new SotMutexHolder )
239 , m_pAntiImpl( NULL )
240 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
241 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
242 , m_bBroadcastModified( sal_False )
243 , m_bCommited( sal_False )
244 , m_bIsRoot( sal_True )
245 , m_bListCreated( sal_False )
246 , m_xFactory( xFactory )
247 , m_xProperties( xProperties )
248 , m_bHasCommonEncryptionData( sal_False )
249 , m_pParent( NULL )
250 , m_bControlMediaType( sal_False )
251 , m_bMTFallbackUsed( sal_False )
252 , m_bControlVersion( sal_False )
253 , m_pSwitchStream( NULL )
254 , m_nStorageType( nStorageType )
255 , m_pRelStorElement( NULL )
256 , m_nRelInfoStatus( RELINFO_NO_INIT )
257 {
258     // all the checks done below by assertion statements must be done by factory
259     OSL_ENSURE( xStream.is(), "No stream is provided!\n" );
260 
261     if ( m_nStorageMode & embed::ElementModes::WRITE )
262     {
263         m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory, xStream );
264         m_xStream = static_cast< io::XStream* >( m_pSwitchStream );
265     }
266     else
267     {
268         m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory,
269                                                                                           xStream->getInputStream() );
270         m_xInputStream = m_pSwitchStream->getInputStream();
271     }
272 }
273 
274 //-----------------------------------------------
OStorage_Impl(OStorage_Impl * pParent,sal_Int32 nMode,uno::Reference<container::XNameContainer> xPackageFolder,uno::Reference<lang::XSingleServiceFactory> xPackage,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)275 OStorage_Impl::OStorage_Impl(   OStorage_Impl* pParent,
276                                 sal_Int32 nMode,
277                                 uno::Reference< container::XNameContainer > xPackageFolder,
278                                 uno::Reference< lang::XSingleServiceFactory > xPackage,
279                                 uno::Reference< lang::XMultiServiceFactory > xFactory,
280                                 sal_Int32 nStorageType )
281 : m_rMutexRef( new SotMutexHolder )
282 , m_pAntiImpl( NULL )
283 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
284 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
285 , m_bBroadcastModified( sal_False )
286 , m_bCommited( sal_False )
287 , m_bIsRoot( sal_False )
288 , m_bListCreated( sal_False )
289 , m_xPackageFolder( xPackageFolder )
290 , m_xPackage( xPackage )
291 , m_xFactory( xFactory )
292 , m_bHasCommonEncryptionData( sal_False )
293 , m_pParent( pParent ) // can be empty in case of temporary readonly substorages and relation storage
294 , m_bControlMediaType( sal_False )
295 , m_bMTFallbackUsed( sal_False )
296 , m_bControlVersion( sal_False )
297 , m_pSwitchStream( NULL )
298 , m_nStorageType( nStorageType )
299 , m_pRelStorElement( NULL )
300 , m_nRelInfoStatus( RELINFO_NO_INIT )
301 {
302     OSL_ENSURE( xPackageFolder.is(), "No package folder!\n" );
303 }
304 
305 //-----------------------------------------------
~OStorage_Impl()306 OStorage_Impl::~OStorage_Impl()
307 {
308     {
309         ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
310         if ( m_pAntiImpl ) // root storage wrapper must set this member to NULL before destruction of object
311         {
312             OSL_ENSURE( !m_bIsRoot, "The root storage wrapper must be disposed already" );
313 
314             try {
315                 m_pAntiImpl->InternalDispose( sal_False );
316             }
317             catch ( uno::Exception& aException )
318             {
319                 AddLog( aException.Message );
320                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
321             }
322             m_pAntiImpl = NULL;
323         }
324         else if ( !m_aReadOnlyWrapList.empty() )
325         {
326             for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
327                   pStorageIter != m_aReadOnlyWrapList.end(); pStorageIter++ )
328             {
329                 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
330                 if ( xTmp.is() )
331                     try {
332                         pStorageIter->m_pPointer->InternalDispose( sal_False );
333                     } catch( uno::Exception& aException )
334                     {
335                         AddLog( aException.Message );
336                         AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
337                     }
338             }
339 
340             m_aReadOnlyWrapList.clear();
341         }
342 
343         m_pParent = NULL;
344     }
345 
346     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
347           pElementIter != m_aChildrenList.end(); pElementIter++ )
348         delete *pElementIter;
349 
350     m_aChildrenList.clear();
351 
352     for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
353           pDeletedIter != m_aDeletedList.end(); pDeletedIter++ )
354         delete *pDeletedIter;
355 
356     m_aDeletedList.clear();
357 
358     if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_pRelStorElement )
359     {
360         delete m_pRelStorElement;
361         m_pRelStorElement = NULL;
362     }
363 
364     m_xPackageFolder = uno::Reference< container::XNameContainer >();
365     m_xPackage = uno::Reference< lang::XSingleServiceFactory >();
366 
367     ::rtl::OUString aPropertyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
368     for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
369     {
370         if ( m_xProperties[aInd].Name.equals( aPropertyName ) )
371         {
372             // the storage is URL based so all the streams are opened by factory and should be closed
373             try
374             {
375                 if ( m_xInputStream.is() )
376                 {
377                     m_xInputStream->closeInput();
378                     m_xInputStream = uno::Reference< io::XInputStream >();
379                 }
380 
381                 if ( m_xStream.is() )
382                 {
383                     uno::Reference< io::XInputStream > xInStr = m_xStream->getInputStream();
384                     if ( xInStr.is() )
385                         xInStr->closeInput();
386 
387                     uno::Reference< io::XOutputStream > xOutStr = m_xStream->getOutputStream();
388                     if ( xOutStr.is() )
389                         xOutStr->closeOutput();
390 
391                     m_xStream = uno::Reference< io::XStream >();
392                 }
393             }
394             catch( uno::Exception& aException )
395             {
396                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
397                 AddLog( aException.Message );
398             }
399         }
400     }
401 }
402 
403 //-----------------------------------------------
AddLog(const::rtl::OUString & aMessage)404 void OStorage_Impl::AddLog( const ::rtl::OUString& aMessage )
405 {
406     if ( !m_xLogRing.is() )
407     {
408         try
409         {
410             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
411             if ( aContext.is() )
412                 m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), uno::UNO_QUERY_THROW );
413         }
414         catch( uno::Exception& )
415         {
416             // No log
417         }
418     }
419 
420     if ( m_xLogRing.is() )
421         m_xLogRing->logString( aMessage );
422 }
423 
424 //-----------------------------------------------
SetReadOnlyWrap(OStorage & aStorage)425 void OStorage_Impl::SetReadOnlyWrap( OStorage& aStorage )
426 {
427     // Weak reference is used inside the holder so the refcount must not be zero at this point
428     OSL_ENSURE( aStorage.GetRefCount_Impl(), "There must be a reference alive to use this method!\n" );
429     m_aReadOnlyWrapList.push_back( StorageHolder_Impl( &aStorage ) );
430 }
431 
432 //-----------------------------------------------
RemoveReadOnlyWrap(OStorage & aStorage)433 void OStorage_Impl::RemoveReadOnlyWrap( OStorage& aStorage )
434 {
435     for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
436       pStorageIter != m_aReadOnlyWrapList.end();)
437     {
438         uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
439         if ( !xTmp.is() || pStorageIter->m_pPointer == &aStorage )
440         {
441             try {
442                 pStorageIter->m_pPointer->InternalDispose( sal_False );
443             } catch( uno::Exception& aException )
444             {
445                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
446                 AddLog( aException.Message );
447             }
448 
449             OStorageList_Impl::iterator pIterToDelete( pStorageIter );
450             pStorageIter++;
451             m_aReadOnlyWrapList.erase( pIterToDelete );
452         }
453         else
454             pStorageIter++;
455     }
456 }
457 
458 //-----------------------------------------------
OpenOwnPackage()459 void OStorage_Impl::OpenOwnPackage()
460 {
461     OSL_ENSURE( m_bIsRoot, "Opening of the package has no sence!\n" );
462 
463     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
464 
465     if ( !m_xPackageFolder.is() )
466     {
467         if ( !m_xPackage.is() )
468         {
469             uno::Sequence< uno::Any > aArguments( 2 );
470             if ( m_nStorageMode & embed::ElementModes::WRITE )
471                 aArguments[ 0 ] <<= m_xStream;
472             else
473             {
474                 OSL_ENSURE( m_xInputStream.is(), "Input stream must be set for readonly access!\n" );
475                 aArguments[ 0 ] <<= m_xInputStream;
476                 // TODO: if input stream is not seekable or XSeekable interface is supported
477                 // on XStream object a wrapper must be used
478             }
479 
480             // do not allow elements to remove themself from the old container in case of insertion to another container
481             aArguments[ 1 ] <<= beans::NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowRemoveOnInsert" ) ),
482                                                     uno::makeAny( (sal_Bool)sal_False ) );
483 
484             sal_Int32 nArgNum = 2;
485             for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
486             {
487                 if ( m_xProperties[aInd].Name.equalsAscii( "RepairPackage" )
488                   || m_xProperties[aInd].Name.equalsAscii( "ProgressHandler" ) )
489                 {
490                     beans::NamedValue aNamedValue( m_xProperties[aInd].Name,
491                                                     m_xProperties[aInd].Value );
492                     aArguments.realloc( ++nArgNum );
493                     aArguments[nArgNum-1] <<= aNamedValue;
494                 }
495                 else if ( m_xProperties[aInd].Name.equalsAscii( "Password" ) )
496                 {
497                     // TODO: implement password setting for documents
498                     // the password entry must be removed after setting
499                 }
500             }
501 
502             if ( m_nStorageType == embed::StorageFormats::ZIP )
503             {
504                 // let the package support only plain zip format
505                 beans::NamedValue aNamedValue;
506                 aNamedValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
507                 aNamedValue.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ZipFormat" ) );
508                 aArguments.realloc( ++nArgNum );
509                 aArguments[nArgNum-1] <<= aNamedValue;
510             }
511             else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
512             {
513                 // let the package support OFOPXML media type handling
514                 beans::NamedValue aNamedValue;
515                 aNamedValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
516                 aNamedValue.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) );
517                 aArguments.realloc( ++nArgNum );
518                 aArguments[nArgNum-1] <<= aNamedValue;
519             }
520 
521             m_xPackage = uno::Reference< lang::XSingleServiceFactory > (
522                                         GetServiceFactory()->createInstanceWithArguments(
523                                             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.packages.comp.ZipPackage" ) ),
524                                             aArguments ),
525                                         uno::UNO_QUERY );
526         }
527 
528         uno::Reference< container::XHierarchicalNameAccess > xHNameAccess( m_xPackage, uno::UNO_QUERY );
529         OSL_ENSURE( xHNameAccess.is(), "The package could not be created!\n" );
530 
531         if ( xHNameAccess.is() )
532         {
533             uno::Any aFolder = xHNameAccess->getByHierarchicalName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) );
534             aFolder >>= m_xPackageFolder;
535         }
536     }
537 
538     OSL_ENSURE( m_xPackageFolder.is(), "The package root folder can not be opened!\n" );
539     if ( !m_xPackageFolder.is() )
540         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
541 }
542 
543 //-----------------------------------------------
GetServiceFactory()544 uno::Reference< lang::XMultiServiceFactory > OStorage_Impl::GetServiceFactory()
545 {
546     if ( m_xFactory.is() )
547         return m_xFactory;
548 
549     return ::comphelper::getProcessServiceFactory();
550 }
551 
552 //-----------------------------------------------
GetChildrenList()553 SotElementList_Impl& OStorage_Impl::GetChildrenList()
554 {
555     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
556 
557     ReadContents();
558     return m_aChildrenList;
559 }
560 
561 //-----------------------------------------------
GetStorageProperties()562 void OStorage_Impl::GetStorageProperties()
563 {
564     if ( m_nStorageType == embed::StorageFormats::PACKAGE )
565     {
566         uno::Reference< beans::XPropertySet > xProps( m_xPackageFolder, uno::UNO_QUERY_THROW );
567 
568         if ( !m_bControlMediaType )
569         {
570             uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
571             xPackageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MEDIATYPE_FALLBACK_USED_PROPERTY ) ) ) >>= m_bMTFallbackUsed;
572 
573             xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ) >>= m_aMediaType;
574             m_bControlMediaType = sal_True;
575         }
576 
577         if ( !m_bControlVersion )
578         {
579             xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= m_aVersion;
580             m_bControlVersion = sal_True;
581         }
582     }
583 
584     // the properties of OFOPXML will be handled directly
585 }
586 
587 //-----------------------------------------------
ReadRelInfoIfNecessary()588 void OStorage_Impl::ReadRelInfoIfNecessary()
589 {
590     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
591         return;
592 
593     if ( m_nRelInfoStatus == RELINFO_NO_INIT )
594     {
595         // Init from original stream
596         uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( ::rtl::OUString() );
597         if ( xRelInfoStream.is() )
598             m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
599                                     xRelInfoStream,
600                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/.rels" ) ),
601                                     m_xFactory );
602 
603         m_nRelInfoStatus = RELINFO_READ;
604     }
605     else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
606     {
607         // Init from the new stream
608         try
609         {
610             if ( m_xNewRelInfoStream.is() )
611                 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
612                                         m_xNewRelInfoStream,
613                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/.rels" ) ),
614                                         m_xFactory );
615 
616             m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
617         }
618         catch( uno::Exception )
619         {
620             m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
621         }
622     }
623 }
624 
625 //-----------------------------------------------
ReadContents()626 void OStorage_Impl::ReadContents()
627 {
628     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
629 
630     if ( m_bListCreated )
631         return;
632 
633     if ( m_bIsRoot )
634         OpenOwnPackage();
635 
636     uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xPackageFolder, uno::UNO_QUERY );
637     if ( !xEnumAccess.is() )
638         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
639 
640     uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
641     if ( !xEnum.is() )
642         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
643 
644     m_bListCreated = sal_True;
645 
646     while( xEnum->hasMoreElements() )
647     {
648         try {
649             uno::Reference< container::XNamed > xNamed;
650             xEnum->nextElement() >>= xNamed;
651 
652             if ( !xNamed.is() )
653             {
654                 OSL_ENSURE( sal_False, "XNamed is not supported!\n" );
655                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
656             }
657 
658             ::rtl::OUString aName = xNamed->getName();
659             OSL_ENSURE( aName.getLength(), "Empty name!\n" );
660 
661             uno::Reference< container::XNameContainer > xNameContainer( xNamed, uno::UNO_QUERY );
662 
663             SotElement_Impl* pNewElement = new SotElement_Impl( aName, xNameContainer.is(), sal_False );
664             if ( m_nStorageType == embed::StorageFormats::OFOPXML && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
665             {
666                 if ( !pNewElement->m_bIsStorage )
667                     throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Unexpected format
668 
669                 m_pRelStorElement = pNewElement;
670                 CreateRelStorage();
671             }
672             else
673             {
674                 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
675                 {
676                     // if a storage is truncated all of it elements are marked as deleted
677                     pNewElement->m_bIsRemoved = sal_True;
678                 }
679 
680                 m_aChildrenList.push_back( pNewElement );
681             }
682         }
683         catch( container::NoSuchElementException& aNoSuchElementException )
684         {
685             AddLog( aNoSuchElementException.Message );
686             AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "NoSuchElement" ) ) );
687 
688             OSL_ENSURE( sal_False, "hasMoreElements() implementation has problems!\n" );
689             break;
690         }
691     }
692     if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
693     {
694         // if a storage is truncated the relations information should be cleaned
695         m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
696         m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
697         m_nRelInfoStatus = RELINFO_CHANGED;
698     }
699 
700     // cache changeable folder properties
701     GetStorageProperties();
702 }
703 
704 //-----------------------------------------------
CopyToStorage(const uno::Reference<embed::XStorage> & xDest,sal_Bool bDirect)705 void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDest, sal_Bool bDirect )
706 {
707     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
708 
709     uno::Reference< beans::XPropertySet > xPropSet( xDest, uno::UNO_QUERY );
710     if ( !xPropSet.is() )
711         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
712 
713     sal_Int32 nDestMode = embed::ElementModes::READ;
714     xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) ) >>= nDestMode;
715 
716     if ( !( nDestMode & embed::ElementModes::WRITE ) )
717         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
718 
719     ReadContents();
720 
721     if ( !m_xPackageFolder.is() )
722         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
723 
724     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
725           pElementIter != m_aChildrenList.end(); pElementIter++ )
726     {
727         if ( !(*pElementIter)->m_bIsRemoved )
728             CopyStorageElement( *pElementIter, xDest, (*pElementIter)->m_aName, bDirect );
729     }
730 
731     // move storage properties to the destination one ( means changeable properties )
732     if ( m_nStorageType == embed::StorageFormats::PACKAGE )
733     {
734         ::rtl::OUString aMediaTypeString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
735         ::rtl::OUString aVersionString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) );
736         xPropSet->setPropertyValue( aMediaTypeString, uno::makeAny( m_aMediaType ) );
737         xPropSet->setPropertyValue( aVersionString, uno::makeAny( m_aVersion ) );
738     }
739 
740     if ( m_nStorageType == embed::StorageFormats::PACKAGE )
741     {
742         // if this is a root storage, the common key from current one should be moved there
743         sal_Bool bIsRoot = sal_False;
744         ::rtl::OUString aRootString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRoot" ) );
745         if ( ( xPropSet->getPropertyValue( aRootString ) >>= bIsRoot ) && bIsRoot )
746         {
747             try
748             {
749                 uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xDest, uno::UNO_QUERY );
750                 if ( xEncr.is() )
751                 {
752                     xEncr->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
753 
754                     uno::Sequence< beans::NamedValue > aAlgorithms;
755                     uno::Reference< beans::XPropertySet > xPackPropSet( m_xPackage, uno::UNO_QUERY_THROW );
756                     xPackPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ) )
757                         >>= aAlgorithms;
758                     xEncr->setEncryptionAlgorithms( aAlgorithms );
759                 }
760             }
761             catch( packages::NoEncryptionException& aNoEncryptionException )
762             {
763                 AddLog( aNoEncryptionException.Message );
764                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No Encryption" ) ) );
765             }
766         }
767     }
768     else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
769     {
770 
771         // TODO/LATER: currently the optimization is not active
772         // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( ::rtl::OUString() ); // own stream
773         // if ( xRelInfoStream.is() )
774         // {
775         //  // Relations info stream is a writeonly property, introduced only to optimyze copying
776         //  // Should be used carefuly since no check for stream consistency is done, and the stream must not stay locked
777         //
778         //  ::rtl::OUString aRelInfoString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelationsInfoStream" ) );
779         //  xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
780         // }
781 
782         uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
783         if ( !xRels.is() )
784             throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
785 
786         xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
787     }
788 
789     // if possible the destination storage should be commited after successful copying
790     uno::Reference< embed::XTransactedObject > xObjToCommit( xDest, uno::UNO_QUERY );
791     if ( xObjToCommit.is() )
792         xObjToCommit->commit();
793 }
794 
795 //-----------------------------------------------
CopyStorageElement(SotElement_Impl * pElement,uno::Reference<embed::XStorage> xDest,::rtl::OUString aName,sal_Bool bDirect)796 void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
797                                         uno::Reference< embed::XStorage > xDest,
798                                         ::rtl::OUString aName,
799                                         sal_Bool bDirect )
800 {
801     OSL_ENSURE( xDest.is(), "No destination storage!\n" );
802     OSL_ENSURE( aName.getLength(), "Empty element name!\n" );
803 
804     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
805 
806     uno::Reference< container::XNameAccess > xDestAccess( xDest, uno::UNO_QUERY );
807     if ( !xDestAccess.is() )
808         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
809 
810     if ( xDestAccess->hasByName( aName )
811       && !( pElement->m_bIsStorage && xDest->isStorageElement( aName ) ) )
812         xDest->removeElement( aName );
813 
814     if ( pElement->m_bIsStorage )
815     {
816         uno::Reference< embed::XStorage > xSubDest =
817                                     xDest->openStorageElement(  aName,
818                                                                 embed::ElementModes::WRITE );
819 
820         OSL_ENSURE( xSubDest.is(), "No destination substorage!\n" );
821 
822         if ( !pElement->m_pStorage )
823         {
824             OpenSubStorage( pElement, embed::ElementModes::READ );
825             if ( !pElement->m_pStorage )
826                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
827         }
828 
829         pElement->m_pStorage->CopyToStorage( xSubDest, bDirect );
830     }
831     else
832     {
833         if ( !pElement->m_pStream )
834         {
835             OpenSubStream( pElement );
836             if ( !pElement->m_pStream )
837                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
838         }
839 
840         if ( !pElement->m_pStream->IsEncrypted() )
841         {
842             if ( bDirect )
843             {
844                 // fill in the properties for the stream
845                 uno::Sequence< beans::PropertyValue > aStrProps(0);
846                 uno::Sequence< beans::PropertyValue > aSrcPkgProps = pElement->m_pStream->GetStreamProperties();
847                 sal_Int32 nNum = 0;
848                 for ( int ind = 0; ind < aSrcPkgProps.getLength(); ind++ )
849                 {
850                     if ( aSrcPkgProps[ind].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) ) )
851                       || aSrcPkgProps[ind].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "Compressed" ) ) ) )
852                     {
853                         aStrProps.realloc( ++nNum );
854                         aStrProps[nNum-1].Name = aSrcPkgProps[ind].Name;
855                         aStrProps[nNum-1].Value = aSrcPkgProps[ind].Value;
856                     }
857                 }
858 
859                 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
860                 {
861                     aStrProps.realloc( ++nNum );
862                     aStrProps[nNum-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
863                     aStrProps[nNum-1].Value <<= (sal_Bool)( pElement->m_pStream->UsesCommonEncryption_Impl() );
864                 }
865                 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
866                 {
867                     // TODO/LATER: currently the optimization is not active
868                     // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( ::rtl::OUString() ); // own rels stream
869                     // if ( xInStream.is() )
870                     // {
871                     //  aStrProps.realloc( ++nNum );
872                     //  aStrProps[nNum-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelationsInfoStream" ) );
873                     //  aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
874                     // }
875 
876                     uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
877                     if ( !xRels.is() )
878                         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
879 
880                     xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
881                 }
882 
883                 uno::Reference< embed::XOptimizedStorage > xOptDest( xDest, uno::UNO_QUERY_THROW );
884                 uno::Reference < io::XInputStream > xInputToInsert;
885 
886                 if ( pElement->m_pStream->HasTempFile_Impl() || !pElement->m_pStream->m_xPackageStream.is() )
887                 {
888                     OSL_ENSURE( pElement->m_pStream->m_xPackageStream.is(), "No package stream!" );
889 
890                     // if the stream is modified - the temporary file must be used for insertion
891                     xInputToInsert = pElement->m_pStream->GetTempFileAsInputStream();
892                 }
893                 else
894                 {
895                     // for now get just nonseekable access to the stream
896                     // TODO/LATER: the raw stream can be used
897 
898                     xInputToInsert = pElement->m_pStream->m_xPackageStream->getDataStream();
899                 }
900 
901                 if ( !xInputToInsert.is() )
902                         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
903 
904                 xOptDest->insertStreamElementDirect( aName, xInputToInsert, aStrProps );
905             }
906             else
907             {
908                 uno::Reference< io::XStream > xSubStr =
909                                             xDest->openStreamElement( aName,
910                                             embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
911                 OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
912 
913                 pElement->m_pStream->CopyInternallyTo_Impl( xSubStr );
914             }
915         }
916         else if ( m_nStorageType != embed::StorageFormats::PACKAGE )
917         {
918             OSL_ENSURE( sal_False, "Encryption is only supported in package storage!\n" );
919             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
920         }
921         else if ( pElement->m_pStream->HasCachedEncryptionData()
922              && ( pElement->m_pStream->IsModified() || pElement->m_pStream->HasWriteOwner_Impl() ) )
923         {
924             ::comphelper::SequenceAsHashMap aCommonEncryptionData;
925             sal_Bool bHasCommonEncryptionData = sal_False;
926             try
927             {
928                 aCommonEncryptionData = GetCommonRootEncryptionData();
929                 bHasCommonEncryptionData = sal_True;
930             }
931             catch( packages::NoEncryptionException& aNoEncryptionException )
932             {
933                 AddLog( aNoEncryptionException.Message );
934                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "No Encryption" ) ) );
935             }
936 
937             if ( bHasCommonEncryptionData && ::package::PackageEncryptionDatasEqual( pElement->m_pStream->GetCachedEncryptionData(), aCommonEncryptionData ) )
938             {
939                 // If the stream can be opened with the common storage password
940                 // it must be stored with the common storage password as well
941                 uno::Reference< io::XStream > xDestStream =
942                                             xDest->openStreamElement( aName,
943                                                 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
944 
945                 pElement->m_pStream->CopyInternallyTo_Impl( xDestStream );
946 
947                 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
948                 xProps->setPropertyValue(
949                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
950                     uno::Any( (sal_Bool) sal_True ) );
951             }
952             else
953             {
954                 // the stream is already opened for writing or was changed
955                 uno::Reference< embed::XStorage2 > xDest2( xDest, uno::UNO_QUERY_THROW );
956                 uno::Reference< io::XStream > xSubStr =
957                                             xDest2->openEncryptedStream( aName,
958                                                 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE,
959                                                 pElement->m_pStream->GetCachedEncryptionData().getAsConstNamedValueList() );
960                 OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
961 
962                 pElement->m_pStream->CopyInternallyTo_Impl( xSubStr, pElement->m_pStream->GetCachedEncryptionData() );
963             }
964         }
965         else
966         {
967             // the stream is not opened at all, so it can be just opened for reading
968             try
969             {
970                 // If the stream can be opened with the common storage password
971                 // it must be stored with the common storage password as well
972 
973                 uno::Reference< io::XStream > xOwnStream = pElement->m_pStream->GetStream( embed::ElementModes::READ,
974                                                                                             sal_False );
975                 uno::Reference< io::XStream > xDestStream =
976                                             xDest->openStreamElement( aName,
977                                                 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
978                 OSL_ENSURE( xDestStream.is(), "No destination substream!\n" );
979                 completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
980 
981                 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
982                 xProps->setPropertyValue(
983                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
984                     uno::Any( (sal_Bool) sal_True ) );
985             }
986             catch( packages::WrongPasswordException& aWrongPasswordException )
987             {
988                 AddLog( aWrongPasswordException.Message );
989                 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
990 
991                 // If the common storage password does not allow to open the stream
992                 // it could be copyed in raw way, the problem is that the StartKey should be the same
993                 // in the ODF1.2 package, so an invalid package could be produced if the stream
994                 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
995                 uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
996                 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
997                 xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
998             }
999         }
1000     }
1001 }
1002 
1003 //-----------------------------------------------
GetAllRelationshipsIfAny()1004 uno::Sequence< uno::Sequence< beans::StringPair > > OStorage_Impl::GetAllRelationshipsIfAny()
1005 {
1006     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1007         return uno::Sequence< uno::Sequence< beans::StringPair > >();
1008 
1009     ReadRelInfoIfNecessary();
1010 
1011     if ( m_nRelInfoStatus == RELINFO_READ
1012       || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
1013         return m_aRelInfo;
1014     else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
1015             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Wrong relinfo stream!" ) ),
1016                                     uno::Reference< uno::XInterface >() );
1017 }
1018 
1019 //-----------------------------------------------
CopyLastCommitTo(const uno::Reference<embed::XStorage> & xNewStor)1020 void OStorage_Impl::CopyLastCommitTo( const uno::Reference< embed::XStorage >& xNewStor )
1021 {
1022     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1023 
1024     OSL_ENSURE( m_xPackageFolder.is(), "A commited storage is incomplete!\n" );
1025     if ( !m_xPackageFolder.is() )
1026         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1027 
1028     OStorage_Impl aTempRepresent( NULL,
1029                                 embed::ElementModes::READ,
1030                                 m_xPackageFolder,
1031                                 m_xPackage,
1032                                 m_xFactory,
1033                                 m_nStorageType);
1034 
1035     // TODO/LATER: could use direct copying
1036     aTempRepresent.CopyToStorage( xNewStor, sal_False );
1037 }
1038 
1039 //-----------------------------------------------
InsertIntoPackageFolder(const::rtl::OUString & aName,const uno::Reference<container::XNameContainer> & xParentPackageFolder)1040 void OStorage_Impl::InsertIntoPackageFolder( const ::rtl::OUString& aName,
1041                                              const uno::Reference< container::XNameContainer >& xParentPackageFolder )
1042 {
1043     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1044 
1045     OSL_ENSURE( m_xPackageFolder.is(), "An inserted storage is incomplete!\n" );
1046     uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageFolder, uno::UNO_QUERY );
1047     if ( !xTunnel.is() )
1048         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1049 
1050     xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
1051 
1052     m_bCommited = sal_False;
1053 }
1054 
1055 //-----------------------------------------------
Commit()1056 void OStorage_Impl::Commit()
1057 {
1058     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1059 
1060     if ( !m_bIsModified )
1061         return;
1062 
1063     // in case of a new empty storage it is possible that the contents are still not read
1064     // ( the storage of course has no contents, but the initialization is postponed till the first use,
1065     //   thus if a new storage was created and commited immediatelly it must be initialized here )
1066     ReadContents();
1067 
1068     // if storage is commited it should have a valid Package representation
1069     OSL_ENSURE( m_xPackageFolder.is(), "The package representation should exist!\n" );
1070     if ( !m_xPackageFolder.is() )
1071         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1072 
1073     OSL_ENSURE( m_nStorageMode & embed::ElementModes::WRITE,
1074                 "Commit of readonly storage, should be detected before!\n" );
1075 
1076     uno::Reference< container::XNameContainer > xNewPackageFolder;
1077 
1078     // here the storage will switch to the temporary package folder
1079     // if the storage was already commited and the parent was not commited after that
1080     // the switch should not be done since the package folder in use is a temporary one;
1081     // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
1082     if ( !m_bCommited && !m_bIsRoot )
1083     {
1084         uno::Sequence< uno::Any > aSeq( 1 );
1085         aSeq[0] <<= sal_True;
1086 
1087         xNewPackageFolder = uno::Reference< container::XNameContainer >(
1088                                                     m_xPackage->createInstanceWithArguments( aSeq ),
1089                                                     uno::UNO_QUERY );
1090     }
1091     else
1092         xNewPackageFolder = m_xPackageFolder;
1093 
1094     // remove replaced removed elements
1095     for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
1096           pDeletedIter != m_aDeletedList.end();
1097           pDeletedIter++ )
1098     {
1099 
1100         if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pDeletedIter)->m_bIsStorage )
1101             RemoveStreamRelInfo( (*pDeletedIter)->m_aOriginalName );
1102 
1103         // the removed elements are not in new temporary storage
1104         if ( m_bCommited || m_bIsRoot )
1105             xNewPackageFolder->removeByName( (*pDeletedIter)->m_aOriginalName );
1106         delete *pDeletedIter;
1107         *pDeletedIter = NULL;
1108     }
1109     m_aDeletedList.clear();
1110 
1111     // remove removed elements
1112     SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1113     while (  pElementIter != m_aChildrenList.end() )
1114     {
1115         // renamed and inserted elements must be really inserted to package later
1116         // since thay can conflict with removed elements
1117 
1118         if ( (*pElementIter)->m_bIsRemoved )
1119         {
1120             if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
1121                 RemoveStreamRelInfo( (*pElementIter)->m_aOriginalName );
1122 
1123             // the removed elements are not in new temporary storage
1124             if ( m_bCommited || m_bIsRoot )
1125                 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1126 
1127             SotElement_Impl* pToDelete = *pElementIter;
1128 
1129             pElementIter++; // to let the iterator be valid it should be increased before removing
1130 
1131             m_aChildrenList.remove( pToDelete );
1132             delete pToDelete;
1133         }
1134         else
1135             pElementIter++;
1136     }
1137 
1138     // there should be no more deleted elements
1139     for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); pElementIter++ )
1140     {
1141         // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1142         // since thay can conflict with renamed elements
1143 
1144         if ( !(*pElementIter)->m_bIsInserted )
1145         {
1146             // for now stream is opened in direct mode that means that in case
1147             // storage is commited all the streams from it are commited in current state.
1148             // following two steps are separated to allow easily implement transacted mode
1149             // for streams if we need it in future.
1150             // Only hierarchical access uses transacted streams currently
1151             if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream
1152               && !(*pElementIter)->m_pStream->IsTransacted() )
1153                 (*pElementIter)->m_pStream->Commit();
1154 
1155             // if the storage was not open, there is no need to commit it ???
1156             // the storage should be checked that it is commited
1157             if ( (*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStorage && (*pElementIter)->m_pStorage->m_bCommited )
1158             {
1159                 // it's temporary PackageFolder should be inserted instead of current one
1160                 // also the new copy of PackageFolder should be used by the children storages
1161 
1162                 // the renamed elements are not in new temporary storage
1163                 if ( m_bCommited || m_bIsRoot )
1164                     xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1165 
1166                 (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1167             }
1168             else if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream && (*pElementIter)->m_pStream->m_bFlushed )
1169             {
1170                 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1171                     CommitStreamRelInfo( *pElementIter );
1172 
1173                 // the renamed elements are not in new temporary storage
1174                 if ( m_bCommited || m_bIsRoot )
1175                     xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1176 
1177                 (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1178             }
1179             else if ( !m_bCommited && !m_bIsRoot )
1180             {
1181                 // the element must be just copied to the new temporary package folder
1182                 // the connection with the original package should not be lost just because
1183                 // the element is still refered by the folder in the original hierarchy
1184                 uno::Any aPackageElement = m_xPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
1185                 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1186             }
1187             else if ( (*pElementIter)->m_aName.compareTo( (*pElementIter)->m_aOriginalName ) )
1188             {
1189                 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1190                 // in case the name was changed and it is not a changed storage - rename the element
1191                 uno::Reference< container::XNamed > xNamed;
1192                 uno::Any aPackageElement = xNewPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
1193                 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1194                 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1195 
1196                 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
1197                 {
1198                     if ( !(*pElementIter)->m_pStream )
1199                     {
1200                         OpenSubStream( *pElementIter );
1201                         if ( !(*pElementIter)->m_pStream )
1202                             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1203                     }
1204 
1205                     CommitStreamRelInfo( *pElementIter );
1206                 }
1207             }
1208 
1209             (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1210         }
1211     }
1212 
1213     for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); pElementIter++ )
1214     {
1215         // now inserted elements can be inserted to the package
1216         if ( (*pElementIter)->m_bIsInserted )
1217         {
1218             (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1219             uno::Reference< lang::XUnoTunnel > xNewElement;
1220 
1221             if ( (*pElementIter)->m_bIsStorage )
1222             {
1223                 if ( (*pElementIter)->m_pStorage->m_bCommited )
1224                 {
1225                     OSL_ENSURE( (*pElementIter)->m_pStorage, "An inserted storage is incomplete!\n" );
1226                     if ( !(*pElementIter)->m_pStorage )
1227                         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1228 
1229                     (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1230 
1231                     (*pElementIter)->m_bIsInserted = sal_False;
1232                 }
1233             }
1234             else
1235             {
1236                 OSL_ENSURE( (*pElementIter)->m_pStream, "An inserted stream is incomplete!\n" );
1237                 if ( !(*pElementIter)->m_pStream )
1238                     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1239 
1240                 if ( !(*pElementIter)->m_pStream->IsTransacted() )
1241                     (*pElementIter)->m_pStream->Commit();
1242 
1243                 if ( (*pElementIter)->m_pStream->m_bFlushed )
1244                 {
1245                     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1246                         CommitStreamRelInfo( *pElementIter );
1247 
1248                     (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1249 
1250                     (*pElementIter)->m_bIsInserted = sal_False;
1251                 }
1252             }
1253         }
1254     }
1255 
1256     if ( m_nStorageType == embed::StorageFormats::PACKAGE )
1257     {
1258         // move properties to the destination package folder
1259         uno::Reference< beans::XPropertySet > xProps( xNewPackageFolder, uno::UNO_QUERY );
1260         if ( !xProps.is() )
1261             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1262 
1263         xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), uno::makeAny( m_aMediaType ) );
1264         xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), uno::makeAny( m_aVersion ) );
1265     }
1266 
1267     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1268         CommitRelInfo( xNewPackageFolder ); // store own relations and commit complete relations storage
1269 
1270     if ( m_bIsRoot )
1271     {
1272         uno::Reference< util::XChangesBatch > xChangesBatch( m_xPackage, uno::UNO_QUERY );
1273 
1274         OSL_ENSURE( xChangesBatch.is(), "Impossible to commit package!\n" );
1275         if ( !xChangesBatch.is() )
1276             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1277 
1278         try
1279         {
1280             xChangesBatch->commitChanges();
1281         }
1282         catch( lang::WrappedTargetException& r )
1283         {
1284             // the wrapped UseBackupException means that the target medium can be corrupted
1285             embed::UseBackupException aException;
1286             if ( r.TargetException >>= aException )
1287             {
1288                 m_xStream = uno::Reference< io::XStream >();
1289                 m_xInputStream = uno::Reference< io::XInputStream >();
1290                 throw aException;
1291             }
1292 
1293             AddLog( aException.Message );
1294             AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
1295             throw;
1296         }
1297     }
1298     else if ( !m_bCommited )
1299     {
1300         m_xPackageFolder = xNewPackageFolder;
1301         m_bCommited = sal_True;
1302     }
1303 
1304     // after commit the mediatype treated as the correct one
1305     m_bMTFallbackUsed = sal_False;
1306 }
1307 
1308 //-----------------------------------------------
Revert()1309 void OStorage_Impl::Revert()
1310 {
1311     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1312 
1313     if ( !( m_nStorageMode & embed::ElementModes::WRITE ) )
1314         return; // nothing to do
1315 
1316     // all the children must be removed
1317     // they will be created later on demand
1318 
1319     SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1320     while (  pElementIter != m_aChildrenList.end() )
1321     {
1322         if ( (*pElementIter)->m_bIsInserted )
1323         {
1324             SotElement_Impl* pToDelete = *pElementIter;
1325 
1326             pElementIter++; // to let the iterator be valid it should be increased before removing
1327 
1328             m_aChildrenList.remove( pToDelete );
1329             delete pToDelete;
1330         }
1331         else
1332         {
1333             ClearElement( *pElementIter );
1334 
1335             (*pElementIter)->m_aName = (*pElementIter)->m_aOriginalName;
1336             (*pElementIter)->m_bIsRemoved = sal_False;
1337 
1338             pElementIter++;
1339         }
1340     }
1341 
1342     // return replaced removed elements
1343     for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
1344           pDeletedIter != m_aDeletedList.end();
1345           pDeletedIter++ )
1346     {
1347         m_aChildrenList.push_back( (*pDeletedIter) );
1348 
1349         ClearElement( *pDeletedIter );
1350 
1351         (*pDeletedIter)->m_aName = (*pDeletedIter)->m_aOriginalName;
1352         (*pDeletedIter)->m_bIsRemoved = sal_False;
1353     }
1354     m_aDeletedList.clear();
1355 
1356     m_bControlMediaType = sal_False;
1357     m_bControlVersion = sal_False;
1358 
1359     GetStorageProperties();
1360 
1361     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1362     {
1363         // currently the relations storage is changed only on commit
1364         m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1365         m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1366         m_nRelInfoStatus = RELINFO_NO_INIT;
1367     }
1368 }
1369 
1370 //-----------------------------------------------
GetCommonRootEncryptionData()1371 ::comphelper::SequenceAsHashMap OStorage_Impl::GetCommonRootEncryptionData()
1372     throw ( packages::NoEncryptionException )
1373 {
1374     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
1375 
1376     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1377         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1378 
1379     if ( m_bIsRoot )
1380     {
1381         if ( !m_bHasCommonEncryptionData )
1382             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1383 
1384         return m_aCommonEncryptionData;
1385     }
1386     else
1387     {
1388         if ( !m_pParent )
1389             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1390 
1391         return m_pParent->GetCommonRootEncryptionData();
1392     }
1393 }
1394 
1395 //-----------------------------------------------
FindElement(const::rtl::OUString & rName)1396 SotElement_Impl* OStorage_Impl::FindElement( const ::rtl::OUString& rName )
1397 {
1398     OSL_ENSURE( rName.getLength(), "Name is empty!" );
1399 
1400     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1401 
1402     ReadContents();
1403 
1404     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1405           pElementIter != m_aChildrenList.end(); pElementIter++ )
1406     {
1407         if ( (*pElementIter)->m_aName == rName && !(*pElementIter)->m_bIsRemoved )
1408             return *pElementIter;
1409     }
1410 
1411     return NULL;
1412 }
1413 
1414 //-----------------------------------------------
InsertStream(::rtl::OUString aName,sal_Bool bEncr)1415 SotElement_Impl* OStorage_Impl::InsertStream( ::rtl::OUString aName, sal_Bool bEncr )
1416 {
1417     OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1418     if ( !m_xPackage.is() )
1419         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1420 
1421     uno::Sequence< uno::Any > aSeq( 1 );
1422     aSeq[0] <<= sal_False;
1423     uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1424                                                     uno::UNO_QUERY );
1425 
1426     OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1427     if ( !xNewElement.is() )
1428         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1429 
1430     uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1431     if ( !xPackageSubStream.is() )
1432         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1433 
1434     OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE || !bEncr, "Only package storage supports encryption!\n" );
1435     if ( m_nStorageType != embed::StorageFormats::PACKAGE && bEncr )
1436         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1437 
1438     // the mode is not needed for storage stream internal implementation
1439     SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1440     pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, bEncr, m_nStorageType, sal_True );
1441 
1442     m_aChildrenList.push_back( pNewElement );
1443     m_bIsModified = sal_True;
1444     m_bBroadcastModified = sal_True;
1445 
1446     return pNewElement;
1447 }
1448 
1449 //-----------------------------------------------
InsertRawStream(::rtl::OUString aName,const uno::Reference<io::XInputStream> & xInStream)1450 SotElement_Impl* OStorage_Impl::InsertRawStream( ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInStream )
1451 {
1452     // insert of raw stream means insert and commit
1453     OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1454     if ( !m_xPackage.is() )
1455         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1456 
1457     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1458         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1459 
1460     uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1461     uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
1462                                                                      GetSeekableTempCopy( xInStream, GetServiceFactory() );
1463 
1464     uno::Sequence< uno::Any > aSeq( 1 );
1465     aSeq[0] <<= sal_False;
1466     uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1467                                                     uno::UNO_QUERY );
1468 
1469     OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1470     if ( !xNewElement.is() )
1471         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1472 
1473     uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1474     if ( !xPackageSubStream.is() )
1475         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1476 
1477     xPackageSubStream->setRawStream( xInStrToInsert );
1478 
1479     // the mode is not needed for storage stream internal implementation
1480     SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1481     pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_True, m_nStorageType, sal_False );
1482     // the stream is inserted and must be treated as a commited one
1483     pNewElement->m_pStream->SetToBeCommited();
1484 
1485     m_aChildrenList.push_back( pNewElement );
1486     m_bIsModified = sal_True;
1487     m_bBroadcastModified = sal_True;
1488 
1489     return pNewElement;
1490 }
1491 
1492 //-----------------------------------------------
CreateNewStorageImpl(sal_Int32 nStorageMode)1493 OStorage_Impl* OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
1494 {
1495     OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1496     if ( !m_xPackage.is() )
1497         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1498 
1499     uno::Sequence< uno::Any > aSeq( 1 );
1500     aSeq[0] <<= sal_True;
1501     uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1502                                                     uno::UNO_QUERY );
1503 
1504     OSL_ENSURE( xNewElement.is(), "Not possible to create a new storage!\n" );
1505     if ( !xNewElement.is() )
1506         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1507 
1508     uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY );
1509     if ( !xPackageSubFolder.is() )
1510         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1511 
1512     OStorage_Impl* pResult =
1513             new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
1514     pResult->m_bIsModified = sal_True;
1515 
1516     return pResult;
1517 }
1518 
1519 //-----------------------------------------------
InsertStorage(::rtl::OUString aName,sal_Int32 nStorageMode)1520 SotElement_Impl* OStorage_Impl::InsertStorage( ::rtl::OUString aName, sal_Int32 nStorageMode )
1521 {
1522     SotElement_Impl* pNewElement = InsertElement( aName, sal_True );
1523 
1524     pNewElement->m_pStorage = CreateNewStorageImpl( nStorageMode );
1525 
1526     m_aChildrenList.push_back( pNewElement );
1527 
1528     return pNewElement;
1529 }
1530 
1531 //-----------------------------------------------
InsertElement(::rtl::OUString aName,sal_Bool bIsStorage)1532 SotElement_Impl* OStorage_Impl::InsertElement( ::rtl::OUString aName, sal_Bool bIsStorage )
1533 {
1534     OSL_ENSURE( FindElement( aName ) == NULL, "Should not try to insert existing element" );
1535 
1536     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1537 
1538     SotElement_Impl* pDeletedElm = NULL;
1539 
1540     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1541           pElementIter != m_aChildrenList.end(); pElementIter++ )
1542     {
1543         if ( (*pElementIter)->m_aName == aName )
1544         {
1545             OSL_ENSURE( (*pElementIter)->m_bIsRemoved, "Try to insert an element instead of existing one!\n" );
1546             if ( (*pElementIter)->m_bIsRemoved )
1547             {
1548                 OSL_ENSURE( !(*pElementIter)->m_bIsInserted, "Inserted elements must be deleted immediatelly!\n" );
1549                 pDeletedElm = *pElementIter;
1550                 break;
1551             }
1552         }
1553     }
1554 
1555     if ( pDeletedElm )
1556     {
1557         if ( pDeletedElm->m_bIsStorage )
1558             OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
1559         else
1560             OpenSubStream( pDeletedElm );
1561 
1562         m_aChildrenList.remove( pDeletedElm );  // correct usage of list ???
1563         m_aDeletedList.push_back( pDeletedElm );
1564     }
1565 
1566     // create new element
1567     return new SotElement_Impl( aName, bIsStorage, sal_True );
1568 }
1569 
1570 //-----------------------------------------------
OpenSubStorage(SotElement_Impl * pElement,sal_Int32 nStorageMode)1571 void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
1572 {
1573     OSL_ENSURE( pElement, "pElement is not set!\n" );
1574     OSL_ENSURE( pElement->m_bIsStorage, "Storage flag is not set!\n" );
1575 
1576     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1577 
1578     if ( !pElement->m_pStorage )
1579     {
1580         OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1581 
1582         uno::Reference< lang::XUnoTunnel > xTunnel;
1583         m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1584         if ( !xTunnel.is() )
1585             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1586 
1587         uno::Reference< container::XNameContainer > xPackageSubFolder( xTunnel, uno::UNO_QUERY );
1588 
1589         OSL_ENSURE( xPackageSubFolder.is(), "Can not get XNameContainer interface from folder!\n" );
1590 
1591         if ( !xPackageSubFolder.is() )
1592             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1593 
1594         pElement->m_pStorage = new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
1595     }
1596 }
1597 
1598 //-----------------------------------------------
OpenSubStream(SotElement_Impl * pElement)1599 void OStorage_Impl::OpenSubStream( SotElement_Impl* pElement )
1600 {
1601     OSL_ENSURE( pElement, "pElement is not set!\n" );
1602     OSL_ENSURE( !pElement->m_bIsStorage, "Storage flag is set!\n" );
1603 
1604     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1605 
1606     if ( !pElement->m_pStream )
1607     {
1608         OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1609 
1610         uno::Reference< lang::XUnoTunnel > xTunnel;
1611         m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1612         if ( !xTunnel.is() )
1613             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1614 
1615         uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTunnel, uno::UNO_QUERY );
1616         if ( !xPackageSubStream.is() )
1617             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1618 
1619         // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1620         pElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_False, m_nStorageType, sal_False, GetRelInfoStreamForName( pElement->m_aOriginalName ) );
1621     }
1622 }
1623 
1624 //-----------------------------------------------
GetElementNames()1625 uno::Sequence< ::rtl::OUString > OStorage_Impl::GetElementNames()
1626 {
1627     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1628 
1629     ReadContents();
1630 
1631     sal_uInt32 nSize = m_aChildrenList.size();
1632     uno::Sequence< ::rtl::OUString > aElementNames( nSize );
1633 
1634     sal_uInt32 nInd = 0;
1635     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1636           pElementIter != m_aChildrenList.end(); pElementIter++ )
1637     {
1638         if ( !(*pElementIter)->m_bIsRemoved )
1639             aElementNames[nInd++] = (*pElementIter)->m_aName;
1640     }
1641 
1642     aElementNames.realloc( nInd );
1643     return aElementNames;
1644 }
1645 
1646 //-----------------------------------------------
RemoveElement(SotElement_Impl * pElement)1647 void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
1648 {
1649     OSL_ENSURE( pElement, "Element must be provided!" );
1650 
1651     if ( !pElement )
1652         return;
1653 
1654     if ( (pElement->m_pStorage && ( pElement->m_pStorage->m_pAntiImpl || !pElement->m_pStorage->m_aReadOnlyWrapList.empty() ))
1655       || (pElement->m_pStream && ( pElement->m_pStream->m_pAntiImpl || !pElement->m_pStream->m_aInputStreamsList.empty() )) )
1656         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Access denied
1657 
1658     if ( pElement->m_bIsInserted )
1659     {
1660         m_aChildrenList.remove( pElement );
1661         delete pElement; // ???
1662     }
1663     else
1664     {
1665         pElement->m_bIsRemoved = sal_True;
1666         ClearElement( pElement );
1667     }
1668 
1669     // TODO/OFOPXML: the rel stream should be removed as well
1670 }
1671 
1672 //-----------------------------------------------
ClearElement(SotElement_Impl * pElement)1673 void OStorage_Impl::ClearElement( SotElement_Impl* pElement )
1674 {
1675     if ( pElement->m_pStorage )
1676     {
1677         delete pElement->m_pStorage;
1678         pElement->m_pStorage = NULL;
1679     }
1680 
1681     if ( pElement->m_pStream )
1682     {
1683         delete pElement->m_pStream;
1684         pElement->m_pStream = NULL;
1685     }
1686 }
1687 
1688 //-----------------------------------------------
CloneStreamElement(const::rtl::OUString & aStreamName,sal_Bool bEncryptionDataProvided,const::comphelper::SequenceAsHashMap & aEncryptionData,uno::Reference<io::XStream> & xTargetStream)1689 void OStorage_Impl::CloneStreamElement( const ::rtl::OUString& aStreamName,
1690                                         sal_Bool bEncryptionDataProvided,
1691                                         const ::comphelper::SequenceAsHashMap& aEncryptionData,
1692                                         uno::Reference< io::XStream >& xTargetStream )
1693         throw ( embed::InvalidStorageException,
1694                 lang::IllegalArgumentException,
1695                 packages::WrongPasswordException,
1696                 io::IOException,
1697                 embed::StorageWrappedTargetException,
1698                 uno::RuntimeException )
1699 {
1700     SotElement_Impl *pElement = FindElement( aStreamName );
1701     if ( !pElement )
1702     {
1703         // element does not exist, throw exception
1704         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
1705     }
1706     else if ( pElement->m_bIsStorage )
1707         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1708 
1709     if ( !pElement->m_pStream )
1710         OpenSubStream( pElement );
1711 
1712     if ( pElement->m_pStream && pElement->m_pStream->m_xPackageStream.is() )
1713     {
1714         // the existence of m_pAntiImpl of the child is not interesting,
1715         // the copy will be created internally
1716 
1717         // usual copying is not applicable here, only last flushed version of the
1718         // child stream should be used for copiing. Probably the childs m_xPackageStream
1719         // can be used as a base of a new stream, that would be copied to result
1720         // storage. The only problem is that some package streams can be accessed from outside
1721         // at the same time ( now solwed by wrappers that remember own position ).
1722 
1723         if ( bEncryptionDataProvided )
1724             pElement->m_pStream->GetCopyOfLastCommit( xTargetStream, aEncryptionData );
1725         else
1726             pElement->m_pStream->GetCopyOfLastCommit( xTargetStream );
1727     }
1728     else
1729         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
1730 }
1731 
1732 //-----------------------------------------------
RemoveStreamRelInfo(const::rtl::OUString & aOriginalName)1733 void OStorage_Impl::RemoveStreamRelInfo( const ::rtl::OUString& aOriginalName )
1734 {
1735     // this method should be used only in OStorage_Impl::Commit() method
1736     // the aOriginalName can be empty, in this case the storage relation info should be removed
1737 
1738     if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_xRelStorage.is() )
1739     {
1740         ::rtl::OUString aRelStreamName = aOriginalName;
1741         aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1742 
1743         if ( m_xRelStorage->hasByName( aRelStreamName ) )
1744             m_xRelStorage->removeElement( aRelStreamName );
1745     }
1746 }
1747 
1748 //-----------------------------------------------
CreateRelStorage()1749 void OStorage_Impl::CreateRelStorage()
1750 {
1751     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1752         return;
1753 
1754     if ( !m_xRelStorage.is() )
1755     {
1756         if ( !m_pRelStorElement )
1757         {
1758             m_pRelStorElement = new SotElement_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ), sal_True, sal_True );
1759             m_pRelStorElement->m_pStorage = CreateNewStorageImpl( embed::ElementModes::WRITE );
1760             if ( m_pRelStorElement->m_pStorage )
1761                 m_pRelStorElement->m_pStorage->m_pParent = NULL; // the relation storage is completely controlled by parent
1762         }
1763 
1764         if ( !m_pRelStorElement->m_pStorage )
1765             OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
1766 
1767         if ( !m_pRelStorElement->m_pStorage )
1768             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1769 
1770         OStorage* pResultStorage = new OStorage( m_pRelStorElement->m_pStorage, sal_False );
1771         m_xRelStorage = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
1772     }
1773 }
1774 
1775 //-----------------------------------------------
CommitStreamRelInfo(SotElement_Impl * pStreamElement)1776 void OStorage_Impl::CommitStreamRelInfo( SotElement_Impl* pStreamElement )
1777 {
1778     // this method should be used only in OStorage_Impl::Commit() method
1779 
1780     // the stream element must be provided
1781     if ( !pStreamElement )
1782         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1783 
1784     if ( m_nStorageType == embed::StorageFormats::OFOPXML && pStreamElement->m_pStream )
1785     {
1786         OSL_ENSURE( pStreamElement->m_aName.getLength(), "The name must not be empty!\n" );
1787 
1788         if ( !m_xRelStorage.is() )
1789         {
1790             // Create new rels storage, this is commit scenario so it must be possible
1791             CreateRelStorage();
1792         }
1793 
1794         pStreamElement->m_pStream->CommitStreamRelInfo( m_xRelStorage, pStreamElement->m_aOriginalName, pStreamElement->m_aName );
1795     }
1796 }
1797 
1798 //-----------------------------------------------
GetRelInfoStreamForName(const::rtl::OUString & aName)1799 uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName( const ::rtl::OUString& aName )
1800 {
1801     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1802     {
1803         ReadContents();
1804         if ( m_xRelStorage.is() )
1805         {
1806             ::rtl::OUString aRelStreamName = aName;
1807             aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1808             if ( m_xRelStorage->hasByName( aRelStreamName ) )
1809             {
1810                 uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
1811                 if ( xStream.is() )
1812                     return xStream->getInputStream();
1813             }
1814         }
1815     }
1816 
1817     return uno::Reference< io::XInputStream >();
1818 }
1819 
1820 //-----------------------------------------------
CommitRelInfo(const uno::Reference<container::XNameContainer> & xNewPackageFolder)1821 void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
1822 {
1823     // this method should be used only in OStorage_Impl::Commit() method
1824     ::rtl::OUString aRelsStorName( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) );
1825 
1826     if ( !xNewPackageFolder.is() )
1827         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1828 
1829     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1830     {
1831         if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
1832             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1833 
1834         if ( m_nRelInfoStatus == RELINFO_CHANGED
1835           || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1836           || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1837         {
1838             if ( m_nRelInfoStatus == RELINFO_CHANGED )
1839             {
1840                 if ( m_aRelInfo.getLength() )
1841                 {
1842                     CreateRelStorage();
1843 
1844                     uno::Reference< io::XStream > xRelsStream =
1845                         m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
1846                                                             embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1847 
1848                     uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
1849                     if ( !xOutStream.is() )
1850                         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1851 
1852                     ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aRelInfo, m_xFactory );
1853 
1854                     // set the mediatype
1855                     uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1856                     xPropSet->setPropertyValue(
1857                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1858                         uno::makeAny( ::rtl::OUString(
1859                             RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1860 
1861                     m_nRelInfoStatus = RELINFO_READ;
1862                 }
1863                 else if ( m_xRelStorage.is() )
1864                     RemoveStreamRelInfo( ::rtl::OUString() ); // remove own rel info
1865             }
1866             else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1867                     || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1868             {
1869                 CreateRelStorage();
1870 
1871                 uno::Reference< io::XStream > xRelsStream =
1872                     m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
1873                                                         embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1874 
1875                 uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
1876                 if ( !xOutputStream.is() )
1877                     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1878 
1879                 uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
1880                 xSeek->seek( 0 );
1881                 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
1882 
1883                 // set the mediatype
1884                 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1885                 xPropSet->setPropertyValue(
1886                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1887                     uno::makeAny( ::rtl::OUString(
1888                         RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1889 
1890                 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1891                 if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1892                 {
1893                     m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1894                     m_nRelInfoStatus = RELINFO_NO_INIT;
1895                 }
1896                 else
1897                     m_nRelInfoStatus = RELINFO_READ;
1898             }
1899         }
1900 
1901         if ( m_xRelStorage.is() )
1902         {
1903             if ( m_xRelStorage->hasElements() )
1904             {
1905                 uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
1906                 if ( xTrans.is() )
1907                     xTrans->commit();
1908             }
1909 
1910             if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
1911                 xNewPackageFolder->removeByName( aRelsStorName );
1912 
1913             if ( !m_xRelStorage->hasElements() )
1914             {
1915                 // the empty relations storage should not be created
1916                 delete m_pRelStorElement;
1917                 m_pRelStorElement = NULL;
1918                 m_xRelStorage = uno::Reference< embed::XStorage >();
1919             }
1920             else if ( m_pRelStorElement && m_pRelStorElement->m_pStorage && xNewPackageFolder.is() )
1921                 m_pRelStorElement->m_pStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
1922         }
1923     }
1924 }
1925 
1926 //=====================================================
1927 // OStorage implementation
1928 //=====================================================
1929 
1930 //-----------------------------------------------
OStorage(uno::Reference<io::XInputStream> xInputStream,sal_Int32 nMode,uno::Sequence<beans::PropertyValue> xProperties,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)1931 OStorage::OStorage( uno::Reference< io::XInputStream > xInputStream,
1932                     sal_Int32 nMode,
1933                     uno::Sequence< beans::PropertyValue > xProperties,
1934                     uno::Reference< lang::XMultiServiceFactory > xFactory,
1935                     sal_Int32 nStorageType )
1936 : m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xFactory, nStorageType ) )
1937 {
1938     m_pImpl->m_pAntiImpl = this;
1939     m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1940 }
1941 
1942 //-----------------------------------------------
OStorage(uno::Reference<io::XStream> xStream,sal_Int32 nMode,uno::Sequence<beans::PropertyValue> xProperties,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)1943 OStorage::OStorage( uno::Reference< io::XStream > xStream,
1944                     sal_Int32 nMode,
1945                     uno::Sequence< beans::PropertyValue > xProperties,
1946                     uno::Reference< lang::XMultiServiceFactory > xFactory,
1947                     sal_Int32 nStorageType )
1948 : m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xFactory, nStorageType ) )
1949 {
1950     m_pImpl->m_pAntiImpl = this;
1951     m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1952 }
1953 
1954 //-----------------------------------------------
OStorage(OStorage_Impl * pImpl,sal_Bool bReadOnlyWrap)1955 OStorage::OStorage( OStorage_Impl* pImpl, sal_Bool bReadOnlyWrap )
1956 : m_pImpl( pImpl )
1957 {
1958     // this call can be done only from OStorage_Impl implementation to create child storage
1959     OSL_ENSURE( m_pImpl && m_pImpl->m_rMutexRef.Is(), "The provided pointer & mutex MUST NOT be empty!\n" );
1960 
1961     m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, bReadOnlyWrap );
1962 
1963     OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
1964                     m_pData->m_bReadOnlyWrap,
1965                 "The wrapper can not allow writing in case implementation does not!\n" );
1966 
1967     if ( !bReadOnlyWrap )
1968         m_pImpl->m_pAntiImpl = this;
1969 }
1970 
1971 //-----------------------------------------------
~OStorage()1972 OStorage::~OStorage()
1973 {
1974     {
1975         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
1976         if ( m_pImpl )
1977         {
1978             m_refCount++; // to call dispose
1979             try {
1980                 dispose();
1981             }
1982             catch( uno::RuntimeException& aRuntimeException )
1983             {
1984                 m_pImpl->AddLog( aRuntimeException.Message );
1985                 m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
1986             }
1987         }
1988     }
1989 
1990     if ( m_pData )
1991     {
1992         if ( m_pData->m_pSubElDispListener )
1993         {
1994             m_pData->m_pSubElDispListener->release();
1995             m_pData->m_pSubElDispListener = NULL;
1996         }
1997 
1998         if ( m_pData->m_pTypeCollection )
1999         {
2000             delete m_pData->m_pTypeCollection;
2001             m_pData->m_pTypeCollection = NULL;
2002         }
2003 
2004         delete m_pData;
2005     }
2006 }
2007 
2008 //-----------------------------------------------
InternalDispose(sal_Bool bNotifyImpl)2009 void SAL_CALL OStorage::InternalDispose( sal_Bool bNotifyImpl )
2010 {
2011     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::InternalDispose" );
2012 
2013     if ( !m_pImpl )
2014     {
2015         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2016         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2017     }
2018 
2019     // the source object is also a kind of locker for the current object
2020     // since the listeners could dispose the object while being notified
2021     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2022     m_pData->m_aListenersContainer.disposeAndClear( aSource );
2023 
2024     if ( m_pData->m_bReadOnlyWrap )
2025     {
2026         OSL_ENSURE( !m_pData->m_aOpenSubComponentsList.size() || m_pData->m_pSubElDispListener,
2027                     "If any subelements are open the listener must exist!\n" );
2028 
2029         if ( m_pData->m_pSubElDispListener )
2030         {
2031             m_pData->m_pSubElDispListener->OwnerIsDisposed();
2032 
2033             // iterate through m_pData->m_aOpenSubComponentsList
2034             // deregister m_pData->m_pSubElDispListener and dispose all of them
2035             if ( !m_pData->m_aOpenSubComponentsList.empty() )
2036             {
2037                 for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2038                     pCompIter != m_pData->m_aOpenSubComponentsList.end(); pCompIter++ )
2039                 {
2040                     uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2041                     if ( xTmp.is() )
2042                     {
2043                         xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
2044                                     static_cast< lang::XEventListener* >( m_pData->m_pSubElDispListener ) ) );
2045 
2046                         try {
2047                             xTmp->dispose();
2048                         } catch( uno::Exception& aException )
2049                         {
2050                             m_pImpl->AddLog( aException.Message );
2051                             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
2052                         }
2053                     }
2054                 }
2055 
2056                 m_pData->m_aOpenSubComponentsList.clear();
2057             }
2058         }
2059 
2060         if ( bNotifyImpl )
2061             m_pImpl->RemoveReadOnlyWrap( *this );
2062     }
2063     else
2064     {
2065         m_pImpl->m_pAntiImpl = NULL;
2066 
2067         if ( bNotifyImpl )
2068         {
2069             if ( m_pData->m_bIsRoot )
2070                 delete m_pImpl;
2071             else
2072             {
2073                 // the noncommited changes for the storage must be removed
2074                 m_pImpl->Revert();
2075             }
2076         }
2077     }
2078 
2079     m_pImpl = NULL;
2080 }
2081 
2082 //-----------------------------------------------
ChildIsDisposed(const uno::Reference<uno::XInterface> & xChild)2083 void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
2084 {
2085     // this method can only be called by child disposing listener
2086 
2087     // this method must not contain any locking
2088     // the locking is done in the listener
2089 
2090     if ( !m_pData->m_aOpenSubComponentsList.empty() )
2091     {
2092         for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2093             pCompIter != m_pData->m_aOpenSubComponentsList.end(); )
2094         {
2095             uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2096             if ( !xTmp.is() || xTmp == xChild )
2097             {
2098                 WeakComponentList::iterator pIterToRemove = pCompIter;
2099                 pCompIter++;
2100                 m_pData->m_aOpenSubComponentsList.erase( pIterToRemove );
2101             }
2102             else
2103                 pCompIter++;
2104         }
2105     }
2106 }
2107 
2108 //-----------------------------------------------
BroadcastModifiedIfNecessary()2109 void OStorage::BroadcastModifiedIfNecessary()
2110 {
2111     // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2112     if ( !m_pImpl )
2113     {
2114         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2115         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2116     }
2117 
2118     if ( !m_pImpl->m_bBroadcastModified )
2119         return;
2120 
2121     m_pImpl->m_bBroadcastModified = sal_False;
2122 
2123     OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2124 
2125     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2126 
2127     ::cppu::OInterfaceContainerHelper* pContainer =
2128             m_pData->m_aListenersContainer.getContainer(
2129                 ::getCppuType( ( const uno::Reference< util::XModifyListener >*) NULL ) );
2130     if ( pContainer )
2131     {
2132         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2133         while ( pIterator.hasMoreElements( ) )
2134         {
2135             ( ( util::XModifyListener* )pIterator.next( ) )->modified( aSource );
2136         }
2137     }
2138 }
2139 
2140 //-----------------------------------------------
BroadcastTransaction(sal_Int8 nMessage)2141 void OStorage::BroadcastTransaction( sal_Int8 nMessage )
2142 /*
2143     1 - preCommit
2144     2 - commited
2145     3 - preRevert
2146     4 - reverted
2147 */
2148 {
2149     // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2150     if ( !m_pImpl )
2151     {
2152         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2153         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2154     }
2155 
2156     OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2157 
2158     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2159 
2160     ::cppu::OInterfaceContainerHelper* pContainer =
2161             m_pData->m_aListenersContainer.getContainer(
2162                 ::getCppuType( ( const uno::Reference< embed::XTransactionListener >*) NULL ) );
2163     if ( pContainer )
2164     {
2165         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2166         while ( pIterator.hasMoreElements( ) )
2167         {
2168             OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
2169 
2170             switch( nMessage )
2171             {
2172                 case STOR_MESS_PRECOMMIT:
2173                     ( ( embed::XTransactionListener* )pIterator.next( ) )->preCommit( aSource );
2174                     break;
2175                 case STOR_MESS_COMMITED:
2176                     ( ( embed::XTransactionListener* )pIterator.next( ) )->commited( aSource );
2177                     break;
2178                 case STOR_MESS_PREREVERT:
2179                     ( ( embed::XTransactionListener* )pIterator.next( ) )->preRevert( aSource );
2180                     break;
2181                 case STOR_MESS_REVERTED:
2182                     ( ( embed::XTransactionListener* )pIterator.next( ) )->reverted( aSource );
2183                     break;
2184             }
2185         }
2186     }
2187 }
2188 
2189 //-----------------------------------------------
OpenStreamElement_Impl(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode,sal_Bool bEncr)2190 SotElement_Impl* OStorage::OpenStreamElement_Impl( const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, sal_Bool bEncr )
2191 {
2192     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2193 
2194     OSL_ENSURE( !m_pData->m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
2195                 "An element can not be opened for writing in readonly storage!\n" );
2196 
2197     SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
2198     if ( !pElement )
2199     {
2200         // element does not exist, check if creation is allowed
2201         if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2202           || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2203           || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2204             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2205 
2206         // create a new StreamElement and insert it into the list
2207         pElement = m_pImpl->InsertStream( aStreamName, bEncr );
2208     }
2209     else if ( pElement->m_bIsStorage )
2210     {
2211         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2212     }
2213 
2214     OSL_ENSURE( pElement, "In case element can not be created an exception must be thrown!" );
2215 
2216     if ( !pElement->m_pStream )
2217         m_pImpl->OpenSubStream( pElement );
2218 
2219     if ( !pElement->m_pStream )
2220         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2221 
2222     return pElement;
2223 }
2224 
2225 //-----------------------------------------------
MakeLinkToSubComponent_Impl(const uno::Reference<lang::XComponent> & xComponent)2226 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
2227 {
2228     if ( !xComponent.is() )
2229         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2230 
2231     if ( !m_pData->m_pSubElDispListener )
2232     {
2233         m_pData->m_pSubElDispListener = new OChildDispListener_Impl( *this );
2234         m_pData->m_pSubElDispListener->acquire();
2235     }
2236 
2237     xComponent->addEventListener( uno::Reference< lang::XEventListener >(
2238         static_cast< ::cppu::OWeakObject* >( m_pData->m_pSubElDispListener ), uno::UNO_QUERY ) );
2239 
2240     m_pData->m_aOpenSubComponentsList.push_back( xComponent );
2241 }
2242 
2243 //____________________________________________________________________________________________________
2244 //  XInterface
2245 //____________________________________________________________________________________________________
2246 
2247 //-----------------------------------------------
queryInterface(const uno::Type & rType)2248 uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
2249         throw( uno::RuntimeException )
2250 {
2251     uno::Any aReturn;
2252 
2253     // common interfaces
2254     aReturn <<= ::cppu::queryInterface
2255                 (   rType
2256                 ,   static_cast<lang::XTypeProvider*> ( this )
2257                 ,   static_cast<embed::XStorage*> ( this )
2258                 ,   static_cast<embed::XStorage2*> ( this )
2259                 ,   static_cast<embed::XTransactedObject*> ( this )
2260                 ,   static_cast<embed::XTransactionBroadcaster*> ( this )
2261                 ,   static_cast<util::XModifiable*> ( this )
2262                 ,   static_cast<container::XNameAccess*> ( this )
2263                 ,   static_cast<container::XElementAccess*> ( this )
2264                 ,   static_cast<lang::XComponent*> ( this )
2265                 ,   static_cast<beans::XPropertySet*> ( this )
2266                 ,   static_cast<embed::XOptimizedStorage*> ( this ) );
2267 
2268     if ( aReturn.hasValue() == sal_True )
2269         return aReturn ;
2270 
2271     aReturn <<= ::cppu::queryInterface
2272                 (   rType
2273                 ,   static_cast<embed::XHierarchicalStorageAccess*> ( this )
2274                 ,   static_cast<embed::XHierarchicalStorageAccess2*> ( this ) );
2275 
2276     if ( aReturn.hasValue() == sal_True )
2277         return aReturn ;
2278 
2279     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2280     {
2281         if ( m_pData->m_bIsRoot )
2282         {
2283             aReturn <<= ::cppu::queryInterface
2284                         (   rType
2285                         ,   static_cast<embed::XStorageRawAccess*> ( this )
2286                         ,   static_cast<embed::XEncryptionProtectedSource*> ( this )
2287                         ,   static_cast<embed::XEncryptionProtectedSource2*> ( this )
2288                         ,   static_cast<embed::XEncryptionProtectedStorage*> ( this ) );
2289         }
2290         else
2291         {
2292             aReturn <<= ::cppu::queryInterface
2293                         (   rType
2294                         ,   static_cast<embed::XStorageRawAccess*> ( this ) );
2295         }
2296     }
2297     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2298     {
2299         aReturn <<= ::cppu::queryInterface
2300                     (   rType
2301                     ,   static_cast<embed::XRelationshipAccess*> ( this ) );
2302     }
2303 
2304     if ( aReturn.hasValue() == sal_True )
2305         return aReturn ;
2306 
2307     return OWeakObject::queryInterface( rType );
2308 }
2309 
2310 //-----------------------------------------------
acquire()2311 void SAL_CALL OStorage::acquire() throw()
2312 {
2313     OWeakObject::acquire();
2314 }
2315 
2316 //-----------------------------------------------
release()2317 void SAL_CALL OStorage::release() throw()
2318 {
2319     OWeakObject::release();
2320 }
2321 
2322 //____________________________________________________________________________________________________
2323 //  XTypeProvider
2324 //____________________________________________________________________________________________________
2325 
2326 //-----------------------------------------------
getTypes()2327 uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
2328         throw( uno::RuntimeException )
2329 {
2330     if ( m_pData->m_pTypeCollection == NULL )
2331     {
2332         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2333 
2334         if ( m_pData->m_pTypeCollection == NULL )
2335         {
2336             if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2337             {
2338                 if ( m_pData->m_bIsRoot )
2339                 {
2340                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2341                                     (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2342                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2343                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage2 >* )NULL )
2344                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2345                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2346                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2347                                     ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2348                                     ,   ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedStorage >* )NULL )
2349                                     ,   ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource2 >* )NULL )
2350                                     ,   ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
2351                                     ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2352                 }
2353                 else
2354                 {
2355                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2356                                     (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2357                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2358                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage2 >* )NULL )
2359                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2360                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2361                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2362                                     ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2363                                     ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2364                 }
2365             }
2366             else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2367             {
2368                 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2369                                 (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2370                                 ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2371                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2372                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2373                                 ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2374                                 ,   ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
2375                                 ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2376             }
2377             else
2378             {
2379                 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2380                                 (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2381                                 ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2382                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2383                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2384                                 ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2385                                 ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2386             }
2387         }
2388     }
2389 
2390     return m_pData->m_pTypeCollection->getTypes() ;
2391 }
2392 
2393 namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; }
2394 
2395 //-----------------------------------------------
getImplementationId()2396 uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
2397         throw( uno::RuntimeException )
2398 {
2399     ::cppu::OImplementationId &rID = lcl_ImplId::get();
2400     return rID.getImplementationId();
2401 }
2402 
2403 //____________________________________________________________________________________________________
2404 //  XStorage
2405 //____________________________________________________________________________________________________
2406 
2407 
2408 //-----------------------------------------------
copyToStorage(const uno::Reference<embed::XStorage> & xDest)2409 void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
2410         throw ( embed::InvalidStorageException,
2411                 io::IOException,
2412                 lang::IllegalArgumentException,
2413                 embed::StorageWrappedTargetException,
2414                 uno::RuntimeException )
2415 {
2416     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyToStorage" );
2417 
2418     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2419 
2420     if ( !m_pImpl )
2421     {
2422         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2423         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2424     }
2425 
2426     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
2427         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
2428 
2429     try {
2430         m_pImpl->CopyToStorage( xDest, sal_False );
2431     }
2432     catch( embed::InvalidStorageException& aInvalidStorageException )
2433     {
2434         m_pImpl->AddLog( aInvalidStorageException.Message );
2435         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2436         throw;
2437     }
2438     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2439     {
2440         m_pImpl->AddLog( aIllegalArgumentException.Message );
2441         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2442         throw;
2443     }
2444     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2445     {
2446         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2447         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2448         throw;
2449     }
2450     catch( io::IOException& aIOException )
2451     {
2452         m_pImpl->AddLog( aIOException.Message );
2453         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2454         throw;
2455     }
2456     catch( uno::RuntimeException& aRuntimeException )
2457     {
2458         m_pImpl->AddLog( aRuntimeException.Message );
2459         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2460         throw;
2461     }
2462     catch( uno::Exception& aException )
2463     {
2464         m_pImpl->AddLog( aException.Message );
2465         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2466 
2467         uno::Any aCaught( ::cppu::getCaughtException() );
2468         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy storage!" ) ),
2469                                                  uno::Reference< io::XInputStream >(),
2470                                                  aCaught );
2471     }
2472 }
2473 
2474 //-----------------------------------------------
openStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode)2475 uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
2476     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
2477         throw ( embed::InvalidStorageException,
2478                 lang::IllegalArgumentException,
2479                 packages::WrongPasswordException,
2480                 io::IOException,
2481                 embed::StorageWrappedTargetException,
2482                 uno::RuntimeException )
2483 {
2484     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStreamElement" );
2485 
2486     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2487 
2488     if ( !m_pImpl )
2489     {
2490         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2491         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2492     }
2493 
2494     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2495         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2496 
2497     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2498       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2499         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
2500 
2501     if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2502         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
2503 
2504     uno::Reference< io::XStream > xResult;
2505     try
2506     {
2507         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_False );
2508         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
2509 
2510         xResult = pElement->m_pStream->GetStream( nOpenMode, sal_False );
2511         OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
2512 
2513         if ( m_pData->m_bReadOnlyWrap )
2514         {
2515             // before the storage disposes the stream it must deregister itself as listener
2516             uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
2517             if ( !xStreamComponent.is() )
2518                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2519 
2520             MakeLinkToSubComponent_Impl( xStreamComponent );
2521         }
2522     }
2523     catch( embed::InvalidStorageException& aInvalidStorageException )
2524     {
2525         m_pImpl->AddLog( aInvalidStorageException.Message );
2526         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2527         throw;
2528     }
2529     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2530     {
2531         m_pImpl->AddLog( aIllegalArgumentException.Message );
2532         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2533         throw;
2534     }
2535     catch( packages::WrongPasswordException& aWrongPasswordException )
2536     {
2537         m_pImpl->AddLog( aWrongPasswordException.Message );
2538         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2539         throw;
2540     }
2541     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2542     {
2543         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2544         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2545         throw;
2546     }
2547     catch( io::IOException& aIOException )
2548     {
2549         m_pImpl->AddLog( aIOException.Message );
2550         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2551         throw;
2552     }
2553     catch( uno::RuntimeException& aRuntimeException )
2554     {
2555         m_pImpl->AddLog( aRuntimeException.Message );
2556         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2557         throw;
2558     }
2559     catch( uno::Exception& aException )
2560     {
2561         m_pImpl->AddLog( aException.Message );
2562         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2563 
2564         uno::Any aCaught( ::cppu::getCaughtException() );
2565         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open stream element!" ) ),
2566                                                  uno::Reference< io::XInputStream >(),
2567                                                  aCaught );
2568     }
2569 
2570     aGuard.clear();
2571 
2572     BroadcastModifiedIfNecessary();
2573 
2574     return xResult;
2575 }
2576 
2577 //-----------------------------------------------
openEncryptedStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode,const::rtl::OUString & aPass)2578 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
2579     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const ::rtl::OUString& aPass )
2580         throw ( embed::InvalidStorageException,
2581                 lang::IllegalArgumentException,
2582                 packages::NoEncryptionException,
2583                 packages::WrongPasswordException,
2584                 io::IOException,
2585                 embed::StorageWrappedTargetException,
2586                 uno::RuntimeException )
2587 {
2588     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStreamElement" );
2589 
2590     return openEncryptedStream( aStreamName, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2591 }
2592 
2593 //-----------------------------------------------
openStorageElement(const::rtl::OUString & aStorName,sal_Int32 nStorageMode)2594 uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
2595             const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
2596         throw ( embed::InvalidStorageException,
2597                 lang::IllegalArgumentException,
2598                 io::IOException,
2599                 embed::StorageWrappedTargetException,
2600                 uno::RuntimeException )
2601 {
2602     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStorageElement" );
2603 
2604     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2605 
2606     if ( !m_pImpl )
2607     {
2608         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2609         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2610     }
2611 
2612     if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2613         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2614 
2615     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2616       && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2617         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2618 
2619     if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2620         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
2621 
2622     if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
2623       && !( nStorageMode & embed::ElementModes::WRITE ) )
2624         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
2625 
2626     // it's allways possible to read written storage in this implementation
2627     nStorageMode |= embed::ElementModes::READ;
2628 
2629     uno::Reference< embed::XStorage > xResult;
2630     try
2631     {
2632         SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2633         if ( !pElement )
2634         {
2635             // element does not exist, check if creation is allowed
2636             if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2637             || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2638             || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2639                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2640 
2641             // create a new StorageElement and insert it into the list
2642             pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
2643         }
2644         else if ( !pElement->m_bIsStorage )
2645         {
2646             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2647         }
2648         else if ( pElement->m_pStorage )
2649         {
2650             // storage has already been opened; it may be opened another time, if it the mode allows to do so
2651             if ( pElement->m_pStorage->m_pAntiImpl )
2652             {
2653                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2654             }
2655             else if ( !pElement->m_pStorage->m_aReadOnlyWrapList.empty()
2656                     && ( nStorageMode & embed::ElementModes::WRITE ) )
2657             {
2658                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2659             }
2660             else
2661             {
2662                 // in case parent storage allows writing the readonly mode of the child storage is
2663                 // virtual, that means that it is just enough to change the flag to let it be writable
2664                 // and since there is no AntiImpl nobody should be notified about it
2665                 pElement->m_pStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
2666 
2667                 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
2668                 {
2669                     for ( SotElementList_Impl::iterator pElementIter = pElement->m_pStorage->m_aChildrenList.begin();
2670                         pElementIter != pElement->m_pStorage->m_aChildrenList.end(); )
2671                     {
2672                         SotElement_Impl* pElementToDel = (*pElementIter);
2673                         pElementIter++;
2674 
2675                         m_pImpl->RemoveElement( pElementToDel );
2676                     }
2677                 }
2678             }
2679         }
2680 
2681         if ( !pElement->m_pStorage )
2682             m_pImpl->OpenSubStorage( pElement, nStorageMode );
2683 
2684         if ( !pElement->m_pStorage )
2685             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
2686 
2687         sal_Bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
2688         OStorage* pResultStorage = new OStorage( pElement->m_pStorage, bReadOnlyWrap );
2689         xResult = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
2690 
2691         if ( bReadOnlyWrap )
2692         {
2693             // Before this call is done the object must be refcounted already
2694             pElement->m_pStorage->SetReadOnlyWrap( *pResultStorage );
2695 
2696             // before the storage disposes the stream it must deregister itself as listener
2697             uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY );
2698             if ( !xStorageComponent.is() )
2699                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2700 
2701             MakeLinkToSubComponent_Impl( xStorageComponent );
2702         }
2703     }
2704     catch( embed::InvalidStorageException& aInvalidStorageException )
2705     {
2706         m_pImpl->AddLog( aInvalidStorageException.Message );
2707         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2708         throw;
2709     }
2710     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2711     {
2712         m_pImpl->AddLog( aIllegalArgumentException.Message );
2713         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2714         throw;
2715     }
2716     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2717     {
2718         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2719         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2720         throw;
2721     }
2722     catch( io::IOException& aIOException )
2723     {
2724         m_pImpl->AddLog( aIOException.Message );
2725         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2726         throw;
2727     }
2728     catch( uno::RuntimeException& aRuntimeException )
2729     {
2730         m_pImpl->AddLog( aRuntimeException.Message );
2731         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2732         throw;
2733     }
2734     catch( uno::Exception& aException )
2735     {
2736         m_pImpl->AddLog( aException.Message );
2737         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2738 
2739         uno::Any aCaught( ::cppu::getCaughtException() );
2740         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open storage!" ) ),
2741                                                  uno::Reference< io::XInputStream >(),
2742                                                  aCaught );
2743     }
2744 
2745     return xResult;
2746 }
2747 
2748 //-----------------------------------------------
cloneStreamElement(const::rtl::OUString & aStreamName)2749 uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
2750         throw ( embed::InvalidStorageException,
2751                 lang::IllegalArgumentException,
2752                 packages::WrongPasswordException,
2753                 io::IOException,
2754                 embed::StorageWrappedTargetException,
2755                 uno::RuntimeException )
2756 {
2757     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneStreamElement" );
2758 
2759     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2760 
2761     if ( !m_pImpl )
2762     {
2763         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2764         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2765     }
2766 
2767     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2768         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2769 
2770     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2771       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2772         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2773 
2774     try
2775     {
2776         uno::Reference< io::XStream > xResult;
2777         m_pImpl->CloneStreamElement( aStreamName, sal_False, ::comphelper::SequenceAsHashMap(), xResult );
2778         if ( !xResult.is() )
2779             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2780         return xResult;
2781     }
2782     catch( embed::InvalidStorageException& aInvalidStorageException )
2783     {
2784         m_pImpl->AddLog( aInvalidStorageException.Message );
2785         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2786         throw;
2787     }
2788     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2789     {
2790         m_pImpl->AddLog( aIllegalArgumentException.Message );
2791         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2792         throw;
2793     }
2794     catch( packages::WrongPasswordException& aWrongPasswordException )
2795     {
2796         m_pImpl->AddLog( aWrongPasswordException.Message );
2797         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2798         throw;
2799     }
2800     catch( io::IOException& aIOException )
2801     {
2802         m_pImpl->AddLog( aIOException.Message );
2803         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2804         throw;
2805     }
2806     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2807     {
2808         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2809         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2810         throw;
2811     }
2812     catch( uno::RuntimeException& aRuntimeException )
2813     {
2814         m_pImpl->AddLog( aRuntimeException.Message );
2815         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2816         throw;
2817     }
2818     catch( uno::Exception& aException )
2819     {
2820         m_pImpl->AddLog( aException.Message );
2821         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2822 
2823         uno::Any aCaught( ::cppu::getCaughtException() );
2824         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't clone stream!" ) ),
2825                                                  uno::Reference< io::XInputStream >(),
2826                                                  aCaught );
2827     }
2828 }
2829 
2830 //-----------------------------------------------
cloneEncryptedStreamElement(const::rtl::OUString & aStreamName,const::rtl::OUString & aPass)2831 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
2832     const ::rtl::OUString& aStreamName,
2833     const ::rtl::OUString& aPass )
2834         throw ( embed::InvalidStorageException,
2835                 lang::IllegalArgumentException,
2836                 packages::NoEncryptionException,
2837                 packages::WrongPasswordException,
2838                 io::IOException,
2839                 embed::StorageWrappedTargetException,
2840                 uno::RuntimeException )
2841 {
2842     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStreamElement" );
2843 
2844     return cloneEncryptedStream( aStreamName, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2845 }
2846 
2847 //-----------------------------------------------
copyLastCommitTo(const uno::Reference<embed::XStorage> & xTargetStorage)2848 void SAL_CALL OStorage::copyLastCommitTo(
2849             const uno::Reference< embed::XStorage >& xTargetStorage )
2850         throw ( embed::InvalidStorageException,
2851                 lang::IllegalArgumentException,
2852                 io::IOException,
2853                 embed::StorageWrappedTargetException,
2854                 uno::RuntimeException )
2855 {
2856     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyLastCommitTo" );
2857 
2858     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2859 
2860     if ( !m_pImpl )
2861     {
2862         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2863         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2864     }
2865 
2866     try
2867     {
2868         m_pImpl->CopyLastCommitTo( xTargetStorage );
2869     }
2870     catch( embed::InvalidStorageException& aInvalidStorageException )
2871     {
2872         m_pImpl->AddLog( aInvalidStorageException.Message );
2873         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2874         throw;
2875     }
2876     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2877     {
2878         m_pImpl->AddLog( aIllegalArgumentException.Message );
2879         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2880         throw;
2881     }
2882     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2883     {
2884         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2885         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2886         throw;
2887     }
2888     catch( io::IOException& aIOException )
2889     {
2890         m_pImpl->AddLog( aIOException.Message );
2891         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2892         throw;
2893     }
2894     catch( uno::RuntimeException& aRuntimeException )
2895     {
2896         m_pImpl->AddLog( aRuntimeException.Message );
2897         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2898         throw;
2899     }
2900     catch( uno::Exception& aException )
2901     {
2902         m_pImpl->AddLog( aException.Message );
2903         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2904 
2905         uno::Any aCaught( ::cppu::getCaughtException() );
2906         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy last commit version!" ) ),
2907                                                  uno::Reference< io::XInputStream >(),
2908                                                  aCaught );
2909     }
2910 
2911 }
2912 
2913 //-----------------------------------------------
copyStorageElementLastCommitTo(const::rtl::OUString & aStorName,const uno::Reference<embed::XStorage> & xTargetStorage)2914 void SAL_CALL OStorage::copyStorageElementLastCommitTo(
2915             const ::rtl::OUString& aStorName,
2916             const uno::Reference< embed::XStorage >& xTargetStorage )
2917         throw ( embed::InvalidStorageException,
2918                 lang::IllegalArgumentException,
2919                 io::IOException,
2920                 embed::StorageWrappedTargetException,
2921                 uno::RuntimeException )
2922 {
2923     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyStorageElementLastCommitTo" );
2924 
2925     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2926 
2927     if ( !m_pImpl )
2928     {
2929         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2930         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2931     }
2932 
2933     if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2934         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2935 
2936     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2937       && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2938         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2939 
2940     // it's allways possible to read written storage in this implementation
2941     sal_Int32 nStorageMode = embed::ElementModes::READ;
2942 
2943     try
2944     {
2945         SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2946         if ( !pElement )
2947         {
2948             // element does not exist, throw exception
2949             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2950         }
2951         else if ( !pElement->m_bIsStorage )
2952         {
2953             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2954         }
2955 
2956         if ( !pElement->m_pStorage )
2957             m_pImpl->OpenSubStorage( pElement, nStorageMode );
2958 
2959         uno::Reference< embed::XStorage > xResult;
2960         if ( pElement->m_pStorage )
2961         {
2962             // the existence of m_pAntiImpl of the child is not interesting,
2963             // the copy will be created internally
2964 
2965             pElement->m_pStorage->CopyLastCommitTo( xTargetStorage );
2966         }
2967         else
2968             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
2969     }
2970     catch( embed::InvalidStorageException& aInvalidStorageException )
2971     {
2972         m_pImpl->AddLog( aInvalidStorageException.Message );
2973         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2974         throw;
2975     }
2976     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2977     {
2978         m_pImpl->AddLog( aIllegalArgumentException.Message );
2979         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2980         throw;
2981     }
2982     catch( io::IOException& aIOException )
2983     {
2984         m_pImpl->AddLog( aIOException.Message );
2985         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2986         throw;
2987     }
2988     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2989     {
2990         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2991         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2992         throw;
2993     }
2994     catch( uno::RuntimeException& aRuntimeException )
2995     {
2996         m_pImpl->AddLog( aRuntimeException.Message );
2997         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2998         throw;
2999     }
3000     catch( uno::Exception& aException )
3001     {
3002         m_pImpl->AddLog( aException.Message );
3003         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3004 
3005         uno::Any aCaught( ::cppu::getCaughtException() );
3006         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy last commit element version!" ) ),
3007                                                  uno::Reference< io::XInputStream >(),
3008                                                  aCaught );
3009     }
3010 }
3011 
3012 //-----------------------------------------------
isStreamElement(const::rtl::OUString & aElementName)3013 sal_Bool SAL_CALL OStorage::isStreamElement( const ::rtl::OUString& aElementName )
3014         throw ( embed::InvalidStorageException,
3015                 lang::IllegalArgumentException,
3016                 container::NoSuchElementException,
3017                 uno::RuntimeException )
3018 {
3019     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3020 
3021     if ( !m_pImpl )
3022     {
3023         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3024         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3025     }
3026 
3027     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3028         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3029 
3030     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3031       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3032         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
3033 
3034     SotElement_Impl* pElement = NULL;
3035 
3036     try
3037     {
3038         pElement = m_pImpl->FindElement( aElementName );
3039     }
3040     catch( embed::InvalidStorageException& aInvalidStorageException )
3041     {
3042         m_pImpl->AddLog( aInvalidStorageException.Message );
3043         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3044         throw;
3045     }
3046     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3047     {
3048         m_pImpl->AddLog( aIllegalArgumentException.Message );
3049         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3050         throw;
3051     }
3052     catch( container::NoSuchElementException& aNoSuchElementException )
3053     {
3054         m_pImpl->AddLog( aNoSuchElementException.Message );
3055         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3056         throw;
3057     }
3058     catch( uno::RuntimeException& aRuntimeException )
3059     {
3060         m_pImpl->AddLog( aRuntimeException.Message );
3061         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3062         throw;
3063     }
3064     catch( uno::Exception& aException )
3065     {
3066         m_pImpl->AddLog( aException.Message );
3067         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3068 
3069         uno::Any aCaught( ::cppu::getCaughtException() );
3070         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't detect whether it is a stream!" ) ),
3071                                                  uno::Reference< io::XInputStream >(),
3072                                                  aCaught );
3073     }
3074 
3075     if ( !pElement )
3076         throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3077 
3078     return !pElement->m_bIsStorage;
3079 }
3080 
3081 //-----------------------------------------------
isStorageElement(const::rtl::OUString & aElementName)3082 sal_Bool SAL_CALL OStorage::isStorageElement( const ::rtl::OUString& aElementName )
3083         throw ( embed::InvalidStorageException,
3084                 lang::IllegalArgumentException,
3085                 container::NoSuchElementException,
3086                 uno::RuntimeException )
3087 {
3088     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3089 
3090     if ( !m_pImpl )
3091     {
3092         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3093         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3094     }
3095 
3096     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3097         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3098 
3099     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3100       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3101         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
3102 
3103     SotElement_Impl* pElement = NULL;
3104 
3105     try
3106     {
3107         pElement = m_pImpl->FindElement( aElementName );
3108     }
3109     catch( embed::InvalidStorageException& aInvalidStorageException )
3110     {
3111         m_pImpl->AddLog( aInvalidStorageException.Message );
3112         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3113         throw;
3114     }
3115     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3116     {
3117         m_pImpl->AddLog( aIllegalArgumentException.Message );
3118         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3119         throw;
3120     }
3121     catch( container::NoSuchElementException& aNoSuchElementException )
3122     {
3123         m_pImpl->AddLog( aNoSuchElementException.Message );
3124         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3125         throw;
3126     }
3127     catch( uno::RuntimeException& aRuntimeException )
3128     {
3129         m_pImpl->AddLog( aRuntimeException.Message );
3130         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3131         throw;
3132     }
3133     catch( uno::Exception& aException )
3134     {
3135         m_pImpl->AddLog( aException.Message );
3136         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3137 
3138         uno::Any aCaught( ::cppu::getCaughtException() );
3139         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "can't detect whether it is a storage" ) ),
3140                                                  uno::Reference< io::XInputStream >(),
3141                                                  aCaught );
3142     }
3143 
3144     if ( !pElement )
3145         throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3146 
3147     return pElement->m_bIsStorage;
3148 }
3149 
3150 //-----------------------------------------------
removeElement(const::rtl::OUString & aElementName)3151 void SAL_CALL OStorage::removeElement( const ::rtl::OUString& aElementName )
3152         throw ( embed::InvalidStorageException,
3153                 lang::IllegalArgumentException,
3154                 container::NoSuchElementException,
3155                 io::IOException,
3156                 embed::StorageWrappedTargetException,
3157                 uno::RuntimeException )
3158 {
3159     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeElement" );
3160 
3161     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3162 
3163     if ( !m_pImpl )
3164     {
3165         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3166         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3167     }
3168 
3169     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3170         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3171 
3172     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3173       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3174         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
3175 
3176     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3177         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3178 
3179     try
3180     {
3181         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3182 
3183         if ( !pElement )
3184             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3185 
3186         m_pImpl->RemoveElement( pElement );
3187 
3188         m_pImpl->m_bIsModified = sal_True;
3189         m_pImpl->m_bBroadcastModified = sal_True;
3190     }
3191     catch( embed::InvalidStorageException& aInvalidStorageException )
3192     {
3193         m_pImpl->AddLog( aInvalidStorageException.Message );
3194         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3195         throw;
3196     }
3197     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3198     {
3199         m_pImpl->AddLog( aIllegalArgumentException.Message );
3200         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3201         throw;
3202     }
3203     catch( container::NoSuchElementException& aNoSuchElementException )
3204     {
3205         m_pImpl->AddLog( aNoSuchElementException.Message );
3206         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3207         throw;
3208     }
3209     catch( io::IOException& aIOException )
3210     {
3211         m_pImpl->AddLog( aIOException.Message );
3212         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3213         throw;
3214     }
3215     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3216     {
3217         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3218         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3219         throw;
3220     }
3221     catch( uno::RuntimeException& aRuntimeException )
3222     {
3223         m_pImpl->AddLog( aRuntimeException.Message );
3224         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3225         throw;
3226     }
3227     catch( uno::Exception& aException )
3228     {
3229         m_pImpl->AddLog( aException.Message );
3230         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3231 
3232         uno::Any aCaught( ::cppu::getCaughtException() );
3233         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't remove element!" ) ),
3234                                                  uno::Reference< io::XInputStream >(),
3235                                                  aCaught );
3236     }
3237 
3238     aGuard.clear();
3239 
3240     BroadcastModifiedIfNecessary();
3241 }
3242 
3243 //-----------------------------------------------
renameElement(const::rtl::OUString & aElementName,const::rtl::OUString & aNewName)3244 void SAL_CALL OStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
3245         throw ( embed::InvalidStorageException,
3246                 lang::IllegalArgumentException,
3247                 container::NoSuchElementException,
3248                 container::ElementExistException,
3249                 io::IOException,
3250                 embed::StorageWrappedTargetException,
3251                 uno::RuntimeException )
3252 {
3253     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::renameElement" );
3254 
3255     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3256 
3257     if ( !m_pImpl )
3258     {
3259         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3260         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3261     }
3262 
3263     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3264       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3265         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3266 
3267     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3268       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3269         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3270         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // TODO: unacceptable element name
3271 
3272     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3273         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3274 
3275     try
3276     {
3277         SotElement_Impl* pRefElement = m_pImpl->FindElement( aNewName );
3278         if ( pRefElement )
3279             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3280 
3281         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3282         if ( !pElement )
3283             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3284 
3285         pElement->m_aName = aNewName;
3286 
3287         m_pImpl->m_bIsModified = sal_True;
3288         m_pImpl->m_bBroadcastModified = sal_True;
3289     }
3290     catch( embed::InvalidStorageException& aInvalidStorageException )
3291     {
3292         m_pImpl->AddLog( aInvalidStorageException.Message );
3293         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3294         throw;
3295     }
3296     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3297     {
3298         m_pImpl->AddLog( aIllegalArgumentException.Message );
3299         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3300         throw;
3301     }
3302     catch( container::NoSuchElementException& aNoSuchElementException )
3303     {
3304         m_pImpl->AddLog( aNoSuchElementException.Message );
3305         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3306         throw;
3307     }
3308     catch( container::ElementExistException& aElementExistException )
3309     {
3310         m_pImpl->AddLog( aElementExistException.Message );
3311         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3312         throw;
3313     }
3314     catch( io::IOException& aIOException )
3315     {
3316         m_pImpl->AddLog( aIOException.Message );
3317         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3318         throw;
3319     }
3320     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3321     {
3322         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3323         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3324         throw;
3325     }
3326     catch( uno::RuntimeException& aRuntimeException )
3327     {
3328         m_pImpl->AddLog( aRuntimeException.Message );
3329         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3330         throw;
3331     }
3332     catch( uno::Exception& aException )
3333     {
3334         m_pImpl->AddLog( aException.Message );
3335         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3336 
3337         uno::Any aCaught( ::cppu::getCaughtException() );
3338         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't rename element!" ) ),
3339                                                  uno::Reference< io::XInputStream >(),
3340                                                  aCaught );
3341     }
3342 
3343     aGuard.clear();
3344 
3345     BroadcastModifiedIfNecessary();
3346 }
3347 
3348 //-----------------------------------------------
copyElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)3349 void SAL_CALL OStorage::copyElementTo(  const ::rtl::OUString& aElementName,
3350                                         const uno::Reference< embed::XStorage >& xDest,
3351                                         const ::rtl::OUString& aNewName )
3352         throw ( embed::InvalidStorageException,
3353                 lang::IllegalArgumentException,
3354                 container::NoSuchElementException,
3355                 container::ElementExistException,
3356                 io::IOException,
3357                 embed::StorageWrappedTargetException,
3358                 uno::RuntimeException )
3359 {
3360     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementTo" );
3361 
3362     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3363 
3364     if ( !m_pImpl )
3365     {
3366         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3367         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3368     }
3369 
3370     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3371       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3372         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3373 
3374     if ( !xDest.is() )
3375         // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3376         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3377 
3378     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3379       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3380         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3381         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3382 
3383     try
3384     {
3385         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3386         if ( !pElement )
3387             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3388 
3389         uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3390         if ( !xNameAccess.is() )
3391             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3392 
3393         if ( xNameAccess->hasByName( aNewName ) )
3394             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3395 
3396         m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3397     }
3398     catch( embed::InvalidStorageException& aInvalidStorageException )
3399     {
3400         m_pImpl->AddLog( aInvalidStorageException.Message );
3401         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3402         throw;
3403     }
3404     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3405     {
3406         m_pImpl->AddLog( aIllegalArgumentException.Message );
3407         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3408         throw;
3409     }
3410     catch( container::NoSuchElementException& aNoSuchElementException )
3411     {
3412         m_pImpl->AddLog( aNoSuchElementException.Message );
3413         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3414         throw;
3415     }
3416     catch( container::ElementExistException& aElementExistException )
3417     {
3418         m_pImpl->AddLog( aElementExistException.Message );
3419         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3420         throw;
3421     }
3422     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3423     {
3424         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3425         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3426         throw;
3427     }
3428     catch( io::IOException& aIOException )
3429     {
3430         m_pImpl->AddLog( aIOException.Message );
3431         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3432         throw;
3433     }
3434     catch( uno::RuntimeException& aRuntimeException )
3435     {
3436         m_pImpl->AddLog( aRuntimeException.Message );
3437         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3438         throw;
3439     }
3440     catch( uno::Exception& aException )
3441     {
3442         m_pImpl->AddLog( aException.Message );
3443         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3444 
3445         uno::Any aCaught( ::cppu::getCaughtException() );
3446         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy element!" ) ),
3447                                                  uno::Reference< io::XInputStream >(),
3448                                                  aCaught );
3449     }
3450 }
3451 
3452 
3453 //-----------------------------------------------
moveElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)3454 void SAL_CALL OStorage::moveElementTo(  const ::rtl::OUString& aElementName,
3455                                         const uno::Reference< embed::XStorage >& xDest,
3456                                         const ::rtl::OUString& aNewName )
3457         throw ( embed::InvalidStorageException,
3458                 lang::IllegalArgumentException,
3459                 container::NoSuchElementException,
3460                 container::ElementExistException,
3461                 io::IOException,
3462                 embed::StorageWrappedTargetException,
3463                 uno::RuntimeException )
3464 {
3465     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::moveElementTo" );
3466 
3467     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3468 
3469     if ( !m_pImpl )
3470     {
3471         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3472         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3473     }
3474 
3475     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3476       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3477         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3478 
3479     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3480         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3481 
3482     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3483       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3484         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3485         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3486 
3487     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3488         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3489 
3490     try
3491     {
3492         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3493         if ( !pElement )
3494             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3495 
3496         uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3497         if ( !xNameAccess.is() )
3498             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3499 
3500         if ( xNameAccess->hasByName( aNewName ) )
3501             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3502 
3503         m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3504 
3505         m_pImpl->RemoveElement( pElement );
3506 
3507         m_pImpl->m_bIsModified = sal_True;
3508         m_pImpl->m_bBroadcastModified = sal_True;
3509     }
3510     catch( embed::InvalidStorageException& aInvalidStorageException )
3511     {
3512         m_pImpl->AddLog( aInvalidStorageException.Message );
3513         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3514         throw;
3515     }
3516     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3517     {
3518         m_pImpl->AddLog( aIllegalArgumentException.Message );
3519         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3520         throw;
3521     }
3522     catch( container::NoSuchElementException& aNoSuchElementException )
3523     {
3524         m_pImpl->AddLog( aNoSuchElementException.Message );
3525         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3526         throw;
3527     }
3528     catch( container::ElementExistException& aElementExistException )
3529     {
3530         m_pImpl->AddLog( aElementExistException.Message );
3531         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3532         throw;
3533     }
3534     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3535     {
3536         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3537         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3538         throw;
3539     }
3540     catch( io::IOException& aIOException )
3541     {
3542         m_pImpl->AddLog( aIOException.Message );
3543         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3544         throw;
3545     }
3546     catch( uno::RuntimeException& aRuntimeException )
3547     {
3548         m_pImpl->AddLog( aRuntimeException.Message );
3549         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3550         throw;
3551     }
3552     catch( uno::Exception& aException )
3553     {
3554         m_pImpl->AddLog( aException.Message );
3555         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3556 
3557         uno::Any aCaught( ::cppu::getCaughtException() );
3558         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't move element!" ) ),
3559                                                  uno::Reference< io::XInputStream >(),
3560                                                  aCaught );
3561     }
3562 
3563     aGuard.clear();
3564 
3565     BroadcastModifiedIfNecessary();
3566 }
3567 
3568 //____________________________________________________________________________________________________
3569 //  XStorage2
3570 //____________________________________________________________________________________________________
3571 
3572 //-----------------------------------------------
openEncryptedStream(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode,const uno::Sequence<beans::NamedValue> & aEncryptionData)3573 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStream(
3574     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
3575         throw ( embed::InvalidStorageException,
3576                 lang::IllegalArgumentException,
3577                 packages::NoEncryptionException,
3578                 packages::WrongPasswordException,
3579                 io::IOException,
3580                 embed::StorageWrappedTargetException,
3581                 uno::RuntimeException )
3582 {
3583     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStream" );
3584 
3585     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3586 
3587     if ( !m_pImpl )
3588     {
3589         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3590         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3591     }
3592 
3593     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3594         packages::NoEncryptionException();
3595 
3596     if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
3597         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3598 
3599     if ( !aEncryptionData.getLength() )
3600         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 3 );
3601 
3602     uno::Reference< io::XStream > xResult;
3603     try
3604     {
3605         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_True );
3606         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
3607 
3608         xResult = pElement->m_pStream->GetStream( nOpenMode, aEncryptionData, sal_False );
3609         OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
3610 
3611         if ( m_pData->m_bReadOnlyWrap )
3612         {
3613             // before the storage disposes the stream it must deregister itself as listener
3614             uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
3615             if ( !xStreamComponent.is() )
3616                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3617 
3618             MakeLinkToSubComponent_Impl( xStreamComponent );
3619         }
3620     }
3621     catch( embed::InvalidStorageException& aInvalidStorageException )
3622     {
3623         m_pImpl->AddLog( aInvalidStorageException.Message );
3624         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3625         throw;
3626     }
3627     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3628     {
3629         m_pImpl->AddLog( aIllegalArgumentException.Message );
3630         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3631         throw;
3632     }
3633     catch( packages::NoEncryptionException& aNoEncryptionException )
3634     {
3635         m_pImpl->AddLog( aNoEncryptionException.Message );
3636         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3637         throw;
3638     }
3639     catch( packages::WrongPasswordException& aWrongPasswordException )
3640     {
3641         m_pImpl->AddLog( aWrongPasswordException.Message );
3642         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3643         throw;
3644     }
3645     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3646     {
3647         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3648         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3649         throw;
3650     }
3651     catch( io::IOException& aIOException )
3652     {
3653         m_pImpl->AddLog( aIOException.Message );
3654         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3655         throw;
3656     }
3657     catch( uno::RuntimeException& aRuntimeException )
3658     {
3659         m_pImpl->AddLog( aRuntimeException.Message );
3660         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3661         throw;
3662     }
3663     catch( uno::Exception& aException )
3664     {
3665         m_pImpl->AddLog( aException.Message );
3666         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3667 
3668         uno::Any aCaught( ::cppu::getCaughtException() );
3669         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open encrypted stream stream!" ) ),
3670                                                  uno::Reference< io::XInputStream >(),
3671                                                  aCaught );
3672     }
3673 
3674     aGuard.clear();
3675 
3676     BroadcastModifiedIfNecessary();
3677 
3678     return xResult;
3679 }
3680 
3681 //-----------------------------------------------
cloneEncryptedStream(const::rtl::OUString & aStreamName,const uno::Sequence<beans::NamedValue> & aEncryptionData)3682 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStream(
3683     const ::rtl::OUString& aStreamName,
3684     const uno::Sequence< beans::NamedValue >& aEncryptionData )
3685         throw ( embed::InvalidStorageException,
3686                 lang::IllegalArgumentException,
3687                 packages::NoEncryptionException,
3688                 packages::WrongPasswordException,
3689                 io::IOException,
3690                 embed::StorageWrappedTargetException,
3691                 uno::RuntimeException )
3692 {
3693     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStream" );
3694 
3695     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3696 
3697     if ( !m_pImpl )
3698     {
3699         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3700         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3701     }
3702 
3703     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3704         packages::NoEncryptionException();
3705 
3706     if ( !aEncryptionData.getLength() )
3707         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3708 
3709     try
3710     {
3711         uno::Reference< io::XStream > xResult;
3712         m_pImpl->CloneStreamElement( aStreamName, sal_True, aEncryptionData, xResult );
3713         if ( !xResult.is() )
3714             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3715         return xResult;
3716     }
3717     catch( embed::InvalidStorageException& aInvalidStorageException )
3718     {
3719         m_pImpl->AddLog( aInvalidStorageException.Message );
3720         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3721         throw;
3722     }
3723     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3724     {
3725         m_pImpl->AddLog( aIllegalArgumentException.Message );
3726         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3727         throw;
3728     }
3729     catch( packages::NoEncryptionException& aNoEncryptionException )
3730     {
3731         m_pImpl->AddLog( aNoEncryptionException.Message );
3732         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3733         throw;
3734     }
3735     catch( packages::WrongPasswordException& aWrongPasswordException )
3736     {
3737         m_pImpl->AddLog( aWrongPasswordException.Message );
3738         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3739         throw;
3740     }
3741     catch( io::IOException& aIOException )
3742     {
3743         m_pImpl->AddLog( aIOException.Message );
3744         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3745         throw;
3746     }
3747     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3748     {
3749         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3750         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3751         throw;
3752     }
3753     catch( uno::RuntimeException& aRuntimeException )
3754     {
3755         m_pImpl->AddLog( aRuntimeException.Message );
3756         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3757         throw;
3758     }
3759     catch( uno::Exception& aException )
3760     {
3761         m_pImpl->AddLog( aException.Message );
3762         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3763 
3764         uno::Any aCaught( ::cppu::getCaughtException() );
3765         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't clone encrypted stream!" ) ),
3766                                                  uno::Reference< io::XInputStream >(),
3767                                                  aCaught );
3768     }
3769 }
3770 
3771 
3772 //____________________________________________________________________________________________________
3773 //  XStorageRawAccess
3774 //____________________________________________________________________________________________________
3775 
3776 //-----------------------------------------------
getPlainRawStreamElement(const::rtl::OUString & sStreamName)3777 uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
3778             const ::rtl::OUString& sStreamName )
3779         throw ( embed::InvalidStorageException,
3780                 lang::IllegalArgumentException,
3781                 container::NoSuchElementException,
3782                 io::IOException,
3783                 embed::StorageWrappedTargetException,
3784                 uno::RuntimeException )
3785 {
3786     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPlainRawStreamElement" );
3787 
3788     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3789 
3790     if ( !m_pImpl )
3791     {
3792         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3793         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3794     }
3795 
3796     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
3797         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface is not supported and must not be accessible
3798 
3799     if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3800         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3801 
3802     uno::Reference < io::XInputStream > xTempIn;
3803     try
3804     {
3805         SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3806         if ( !pElement )
3807             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3808 
3809         if ( !pElement->m_pStream )
3810         {
3811             m_pImpl->OpenSubStream( pElement );
3812             if ( !pElement->m_pStream )
3813                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3814         }
3815 
3816         uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetPlainRawInStream();
3817         if ( !xRawInStream.is() )
3818             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3819 
3820         uno::Reference < io::XOutputStream > xTempOut(
3821                             m_pImpl->GetServiceFactory()->createInstance (
3822                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
3823                             uno::UNO_QUERY );
3824         xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
3825         uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3826 
3827         if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3828             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3829 
3830         // Copy temporary file to a new one
3831         ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3832         xTempOut->closeOutput();
3833         xSeek->seek( 0 );
3834     }
3835     catch( embed::InvalidStorageException& aInvalidStorageException )
3836     {
3837         m_pImpl->AddLog( aInvalidStorageException.Message );
3838         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3839         throw;
3840     }
3841     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3842     {
3843         m_pImpl->AddLog( aIllegalArgumentException.Message );
3844         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3845         throw;
3846     }
3847     catch( container::NoSuchElementException& aNoSuchElementException )
3848     {
3849         m_pImpl->AddLog( aNoSuchElementException.Message );
3850         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3851         throw;
3852     }
3853     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3854     {
3855         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3856         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3857         throw;
3858     }
3859     catch( io::IOException& aIOException )
3860     {
3861         m_pImpl->AddLog( aIOException.Message );
3862         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3863         throw;
3864     }
3865     catch( uno::RuntimeException& aRuntimeException )
3866     {
3867         m_pImpl->AddLog( aRuntimeException.Message );
3868         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3869         throw;
3870     }
3871     catch( uno::Exception& aException )
3872     {
3873         m_pImpl->AddLog( aException.Message );
3874         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3875 
3876         uno::Any aCaught( ::cppu::getCaughtException() );
3877         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get plain raw stream!" ) ),
3878                                                  uno::Reference< io::XInputStream >(),
3879                                                  aCaught );
3880     }
3881 
3882     return xTempIn;
3883 }
3884 
3885 //-----------------------------------------------
getRawEncrStreamElement(const::rtl::OUString & sStreamName)3886 uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
3887             const ::rtl::OUString& sStreamName )
3888         throw ( embed::InvalidStorageException,
3889                 lang::IllegalArgumentException,
3890                 packages::NoEncryptionException,
3891                 container::NoSuchElementException,
3892                 io::IOException,
3893                 embed::StorageWrappedTargetException,
3894                 uno::RuntimeException )
3895 {
3896     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getRawEncrStreamElement" );
3897 
3898     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3899 
3900     if ( !m_pImpl )
3901     {
3902         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3903         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3904     }
3905 
3906     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3907         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3908 
3909     if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3910         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3911 
3912     uno::Reference < io::XInputStream > xTempIn;
3913     try
3914     {
3915         SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3916         if ( !pElement )
3917             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3918 
3919         if ( !pElement->m_pStream )
3920         {
3921             m_pImpl->OpenSubStream( pElement );
3922             if ( !pElement->m_pStream )
3923                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3924         }
3925 
3926         if ( !pElement->m_pStream->IsEncrypted() )
3927             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3928 
3929         uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
3930         if ( !xRawInStream.is() )
3931             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3932 
3933         uno::Reference < io::XOutputStream > xTempOut(
3934                             m_pImpl->GetServiceFactory()->createInstance (
3935                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
3936                             uno::UNO_QUERY );
3937         xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
3938         uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3939 
3940         if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3941             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3942 
3943         // Copy temporary file to a new one
3944         ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3945         xTempOut->closeOutput();
3946         xSeek->seek( 0 );
3947 
3948     }
3949     catch( embed::InvalidStorageException& aInvalidStorageException )
3950     {
3951         m_pImpl->AddLog( aInvalidStorageException.Message );
3952         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3953         throw;
3954     }
3955     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3956     {
3957         m_pImpl->AddLog( aIllegalArgumentException.Message );
3958         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3959         throw;
3960     }
3961     catch( packages::NoEncryptionException& aNoEncryptionException )
3962     {
3963         m_pImpl->AddLog( aNoEncryptionException.Message );
3964         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3965         throw;
3966     }
3967     catch( container::NoSuchElementException& aNoSuchElementException )
3968     {
3969         m_pImpl->AddLog( aNoSuchElementException.Message );
3970         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3971         throw;
3972     }
3973     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3974     {
3975         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3976         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3977         throw;
3978     }
3979     catch( io::IOException& aIOException )
3980     {
3981         m_pImpl->AddLog( aIOException.Message );
3982         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3983         throw;
3984     }
3985     catch( uno::RuntimeException& aRuntimeException )
3986     {
3987         m_pImpl->AddLog( aRuntimeException.Message );
3988         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3989         throw;
3990     }
3991     catch( uno::Exception& aException )
3992     {
3993         m_pImpl->AddLog( aException.Message );
3994         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3995 
3996         uno::Any aCaught( ::cppu::getCaughtException() );
3997         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get raw stream!" ) ),
3998                                                  uno::Reference< io::XInputStream >(),
3999                                                  aCaught );
4000     }
4001 
4002     return xTempIn;
4003 }
4004 
4005 //-----------------------------------------------
insertRawEncrStreamElement(const::rtl::OUString & aStreamName,const uno::Reference<io::XInputStream> & xInStream)4006 void SAL_CALL OStorage::insertRawEncrStreamElement( const ::rtl::OUString& aStreamName,
4007                                 const uno::Reference< io::XInputStream >& xInStream )
4008         throw ( embed::InvalidStorageException,
4009                 lang::IllegalArgumentException,
4010                 packages::NoRawFormatException,
4011                 container::ElementExistException,
4012                 io::IOException,
4013                 embed::StorageWrappedTargetException,
4014                 uno::RuntimeException)
4015 {
4016     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertRawEncrStreamElement" );
4017 
4018     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4019 
4020     if ( !m_pImpl )
4021     {
4022         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4023         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4024     }
4025 
4026     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4027         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4028 
4029     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
4030         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
4031 
4032     if ( !xInStream.is() )
4033         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
4034 
4035     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
4036         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
4037 
4038     try
4039     {
4040         SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
4041         if ( pElement )
4042             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4043 
4044         m_pImpl->InsertRawStream( aStreamName, xInStream );
4045     }
4046     catch( embed::InvalidStorageException& aInvalidStorageException )
4047     {
4048         m_pImpl->AddLog( aInvalidStorageException.Message );
4049         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4050         throw;
4051     }
4052     catch( lang::IllegalArgumentException& aIllegalArgumentException )
4053     {
4054         m_pImpl->AddLog( aIllegalArgumentException.Message );
4055         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4056         throw;
4057     }
4058     catch( packages::NoRawFormatException& aNoRawFormatException )
4059     {
4060         m_pImpl->AddLog( aNoRawFormatException.Message );
4061         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4062         throw;
4063     }
4064     catch( container::ElementExistException& aElementExistException )
4065     {
4066         m_pImpl->AddLog( aElementExistException.Message );
4067         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4068         throw;
4069     }
4070     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
4071     {
4072         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
4073         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4074         throw;
4075     }
4076     catch( io::IOException& aIOException )
4077     {
4078         m_pImpl->AddLog( aIOException.Message );
4079         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4080         throw;
4081     }
4082     catch( uno::RuntimeException& aRuntimeException )
4083     {
4084         m_pImpl->AddLog( aRuntimeException.Message );
4085         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4086         throw;
4087     }
4088     catch( uno::Exception& aException )
4089     {
4090         m_pImpl->AddLog( aException.Message );
4091         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4092 
4093         uno::Any aCaught( ::cppu::getCaughtException() );
4094         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't insert raw stream!" ) ),
4095                                                  uno::Reference< io::XInputStream >(),
4096                                                  aCaught );
4097     }
4098 }
4099 
4100 //____________________________________________________________________________________________________
4101 //  XTransactedObject
4102 //____________________________________________________________________________________________________
4103 
4104 //-----------------------------------------------
commit()4105 void SAL_CALL OStorage::commit()
4106         throw ( io::IOException,
4107                 embed::StorageWrappedTargetException,
4108                 uno::RuntimeException )
4109 {
4110     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::commit" );
4111 
4112     uno::Reference< util::XModifiable > xParentModif;
4113 
4114     try {
4115         BroadcastTransaction( STOR_MESS_PRECOMMIT );
4116 
4117         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4118 
4119         if ( !m_pImpl )
4120         {
4121             ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4122             throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4123         }
4124 
4125         if ( m_pData->m_bReadOnlyWrap )
4126             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
4127 
4128         m_pImpl->Commit(); // the root storage initiates the storing to source
4129 
4130         // when the storage is commited the parent is modified
4131         if ( m_pImpl->m_pParent && m_pImpl->m_pParent->m_pAntiImpl )
4132             xParentModif = (util::XModifiable*)m_pImpl->m_pParent->m_pAntiImpl;
4133     }
4134     catch( io::IOException& aIOException )
4135     {
4136         m_pImpl->AddLog( aIOException.Message );
4137         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4138         throw;
4139     }
4140     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
4141     {
4142         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
4143         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4144         throw;
4145     }
4146     catch( uno::RuntimeException& aRuntimeException )
4147     {
4148         m_pImpl->AddLog( aRuntimeException.Message );
4149         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4150         throw;
4151     }
4152     catch( uno::Exception& aException )
4153     {
4154         m_pImpl->AddLog( aException.Message );
4155         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4156 
4157         uno::Any aCaught( ::cppu::getCaughtException() );
4158         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Problems on commit!" ) ),
4159                                   uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
4160                                   aCaught );
4161     }
4162 
4163     setModified( sal_False );
4164     if ( xParentModif.is() )
4165         xParentModif->setModified( sal_True );
4166 
4167     BroadcastTransaction( STOR_MESS_COMMITED );
4168 }
4169 
4170 //-----------------------------------------------
revert()4171 void SAL_CALL OStorage::revert()
4172         throw ( io::IOException,
4173                 embed::StorageWrappedTargetException,
4174                 uno::RuntimeException )
4175 {
4176     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::revert" );
4177 
4178     // the method removes all the changes done after last commit
4179 
4180     BroadcastTransaction( STOR_MESS_PREREVERT );
4181 
4182     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4183 
4184     if ( !m_pImpl )
4185     {
4186         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4187         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4188     }
4189 
4190     for ( SotElementList_Impl::iterator pElementIter = m_pImpl->m_aChildrenList.begin();
4191           pElementIter != m_pImpl->m_aChildrenList.end(); pElementIter++ )
4192     {
4193         if ( ((*pElementIter)->m_pStorage
4194                 && ( (*pElementIter)->m_pStorage->m_pAntiImpl || !(*pElementIter)->m_pStorage->m_aReadOnlyWrapList.empty() ))
4195           || ((*pElementIter)->m_pStream
4196                 && ( (*pElementIter)->m_pStream->m_pAntiImpl || !(*pElementIter)->m_pStream->m_aInputStreamsList.empty()) ) )
4197             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
4198     }
4199 
4200     if ( m_pData->m_bReadOnlyWrap || !m_pImpl->m_bListCreated )
4201         return; // nothing to do
4202 
4203     try {
4204         m_pImpl->Revert();
4205         m_pImpl->m_bIsModified = sal_False;
4206         m_pImpl->m_bBroadcastModified = sal_True;
4207     }
4208     catch( io::IOException& aIOException )
4209     {
4210         m_pImpl->AddLog( aIOException.Message );
4211         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4212         throw;
4213     }
4214     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
4215     {
4216         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
4217         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4218         throw;
4219     }
4220     catch( uno::RuntimeException& aRuntimeException )
4221     {
4222         m_pImpl->AddLog( aRuntimeException.Message );
4223         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4224         throw;
4225     }
4226     catch( uno::Exception& aException )
4227     {
4228         m_pImpl->AddLog( aException.Message );
4229         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4230 
4231         uno::Any aCaught( ::cppu::getCaughtException() );
4232         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Problems on revert!" ) ),
4233                                   uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
4234                                   aCaught );
4235     }
4236 
4237     aGuard.clear();
4238 
4239     setModified( sal_False );
4240     BroadcastTransaction( STOR_MESS_REVERTED );
4241 }
4242 
4243 //____________________________________________________________________________________________________
4244 //  XTransactionBroadcaster
4245 //____________________________________________________________________________________________________
4246 
4247 //-----------------------------------------------
addTransactionListener(const uno::Reference<embed::XTransactionListener> & aListener)4248 void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
4249         throw ( uno::RuntimeException )
4250 {
4251     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4252 
4253     if ( !m_pImpl )
4254     {
4255         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4256         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4257     }
4258 
4259     m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
4260                                                 aListener );
4261 }
4262 
4263 //-----------------------------------------------
removeTransactionListener(const uno::Reference<embed::XTransactionListener> & aListener)4264 void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
4265         throw ( uno::RuntimeException )
4266 {
4267     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4268 
4269     if ( !m_pImpl )
4270     {
4271         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4272         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4273     }
4274 
4275     m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
4276                                                     aListener );
4277 }
4278 
4279 //____________________________________________________________________________________________________
4280 //  XModifiable
4281 //  TODO: if there will be no demand on this interface it will be removed from implementation,
4282 //        I do not want to remove it now since it is still possible that it will be inserted
4283 //        to the service back.
4284 //____________________________________________________________________________________________________
4285 
4286 //-----------------------------------------------
isModified()4287 sal_Bool SAL_CALL OStorage::isModified()
4288         throw ( uno::RuntimeException )
4289 {
4290     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4291 
4292     if ( !m_pImpl )
4293     {
4294         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4295         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4296     }
4297 
4298     return m_pImpl->m_bIsModified;
4299 }
4300 
4301 
4302 //-----------------------------------------------
setModified(sal_Bool bModified)4303 void SAL_CALL OStorage::setModified( sal_Bool bModified )
4304         throw ( beans::PropertyVetoException,
4305                 uno::RuntimeException )
4306 {
4307     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4308 
4309     if ( !m_pImpl )
4310     {
4311         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4312         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4313     }
4314 
4315     if ( m_pData->m_bReadOnlyWrap )
4316         throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
4317 
4318     if ( m_pImpl->m_bIsModified != bModified )
4319         m_pImpl->m_bIsModified = bModified;
4320 
4321     aGuard.clear();
4322     if ( bModified )
4323     {
4324         m_pImpl->m_bBroadcastModified = sal_True;
4325         BroadcastModifiedIfNecessary();
4326     }
4327 }
4328 
4329 //-----------------------------------------------
addModifyListener(const uno::Reference<util::XModifyListener> & aListener)4330 void SAL_CALL OStorage::addModifyListener(
4331             const uno::Reference< util::XModifyListener >& aListener )
4332         throw ( uno::RuntimeException )
4333 {
4334     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4335 
4336     if ( !m_pImpl )
4337     {
4338         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4339         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4340     }
4341 
4342     m_pData->m_aListenersContainer.addInterface(
4343                                 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
4344 }
4345 
4346 
4347 //-----------------------------------------------
removeModifyListener(const uno::Reference<util::XModifyListener> & aListener)4348 void SAL_CALL OStorage::removeModifyListener(
4349             const uno::Reference< util::XModifyListener >& aListener )
4350         throw ( uno::RuntimeException )
4351 {
4352     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4353 
4354     if ( !m_pImpl )
4355     {
4356         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4357         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4358     }
4359 
4360     m_pData->m_aListenersContainer.removeInterface(
4361                                 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
4362 }
4363 
4364 //____________________________________________________________________________________________________
4365 //  XNameAccess
4366 //____________________________________________________________________________________________________
4367 
4368 //-----------------------------------------------
getByName(const::rtl::OUString & aName)4369 uno::Any SAL_CALL OStorage::getByName( const ::rtl::OUString& aName )
4370         throw ( container::NoSuchElementException,
4371                 lang::WrappedTargetException,
4372                 uno::RuntimeException )
4373 {
4374     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getByName" );
4375 
4376     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4377 
4378     if ( !m_pImpl )
4379     {
4380         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4381         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4382     }
4383 
4384     if ( !aName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, sal_False ) )
4385         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
4386 
4387     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
4388       && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
4389         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
4390 
4391     uno::Any aResult;
4392     try
4393     {
4394         SotElement_Impl* pElement = m_pImpl->FindElement( aName );
4395         if ( !pElement )
4396             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4397 
4398         if ( pElement->m_bIsStorage )
4399             aResult <<= openStorageElement( aName, embed::ElementModes::READ );
4400         else
4401             aResult <<= openStreamElement( aName, embed::ElementModes::READ );
4402     }
4403     catch( container::NoSuchElementException& aNoSuchElementException )
4404     {
4405         m_pImpl->AddLog( aNoSuchElementException.Message );
4406         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4407         throw;
4408     }
4409     catch( lang::WrappedTargetException& aWrappedTargetException )
4410     {
4411         m_pImpl->AddLog( aWrappedTargetException.Message );
4412         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4413         throw;
4414     }
4415     catch( uno::RuntimeException& aRuntimeException )
4416     {
4417         m_pImpl->AddLog( aRuntimeException.Message );
4418         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4419         throw;
4420     }
4421     catch ( uno::Exception& aException )
4422     {
4423         m_pImpl->AddLog( aException.Message );
4424         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4425 
4426         uno::Any aCaught( ::cppu::getCaughtException() );
4427         throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4428                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4429                                                                                 uno::UNO_QUERY ),
4430                                             aCaught );
4431     }
4432 
4433     return aResult;
4434 }
4435 
4436 
4437 //-----------------------------------------------
getElementNames()4438 uno::Sequence< ::rtl::OUString > SAL_CALL OStorage::getElementNames()
4439         throw ( uno::RuntimeException )
4440 {
4441     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementNames" );
4442 
4443     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4444 
4445     if ( !m_pImpl )
4446     {
4447         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4448         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4449     }
4450 
4451     try
4452     {
4453         return m_pImpl->GetElementNames();
4454     }
4455     catch( uno::RuntimeException& aRuntimeException )
4456     {
4457         m_pImpl->AddLog( aRuntimeException.Message );
4458         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4459         throw;
4460     }
4461     catch ( uno::Exception& aException )
4462     {
4463         m_pImpl->AddLog( aException.Message );
4464         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4465 
4466         uno::Any aCaught( ::cppu::getCaughtException() );
4467         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4468                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4469                                                                                 uno::UNO_QUERY ),
4470                                             aCaught );
4471     }
4472 }
4473 
4474 
4475 //-----------------------------------------------
hasByName(const::rtl::OUString & aName)4476 sal_Bool SAL_CALL OStorage::hasByName( const ::rtl::OUString& aName )
4477         throw ( uno::RuntimeException )
4478 {
4479     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasByName" );
4480 
4481     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4482 
4483     if ( !m_pImpl )
4484     {
4485         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4486         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4487     }
4488 
4489     if ( !aName.getLength() )
4490         return sal_False;
4491 
4492     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
4493       && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
4494         return sal_False;
4495 
4496     SotElement_Impl* pElement = NULL;
4497     try
4498     {
4499         pElement = m_pImpl->FindElement( aName );
4500     }
4501     catch( uno::RuntimeException& aRuntimeException )
4502     {
4503         m_pImpl->AddLog( aRuntimeException.Message );
4504         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4505         throw;
4506     }
4507     catch ( uno::Exception& aException )
4508     {
4509         m_pImpl->AddLog( aException.Message );
4510         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4511 
4512         uno::Any aCaught( ::cppu::getCaughtException() );
4513         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4514                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4515                                                                                 uno::UNO_QUERY ),
4516                                             aCaught );
4517     }
4518 
4519     return ( pElement != NULL );
4520 }
4521 
4522 
4523 //-----------------------------------------------
getElementType()4524 uno::Type SAL_CALL OStorage::getElementType()
4525         throw ( uno::RuntimeException )
4526 {
4527     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4528 
4529     if ( !m_pImpl )
4530     {
4531         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4532         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4533     }
4534 
4535     // it is a multitype container
4536     return uno::Type();
4537 }
4538 
4539 
4540 //-----------------------------------------------
hasElements()4541 sal_Bool SAL_CALL OStorage::hasElements()
4542         throw ( uno::RuntimeException )
4543 {
4544     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasElements" );
4545 
4546     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4547 
4548     if ( !m_pImpl )
4549     {
4550         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4551         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4552     }
4553 
4554     try
4555     {
4556         return ( m_pImpl->GetChildrenList().size() != 0 );
4557     }
4558     catch( uno::RuntimeException& aRuntimeException )
4559     {
4560         m_pImpl->AddLog( aRuntimeException.Message );
4561         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4562         throw;
4563     }
4564     catch ( uno::Exception& aException )
4565     {
4566         m_pImpl->AddLog( aException.Message );
4567         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4568 
4569         uno::Any aCaught( ::cppu::getCaughtException() );
4570         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4571                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4572                                                                                 uno::UNO_QUERY ),
4573                                             aCaught );
4574     }
4575 }
4576 
4577 
4578 //____________________________________________________________________________________________________
4579 //  XComponent
4580 //____________________________________________________________________________________________________
4581 
4582 //-----------------------------------------------
dispose()4583 void SAL_CALL OStorage::dispose()
4584         throw ( uno::RuntimeException )
4585 {
4586     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4587 
4588     if ( !m_pImpl )
4589     {
4590         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4591         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4592     }
4593 
4594     try
4595     {
4596         InternalDispose( sal_True );
4597     }
4598     catch( uno::RuntimeException& aRuntimeException )
4599     {
4600         m_pImpl->AddLog( aRuntimeException.Message );
4601         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4602         throw;
4603     }
4604     catch ( uno::Exception& aException )
4605     {
4606         m_pImpl->AddLog( aException.Message );
4607         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4608 
4609         uno::Any aCaught( ::cppu::getCaughtException() );
4610         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4611                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4612                                                                                 uno::UNO_QUERY ),
4613                                             aCaught );
4614     }
4615 }
4616 
4617 //-----------------------------------------------
addEventListener(const uno::Reference<lang::XEventListener> & xListener)4618 void SAL_CALL OStorage::addEventListener(
4619             const uno::Reference< lang::XEventListener >& xListener )
4620         throw ( uno::RuntimeException )
4621 {
4622     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4623 
4624     if ( !m_pImpl )
4625     {
4626         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4627         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4628     }
4629 
4630     m_pData->m_aListenersContainer.addInterface(
4631                                 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4632 }
4633 
4634 //-----------------------------------------------
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)4635 void SAL_CALL OStorage::removeEventListener(
4636             const uno::Reference< lang::XEventListener >& xListener )
4637         throw ( uno::RuntimeException )
4638 {
4639     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4640 
4641     if ( !m_pImpl )
4642     {
4643         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4644         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4645     }
4646 
4647     m_pData->m_aListenersContainer.removeInterface(
4648                                 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4649 }
4650 
4651 //____________________________________________________________________________________________________
4652 //  XEncryptionProtectedSource
4653 //____________________________________________________________________________________________________
4654 
setEncryptionPassword(const::rtl::OUString & aPass)4655 void SAL_CALL OStorage::setEncryptionPassword( const ::rtl::OUString& aPass )
4656     throw ( uno::RuntimeException,
4657             io::IOException )
4658 {
4659     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionPassword" );
4660     setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
4661 }
4662 
4663 //-----------------------------------------------
removeEncryption()4664 void SAL_CALL OStorage::removeEncryption()
4665     throw ( uno::RuntimeException,
4666             io::IOException )
4667 {
4668     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeEncryption" );
4669 
4670     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4671 
4672     if ( !m_pImpl )
4673     {
4674         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4675         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4676     }
4677 
4678     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4679         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4680 
4681     OSL_ENSURE( m_pData->m_bIsRoot, "removeEncryption() method is not available for nonroot storages!\n" );
4682     if ( m_pData->m_bIsRoot )
4683     {
4684         try {
4685             m_pImpl->ReadContents();
4686         }
4687         catch ( uno::RuntimeException& aRuntimeException )
4688         {
4689             m_pImpl->AddLog( aRuntimeException.Message );
4690             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4691             throw;
4692         }
4693         catch ( uno::Exception& aException )
4694         {
4695             m_pImpl->AddLog( aException.Message );
4696             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4697 
4698             uno::Any aCaught( ::cppu::getCaughtException() );
4699             throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4700                                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4701                                                                                     uno::UNO_QUERY ),
4702                                                 aCaught );
4703         }
4704 
4705         // TODO: check if the password is valid
4706         // update all streams that was encrypted with old password
4707 
4708         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4709         try
4710         {
4711             xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ),
4712                                             uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
4713 
4714             m_pImpl->m_bHasCommonEncryptionData = sal_False;
4715             m_pImpl->m_aCommonEncryptionData.clear();
4716         }
4717         catch( uno::RuntimeException& aRException )
4718         {
4719             m_pImpl->AddLog( aRException.Message );
4720             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4721 
4722             OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4723             throw;
4724         }
4725         catch( uno::Exception& aException )
4726         {
4727             m_pImpl->AddLog( aException.Message );
4728             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4729 
4730             OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4731             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4732         }
4733     }
4734 }
4735 
4736 //____________________________________________________________________________________________________
4737 //  XEncryptionProtectedSource2
4738 //____________________________________________________________________________________________________
4739 
setEncryptionData(const uno::Sequence<beans::NamedValue> & aEncryptionData)4740 void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValue >& aEncryptionData )
4741     throw ( io::IOException,
4742             uno::RuntimeException )
4743 {
4744     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionData" );
4745 
4746     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4747 
4748     if ( !m_pImpl )
4749     {
4750         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4751         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4752     }
4753 
4754     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4755         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4756 
4757     if ( !aEncryptionData.getLength() )
4758         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected empty encryption data!") ), uno::Reference< uno::XInterface >() );
4759 
4760     OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionData() method is not available for nonroot storages!\n" );
4761     if ( m_pData->m_bIsRoot )
4762     {
4763         try {
4764             m_pImpl->ReadContents();
4765         }
4766         catch ( uno::RuntimeException& aRuntimeException )
4767         {
4768             m_pImpl->AddLog( aRuntimeException.Message );
4769             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4770             throw;
4771         }
4772         catch ( uno::Exception& aException )
4773         {
4774             m_pImpl->AddLog( aException.Message );
4775             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4776 
4777             uno::Any aCaught( ::cppu::getCaughtException() );
4778             throw lang::WrappedTargetRuntimeException(
4779                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4780                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
4781                                 aCaught );
4782         }
4783 
4784         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4785         try
4786         {
4787             ::comphelper::SequenceAsHashMap aEncryptionMap( aEncryptionData );
4788             xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ),
4789                                             uno::makeAny( aEncryptionMap.getAsConstNamedValueList() ) );
4790 
4791             m_pImpl->m_bHasCommonEncryptionData = sal_True;
4792             m_pImpl->m_aCommonEncryptionData = aEncryptionMap;
4793         }
4794         catch( uno::Exception& aException )
4795         {
4796             m_pImpl->AddLog( aException.Message );
4797             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4798 
4799             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4800         }
4801     }
4802 }
4803 
4804 //____________________________________________________________________________________________________
4805 //  XEncryptionProtectedStorage
4806 //____________________________________________________________________________________________________
4807 
4808 //-----------------------------------------------
setEncryptionAlgorithms(const uno::Sequence<beans::NamedValue> & aAlgorithms)4809 void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::NamedValue >& aAlgorithms )
4810     throw (lang::IllegalArgumentException, uno::RuntimeException)
4811 {
4812     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionAlgorithms" );
4813 
4814     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4815 
4816     if ( !m_pImpl )
4817     {
4818         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4819         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4820     }
4821 
4822     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4823         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4824 
4825     if ( !aAlgorithms.getLength() )
4826         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected empty encryption algorithms list!") ), uno::Reference< uno::XInterface >() );
4827 
4828     OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionAlgorithms() method is not available for nonroot storages!\n" );
4829     if ( m_pData->m_bIsRoot )
4830     {
4831         try {
4832             m_pImpl->ReadContents();
4833         }
4834         catch ( uno::RuntimeException& aRuntimeException )
4835         {
4836             m_pImpl->AddLog( aRuntimeException.Message );
4837             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4838             throw;
4839         }
4840         catch ( uno::Exception& aException )
4841         {
4842             m_pImpl->AddLog( aException.Message );
4843             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4844 
4845             uno::Any aCaught( ::cppu::getCaughtException() );
4846             throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4847                                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4848                                                                                     uno::UNO_QUERY ),
4849                                                 aCaught );
4850         }
4851 
4852         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4853         try
4854         {
4855             xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ),
4856                                             uno::makeAny( aAlgorithms ) );
4857         }
4858         catch ( uno::RuntimeException& aRuntimeException )
4859         {
4860             m_pImpl->AddLog( aRuntimeException.Message );
4861             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4862             throw;
4863         }
4864         catch( lang::IllegalArgumentException& aIAException )
4865         {
4866             m_pImpl->AddLog( aIAException.Message );
4867             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4868 
4869             throw;
4870         }
4871         catch( uno::Exception& aException )
4872         {
4873             m_pImpl->AddLog( aException.Message );
4874             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4875 
4876             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4877         }
4878     }
4879 }
4880 
4881 //-----------------------------------------------
getEncryptionAlgorithms()4882 uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms()
4883     throw (uno::RuntimeException)
4884 {
4885     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getEncryptionAlgorithms" );
4886 
4887     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4888 
4889     if ( !m_pImpl )
4890     {
4891         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4892         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4893     }
4894 
4895     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4896         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4897 
4898     uno::Sequence< beans::NamedValue > aResult;
4899     OSL_ENSURE( m_pData->m_bIsRoot, "getEncryptionAlgorithms() method is not available for nonroot storages!\n" );
4900     if ( m_pData->m_bIsRoot )
4901     {
4902         try {
4903             m_pImpl->ReadContents();
4904         }
4905         catch ( uno::RuntimeException& aRuntimeException )
4906         {
4907             m_pImpl->AddLog( aRuntimeException.Message );
4908             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4909             throw;
4910         }
4911         catch ( uno::Exception& aException )
4912         {
4913             m_pImpl->AddLog( aException.Message );
4914             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4915 
4916             uno::Any aCaught( ::cppu::getCaughtException() );
4917             throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4918                                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4919                                                                                     uno::UNO_QUERY ),
4920                                                 aCaught );
4921         }
4922 
4923         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4924         try
4925         {
4926             xPackPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ) ) >>= aResult;
4927         }
4928         catch ( uno::RuntimeException& aRuntimeException )
4929         {
4930             m_pImpl->AddLog( aRuntimeException.Message );
4931             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4932             throw;
4933         }
4934         catch( uno::Exception& aException )
4935         {
4936             m_pImpl->AddLog( aException.Message );
4937             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4938 
4939             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4940         }
4941     }
4942 
4943     return aResult;
4944 }
4945 
4946 
4947 //____________________________________________________________________________________________________
4948 //  XPropertySet
4949 //____________________________________________________________________________________________________
4950 
4951 //-----------------------------------------------
getPropertySetInfo()4952 uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
4953         throw ( uno::RuntimeException )
4954 {
4955     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4956 
4957     if ( !m_pImpl )
4958     {
4959         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4960         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4961     }
4962 
4963     //TODO:
4964     return uno::Reference< beans::XPropertySetInfo >();
4965 }
4966 
4967 
4968 //-----------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any & aValue)4969 void SAL_CALL OStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue )
4970         throw ( beans::UnknownPropertyException,
4971                 beans::PropertyVetoException,
4972                 lang::IllegalArgumentException,
4973                 lang::WrappedTargetException,
4974                 uno::RuntimeException )
4975 {
4976     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setPropertyValue" );
4977 
4978     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4979 
4980     if ( !m_pImpl )
4981     {
4982         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4983         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4984     }
4985 
4986     //TODO: think about interaction handler
4987 
4988     // WORKAROUND:
4989     // The old document might have no version in the manifest.xml, so we have to allow to set the version
4990     // even for readonly storages, so that the version from content.xml can be used.
4991     if ( m_pData->m_bReadOnlyWrap && !aPropertyName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) )
4992         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Access denied
4993 
4994     if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
4995         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4996     else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
4997     {
4998         if ( aPropertyName.equalsAscii( "MediaType" ) )
4999         {
5000             aValue >>= m_pImpl->m_aMediaType;
5001             m_pImpl->m_bControlMediaType = sal_True;
5002 
5003             m_pImpl->m_bBroadcastModified = sal_True;
5004             m_pImpl->m_bIsModified = sal_True;
5005         }
5006         else if ( aPropertyName.equalsAscii( "Version" ) )
5007         {
5008             aValue >>= m_pImpl->m_aVersion;
5009             m_pImpl->m_bControlVersion = sal_True;
5010 
5011             // this property can be set even for readonly storage
5012             if ( !m_pData->m_bReadOnlyWrap )
5013             {
5014                 m_pImpl->m_bBroadcastModified = sal_True;
5015                 m_pImpl->m_bIsModified = sal_True;
5016             }
5017         }
5018         else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( HAS_ENCRYPTED_ENTRIES_PROPERTY )
5019                                     || aPropertyName.equalsAscii( HAS_NONENCRYPTED_ENTRIES_PROPERTY )
5020                                     || aPropertyName.equalsAscii( IS_INCONSISTENT_PROPERTY )
5021                                     || aPropertyName.equalsAscii( "URL" )
5022                                     || aPropertyName.equalsAscii( "RepairPackage" ) ) )
5023            || aPropertyName.equalsAscii( "IsRoot" )
5024            || aPropertyName.equalsAscii( MEDIATYPE_FALLBACK_USED_PROPERTY ) )
5025             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5026         else
5027             throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5028     }
5029     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
5030     {
5031         if ( aPropertyName.equalsAscii( "RelationsInfoStream" ) )
5032         {
5033             uno::Reference< io::XInputStream > xInRelStream;
5034             if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
5035             {
5036                 uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
5037                 if ( !xSeek.is() )
5038                 {
5039                     // currently this is an internal property that is used for optimization
5040                     // and the stream must support XSeekable interface
5041                     // TODO/LATER: in future it can be changed if property is used from outside
5042                     throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5043                 }
5044 
5045                 m_pImpl->m_xNewRelInfoStream = xInRelStream;
5046                 m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
5047                 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
5048                 m_pImpl->m_bBroadcastModified = sal_True;
5049                 m_pImpl->m_bIsModified = sal_True;
5050             }
5051             else
5052                 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5053         }
5054         else if ( aPropertyName.equalsAscii( "RelationsInfo" ) )
5055         {
5056             if ( aValue >>= m_pImpl->m_aRelInfo )
5057             {
5058                 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5059                 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5060                 m_pImpl->m_bBroadcastModified = sal_True;
5061                 m_pImpl->m_bIsModified = sal_True;
5062             }
5063             else
5064                 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5065         }
5066         else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( "URL" )
5067                                     || aPropertyName.equalsAscii( "RepairPackage" ) ) )
5068            || aPropertyName.equalsAscii( "IsRoot" ) )
5069             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5070         else
5071             throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5072     }
5073     else
5074         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5075 
5076     BroadcastModifiedIfNecessary();
5077 }
5078 
5079 
5080 //-----------------------------------------------
getPropertyValue(const::rtl::OUString & aPropertyName)5081 uno::Any SAL_CALL OStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
5082         throw ( beans::UnknownPropertyException,
5083                 lang::WrappedTargetException,
5084                 uno::RuntimeException )
5085 {
5086     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPropertyValue" );
5087 
5088     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5089 
5090     if ( !m_pImpl )
5091     {
5092         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5093         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5094     }
5095 
5096     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
5097       && ( aPropertyName.equalsAscii( "MediaType" )
5098         || aPropertyName.equalsAscii( MEDIATYPE_FALLBACK_USED_PROPERTY )
5099         || aPropertyName.equalsAscii( "Version" ) ) )
5100     {
5101         try
5102         {
5103             m_pImpl->ReadContents();
5104         }
5105         catch ( uno::RuntimeException& aRuntimeException )
5106         {
5107             m_pImpl->AddLog( aRuntimeException.Message );
5108             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5109             throw;
5110         }
5111         catch ( uno::Exception& aException )
5112         {
5113             m_pImpl->AddLog( aException.Message );
5114             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5115 
5116             uno::Any aCaught( ::cppu::getCaughtException() );
5117             throw lang::WrappedTargetException(
5118                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't read contents!" ) ),
5119                                         uno::Reference< XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
5120                                         aCaught );
5121         }
5122 
5123         if ( aPropertyName.equalsAscii( "MediaType" ) )
5124             return uno::makeAny( m_pImpl->m_aMediaType );
5125         else if ( aPropertyName.equalsAscii( "Version" ) )
5126             return uno::makeAny( m_pImpl->m_aVersion );
5127         else
5128             return uno::makeAny( m_pImpl->m_bMTFallbackUsed );
5129     }
5130     else if ( aPropertyName.equalsAscii( "IsRoot" ) )
5131     {
5132         return uno::makeAny( m_pData->m_bIsRoot );
5133     }
5134     else if ( aPropertyName.equalsAscii( "OpenMode" ) )
5135     {
5136         return uno::makeAny( m_pImpl->m_nStorageMode );
5137     }
5138     else if ( m_pData->m_bIsRoot )
5139     {
5140         if ( aPropertyName.equalsAscii( "URL" )
5141           || aPropertyName.equalsAscii( "RepairPackage" ) )
5142         {
5143             for ( sal_Int32 aInd = 0; aInd < m_pImpl->m_xProperties.getLength(); aInd++ )
5144             {
5145                 if ( m_pImpl->m_xProperties[aInd].Name.equals( aPropertyName ) )
5146                     return m_pImpl->m_xProperties[aInd].Value;
5147             }
5148 
5149             if ( aPropertyName.equalsAscii( "URL" ) )
5150                 return uno::makeAny( ::rtl::OUString() );
5151 
5152             return uno::makeAny( sal_False ); // RepairPackage
5153         }
5154         else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
5155           && ( aPropertyName.equalsAscii( HAS_ENCRYPTED_ENTRIES_PROPERTY )
5156             || aPropertyName.equalsAscii( HAS_NONENCRYPTED_ENTRIES_PROPERTY )
5157             || aPropertyName.equalsAscii( IS_INCONSISTENT_PROPERTY ) ) )
5158         {
5159             try {
5160                 m_pImpl->ReadContents();
5161                 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
5162                 if ( !xPackPropSet.is() )
5163                     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5164 
5165                 return xPackPropSet->getPropertyValue( aPropertyName );
5166             }
5167             catch ( uno::RuntimeException& aRuntimeException )
5168             {
5169                 m_pImpl->AddLog( aRuntimeException.Message );
5170                 m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5171                 throw;
5172             }
5173             catch ( uno::Exception& aException )
5174             {
5175                 m_pImpl->AddLog( aException.Message );
5176                 m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5177 
5178                 uno::Any aCaught( ::cppu::getCaughtException() );
5179                 throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
5180                                                     uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
5181                                                                                         uno::UNO_QUERY ),
5182                                                     aCaught );
5183             }
5184         }
5185     }
5186 
5187     throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5188 }
5189 
5190 
5191 //-----------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)5192 void SAL_CALL OStorage::addPropertyChangeListener(
5193     const ::rtl::OUString& /*aPropertyName*/,
5194     const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
5195         throw ( beans::UnknownPropertyException,
5196                 lang::WrappedTargetException,
5197                 uno::RuntimeException )
5198 {
5199     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5200 
5201     if ( !m_pImpl )
5202     {
5203         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5204         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5205     }
5206 
5207     //TODO:
5208 }
5209 
5210 
5211 //-----------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)5212 void SAL_CALL OStorage::removePropertyChangeListener(
5213     const ::rtl::OUString& /*aPropertyName*/,
5214     const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
5215         throw ( beans::UnknownPropertyException,
5216                 lang::WrappedTargetException,
5217                 uno::RuntimeException )
5218 {
5219     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5220 
5221     if ( !m_pImpl )
5222     {
5223         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5224         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5225     }
5226 
5227     //TODO:
5228 }
5229 
5230 
5231 //-----------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)5232 void SAL_CALL OStorage::addVetoableChangeListener(
5233     const ::rtl::OUString& /*PropertyName*/,
5234     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
5235         throw ( beans::UnknownPropertyException,
5236                 lang::WrappedTargetException,
5237                 uno::RuntimeException )
5238 {
5239     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5240 
5241     if ( !m_pImpl )
5242     {
5243         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5244         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5245     }
5246 
5247     //TODO:
5248 }
5249 
5250 
5251 //-----------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)5252 void SAL_CALL OStorage::removeVetoableChangeListener(
5253     const ::rtl::OUString& /*PropertyName*/,
5254     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
5255         throw ( beans::UnknownPropertyException,
5256                 lang::WrappedTargetException,
5257                 uno::RuntimeException )
5258 {
5259     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5260 
5261     if ( !m_pImpl )
5262     {
5263         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5264         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5265     }
5266 
5267     //TODO:
5268 }
5269 
5270 //____________________________________________________________________________________________________
5271 //  XRelationshipAccess
5272 //____________________________________________________________________________________________________
5273 
5274 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
5275 
5276 //-----------------------------------------------
hasByID(const::rtl::OUString & sID)5277 sal_Bool SAL_CALL OStorage::hasByID(  const ::rtl::OUString& sID )
5278         throw ( io::IOException,
5279                 uno::RuntimeException )
5280 {
5281     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5282 
5283     if ( !m_pImpl )
5284     {
5285         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5286         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5287     }
5288 
5289     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5290         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5291 
5292     try
5293     {
5294         getRelationshipByID( sID );
5295         return sal_True;
5296     }
5297     catch( container::NoSuchElementException& aNoSuchElementException )
5298     {
5299         m_pImpl->AddLog( aNoSuchElementException.Message );
5300         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
5301     }
5302 
5303     return sal_False;
5304 }
5305 
5306 //-----------------------------------------------
getTargetByID(const::rtl::OUString & sID)5307 ::rtl::OUString SAL_CALL OStorage::getTargetByID(  const ::rtl::OUString& sID  )
5308         throw ( container::NoSuchElementException,
5309                 io::IOException,
5310                 uno::RuntimeException )
5311 {
5312     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5313 
5314     if ( !m_pImpl )
5315     {
5316         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5317         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5318     }
5319 
5320     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5321         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5322 
5323     uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
5324     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
5325         if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
5326             return aSeq[nInd].Second;
5327 
5328     return ::rtl::OUString();
5329 }
5330 
5331 //-----------------------------------------------
getTypeByID(const::rtl::OUString & sID)5332 ::rtl::OUString SAL_CALL OStorage::getTypeByID(  const ::rtl::OUString& sID  )
5333         throw ( container::NoSuchElementException,
5334                 io::IOException,
5335                 uno::RuntimeException )
5336 {
5337     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5338 
5339     if ( !m_pImpl )
5340     {
5341         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5342         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5343     }
5344 
5345     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5346         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5347 
5348     uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
5349     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
5350         if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
5351             return aSeq[nInd].Second;
5352 
5353     return ::rtl::OUString();
5354 }
5355 
5356 //-----------------------------------------------
getRelationshipByID(const::rtl::OUString & sID)5357 uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID(  const ::rtl::OUString& sID  )
5358         throw ( container::NoSuchElementException,
5359                 io::IOException,
5360                 uno::RuntimeException )
5361 {
5362     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5363 
5364     if ( !m_pImpl )
5365     {
5366         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5367         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5368     }
5369 
5370     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5371         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5372 
5373     // TODO/LATER: in future the unification of the ID could be checked
5374     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5375     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5376         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5377             if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
5378             {
5379                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5380                     return aSeq[nInd1];
5381                 break;
5382             }
5383 
5384     throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5385 }
5386 
5387 //-----------------------------------------------
getRelationshipsByType(const::rtl::OUString & sType)5388 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType(  const ::rtl::OUString& sType  )
5389         throw ( io::IOException,
5390                 uno::RuntimeException )
5391 {
5392     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5393 
5394     if ( !m_pImpl )
5395     {
5396         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5397         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5398     }
5399 
5400     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5401         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5402 
5403     uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
5404     sal_Int32 nEntriesNum = 0;
5405 
5406     // TODO/LATER: in future the unification of the ID could be checked
5407     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5408     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5409         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5410             if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
5411             {
5412                 // the type is usually an URL, so the check should be case insensitive
5413                 if ( aSeq[nInd1][nInd2].Second.equalsIgnoreAsciiCase( sType ) )
5414                 {
5415                     aResult.realloc( ++nEntriesNum );
5416                     aResult[nEntriesNum-1] = aSeq[nInd1];
5417                 }
5418                 break;
5419             }
5420 
5421     return aResult;
5422 }
5423 
5424 //-----------------------------------------------
getAllRelationships()5425 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
5426         throw (io::IOException, uno::RuntimeException)
5427 {
5428     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5429 
5430     if ( !m_pImpl )
5431     {
5432         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5433         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5434     }
5435 
5436     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5437         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5438 
5439     return m_pImpl->GetAllRelationshipsIfAny();
5440 }
5441 
5442 //-----------------------------------------------
insertRelationshipByID(const::rtl::OUString & sID,const uno::Sequence<beans::StringPair> & aEntry,::sal_Bool bReplace)5443 void SAL_CALL OStorage::insertRelationshipByID(  const ::rtl::OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, ::sal_Bool bReplace  )
5444         throw ( container::ElementExistException,
5445                 io::IOException,
5446                 uno::RuntimeException )
5447 {
5448     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5449 
5450     if ( !m_pImpl )
5451     {
5452         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5453         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5454     }
5455 
5456     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5457         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5458 
5459     ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
5460 
5461     sal_Int32 nIDInd = -1;
5462 
5463     // TODO/LATER: in future the unification of the ID could be checked
5464     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5465     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5466         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5467             if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
5468             {
5469                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5470                     nIDInd = nInd1;
5471 
5472                 break;
5473             }
5474 
5475     if ( nIDInd == -1 || bReplace )
5476     {
5477         if ( nIDInd == -1 )
5478         {
5479             nIDInd = aSeq.getLength();
5480             aSeq.realloc( nIDInd + 1 );
5481         }
5482 
5483         aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
5484 
5485         aSeq[nIDInd][0].First = aIDTag;
5486         aSeq[nIDInd][0].Second = sID;
5487         sal_Int32 nIndTarget = 1;
5488         for ( sal_Int32 nIndOrig = 0;
5489               nIndOrig < aEntry.getLength();
5490               nIndOrig++ )
5491         {
5492             if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
5493                 aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
5494         }
5495 
5496         aSeq[nIDInd].realloc( nIndTarget );
5497     }
5498     else
5499         throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5500 
5501 
5502     m_pImpl->m_aRelInfo = aSeq;
5503     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5504     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5505 }
5506 
5507 //-----------------------------------------------
removeRelationshipByID(const::rtl::OUString & sID)5508 void SAL_CALL OStorage::removeRelationshipByID(  const ::rtl::OUString& sID  )
5509         throw ( container::NoSuchElementException,
5510                 io::IOException,
5511                 uno::RuntimeException )
5512 {
5513     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5514 
5515     if ( !m_pImpl )
5516     {
5517         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5518         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5519     }
5520 
5521     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5522         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5523 
5524     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5525     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5526         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5527             if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
5528             {
5529                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5530                 {
5531                     sal_Int32 nLength = aSeq.getLength();
5532                     aSeq[nInd1] = aSeq[nLength-1];
5533                     aSeq.realloc( nLength - 1 );
5534 
5535                     m_pImpl->m_aRelInfo = aSeq;
5536                     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5537                     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5538 
5539                     // TODO/LATER: in future the unification of the ID could be checked
5540                     return;
5541                 }
5542 
5543                 break;
5544             }
5545 
5546     throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5547 }
5548 
5549 //-----------------------------------------------
insertRelationships(const uno::Sequence<uno::Sequence<beans::StringPair>> & aEntries,::sal_Bool bReplace)5550 void SAL_CALL OStorage::insertRelationships(  const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, ::sal_Bool bReplace  )
5551         throw ( container::ElementExistException,
5552                 io::IOException,
5553                 uno::RuntimeException )
5554 {
5555     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5556 
5557     if ( !m_pImpl )
5558     {
5559         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5560         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5561     }
5562 
5563     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5564         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5565 
5566     ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
5567     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5568     uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
5569     sal_Int32 nResultInd = 0;
5570 
5571     for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
5572         for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
5573             if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
5574             {
5575                 sal_Int32 nIndSourceSame = -1;
5576 
5577                 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
5578                     for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
5579                     {
5580                         if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
5581                         {
5582                             if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
5583                             {
5584                                 if ( !bReplace )
5585                                     throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5586 
5587                                 nIndSourceSame = nIndSource1;
5588                             }
5589 
5590                             break;
5591                         }
5592                     }
5593 
5594                 if ( nIndSourceSame == -1 )
5595                 {
5596                     // no such element in the provided sequence
5597                     aResultSeq[nResultInd++] = aSeq[nIndTarget1];
5598                 }
5599 
5600                 break;
5601             }
5602 
5603     for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
5604     {
5605         aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
5606         sal_Bool bHasID = sal_False;
5607         sal_Int32 nResInd2 = 1;
5608 
5609         for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
5610             if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
5611             {
5612                 aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
5613                 bHasID = sal_True;
5614             }
5615             else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
5616                 aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
5617             else
5618                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: illegal relation ( no ID )
5619 
5620         if ( !bHasID )
5621             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: illegal relations
5622 
5623         nResultInd++;
5624     }
5625 
5626     aResultSeq.realloc( nResultInd );
5627     m_pImpl->m_aRelInfo = aResultSeq;
5628     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5629     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5630 }
5631 
5632 //-----------------------------------------------
clearRelationships()5633 void SAL_CALL OStorage::clearRelationships()
5634         throw ( io::IOException,
5635                 uno::RuntimeException )
5636 {
5637     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5638 
5639     if ( !m_pImpl )
5640     {
5641         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5642         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5643     }
5644 
5645     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5646         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5647 
5648     m_pImpl->m_aRelInfo.realloc( 0 );
5649     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5650     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5651 }
5652 
5653 //____________________________________________________________________________________________________
5654 //  XOptimizedStorage
5655 //____________________________________________________________________________________________________
5656 //-----------------------------------------------
insertRawNonEncrStreamElementDirect(const::rtl::OUString &,const uno::Reference<io::XInputStream> &)5657 void SAL_CALL OStorage::insertRawNonEncrStreamElementDirect(
5658             const ::rtl::OUString& /*sStreamName*/,
5659             const uno::Reference< io::XInputStream >& /*xInStream*/ )
5660         throw ( embed::InvalidStorageException,
5661                 lang::IllegalArgumentException,
5662                 packages::NoRawFormatException,
5663                 container::ElementExistException,
5664                 io::IOException,
5665                 embed::StorageWrappedTargetException,
5666                 uno::RuntimeException )
5667 {
5668     // not implemented currently because there is still no demand
5669     // might need to be implemented if direct copying of compressed streams is used
5670     throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5671 }
5672 
5673 //-----------------------------------------------
insertStreamElementDirect(const::rtl::OUString & aStreamName,const uno::Reference<io::XInputStream> & xInStream,const uno::Sequence<beans::PropertyValue> & aProps)5674 void SAL_CALL OStorage::insertStreamElementDirect(
5675             const ::rtl::OUString& aStreamName,
5676             const uno::Reference< io::XInputStream >& xInStream,
5677             const uno::Sequence< beans::PropertyValue >& aProps )
5678         throw ( embed::InvalidStorageException,
5679                 lang::IllegalArgumentException,
5680                 container::ElementExistException,
5681                 io::IOException,
5682                 embed::StorageWrappedTargetException,
5683                 uno::RuntimeException )
5684 {
5685     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertStreamElementDirect" );
5686 
5687     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5688 
5689     if ( !m_pImpl )
5690     {
5691         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5692         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5693     }
5694 
5695     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
5696         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5697 
5698     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
5699       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5700         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
5701 
5702     if ( m_pData->m_bReadOnlyWrap )
5703         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
5704 
5705     try
5706     {
5707         SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
5708 
5709         if ( pElement )
5710             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5711 
5712         pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, sal_False );
5713         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
5714 
5715         pElement->m_pStream->InsertStreamDirectly( xInStream, aProps );
5716     }
5717     catch( embed::InvalidStorageException& aInvalidStorageException )
5718     {
5719         m_pImpl->AddLog( aInvalidStorageException.Message );
5720         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5721         throw;
5722     }
5723     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5724     {
5725         m_pImpl->AddLog( aIllegalArgumentException.Message );
5726         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5727         throw;
5728     }
5729     catch( container::ElementExistException& aElementExistException )
5730     {
5731         m_pImpl->AddLog( aElementExistException.Message );
5732         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5733         throw;
5734     }
5735     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5736     {
5737         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5738         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5739         throw;
5740     }
5741     catch( io::IOException& aIOException )
5742     {
5743         m_pImpl->AddLog( aIOException.Message );
5744         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5745         throw;
5746     }
5747     catch( uno::RuntimeException& aRuntimeException )
5748     {
5749         m_pImpl->AddLog( aRuntimeException.Message );
5750         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5751         throw;
5752     }
5753     catch( uno::Exception& aException )
5754     {
5755         m_pImpl->AddLog( aException.Message );
5756         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5757 
5758         uno::Any aCaught( ::cppu::getCaughtException() );
5759         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't insert stream directly!" ) ),
5760                                                  uno::Reference< io::XInputStream >(),
5761                                                  aCaught );
5762     }
5763 }
5764 
5765 //-----------------------------------------------
copyElementDirectlyTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XOptimizedStorage> & xDest,const::rtl::OUString & aNewName)5766 void SAL_CALL OStorage::copyElementDirectlyTo(
5767             const ::rtl::OUString& aElementName,
5768             const uno::Reference< embed::XOptimizedStorage >& xDest,
5769             const ::rtl::OUString& aNewName )
5770         throw ( embed::InvalidStorageException,
5771                 lang::IllegalArgumentException,
5772                 container::NoSuchElementException,
5773                 container::ElementExistException,
5774                 io::IOException,
5775                 embed::StorageWrappedTargetException,
5776                 uno::RuntimeException )
5777 {
5778     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementDirectlyTo" );
5779 
5780     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5781 
5782     if ( !m_pImpl )
5783     {
5784         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5785         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5786     }
5787 
5788     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
5789       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
5790         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5791 
5792     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
5793         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
5794 
5795     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
5796       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
5797         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
5798         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable name
5799 
5800     try
5801     {
5802         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
5803         if ( !pElement )
5804             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5805 
5806         uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
5807         if ( !xNameAccess.is() )
5808             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5809 
5810         if ( xNameAccess->hasByName( aNewName ) )
5811             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5812 
5813         // let the element be copied directly
5814         uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
5815         m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, sal_True );
5816     }
5817     catch( embed::InvalidStorageException& aInvalidStorageException )
5818     {
5819         m_pImpl->AddLog( aInvalidStorageException.Message );
5820         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5821         throw;
5822     }
5823     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5824     {
5825         m_pImpl->AddLog( aIllegalArgumentException.Message );
5826         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5827         throw;
5828     }
5829     catch( container::NoSuchElementException& aNoSuchElementException )
5830     {
5831         m_pImpl->AddLog( aNoSuchElementException.Message );
5832         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5833         throw;
5834     }
5835     catch( container::ElementExistException& aElementExistException )
5836     {
5837         m_pImpl->AddLog( aElementExistException.Message );
5838         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5839         throw;
5840     }
5841     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5842     {
5843         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5844         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5845         throw;
5846     }
5847     catch( io::IOException& aIOException )
5848     {
5849         m_pImpl->AddLog( aIOException.Message );
5850         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5851         throw;
5852     }
5853     catch( uno::RuntimeException& aRuntimeException )
5854     {
5855         m_pImpl->AddLog( aRuntimeException.Message );
5856         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5857         throw;
5858     }
5859     catch( uno::Exception& aException )
5860     {
5861         m_pImpl->AddLog( aException.Message );
5862         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5863 
5864         uno::Any aCaught( ::cppu::getCaughtException() );
5865         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy element direcly!" ) ),
5866                                                  uno::Reference< io::XInputStream >(),
5867                                                  aCaught );
5868     }
5869 }
5870 
5871 //-----------------------------------------------
writeAndAttachToStream(const uno::Reference<io::XStream> & xStream)5872 void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
5873         throw ( embed::InvalidStorageException,
5874                 lang::IllegalArgumentException,
5875                 io::IOException,
5876                 embed::StorageWrappedTargetException,
5877                 uno::RuntimeException )
5878 {
5879     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::writeAndAttachToStream" );
5880 
5881     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5882 
5883     if ( !m_pImpl )
5884     {
5885         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5886         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5887     }
5888 
5889     if ( !m_pData->m_bIsRoot )
5890         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5891 
5892     if ( !m_pImpl->m_pSwitchStream )
5893         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5894 
5895     try
5896     {
5897         m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
5898     }
5899     catch( embed::InvalidStorageException& aInvalidStorageException )
5900     {
5901         m_pImpl->AddLog( aInvalidStorageException.Message );
5902         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5903         throw;
5904     }
5905     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5906     {
5907         m_pImpl->AddLog( aIllegalArgumentException.Message );
5908         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5909         throw;
5910     }
5911     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5912     {
5913         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5914         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5915         throw;
5916     }
5917     catch( io::IOException& aIOException )
5918     {
5919         m_pImpl->AddLog( aIOException.Message );
5920         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5921         throw;
5922     }
5923     catch( uno::RuntimeException& aRuntimeException )
5924     {
5925         m_pImpl->AddLog( aRuntimeException.Message );
5926         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5927         throw;
5928     }
5929     catch( uno::Exception& aException )
5930     {
5931         m_pImpl->AddLog( aException.Message );
5932         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5933 
5934         uno::Any aCaught( ::cppu::getCaughtException() );
5935         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't write and attach to stream!" ) ),
5936                                                  uno::Reference< io::XInputStream >(),
5937                                                  aCaught );
5938     }
5939 
5940 }
5941 
5942 //-----------------------------------------------
attachToURL(const::rtl::OUString & sURL,sal_Bool bReadOnly)5943 void SAL_CALL OStorage::attachToURL( const ::rtl::OUString& sURL,
5944                                     sal_Bool bReadOnly )
5945         throw ( embed::InvalidStorageException,
5946                 lang::IllegalArgumentException,
5947                 io::IOException,
5948                 embed::StorageWrappedTargetException,
5949                 uno::RuntimeException )
5950 {
5951     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::attachToURL" );
5952 
5953     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5954 
5955     if ( !m_pImpl )
5956     {
5957         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5958         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5959     }
5960 
5961     if ( !m_pData->m_bIsRoot )
5962         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5963 
5964     if ( !m_pImpl->m_pSwitchStream )
5965         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5966 
5967     uno::Reference < ucb::XSimpleFileAccess > xAccess(
5968             m_pImpl->m_xFactory->createInstance (
5969                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
5970             uno::UNO_QUERY_THROW );
5971 
5972     try
5973     {
5974         if ( bReadOnly )
5975         {
5976             uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
5977             m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
5978         }
5979         else
5980         {
5981             uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
5982             m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
5983         }
5984     }
5985     catch( embed::InvalidStorageException& aInvalidStorageException )
5986     {
5987         m_pImpl->AddLog( aInvalidStorageException.Message );
5988         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5989         throw;
5990     }
5991     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5992     {
5993         m_pImpl->AddLog( aIllegalArgumentException.Message );
5994         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5995         throw;
5996     }
5997     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5998     {
5999         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
6000         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6001         throw;
6002     }
6003     catch( io::IOException& aIOException )
6004     {
6005         m_pImpl->AddLog( aIOException.Message );
6006         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6007         throw;
6008     }
6009     catch( uno::RuntimeException& aRuntimeException )
6010     {
6011         m_pImpl->AddLog( aRuntimeException.Message );
6012         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6013         throw;
6014     }
6015     catch( uno::Exception& aException )
6016     {
6017         m_pImpl->AddLog( aException.Message );
6018         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6019 
6020         uno::Any aCaught( ::cppu::getCaughtException() );
6021         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't attach to URL!" ) ),
6022                                                  uno::Reference< io::XInputStream >(),
6023                                                  aCaught );
6024     }
6025 }
6026 
6027 //-----------------------------------------------
getElementPropertyValue(const::rtl::OUString & aElementName,const::rtl::OUString & aPropertyName)6028 uno::Any SAL_CALL OStorage::getElementPropertyValue( const ::rtl::OUString& aElementName, const ::rtl::OUString& aPropertyName )
6029         throw ( embed::InvalidStorageException,
6030                 lang::IllegalArgumentException,
6031                 container::NoSuchElementException,
6032                 io::IOException,
6033                 beans::UnknownPropertyException,
6034                 beans::PropertyVetoException,
6035                 embed::StorageWrappedTargetException,
6036                 uno::RuntimeException)
6037 {
6038     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementPropertyValue" );
6039 
6040     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6041 
6042     if ( !m_pImpl )
6043     {
6044         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
6045         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6046     }
6047 
6048     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
6049         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
6050 
6051     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
6052       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
6053         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
6054 
6055     try
6056     {
6057         SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
6058         if ( !pElement )
6059             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6060 
6061         // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
6062         if ( !pElement->m_bIsStorage || m_pData->m_nStorageType != embed::StorageFormats::PACKAGE || !aPropertyName.equalsAscii( "MediaType" ) )
6063             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6064 
6065         if ( !pElement->m_pStorage )
6066             m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
6067 
6068         if ( !pElement->m_pStorage )
6069             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
6070 
6071         pElement->m_pStorage->ReadContents();
6072         return uno::makeAny( pElement->m_pStorage->m_aMediaType );
6073     }
6074     catch( embed::InvalidStorageException& aInvalidStorageException )
6075     {
6076         m_pImpl->AddLog( aInvalidStorageException.Message );
6077         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6078         throw;
6079     }
6080     catch( lang::IllegalArgumentException& aIllegalArgumentException )
6081     {
6082         m_pImpl->AddLog( aIllegalArgumentException.Message );
6083         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6084         throw;
6085     }
6086     catch( container::NoSuchElementException& aNoSuchElementException )
6087     {
6088         m_pImpl->AddLog( aNoSuchElementException.Message );
6089         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6090         throw;
6091     }
6092     catch( beans::UnknownPropertyException& aUnknownPropertyException )
6093     {
6094         m_pImpl->AddLog( aUnknownPropertyException.Message );
6095         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6096         throw;
6097     }
6098     catch( beans::PropertyVetoException& aPropertyVetoException )
6099     {
6100         m_pImpl->AddLog( aPropertyVetoException.Message );
6101         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6102         throw;
6103     }
6104     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
6105     {
6106         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
6107         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6108         throw;
6109     }
6110     catch( io::IOException& aIOException )
6111     {
6112         m_pImpl->AddLog( aIOException.Message );
6113         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6114         throw;
6115     }
6116     catch( uno::RuntimeException& aRuntimeException )
6117     {
6118         m_pImpl->AddLog( aRuntimeException.Message );
6119         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6120         throw;
6121     }
6122     catch( uno::Exception& aException )
6123     {
6124         m_pImpl->AddLog( aException.Message );
6125         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6126 
6127         uno::Any aCaught( ::cppu::getCaughtException() );
6128         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get element property!" ) ),
6129                                                  uno::Reference< io::XInputStream >(),
6130                                                  aCaught );
6131     }
6132 }
6133 
6134 //-----------------------------------------------
copyStreamElementData(const::rtl::OUString & aStreamName,const uno::Reference<io::XStream> & xTargetStream)6135 void SAL_CALL OStorage::copyStreamElementData( const ::rtl::OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
6136         throw ( embed::InvalidStorageException,
6137                 lang::IllegalArgumentException,
6138                 packages::WrongPasswordException,
6139                 io::IOException,
6140                 embed::StorageWrappedTargetException,
6141                 uno::RuntimeException )
6142 {
6143     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6144 
6145     if ( !m_pImpl )
6146     {
6147         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
6148         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6149     }
6150 
6151     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
6152         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
6153 
6154     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
6155       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
6156         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
6157 
6158     if ( !xTargetStream.is() )
6159         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
6160 
6161     try
6162     {
6163         uno::Reference< io::XStream > xNonconstRef = xTargetStream;
6164         m_pImpl->CloneStreamElement( aStreamName, sal_False, ::comphelper::SequenceAsHashMap(), xNonconstRef );
6165 
6166         OSL_ENSURE( xNonconstRef == xTargetStream, "The provided stream reference seems not be filled in correctly!\n" );
6167         if ( xNonconstRef != xTargetStream )
6168             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // if the stream reference is set it must not be changed!
6169     }
6170     catch( embed::InvalidStorageException& aInvalidStorageException )
6171     {
6172         m_pImpl->AddLog( aInvalidStorageException.Message );
6173         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6174         throw;
6175     }
6176     catch( lang::IllegalArgumentException& aIllegalArgumentException )
6177     {
6178         m_pImpl->AddLog( aIllegalArgumentException.Message );
6179         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6180         throw;
6181     }
6182     catch( packages::WrongPasswordException& aWrongPasswordException )
6183     {
6184         m_pImpl->AddLog( aWrongPasswordException.Message );
6185         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6186         throw;
6187     }
6188     catch( io::IOException& aIOException )
6189     {
6190         m_pImpl->AddLog( aIOException.Message );
6191         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6192         throw;
6193     }
6194     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
6195     {
6196         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
6197         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6198         throw;
6199     }
6200     catch( uno::RuntimeException& aRuntimeException )
6201     {
6202         m_pImpl->AddLog( aRuntimeException.Message );
6203         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6204         throw;
6205     }
6206     catch( uno::Exception& aException )
6207     {
6208         m_pImpl->AddLog( aException.Message );
6209         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
6210 
6211         uno::Any aCaught( ::cppu::getCaughtException() );
6212         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy stream data!" ) ),
6213                                                  uno::Reference< io::XInputStream >(),
6214                                                  aCaught );
6215     }
6216 
6217 
6218 }
6219 
6220 //____________________________________________________________________________________________________
6221 // XHierarchicalStorageAccess
6222 //____________________________________________________________________________________________________
6223 
6224 //-----------------------------------------------
openStreamElementByHierarchicalName(const::rtl::OUString & aStreamPath,::sal_Int32 nOpenMode)6225 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode )
6226         throw ( embed::InvalidStorageException,
6227                 lang::IllegalArgumentException,
6228                 packages::WrongPasswordException,
6229                 io::IOException,
6230                 embed::StorageWrappedTargetException,
6231                 uno::RuntimeException )
6232 {
6233     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6234 
6235     if ( !m_pImpl )
6236     {
6237         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
6238         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6239     }
6240 
6241     if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6242         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
6243 
6244     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
6245       && ( nOpenMode & embed::ElementModes::WRITE ) )
6246         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
6247 
6248     OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6249     OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6250 
6251     uno::Reference< embed::XExtendedStorageStream > xResult;
6252     if ( aListPath.size() == 1 )
6253     {
6254         // that must be a direct request for a stream
6255         // the transacted version of the stream should be opened
6256 
6257         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_False );
6258         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
6259 
6260         xResult = uno::Reference< embed::XExtendedStorageStream >(
6261                         pElement->m_pStream->GetStream( nOpenMode, sal_True ),
6262                         uno::UNO_QUERY_THROW );
6263     }
6264     else
6265     {
6266         // there are still storages in between
6267         if ( !m_pData->m_rHierarchyHolder.is() )
6268             m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6269                 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6270 
6271         xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
6272                                                 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
6273                                                 aListPath,
6274                                                 nOpenMode );
6275     }
6276 
6277     if ( !xResult.is() )
6278         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6279 
6280     return xResult;
6281 }
6282 
6283 //-----------------------------------------------
openEncryptedStreamElementByHierarchicalName(const::rtl::OUString & aStreamPath,::sal_Int32 nOpenMode,const::rtl::OUString & sPassword)6284 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode, const ::rtl::OUString& sPassword )
6285         throw ( embed::InvalidStorageException,
6286                 lang::IllegalArgumentException,
6287                 packages::NoEncryptionException,
6288                 packages::WrongPasswordException,
6289                 io::IOException,
6290                 embed::StorageWrappedTargetException,
6291                 uno::RuntimeException )
6292 {
6293     return openEncryptedStreamByHierarchicalName( aStreamPath, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword ) );
6294 }
6295 
6296 //-----------------------------------------------
removeStreamElementByHierarchicalName(const::rtl::OUString & aStreamPath)6297 void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath )
6298         throw ( embed::InvalidStorageException,
6299                 lang::IllegalArgumentException,
6300                 container::NoSuchElementException,
6301                 io::IOException,
6302                 embed::StorageWrappedTargetException,
6303                 uno::RuntimeException )
6304 {
6305     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6306 
6307     if ( !m_pImpl )
6308     {
6309         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
6310         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6311     }
6312 
6313     if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6314         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
6315 
6316     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
6317         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
6318 
6319     OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6320     OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6321 
6322     if ( !m_pData->m_rHierarchyHolder.is() )
6323         m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6324             uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6325 
6326     m_pData->m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );
6327 }
6328 
6329 //____________________________________________________________________________________________________
6330 // XHierarchicalStorageAccess2
6331 //____________________________________________________________________________________________________
6332 
openEncryptedStreamByHierarchicalName(const::rtl::OUString & aStreamPath,::sal_Int32 nOpenMode,const uno::Sequence<beans::NamedValue> & aEncryptionData)6333 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
6334         throw ( embed::InvalidStorageException,
6335                 lang::IllegalArgumentException,
6336                 packages::NoEncryptionException,
6337                 packages::WrongPasswordException,
6338                 io::IOException,
6339                 embed::StorageWrappedTargetException,
6340                 uno::RuntimeException )
6341 {
6342     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6343 
6344     if ( !m_pImpl )
6345     {
6346         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
6347         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6348     }
6349 
6350     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
6351         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6352 
6353     if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6354         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
6355 
6356     if ( !aEncryptionData.getLength() )
6357         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 3 );
6358 
6359     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
6360       && ( nOpenMode & embed::ElementModes::WRITE ) )
6361         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
6362 
6363     OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6364     OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6365 
6366     uno::Reference< embed::XExtendedStorageStream > xResult;
6367     if ( aListPath.size() == 1 )
6368     {
6369         // that must be a direct request for a stream
6370         // the transacted version of the stream should be opened
6371 
6372         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_True );
6373         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
6374 
6375         xResult = uno::Reference< embed::XExtendedStorageStream >(
6376                         pElement->m_pStream->GetStream( nOpenMode, aEncryptionData, sal_True ),
6377                         uno::UNO_QUERY_THROW );
6378     }
6379     else
6380     {
6381         // there are still storages in between
6382         if ( !m_pData->m_rHierarchyHolder.is() )
6383             m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6384                 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6385 
6386         xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
6387                                                 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
6388                                                 aListPath,
6389                                                 nOpenMode,
6390                                                 aEncryptionData );
6391     }
6392 
6393     if ( !xResult.is() )
6394         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6395 
6396     return xResult;
6397 }
6398 
6399 
6400