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