xref: /trunk/main/comphelper/source/misc/storagehelper.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <com/sun/star/embed/ElementModes.hpp>
31 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
32 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/NamedValue.hpp>
36 #include <com/sun/star/beans/IllegalTypeException.hpp>
37 #include <com/sun/star/xml/crypto/XDigestContext.hpp>
38 #include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
39 #include <com/sun/star/xml/crypto/DigestID.hpp>
40 
41 #include <rtl/digest.h>
42 
43 #include <ucbhelper/content.hxx>
44 
45 #include <comphelper/fileformat.h>
46 #include <comphelper/processfactory.hxx>
47 #include <comphelper/documentconstants.hxx>
48 
49 #include <comphelper/storagehelper.hxx>
50 
51 
52 using namespace ::com::sun::star;
53 
54 namespace comphelper {
55 
56 // ----------------------------------------------------------------------
57 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory(
58                             const uno::Reference< lang::XMultiServiceFactory >& xSF )
59         throw ( uno::Exception )
60 {
61     uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
62     if ( !xFactory.is() )
63         throw uno::RuntimeException();
64 
65     uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
66                     xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
67                     uno::UNO_QUERY );
68 
69     if ( !xStorageFactory.is() )
70         throw uno::RuntimeException();
71 
72     return xStorageFactory;
73 }
74 
75 // ----------------------------------------------------------------------
76 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetFileSystemStorageFactory(
77                             const uno::Reference< lang::XMultiServiceFactory >& xSF )
78         throw ( uno::Exception )
79 {
80     uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
81     if ( !xFactory.is() )
82         throw uno::RuntimeException();
83 
84     uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
85                     xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.FileSystemStorageFactory" ) ),
86                     uno::UNO_QUERY );
87 
88     if ( !xStorageFactory.is() )
89         throw uno::RuntimeException();
90 
91     return xStorageFactory;
92 }
93 
94 // ----------------------------------------------------------------------
95 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage(
96             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
97     throw ( uno::Exception )
98 {
99     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(),
100                                                     uno::UNO_QUERY );
101     if ( !xTempStorage.is() )
102         throw uno::RuntimeException();
103 
104     return xTempStorage;
105 }
106 
107 // ----------------------------------------------------------------------
108 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL(
109             const ::rtl::OUString& aURL,
110             sal_Int32 nStorageMode,
111             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
112     throw ( uno::Exception )
113 {
114     uno::Sequence< uno::Any > aArgs( 2 );
115     aArgs[0] <<= aURL;
116     aArgs[1] <<= nStorageMode;
117 
118     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
119                                                     uno::UNO_QUERY );
120     if ( !xTempStorage.is() )
121         throw uno::RuntimeException();
122 
123     return xTempStorage;
124 }
125 
126 // ----------------------------------------------------------------------
127 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL2(
128             const ::rtl::OUString& aURL,
129             sal_Int32 nStorageMode,
130             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
131     throw ( uno::Exception )
132 {
133     uno::Sequence< uno::Any > aArgs( 2 );
134     aArgs[0] <<= aURL;
135     aArgs[1] <<= nStorageMode;
136 
137     uno::Reference< lang::XSingleServiceFactory > xFact;
138     try {
139         ::ucbhelper::Content aCntnt( aURL,
140             uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
141         if (aCntnt.isDocument()) {
142             xFact = GetStorageFactory( xFactory );
143         } else {
144             xFact = GetFileSystemStorageFactory( xFactory );
145         }
146     } catch (uno::Exception &) { }
147 
148     if (!xFact.is()) throw uno::RuntimeException();
149 
150     uno::Reference< embed::XStorage > xTempStorage(
151         xFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
152     if ( !xTempStorage.is() )
153         throw uno::RuntimeException();
154 
155     return xTempStorage;
156 }
157 
158 // ----------------------------------------------------------------------
159 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream(
160             const uno::Reference < io::XInputStream >& xStream,
161             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
162         throw ( uno::Exception )
163 {
164     uno::Sequence< uno::Any > aArgs( 2 );
165     aArgs[0] <<= xStream;
166     aArgs[1] <<= embed::ElementModes::READ;
167 
168     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
169                                                     uno::UNO_QUERY );
170     if ( !xTempStorage.is() )
171         throw uno::RuntimeException();
172 
173     return xTempStorage;
174 }
175 
176 // ----------------------------------------------------------------------
177 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream(
178             const uno::Reference < io::XStream >& xStream,
179             sal_Int32 nStorageMode,
180             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
181         throw ( uno::Exception )
182 {
183     uno::Sequence< uno::Any > aArgs( 2 );
184     aArgs[0] <<= xStream;
185     aArgs[1] <<= nStorageMode;
186 
187     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
188                                                     uno::UNO_QUERY );
189     if ( !xTempStorage.is() )
190         throw uno::RuntimeException();
191 
192     return xTempStorage;
193 }
194 
195 // ----------------------------------------------------------------------
196 void OStorageHelper::CopyInputToOutput(
197             const uno::Reference< io::XInputStream >& xInput,
198             const uno::Reference< io::XOutputStream >& xOutput )
199     throw ( uno::Exception )
200 {
201     static const sal_Int32 nConstBufferSize = 32000;
202 
203     sal_Int32 nRead;
204     uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
205 
206     do
207     {
208         nRead = xInput->readBytes ( aSequence, nConstBufferSize );
209         if ( nRead < nConstBufferSize )
210         {
211             uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
212             xOutput->writeBytes ( aTempBuf );
213         }
214         else
215             xOutput->writeBytes ( aSequence );
216     }
217     while ( nRead == nConstBufferSize );
218 }
219 
220 // ----------------------------------------------------------------------
221 uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL(
222             const ::rtl::OUString& aURL,
223             const uno::Reference< lang::XMultiServiceFactory >& xSF )
224     throw ( uno::Exception )
225 {
226     uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
227     if ( !xFactory.is() )
228         throw uno::RuntimeException();
229 
230     uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess(
231             xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
232             uno::UNO_QUERY );
233 
234     if ( !xTempAccess.is() )
235         throw uno::RuntimeException();
236 
237     uno::Reference< io::XInputStream > xInputStream = xTempAccess->openFileRead( aURL );
238     if ( !xInputStream.is() )
239         throw uno::RuntimeException();
240 
241     return xInputStream;
242 }
243 
244 // ----------------------------------------------------------------------
245 void OStorageHelper::SetCommonStorageEncryptionData(
246             const uno::Reference< embed::XStorage >& xStorage,
247             const uno::Sequence< beans::NamedValue >& aEncryptionData )
248     throw ( uno::Exception )
249 {
250     uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY );
251     if ( !xEncrSet.is() )
252         throw io::IOException(); // TODO
253 
254     xEncrSet->setEncryptionData( aEncryptionData );
255 }
256 
257 // ----------------------------------------------------------------------
258 sal_Int32 OStorageHelper::GetXStorageFormat(
259             const uno::Reference< embed::XStorage >& xStorage )
260         throw ( uno::Exception )
261 {
262     uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );
263 
264     ::rtl::OUString aMediaType;
265     xStorProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;
266 
267     sal_Int32 nResult = 0;
268 
269     // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
270     if (
271         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_ASCII       ) ||
272         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII   ) ||
273         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII) ||
274         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_DRAW_ASCII         ) ||
275         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII      ) ||
276         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CALC_ASCII         ) ||
277         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CHART_ASCII        ) ||
278         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_MATH_ASCII         )
279        )
280     {
281         nResult = SOFFICE_FILEFORMAT_60;
282     }
283     else
284     if (
285         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII        ) ||
286         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII    ) ||
287         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) ||
288         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII     ) ||
289         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) ||
290         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) ||
291         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII       ) ||
292         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII     ) ||
293         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII    ) ||
294         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII    ) ||
295         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII    ) ||
296         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII        ) ||
297         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII     ) ||
298         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) ||
299         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) ||
300         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII       ) ||
301         aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII     )
302        )
303     {
304         nResult = SOFFICE_FILEFORMAT_8;
305     }
306     else
307     {
308         // the mediatype is not known
309         throw beans::IllegalTypeException();
310     }
311 
312     return nResult;
313 }
314 
315 // ----------------------------------------------------------------------
316 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorageOfFormat(
317             const ::rtl::OUString& aFormat,
318             const uno::Reference< lang::XMultiServiceFactory >& xFactory )
319     throw ( uno::Exception )
320 {
321     uno::Reference< lang::XMultiServiceFactory > xFactoryToUse = xFactory.is() ? xFactory : ::comphelper::getProcessServiceFactory();
322     if ( !xFactoryToUse.is() )
323         throw uno::RuntimeException();
324 
325     uno::Reference< io::XStream > xTmpStream(
326         xFactoryToUse->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
327         uno::UNO_QUERY_THROW );
328 
329     return GetStorageOfFormatFromStream( aFormat, xTmpStream, embed::ElementModes::READWRITE, xFactoryToUse );
330 }
331 
332 // ----------------------------------------------------------------------
333 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromURL(
334             const ::rtl::OUString& aFormat,
335             const ::rtl::OUString& aURL,
336             sal_Int32 nStorageMode,
337             const uno::Reference< lang::XMultiServiceFactory >& xFactory,
338             sal_Bool bRepairStorage )
339     throw ( uno::Exception )
340 {
341     uno::Sequence< beans::PropertyValue > aProps( 1 );
342     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
343     aProps[0].Value <<= aFormat;
344     if ( bRepairStorage )
345     {
346         aProps.realloc( 2 );
347         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
348         aProps[1].Value <<= bRepairStorage;
349     }
350 
351     uno::Sequence< uno::Any > aArgs( 3 );
352     aArgs[0] <<= aURL;
353     aArgs[1] <<= nStorageMode;
354     aArgs[2] <<= aProps;
355 
356     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
357                                                     uno::UNO_QUERY );
358     if ( !xTempStorage.is() )
359         throw uno::RuntimeException();
360 
361     return xTempStorage;
362 }
363 
364 // ----------------------------------------------------------------------
365 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStream(
366             const ::rtl::OUString& aFormat,
367             const uno::Reference < io::XInputStream >& xStream,
368             const uno::Reference< lang::XMultiServiceFactory >& xFactory,
369             sal_Bool bRepairStorage )
370         throw ( uno::Exception )
371 {
372     uno::Sequence< beans::PropertyValue > aProps( 1 );
373     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
374     aProps[0].Value <<= aFormat;
375     if ( bRepairStorage )
376     {
377         aProps.realloc( 2 );
378         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
379         aProps[1].Value <<= bRepairStorage;
380     }
381 
382     uno::Sequence< uno::Any > aArgs( 3 );
383     aArgs[0] <<= xStream;
384     aArgs[1] <<= embed::ElementModes::READ;
385     aArgs[2] <<= aProps;
386 
387     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
388                                                     uno::UNO_QUERY );
389     if ( !xTempStorage.is() )
390         throw uno::RuntimeException();
391 
392     return xTempStorage;
393 }
394 
395 // ----------------------------------------------------------------------
396 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream(
397             const ::rtl::OUString& aFormat,
398             const uno::Reference < io::XStream >& xStream,
399             sal_Int32 nStorageMode,
400             const uno::Reference< lang::XMultiServiceFactory >& xFactory,
401             sal_Bool bRepairStorage )
402         throw ( uno::Exception )
403 {
404     uno::Sequence< beans::PropertyValue > aProps( 1 );
405     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
406     aProps[0].Value <<= aFormat;
407     if ( bRepairStorage )
408     {
409         aProps.realloc( 2 );
410         aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
411         aProps[1].Value <<= bRepairStorage;
412     }
413 
414     uno::Sequence< uno::Any > aArgs( 3 );
415     aArgs[0] <<= xStream;
416     aArgs[1] <<= nStorageMode;
417     aArgs[2] <<= aProps;
418 
419     uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
420                                                     uno::UNO_QUERY );
421     if ( !xTempStorage.is() )
422         throw uno::RuntimeException();
423 
424     return xTempStorage;
425 }
426 
427 // ----------------------------------------------------------------------
428 uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( const ::rtl::OUString& aPassword, const uno::Reference< lang::XMultiServiceFactory >& xSF )
429 {
430     // TODO/LATER: Should not the method be part of DocPasswordHelper?
431     uno::Sequence< beans::NamedValue > aEncryptionData;
432     sal_Int32 nSha1Ind = 0;
433     if ( aPassword.getLength() )
434     {
435         // generate SHA256 start key
436         try
437         {
438             uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
439             if ( !xFactory.is() )
440                 throw uno::RuntimeException();
441 
442             uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ), uno::UNO_QUERY_THROW );
443             uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
444 
445             ::rtl::OString aUTF8Password( ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) );
446             xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) );
447             uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose();
448 
449             aEncryptionData.realloc( ++nSha1Ind );
450             aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
451             aEncryptionData[0].Value <<= aDigest;
452         }
453         catch ( uno::Exception& )
454         {
455             OSL_ENSURE( false, "Can not create SHA256 digest!" );
456         }
457 
458         // MS_1252 encoding was used for SO60 document format password encoding,
459         // this encoding supports only a minor subset of nonascii characters,
460         // but for compatibility reasons it has to be used for old document formats
461         aEncryptionData.realloc( nSha1Ind + 2 );
462         aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
463         aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252;
464 
465         rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 };
466 
467         for ( sal_Int32 nInd = 0; nInd < 2; nInd++ )
468         {
469             ::rtl::OString aByteStrPass = ::rtl::OUStringToOString( aPassword, pEncoding[nInd] );
470 
471             sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1];
472             rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(),
473                                                     aByteStrPass.getLength(),
474                                                     pBuffer,
475                                                     RTL_DIGEST_LENGTH_SHA1 );
476 
477             if ( nError != rtl_Digest_E_None )
478             {
479                 aEncryptionData.realloc( nSha1Ind );
480                 break;
481             }
482 
483             aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
484         }
485     }
486 
487     return aEncryptionData;
488 }
489 
490 // ----------------------------------------------------------------------
491 sal_Bool OStorageHelper::IsValidZipEntryFileName( const ::rtl::OUString& aName, sal_Bool bSlashAllowed )
492 {
493     return IsValidZipEntryFileName( aName.getStr(), aName.getLength(), bSlashAllowed );
494 }
495 
496 // ----------------------------------------------------------------------
497 sal_Bool OStorageHelper::IsValidZipEntryFileName(
498     const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed )
499 {
500     for ( sal_Int32 i = 0; i < nLength; i++ )
501     {
502         switch ( pChar[i] )
503         {
504             case '\\':
505             case '?':
506             case '<':
507             case '>':
508             case '\"':
509             case '|':
510             case ':':
511                 return sal_False;
512             case '/':
513                 if ( !bSlashAllowed )
514                     return sal_False;
515                 break;
516             default:
517                 if ( pChar[i] < 32  || (pChar[i] >= 0xD800 && pChar[i] <= 0xDFFF) )
518                     return sal_False;
519         }
520     }
521     return sal_True;
522 }
523 
524 // ----------------------------------------------------------------------
525 sal_Bool OStorageHelper::PathHasSegment( const ::rtl::OUString& aPath, const ::rtl::OUString& aSegment )
526 {
527     sal_Bool bResult = sal_False;
528     const sal_Int32 nPathLen = aPath.getLength();
529     const sal_Int32 nSegLen = aSegment.getLength();
530 
531     if ( nSegLen && nPathLen >= nSegLen )
532     {
533         ::rtl::OUString aEndSegment( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
534         aEndSegment += aSegment;
535 
536         ::rtl::OUString aInternalSegment( aEndSegment );
537         aInternalSegment += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
538 
539         if ( aPath.indexOf( aInternalSegment ) >= 0 )
540             bResult = sal_True;
541 
542         if ( !bResult && !aPath.compareTo( aSegment, nSegLen ) )
543         {
544             if ( nPathLen == nSegLen || aPath.getStr()[nSegLen] == (sal_Unicode)'/' )
545                 bResult = sal_True;
546         }
547 
548         if ( !bResult && nPathLen > nSegLen && aPath.copy( nPathLen - nSegLen - 1, nSegLen + 1 ).equals( aEndSegment ) )
549             bResult = sal_True;
550     }
551 
552     return bResult;
553 }
554 
555 }
556 
557