xref: /trunk/main/package/source/xstor/xstorage.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 {
1371     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
1372 
1373     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1374         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1375 
1376     if ( m_bIsRoot )
1377     {
1378         if ( !m_bHasCommonEncryptionData )
1379             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1380 
1381         return m_aCommonEncryptionData;
1382     }
1383     else
1384     {
1385         if ( !m_pParent )
1386             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1387 
1388         return m_pParent->GetCommonRootEncryptionData();
1389     }
1390 }
1391 
1392 //-----------------------------------------------
FindElement(const::rtl::OUString & rName)1393 SotElement_Impl* OStorage_Impl::FindElement( const ::rtl::OUString& rName )
1394 {
1395     OSL_ENSURE( rName.getLength(), "Name is empty!" );
1396 
1397     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1398 
1399     ReadContents();
1400 
1401     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1402           pElementIter != m_aChildrenList.end(); pElementIter++ )
1403     {
1404         if ( (*pElementIter)->m_aName == rName && !(*pElementIter)->m_bIsRemoved )
1405             return *pElementIter;
1406     }
1407 
1408     return NULL;
1409 }
1410 
1411 //-----------------------------------------------
InsertStream(::rtl::OUString aName,sal_Bool bEncr)1412 SotElement_Impl* OStorage_Impl::InsertStream( ::rtl::OUString aName, sal_Bool bEncr )
1413 {
1414     OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1415     if ( !m_xPackage.is() )
1416         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1417 
1418     uno::Sequence< uno::Any > aSeq( 1 );
1419     aSeq[0] <<= sal_False;
1420     uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1421                                                     uno::UNO_QUERY );
1422 
1423     OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1424     if ( !xNewElement.is() )
1425         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1426 
1427     uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1428     if ( !xPackageSubStream.is() )
1429         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1430 
1431     OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE || !bEncr, "Only package storage supports encryption!\n" );
1432     if ( m_nStorageType != embed::StorageFormats::PACKAGE && bEncr )
1433         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1434 
1435     // the mode is not needed for storage stream internal implementation
1436     SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1437     pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, bEncr, m_nStorageType, sal_True );
1438 
1439     m_aChildrenList.push_back( pNewElement );
1440     m_bIsModified = sal_True;
1441     m_bBroadcastModified = sal_True;
1442 
1443     return pNewElement;
1444 }
1445 
1446 //-----------------------------------------------
InsertRawStream(::rtl::OUString aName,const uno::Reference<io::XInputStream> & xInStream)1447 SotElement_Impl* OStorage_Impl::InsertRawStream( ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInStream )
1448 {
1449     // insert of raw stream means insert and commit
1450     OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1451     if ( !m_xPackage.is() )
1452         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1453 
1454     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1455         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1456 
1457     uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1458     uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
1459                                                                      GetSeekableTempCopy( xInStream, GetServiceFactory() );
1460 
1461     uno::Sequence< uno::Any > aSeq( 1 );
1462     aSeq[0] <<= sal_False;
1463     uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1464                                                     uno::UNO_QUERY );
1465 
1466     OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1467     if ( !xNewElement.is() )
1468         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1469 
1470     uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1471     if ( !xPackageSubStream.is() )
1472         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1473 
1474     xPackageSubStream->setRawStream( xInStrToInsert );
1475 
1476     // the mode is not needed for storage stream internal implementation
1477     SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1478     pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_True, m_nStorageType, sal_False );
1479     // the stream is inserted and must be treated as a committed one
1480     pNewElement->m_pStream->SetToBeCommited();
1481 
1482     m_aChildrenList.push_back( pNewElement );
1483     m_bIsModified = sal_True;
1484     m_bBroadcastModified = sal_True;
1485 
1486     return pNewElement;
1487 }
1488 
1489 //-----------------------------------------------
CreateNewStorageImpl(sal_Int32 nStorageMode)1490 OStorage_Impl* OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
1491 {
1492     OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1493     if ( !m_xPackage.is() )
1494         throw embed::InvalidStorageException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1495 
1496     uno::Sequence< uno::Any > aSeq( 1 );
1497     aSeq[0] <<= sal_True;
1498     uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1499                                                     uno::UNO_QUERY );
1500 
1501     OSL_ENSURE( xNewElement.is(), "Not possible to create a new storage!\n" );
1502     if ( !xNewElement.is() )
1503         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1504 
1505     uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY );
1506     if ( !xPackageSubFolder.is() )
1507         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1508 
1509     OStorage_Impl* pResult =
1510             new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
1511     pResult->m_bIsModified = sal_True;
1512 
1513     return pResult;
1514 }
1515 
1516 //-----------------------------------------------
InsertStorage(::rtl::OUString aName,sal_Int32 nStorageMode)1517 SotElement_Impl* OStorage_Impl::InsertStorage( ::rtl::OUString aName, sal_Int32 nStorageMode )
1518 {
1519     SotElement_Impl* pNewElement = InsertElement( aName, sal_True );
1520 
1521     pNewElement->m_pStorage = CreateNewStorageImpl( nStorageMode );
1522 
1523     m_aChildrenList.push_back( pNewElement );
1524 
1525     return pNewElement;
1526 }
1527 
1528 //-----------------------------------------------
InsertElement(::rtl::OUString aName,sal_Bool bIsStorage)1529 SotElement_Impl* OStorage_Impl::InsertElement( ::rtl::OUString aName, sal_Bool bIsStorage )
1530 {
1531     OSL_ENSURE( FindElement( aName ) == NULL, "Should not try to insert existing element" );
1532 
1533     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1534 
1535     SotElement_Impl* pDeletedElm = NULL;
1536 
1537     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1538           pElementIter != m_aChildrenList.end(); pElementIter++ )
1539     {
1540         if ( (*pElementIter)->m_aName == aName )
1541         {
1542             OSL_ENSURE( (*pElementIter)->m_bIsRemoved, "Try to insert an element instead of existing one!\n" );
1543             if ( (*pElementIter)->m_bIsRemoved )
1544             {
1545                 OSL_ENSURE( !(*pElementIter)->m_bIsInserted, "Inserted elements must be deleted immediately!\n" );
1546                 pDeletedElm = *pElementIter;
1547                 break;
1548             }
1549         }
1550     }
1551 
1552     if ( pDeletedElm )
1553     {
1554         if ( pDeletedElm->m_bIsStorage )
1555             OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
1556         else
1557             OpenSubStream( pDeletedElm );
1558 
1559         m_aChildrenList.remove( pDeletedElm );  // correct usage of list ???
1560         m_aDeletedList.push_back( pDeletedElm );
1561     }
1562 
1563     // create new element
1564     return new SotElement_Impl( aName, bIsStorage, sal_True );
1565 }
1566 
1567 //-----------------------------------------------
OpenSubStorage(SotElement_Impl * pElement,sal_Int32 nStorageMode)1568 void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
1569 {
1570     OSL_ENSURE( pElement, "pElement is not set!\n" );
1571     OSL_ENSURE( pElement->m_bIsStorage, "Storage flag is not set!\n" );
1572 
1573     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1574 
1575     if ( !pElement->m_pStorage )
1576     {
1577         OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1578 
1579         uno::Reference< lang::XUnoTunnel > xTunnel;
1580         m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1581         if ( !xTunnel.is() )
1582             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1583 
1584         uno::Reference< container::XNameContainer > xPackageSubFolder( xTunnel, uno::UNO_QUERY );
1585 
1586         OSL_ENSURE( xPackageSubFolder.is(), "Can not get XNameContainer interface from folder!\n" );
1587 
1588         if ( !xPackageSubFolder.is() )
1589             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1590 
1591         pElement->m_pStorage = new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
1592     }
1593 }
1594 
1595 //-----------------------------------------------
OpenSubStream(SotElement_Impl * pElement)1596 void OStorage_Impl::OpenSubStream( SotElement_Impl* pElement )
1597 {
1598     OSL_ENSURE( pElement, "pElement is not set!\n" );
1599     OSL_ENSURE( !pElement->m_bIsStorage, "Storage flag is set!\n" );
1600 
1601     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1602 
1603     if ( !pElement->m_pStream )
1604     {
1605         OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1606 
1607         uno::Reference< lang::XUnoTunnel > xTunnel;
1608         m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1609         if ( !xTunnel.is() )
1610             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1611 
1612         uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTunnel, uno::UNO_QUERY );
1613         if ( !xPackageSubStream.is() )
1614             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1615 
1616         // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1617         pElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_False, m_nStorageType, sal_False, GetRelInfoStreamForName( pElement->m_aOriginalName ) );
1618     }
1619 }
1620 
1621 //-----------------------------------------------
GetElementNames()1622 uno::Sequence< ::rtl::OUString > OStorage_Impl::GetElementNames()
1623 {
1624     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1625 
1626     ReadContents();
1627 
1628     sal_uInt32 nSize = m_aChildrenList.size();
1629     uno::Sequence< ::rtl::OUString > aElementNames( nSize );
1630 
1631     sal_uInt32 nInd = 0;
1632     for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1633           pElementIter != m_aChildrenList.end(); pElementIter++ )
1634     {
1635         if ( !(*pElementIter)->m_bIsRemoved )
1636             aElementNames[nInd++] = (*pElementIter)->m_aName;
1637     }
1638 
1639     aElementNames.realloc( nInd );
1640     return aElementNames;
1641 }
1642 
1643 //-----------------------------------------------
RemoveElement(SotElement_Impl * pElement)1644 void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
1645 {
1646     OSL_ENSURE( pElement, "Element must be provided!" );
1647 
1648     if ( !pElement )
1649         return;
1650 
1651     if ( (pElement->m_pStorage && ( pElement->m_pStorage->m_pAntiImpl || !pElement->m_pStorage->m_aReadOnlyWrapList.empty() ))
1652       || (pElement->m_pStream && ( pElement->m_pStream->m_pAntiImpl || !pElement->m_pStream->m_aInputStreamsList.empty() )) )
1653         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Access denied
1654 
1655     if ( pElement->m_bIsInserted )
1656     {
1657         m_aChildrenList.remove( pElement );
1658         delete pElement; // ???
1659     }
1660     else
1661     {
1662         pElement->m_bIsRemoved = sal_True;
1663         ClearElement( pElement );
1664     }
1665 
1666     // TODO/OFOPXML: the rel stream should be removed as well
1667 }
1668 
1669 //-----------------------------------------------
ClearElement(SotElement_Impl * pElement)1670 void OStorage_Impl::ClearElement( SotElement_Impl* pElement )
1671 {
1672     if ( pElement->m_pStorage )
1673     {
1674         delete pElement->m_pStorage;
1675         pElement->m_pStorage = NULL;
1676     }
1677 
1678     if ( pElement->m_pStream )
1679     {
1680         delete pElement->m_pStream;
1681         pElement->m_pStream = NULL;
1682     }
1683 }
1684 
1685 //-----------------------------------------------
CloneStreamElement(const::rtl::OUString & aStreamName,sal_Bool bEncryptionDataProvided,const::comphelper::SequenceAsHashMap & aEncryptionData,uno::Reference<io::XStream> & xTargetStream)1686 void OStorage_Impl::CloneStreamElement( const ::rtl::OUString& aStreamName,
1687                                         sal_Bool bEncryptionDataProvided,
1688                                         const ::comphelper::SequenceAsHashMap& aEncryptionData,
1689                                         uno::Reference< io::XStream >& xTargetStream )
1690 {
1691     SotElement_Impl *pElement = FindElement( aStreamName );
1692     if ( !pElement )
1693     {
1694         // element does not exist, throw exception
1695         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
1696     }
1697     else if ( pElement->m_bIsStorage )
1698         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1699 
1700     if ( !pElement->m_pStream )
1701         OpenSubStream( pElement );
1702 
1703     if ( pElement->m_pStream && pElement->m_pStream->m_xPackageStream.is() )
1704     {
1705         // the existence of m_pAntiImpl of the child is not interesting,
1706         // the copy will be created internally
1707 
1708         // usual copying is not applicable here, only last flushed version of the
1709         // child stream should be used for copying. Probably the childs m_xPackageStream
1710         // can be used as a base of a new stream, that would be copied to result
1711         // storage. The only problem is that some package streams can be accessed from outside
1712         // at the same time ( now solved by wrappers that remember own position ).
1713 
1714         if ( bEncryptionDataProvided )
1715             pElement->m_pStream->GetCopyOfLastCommit( xTargetStream, aEncryptionData );
1716         else
1717             pElement->m_pStream->GetCopyOfLastCommit( xTargetStream );
1718     }
1719     else
1720         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
1721 }
1722 
1723 //-----------------------------------------------
RemoveStreamRelInfo(const::rtl::OUString & aOriginalName)1724 void OStorage_Impl::RemoveStreamRelInfo( const ::rtl::OUString& aOriginalName )
1725 {
1726     // this method should be used only in OStorage_Impl::Commit() method
1727     // the aOriginalName can be empty, in this case the storage relation info should be removed
1728 
1729     if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_xRelStorage.is() )
1730     {
1731         ::rtl::OUString aRelStreamName = aOriginalName;
1732         aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1733 
1734         if ( m_xRelStorage->hasByName( aRelStreamName ) )
1735             m_xRelStorage->removeElement( aRelStreamName );
1736     }
1737 }
1738 
1739 //-----------------------------------------------
CreateRelStorage()1740 void OStorage_Impl::CreateRelStorage()
1741 {
1742     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1743         return;
1744 
1745     if ( !m_xRelStorage.is() )
1746     {
1747         if ( !m_pRelStorElement )
1748         {
1749             m_pRelStorElement = new SotElement_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ), sal_True, sal_True );
1750             m_pRelStorElement->m_pStorage = CreateNewStorageImpl( embed::ElementModes::WRITE );
1751             if ( m_pRelStorElement->m_pStorage )
1752                 m_pRelStorElement->m_pStorage->m_pParent = NULL; // the relation storage is completely controlled by parent
1753         }
1754 
1755         if ( !m_pRelStorElement->m_pStorage )
1756             OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
1757 
1758         if ( !m_pRelStorElement->m_pStorage )
1759             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1760 
1761         OStorage* pResultStorage = new OStorage( m_pRelStorElement->m_pStorage, sal_False );
1762         m_xRelStorage = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
1763     }
1764 }
1765 
1766 //-----------------------------------------------
CommitStreamRelInfo(SotElement_Impl * pStreamElement)1767 void OStorage_Impl::CommitStreamRelInfo( SotElement_Impl* pStreamElement )
1768 {
1769     // this method should be used only in OStorage_Impl::Commit() method
1770 
1771     // the stream element must be provided
1772     if ( !pStreamElement )
1773         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1774 
1775     if ( m_nStorageType == embed::StorageFormats::OFOPXML && pStreamElement->m_pStream )
1776     {
1777         OSL_ENSURE( pStreamElement->m_aName.getLength(), "The name must not be empty!\n" );
1778 
1779         if ( !m_xRelStorage.is() )
1780         {
1781             // Create new rels storage, this is commit scenario so it must be possible
1782             CreateRelStorage();
1783         }
1784 
1785         pStreamElement->m_pStream->CommitStreamRelInfo( m_xRelStorage, pStreamElement->m_aOriginalName, pStreamElement->m_aName );
1786     }
1787 }
1788 
1789 //-----------------------------------------------
GetRelInfoStreamForName(const::rtl::OUString & aName)1790 uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName( const ::rtl::OUString& aName )
1791 {
1792     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1793     {
1794         ReadContents();
1795         if ( m_xRelStorage.is() )
1796         {
1797             ::rtl::OUString aRelStreamName = aName;
1798             aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1799             if ( m_xRelStorage->hasByName( aRelStreamName ) )
1800             {
1801                 uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
1802                 if ( xStream.is() )
1803                     return xStream->getInputStream();
1804             }
1805         }
1806     }
1807 
1808     return uno::Reference< io::XInputStream >();
1809 }
1810 
1811 //-----------------------------------------------
CommitRelInfo(const uno::Reference<container::XNameContainer> & xNewPackageFolder)1812 void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
1813 {
1814     // this method should be used only in OStorage_Impl::Commit() method
1815     ::rtl::OUString aRelsStorName( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) );
1816 
1817     if ( !xNewPackageFolder.is() )
1818         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1819 
1820     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1821     {
1822         if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
1823             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1824 
1825         if ( m_nRelInfoStatus == RELINFO_CHANGED
1826           || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1827           || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1828         {
1829             if ( m_nRelInfoStatus == RELINFO_CHANGED )
1830             {
1831                 if ( m_aRelInfo.getLength() )
1832                 {
1833                     CreateRelStorage();
1834 
1835                     uno::Reference< io::XStream > xRelsStream =
1836                         m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
1837                                                             embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1838 
1839                     uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
1840                     if ( !xOutStream.is() )
1841                         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1842 
1843                     ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aRelInfo, m_xFactory );
1844 
1845                     // set the mediatype
1846                     uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1847                     xPropSet->setPropertyValue(
1848                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1849                         uno::makeAny( ::rtl::OUString(
1850                             RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1851 
1852                     m_nRelInfoStatus = RELINFO_READ;
1853                 }
1854                 else if ( m_xRelStorage.is() )
1855                     RemoveStreamRelInfo( ::rtl::OUString() ); // remove own rel info
1856             }
1857             else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1858                     || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1859             {
1860                 CreateRelStorage();
1861 
1862                 uno::Reference< io::XStream > xRelsStream =
1863                     m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
1864                                                         embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1865 
1866                 uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
1867                 if ( !xOutputStream.is() )
1868                     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
1869 
1870                 uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
1871                 xSeek->seek( 0 );
1872                 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
1873 
1874                 // set the mediatype
1875                 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1876                 xPropSet->setPropertyValue(
1877                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1878                     uno::makeAny( ::rtl::OUString(
1879                         RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1880 
1881                 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1882                 if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1883                 {
1884                     m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1885                     m_nRelInfoStatus = RELINFO_NO_INIT;
1886                 }
1887                 else
1888                     m_nRelInfoStatus = RELINFO_READ;
1889             }
1890         }
1891 
1892         if ( m_xRelStorage.is() )
1893         {
1894             if ( m_xRelStorage->hasElements() )
1895             {
1896                 uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
1897                 if ( xTrans.is() )
1898                     xTrans->commit();
1899             }
1900 
1901             if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
1902                 xNewPackageFolder->removeByName( aRelsStorName );
1903 
1904             if ( !m_xRelStorage->hasElements() )
1905             {
1906                 // the empty relations storage should not be created
1907                 delete m_pRelStorElement;
1908                 m_pRelStorElement = NULL;
1909                 m_xRelStorage = uno::Reference< embed::XStorage >();
1910             }
1911             else if ( m_pRelStorElement && m_pRelStorElement->m_pStorage && xNewPackageFolder.is() )
1912                 m_pRelStorElement->m_pStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
1913         }
1914     }
1915 }
1916 
1917 //=====================================================
1918 // OStorage implementation
1919 //=====================================================
1920 
1921 //-----------------------------------------------
OStorage(uno::Reference<io::XInputStream> xInputStream,sal_Int32 nMode,uno::Sequence<beans::PropertyValue> xProperties,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)1922 OStorage::OStorage( uno::Reference< io::XInputStream > xInputStream,
1923                     sal_Int32 nMode,
1924                     uno::Sequence< beans::PropertyValue > xProperties,
1925                     uno::Reference< lang::XMultiServiceFactory > xFactory,
1926                     sal_Int32 nStorageType )
1927 : m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xFactory, nStorageType ) )
1928 {
1929     m_pImpl->m_pAntiImpl = this;
1930     m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1931 }
1932 
1933 //-----------------------------------------------
OStorage(uno::Reference<io::XStream> xStream,sal_Int32 nMode,uno::Sequence<beans::PropertyValue> xProperties,uno::Reference<lang::XMultiServiceFactory> xFactory,sal_Int32 nStorageType)1934 OStorage::OStorage( uno::Reference< io::XStream > xStream,
1935                     sal_Int32 nMode,
1936                     uno::Sequence< beans::PropertyValue > xProperties,
1937                     uno::Reference< lang::XMultiServiceFactory > xFactory,
1938                     sal_Int32 nStorageType )
1939 : m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xFactory, nStorageType ) )
1940 {
1941     m_pImpl->m_pAntiImpl = this;
1942     m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1943 }
1944 
1945 //-----------------------------------------------
OStorage(OStorage_Impl * pImpl,sal_Bool bReadOnlyWrap)1946 OStorage::OStorage( OStorage_Impl* pImpl, sal_Bool bReadOnlyWrap )
1947 : m_pImpl( pImpl )
1948 {
1949     // this call can be done only from OStorage_Impl implementation to create child storage
1950     OSL_ENSURE( m_pImpl && m_pImpl->m_rMutexRef.Is(), "The provided pointer & mutex MUST NOT be empty!\n" );
1951 
1952     m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, bReadOnlyWrap );
1953 
1954     OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
1955                     m_pData->m_bReadOnlyWrap,
1956                 "The wrapper can not allow writing in case implementation does not!\n" );
1957 
1958     if ( !bReadOnlyWrap )
1959         m_pImpl->m_pAntiImpl = this;
1960 }
1961 
1962 //-----------------------------------------------
~OStorage()1963 OStorage::~OStorage()
1964 {
1965     {
1966         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
1967         if ( m_pImpl )
1968         {
1969             m_refCount++; // to call dispose
1970             try {
1971                 dispose();
1972             }
1973             catch( uno::RuntimeException& aRuntimeException )
1974             {
1975                 m_pImpl->AddLog( aRuntimeException.Message );
1976                 m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Handled exception" ) ) );
1977             }
1978         }
1979     }
1980 
1981     if ( m_pData )
1982     {
1983         if ( m_pData->m_pSubElDispListener )
1984         {
1985             m_pData->m_pSubElDispListener->release();
1986             m_pData->m_pSubElDispListener = NULL;
1987         }
1988 
1989         if ( m_pData->m_pTypeCollection )
1990         {
1991             delete m_pData->m_pTypeCollection;
1992             m_pData->m_pTypeCollection = NULL;
1993         }
1994 
1995         delete m_pData;
1996     }
1997 }
1998 
1999 //-----------------------------------------------
InternalDispose(sal_Bool bNotifyImpl)2000 void SAL_CALL OStorage::InternalDispose( sal_Bool bNotifyImpl )
2001 {
2002     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::InternalDispose" );
2003 
2004     if ( !m_pImpl )
2005     {
2006         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2007         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2008     }
2009 
2010     // the source object is also a kind of locker for the current object
2011     // since the listeners could dispose the object while being notified
2012     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2013     m_pData->m_aListenersContainer.disposeAndClear( aSource );
2014 
2015     if ( m_pData->m_bReadOnlyWrap )
2016     {
2017         OSL_ENSURE( !m_pData->m_aOpenSubComponentsList.size() || m_pData->m_pSubElDispListener,
2018                     "If any subelements are open the listener must exist!\n" );
2019 
2020         if ( m_pData->m_pSubElDispListener )
2021         {
2022             m_pData->m_pSubElDispListener->OwnerIsDisposed();
2023 
2024             // iterate through m_pData->m_aOpenSubComponentsList
2025             // deregister m_pData->m_pSubElDispListener and dispose all of them
2026             if ( !m_pData->m_aOpenSubComponentsList.empty() )
2027             {
2028                 for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2029                     pCompIter != m_pData->m_aOpenSubComponentsList.end(); pCompIter++ )
2030                 {
2031                     uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2032                     if ( xTmp.is() )
2033                     {
2034                         xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
2035                                     static_cast< lang::XEventListener* >( m_pData->m_pSubElDispListener ) ) );
2036 
2037                         try {
2038                             xTmp->dispose();
2039                         } catch( uno::Exception& aException )
2040                         {
2041                             m_pImpl->AddLog( aException.Message );
2042                             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
2043                         }
2044                     }
2045                 }
2046 
2047                 m_pData->m_aOpenSubComponentsList.clear();
2048             }
2049         }
2050 
2051         if ( bNotifyImpl )
2052             m_pImpl->RemoveReadOnlyWrap( *this );
2053     }
2054     else
2055     {
2056         m_pImpl->m_pAntiImpl = NULL;
2057 
2058         if ( bNotifyImpl )
2059         {
2060             if ( m_pData->m_bIsRoot )
2061                 delete m_pImpl;
2062             else
2063             {
2064                 // the noncommited changes for the storage must be removed
2065                 m_pImpl->Revert();
2066             }
2067         }
2068     }
2069 
2070     m_pImpl = NULL;
2071 }
2072 
2073 //-----------------------------------------------
ChildIsDisposed(const uno::Reference<uno::XInterface> & xChild)2074 void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
2075 {
2076     // this method can only be called by child disposing listener
2077 
2078     // this method must not contain any locking
2079     // the locking is done in the listener
2080 
2081     if ( !m_pData->m_aOpenSubComponentsList.empty() )
2082     {
2083         for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2084             pCompIter != m_pData->m_aOpenSubComponentsList.end(); )
2085         {
2086             uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2087             if ( !xTmp.is() || xTmp == xChild )
2088             {
2089                 WeakComponentList::iterator pIterToRemove = pCompIter;
2090                 pCompIter++;
2091                 m_pData->m_aOpenSubComponentsList.erase( pIterToRemove );
2092             }
2093             else
2094                 pCompIter++;
2095         }
2096     }
2097 }
2098 
2099 //-----------------------------------------------
BroadcastModifiedIfNecessary()2100 void OStorage::BroadcastModifiedIfNecessary()
2101 {
2102     // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2103     if ( !m_pImpl )
2104     {
2105         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2106         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2107     }
2108 
2109     if ( !m_pImpl->m_bBroadcastModified )
2110         return;
2111 
2112     m_pImpl->m_bBroadcastModified = sal_False;
2113 
2114     OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2115 
2116     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2117 
2118     ::cppu::OInterfaceContainerHelper* pContainer =
2119             m_pData->m_aListenersContainer.getContainer(
2120                 ::getCppuType( ( const uno::Reference< util::XModifyListener >*) NULL ) );
2121     if ( pContainer )
2122     {
2123         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2124         while ( pIterator.hasMoreElements( ) )
2125         {
2126             ( ( util::XModifyListener* )pIterator.next( ) )->modified( aSource );
2127         }
2128     }
2129 }
2130 
2131 //-----------------------------------------------
BroadcastTransaction(sal_Int8 nMessage)2132 void OStorage::BroadcastTransaction( sal_Int8 nMessage )
2133 /*
2134     1 - preCommit
2135     2 - committed
2136     3 - preRevert
2137     4 - reverted
2138 */
2139 {
2140     // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2141     if ( !m_pImpl )
2142     {
2143         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2144         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2145     }
2146 
2147     OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2148 
2149     lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2150 
2151     ::cppu::OInterfaceContainerHelper* pContainer =
2152             m_pData->m_aListenersContainer.getContainer(
2153                 ::getCppuType( ( const uno::Reference< embed::XTransactionListener >*) NULL ) );
2154     if ( pContainer )
2155     {
2156         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2157         while ( pIterator.hasMoreElements( ) )
2158         {
2159             OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
2160 
2161             switch( nMessage )
2162             {
2163                 case STOR_MESS_PRECOMMIT:
2164                     ( ( embed::XTransactionListener* )pIterator.next( ) )->preCommit( aSource );
2165                     break;
2166                 case STOR_MESS_COMMITED:
2167                     ( ( embed::XTransactionListener* )pIterator.next( ) )->commited( aSource );
2168                     break;
2169                 case STOR_MESS_PREREVERT:
2170                     ( ( embed::XTransactionListener* )pIterator.next( ) )->preRevert( aSource );
2171                     break;
2172                 case STOR_MESS_REVERTED:
2173                     ( ( embed::XTransactionListener* )pIterator.next( ) )->reverted( aSource );
2174                     break;
2175             }
2176         }
2177     }
2178 }
2179 
2180 //-----------------------------------------------
OpenStreamElement_Impl(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode,sal_Bool bEncr)2181 SotElement_Impl* OStorage::OpenStreamElement_Impl( const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, sal_Bool bEncr )
2182 {
2183     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2184 
2185     OSL_ENSURE( !m_pData->m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
2186                 "An element can not be opened for writing in readonly storage!\n" );
2187 
2188     SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
2189     if ( !pElement )
2190     {
2191         // element does not exist, check if creation is allowed
2192         if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2193           || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2194           || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2195             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2196 
2197         // create a new StreamElement and insert it into the list
2198         pElement = m_pImpl->InsertStream( aStreamName, bEncr );
2199     }
2200     else if ( pElement->m_bIsStorage )
2201     {
2202         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2203     }
2204 
2205     OSL_ENSURE( pElement, "In case element can not be created an exception must be thrown!" );
2206 
2207     if ( !pElement->m_pStream )
2208         m_pImpl->OpenSubStream( pElement );
2209 
2210     if ( !pElement->m_pStream )
2211         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2212 
2213     return pElement;
2214 }
2215 
2216 //-----------------------------------------------
MakeLinkToSubComponent_Impl(const uno::Reference<lang::XComponent> & xComponent)2217 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
2218 {
2219     if ( !xComponent.is() )
2220         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2221 
2222     if ( !m_pData->m_pSubElDispListener )
2223     {
2224         m_pData->m_pSubElDispListener = new OChildDispListener_Impl( *this );
2225         m_pData->m_pSubElDispListener->acquire();
2226     }
2227 
2228     xComponent->addEventListener( uno::Reference< lang::XEventListener >(
2229         static_cast< ::cppu::OWeakObject* >( m_pData->m_pSubElDispListener ), uno::UNO_QUERY ) );
2230 
2231     m_pData->m_aOpenSubComponentsList.push_back( xComponent );
2232 }
2233 
2234 //____________________________________________________________________________________________________
2235 //  XInterface
2236 //____________________________________________________________________________________________________
2237 
2238 //-----------------------------------------------
queryInterface(const uno::Type & rType)2239 uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
2240 {
2241     uno::Any aReturn;
2242 
2243     // common interfaces
2244     aReturn <<= ::cppu::queryInterface
2245                 (   rType
2246                 ,   static_cast<lang::XTypeProvider*> ( this )
2247                 ,   static_cast<embed::XStorage*> ( this )
2248                 ,   static_cast<embed::XStorage2*> ( this )
2249                 ,   static_cast<embed::XTransactedObject*> ( this )
2250                 ,   static_cast<embed::XTransactionBroadcaster*> ( this )
2251                 ,   static_cast<util::XModifiable*> ( this )
2252                 ,   static_cast<container::XNameAccess*> ( this )
2253                 ,   static_cast<container::XElementAccess*> ( this )
2254                 ,   static_cast<lang::XComponent*> ( this )
2255                 ,   static_cast<beans::XPropertySet*> ( this )
2256                 ,   static_cast<embed::XOptimizedStorage*> ( this ) );
2257 
2258     if ( aReturn.hasValue() == sal_True )
2259         return aReturn ;
2260 
2261     aReturn <<= ::cppu::queryInterface
2262                 (   rType
2263                 ,   static_cast<embed::XHierarchicalStorageAccess*> ( this )
2264                 ,   static_cast<embed::XHierarchicalStorageAccess2*> ( this ) );
2265 
2266     if ( aReturn.hasValue() == sal_True )
2267         return aReturn ;
2268 
2269     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2270     {
2271         if ( m_pData->m_bIsRoot )
2272         {
2273             aReturn <<= ::cppu::queryInterface
2274                         (   rType
2275                         ,   static_cast<embed::XStorageRawAccess*> ( this )
2276                         ,   static_cast<embed::XEncryptionProtectedSource*> ( this )
2277                         ,   static_cast<embed::XEncryptionProtectedSource2*> ( this )
2278                         ,   static_cast<embed::XEncryptionProtectedStorage*> ( this ) );
2279         }
2280         else
2281         {
2282             aReturn <<= ::cppu::queryInterface
2283                         (   rType
2284                         ,   static_cast<embed::XStorageRawAccess*> ( this ) );
2285         }
2286     }
2287     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2288     {
2289         aReturn <<= ::cppu::queryInterface
2290                     (   rType
2291                     ,   static_cast<embed::XRelationshipAccess*> ( this ) );
2292     }
2293 
2294     if ( aReturn.hasValue() == sal_True )
2295         return aReturn ;
2296 
2297     return OWeakObject::queryInterface( rType );
2298 }
2299 
2300 //-----------------------------------------------
acquire()2301 void SAL_CALL OStorage::acquire() throw()
2302 {
2303     OWeakObject::acquire();
2304 }
2305 
2306 //-----------------------------------------------
release()2307 void SAL_CALL OStorage::release() throw()
2308 {
2309     OWeakObject::release();
2310 }
2311 
2312 //____________________________________________________________________________________________________
2313 //  XTypeProvider
2314 //____________________________________________________________________________________________________
2315 
2316 //-----------------------------------------------
getTypes()2317 uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
2318 {
2319     if ( m_pData->m_pTypeCollection == NULL )
2320     {
2321         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2322 
2323         if ( m_pData->m_pTypeCollection == NULL )
2324         {
2325             if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2326             {
2327                 if ( m_pData->m_bIsRoot )
2328                 {
2329                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2330                                     (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2331                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2332                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage2 >* )NULL )
2333                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2334                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2335                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2336                                     ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2337                                     ,   ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedStorage >* )NULL )
2338                                     ,   ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource2 >* )NULL )
2339                                     ,   ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
2340                                     ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2341                 }
2342                 else
2343                 {
2344                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2345                                     (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2346                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2347                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorage2 >* )NULL )
2348                                     ,   ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2349                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2350                                     ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2351                                     ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2352                                     ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2353                 }
2354             }
2355             else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2356             {
2357                 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2358                                 (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2359                                 ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2360                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2361                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2362                                 ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2363                                 ,   ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
2364                                 ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2365             }
2366             else
2367             {
2368                 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2369                                 (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2370                                 ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2371                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2372                                 ,   ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2373                                 ,   ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2374                                 ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2375             }
2376         }
2377     }
2378 
2379     return m_pData->m_pTypeCollection->getTypes() ;
2380 }
2381 
2382 namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; }
2383 
2384 //-----------------------------------------------
getImplementationId()2385 uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
2386 {
2387     ::cppu::OImplementationId &rID = lcl_ImplId::get();
2388     return rID.getImplementationId();
2389 }
2390 
2391 //____________________________________________________________________________________________________
2392 //  XStorage
2393 //____________________________________________________________________________________________________
2394 
2395 
2396 //-----------------------------------------------
copyToStorage(const uno::Reference<embed::XStorage> & xDest)2397 void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
2398 {
2399     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyToStorage" );
2400 
2401     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2402 
2403     if ( !m_pImpl )
2404     {
2405         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2406         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2407     }
2408 
2409     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
2410         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
2411 
2412     try {
2413         m_pImpl->CopyToStorage( xDest, sal_False );
2414     }
2415     catch( embed::InvalidStorageException& aInvalidStorageException )
2416     {
2417         m_pImpl->AddLog( aInvalidStorageException.Message );
2418         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2419         throw;
2420     }
2421     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2422     {
2423         m_pImpl->AddLog( aIllegalArgumentException.Message );
2424         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2425         throw;
2426     }
2427     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2428     {
2429         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2430         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2431         throw;
2432     }
2433     catch( io::IOException& aIOException )
2434     {
2435         m_pImpl->AddLog( aIOException.Message );
2436         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2437         throw;
2438     }
2439     catch( uno::RuntimeException& aRuntimeException )
2440     {
2441         m_pImpl->AddLog( aRuntimeException.Message );
2442         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2443         throw;
2444     }
2445     catch( uno::Exception& aException )
2446     {
2447         m_pImpl->AddLog( aException.Message );
2448         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2449 
2450         uno::Any aCaught( ::cppu::getCaughtException() );
2451         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy storage!" ) ),
2452                                                  uno::Reference< io::XInputStream >(),
2453                                                  aCaught );
2454     }
2455 }
2456 
2457 //-----------------------------------------------
openStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode)2458 uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
2459     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
2460 {
2461     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStreamElement" );
2462 
2463     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2464 
2465     if ( !m_pImpl )
2466     {
2467         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2468         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2469     }
2470 
2471     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2472         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2473 
2474     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2475       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2476         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
2477 
2478     if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2479         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
2480 
2481     uno::Reference< io::XStream > xResult;
2482     try
2483     {
2484         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_False );
2485         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
2486 
2487         xResult = pElement->m_pStream->GetStream( nOpenMode, sal_False );
2488         OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
2489 
2490         if ( m_pData->m_bReadOnlyWrap )
2491         {
2492             // before the storage disposes the stream it must deregister itself as listener
2493             uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
2494             if ( !xStreamComponent.is() )
2495                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2496 
2497             MakeLinkToSubComponent_Impl( xStreamComponent );
2498         }
2499     }
2500     catch( embed::InvalidStorageException& aInvalidStorageException )
2501     {
2502         m_pImpl->AddLog( aInvalidStorageException.Message );
2503         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2504         throw;
2505     }
2506     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2507     {
2508         m_pImpl->AddLog( aIllegalArgumentException.Message );
2509         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2510         throw;
2511     }
2512     catch( packages::WrongPasswordException& aWrongPasswordException )
2513     {
2514         m_pImpl->AddLog( aWrongPasswordException.Message );
2515         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2516         throw;
2517     }
2518     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2519     {
2520         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2521         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2522         throw;
2523     }
2524     catch( io::IOException& aIOException )
2525     {
2526         m_pImpl->AddLog( aIOException.Message );
2527         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2528         throw;
2529     }
2530     catch( uno::RuntimeException& aRuntimeException )
2531     {
2532         m_pImpl->AddLog( aRuntimeException.Message );
2533         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2534         throw;
2535     }
2536     catch( uno::Exception& aException )
2537     {
2538         m_pImpl->AddLog( aException.Message );
2539         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2540 
2541         uno::Any aCaught( ::cppu::getCaughtException() );
2542         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open stream element!" ) ),
2543                                                  uno::Reference< io::XInputStream >(),
2544                                                  aCaught );
2545     }
2546 
2547     aGuard.clear();
2548 
2549     BroadcastModifiedIfNecessary();
2550 
2551     return xResult;
2552 }
2553 
2554 //-----------------------------------------------
openEncryptedStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode,const::rtl::OUString & aPass)2555 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
2556     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const ::rtl::OUString& aPass )
2557 {
2558     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStreamElement" );
2559 
2560     return openEncryptedStream( aStreamName, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2561 }
2562 
2563 //-----------------------------------------------
openStorageElement(const::rtl::OUString & aStorName,sal_Int32 nStorageMode)2564 uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
2565             const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
2566 {
2567     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStorageElement" );
2568 
2569     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2570 
2571     if ( !m_pImpl )
2572     {
2573         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2574         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2575     }
2576 
2577     if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2578         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2579 
2580     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2581       && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2582         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2583 
2584     if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2585         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
2586 
2587     if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
2588       && !( nStorageMode & embed::ElementModes::WRITE ) )
2589         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
2590 
2591     // it's always possible to read written storage in this implementation
2592     nStorageMode |= embed::ElementModes::READ;
2593 
2594     uno::Reference< embed::XStorage > xResult;
2595     try
2596     {
2597         SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2598         if ( !pElement )
2599         {
2600             // element does not exist, check if creation is allowed
2601             if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2602             || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2603             || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2604                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2605 
2606             // create a new StorageElement and insert it into the list
2607             pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
2608         }
2609         else if ( !pElement->m_bIsStorage )
2610         {
2611             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2612         }
2613         else if ( pElement->m_pStorage )
2614         {
2615             // storage has already been opened; it may be opened another time, if it the mode allows to do so
2616             if ( pElement->m_pStorage->m_pAntiImpl )
2617             {
2618                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2619             }
2620             else if ( !pElement->m_pStorage->m_aReadOnlyWrapList.empty()
2621                     && ( nStorageMode & embed::ElementModes::WRITE ) )
2622             {
2623                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2624             }
2625             else
2626             {
2627                 // in case parent storage allows writing the readonly mode of the child storage is
2628                 // virtual, that means that it is just enough to change the flag to let it be writable
2629                 // and since there is no AntiImpl nobody should be notified about it
2630                 pElement->m_pStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
2631 
2632                 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
2633                 {
2634                     for ( SotElementList_Impl::iterator pElementIter = pElement->m_pStorage->m_aChildrenList.begin();
2635                         pElementIter != pElement->m_pStorage->m_aChildrenList.end(); )
2636                     {
2637                         SotElement_Impl* pElementToDel = (*pElementIter);
2638                         pElementIter++;
2639 
2640                         m_pImpl->RemoveElement( pElementToDel );
2641                     }
2642                 }
2643             }
2644         }
2645 
2646         if ( !pElement->m_pStorage )
2647             m_pImpl->OpenSubStorage( pElement, nStorageMode );
2648 
2649         if ( !pElement->m_pStorage )
2650             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
2651 
2652         sal_Bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
2653         OStorage* pResultStorage = new OStorage( pElement->m_pStorage, bReadOnlyWrap );
2654         xResult = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
2655 
2656         if ( bReadOnlyWrap )
2657         {
2658             // Before this call is done the object must be refcounted already
2659             pElement->m_pStorage->SetReadOnlyWrap( *pResultStorage );
2660 
2661             // before the storage disposes the stream it must deregister itself as listener
2662             uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY );
2663             if ( !xStorageComponent.is() )
2664                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2665 
2666             MakeLinkToSubComponent_Impl( xStorageComponent );
2667         }
2668     }
2669     catch( embed::InvalidStorageException& aInvalidStorageException )
2670     {
2671         m_pImpl->AddLog( aInvalidStorageException.Message );
2672         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2673         throw;
2674     }
2675     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2676     {
2677         m_pImpl->AddLog( aIllegalArgumentException.Message );
2678         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2679         throw;
2680     }
2681     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2682     {
2683         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2684         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2685         throw;
2686     }
2687     catch( io::IOException& aIOException )
2688     {
2689         m_pImpl->AddLog( aIOException.Message );
2690         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2691         throw;
2692     }
2693     catch( uno::RuntimeException& aRuntimeException )
2694     {
2695         m_pImpl->AddLog( aRuntimeException.Message );
2696         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2697         throw;
2698     }
2699     catch( uno::Exception& aException )
2700     {
2701         m_pImpl->AddLog( aException.Message );
2702         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2703 
2704         uno::Any aCaught( ::cppu::getCaughtException() );
2705         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open storage!" ) ),
2706                                                  uno::Reference< io::XInputStream >(),
2707                                                  aCaught );
2708     }
2709 
2710     return xResult;
2711 }
2712 
2713 //-----------------------------------------------
cloneStreamElement(const::rtl::OUString & aStreamName)2714 uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
2715 {
2716     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneStreamElement" );
2717 
2718     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2719 
2720     if ( !m_pImpl )
2721     {
2722         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2723         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2724     }
2725 
2726     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2727         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2728 
2729     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2730       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2731         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2732 
2733     try
2734     {
2735         uno::Reference< io::XStream > xResult;
2736         m_pImpl->CloneStreamElement( aStreamName, sal_False, ::comphelper::SequenceAsHashMap(), xResult );
2737         if ( !xResult.is() )
2738             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2739         return xResult;
2740     }
2741     catch( embed::InvalidStorageException& aInvalidStorageException )
2742     {
2743         m_pImpl->AddLog( aInvalidStorageException.Message );
2744         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2745         throw;
2746     }
2747     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2748     {
2749         m_pImpl->AddLog( aIllegalArgumentException.Message );
2750         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2751         throw;
2752     }
2753     catch( packages::WrongPasswordException& aWrongPasswordException )
2754     {
2755         m_pImpl->AddLog( aWrongPasswordException.Message );
2756         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2757         throw;
2758     }
2759     catch( io::IOException& aIOException )
2760     {
2761         m_pImpl->AddLog( aIOException.Message );
2762         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2763         throw;
2764     }
2765     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2766     {
2767         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2768         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2769         throw;
2770     }
2771     catch( uno::RuntimeException& aRuntimeException )
2772     {
2773         m_pImpl->AddLog( aRuntimeException.Message );
2774         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2775         throw;
2776     }
2777     catch( uno::Exception& aException )
2778     {
2779         m_pImpl->AddLog( aException.Message );
2780         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2781 
2782         uno::Any aCaught( ::cppu::getCaughtException() );
2783         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't clone stream!" ) ),
2784                                                  uno::Reference< io::XInputStream >(),
2785                                                  aCaught );
2786     }
2787 }
2788 
2789 //-----------------------------------------------
cloneEncryptedStreamElement(const::rtl::OUString & aStreamName,const::rtl::OUString & aPass)2790 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
2791     const ::rtl::OUString& aStreamName,
2792     const ::rtl::OUString& aPass )
2793 {
2794     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStreamElement" );
2795 
2796     return cloneEncryptedStream( aStreamName, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2797 }
2798 
2799 //-----------------------------------------------
copyLastCommitTo(const uno::Reference<embed::XStorage> & xTargetStorage)2800 void SAL_CALL OStorage::copyLastCommitTo(
2801             const uno::Reference< embed::XStorage >& xTargetStorage )
2802 {
2803     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyLastCommitTo" );
2804 
2805     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2806 
2807     if ( !m_pImpl )
2808     {
2809         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2810         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2811     }
2812 
2813     try
2814     {
2815         m_pImpl->CopyLastCommitTo( xTargetStorage );
2816     }
2817     catch( embed::InvalidStorageException& aInvalidStorageException )
2818     {
2819         m_pImpl->AddLog( aInvalidStorageException.Message );
2820         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2821         throw;
2822     }
2823     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2824     {
2825         m_pImpl->AddLog( aIllegalArgumentException.Message );
2826         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2827         throw;
2828     }
2829     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2830     {
2831         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2832         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2833         throw;
2834     }
2835     catch( io::IOException& aIOException )
2836     {
2837         m_pImpl->AddLog( aIOException.Message );
2838         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2839         throw;
2840     }
2841     catch( uno::RuntimeException& aRuntimeException )
2842     {
2843         m_pImpl->AddLog( aRuntimeException.Message );
2844         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2845         throw;
2846     }
2847     catch( uno::Exception& aException )
2848     {
2849         m_pImpl->AddLog( aException.Message );
2850         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2851 
2852         uno::Any aCaught( ::cppu::getCaughtException() );
2853         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy last commit version!" ) ),
2854                                                  uno::Reference< io::XInputStream >(),
2855                                                  aCaught );
2856     }
2857 
2858 }
2859 
2860 //-----------------------------------------------
copyStorageElementLastCommitTo(const::rtl::OUString & aStorName,const uno::Reference<embed::XStorage> & xTargetStorage)2861 void SAL_CALL OStorage::copyStorageElementLastCommitTo(
2862             const ::rtl::OUString& aStorName,
2863             const uno::Reference< embed::XStorage >& xTargetStorage )
2864 {
2865     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyStorageElementLastCommitTo" );
2866 
2867     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2868 
2869     if ( !m_pImpl )
2870     {
2871         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2872         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2873     }
2874 
2875     if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2876         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2877 
2878     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2879       && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2880         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2881 
2882     // it's always possible to read written storage in this implementation
2883     sal_Int32 nStorageMode = embed::ElementModes::READ;
2884 
2885     try
2886     {
2887         SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2888         if ( !pElement )
2889         {
2890             // element does not exist, throw exception
2891             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
2892         }
2893         else if ( !pElement->m_bIsStorage )
2894         {
2895             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2896         }
2897 
2898         if ( !pElement->m_pStorage )
2899             m_pImpl->OpenSubStorage( pElement, nStorageMode );
2900 
2901         uno::Reference< embed::XStorage > xResult;
2902         if ( pElement->m_pStorage )
2903         {
2904             // the existence of m_pAntiImpl of the child is not interesting,
2905             // the copy will be created internally
2906 
2907             pElement->m_pStorage->CopyLastCommitTo( xTargetStorage );
2908         }
2909         else
2910             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
2911     }
2912     catch( embed::InvalidStorageException& aInvalidStorageException )
2913     {
2914         m_pImpl->AddLog( aInvalidStorageException.Message );
2915         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2916         throw;
2917     }
2918     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2919     {
2920         m_pImpl->AddLog( aIllegalArgumentException.Message );
2921         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2922         throw;
2923     }
2924     catch( io::IOException& aIOException )
2925     {
2926         m_pImpl->AddLog( aIOException.Message );
2927         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2928         throw;
2929     }
2930     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
2931     {
2932         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
2933         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2934         throw;
2935     }
2936     catch( uno::RuntimeException& aRuntimeException )
2937     {
2938         m_pImpl->AddLog( aRuntimeException.Message );
2939         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2940         throw;
2941     }
2942     catch( uno::Exception& aException )
2943     {
2944         m_pImpl->AddLog( aException.Message );
2945         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2946 
2947         uno::Any aCaught( ::cppu::getCaughtException() );
2948         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy last commit element version!" ) ),
2949                                                  uno::Reference< io::XInputStream >(),
2950                                                  aCaught );
2951     }
2952 }
2953 
2954 //-----------------------------------------------
isStreamElement(const::rtl::OUString & aElementName)2955 sal_Bool SAL_CALL OStorage::isStreamElement( const ::rtl::OUString& aElementName )
2956 {
2957     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2958 
2959     if ( !m_pImpl )
2960     {
2961         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
2962         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
2963     }
2964 
2965     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
2966         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2967 
2968     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
2969       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2970         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
2971 
2972     SotElement_Impl* pElement = NULL;
2973 
2974     try
2975     {
2976         pElement = m_pImpl->FindElement( aElementName );
2977     }
2978     catch( embed::InvalidStorageException& aInvalidStorageException )
2979     {
2980         m_pImpl->AddLog( aInvalidStorageException.Message );
2981         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2982         throw;
2983     }
2984     catch( lang::IllegalArgumentException& aIllegalArgumentException )
2985     {
2986         m_pImpl->AddLog( aIllegalArgumentException.Message );
2987         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2988         throw;
2989     }
2990     catch( container::NoSuchElementException& aNoSuchElementException )
2991     {
2992         m_pImpl->AddLog( aNoSuchElementException.Message );
2993         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
2994         throw;
2995     }
2996     catch( uno::RuntimeException& aRuntimeException )
2997     {
2998         m_pImpl->AddLog( aRuntimeException.Message );
2999         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3000         throw;
3001     }
3002     catch( uno::Exception& aException )
3003     {
3004         m_pImpl->AddLog( aException.Message );
3005         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3006 
3007         uno::Any aCaught( ::cppu::getCaughtException() );
3008         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't detect whether it is a stream!" ) ),
3009                                                  uno::Reference< io::XInputStream >(),
3010                                                  aCaught );
3011     }
3012 
3013     if ( !pElement )
3014         throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3015 
3016     return !pElement->m_bIsStorage;
3017 }
3018 
3019 //-----------------------------------------------
isStorageElement(const::rtl::OUString & aElementName)3020 sal_Bool SAL_CALL OStorage::isStorageElement( const ::rtl::OUString& aElementName )
3021 {
3022     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3023 
3024     if ( !m_pImpl )
3025     {
3026         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3027         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3028     }
3029 
3030     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3031         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3032 
3033     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3034       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3035         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 );
3036 
3037     SotElement_Impl* pElement = NULL;
3038 
3039     try
3040     {
3041         pElement = m_pImpl->FindElement( aElementName );
3042     }
3043     catch( embed::InvalidStorageException& aInvalidStorageException )
3044     {
3045         m_pImpl->AddLog( aInvalidStorageException.Message );
3046         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3047         throw;
3048     }
3049     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3050     {
3051         m_pImpl->AddLog( aIllegalArgumentException.Message );
3052         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3053         throw;
3054     }
3055     catch( container::NoSuchElementException& aNoSuchElementException )
3056     {
3057         m_pImpl->AddLog( aNoSuchElementException.Message );
3058         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3059         throw;
3060     }
3061     catch( uno::RuntimeException& aRuntimeException )
3062     {
3063         m_pImpl->AddLog( aRuntimeException.Message );
3064         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3065         throw;
3066     }
3067     catch( uno::Exception& aException )
3068     {
3069         m_pImpl->AddLog( aException.Message );
3070         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3071 
3072         uno::Any aCaught( ::cppu::getCaughtException() );
3073         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "can't detect whether it is a storage" ) ),
3074                                                  uno::Reference< io::XInputStream >(),
3075                                                  aCaught );
3076     }
3077 
3078     if ( !pElement )
3079         throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3080 
3081     return pElement->m_bIsStorage;
3082 }
3083 
3084 //-----------------------------------------------
removeElement(const::rtl::OUString & aElementName)3085 void SAL_CALL OStorage::removeElement( const ::rtl::OUString& aElementName )
3086 {
3087     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeElement" );
3088 
3089     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3090 
3091     if ( !m_pImpl )
3092     {
3093         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3094         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3095     }
3096 
3097     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3098         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3099 
3100     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3101       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3102         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
3103 
3104     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3105         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3106 
3107     try
3108     {
3109         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3110 
3111         if ( !pElement )
3112             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3113 
3114         m_pImpl->RemoveElement( pElement );
3115 
3116         m_pImpl->m_bIsModified = sal_True;
3117         m_pImpl->m_bBroadcastModified = sal_True;
3118     }
3119     catch( embed::InvalidStorageException& aInvalidStorageException )
3120     {
3121         m_pImpl->AddLog( aInvalidStorageException.Message );
3122         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3123         throw;
3124     }
3125     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3126     {
3127         m_pImpl->AddLog( aIllegalArgumentException.Message );
3128         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3129         throw;
3130     }
3131     catch( container::NoSuchElementException& aNoSuchElementException )
3132     {
3133         m_pImpl->AddLog( aNoSuchElementException.Message );
3134         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3135         throw;
3136     }
3137     catch( io::IOException& aIOException )
3138     {
3139         m_pImpl->AddLog( aIOException.Message );
3140         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3141         throw;
3142     }
3143     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3144     {
3145         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3146         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3147         throw;
3148     }
3149     catch( uno::RuntimeException& aRuntimeException )
3150     {
3151         m_pImpl->AddLog( aRuntimeException.Message );
3152         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3153         throw;
3154     }
3155     catch( uno::Exception& aException )
3156     {
3157         m_pImpl->AddLog( aException.Message );
3158         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3159 
3160         uno::Any aCaught( ::cppu::getCaughtException() );
3161         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't remove element!" ) ),
3162                                                  uno::Reference< io::XInputStream >(),
3163                                                  aCaught );
3164     }
3165 
3166     aGuard.clear();
3167 
3168     BroadcastModifiedIfNecessary();
3169 }
3170 
3171 //-----------------------------------------------
renameElement(const::rtl::OUString & aElementName,const::rtl::OUString & aNewName)3172 void SAL_CALL OStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
3173 {
3174     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::renameElement" );
3175 
3176     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3177 
3178     if ( !m_pImpl )
3179     {
3180         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3181         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3182     }
3183 
3184     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3185       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3186         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3187 
3188     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3189       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3190         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3191         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // TODO: unacceptable element name
3192 
3193     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3194         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3195 
3196     try
3197     {
3198         SotElement_Impl* pRefElement = m_pImpl->FindElement( aNewName );
3199         if ( pRefElement )
3200             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3201 
3202         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3203         if ( !pElement )
3204             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3205 
3206         pElement->m_aName = aNewName;
3207 
3208         m_pImpl->m_bIsModified = sal_True;
3209         m_pImpl->m_bBroadcastModified = sal_True;
3210     }
3211     catch( embed::InvalidStorageException& aInvalidStorageException )
3212     {
3213         m_pImpl->AddLog( aInvalidStorageException.Message );
3214         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3215         throw;
3216     }
3217     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3218     {
3219         m_pImpl->AddLog( aIllegalArgumentException.Message );
3220         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3221         throw;
3222     }
3223     catch( container::NoSuchElementException& aNoSuchElementException )
3224     {
3225         m_pImpl->AddLog( aNoSuchElementException.Message );
3226         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3227         throw;
3228     }
3229     catch( container::ElementExistException& aElementExistException )
3230     {
3231         m_pImpl->AddLog( aElementExistException.Message );
3232         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3233         throw;
3234     }
3235     catch( io::IOException& aIOException )
3236     {
3237         m_pImpl->AddLog( aIOException.Message );
3238         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3239         throw;
3240     }
3241     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3242     {
3243         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3244         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3245         throw;
3246     }
3247     catch( uno::RuntimeException& aRuntimeException )
3248     {
3249         m_pImpl->AddLog( aRuntimeException.Message );
3250         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3251         throw;
3252     }
3253     catch( uno::Exception& aException )
3254     {
3255         m_pImpl->AddLog( aException.Message );
3256         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3257 
3258         uno::Any aCaught( ::cppu::getCaughtException() );
3259         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't rename element!" ) ),
3260                                                  uno::Reference< io::XInputStream >(),
3261                                                  aCaught );
3262     }
3263 
3264     aGuard.clear();
3265 
3266     BroadcastModifiedIfNecessary();
3267 }
3268 
3269 //-----------------------------------------------
copyElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)3270 void SAL_CALL OStorage::copyElementTo(  const ::rtl::OUString& aElementName,
3271                                         const uno::Reference< embed::XStorage >& xDest,
3272                                         const ::rtl::OUString& aNewName )
3273 {
3274     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementTo" );
3275 
3276     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3277 
3278     if ( !m_pImpl )
3279     {
3280         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3281         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3282     }
3283 
3284     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3285       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3286         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3287 
3288     if ( !xDest.is() )
3289         // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3290         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3291 
3292     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3293       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3294         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3295         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3296 
3297     try
3298     {
3299         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3300         if ( !pElement )
3301             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3302 
3303         uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3304         if ( !xNameAccess.is() )
3305             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3306 
3307         if ( xNameAccess->hasByName( aNewName ) )
3308             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3309 
3310         m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3311     }
3312     catch( embed::InvalidStorageException& aInvalidStorageException )
3313     {
3314         m_pImpl->AddLog( aInvalidStorageException.Message );
3315         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3316         throw;
3317     }
3318     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3319     {
3320         m_pImpl->AddLog( aIllegalArgumentException.Message );
3321         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3322         throw;
3323     }
3324     catch( container::NoSuchElementException& aNoSuchElementException )
3325     {
3326         m_pImpl->AddLog( aNoSuchElementException.Message );
3327         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3328         throw;
3329     }
3330     catch( container::ElementExistException& aElementExistException )
3331     {
3332         m_pImpl->AddLog( aElementExistException.Message );
3333         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3334         throw;
3335     }
3336     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3337     {
3338         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3339         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3340         throw;
3341     }
3342     catch( io::IOException& aIOException )
3343     {
3344         m_pImpl->AddLog( aIOException.Message );
3345         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3346         throw;
3347     }
3348     catch( uno::RuntimeException& aRuntimeException )
3349     {
3350         m_pImpl->AddLog( aRuntimeException.Message );
3351         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3352         throw;
3353     }
3354     catch( uno::Exception& aException )
3355     {
3356         m_pImpl->AddLog( aException.Message );
3357         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3358 
3359         uno::Any aCaught( ::cppu::getCaughtException() );
3360         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy element!" ) ),
3361                                                  uno::Reference< io::XInputStream >(),
3362                                                  aCaught );
3363     }
3364 }
3365 
3366 
3367 //-----------------------------------------------
moveElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)3368 void SAL_CALL OStorage::moveElementTo(  const ::rtl::OUString& aElementName,
3369                                         const uno::Reference< embed::XStorage >& xDest,
3370                                         const ::rtl::OUString& aNewName )
3371 {
3372     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::moveElementTo" );
3373 
3374     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3375 
3376     if ( !m_pImpl )
3377     {
3378         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3379         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3380     }
3381 
3382     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3383       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3384         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3385 
3386     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3387         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3388 
3389     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
3390       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3391         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3392         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3393 
3394     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3395         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3396 
3397     try
3398     {
3399         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3400         if ( !pElement )
3401             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); //???
3402 
3403         uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3404         if ( !xNameAccess.is() )
3405             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3406 
3407         if ( xNameAccess->hasByName( aNewName ) )
3408             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3409 
3410         m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3411 
3412         m_pImpl->RemoveElement( pElement );
3413 
3414         m_pImpl->m_bIsModified = sal_True;
3415         m_pImpl->m_bBroadcastModified = sal_True;
3416     }
3417     catch( embed::InvalidStorageException& aInvalidStorageException )
3418     {
3419         m_pImpl->AddLog( aInvalidStorageException.Message );
3420         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3421         throw;
3422     }
3423     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3424     {
3425         m_pImpl->AddLog( aIllegalArgumentException.Message );
3426         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3427         throw;
3428     }
3429     catch( container::NoSuchElementException& aNoSuchElementException )
3430     {
3431         m_pImpl->AddLog( aNoSuchElementException.Message );
3432         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3433         throw;
3434     }
3435     catch( container::ElementExistException& aElementExistException )
3436     {
3437         m_pImpl->AddLog( aElementExistException.Message );
3438         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3439         throw;
3440     }
3441     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3442     {
3443         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3444         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3445         throw;
3446     }
3447     catch( io::IOException& aIOException )
3448     {
3449         m_pImpl->AddLog( aIOException.Message );
3450         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3451         throw;
3452     }
3453     catch( uno::RuntimeException& aRuntimeException )
3454     {
3455         m_pImpl->AddLog( aRuntimeException.Message );
3456         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3457         throw;
3458     }
3459     catch( uno::Exception& aException )
3460     {
3461         m_pImpl->AddLog( aException.Message );
3462         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3463 
3464         uno::Any aCaught( ::cppu::getCaughtException() );
3465         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't move element!" ) ),
3466                                                  uno::Reference< io::XInputStream >(),
3467                                                  aCaught );
3468     }
3469 
3470     aGuard.clear();
3471 
3472     BroadcastModifiedIfNecessary();
3473 }
3474 
3475 //____________________________________________________________________________________________________
3476 //  XStorage2
3477 //____________________________________________________________________________________________________
3478 
3479 //-----------------------------------------------
openEncryptedStream(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode,const uno::Sequence<beans::NamedValue> & aEncryptionData)3480 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStream(
3481     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
3482 {
3483     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStream" );
3484 
3485     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3486 
3487     if ( !m_pImpl )
3488     {
3489         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3490         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3491     }
3492 
3493     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3494         packages::NoEncryptionException();
3495 
3496     if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
3497         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3498 
3499     if ( !aEncryptionData.getLength() )
3500         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 3 );
3501 
3502     uno::Reference< io::XStream > xResult;
3503     try
3504     {
3505         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_True );
3506         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
3507 
3508         xResult = pElement->m_pStream->GetStream( nOpenMode, aEncryptionData, sal_False );
3509         OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
3510 
3511         if ( m_pData->m_bReadOnlyWrap )
3512         {
3513             // before the storage disposes the stream it must deregister itself as listener
3514             uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
3515             if ( !xStreamComponent.is() )
3516                 throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3517 
3518             MakeLinkToSubComponent_Impl( xStreamComponent );
3519         }
3520     }
3521     catch( embed::InvalidStorageException& aInvalidStorageException )
3522     {
3523         m_pImpl->AddLog( aInvalidStorageException.Message );
3524         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3525         throw;
3526     }
3527     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3528     {
3529         m_pImpl->AddLog( aIllegalArgumentException.Message );
3530         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3531         throw;
3532     }
3533     catch( packages::NoEncryptionException& aNoEncryptionException )
3534     {
3535         m_pImpl->AddLog( aNoEncryptionException.Message );
3536         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3537         throw;
3538     }
3539     catch( packages::WrongPasswordException& aWrongPasswordException )
3540     {
3541         m_pImpl->AddLog( aWrongPasswordException.Message );
3542         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3543         throw;
3544     }
3545     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3546     {
3547         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3548         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3549         throw;
3550     }
3551     catch( io::IOException& aIOException )
3552     {
3553         m_pImpl->AddLog( aIOException.Message );
3554         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3555         throw;
3556     }
3557     catch( uno::RuntimeException& aRuntimeException )
3558     {
3559         m_pImpl->AddLog( aRuntimeException.Message );
3560         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3561         throw;
3562     }
3563     catch( uno::Exception& aException )
3564     {
3565         m_pImpl->AddLog( aException.Message );
3566         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3567 
3568         uno::Any aCaught( ::cppu::getCaughtException() );
3569         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't open encrypted stream stream!" ) ),
3570                                                  uno::Reference< io::XInputStream >(),
3571                                                  aCaught );
3572     }
3573 
3574     aGuard.clear();
3575 
3576     BroadcastModifiedIfNecessary();
3577 
3578     return xResult;
3579 }
3580 
3581 //-----------------------------------------------
cloneEncryptedStream(const::rtl::OUString & aStreamName,const uno::Sequence<beans::NamedValue> & aEncryptionData)3582 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStream(
3583     const ::rtl::OUString& aStreamName,
3584     const uno::Sequence< beans::NamedValue >& aEncryptionData )
3585 {
3586     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStream" );
3587 
3588     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3589 
3590     if ( !m_pImpl )
3591     {
3592         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3593         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3594     }
3595 
3596     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3597         packages::NoEncryptionException();
3598 
3599     if ( !aEncryptionData.getLength() )
3600         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3601 
3602     try
3603     {
3604         uno::Reference< io::XStream > xResult;
3605         m_pImpl->CloneStreamElement( aStreamName, sal_True, aEncryptionData, xResult );
3606         if ( !xResult.is() )
3607             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3608         return xResult;
3609     }
3610     catch( embed::InvalidStorageException& aInvalidStorageException )
3611     {
3612         m_pImpl->AddLog( aInvalidStorageException.Message );
3613         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3614         throw;
3615     }
3616     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3617     {
3618         m_pImpl->AddLog( aIllegalArgumentException.Message );
3619         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3620         throw;
3621     }
3622     catch( packages::NoEncryptionException& aNoEncryptionException )
3623     {
3624         m_pImpl->AddLog( aNoEncryptionException.Message );
3625         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3626         throw;
3627     }
3628     catch( packages::WrongPasswordException& aWrongPasswordException )
3629     {
3630         m_pImpl->AddLog( aWrongPasswordException.Message );
3631         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3632         throw;
3633     }
3634     catch( io::IOException& aIOException )
3635     {
3636         m_pImpl->AddLog( aIOException.Message );
3637         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3638         throw;
3639     }
3640     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3641     {
3642         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3643         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3644         throw;
3645     }
3646     catch( uno::RuntimeException& aRuntimeException )
3647     {
3648         m_pImpl->AddLog( aRuntimeException.Message );
3649         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3650         throw;
3651     }
3652     catch( uno::Exception& aException )
3653     {
3654         m_pImpl->AddLog( aException.Message );
3655         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3656 
3657         uno::Any aCaught( ::cppu::getCaughtException() );
3658         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't clone encrypted stream!" ) ),
3659                                                  uno::Reference< io::XInputStream >(),
3660                                                  aCaught );
3661     }
3662 }
3663 
3664 
3665 //____________________________________________________________________________________________________
3666 //  XStorageRawAccess
3667 //____________________________________________________________________________________________________
3668 
3669 //-----------------------------------------------
getPlainRawStreamElement(const::rtl::OUString & sStreamName)3670 uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
3671             const ::rtl::OUString& sStreamName )
3672 {
3673     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPlainRawStreamElement" );
3674 
3675     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3676 
3677     if ( !m_pImpl )
3678     {
3679         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3680         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3681     }
3682 
3683     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
3684         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
3685 
3686     if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3687         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3688 
3689     uno::Reference < io::XInputStream > xTempIn;
3690     try
3691     {
3692         SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3693         if ( !pElement )
3694             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3695 
3696         if ( !pElement->m_pStream )
3697         {
3698             m_pImpl->OpenSubStream( pElement );
3699             if ( !pElement->m_pStream )
3700                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3701         }
3702 
3703         uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetPlainRawInStream();
3704         if ( !xRawInStream.is() )
3705             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3706 
3707         uno::Reference < io::XOutputStream > xTempOut(
3708                             m_pImpl->GetServiceFactory()->createInstance (
3709                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
3710                             uno::UNO_QUERY );
3711         xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
3712         uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3713 
3714         if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3715             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3716 
3717         // Copy temporary file to a new one
3718         ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3719         xTempOut->closeOutput();
3720         xSeek->seek( 0 );
3721     }
3722     catch( embed::InvalidStorageException& aInvalidStorageException )
3723     {
3724         m_pImpl->AddLog( aInvalidStorageException.Message );
3725         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3726         throw;
3727     }
3728     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3729     {
3730         m_pImpl->AddLog( aIllegalArgumentException.Message );
3731         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3732         throw;
3733     }
3734     catch( container::NoSuchElementException& aNoSuchElementException )
3735     {
3736         m_pImpl->AddLog( aNoSuchElementException.Message );
3737         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3738         throw;
3739     }
3740     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3741     {
3742         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3743         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3744         throw;
3745     }
3746     catch( io::IOException& aIOException )
3747     {
3748         m_pImpl->AddLog( aIOException.Message );
3749         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3750         throw;
3751     }
3752     catch( uno::RuntimeException& aRuntimeException )
3753     {
3754         m_pImpl->AddLog( aRuntimeException.Message );
3755         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3756         throw;
3757     }
3758     catch( uno::Exception& aException )
3759     {
3760         m_pImpl->AddLog( aException.Message );
3761         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3762 
3763         uno::Any aCaught( ::cppu::getCaughtException() );
3764         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get plain raw stream!" ) ),
3765                                                  uno::Reference< io::XInputStream >(),
3766                                                  aCaught );
3767     }
3768 
3769     return xTempIn;
3770 }
3771 
3772 //-----------------------------------------------
getRawEncrStreamElement(const::rtl::OUString & sStreamName)3773 uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
3774             const ::rtl::OUString& sStreamName )
3775 {
3776     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getRawEncrStreamElement" );
3777 
3778     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3779 
3780     if ( !m_pImpl )
3781     {
3782         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3783         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3784     }
3785 
3786     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3787         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3788 
3789     if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3790         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3791 
3792     uno::Reference < io::XInputStream > xTempIn;
3793     try
3794     {
3795         SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3796         if ( !pElement )
3797             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3798 
3799         if ( !pElement->m_pStream )
3800         {
3801             m_pImpl->OpenSubStream( pElement );
3802             if ( !pElement->m_pStream )
3803                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3804         }
3805 
3806         if ( !pElement->m_pStream->IsEncrypted() )
3807             throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3808 
3809         uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
3810         if ( !xRawInStream.is() )
3811             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3812 
3813         uno::Reference < io::XOutputStream > xTempOut(
3814                             m_pImpl->GetServiceFactory()->createInstance (
3815                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
3816                             uno::UNO_QUERY );
3817         xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
3818         uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3819 
3820         if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3821             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3822 
3823         // Copy temporary file to a new one
3824         ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3825         xTempOut->closeOutput();
3826         xSeek->seek( 0 );
3827 
3828     }
3829     catch( embed::InvalidStorageException& aInvalidStorageException )
3830     {
3831         m_pImpl->AddLog( aInvalidStorageException.Message );
3832         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3833         throw;
3834     }
3835     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3836     {
3837         m_pImpl->AddLog( aIllegalArgumentException.Message );
3838         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3839         throw;
3840     }
3841     catch( packages::NoEncryptionException& aNoEncryptionException )
3842     {
3843         m_pImpl->AddLog( aNoEncryptionException.Message );
3844         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3845         throw;
3846     }
3847     catch( container::NoSuchElementException& aNoSuchElementException )
3848     {
3849         m_pImpl->AddLog( aNoSuchElementException.Message );
3850         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3851         throw;
3852     }
3853     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3854     {
3855         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3856         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3857         throw;
3858     }
3859     catch( io::IOException& aIOException )
3860     {
3861         m_pImpl->AddLog( aIOException.Message );
3862         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3863         throw;
3864     }
3865     catch( uno::RuntimeException& aRuntimeException )
3866     {
3867         m_pImpl->AddLog( aRuntimeException.Message );
3868         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3869         throw;
3870     }
3871     catch( uno::Exception& aException )
3872     {
3873         m_pImpl->AddLog( aException.Message );
3874         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3875 
3876         uno::Any aCaught( ::cppu::getCaughtException() );
3877         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get raw stream!" ) ),
3878                                                  uno::Reference< io::XInputStream >(),
3879                                                  aCaught );
3880     }
3881 
3882     return xTempIn;
3883 }
3884 
3885 //-----------------------------------------------
insertRawEncrStreamElement(const::rtl::OUString & aStreamName,const uno::Reference<io::XInputStream> & xInStream)3886 void SAL_CALL OStorage::insertRawEncrStreamElement( const ::rtl::OUString& aStreamName,
3887                                 const uno::Reference< io::XInputStream >& xInStream )
3888 {
3889     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertRawEncrStreamElement" );
3890 
3891     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3892 
3893     if ( !m_pImpl )
3894     {
3895         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3896         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3897     }
3898 
3899     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3900         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3901 
3902     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
3903         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3904 
3905     if ( !xInStream.is() )
3906         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
3907 
3908     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3909         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
3910 
3911     try
3912     {
3913         SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
3914         if ( pElement )
3915             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3916 
3917         m_pImpl->InsertRawStream( aStreamName, xInStream );
3918     }
3919     catch( embed::InvalidStorageException& aInvalidStorageException )
3920     {
3921         m_pImpl->AddLog( aInvalidStorageException.Message );
3922         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3923         throw;
3924     }
3925     catch( lang::IllegalArgumentException& aIllegalArgumentException )
3926     {
3927         m_pImpl->AddLog( aIllegalArgumentException.Message );
3928         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3929         throw;
3930     }
3931     catch( packages::NoRawFormatException& aNoRawFormatException )
3932     {
3933         m_pImpl->AddLog( aNoRawFormatException.Message );
3934         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3935         throw;
3936     }
3937     catch( container::ElementExistException& aElementExistException )
3938     {
3939         m_pImpl->AddLog( aElementExistException.Message );
3940         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3941         throw;
3942     }
3943     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
3944     {
3945         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
3946         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3947         throw;
3948     }
3949     catch( io::IOException& aIOException )
3950     {
3951         m_pImpl->AddLog( aIOException.Message );
3952         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3953         throw;
3954     }
3955     catch( uno::RuntimeException& aRuntimeException )
3956     {
3957         m_pImpl->AddLog( aRuntimeException.Message );
3958         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3959         throw;
3960     }
3961     catch( uno::Exception& aException )
3962     {
3963         m_pImpl->AddLog( aException.Message );
3964         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
3965 
3966         uno::Any aCaught( ::cppu::getCaughtException() );
3967         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't insert raw stream!" ) ),
3968                                                  uno::Reference< io::XInputStream >(),
3969                                                  aCaught );
3970     }
3971 }
3972 
3973 //____________________________________________________________________________________________________
3974 //  XTransactedObject
3975 //____________________________________________________________________________________________________
3976 
3977 //-----------------------------------------------
commit()3978 void SAL_CALL OStorage::commit()
3979 {
3980     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::commit" );
3981 
3982     uno::Reference< util::XModifiable > xParentModif;
3983 
3984     try {
3985         BroadcastTransaction( STOR_MESS_PRECOMMIT );
3986 
3987         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3988 
3989         if ( !m_pImpl )
3990         {
3991             ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
3992             throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
3993         }
3994 
3995         if ( m_pData->m_bReadOnlyWrap )
3996             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access_denied
3997 
3998         m_pImpl->Commit(); // the root storage initiates the storing to source
3999 
4000         // when the storage is committed the parent is modified
4001         if ( m_pImpl->m_pParent && m_pImpl->m_pParent->m_pAntiImpl )
4002             xParentModif = (util::XModifiable*)m_pImpl->m_pParent->m_pAntiImpl;
4003     }
4004     catch( io::IOException& aIOException )
4005     {
4006         m_pImpl->AddLog( aIOException.Message );
4007         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4008         throw;
4009     }
4010     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
4011     {
4012         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
4013         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4014         throw;
4015     }
4016     catch( uno::RuntimeException& aRuntimeException )
4017     {
4018         m_pImpl->AddLog( aRuntimeException.Message );
4019         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4020         throw;
4021     }
4022     catch( uno::Exception& aException )
4023     {
4024         m_pImpl->AddLog( aException.Message );
4025         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4026 
4027         uno::Any aCaught( ::cppu::getCaughtException() );
4028         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Problems on commit!" ) ),
4029                                   uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
4030                                   aCaught );
4031     }
4032 
4033     setModified( sal_False );
4034     if ( xParentModif.is() )
4035         xParentModif->setModified( sal_True );
4036 
4037     BroadcastTransaction( STOR_MESS_COMMITED );
4038 }
4039 
4040 //-----------------------------------------------
revert()4041 void SAL_CALL OStorage::revert()
4042 {
4043     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::revert" );
4044 
4045     // the method removes all the changes done after last commit
4046 
4047     BroadcastTransaction( STOR_MESS_PREREVERT );
4048 
4049     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4050 
4051     if ( !m_pImpl )
4052     {
4053         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4054         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4055     }
4056 
4057     for ( SotElementList_Impl::iterator pElementIter = m_pImpl->m_aChildrenList.begin();
4058           pElementIter != m_pImpl->m_aChildrenList.end(); pElementIter++ )
4059     {
4060         if ( ((*pElementIter)->m_pStorage
4061                 && ( (*pElementIter)->m_pStorage->m_pAntiImpl || !(*pElementIter)->m_pStorage->m_aReadOnlyWrapList.empty() ))
4062           || ((*pElementIter)->m_pStream
4063                 && ( (*pElementIter)->m_pStream->m_pAntiImpl || !(*pElementIter)->m_pStream->m_aInputStreamsList.empty()) ) )
4064             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
4065     }
4066 
4067     if ( m_pData->m_bReadOnlyWrap || !m_pImpl->m_bListCreated )
4068         return; // nothing to do
4069 
4070     try {
4071         m_pImpl->Revert();
4072         m_pImpl->m_bIsModified = sal_False;
4073         m_pImpl->m_bBroadcastModified = sal_True;
4074     }
4075     catch( io::IOException& aIOException )
4076     {
4077         m_pImpl->AddLog( aIOException.Message );
4078         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4079         throw;
4080     }
4081     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
4082     {
4083         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
4084         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4085         throw;
4086     }
4087     catch( uno::RuntimeException& aRuntimeException )
4088     {
4089         m_pImpl->AddLog( aRuntimeException.Message );
4090         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4091         throw;
4092     }
4093     catch( uno::Exception& aException )
4094     {
4095         m_pImpl->AddLog( aException.Message );
4096         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4097 
4098         uno::Any aCaught( ::cppu::getCaughtException() );
4099         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Problems on revert!" ) ),
4100                                   uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
4101                                   aCaught );
4102     }
4103 
4104     aGuard.clear();
4105 
4106     setModified( sal_False );
4107     BroadcastTransaction( STOR_MESS_REVERTED );
4108 }
4109 
4110 //____________________________________________________________________________________________________
4111 //  XTransactionBroadcaster
4112 //____________________________________________________________________________________________________
4113 
4114 //-----------------------------------------------
addTransactionListener(const uno::Reference<embed::XTransactionListener> & aListener)4115 void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
4116 {
4117     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4118 
4119     if ( !m_pImpl )
4120     {
4121         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4122         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4123     }
4124 
4125     m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
4126                                                 aListener );
4127 }
4128 
4129 //-----------------------------------------------
removeTransactionListener(const uno::Reference<embed::XTransactionListener> & aListener)4130 void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
4131 {
4132     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4133 
4134     if ( !m_pImpl )
4135     {
4136         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4137         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4138     }
4139 
4140     m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
4141                                                     aListener );
4142 }
4143 
4144 //____________________________________________________________________________________________________
4145 //  XModifiable
4146 //  TODO: if there will be no demand on this interface it will be removed from implementation,
4147 //        I do not want to remove it now since it is still possible that it will be inserted
4148 //        to the service back.
4149 //____________________________________________________________________________________________________
4150 
4151 //-----------------------------------------------
isModified()4152 sal_Bool SAL_CALL OStorage::isModified()
4153 {
4154     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4155 
4156     if ( !m_pImpl )
4157     {
4158         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4159         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4160     }
4161 
4162     return m_pImpl->m_bIsModified;
4163 }
4164 
4165 
4166 //-----------------------------------------------
setModified(sal_Bool bModified)4167 void SAL_CALL OStorage::setModified( sal_Bool bModified )
4168 {
4169     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4170 
4171     if ( !m_pImpl )
4172     {
4173         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4174         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4175     }
4176 
4177     if ( m_pData->m_bReadOnlyWrap )
4178         throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
4179 
4180     if ( m_pImpl->m_bIsModified != bModified )
4181         m_pImpl->m_bIsModified = bModified;
4182 
4183     aGuard.clear();
4184     if ( bModified )
4185     {
4186         m_pImpl->m_bBroadcastModified = sal_True;
4187         BroadcastModifiedIfNecessary();
4188     }
4189 }
4190 
4191 //-----------------------------------------------
addModifyListener(const uno::Reference<util::XModifyListener> & aListener)4192 void SAL_CALL OStorage::addModifyListener(
4193             const uno::Reference< util::XModifyListener >& aListener )
4194 {
4195     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4196 
4197     if ( !m_pImpl )
4198     {
4199         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4200         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4201     }
4202 
4203     m_pData->m_aListenersContainer.addInterface(
4204                                 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
4205 }
4206 
4207 
4208 //-----------------------------------------------
removeModifyListener(const uno::Reference<util::XModifyListener> & aListener)4209 void SAL_CALL OStorage::removeModifyListener(
4210             const uno::Reference< util::XModifyListener >& aListener )
4211 {
4212     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4213 
4214     if ( !m_pImpl )
4215     {
4216         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4217         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4218     }
4219 
4220     m_pData->m_aListenersContainer.removeInterface(
4221                                 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
4222 }
4223 
4224 //____________________________________________________________________________________________________
4225 //  XNameAccess
4226 //____________________________________________________________________________________________________
4227 
4228 //-----------------------------------------------
getByName(const::rtl::OUString & aName)4229 uno::Any SAL_CALL OStorage::getByName( const ::rtl::OUString& aName )
4230 {
4231     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getByName" );
4232 
4233     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4234 
4235     if ( !m_pImpl )
4236     {
4237         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4238         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4239     }
4240 
4241     if ( !aName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, sal_False ) )
4242         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
4243 
4244     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
4245       && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
4246         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
4247 
4248     uno::Any aResult;
4249     try
4250     {
4251         SotElement_Impl* pElement = m_pImpl->FindElement( aName );
4252         if ( !pElement )
4253             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4254 
4255         if ( pElement->m_bIsStorage )
4256             aResult <<= openStorageElement( aName, embed::ElementModes::READ );
4257         else
4258             aResult <<= openStreamElement( aName, embed::ElementModes::READ );
4259     }
4260     catch( container::NoSuchElementException& aNoSuchElementException )
4261     {
4262         m_pImpl->AddLog( aNoSuchElementException.Message );
4263         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4264         throw;
4265     }
4266     catch( lang::WrappedTargetException& aWrappedTargetException )
4267     {
4268         m_pImpl->AddLog( aWrappedTargetException.Message );
4269         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4270         throw;
4271     }
4272     catch( uno::RuntimeException& aRuntimeException )
4273     {
4274         m_pImpl->AddLog( aRuntimeException.Message );
4275         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4276         throw;
4277     }
4278     catch ( uno::Exception& aException )
4279     {
4280         m_pImpl->AddLog( aException.Message );
4281         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4282 
4283         uno::Any aCaught( ::cppu::getCaughtException() );
4284         throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4285                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4286                                                                                 uno::UNO_QUERY ),
4287                                             aCaught );
4288     }
4289 
4290     return aResult;
4291 }
4292 
4293 
4294 //-----------------------------------------------
getElementNames()4295 uno::Sequence< ::rtl::OUString > SAL_CALL OStorage::getElementNames()
4296 {
4297     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementNames" );
4298 
4299     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4300 
4301     if ( !m_pImpl )
4302     {
4303         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4304         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4305     }
4306 
4307     try
4308     {
4309         return m_pImpl->GetElementNames();
4310     }
4311     catch( uno::RuntimeException& aRuntimeException )
4312     {
4313         m_pImpl->AddLog( aRuntimeException.Message );
4314         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4315         throw;
4316     }
4317     catch ( uno::Exception& aException )
4318     {
4319         m_pImpl->AddLog( aException.Message );
4320         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4321 
4322         uno::Any aCaught( ::cppu::getCaughtException() );
4323         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4324                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4325                                                                                 uno::UNO_QUERY ),
4326                                             aCaught );
4327     }
4328 }
4329 
4330 
4331 //-----------------------------------------------
hasByName(const::rtl::OUString & aName)4332 sal_Bool SAL_CALL OStorage::hasByName( const ::rtl::OUString& aName )
4333 {
4334     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasByName" );
4335 
4336     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4337 
4338     if ( !m_pImpl )
4339     {
4340         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4341         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4342     }
4343 
4344     if ( !aName.getLength() )
4345         return sal_False;
4346 
4347     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
4348       && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
4349         return sal_False;
4350 
4351     SotElement_Impl* pElement = NULL;
4352     try
4353     {
4354         pElement = m_pImpl->FindElement( aName );
4355     }
4356     catch( uno::RuntimeException& aRuntimeException )
4357     {
4358         m_pImpl->AddLog( aRuntimeException.Message );
4359         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4360         throw;
4361     }
4362     catch ( uno::Exception& aException )
4363     {
4364         m_pImpl->AddLog( aException.Message );
4365         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4366 
4367         uno::Any aCaught( ::cppu::getCaughtException() );
4368         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4369                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4370                                                                                 uno::UNO_QUERY ),
4371                                             aCaught );
4372     }
4373 
4374     return ( pElement != NULL );
4375 }
4376 
4377 
4378 //-----------------------------------------------
getElementType()4379 uno::Type SAL_CALL OStorage::getElementType()
4380 {
4381     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4382 
4383     if ( !m_pImpl )
4384     {
4385         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4386         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4387     }
4388 
4389     // it is a multitype container
4390     return uno::Type();
4391 }
4392 
4393 
4394 //-----------------------------------------------
hasElements()4395 sal_Bool SAL_CALL OStorage::hasElements()
4396 {
4397     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasElements" );
4398 
4399     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4400 
4401     if ( !m_pImpl )
4402     {
4403         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4404         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4405     }
4406 
4407     try
4408     {
4409         return ( m_pImpl->GetChildrenList().size() != 0 );
4410     }
4411     catch( uno::RuntimeException& aRuntimeException )
4412     {
4413         m_pImpl->AddLog( aRuntimeException.Message );
4414         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4415         throw;
4416     }
4417     catch ( uno::Exception& aException )
4418     {
4419         m_pImpl->AddLog( aException.Message );
4420         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4421 
4422         uno::Any aCaught( ::cppu::getCaughtException() );
4423         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4424                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4425                                                                                 uno::UNO_QUERY ),
4426                                             aCaught );
4427     }
4428 }
4429 
4430 
4431 //____________________________________________________________________________________________________
4432 //  XComponent
4433 //____________________________________________________________________________________________________
4434 
4435 //-----------------------------------------------
dispose()4436 void SAL_CALL OStorage::dispose()
4437 {
4438     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4439 
4440     if ( !m_pImpl )
4441     {
4442         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4443         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4444     }
4445 
4446     try
4447     {
4448         InternalDispose( sal_True );
4449     }
4450     catch( uno::RuntimeException& aRuntimeException )
4451     {
4452         m_pImpl->AddLog( aRuntimeException.Message );
4453         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4454         throw;
4455     }
4456     catch ( uno::Exception& aException )
4457     {
4458         m_pImpl->AddLog( aException.Message );
4459         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4460 
4461         uno::Any aCaught( ::cppu::getCaughtException() );
4462         throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open storage!\n" ) ),
4463                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4464                                                                                 uno::UNO_QUERY ),
4465                                             aCaught );
4466     }
4467 }
4468 
4469 //-----------------------------------------------
addEventListener(const uno::Reference<lang::XEventListener> & xListener)4470 void SAL_CALL OStorage::addEventListener(
4471             const uno::Reference< lang::XEventListener >& xListener )
4472 {
4473     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4474 
4475     if ( !m_pImpl )
4476     {
4477         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4478         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4479     }
4480 
4481     m_pData->m_aListenersContainer.addInterface(
4482                                 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4483 }
4484 
4485 //-----------------------------------------------
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)4486 void SAL_CALL OStorage::removeEventListener(
4487             const uno::Reference< lang::XEventListener >& xListener )
4488 {
4489     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4490 
4491     if ( !m_pImpl )
4492     {
4493         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4494         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4495     }
4496 
4497     m_pData->m_aListenersContainer.removeInterface(
4498                                 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4499 }
4500 
4501 //____________________________________________________________________________________________________
4502 //  XEncryptionProtectedSource
4503 //____________________________________________________________________________________________________
4504 
setEncryptionPassword(const::rtl::OUString & aPass)4505 void SAL_CALL OStorage::setEncryptionPassword( const ::rtl::OUString& aPass )
4506 {
4507     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionPassword" );
4508     setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
4509 }
4510 
4511 //-----------------------------------------------
removeEncryption()4512 void SAL_CALL OStorage::removeEncryption()
4513 {
4514     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeEncryption" );
4515 
4516     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4517 
4518     if ( !m_pImpl )
4519     {
4520         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4521         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4522     }
4523 
4524     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4525         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4526 
4527     OSL_ENSURE( m_pData->m_bIsRoot, "removeEncryption() method is not available for nonroot storages!\n" );
4528     if ( m_pData->m_bIsRoot )
4529     {
4530         try {
4531             m_pImpl->ReadContents();
4532         }
4533         catch ( uno::RuntimeException& aRuntimeException )
4534         {
4535             m_pImpl->AddLog( aRuntimeException.Message );
4536             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4537             throw;
4538         }
4539         catch ( uno::Exception& aException )
4540         {
4541             m_pImpl->AddLog( aException.Message );
4542             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4543 
4544             uno::Any aCaught( ::cppu::getCaughtException() );
4545             throw lang::WrappedTargetRuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4546                                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4547                                                                                     uno::UNO_QUERY ),
4548                                                 aCaught );
4549         }
4550 
4551         // TODO: check if the password is valid
4552         // update all streams that was encrypted with old password
4553 
4554         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4555         try
4556         {
4557             xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ),
4558                                             uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
4559 
4560             m_pImpl->m_bHasCommonEncryptionData = sal_False;
4561             m_pImpl->m_aCommonEncryptionData.clear();
4562         }
4563         catch( uno::RuntimeException& aRException )
4564         {
4565             m_pImpl->AddLog( aRException.Message );
4566             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4567 
4568             OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4569             throw;
4570         }
4571         catch( uno::Exception& aException )
4572         {
4573             m_pImpl->AddLog( aException.Message );
4574             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4575 
4576             OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4577             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4578         }
4579     }
4580 }
4581 
4582 //____________________________________________________________________________________________________
4583 //  XEncryptionProtectedSource2
4584 //____________________________________________________________________________________________________
4585 
setEncryptionData(const uno::Sequence<beans::NamedValue> & aEncryptionData)4586 void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValue >& aEncryptionData )
4587 {
4588     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionData" );
4589 
4590     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4591 
4592     if ( !m_pImpl )
4593     {
4594         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4595         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4596     }
4597 
4598     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4599         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4600 
4601     if ( !aEncryptionData.getLength() )
4602         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected empty encryption data!") ), uno::Reference< uno::XInterface >() );
4603 
4604     OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionData() method is not available for nonroot storages!\n" );
4605     if ( m_pData->m_bIsRoot )
4606     {
4607         try {
4608             m_pImpl->ReadContents();
4609         }
4610         catch ( uno::RuntimeException& aRuntimeException )
4611         {
4612             m_pImpl->AddLog( aRuntimeException.Message );
4613             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4614             throw;
4615         }
4616         catch ( uno::Exception& aException )
4617         {
4618             m_pImpl->AddLog( aException.Message );
4619             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4620 
4621             uno::Any aCaught( ::cppu::getCaughtException() );
4622             throw lang::WrappedTargetRuntimeException(
4623                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4624                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
4625                                 aCaught );
4626         }
4627 
4628         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4629         try
4630         {
4631             ::comphelper::SequenceAsHashMap aEncryptionMap( aEncryptionData );
4632             xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STORAGE_ENCRYPTION_KEYS_PROPERTY ) ),
4633                                             uno::makeAny( aEncryptionMap.getAsConstNamedValueList() ) );
4634 
4635             m_pImpl->m_bHasCommonEncryptionData = sal_True;
4636             m_pImpl->m_aCommonEncryptionData = aEncryptionMap;
4637         }
4638         catch( uno::Exception& aException )
4639         {
4640             m_pImpl->AddLog( aException.Message );
4641             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4642 
4643             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4644         }
4645     }
4646 }
4647 
4648 //____________________________________________________________________________________________________
4649 //  XEncryptionProtectedStorage
4650 //____________________________________________________________________________________________________
4651 
4652 //-----------------------------------------------
setEncryptionAlgorithms(const uno::Sequence<beans::NamedValue> & aAlgorithms)4653 void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::NamedValue >& aAlgorithms )
4654 {
4655     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionAlgorithms" );
4656 
4657     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4658 
4659     if ( !m_pImpl )
4660     {
4661         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4662         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4663     }
4664 
4665     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4666         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4667 
4668     if ( !aAlgorithms.getLength() )
4669         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected empty encryption algorithms list!") ), uno::Reference< uno::XInterface >() );
4670 
4671     OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionAlgorithms() method is not available for nonroot storages!\n" );
4672     if ( m_pData->m_bIsRoot )
4673     {
4674         try {
4675             m_pImpl->ReadContents();
4676         }
4677         catch ( uno::RuntimeException& aRuntimeException )
4678         {
4679             m_pImpl->AddLog( aRuntimeException.Message );
4680             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4681             throw;
4682         }
4683         catch ( uno::Exception& aException )
4684         {
4685             m_pImpl->AddLog( aException.Message );
4686             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4687 
4688             uno::Any aCaught( ::cppu::getCaughtException() );
4689             throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4690                                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4691                                                                                     uno::UNO_QUERY ),
4692                                                 aCaught );
4693         }
4694 
4695         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4696         try
4697         {
4698             xPackPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ),
4699                                             uno::makeAny( aAlgorithms ) );
4700         }
4701         catch ( uno::RuntimeException& aRuntimeException )
4702         {
4703             m_pImpl->AddLog( aRuntimeException.Message );
4704             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4705             throw;
4706         }
4707         catch( lang::IllegalArgumentException& aIAException )
4708         {
4709             m_pImpl->AddLog( aIAException.Message );
4710             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4711 
4712             throw;
4713         }
4714         catch( uno::Exception& aException )
4715         {
4716             m_pImpl->AddLog( aException.Message );
4717             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4718 
4719             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4720         }
4721     }
4722 }
4723 
4724 //-----------------------------------------------
getEncryptionAlgorithms()4725 uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms()
4726 {
4727     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getEncryptionAlgorithms" );
4728 
4729     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4730 
4731     if ( !m_pImpl )
4732     {
4733         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4734         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4735     }
4736 
4737     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4738         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4739 
4740     uno::Sequence< beans::NamedValue > aResult;
4741     OSL_ENSURE( m_pData->m_bIsRoot, "getEncryptionAlgorithms() method is not available for nonroot storages!\n" );
4742     if ( m_pData->m_bIsRoot )
4743     {
4744         try {
4745             m_pImpl->ReadContents();
4746         }
4747         catch ( uno::RuntimeException& aRuntimeException )
4748         {
4749             m_pImpl->AddLog( aRuntimeException.Message );
4750             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4751             throw;
4752         }
4753         catch ( uno::Exception& aException )
4754         {
4755             m_pImpl->AddLog( aException.Message );
4756             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4757 
4758             uno::Any aCaught( ::cppu::getCaughtException() );
4759             throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
4760                                                 uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
4761                                                                                     uno::UNO_QUERY ),
4762                                                 aCaught );
4763         }
4764 
4765         uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4766         try
4767         {
4768             xPackPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_ALGORITHMS_PROPERTY ) ) ) >>= aResult;
4769         }
4770         catch ( uno::RuntimeException& aRuntimeException )
4771         {
4772             m_pImpl->AddLog( aRuntimeException.Message );
4773             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4774             throw;
4775         }
4776         catch( uno::Exception& aException )
4777         {
4778             m_pImpl->AddLog( aException.Message );
4779             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4780 
4781             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4782         }
4783     }
4784 
4785     return aResult;
4786 }
4787 
4788 
4789 //____________________________________________________________________________________________________
4790 //  XPropertySet
4791 //____________________________________________________________________________________________________
4792 
4793 //-----------------------------------------------
getPropertySetInfo()4794 uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
4795 {
4796     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4797 
4798     if ( !m_pImpl )
4799     {
4800         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4801         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4802     }
4803 
4804     //TODO:
4805     return uno::Reference< beans::XPropertySetInfo >();
4806 }
4807 
4808 
4809 //-----------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any & aValue)4810 void SAL_CALL OStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue )
4811 {
4812     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setPropertyValue" );
4813 
4814     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4815 
4816     if ( !m_pImpl )
4817     {
4818         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4819         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4820     }
4821 
4822     //TODO: think about interaction handler
4823 
4824     // WORKAROUND:
4825     // The old document might have no version in the manifest.xml, so we have to allow to set the version
4826     // even for readonly storage, so that the version from content.xml can be used.
4827     if ( m_pData->m_bReadOnlyWrap && !aPropertyName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) )
4828         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: Access denied
4829 
4830     if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
4831         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4832     else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
4833     {
4834         if ( aPropertyName.equalsAscii( "MediaType" ) )
4835         {
4836             aValue >>= m_pImpl->m_aMediaType;
4837             m_pImpl->m_bControlMediaType = sal_True;
4838 
4839             m_pImpl->m_bBroadcastModified = sal_True;
4840             m_pImpl->m_bIsModified = sal_True;
4841         }
4842         else if ( aPropertyName.equalsAscii( "Version" ) )
4843         {
4844             aValue >>= m_pImpl->m_aVersion;
4845             m_pImpl->m_bControlVersion = sal_True;
4846 
4847             // this property can be set even for readonly storage
4848             if ( !m_pData->m_bReadOnlyWrap )
4849             {
4850                 m_pImpl->m_bBroadcastModified = sal_True;
4851                 m_pImpl->m_bIsModified = sal_True;
4852             }
4853         }
4854         else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( HAS_ENCRYPTED_ENTRIES_PROPERTY )
4855                                     || aPropertyName.equalsAscii( HAS_NONENCRYPTED_ENTRIES_PROPERTY )
4856                                     || aPropertyName.equalsAscii( IS_INCONSISTENT_PROPERTY )
4857                                     || aPropertyName.equalsAscii( "URL" )
4858                                     || aPropertyName.equalsAscii( "RepairPackage" ) ) )
4859            || aPropertyName.equalsAscii( "IsRoot" )
4860            || aPropertyName.equalsAscii( MEDIATYPE_FALLBACK_USED_PROPERTY ) )
4861             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4862         else
4863             throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4864     }
4865     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
4866     {
4867         if ( aPropertyName.equalsAscii( "RelationsInfoStream" ) )
4868         {
4869             uno::Reference< io::XInputStream > xInRelStream;
4870             if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
4871             {
4872                 uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
4873                 if ( !xSeek.is() )
4874                 {
4875                     // currently this is an internal property that is used for optimization
4876                     // and the stream must support XSeekable interface
4877                     // TODO/LATER: in future it can be changed if property is used from outside
4878                     throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
4879                 }
4880 
4881                 m_pImpl->m_xNewRelInfoStream = xInRelStream;
4882                 m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
4883                 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
4884                 m_pImpl->m_bBroadcastModified = sal_True;
4885                 m_pImpl->m_bIsModified = sal_True;
4886             }
4887             else
4888                 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
4889         }
4890         else if ( aPropertyName.equalsAscii( "RelationsInfo" ) )
4891         {
4892             if ( aValue >>= m_pImpl->m_aRelInfo )
4893             {
4894                 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
4895                 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4896                 m_pImpl->m_bBroadcastModified = sal_True;
4897                 m_pImpl->m_bIsModified = sal_True;
4898             }
4899             else
4900                 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
4901         }
4902         else if ( ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( "URL" )
4903                                     || aPropertyName.equalsAscii( "RepairPackage" ) ) )
4904            || aPropertyName.equalsAscii( "IsRoot" ) )
4905             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4906         else
4907             throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4908     }
4909     else
4910         throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4911 
4912     BroadcastModifiedIfNecessary();
4913 }
4914 
4915 
4916 //-----------------------------------------------
getPropertyValue(const::rtl::OUString & aPropertyName)4917 uno::Any SAL_CALL OStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
4918 {
4919     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPropertyValue" );
4920 
4921     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4922 
4923     if ( !m_pImpl )
4924     {
4925         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
4926         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4927     }
4928 
4929     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
4930       && ( aPropertyName.equalsAscii( "MediaType" )
4931         || aPropertyName.equalsAscii( MEDIATYPE_FALLBACK_USED_PROPERTY )
4932         || aPropertyName.equalsAscii( "Version" ) ) )
4933     {
4934         try
4935         {
4936             m_pImpl->ReadContents();
4937         }
4938         catch ( uno::RuntimeException& aRuntimeException )
4939         {
4940             m_pImpl->AddLog( aRuntimeException.Message );
4941             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4942             throw;
4943         }
4944         catch ( uno::Exception& aException )
4945         {
4946             m_pImpl->AddLog( aException.Message );
4947             m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
4948 
4949             uno::Any aCaught( ::cppu::getCaughtException() );
4950             throw lang::WrappedTargetException(
4951                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't read contents!" ) ),
4952                                         uno::Reference< XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
4953                                         aCaught );
4954         }
4955 
4956         if ( aPropertyName.equalsAscii( "MediaType" ) )
4957             return uno::makeAny( m_pImpl->m_aMediaType );
4958         else if ( aPropertyName.equalsAscii( "Version" ) )
4959             return uno::makeAny( m_pImpl->m_aVersion );
4960         else
4961             return uno::makeAny( m_pImpl->m_bMTFallbackUsed );
4962     }
4963     else if ( aPropertyName.equalsAscii( "IsRoot" ) )
4964     {
4965         return uno::makeAny( m_pData->m_bIsRoot );
4966     }
4967     else if ( aPropertyName.equalsAscii( "OpenMode" ) )
4968     {
4969         return uno::makeAny( m_pImpl->m_nStorageMode );
4970     }
4971     else if ( m_pData->m_bIsRoot )
4972     {
4973         if ( aPropertyName.equalsAscii( "URL" )
4974           || aPropertyName.equalsAscii( "RepairPackage" ) )
4975         {
4976             for ( sal_Int32 aInd = 0; aInd < m_pImpl->m_xProperties.getLength(); aInd++ )
4977             {
4978                 if ( m_pImpl->m_xProperties[aInd].Name.equals( aPropertyName ) )
4979                     return m_pImpl->m_xProperties[aInd].Value;
4980             }
4981 
4982             if ( aPropertyName.equalsAscii( "URL" ) )
4983                 return uno::makeAny( ::rtl::OUString() );
4984 
4985             return uno::makeAny( sal_False ); // RepairPackage
4986         }
4987         else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
4988           && ( aPropertyName.equalsAscii( HAS_ENCRYPTED_ENTRIES_PROPERTY )
4989             || aPropertyName.equalsAscii( HAS_NONENCRYPTED_ENTRIES_PROPERTY )
4990             || aPropertyName.equalsAscii( IS_INCONSISTENT_PROPERTY ) ) )
4991         {
4992             try {
4993                 m_pImpl->ReadContents();
4994                 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
4995                 if ( !xPackPropSet.is() )
4996                     throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
4997 
4998                 return xPackPropSet->getPropertyValue( aPropertyName );
4999             }
5000             catch ( uno::RuntimeException& aRuntimeException )
5001             {
5002                 m_pImpl->AddLog( aRuntimeException.Message );
5003                 m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5004                 throw;
5005             }
5006             catch ( uno::Exception& aException )
5007             {
5008                 m_pImpl->AddLog( aException.Message );
5009                 m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5010 
5011                 uno::Any aCaught( ::cppu::getCaughtException() );
5012                 throw lang::WrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can not open package!\n" ) ),
5013                                                     uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
5014                                                                                         uno::UNO_QUERY ),
5015                                                     aCaught );
5016             }
5017         }
5018     }
5019 
5020     throw beans::UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5021 }
5022 
5023 
5024 //-----------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)5025 void SAL_CALL OStorage::addPropertyChangeListener(
5026     const ::rtl::OUString& /*aPropertyName*/,
5027     const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
5028 {
5029     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5030 
5031     if ( !m_pImpl )
5032     {
5033         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5034         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5035     }
5036 
5037     //TODO:
5038 }
5039 
5040 
5041 //-----------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)5042 void SAL_CALL OStorage::removePropertyChangeListener(
5043     const ::rtl::OUString& /*aPropertyName*/,
5044     const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
5045 {
5046     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5047 
5048     if ( !m_pImpl )
5049     {
5050         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5051         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5052     }
5053 
5054     //TODO:
5055 }
5056 
5057 
5058 //-----------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)5059 void SAL_CALL OStorage::addVetoableChangeListener(
5060     const ::rtl::OUString& /*PropertyName*/,
5061     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
5062 {
5063     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5064 
5065     if ( !m_pImpl )
5066     {
5067         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5068         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5069     }
5070 
5071     //TODO:
5072 }
5073 
5074 
5075 //-----------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)5076 void SAL_CALL OStorage::removeVetoableChangeListener(
5077     const ::rtl::OUString& /*PropertyName*/,
5078     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
5079 {
5080     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5081 
5082     if ( !m_pImpl )
5083     {
5084         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5085         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5086     }
5087 
5088     //TODO:
5089 }
5090 
5091 //____________________________________________________________________________________________________
5092 //  XRelationshipAccess
5093 //____________________________________________________________________________________________________
5094 
5095 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
5096 
5097 //-----------------------------------------------
hasByID(const::rtl::OUString & sID)5098 sal_Bool SAL_CALL OStorage::hasByID(  const ::rtl::OUString& sID )
5099 {
5100     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5101 
5102     if ( !m_pImpl )
5103     {
5104         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5105         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5106     }
5107 
5108     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5109         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5110 
5111     try
5112     {
5113         getRelationshipByID( sID );
5114         return sal_True;
5115     }
5116     catch( container::NoSuchElementException& aNoSuchElementException )
5117     {
5118         m_pImpl->AddLog( aNoSuchElementException.Message );
5119         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Quiet exception" ) ) );
5120     }
5121 
5122     return sal_False;
5123 }
5124 
5125 //-----------------------------------------------
getTargetByID(const::rtl::OUString & sID)5126 ::rtl::OUString SAL_CALL OStorage::getTargetByID(  const ::rtl::OUString& sID  )
5127 {
5128     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5129 
5130     if ( !m_pImpl )
5131     {
5132         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5133         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5134     }
5135 
5136     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5137         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5138 
5139     uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
5140     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
5141         if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
5142             return aSeq[nInd].Second;
5143 
5144     return ::rtl::OUString();
5145 }
5146 
5147 //-----------------------------------------------
getTypeByID(const::rtl::OUString & sID)5148 ::rtl::OUString SAL_CALL OStorage::getTypeByID(  const ::rtl::OUString& sID  )
5149 {
5150     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5151 
5152     if ( !m_pImpl )
5153     {
5154         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5155         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5156     }
5157 
5158     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5159         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5160 
5161     uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
5162     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
5163         if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
5164             return aSeq[nInd].Second;
5165 
5166     return ::rtl::OUString();
5167 }
5168 
5169 //-----------------------------------------------
getRelationshipByID(const::rtl::OUString & sID)5170 uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID(  const ::rtl::OUString& sID  )
5171 {
5172     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5173 
5174     if ( !m_pImpl )
5175     {
5176         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5177         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5178     }
5179 
5180     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5181         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5182 
5183     // TODO/LATER: in future the unification of the ID could be checked
5184     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5185     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5186         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5187             if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
5188             {
5189                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5190                     return aSeq[nInd1];
5191                 break;
5192             }
5193 
5194     throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5195 }
5196 
5197 //-----------------------------------------------
getRelationshipsByType(const::rtl::OUString & sType)5198 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType(  const ::rtl::OUString& sType  )
5199 {
5200     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5201 
5202     if ( !m_pImpl )
5203     {
5204         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5205         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5206     }
5207 
5208     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5209         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5210 
5211     uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
5212     sal_Int32 nEntriesNum = 0;
5213 
5214     // TODO/LATER: in future the unification of the ID could be checked
5215     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5216     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5217         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5218             if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
5219             {
5220                 // the type is usually an URL, so the check should be case insensitive
5221                 if ( aSeq[nInd1][nInd2].Second.equalsIgnoreAsciiCase( sType ) )
5222                 {
5223                     aResult.realloc( ++nEntriesNum );
5224                     aResult[nEntriesNum-1] = aSeq[nInd1];
5225                 }
5226                 break;
5227             }
5228 
5229     return aResult;
5230 }
5231 
5232 //-----------------------------------------------
getAllRelationships()5233 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
5234 {
5235     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5236 
5237     if ( !m_pImpl )
5238     {
5239         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5240         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5241     }
5242 
5243     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5244         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5245 
5246     return m_pImpl->GetAllRelationshipsIfAny();
5247 }
5248 
5249 //-----------------------------------------------
insertRelationshipByID(const::rtl::OUString & sID,const uno::Sequence<beans::StringPair> & aEntry,::sal_Bool bReplace)5250 void SAL_CALL OStorage::insertRelationshipByID(  const ::rtl::OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, ::sal_Bool bReplace  )
5251 {
5252     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5253 
5254     if ( !m_pImpl )
5255     {
5256         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5257         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5258     }
5259 
5260     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5261         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5262 
5263     ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
5264 
5265     sal_Int32 nIDInd = -1;
5266 
5267     // TODO/LATER: in future the unification of the ID could be checked
5268     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5269     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5270         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5271             if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
5272             {
5273                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5274                     nIDInd = nInd1;
5275 
5276                 break;
5277             }
5278 
5279     if ( nIDInd == -1 || bReplace )
5280     {
5281         if ( nIDInd == -1 )
5282         {
5283             nIDInd = aSeq.getLength();
5284             aSeq.realloc( nIDInd + 1 );
5285         }
5286 
5287         aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
5288 
5289         aSeq[nIDInd][0].First = aIDTag;
5290         aSeq[nIDInd][0].Second = sID;
5291         sal_Int32 nIndTarget = 1;
5292         for ( sal_Int32 nIndOrig = 0;
5293               nIndOrig < aEntry.getLength();
5294               nIndOrig++ )
5295         {
5296             if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
5297                 aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
5298         }
5299 
5300         aSeq[nIDInd].realloc( nIndTarget );
5301     }
5302     else
5303         throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5304 
5305 
5306     m_pImpl->m_aRelInfo = aSeq;
5307     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5308     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5309 }
5310 
5311 //-----------------------------------------------
removeRelationshipByID(const::rtl::OUString & sID)5312 void SAL_CALL OStorage::removeRelationshipByID(  const ::rtl::OUString& sID  )
5313 {
5314     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5315 
5316     if ( !m_pImpl )
5317     {
5318         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5319         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5320     }
5321 
5322     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5323         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5324 
5325     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5326     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5327         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5328             if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
5329             {
5330                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5331                 {
5332                     sal_Int32 nLength = aSeq.getLength();
5333                     aSeq[nInd1] = aSeq[nLength-1];
5334                     aSeq.realloc( nLength - 1 );
5335 
5336                     m_pImpl->m_aRelInfo = aSeq;
5337                     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5338                     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5339 
5340                     // TODO/LATER: in future the unification of the ID could be checked
5341                     return;
5342                 }
5343 
5344                 break;
5345             }
5346 
5347     throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5348 }
5349 
5350 //-----------------------------------------------
insertRelationships(const uno::Sequence<uno::Sequence<beans::StringPair>> & aEntries,::sal_Bool bReplace)5351 void SAL_CALL OStorage::insertRelationships(  const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, ::sal_Bool bReplace  )
5352 {
5353     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5354 
5355     if ( !m_pImpl )
5356     {
5357         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5358         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5359     }
5360 
5361     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5362         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5363 
5364     ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
5365     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5366     uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
5367     sal_Int32 nResultInd = 0;
5368 
5369     for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
5370         for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
5371             if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
5372             {
5373                 sal_Int32 nIndSourceSame = -1;
5374 
5375                 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
5376                     for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
5377                     {
5378                         if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
5379                         {
5380                             if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
5381                             {
5382                                 if ( !bReplace )
5383                                     throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5384 
5385                                 nIndSourceSame = nIndSource1;
5386                             }
5387 
5388                             break;
5389                         }
5390                     }
5391 
5392                 if ( nIndSourceSame == -1 )
5393                 {
5394                     // no such element in the provided sequence
5395                     aResultSeq[nResultInd++] = aSeq[nIndTarget1];
5396                 }
5397 
5398                 break;
5399             }
5400 
5401     for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
5402     {
5403         aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
5404         sal_Bool bHasID = sal_False;
5405         sal_Int32 nResInd2 = 1;
5406 
5407         for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
5408             if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
5409             {
5410                 aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
5411                 bHasID = sal_True;
5412             }
5413             else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
5414                 aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
5415             else
5416                 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: illegal relation ( no ID )
5417 
5418         if ( !bHasID )
5419             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: illegal relations
5420 
5421         nResultInd++;
5422     }
5423 
5424     aResultSeq.realloc( nResultInd );
5425     m_pImpl->m_aRelInfo = aResultSeq;
5426     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5427     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5428 }
5429 
5430 //-----------------------------------------------
clearRelationships()5431 void SAL_CALL OStorage::clearRelationships()
5432 {
5433     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5434 
5435     if ( !m_pImpl )
5436     {
5437         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5438         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5439     }
5440 
5441     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5442         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5443 
5444     m_pImpl->m_aRelInfo.realloc( 0 );
5445     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5446     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5447 }
5448 
5449 //____________________________________________________________________________________________________
5450 //  XOptimizedStorage
5451 //____________________________________________________________________________________________________
5452 //-----------------------------------------------
insertRawNonEncrStreamElementDirect(const::rtl::OUString &,const uno::Reference<io::XInputStream> &)5453 void SAL_CALL OStorage::insertRawNonEncrStreamElementDirect(
5454             const ::rtl::OUString& /*sStreamName*/,
5455             const uno::Reference< io::XInputStream >& /*xInStream*/ )
5456 {
5457     // not implemented currently because there is still no demand
5458     // might need to be implemented if direct copying of compressed streams is used
5459     throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5460 }
5461 
5462 //-----------------------------------------------
insertStreamElementDirect(const::rtl::OUString & aStreamName,const uno::Reference<io::XInputStream> & xInStream,const uno::Sequence<beans::PropertyValue> & aProps)5463 void SAL_CALL OStorage::insertStreamElementDirect(
5464             const ::rtl::OUString& aStreamName,
5465             const uno::Reference< io::XInputStream >& xInStream,
5466             const uno::Sequence< beans::PropertyValue >& aProps )
5467 {
5468     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertStreamElementDirect" );
5469 
5470     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5471 
5472     if ( !m_pImpl )
5473     {
5474         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5475         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5476     }
5477 
5478     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
5479         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5480 
5481     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
5482       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5483         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
5484 
5485     if ( m_pData->m_bReadOnlyWrap )
5486         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: access denied
5487 
5488     try
5489     {
5490         SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
5491 
5492         if ( pElement )
5493             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5494 
5495         pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, sal_False );
5496         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
5497 
5498         pElement->m_pStream->InsertStreamDirectly( xInStream, aProps );
5499     }
5500     catch( embed::InvalidStorageException& aInvalidStorageException )
5501     {
5502         m_pImpl->AddLog( aInvalidStorageException.Message );
5503         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5504         throw;
5505     }
5506     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5507     {
5508         m_pImpl->AddLog( aIllegalArgumentException.Message );
5509         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5510         throw;
5511     }
5512     catch( container::ElementExistException& aElementExistException )
5513     {
5514         m_pImpl->AddLog( aElementExistException.Message );
5515         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5516         throw;
5517     }
5518     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5519     {
5520         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5521         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5522         throw;
5523     }
5524     catch( io::IOException& aIOException )
5525     {
5526         m_pImpl->AddLog( aIOException.Message );
5527         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5528         throw;
5529     }
5530     catch( uno::RuntimeException& aRuntimeException )
5531     {
5532         m_pImpl->AddLog( aRuntimeException.Message );
5533         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5534         throw;
5535     }
5536     catch( uno::Exception& aException )
5537     {
5538         m_pImpl->AddLog( aException.Message );
5539         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5540 
5541         uno::Any aCaught( ::cppu::getCaughtException() );
5542         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't insert stream directly!" ) ),
5543                                                  uno::Reference< io::XInputStream >(),
5544                                                  aCaught );
5545     }
5546 }
5547 
5548 //-----------------------------------------------
copyElementDirectlyTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XOptimizedStorage> & xDest,const::rtl::OUString & aNewName)5549 void SAL_CALL OStorage::copyElementDirectlyTo(
5550             const ::rtl::OUString& aElementName,
5551             const uno::Reference< embed::XOptimizedStorage >& xDest,
5552             const ::rtl::OUString& aNewName )
5553 {
5554     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementDirectlyTo" );
5555 
5556     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5557 
5558     if ( !m_pImpl )
5559     {
5560         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5561         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5562     }
5563 
5564     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
5565       || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
5566         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5567 
5568     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
5569         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
5570 
5571     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
5572       && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
5573         || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
5574         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 ); // unacceptable name
5575 
5576     try
5577     {
5578         SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
5579         if ( !pElement )
5580             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5581 
5582         uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
5583         if ( !xNameAccess.is() )
5584             throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5585 
5586         if ( xNameAccess->hasByName( aNewName ) )
5587             throw container::ElementExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5588 
5589         // let the element be copied directly
5590         uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
5591         m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, sal_True );
5592     }
5593     catch( embed::InvalidStorageException& aInvalidStorageException )
5594     {
5595         m_pImpl->AddLog( aInvalidStorageException.Message );
5596         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5597         throw;
5598     }
5599     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5600     {
5601         m_pImpl->AddLog( aIllegalArgumentException.Message );
5602         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5603         throw;
5604     }
5605     catch( container::NoSuchElementException& aNoSuchElementException )
5606     {
5607         m_pImpl->AddLog( aNoSuchElementException.Message );
5608         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5609         throw;
5610     }
5611     catch( container::ElementExistException& aElementExistException )
5612     {
5613         m_pImpl->AddLog( aElementExistException.Message );
5614         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5615         throw;
5616     }
5617     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5618     {
5619         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5620         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5621         throw;
5622     }
5623     catch( io::IOException& aIOException )
5624     {
5625         m_pImpl->AddLog( aIOException.Message );
5626         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5627         throw;
5628     }
5629     catch( uno::RuntimeException& aRuntimeException )
5630     {
5631         m_pImpl->AddLog( aRuntimeException.Message );
5632         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5633         throw;
5634     }
5635     catch( uno::Exception& aException )
5636     {
5637         m_pImpl->AddLog( aException.Message );
5638         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5639 
5640         uno::Any aCaught( ::cppu::getCaughtException() );
5641         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy element direcly!" ) ),
5642                                                  uno::Reference< io::XInputStream >(),
5643                                                  aCaught );
5644     }
5645 }
5646 
5647 //-----------------------------------------------
writeAndAttachToStream(const uno::Reference<io::XStream> & xStream)5648 void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
5649 {
5650     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::writeAndAttachToStream" );
5651 
5652     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5653 
5654     if ( !m_pImpl )
5655     {
5656         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5657         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5658     }
5659 
5660     if ( !m_pData->m_bIsRoot )
5661         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5662 
5663     if ( !m_pImpl->m_pSwitchStream )
5664         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5665 
5666     try
5667     {
5668         m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
5669     }
5670     catch( embed::InvalidStorageException& aInvalidStorageException )
5671     {
5672         m_pImpl->AddLog( aInvalidStorageException.Message );
5673         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5674         throw;
5675     }
5676     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5677     {
5678         m_pImpl->AddLog( aIllegalArgumentException.Message );
5679         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5680         throw;
5681     }
5682     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5683     {
5684         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5685         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5686         throw;
5687     }
5688     catch( io::IOException& aIOException )
5689     {
5690         m_pImpl->AddLog( aIOException.Message );
5691         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5692         throw;
5693     }
5694     catch( uno::RuntimeException& aRuntimeException )
5695     {
5696         m_pImpl->AddLog( aRuntimeException.Message );
5697         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5698         throw;
5699     }
5700     catch( uno::Exception& aException )
5701     {
5702         m_pImpl->AddLog( aException.Message );
5703         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5704 
5705         uno::Any aCaught( ::cppu::getCaughtException() );
5706         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't write and attach to stream!" ) ),
5707                                                  uno::Reference< io::XInputStream >(),
5708                                                  aCaught );
5709     }
5710 
5711 }
5712 
5713 //-----------------------------------------------
attachToURL(const::rtl::OUString & sURL,sal_Bool bReadOnly)5714 void SAL_CALL OStorage::attachToURL( const ::rtl::OUString& sURL,
5715                                     sal_Bool bReadOnly )
5716 {
5717     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::attachToURL" );
5718 
5719     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5720 
5721     if ( !m_pImpl )
5722     {
5723         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5724         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5725     }
5726 
5727     if ( !m_pData->m_bIsRoot )
5728         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 0 );
5729 
5730     if ( !m_pImpl->m_pSwitchStream )
5731         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5732 
5733     uno::Reference < ucb::XSimpleFileAccess > xAccess(
5734             m_pImpl->m_xFactory->createInstance (
5735                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
5736             uno::UNO_QUERY_THROW );
5737 
5738     try
5739     {
5740         if ( bReadOnly )
5741         {
5742             uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
5743             m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
5744         }
5745         else
5746         {
5747             uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
5748             m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
5749         }
5750     }
5751     catch( embed::InvalidStorageException& aInvalidStorageException )
5752     {
5753         m_pImpl->AddLog( aInvalidStorageException.Message );
5754         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5755         throw;
5756     }
5757     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5758     {
5759         m_pImpl->AddLog( aIllegalArgumentException.Message );
5760         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5761         throw;
5762     }
5763     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5764     {
5765         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5766         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5767         throw;
5768     }
5769     catch( io::IOException& aIOException )
5770     {
5771         m_pImpl->AddLog( aIOException.Message );
5772         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5773         throw;
5774     }
5775     catch( uno::RuntimeException& aRuntimeException )
5776     {
5777         m_pImpl->AddLog( aRuntimeException.Message );
5778         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5779         throw;
5780     }
5781     catch( uno::Exception& aException )
5782     {
5783         m_pImpl->AddLog( aException.Message );
5784         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5785 
5786         uno::Any aCaught( ::cppu::getCaughtException() );
5787         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't attach to URL!" ) ),
5788                                                  uno::Reference< io::XInputStream >(),
5789                                                  aCaught );
5790     }
5791 }
5792 
5793 //-----------------------------------------------
getElementPropertyValue(const::rtl::OUString & aElementName,const::rtl::OUString & aPropertyName)5794 uno::Any SAL_CALL OStorage::getElementPropertyValue( const ::rtl::OUString& aElementName, const ::rtl::OUString& aPropertyName )
5795 {
5796     RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementPropertyValue" );
5797 
5798     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5799 
5800     if ( !m_pImpl )
5801     {
5802         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5803         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5804     }
5805 
5806     if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
5807         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5808 
5809     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
5810       && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5811         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
5812 
5813     try
5814     {
5815         SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
5816         if ( !pElement )
5817             throw container::NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5818 
5819         // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5820         if ( !pElement->m_bIsStorage || m_pData->m_nStorageType != embed::StorageFormats::PACKAGE || !aPropertyName.equalsAscii( "MediaType" ) )
5821             throw beans::PropertyVetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5822 
5823         if ( !pElement->m_pStorage )
5824             m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
5825 
5826         if ( !pElement->m_pStorage )
5827             throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // TODO: general_error
5828 
5829         pElement->m_pStorage->ReadContents();
5830         return uno::makeAny( pElement->m_pStorage->m_aMediaType );
5831     }
5832     catch( embed::InvalidStorageException& aInvalidStorageException )
5833     {
5834         m_pImpl->AddLog( aInvalidStorageException.Message );
5835         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5836         throw;
5837     }
5838     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5839     {
5840         m_pImpl->AddLog( aIllegalArgumentException.Message );
5841         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5842         throw;
5843     }
5844     catch( container::NoSuchElementException& aNoSuchElementException )
5845     {
5846         m_pImpl->AddLog( aNoSuchElementException.Message );
5847         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5848         throw;
5849     }
5850     catch( beans::UnknownPropertyException& aUnknownPropertyException )
5851     {
5852         m_pImpl->AddLog( aUnknownPropertyException.Message );
5853         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5854         throw;
5855     }
5856     catch( beans::PropertyVetoException& aPropertyVetoException )
5857     {
5858         m_pImpl->AddLog( aPropertyVetoException.Message );
5859         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5860         throw;
5861     }
5862     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5863     {
5864         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5865         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5866         throw;
5867     }
5868     catch( io::IOException& aIOException )
5869     {
5870         m_pImpl->AddLog( aIOException.Message );
5871         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5872         throw;
5873     }
5874     catch( uno::RuntimeException& aRuntimeException )
5875     {
5876         m_pImpl->AddLog( aRuntimeException.Message );
5877         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5878         throw;
5879     }
5880     catch( uno::Exception& aException )
5881     {
5882         m_pImpl->AddLog( aException.Message );
5883         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5884 
5885         uno::Any aCaught( ::cppu::getCaughtException() );
5886         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't get element property!" ) ),
5887                                                  uno::Reference< io::XInputStream >(),
5888                                                  aCaught );
5889     }
5890 }
5891 
5892 //-----------------------------------------------
copyStreamElementData(const::rtl::OUString & aStreamName,const uno::Reference<io::XStream> & xTargetStream)5893 void SAL_CALL OStorage::copyStreamElementData( const ::rtl::OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
5894 {
5895     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5896 
5897     if ( !m_pImpl )
5898     {
5899         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5900         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5901     }
5902 
5903     if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
5904         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5905 
5906     if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML
5907       && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5908         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
5909 
5910     if ( !xTargetStream.is() )
5911         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 2 );
5912 
5913     try
5914     {
5915         uno::Reference< io::XStream > xNonconstRef = xTargetStream;
5916         m_pImpl->CloneStreamElement( aStreamName, sal_False, ::comphelper::SequenceAsHashMap(), xNonconstRef );
5917 
5918         OSL_ENSURE( xNonconstRef == xTargetStream, "The provided stream reference seems not be filled in correctly!\n" );
5919         if ( xNonconstRef != xTargetStream )
5920             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!
5921     }
5922     catch( embed::InvalidStorageException& aInvalidStorageException )
5923     {
5924         m_pImpl->AddLog( aInvalidStorageException.Message );
5925         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5926         throw;
5927     }
5928     catch( lang::IllegalArgumentException& aIllegalArgumentException )
5929     {
5930         m_pImpl->AddLog( aIllegalArgumentException.Message );
5931         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5932         throw;
5933     }
5934     catch( packages::WrongPasswordException& aWrongPasswordException )
5935     {
5936         m_pImpl->AddLog( aWrongPasswordException.Message );
5937         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5938         throw;
5939     }
5940     catch( io::IOException& aIOException )
5941     {
5942         m_pImpl->AddLog( aIOException.Message );
5943         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5944         throw;
5945     }
5946     catch( embed::StorageWrappedTargetException& aStorageWrappedTargetException )
5947     {
5948         m_pImpl->AddLog( aStorageWrappedTargetException.Message );
5949         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5950         throw;
5951     }
5952     catch( uno::RuntimeException& aRuntimeException )
5953     {
5954         m_pImpl->AddLog( aRuntimeException.Message );
5955         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5956         throw;
5957     }
5958     catch( uno::Exception& aException )
5959     {
5960         m_pImpl->AddLog( aException.Message );
5961         m_pImpl->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Rethrow" ) ) );
5962 
5963         uno::Any aCaught( ::cppu::getCaughtException() );
5964         throw embed::StorageWrappedTargetException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Can't copy stream data!" ) ),
5965                                                  uno::Reference< io::XInputStream >(),
5966                                                  aCaught );
5967     }
5968 
5969 
5970 }
5971 
5972 //____________________________________________________________________________________________________
5973 // XHierarchicalStorageAccess
5974 //____________________________________________________________________________________________________
5975 
5976 //-----------------------------------------------
openStreamElementByHierarchicalName(const::rtl::OUString & aStreamPath,::sal_Int32 nOpenMode)5977 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode )
5978 {
5979     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5980 
5981     if ( !m_pImpl )
5982     {
5983         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
5984         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
5985     }
5986 
5987     if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
5988         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5989 
5990     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5991       && ( nOpenMode & embed::ElementModes::WRITE ) )
5992         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
5993 
5994     OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5995     OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5996 
5997     uno::Reference< embed::XExtendedStorageStream > xResult;
5998     if ( aListPath.size() == 1 )
5999     {
6000         // that must be a direct request for a stream
6001         // the transacted version of the stream should be opened
6002 
6003         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_False );
6004         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
6005 
6006         xResult = uno::Reference< embed::XExtendedStorageStream >(
6007                         pElement->m_pStream->GetStream( nOpenMode, sal_True ),
6008                         uno::UNO_QUERY_THROW );
6009     }
6010     else
6011     {
6012         // there are still storages in between
6013         if ( !m_pData->m_rHierarchyHolder.is() )
6014             m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6015                 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6016 
6017         xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
6018                                                 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
6019                                                 aListPath,
6020                                                 nOpenMode );
6021     }
6022 
6023     if ( !xResult.is() )
6024         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6025 
6026     return xResult;
6027 }
6028 
6029 //-----------------------------------------------
openEncryptedStreamElementByHierarchicalName(const::rtl::OUString & aStreamPath,::sal_Int32 nOpenMode,const::rtl::OUString & sPassword)6030 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode, const ::rtl::OUString& sPassword )
6031 {
6032     return openEncryptedStreamByHierarchicalName( aStreamPath, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword ) );
6033 }
6034 
6035 //-----------------------------------------------
removeStreamElementByHierarchicalName(const::rtl::OUString & aStreamPath)6036 void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath )
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 ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
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_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
6050         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
6051 
6052     OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6053     OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6054 
6055     if ( !m_pData->m_rHierarchyHolder.is() )
6056         m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6057             uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6058 
6059     m_pData->m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );
6060 }
6061 
6062 //____________________________________________________________________________________________________
6063 // XHierarchicalStorageAccess2
6064 //____________________________________________________________________________________________________
6065 
openEncryptedStreamByHierarchicalName(const::rtl::OUString & aStreamPath,::sal_Int32 nOpenMode,const uno::Sequence<beans::NamedValue> & aEncryptionData)6066 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
6067 {
6068     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6069 
6070     if ( !m_pImpl )
6071     {
6072         ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Disposed!" ) ) );
6073         throw lang::DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6074     }
6075 
6076     if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
6077         throw packages::NoEncryptionException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6078 
6079     if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6080         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
6081 
6082     if ( !aEncryptionData.getLength() )
6083         throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >(), 3 );
6084 
6085     if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
6086       && ( nOpenMode & embed::ElementModes::WRITE ) )
6087         throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); // Access denied
6088 
6089     OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6090     OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6091 
6092     uno::Reference< embed::XExtendedStorageStream > xResult;
6093     if ( aListPath.size() == 1 )
6094     {
6095         // that must be a direct request for a stream
6096         // the transacted version of the stream should be opened
6097 
6098         SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_True );
6099         OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
6100 
6101         xResult = uno::Reference< embed::XExtendedStorageStream >(
6102                         pElement->m_pStream->GetStream( nOpenMode, aEncryptionData, sal_True ),
6103                         uno::UNO_QUERY_THROW );
6104     }
6105     else
6106     {
6107         // there are still storages in between
6108         if ( !m_pData->m_rHierarchyHolder.is() )
6109             m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6110                 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6111 
6112         xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
6113                                                 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
6114                                                 aListPath,
6115                                                 nOpenMode,
6116                                                 aEncryptionData );
6117     }
6118 
6119     if ( !xResult.is() )
6120         throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() );
6121 
6122     return xResult;
6123 }
6124 
6125 /* vim: set noet sw=4 ts=4: */
6126