[ooo-build-commit] Branch 'ooo/master' - filter/source oox/inc oox/prj oox/source oox/util writerfilter/source writerfilter/util

Jan Holesovsky kendy at kemper.freedesktop.org
Mon Sep 7 17:40:15 PDT 2009


 filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu          |    2 
 filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu |    2 
 oox/inc/oox/core/binarycodec.hxx                                          |   33 
 oox/inc/oox/core/binaryfilterbase.hxx                                     |    5 
 oox/inc/oox/core/filterbase.hxx                                           |   30 
 oox/inc/oox/core/filterdetect.hxx                                         |  168 +++
 oox/inc/oox/core/xmlfilterbase.hxx                                        |    9 
 oox/inc/oox/dump/dumperbase.hxx                                           |   50 
 oox/inc/oox/xls/biffcodec.hxx                                             |  111 --
 oox/inc/oox/xls/biffhelper.hxx                                            |    3 
 oox/inc/oox/xls/workbooksettings.hxx                                      |   19 
 oox/prj/build.lst                                                         |    2 
 oox/prj/d.lst                                                             |   23 
 oox/source/core/binarycodec.cxx                                           |   25 
 oox/source/core/binaryfilterbase.cxx                                      |   17 
 oox/source/core/filterbase.cxx                                            |  174 ++-
 oox/source/core/filterdetect.cxx                                          |  535 +++++++---
 oox/source/core/makefile.mk                                               |    4 
 oox/source/core/xmlfilterbase.cxx                                         |   53 
 oox/source/dump/biffdumper.cxx                                            |   84 +
 oox/source/dump/biffdumper.ini                                            |    5 
 oox/source/dump/dumperbase.cxx                                            |   55 -
 oox/source/dump/pptxdumper.cxx                                            |    4 
 oox/source/dump/xlsbdumper.cxx                                            |   10 
 oox/source/vml/vmlshape.cxx                                               |    2 
 oox/source/xls/biffcodec.cxx                                              |  289 ++---
 oox/source/xls/workbookfragment.cxx                                       |   64 -
 oox/source/xls/workbooksettings.cxx                                       |   45 
 oox/source/xls/worksheetsettings.cxx                                      |   15 
 oox/util/makefile.mk                                                      |   14 
 writerfilter/source/filter/ImportFilter.cxx                               |   42 
 writerfilter/util/makefile.mk                                             |    5 
 32 files changed, 1328 insertions(+), 571 deletions(-)

New commits:
commit 364b9042bcc8afd5984c0fad651fde88b7419531
Author: Oliver Bolte <obo at openoffice.org>
Date:   Mon Sep 7 14:41:16 2009 +0000

    CWS-TOOLING: integrate CWS dr72
    2009-08-26 10:24:00 +0200 dr  r275402 : #i92645# CODEPAGE is encrypted...
    2009-08-24 14:37:36 +0200 dr  r275316 : #i10000# enable exceptions for xlroot.cxx
    2009-08-24 14:33:15 +0200 dr  r275313 : #i10000# link openssl under solaris correctly
    2009-08-21 17:41:16 +0200 dr  r275267 : #i10000# unxlngi6 warning
    2009-08-21 15:35:56 +0200 dr  r275265 : #i10000# remove files again, already deleted in previous milestone...
    2009-08-21 11:24:57 +0200 dr  r275227 : #160401# port to DEV300
    2009-08-21 09:53:45 +0200 dr  r275221 : #i92645# full support for encrypted Word2007 files
    2009-08-21 09:50:52 +0200 dr  r275219 : #i92645# final changes for decryption
    2009-08-20 19:48:40 +0200 dr  r275195 : #i104370# missing parentheses, patch from cmc
    2009-08-20 18:28:22 +0200 dr  r275193 : #i92645# rework package decryption to repair 'Reload Document' functionality
    2009-08-20 13:55:14 +0200 dr  r275179 : #i92645# add new property names
    2009-08-19 19:24:21 +0200 dr  r275159 : #160401# open writeprotected files read-only, merged to DEV300
    2009-08-18 14:41:47 +0200 dr  r275109 : #i92645# add 'Aborted' property
    2009-08-18 11:20:34 +0200 dr  r275084 : #i92645# write back password to medium
    2009-08-17 17:52:51 +0200 dr  r275066 : #i92645# detect Word2007 docs with oox detection impl, this adds support of encryped Word2007; correct detection of templates and macro-enabled docs
    2009-08-17 17:51:31 +0200 dr  r275065 : #i92645# detect Word2007 docs with oox detection impl, this adds support of encryped Word2007; correct detection of templates and macro-enabled docs
    2009-08-17 11:06:39 +0200 dr  r275035 : #i92645# more password handling
    2009-08-17 11:05:21 +0200 dr  r275034 : #i92645# use new password input mechanism for BIFF filter and dumper in oox
    2009-08-14 16:33:53 +0200 nn  r274996 : #i104228# DelBroadcastAreasInRange: remove area from hash_set before deleting
    2009-08-14 16:27:12 +0200 nn  r274995 : #i104059# restore a change lost in the integration of fhawfixes1
    2009-08-14 16:24:00 +0200 dr  r274994 : #i92645# adapt BIFF import to latest changes
    2009-08-14 16:21:30 +0200 dr  r274993 : #i92645# adapt BIFF import to latest changes
    2009-08-14 16:20:43 +0200 dr  r274992 : #i92645# do not add default passwords to media descriptor
    2009-08-13 19:20:45 +0200 dr  r274965 : #i92645# add a helper to request a document password
    2009-08-13 19:09:35 +0200 dr  r274964 : #i92645# add a helper to request a document password
    2009-08-13 19:09:03 +0200 dr  r274963 : #i92645# add a helper to request a document password
    2009-08-13 14:35:01 +0200 dr  r274946 : #i92645# comment typo
    2009-08-13 14:33:47 +0200 dr  r274945 : #i92645# add a helper to request a document password
    2009-08-13 14:04:47 +0200 dr  r274941 : #i92645# add a helper to request a document password
    2009-08-13 14:04:22 +0200 dr  r274940 : #i92645# add a helper to request a document password
    2009-08-13 11:16:27 +0200 dr  r274927 : #i42303# show quick help if field name too long for button
    2009-08-13 10:55:48 +0200 dr  r274925 : #i31600# cut field name and add ellipsis, if too long for button
    2009-08-12 18:47:26 +0200 dr  r274914 : #i92645# ask user for a password
    2009-08-12 18:02:39 +0200 dr  r274909 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-12 16:59:11 +0200 dr  r274906 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-12 16:41:18 +0200 dr  r274905 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-12 16:40:33 +0200 dr  r274904 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-12 16:40:08 +0200 dr  r274903 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-12 16:39:30 +0200 dr  r274902 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-12 16:15:28 +0200 dr  r274899 : #i104183# move svtools/DocPasswordRequest to comphelper to be able to use it in oox
    2009-08-11 19:51:12 +0200 dr  r274877 : #i92645# open encrypted MSOOXML package protected with standard XL password 'VelvetSweatshop'

diff --git a/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu b/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu
index 9efffbe..53a7f5b 100644
--- a/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu
+++ b/filter/source/config/fragments/types/writer_MS_Word_2007_XML.xcu
@@ -1,5 +1,5 @@
     <node oor:name="writer_MS_Word_2007" oor:op="replace" >
-        <prop oor:name="DetectService"><value>com.sun.star.comp.Writer.WriterFilterDetector</value></prop>
+    <prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
         <prop oor:name="URLPattern"/>
         <prop oor:name="Extensions"><value>docx docm</value></prop>
         <prop oor:name="MediaType"><value>application/msword</value></prop>
diff --git a/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu b/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu
index 84e6525..c0ec682 100644
--- a/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu
+++ b/filter/source/config/fragments/types/writer_MS_Word_2007_XML_Template.xcu
@@ -1,5 +1,5 @@
     <node oor:name="writer_MS_Word_2007_Template" oor:op="replace" >
-        <prop oor:name="DetectService"><value>com.sun.star.comp.Writer.WriterFilterDetector</value></prop>
+    <prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
         <prop oor:name="URLPattern"/>
         <prop oor:name="Extensions"><value>dotx dotm</value></prop>
         <prop oor:name="MediaType"><value>application/msword</value></prop>
diff --git a/oox/inc/oox/core/binarycodec.hxx b/oox/inc/oox/core/binarycodec.hxx
index bb33c21..767b9c2 100644
--- a/oox/inc/oox/core/binarycodec.hxx
+++ b/oox/inc/oox/core/binarycodec.hxx
@@ -34,11 +34,26 @@
 #include <rtl/cipher.h>
 #include <rtl/digest.h>
 
+namespace oox { class AttributeList; }
+
 namespace oox {
 namespace core {
 
 // ============================================================================
 
+class CodecHelper
+{
+public:
+    /** Returns the password hash if it is in the required 16-bit limit. */
+    static sal_uInt16   getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement );
+
+private:
+                        CodecHelper();
+                        ~CodecHelper();
+};
+
+// ============================================================================
+
 /** Encodes and decodes data from/to protected MS Office documents.
 
     Implements a simple XOR encoding/decoding algorithm used in MS Office
@@ -182,12 +197,12 @@ public:
         @param pnPassData
             Unicode character array containing the password. Must be zero
             terminated, which results in a maximum length of 15 characters.
-        @param pnUnique
-            Unique document identifier read from or written to the file.
+        @param pnSalt
+            Random salt data block read from or written to the file.
      */
     void                initKey(
                             const sal_uInt16 pnPassData[ 16 ],
-                            const sal_uInt8 pnUnique[ 16 ] );
+                            const sal_uInt8 pnSalt[ 16 ] );
 
     /** Verifies the validity of the password using the passed salt data.
 
@@ -195,17 +210,17 @@ public:
             The codec must be initialized with the initKey() function before
             this function can be used.
 
-        @param pnSaltData
-            Salt data block read from the file.
-        @param pnSaltDigest
-            Salt digest read from the file.
+        @param pnVerifier
+            Verifier block read from the file.
+        @param pnVerifierHash
+            Verifier hash read from the file.
 
         @return
             True = test was successful.
      */
     bool                verifyKey(
-                            const sal_uInt8 pnSaltData[ 16 ],
-                            const sal_uInt8 pnSaltDigest[ 16 ] );
+                            const sal_uInt8 pnVerifier[ 16 ],
+                            const sal_uInt8 pnVerifierHash[ 16 ] );
 
     /** Rekeys the codec using the specified counter.
 
diff --git a/oox/inc/oox/core/binaryfilterbase.hxx b/oox/inc/oox/core/binaryfilterbase.hxx
index ce2c4f2..c051934 100644
--- a/oox/inc/oox/core/binaryfilterbase.hxx
+++ b/oox/inc/oox/core/binaryfilterbase.hxx
@@ -49,8 +49,9 @@ public:
 
 private:
     virtual StorageRef  implCreateStorage(
-                            ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
-                            ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const;
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const;
+    virtual StorageRef  implCreateStorage(
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const;
 };
 
 typedef ::rtl::Reference< BinaryFilterBase > BinaryFilterRef;
diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx
index 001b537..9115c88 100644
--- a/oox/inc/oox/core/filterbase.hxx
+++ b/oox/inc/oox/core/filterbase.hxx
@@ -44,7 +44,7 @@
 #include <cppuhelper/implbase5.hxx>
 #include "oox/helper/binarystreambase.hxx"
 #include "oox/helper/storagebase.hxx"
-#include <oox/dllapi.h>
+#include "oox/dllapi.h"
 
 namespace com { namespace sun { namespace star {
     namespace lang { class XMultiServiceFactory; }
@@ -58,6 +58,11 @@ namespace com { namespace sun { namespace star {
     namespace graphic { class XGraphic; }
 } } }
 
+namespace comphelper {
+    class IDocPasswordVerifier;
+    class MediaDescriptor;
+}
+
 namespace oox {
     class GraphicHelper;
     class ModelObjectHelper;
@@ -110,6 +115,9 @@ public:
     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
                         getGlobalFactory() const;
 
+    /** Returns the media descriptor. */
+    ::comphelper::MediaDescriptor& getMediaDescriptor() const;
+
     /** Returns the document model (always existing). */
     const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >&
                         getModel() const;
@@ -193,6 +201,10 @@ public:
     /** Returns a system color specified by the passed XML token identifier. */
     sal_Int32           getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb = -1 ) const;
 
+    /** Requests a password from the media descriptor or from the user. On
+        success, the password will be inserted into the media descriptor. */
+    ::rtl::OUString     requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const;
+
     /** Imports the raw binary data from the specified stream.
         @return  True, if the data could be imported from the stream. */
     bool                importBinaryData( StreamDataSequence& orDataSeq, const ::rtl::OUString& rStreamName );
@@ -251,19 +263,29 @@ public:
     // com.sun.star.document.XFilter interface --------------------------------
 
     virtual sal_Bool SAL_CALL filter(
-                            const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rDescriptor )
+                            const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq )
                             throw( ::com::sun::star::uno::RuntimeException );
 
     virtual void SAL_CALL cancel()
                             throw( ::com::sun::star::uno::RuntimeException );
 
     // ------------------------------------------------------------------------
+protected:
+    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+                        implGetInputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >
+                        implGetOutputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+
 private:
+    void                setMediaDescriptor(
+                            const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq );
+
     virtual ::rtl::OUString implGetImplementationName() const = 0;
 
     virtual StorageRef  implCreateStorage(
-                            ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
-                            ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const = 0;
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const = 0;
+    virtual StorageRef  implCreateStorage(
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const = 0;
 
 private:
     ::std::auto_ptr< FilterBaseImpl > mxImpl;
diff --git a/oox/inc/oox/core/filterdetect.hxx b/oox/inc/oox/core/filterdetect.hxx
new file mode 100644
index 0000000..bd9e3a8
--- /dev/null
+++ b/oox/inc/oox/core/filterdetect.hxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: filterdetect.hxx,v $
+ * $Revision: 1.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef OOX_CORE_FILTERDETECT_HXX
+#define OOX_CORE_FILTERDETECT_HXX
+
+#include <vector>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+    namespace io { class XInputStream; }
+} } }
+
+namespace comphelper { class MediaDescriptor; }
+namespace oox { class AttributeList; }
+
+namespace oox {
+namespace core {
+
+// ============================================================================
+
+/** Document handler specifically designed for detecting OOXML file formats.
+
+    It takes a reference to the filter string object via its constructor, and
+    puts the name of the detected filter to it, if it successfully finds one.
+ */
+class FilterDetectDocHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastDocumentHandler >
+{
+public:
+    explicit            FilterDetectDocHandler( ::rtl::OUString& rFilter );
+    virtual             ~FilterDetectDocHandler();
+
+    // XFastDocumentHandler
+    virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+    // XFastContextHandler
+    virtual void SAL_CALL startFastElement( sal_Int32 nElement, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual ::com::sun::star::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual ::com::sun::star::uno::Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+
+private:
+    void                parseRelationship( const AttributeList& rAttribs );
+
+    ::rtl::OUString     getFilterNameFromContentType( const ::rtl::OUString& rContentType ) const;
+    void                parseContentTypesDefault( const AttributeList& rAttribs );
+    void                parseContentTypesOverride( const AttributeList& rAttribs );
+
+private:
+    typedef ::std::vector< sal_Int32 > ContextVector;
+
+    ::rtl::OUString&    mrFilterName;
+    ContextVector       maContextStack;
+    ::rtl::OUString     maTargetPath;
+};
+
+// ============================================================================
+
+class OOX_DLLPUBLIC FilterDetect : public ::cppu::WeakImplHelper2< ::com::sun::star::document::XExtendedFilterDetection, ::com::sun::star::lang::XServiceInfo >
+{
+public:
+    explicit            FilterDetect( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
+    virtual             ~FilterDetect();
+
+    /** Tries to extract an unencrypted ZIP package from the passed media
+        descriptor.
+
+        First, this function checks if the input stream provided by the media
+        descriptor property 'InputStream' contains a ZIP package. If yes, this
+        stream is returned.
+
+        Second, this function checks if the 'ComponentData' property exists and
+        contains a sequence of com.sun.star.beans.NamedValue. If yes, a named
+        value is searched with the name 'DecryptedPackage' and a value of type
+        com.sun.star.io.XStream. If the input stream provided by this XStream
+        contains a ZIP package, this input stream is returned.
+
+        Third, this function checks if the input stream of the media descriptor
+        contains an OLE package. If yes, it checks the existence of the streams
+        'EncryptionInfo' and 'EncyptedPackage' and tries to decrypt the package
+        into a temporary file. This may include requesting a password from the
+        media descriptor property 'Password' or from the user, using the
+        interaction handler provided by the descriptor. On success, and if the
+        decrypted package is a ZIP package, the XStream of the temporary file
+        is stored in the property 'ComponentData' of the media descriptor and
+        its input stream is returned.
+     */
+    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+                        extractUnencryptedPackage( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+
+    // com.sun.star.lang.XServiceInfo interface -------------------------------
+
+    virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName ) throw( ::com::sun::star::uno::RuntimeException );
+    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
+
+    // com.sun.star.document.XExtendedFilterDetection interface ---------------
+
+    /** Detects MS Office 2007 file types and supports package decryption.
+
+        The following file types are detected:
+        - MS Word 2007 XML Document (*.docx, *.docm)
+        - MS Word 2007 XML Template (*.dotx, *.dotm)
+        - MS Excel 2007 XML Document (*.xlsx, *.xlsm)
+        - MS Excel 2007 BIFF12 Document (*.xlsb)
+        - MS Excel 2007 XML Template (*.xltx, *.xltm)
+        - MS Powerpoint 2007 XML Document (*.pptx, *.pptm)
+        - MS Powerpoint 2007 XML Template (*.potx, *.potm)
+
+        If the package is encrypted, the detection tries to decrypt it into a
+        temporary file. The user may be asked for a password. The XStream
+        interface of the temporary file will be stored in the 'ComponentData'
+        property of the passed media descriptor.
+     */
+    virtual ::rtl::OUString SAL_CALL detect(
+                            ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rMediaDescSeq )
+                            throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxFactory;
+};
+
+// ============================================================================
+
+} // namespace core
+} // namespace oox
+
+#endif
+
diff --git a/oox/inc/oox/core/xmlfilterbase.hxx b/oox/inc/oox/core/xmlfilterbase.hxx
index f885544..d1b79dc 100644
--- a/oox/inc/oox/core/xmlfilterbase.hxx
+++ b/oox/inc/oox/core/xmlfilterbase.hxx
@@ -204,10 +204,15 @@ public:
      */
     XmlFilterBase& exportDocumentProperties( ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > xProperties );
 
+protected:
+    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
+                        implGetInputStream( ::comphelper::MediaDescriptor& rMediaDesc ) const;
+
 private:
     virtual StorageRef  implCreateStorage(
-                            ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
-                            ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const;
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream ) const;
+    virtual StorageRef  implCreateStorage(
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const;
 
 private:
     ::std::auto_ptr< XmlFilterBaseImpl > mxImpl;
diff --git a/oox/inc/oox/dump/dumperbase.hxx b/oox/inc/oox/dump/dumperbase.hxx
index 0c5314c..9a79194 100644
--- a/oox/inc/oox/dump/dumperbase.hxx
+++ b/oox/inc/oox/dump/dumperbase.hxx
@@ -41,6 +41,7 @@
 #include <rtl/ustrbuf.hxx>
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/util/DateTime.hpp>
+#include <comphelper/mediadescriptor.hxx>
 #include "oox/helper/helper.hxx"
 #include "oox/helper/storagebase.hxx"
 #include "oox/helper/binaryinputstream.hxx"
@@ -57,6 +58,10 @@ namespace com { namespace sun { namespace star {
     namespace lang { class XMultiServiceFactory; }
 } } }
 
+namespace comphelper {
+    class IDocPasswordVerifier;
+}
+
 namespace oox {
     class BinaryOutputStream;
 }
@@ -866,7 +871,8 @@ public:
                             const ::rtl::OUString& rFileName,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                             const StorageRef& rxRootStrg,
-                            const ::rtl::OUString& rSysFileName );
+                            const ::rtl::OUString& rSysFileName,
+                            ::comphelper::MediaDescriptor& rMediaDesc );
 
     virtual             ~SharedConfigData();
 
@@ -883,6 +889,9 @@ public:
     void                eraseNameList( const ::rtl::OUString& rListName );
     NameListRef         getNameList( const ::rtl::OUString& rListName ) const;
 
+    ::rtl::OUString     requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier );
+    inline bool         isPasswordCancelled() const { return mbPwCancelled; }
+
 protected:
     virtual bool        implIsValid() const;
     virtual void        implProcessConfigItemStr(
@@ -905,11 +914,13 @@ private:
     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxFactory;
     StorageRef          mxRootStrg;
     ::rtl::OUString     maSysFileName;
+    ::comphelper::MediaDescriptor& mrMediaDesc;
     ConfigFileSet       maConfigFiles;
     ConfigDataMap       maConfigData;
     NameListMap         maNameLists;
     ::rtl::OUString     maConfigPath;
     bool                mbLoaded;
+    bool                mbPwCancelled;
 };
 
 // ----------------------------------------------------------------------------
@@ -947,7 +958,8 @@ public:
                             const sal_Char* pcEnvVar,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                             const StorageRef& rxRootStrg,
-                            const ::rtl::OUString& rSysFileName );
+                            const ::rtl::OUString& rSysFileName,
+                            ::comphelper::MediaDescriptor& rMediaDesc );
 
     virtual             ~Config();
 
@@ -978,6 +990,9 @@ public:
     template< typename Type >
     bool                hasName( const NameListWrapper& rListWrp, Type nKey ) const;
 
+    ::rtl::OUString     requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier );
+    bool                isPasswordCancelled() const;
+
 protected:
     inline explicit     Config() {}
     void                construct( const Config& rParent );
@@ -988,7 +1003,8 @@ protected:
                             const sal_Char* pcEnvVar,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                             const StorageRef& rxRootStrg,
-                            const ::rtl::OUString& rSysFileName );
+                            const ::rtl::OUString& rSysFileName,
+                            ::comphelper::MediaDescriptor& rMediaDesc );
 
     virtual bool        implIsValid() const;
     virtual const ::rtl::OUString* implGetOption( const ::rtl::OUString& rKey ) const;
@@ -1822,11 +1838,6 @@ class RecordObjectBase : public InputObjectBase
 protected:
     inline explicit     RecordObjectBase() {}
 
-    inline sal_Int64    getRecPos() const { return mnRecPos; }
-    inline sal_Int64    getRecId() const { return mnRecId; }
-    inline sal_Int64    getRecSize() const { return mnRecSize; }
-    inline NameListRef  getRecNames() const { return maRecNames.getNameList( cfg() ); }
-
     using               InputObjectBase::construct;
     void                construct(
                             const ObjectBase& rParent,
@@ -1842,6 +1853,14 @@ protected:
                             const String& rRecNames,
                             const String& rSimpleRecs = EMPTY_STRING );
 
+    inline sal_Int64    getRecPos() const { return mnRecPos; }
+    inline sal_Int64    getRecId() const { return mnRecId; }
+    inline sal_Int64    getRecSize() const { return mnRecSize; }
+    inline NameListRef  getRecNames() const { return maRecNames.getNameList( cfg() ); }
+
+    inline void         setBinaryOnlyMode( bool bBinaryOnly ) { mbBinaryOnly = bBinaryOnly; }
+    inline bool         isBinaryOnlyMode() const { return mbBinaryOnly; }
+
     virtual bool        implIsValid() const;
     virtual void        implDump();
 
@@ -1865,6 +1884,7 @@ private:
     sal_Int64           mnRecId;
     sal_Int64           mnRecSize;
     bool                mbShowRecPos;
+    bool                mbBinaryOnly;
 };
 
 // ============================================================================
@@ -1922,6 +1942,7 @@ public:
     virtual             ~DumperBase();
 
     bool                isImportEnabled() const;
+    bool                isImportCancelled() const;
 
 protected:
     inline explicit     DumperBase() {}
@@ -1936,12 +1957,13 @@ protected:
 } // namespace dump
 } // namespace oox
 
-#define OOX_DUMP_FILE( DumperClassName )    \
-do {                                        \
-    DumperClassName aDumper( *this );       \
-    aDumper.dump();                         \
-    if( !aDumper.isImportEnabled() )        \
-        return aDumper.isValid();           \
+#define OOX_DUMP_FILE( DumperClassName )            \
+do {                                                \
+    DumperClassName aDumper( *this );               \
+    aDumper.dump();                                 \
+    bool bCancelled = aDumper.isImportCancelled();  \
+    if( !aDumper.isImportEnabled() || bCancelled )  \
+        return aDumper.isValid() && !bCancelled;    \
 } while( false )
 
 #else   // OOX_INCLUDE_DUMPER
diff --git a/oox/inc/oox/xls/biffcodec.hxx b/oox/inc/oox/xls/biffcodec.hxx
index 165a608..3fc5d77 100644
--- a/oox/inc/oox/xls/biffcodec.hxx
+++ b/oox/inc/oox/xls/biffcodec.hxx
@@ -32,6 +32,7 @@
 #define OOX_XLS_BIFFCODEC_HXX
 
 #include <vector>
+#include <comphelper/docpasswordhelper.hxx>
 #include "oox/core/binarycodec.hxx"
 #include "oox/xls/workbookhelper.hxx"
 
@@ -40,29 +41,27 @@ namespace xls {
 
 // ============================================================================
 
-const sal_Int32 CODEC_OK                    = 0;
-const sal_Int32 CODEC_ERROR_WRONG_PASS      = 1;
-const sal_Int32 CODEC_ERROR_UNSUPP_CRYPT    = 2;
-
 const sal_Int64 BIFF_RCF_BLOCKSIZE          = 1024;
 
 // ============================================================================
 
 /** Base class for BIFF stream decoders. */
-class BiffDecoderBase : public WorkbookHelper
+class BiffDecoderBase : public ::comphelper::IDocPasswordVerifier
 {
 public:
-    explicit            BiffDecoderBase( const WorkbookHelper& rHelper );
+    explicit            BiffDecoderBase();
     virtual             ~BiffDecoderBase();
 
     /** Derived classes return a clone of the decoder for usage in new streams. */
     inline BiffDecoderBase* clone() { return implClone(); }
 
-    /** Returns the current error code of the decoder. */
-    inline sal_Int32    getErrorCode() const { return mnError; }
-    /** Returns true, if the decoder has been constructed successfully.
-        This means especially that construction happened with a valid password. */
-    inline bool         isValid() const { return mnError == CODEC_OK; }
+    /** Implementation of the ::comphelper::IDocPasswordVerifier interface,
+        calls the new virtual function implVerify(). */
+    virtual ::comphelper::DocPasswordVerifierResult
+                        verifyPassword( const ::rtl::OUString& rPassword );
+
+    /** Returns true, if the decoder has been initialized correctly. */
+    inline bool         isValid() const { return mbValid; }
 
     /** Decodes nBytes bytes and writes encrypted data into the buffer pnDestData. */
     void                decode(
@@ -71,17 +70,14 @@ public:
                             sal_Int64 nStreamPos,
                             sal_uInt16 nBytes );
 
-protected:
-    /** Copy constructor for cloning. */
-                        BiffDecoderBase( const BiffDecoderBase& rDecoder );
-
-    /** Sets the decoder to a state showing whether the password was correct. */
-    void                setHasValidPassword( bool bValid );
-
 private:
     /** Derived classes return a clone of the decoder for usage in new streams. */
     virtual BiffDecoderBase* implClone() = 0;
 
+    /** Derived classes implement password verification and initialization of
+        the decoder. */
+    virtual bool        implVerify( const ::rtl::OUString& rPassword ) = 0;
+
     /** Implementation of decryption of a memory block. */
     virtual void        implDecode(
                             sal_uInt8* pnDestData,
@@ -90,7 +86,7 @@ private:
                             sal_uInt16 nBytes ) = 0;
 
 private:
-    sal_Int32           mnError;        /// Decoder error code.
+    bool                mbValid;        /// True = decoder is correctly initialized.
 };
 
 typedef ::boost::shared_ptr< BiffDecoderBase > BiffDecoderRef;
@@ -101,31 +97,18 @@ typedef ::boost::shared_ptr< BiffDecoderBase > BiffDecoderRef;
 class BiffDecoder_XOR : public BiffDecoderBase
 {
 public:
-    /** Constructs the decoder.
-
-        Checks if the passed key and hash specify workbook protection. Asks for
-        a password otherwise.
-
-        @param nKey
-            Password key from FILEPASS record to verify password.
-        @param nHash
-            Password hash value from FILEPASS record to verify password.
-     */
-    explicit            BiffDecoder_XOR(
-                            const WorkbookHelper& rHelper,
-                            sal_uInt16 nKey, sal_uInt16 nHash );
+    explicit            BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash );
 
 private:
     /** Copy constructor for cloning. */
                         BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder );
 
-    /** Initializes the wrapped codec object. After that, internal status can
-        be querried with isValid(). */
-    void                init( const ::rtl::OString& rPass );
-
     /** Returns a clone of the decoder for usage in new streams. */
     virtual BiffDecoder_XOR* implClone();
 
+    /** Implements password verification and initialization of the decoder. */
+    virtual bool        implVerify( const ::rtl::OUString& rPassword );
+
     /** Implementation of decryption of a memory block. */
     virtual void        implDecode(
                             sal_uInt8* pnDestData,
@@ -135,7 +118,7 @@ private:
 
 private:
     ::oox::core::BinaryCodec_XOR maCodec;   /// Cipher algorithm implementation.
-    ::rtl::OString      maPass;
+    ::std::vector< sal_uInt8 > maPassword;
     sal_uInt16          mnKey;
     sal_uInt16          mnHash;
 };
@@ -146,35 +129,21 @@ private:
 class BiffDecoder_RCF : public BiffDecoderBase
 {
 public:
-    /** Constructs the decoder.
-
-        Checks if the passed salt data specifies workbook protection. Asks for
-        a password otherwise.
-
-        @param pnDocId
-            Unique document identifier from FILEPASS record.
-        @param pnSaltData
-            Salt data from FILEPASS record.
-        @param pnSaltHash
-            Salt hash value from FILEPASS record.
-     */
     explicit            BiffDecoder_RCF(
-                            const WorkbookHelper& rHelper,
-                            sal_uInt8 pnDocId[ 16 ],
-                            sal_uInt8 pnSaltData[ 16 ],
-                            sal_uInt8 pnSaltHash[ 16 ] );
+                            sal_uInt8 pnSalt[ 16 ],
+                            sal_uInt8 pnVerifier[ 16 ],
+                            sal_uInt8 pnVerifierHash[ 16 ] );
 
 private:
     /** Copy constructor for cloning. */
                         BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder );
 
-    /** Initializes the wrapped codec object. After that, internal status can
-        be querried with isValid(). */
-    void                init( const ::rtl::OUString& rPass );
-
     /** Returns a clone of the decoder for usage in new streams. */
     virtual BiffDecoder_RCF* implClone();
 
+    /** Implements password verification and initialization of the decoder. */
+    virtual bool        implVerify( const ::rtl::OUString& rPassword );
+
     /** Implementation of decryption of a memory block. */
     virtual void        implDecode(
                             sal_uInt8* pnDestData,
@@ -184,10 +153,10 @@ private:
 
 private:
     ::oox::core::BinaryCodec_RCF maCodec;   /// Cipher algorithm implementation.
-    ::rtl::OUString     maPass;
-    ::std::vector< sal_uInt8 > maDocId;
-    ::std::vector< sal_uInt8 > maSaltData;
-    ::std::vector< sal_uInt8 > maSaltHash;
+    ::std::vector< sal_uInt16 > maPassword;
+    ::std::vector< sal_uInt8 > maSalt;
+    ::std::vector< sal_uInt8 > maVerifier;
+    ::std::vector< sal_uInt8 > maVerifierHash;
 };
 
 // ============================================================================
@@ -198,30 +167,16 @@ class BiffCodecHelper : public WorkbookHelper
 public:
     explicit            BiffCodecHelper( const WorkbookHelper& rHelper );
 
-    /** Returns the fixed password for workbook protection. */
-    static const ::rtl::OString& getBiff5WbProtPassword();
-    /** Returns the fixed password for workbook protection. */
-    static const ::rtl::OUString& getBiff8WbProtPassword();
+    /** Implementation helper, reads the FILEPASS and returns a decoder object. */
+    static BiffDecoderRef implReadFilePass( BiffInputStream& rStrm, BiffType eBiff );
 
-    /** Looks for a password provided via API, or queries it via GUI. */
-    ::rtl::OUString     queryPassword();
-
-    /** Imports the FILEPASS record and sets a decoder at the stream. */
+    /** Imports the FILEPASS record, asks for a password and sets a decoder at the stream. */
     bool                importFilePass( BiffInputStream& rStrm );
     /** Clones the contained decoder object if existing and sets it at the passed stream. */
     void                cloneDecoder( BiffInputStream& rStrm );
 
 private:
-    void                importFilePass_XOR( BiffInputStream& rStrm );
-    void                importFilePass_RCF( BiffInputStream& rStrm );
-    void                importFilePass_Strong( BiffInputStream& rStrm );
-    void                importFilePass2( BiffInputStream& rStrm );
-    void                importFilePass8( BiffInputStream& rStrm );
-
-private:
     BiffDecoderRef      mxDecoder;          /// The decoder for import filter.
-    ::rtl::OUString     maPassword;         /// Password for stream encoder/decoder.
-    bool                mbHasPassword;      /// True = password already querried.
 };
 
 // ============================================================================
diff --git a/oox/inc/oox/xls/biffhelper.hxx b/oox/inc/oox/xls/biffhelper.hxx
index 8d9aac7..1da2c36 100644
--- a/oox/inc/oox/xls/biffhelper.hxx
+++ b/oox/inc/oox/xls/biffhelper.hxx
@@ -120,6 +120,7 @@ const sal_Int32 OOBIN_ID_EXTROW             = 0x016E;
 const sal_Int32 OOBIN_ID_EXTSHEETDATA       = 0x016B;
 const sal_Int32 OOBIN_ID_EXTERNALNAMEFLAGS  = 0x024A;
 const sal_Int32 OOBIN_ID_EXTSHEETNAMES      = 0x0167;
+const sal_Int32 OOBIN_ID_FILESHARING        = 0x0224;
 const sal_Int32 OOBIN_ID_FILEVERSION        = 0x0080;
 const sal_Int32 OOBIN_ID_FILL               = 0x002D;
 const sal_Int32 OOBIN_ID_FILLS              = 0x025B;
@@ -369,6 +370,7 @@ const sal_uInt16 BIFF5_ID_EXTERNALNAME      = 0x0023;
 const sal_uInt16 BIFF_ID_EXTERNSHEET        = 0x0017;
 const sal_uInt16 BIFF_ID_EXTSST             = 0x00FF;
 const sal_uInt16 BIFF_ID_FILEPASS           = 0x002F;
+const sal_uInt16 BIFF_ID_FILESHARING        = 0x005B;
 const sal_uInt16 BIFF2_ID_FONT              = 0x0031;
 const sal_uInt16 BIFF3_ID_FONT              = 0x0231;
 const sal_uInt16 BIFF5_ID_FONT              = 0x0031;
@@ -388,6 +390,7 @@ const sal_uInt16 BIFF_ID_HYPERLINK          = 0x01B8;
 const sal_uInt16 BIFF3_ID_IMGDATA           = 0x007F;
 const sal_uInt16 BIFF8_ID_IMGDATA           = 0x00E9;
 const sal_uInt16 BIFF2_ID_INTEGER           = 0x0002;
+const sal_uInt16 BIFF_ID_INTERFACEHDR       = 0x00E1;
 const sal_uInt16 BIFF_ID_ITERATION          = 0x0011;
 const sal_uInt16 BIFF_ID_IXFE               = 0x0044;
 const sal_uInt16 BIFF2_ID_LABEL             = 0x0004;
diff --git a/oox/inc/oox/xls/workbooksettings.hxx b/oox/inc/oox/xls/workbooksettings.hxx
index 683747c..81712bd 100644
--- a/oox/inc/oox/xls/workbooksettings.hxx
+++ b/oox/inc/oox/xls/workbooksettings.hxx
@@ -40,6 +40,18 @@ namespace xls {
 
 // ============================================================================
 
+/** Settings for workbook write protection. */
+struct FileSharingModel
+{
+    ::rtl::OUString     maUserName;             /// User who added the write protection password.
+    sal_uInt16          mnPasswordHash;         /// Hash value of the write protection password.
+    bool                mbRecommendReadOnly;    /// True = recommend read-only mode on opening.
+
+    explicit            FileSharingModel();
+};
+
+// ============================================================================
+
 /** Global workbook settings. */
 struct WorkbookSettingsModel
 {
@@ -84,11 +96,15 @@ class WorkbookSettings : public WorkbookHelper
 public:
     explicit            WorkbookSettings( const WorkbookHelper& rHelper );
 
+    /** Imports the fileSharing element containing write protection settings. */
+    void                importFileSharing( const AttributeList& rAttribs );
     /** Imports the workbookPr element containing global workbook settings. */
     void                importWorkbookPr( const AttributeList& rAttribs );
     /** Imports the calcPr element containing workbook calculation settings. */
     void                importCalcPr( const AttributeList& rAttribs );
 
+    /** Imports the FILESHARING record containing write protection settings. */
+    void                importFileSharing( RecordInputStream& rStrm );
     /** Imports the WORKBOOKPR record containing global workbook settings. */
     void                importWorkbookPr( RecordInputStream& rStrm );
     /** Imports the CALCPR record containing workbook calculation settings. */
@@ -96,6 +112,8 @@ public:
 
     /** Sets the save external linked values flag, e.g. from the WSBOOL record. */
     void                setSaveExtLinkValues( bool bSaveExtLinks );
+    /** Imports the FILESHARING record. */
+    void                importFileSharing( BiffInputStream& rStrm );
     /** Imports the BOOKBOOL record. */
     void                importBookBool( BiffInputStream& rStrm );
     /** Imports the CALCCOUNT record. */
@@ -136,6 +154,7 @@ private:
     void                setDateMode( bool bDateMode1904 );
 
 private:
+    FileSharingModel    maFileSharing;
     WorkbookSettingsModel maBookSettings;
     CalcSettingsModel   maCalcSettings;
 };
diff --git a/oox/prj/build.lst b/oox/prj/build.lst
index b95c5cb..a1dfa58 100644
--- a/oox/prj/build.lst
+++ b/oox/prj/build.lst
@@ -1,4 +1,4 @@
-oox	oox : vos cppu cppuhelper comphelper sal offapi sax basegfx tools vcl BOOST:boost NULL
+oox	oox : vos cppu cppuhelper comphelper sal offapi sax basegfx tools vcl BOOST:boost OPENSSL:openssl NULL
 oox	oox				usr1	-   all	oox_mkout NULL
 oox	oox\prj				get	-   all	oox_prj NULL
 oox	oox\source\token		nmake	-   all	oox_token NULL
diff --git a/oox/prj/d.lst b/oox/prj/d.lst
index df4430b..50ec059 100644
--- a/oox/prj/d.lst
+++ b/oox/prj/d.lst
@@ -1,10 +1,10 @@
 mkdir: %_DEST%\inc%_EXT%\oox
-mkdir: %_DEST%\inc%_EXT%\oox\core
 mkdir: %_DEST%\inc%_EXT%\oox\helper
-mkdir: %_DEST%\inc%_EXT%\oox\vml
+mkdir: %_DEST%\inc%_EXT%\oox\core
 mkdir: %_DEST%\inc%_EXT%\oox\drawingml
 mkdir: %_DEST%\inc%_EXT%\oox\drawingml\chart
 mkdir: %_DEST%\inc%_EXT%\oox\drawingml\table
+mkdir: %_DEST%\inc%_EXT%\oox\vml
 
 ..\%__SRC%\misc\*.map %_DEST%\bin%_EXT%\*.map
 ..\%__SRC%\lib\ixo.lib %_DEST%\lib%_EXT%\ixo.lib
@@ -13,23 +13,24 @@ mkdir: %_DEST%\inc%_EXT%\oox\drawingml\table
 ..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.dll
 ..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%\lib*.so
 ..\%__SRC%\lib\i*.lib %_DEST%\lib%_EXT%\i*.lib
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
 
-..\inc\oox\dllapi.h %_DEST%\inc%_EXT%\oox\dllapi.h
-..\source\token\tokens.txt %_DEST%\inc%_EXT%\oox\token.txt
-..\inc\oox\core\filterbase.hxx %_DEST%\inc%_EXT%\oox\core\filterbase.hxx
-..\inc\oox\core\relations.hxx %_DEST%\inc%_EXT%\oox\core\relations.hxx
 ..\%__SRC%\inc\tokens.hxx %_DEST%\inc%_EXT%\oox\core\tokens.hxx
-..\inc\oox\core\xmlfilterbase.hxx %_DEST%\inc%_EXT%\oox\core\xmlfilterbase.hxx
+
+..\source\token\tokens.txt %_DEST%\inc%_EXT%\oox\token.txt
+..\inc\oox\dllapi.h %_DEST%\inc%_EXT%\oox\dllapi.h
 ..\inc\oox\helper\binarystreambase.hxx %_DEST%\inc%_EXT%\oox\helper\binarystreambase.hxx
 ..\inc\oox\helper\helper.hxx %_DEST%\inc%_EXT%\oox\helper\helper.hxx
 ..\inc\oox\helper\storagebase.hxx %_DEST%\inc%_EXT%\oox\helper\storagebase.hxx
 ..\inc\oox\helper\zipstorage.hxx %_DEST%\inc%_EXT%\oox\helper\zipstorage.hxx
-..\inc\oox\vml\drawing.hxx %_DEST%\inc%_EXT%\oox\vml\drawing.hxx
+..\inc\oox\core\filterbase.hxx %_DEST%\inc%_EXT%\oox\core\filterbase.hxx
+..\inc\oox\core\filterdetect.hxx %_DEST%\inc%_EXT%\oox\core\filterdetect.hxx
+..\inc\oox\core\relations.hxx %_DEST%\inc%_EXT%\oox\core\relations.hxx
+..\inc\oox\core\xmlfilterbase.hxx %_DEST%\inc%_EXT%\oox\core\xmlfilterbase.hxx
 ..\inc\oox\drawingml\chart\chartconverter.hxx %_DEST%\inc%_EXT%\oox\drawingml\chart\chartconverter.hxx
 ..\inc\oox\drawingml\table\tablestylelist.hxx %_DEST%\inc%_EXT%\oox\drawingml\table\tablestylelist.hxx
-..\inc\oox\vml\shape.hxx %_DEST%\inc%_EXT%\oox\vml\shape.hxx
-
-..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\inc\oox\vml\vmldrawing.hxx %_DEST%\inc%_EXT%\oox\vml\vmldrawing.hxx
+..\inc\oox\vml\vmlshape.hxx %_DEST%\inc%_EXT%\oox\vml\vmlshape.hxx
 
 dos: sh -c "if test %OS% = MACOSX; then create-bundle %_DEST%\lib%_EXT%\*.dylib; fi"
 
diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx
index 6e465fb..b6a7e92 100644
--- a/oox/source/core/binarycodec.cxx
+++ b/oox/source/core/binarycodec.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -31,7 +31,7 @@
 #include "oox/core/binarycodec.hxx"
 #include <algorithm>
 #include <string.h>
-#include <osl/diagnose.h>
+#include "oox/helper/attributelist.hxx"
 
 namespace oox {
 namespace core {
@@ -113,6 +113,15 @@ sal_uInt16 lclGetHash( const sal_uInt8* pnPassData, sal_Int32 nBufferSize )
 
 // ============================================================================
 
+/*static*/ sal_uInt16 CodecHelper::getPasswordHash( const AttributeList& rAttribs, sal_Int32 nElement )
+{
+    sal_Int32 nPasswordHash = rAttribs.getIntegerHex( nElement, 0 );
+    OSL_ENSURE( (0 <= nPasswordHash) && (nPasswordHash <= SAL_MAX_UINT16), "CodecHelper::getPasswordHash - invalid password hash" );
+    return static_cast< sal_uInt16 >( ((0 <= nPasswordHash) && (nPasswordHash <= SAL_MAX_UINT16)) ? nPasswordHash : 0 );
+}
+
+// ============================================================================
+
 BinaryCodec_XOR::BinaryCodec_XOR( CodecType eCodecType ) :
     meCodecType( eCodecType ),
     mnOffset( 0 ),
@@ -249,7 +258,7 @@ BinaryCodec_RCF::~BinaryCodec_RCF()
     rtl_cipher_destroy( mhCipher );
 }
 
-void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnUnique[ 16 ] )
+void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt8 pnSalt[ 16 ] )
 {
     // create little-endian key data array from password data
     sal_uInt8 pnKeyData[ 64 ];
@@ -271,11 +280,11 @@ void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt
     (void)rtl_digest_updateMD5( mhDigest, pnKeyData, sizeof( pnKeyData ) );
     (void)rtl_digest_rawMD5( mhDigest, pnKeyData, RTL_DIGEST_LENGTH_MD5 );
 
-    // update digest with key data and passed unique data
+    // update digest with key data and passed salt data
     for( size_t nIndex = 0; nIndex < 16; ++nIndex )
     {
         rtl_digest_updateMD5( mhDigest, pnKeyData, 5 );
-        rtl_digest_updateMD5( mhDigest, pnUnique, 16 );
+        rtl_digest_updateMD5( mhDigest, pnSalt, 16 );
     }
 
     // update digest with padding
@@ -292,7 +301,7 @@ void BinaryCodec_RCF::initKey( const sal_uInt16 pnPassData[ 16 ], const sal_uInt
     (void)memset( pnKeyData, 0, sizeof( pnKeyData ) );
 }
 
-bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uInt8 pnSaltDigest[ 16 ] )
+bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnVerifier[ 16 ], const sal_uInt8 pnVerifierHash[ 16 ] )
 {
     if( !startBlock( 0 ) )
         return false;
@@ -301,7 +310,7 @@ bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uIn
     sal_uInt8 pnBuffer[ 64 ];
 
     // decode salt data into buffer
-    rtl_cipher_decode( mhCipher, pnSaltData, 16, pnBuffer, sizeof( pnBuffer ) );
+    rtl_cipher_decode( mhCipher, pnVerifier, 16, pnBuffer, sizeof( pnBuffer ) );
 
     pnBuffer[ 16 ] = 0x80;
     (void)memset( pnBuffer + 17, 0, sizeof( pnBuffer ) - 17 );
@@ -312,7 +321,7 @@ bool BinaryCodec_RCF::verifyKey( const sal_uInt8 pnSaltData[ 16 ], const sal_uIn
     rtl_digest_rawMD5( mhDigest, pnDigest, sizeof( pnDigest ) );
 
     // decode original salt digest into buffer
-    rtl_cipher_decode( mhCipher, pnSaltDigest, 16, pnBuffer, sizeof( pnBuffer ) );
+    rtl_cipher_decode( mhCipher, pnVerifierHash, 16, pnBuffer, sizeof( pnBuffer ) );
 
     // compare buffer with computed digest
     bool bResult = memcmp( pnBuffer, pnDigest, sizeof( pnDigest ) ) == 0;
diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx
index 86e8931..c883284 100644
--- a/oox/source/core/binaryfilterbase.cxx
+++ b/oox/source/core/binaryfilterbase.cxx
@@ -51,15 +51,16 @@ BinaryFilterBase::~BinaryFilterBase()
 {
 }
 
-StorageRef BinaryFilterBase::implCreateStorage(
-        Reference< XInputStream >& rxInStream, Reference< XStream >& rxOutStream ) const
+// private --------------------------------------------------------------------
+
+StorageRef BinaryFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
+{
+    return StorageRef( new OleStorage( getGlobalFactory(), rxInStream, true ) );
+}
+
+StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
 {
-    StorageRef xStorage;
-    if( rxInStream.is() )
-        xStorage.reset( new OleStorage( getGlobalFactory(), rxInStream, true ) );
-    else if( rxOutStream.is() )
-        xStorage.reset( new OleStorage( getGlobalFactory(), rxOutStream, true ) );
-    return xStorage;
+    return StorageRef( new OleStorage( getGlobalFactory(), rxOutStream, true ) );
 }
 
 // ============================================================================
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx
index 23363db..5579385 100644
--- a/oox/source/core/filterbase.cxx
+++ b/oox/source/core/filterbase.cxx
@@ -38,6 +38,7 @@
 #include <osl/mutex.hxx>
 #include <rtl/instance.hxx>
 #include <rtl/uri.hxx>
+#include <comphelper/docpasswordhelper.hxx>
 #include <comphelper/mediadescriptor.hxx>
 #include "tokens.hxx"
 #include "oox/helper/binaryinputstream.hxx"
@@ -58,7 +59,6 @@ using ::com::sun::star::uno::UNO_SET_THROW;
 using ::com::sun::star::lang::IllegalArgumentException;
 using ::com::sun::star::lang::XMultiServiceFactory;
 using ::com::sun::star::lang::XComponent;
-using ::com::sun::star::beans::NamedValue;
 using ::com::sun::star::beans::PropertyValue;
 using ::com::sun::star::awt::DeviceInfo;
 using ::com::sun::star::awt::XDevice;
@@ -72,6 +72,7 @@ using ::com::sun::star::task::XStatusIndicator;
 using ::com::sun::star::task::XInteractionHandler;
 using ::com::sun::star::graphic::XGraphic;
 using ::comphelper::MediaDescriptor;
+using ::comphelper::SequenceAsHashMap;
 using ::oox::ole::OleObjectHelper;
 
 namespace oox {
@@ -125,6 +126,16 @@ DocumentOpenedGuard::~DocumentOpenedGuard()
 
 // ============================================================================
 
+/** Specifies whether this filter is an import or export filter. */
+enum FilterDirection
+{
+    FILTERDIRECTION_UNKNOWN,
+    FILTERDIRECTION_IMPORT,
+    FILTERDIRECTION_EXPORT
+};
+
+// ----------------------------------------------------------------------------
+
 struct FilterBaseImpl
 {
     typedef ::boost::shared_ptr< GraphicHelper >            GraphicHelperRef;
@@ -132,9 +143,10 @@ struct FilterBaseImpl
     typedef ::boost::shared_ptr< OleObjectHelper >          OleObjHelperRef;
     typedef ::std::map< OUString, Reference< XGraphic > >   EmbeddedGraphicMap;
     typedef ::std::map< sal_Int32, sal_Int32 >              SystemPalette;
-    typedef ::std::map< OUString, Any >                     ArgumentMap;
 
-    MediaDescriptor     maDescriptor;
+    FilterDirection     meDirection;
+    SequenceAsHashMap   maArguments;
+    MediaDescriptor     maMediaDesc;
     DeviceInfo          maDeviceInfo;
     OUString            maFileUrl;
     StorageRef          mxStorage;
@@ -145,7 +157,6 @@ struct FilterBaseImpl
     EmbeddedGraphicMap  maEmbeddedGraphics;     /// Maps all imported embedded graphics by their path.
     SystemPalette       maSystemPalette;        /// Maps system colors (XML tokens) to RGB color values.
 
-    ArgumentMap                         maArguments;
     Reference< XMultiServiceFactory >   mxGlobalFactory;
     Reference< XModel >                 mxModel;
     Reference< XMultiServiceFactory >   mxModelFactory;
@@ -157,14 +168,16 @@ struct FilterBaseImpl
     explicit            FilterBaseImpl( const Reference< XMultiServiceFactory >& rxGlobalFactory );
 
     void                setDocumentModel( const Reference< XComponent >& rxComponent );
-    void                setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor );
-
     bool                hasDocumentModel() const;
+
+    void                initializeFilter();
+    void                finalizeFilter();
 };
 
 // ----------------------------------------------------------------------------
 
 FilterBaseImpl::FilterBaseImpl( const Reference< XMultiServiceFactory >& rxGlobalFactory ) :
+    meDirection( FILTERDIRECTION_UNKNOWN ),
     mxGlobalFactory( rxGlobalFactory )
 {
     OSL_ENSURE( mxGlobalFactory.is(), "FilterBaseImpl::FilterBaseImpl - missing service factory" );
@@ -223,23 +236,39 @@ void FilterBaseImpl::setDocumentModel( const Reference< XComponent >& rxComponen
     mxModelFactory.set( rxComponent, UNO_QUERY );
 }
 
-void FilterBaseImpl::setMediaDescriptor( const Sequence< PropertyValue >& rDescriptor )
+bool FilterBaseImpl::hasDocumentModel() const
 {
-    maDescriptor = rDescriptor;
-
-    maFileUrl = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), maFileUrl );
-    mxInStream = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), mxInStream );
-    mxOutStream = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_STREAMFOROUTPUT(), mxOutStream );
-    mxStatusIndicator = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_STATUSINDICATOR(), mxStatusIndicator );
-    mxInteractionHandler = maDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_INTERACTIONHANDLER(), mxInteractionHandler );
+    return mxGlobalFactory.is() && mxModel.is() && mxModelFactory.is();
+}
 
-    if( mxInStream.is() )
-        maDescriptor.addInputStream();
+void FilterBaseImpl::initializeFilter()
+{
+    try
+    {
+        // lock the model controllers
+        mxModel->lockControllers();
+    }
+    catch( Exception& )
+    {
+    }
 }
 
-bool FilterBaseImpl::hasDocumentModel() const
+void FilterBaseImpl::finalizeFilter()
 {
-    return mxGlobalFactory.is() && mxModel.is() && mxModelFactory.is();
+    try
+    {
+        // clear the 'ComponentData' property in the descriptor
+        MediaDescriptor::iterator aIt = maMediaDesc.find( MediaDescriptor::PROP_COMPONENTDATA() );
+        if( aIt != maMediaDesc.end() )
+            aIt->second.clear();
+        // write the descriptor back to the document model (adds the password)
+        mxModel->attachResource( maFileUrl, maMediaDesc.getAsConstPropertyValueList() );
+        // unlock the model controllers
+        mxModel->unlockControllers();
+    }
+    catch( Exception& )
+    {
+    }
 }
 
 // ============================================================================
@@ -255,19 +284,19 @@ FilterBase::~FilterBase()
 
 bool FilterBase::isImportFilter() const
 {
-    return mxImpl->mxInStream.is();
+    return mxImpl->meDirection == FILTERDIRECTION_IMPORT;
 }
 
 bool FilterBase::isExportFilter() const
 {
-    return mxImpl->mxOutStream.is();
+    return mxImpl->meDirection == FILTERDIRECTION_EXPORT;
 }
 
 // ----------------------------------------------------------------------------
 
 Any FilterBase::getArgument( const OUString& rArgName ) const
 {
-    FilterBaseImpl::ArgumentMap::const_iterator aIt = mxImpl->maArguments.find( rArgName );
+    SequenceAsHashMap::const_iterator aIt = mxImpl->maArguments.find( rArgName );
     return (aIt == mxImpl->maArguments.end()) ? Any() : aIt->second;
 }
 
@@ -276,6 +305,11 @@ const Reference< XMultiServiceFactory >& FilterBase::getGlobalFactory() const
     return mxImpl->mxGlobalFactory;
 }
 
+MediaDescriptor& FilterBase::getMediaDescriptor() const
+{
+    return mxImpl->maMediaDesc;
+}
+
 const Reference< XModel >& FilterBase::getModel() const
 {
     return mxImpl->mxModel;
@@ -440,6 +474,14 @@ sal_Int32 FilterBase::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb )
     return (aIt == mxImpl->maSystemPalette.end()) ? ((nDefaultRgb < 0) ? API_RGB_WHITE : nDefaultRgb) : aIt->second;
 }
 
+OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const
+{
+    ::std::vector< OUString > aDefaultPasswords;
+    aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
+    return ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+        rVerifier, mxImpl->maMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
+}
+
 bool FilterBase::importBinaryData( StreamDataSequence& orDataSeq, const OUString& rStreamName )
 {
     OSL_ENSURE( rStreamName.getLength() > 0, "FilterBase::importBinaryData - empty stream name" );
@@ -508,17 +550,12 @@ Sequence< OUString > SAL_CALL FilterBase::getSupportedServiceNames() throw( Runt
 
 void SAL_CALL FilterBase::initialize( const Sequence< Any >& rArgs ) throw( Exception, RuntimeException )
 {
-    if( rArgs.getLength() >= 2 )
+    if( rArgs.getLength() >= 2 ) try
+    {
+        mxImpl->maArguments << rArgs[ 1 ];
+    }
+    catch( Exception& )
     {
-        Sequence< NamedValue > aArgSeq;
-        if( (rArgs[ 1 ] >>= aArgSeq) && aArgSeq.hasElements() )
-        {
-            const NamedValue* pArg = aArgSeq.getConstArray();
-            const NamedValue* pEnd = pArg + aArgSeq.getLength();
-            for( ; pArg < pEnd; ++pArg )
-                if( pArg->Name.getLength() > 0 )
-                    mxImpl->maArguments[ pArg->Name ] = pArg->Value;
-        }
     }
 }
 
@@ -529,6 +566,7 @@ void SAL_CALL FilterBase::setTargetDocument( const Reference< XComponent >& rxDo
     mxImpl->setDocumentModel( rxDocument );
     if( !mxImpl->hasDocumentModel() )
         throw IllegalArgumentException();
+    mxImpl->meDirection = FILTERDIRECTION_IMPORT;
 }
 
 // com.sun.star.document.XExporter interface ----------------------------------
@@ -538,29 +576,41 @@ void SAL_CALL FilterBase::setSourceDocument( const Reference< XComponent >& rxDo
     mxImpl->setDocumentModel( rxDocument );
     if( !mxImpl->hasDocumentModel() )
         throw IllegalArgumentException();
+    mxImpl->meDirection = FILTERDIRECTION_EXPORT;
 }
 
 // com.sun.star.document.XFilter interface ------------------------------------
 
-sal_Bool SAL_CALL FilterBase::filter( const Sequence< PropertyValue >& rDescriptor ) throw( RuntimeException )
+sal_Bool SAL_CALL FilterBase::filter( const Sequence< PropertyValue >& rMediaDescSeq ) throw( RuntimeException )
 {
     sal_Bool bRet = sal_False;
-    if( mxImpl->hasDocumentModel() )
+    if( mxImpl->hasDocumentModel() && (mxImpl->meDirection != FILTERDIRECTION_UNKNOWN) )
     {
-        mxImpl->setMediaDescriptor( rDescriptor );
+        setMediaDescriptor( rMediaDescSeq );
         DocumentOpenedGuard aOpenedGuard( mxImpl->maFileUrl );
         if( aOpenedGuard.isValid() )
         {
-            mxImpl->mxStorage = implCreateStorage( mxImpl->mxInStream, mxImpl->mxOutStream );
-            if( mxImpl->mxStorage.get() )
+            mxImpl->initializeFilter();
+            switch( mxImpl->meDirection )
             {
-                mxImpl->mxModel->lockControllers();
-                if( mxImpl->mxInStream.is() )
-                    bRet = importDocument();
-                else if( mxImpl->mxOutStream.is() )
-                    bRet = exportDocument();
-                mxImpl->mxModel->unlockControllers();
+                case FILTERDIRECTION_UNKNOWN:
+                break;
+                case FILTERDIRECTION_IMPORT:
+                    if( mxImpl->mxInStream.is() )
+                    {
+                        mxImpl->mxStorage = implCreateStorage( mxImpl->mxInStream );
+                        bRet = mxImpl->mxStorage.get() && importDocument();
+                    }
+                break;
+                case FILTERDIRECTION_EXPORT:
+                    if( mxImpl->mxOutStream.is() )
+                    {
+                        mxImpl->mxStorage = implCreateStorage( mxImpl->mxOutStream );
+                        bRet = mxImpl->mxStorage.get() && exportDocument();
+                    }
+                break;
             }
+            mxImpl->finalizeFilter();
         }
     }
     return bRet;
@@ -570,6 +620,46 @@ void SAL_CALL FilterBase::cancel() throw( RuntimeException )
 {
 }
 
+// protected ------------------------------------------------------------------
+
+Reference< XInputStream > FilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const
+{
+    return rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), Reference< XInputStream >() );
+}
+
+Reference< XStream > FilterBase::implGetOutputStream( MediaDescriptor& rMediaDesc ) const
+{
+    return rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STREAMFOROUTPUT(), Reference< XStream >() );
+}
+
+// private --------------------------------------------------------------------
+
+void FilterBase::setMediaDescriptor( const Sequence< PropertyValue >& rMediaDescSeq )
+{
+    mxImpl->maMediaDesc = rMediaDescSeq;
+
+    switch( mxImpl->meDirection )
+    {
+        case FILTERDIRECTION_UNKNOWN:
+            OSL_ENSURE( false, "FilterBase::setMediaDescriptor - invalid filter direction" );
+        break;
+        case FILTERDIRECTION_IMPORT:
+            mxImpl->maMediaDesc.addInputStream();
+            mxImpl->mxInStream = implGetInputStream( mxImpl->maMediaDesc );
+            OSL_ENSURE( mxImpl->mxInStream.is(), "FilterBase::setMediaDescriptor - missing input stream" );
+        break;
+        case FILTERDIRECTION_EXPORT:
+            mxImpl->mxOutStream = implGetOutputStream( mxImpl->maMediaDesc );
+            OSL_ENSURE( mxImpl->mxOutStream.is(), "FilterBase::setMediaDescriptor - missing output stream" );
+        break;
+    }
+
+    mxImpl->maFileUrl = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL(), OUString() );
+    mxImpl->mxStatusIndicator = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STATUSINDICATOR(), Reference< XStatusIndicator >() );
+    mxImpl->mxInteractionHandler = mxImpl->maMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INTERACTIONHANDLER(), Reference< XInteractionHandler >() );
+}
+
+
 // ============================================================================
 
 } // namespace core
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index b0496de..434adb9 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -28,89 +28,52 @@
  *
  ************************************************************************/
 
-#include <com/sun/star/document/XExtendedFilterDetection.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
-
-#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
-#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
+#include "oox/core/filterdetect.hxx"
+#include <com/sun/star/io/XStream.hpp>
 #include <com/sun/star/xml/sax/XFastParser.hpp>
-
+#include <rtl/digest.h>
+#include <openssl/evp.h>
+#include <comphelper/docpasswordhelper.hxx>
 #include <comphelper/mediadescriptor.hxx>
-#include <cppuhelper/implbase1.hxx>
-#include <cppuhelper/implbase2.hxx>
-
 #include "oox/helper/attributelist.hxx"
+#include "oox/helper/binaryinputstream.hxx"
+#include "oox/helper/binaryoutputstream.hxx"
+#include "oox/helper/olestorage.hxx"
 #include "oox/helper/zipstorage.hxx"
 #include "oox/core/fasttokenhandler.hxx"
 #include "oox/core/namespaces.hxx"
-#include "tokens.hxx"
-
-#include <vector>
 
 using ::rtl::OUString;
-using ::rtl::OString;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::io::XInputStream;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::io::XStream;
+using ::com::sun::star::xml::sax::InputSource;
+using ::com::sun::star::xml::sax::SAXException;
+using ::com::sun::star::xml::sax::XFastAttributeList;
+using ::com::sun::star::xml::sax::XFastContextHandler;
+using ::com::sun::star::xml::sax::XFastParser;
+using ::com::sun::star::xml::sax::XLocator;
 using ::comphelper::MediaDescriptor;
-using namespace ::com::sun::star::document;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::beans;
-using namespace ::com::sun::star::io;
-using namespace ::com::sun::star::embed;
-using namespace ::com::sun::star::xml::sax;
+using ::comphelper::SequenceAsHashMap;
 
 namespace oox {
 namespace core {
 
 // ============================================================================
 
-/** Document handler specifically designed for detecting OOXML file formats.
-
-    It takes a reference to the filter string object via its constructor, and
-    puts the name of the detected filter to it if it successfully finds one.
- */
-class FilterDetectDocHandler : public ::cppu::WeakImplHelper1< XFastDocumentHandler >
-{
-public:
-    explicit            FilterDetectDocHandler( OUString& rFilter );
-    virtual             ~FilterDetectDocHandler();
-
-    // XFastDocumentHandler
-    virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException);
-    virtual void SAL_CALL endDocument() throw (SAXException, RuntimeException);
-    virtual void SAL_CALL setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException);
-
-    // XFastContextHandler
-    virtual void SAL_CALL startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-    virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-    virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (SAXException, RuntimeException);
-    virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) throw (SAXException, RuntimeException);
-    virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-    virtual Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException);
-    virtual void SAL_CALL characters( const OUString& aChars ) throw (SAXException, RuntimeException);
-    virtual void SAL_CALL ignorableWhitespace( const OUString& aWhitespaces ) throw (SAXException, RuntimeException);
-    virtual void SAL_CALL processingInstruction( const OUString& aTarget, const OUString& aData ) throw (SAXException, RuntimeException);
-
-private:
-    void                parseRelationship( const AttributeList& rAttribs );
-
-    OUString            getFilterNameFromContentType( const OUString& rContentType ) const;
-    void                parseContentTypesDefault( const AttributeList& rAttribs );
-    void                parseContentTypesOverride( const AttributeList& rAttribs );
-
-private:
-    typedef ::std::vector< sal_Int32 > ContextVector;
-
-    OUString&           mrFilter;
-    ContextVector       maContextStack;
-    OUString            maTargetPath;
-};
-
-// ============================================================================
-
-FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilter ) :
-    mrFilter( rFilter )
+FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilterName ) :
+    mrFilterName( rFilterName )
 {
     maContextStack.reserve( 2 );
 }
@@ -134,8 +97,6 @@ void SAL_CALL FilterDetectDocHandler::setDocumentLocator( const Reference<XLocat
 {
 }
 
-// ===========================================================================
-
 void SAL_CALL FilterDetectDocHandler::startFastElement(
         sal_Int32 nElement, const Reference< XFastAttributeList >& rAttribs )
     throw (SAXException,RuntimeException)
@@ -213,8 +174,6 @@ void SAL_CALL FilterDetectDocHandler::processingInstruction(
 {
 }
 
-// ============================================================================
-
 void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs )
 {
     OUString aType = rAttribs.getString( XML_Type, OUString() );
@@ -224,6 +183,14 @@ void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs )
 
 OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& rContentType ) const
 {
+    if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" ) ||
+        rContentType.equalsAscii( "application/vnd.ms-word.document.macroEnabled.main+xml" ) )
+        return CREATE_OUSTRING( "writer_MS_Word_2007" );
+
+    if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml" ) ||
+        rContentType.equalsAscii( "application/vnd.ms-word.template.macroEnabledTemplate.main+xml" ) )
+        return CREATE_OUSTRING( "writer_MS_Word_2007_Template" );
+
     if( rContentType.equalsAscii( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" ) ||
         rContentType.equalsAscii( "application/vnd.ms-excel.sheet.macroEnabled.main+xml" ) )
         return CREATE_OUSTRING( "MS Excel 2007 XML" );
@@ -249,44 +216,24 @@ OUString FilterDetectDocHandler::getFilterNameFromContentType( const OUString& r
 void FilterDetectDocHandler::parseContentTypesDefault( const AttributeList& rAttribs )
 {
     // only if no overridden part name found
-    if( mrFilter.getLength() == 0 )
+    if( mrFilterName.getLength() == 0 )
     {
         // check if target path ends with extension
         OUString aExtension = rAttribs.getString( XML_Extension, OUString() );
         sal_Int32 nExtPos = maTargetPath.getLength() - aExtension.getLength();
         if( (nExtPos > 0) && (maTargetPath[ nExtPos - 1 ] == '.') && maTargetPath.match( aExtension, nExtPos ) )
-            mrFilter = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
+            mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
     }
 }
 
 void FilterDetectDocHandler::parseContentTypesOverride( const AttributeList& rAttribs )
 {
     if( rAttribs.getString( XML_PartName, OUString() ).equals( maTargetPath ) )
-        mrFilter = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
+        mrFilterName = getFilterNameFromContentType( rAttribs.getString( XML_ContentType, OUString() ) );
 }
 
 // ============================================================================
 
-class FilterDetect : public ::cppu::WeakImplHelper2< XExtendedFilterDetection, XServiceInfo >
-{
-public:
-    explicit            FilterDetect( const Reference< XMultiServiceFactory >& xFactory );
-    virtual             ~FilterDetect();
-
-    // XServiceInfo
-    virtual OUString SAL_CALL getImplementationName() throw( RuntimeException );
-    virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) throw( RuntimeException );
-    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException );
-
-    // XExtendedFilterDetect
-    virtual OUString SAL_CALL detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException );
-
-private:
-    Reference< XMultiServiceFactory > mxFactory;
-};
-
-// ----------------------------------------------------------------------------
-
 /* Helper for XServiceInfo */
 Sequence< OUString > FilterDetect_getSupportedServiceNames()
 {
@@ -307,8 +254,10 @@ Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< X
     return Reference< XInterface >( *new FilterDetect( xServiceManager ) );
 }
 
-FilterDetect::FilterDetect( const Reference< XMultiServiceFactory >& xFactory ) :
-    mxFactory( xFactory )
+// ----------------------------------------------------------------------------
+
+FilterDetect::FilterDetect( const Reference< XMultiServiceFactory >& rxFactory ) :
+    mxFactory( rxFactory )
 {
     OSL_ENSURE( mxFactory.is(), "FilterDetect::FilterDetect - no service factory" );
 }
@@ -317,45 +266,319 @@ FilterDetect::~FilterDetect()
 {
 }
 
-// com.sun.star.document.XExtendedFilterDetect interface ----------------------
+/* =========================================================================== */
+/*  Kudos to Caolan McNamara who provided the core decryption implementations. */
+/* =========================================================================== */
+
+namespace {
+
+const sal_uInt32 ENCRYPTINFO_CRYPTOAPI      = 0x00000004;
+const sal_uInt32 ENCRYPTINFO_DOCPROPS       = 0x00000008;
+const sal_uInt32 ENCRYPTINFO_EXTERNAL       = 0x00000010;
+const sal_uInt32 ENCRYPTINFO_AES            = 0x00000020;
+
+const sal_uInt32 ENCRYPT_ALGO_AES128        = 0x0000660E;
+const sal_uInt32 ENCRYPT_ALGO_AES192        = 0x0000660F;
+const sal_uInt32 ENCRYPT_ALGO_AES256        = 0x00006610;
+const sal_uInt32 ENCRYPT_ALGO_RC4           = 0x00006801;
+
+const sal_uInt32 ENCRYPT_HASH_SHA1          = 0x00008004;
+
+// ----------------------------------------------------------------------------
+
+bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm )
+{
+    ZipStorage aZipStorage( rxFactory, rxInStrm );
+    return aZipStorage.isStorage();
+}
+
+// ----------------------------------------------------------------------------
+
+struct PackageEncryptionInfo
+{
+    sal_uInt8           mpnSalt[ 16 ];
+    sal_uInt8           mpnEncrVerifier[ 16 ];
+    sal_uInt8           mpnEncrVerifierHash[ 32 ];
+    sal_uInt32          mnFlags;
+    sal_uInt32          mnAlgorithmId;
+    sal_uInt32          mnAlgorithmIdHash;
+    sal_uInt32          mnKeySize;
+    sal_uInt32          mnSaltSize;
+    sal_uInt32          mnVerifierHashSize;
+};
+
+bool lclReadEncryptionInfo( PackageEncryptionInfo& rEncrInfo, BinaryInputStream& rStrm )
+{
+    rStrm.skip( 4 );
+    rStrm >> rEncrInfo.mnFlags;
+    if( getFlag( rEncrInfo.mnFlags, ENCRYPTINFO_EXTERNAL ) )
+        return false;
+
+    sal_uInt32 nHeaderSize, nRepeatedFlags;
+    rStrm >> nHeaderSize >> nRepeatedFlags;
+    if( (nHeaderSize < 20) || (nRepeatedFlags != rEncrInfo.mnFlags) )
+        return false;
+
+    rStrm.skip( 4 );
+    rStrm >> rEncrInfo.mnAlgorithmId >> rEncrInfo.mnAlgorithmIdHash >> rEncrInfo.mnKeySize;
+    rStrm.skip( nHeaderSize - 20 );
+    rStrm >> rEncrInfo.mnSaltSize;
+    if( rEncrInfo.mnSaltSize != 16 )
+        return false;
+
+    rStrm.readMemory( rEncrInfo.mpnSalt, 16 );
+    rStrm.readMemory( rEncrInfo.mpnEncrVerifier, 16 );
+    rStrm >> rEncrInfo.mnVerifierHashSize;
+    rStrm.readMemory( rEncrInfo.mpnEncrVerifierHash, 32 );
+    return !rStrm.isEof();
+}
+
+// ----------------------------------------------------------------------------
+
+void lclDeriveKey( const sal_uInt8* pnHash, sal_uInt32 nHashLen, sal_uInt8* pnKeyDerived, sal_uInt32 nRequiredKeyLen )
+{
+    sal_uInt8 pnBuffer[ 64 ];
+    memset( pnBuffer, 0x36, sizeof( pnBuffer ) );
+    for( sal_uInt32 i = 0; i < nHashLen; ++i )
+        pnBuffer[ i ] ^= pnHash[ i ];
+
+    rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+    rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) );
+    sal_uInt8 pnX1[ RTL_DIGEST_LENGTH_SHA1 ];
+    aError = rtl_digest_get( aDigest, pnX1, RTL_DIGEST_LENGTH_SHA1 );
+    rtl_digest_destroy( aDigest );
+
+    memset( pnBuffer, 0x5C, sizeof( pnBuffer ) );
+    for( sal_uInt32 i = 0; i < nHashLen; ++i )
+        pnBuffer[ i ] ^= pnHash[ i ];
+
+    aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+    aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) );
+    sal_uInt8 pnX2[ RTL_DIGEST_LENGTH_SHA1 ];
+    aError = rtl_digest_get( aDigest, pnX2, RTL_DIGEST_LENGTH_SHA1 );
+    rtl_digest_destroy( aDigest );
+
+    if( nRequiredKeyLen > RTL_DIGEST_LENGTH_SHA1 )
+    {
+        memcpy( pnKeyDerived + RTL_DIGEST_LENGTH_SHA1, pnX2, nRequiredKeyLen - RTL_DIGEST_LENGTH_SHA1 );
+        nRequiredKeyLen = RTL_DIGEST_LENGTH_SHA1;
+    }
+    memcpy( pnKeyDerived, pnX1, nRequiredKeyLen );
+}
+
+// ----------------------------------------------------------------------------
 
-OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException )
+bool lclGenerateEncryptionKey( const PackageEncryptionInfo& rEncrInfo, const OUString& rPassword, sal_uInt8* pnKey, sal_uInt32 nRequiredKeyLen )
 {
-    OUString aFilter;
+    size_t nBufferSize = rEncrInfo.mnSaltSize + 2 * rPassword.getLength();
+    sal_uInt8* pnBuffer = new sal_uInt8[ nBufferSize ];
+    memcpy( pnBuffer, rEncrInfo.mpnSalt, rEncrInfo.mnSaltSize );
+
+    sal_uInt8* pnPasswordLoc = pnBuffer + rEncrInfo.mnSaltSize;
+    const sal_Unicode* pStr = rPassword.getStr();
+    for( sal_Int32 i = 0, nLen = rPassword.getLength(); i < nLen; ++i, ++pStr, pnPasswordLoc += 2 )
+        ByteOrderConverter::writeLittleEndian( pnPasswordLoc, static_cast< sal_uInt16 >( *pStr ) );
+
+    rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+    rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, nBufferSize );
+    delete[] pnBuffer;
 
-    if( mxFactory.is() ) try
+    size_t nHashSize = RTL_DIGEST_LENGTH_SHA1 + 4;
+    sal_uInt8* pnHash = new sal_uInt8[ nHashSize ];
+    aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 );
+    rtl_digest_destroy( aDigest );
+
+    for( sal_uInt32 i = 0; i < 50000; ++i )
     {
-        Reference< XFastParser > xParser( mxFactory->createInstance(
-            CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW );
-
-        xParser->setFastDocumentHandler( new FilterDetectDocHandler( aFilter ) );
-        xParser->setTokenHandler( new FastTokenHandler );
-
-        xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS );
-        xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS );
-        xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/content-types" ), NMSP_CONTENT_TYPES );
-
-        MediaDescriptor aDescriptor( lDescriptor );
-        aDescriptor.addInputStream();
-        Reference< XInputStream > xInputStream( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY_THROW );
-        StorageRef xStorage( new ZipStorage( mxFactory, xInputStream ) );
-
-        // Parse _rels/.rels to get the target path.
-        InputSource aParserInput;
-        aParserInput.sSystemId = CREATE_OUSTRING( "_rels/.rels" );
-        aParserInput.aInputStream = xStorage->openInputStream( aParserInput.sSystemId );
-        xParser->parseStream( aParserInput );
-
-        // Parse [Content_Types].xml to determine the content type of the part at the target path.
-        aParserInput.sSystemId = CREATE_OUSTRING( "[Content_Types].xml" );
-        aParserInput.aInputStream = xStorage->openInputStream( aParserInput.sSystemId );
-        xParser->parseStream( aParserInput );
+        ByteOrderConverter::writeLittleEndian( pnHash, i );
+        aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+        aError = rtl_digest_update( aDigest, pnHash, nHashSize );
+        aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 );
+        rtl_digest_destroy( aDigest );
     }
-    catch ( const Exception& )
+
+    memmove( pnHash, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 );
+    memset( pnHash + RTL_DIGEST_LENGTH_SHA1, 0, 4 );
+    aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+    aError = rtl_digest_update( aDigest, pnHash, nHashSize );
+    aError = rtl_digest_get( aDigest, pnHash, RTL_DIGEST_LENGTH_SHA1 );
+    rtl_digest_destroy( aDigest );
+
+    lclDeriveKey( pnHash, RTL_DIGEST_LENGTH_SHA1, pnKey, nRequiredKeyLen );
+    delete[] pnHash;
+
+    // check password
+    EVP_CIPHER_CTX aes_ctx;
+    EVP_CIPHER_CTX_init( &aes_ctx );
+    EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
+    EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+    int nOutLen = 0;
+    sal_uInt8 pnVerifier[ 16 ] = { 0 };
+    /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifier, &nOutLen, rEncrInfo.mpnEncrVerifier, sizeof( rEncrInfo.mpnEncrVerifier ) );
+    EVP_CIPHER_CTX_cleanup( &aes_ctx );
+
+    EVP_CIPHER_CTX_init( &aes_ctx );
+    EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 );
+    EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+    sal_uInt8 pnVerifierHash[ 32 ] = { 0 };
+    /*int*/ EVP_DecryptUpdate( &aes_ctx, pnVerifierHash, &nOutLen, rEncrInfo.mpnEncrVerifierHash, sizeof( rEncrInfo.mpnEncrVerifierHash ) );
+    EVP_CIPHER_CTX_cleanup( &aes_ctx );
+
+    aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
+    aError = rtl_digest_update( aDigest, pnVerifier, sizeof( pnVerifier ) );
+    sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ];
+    aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 );
+    rtl_digest_destroy( aDigest );
+
+    return memcmp( pnSha1Hash, pnVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0;
+}
+
+// the password verifier ------------------------------------------------------
+
+class PasswordVerifier : public ::comphelper::IDocPasswordVerifier
+{
+public:
+    explicit            PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo );
+
+    virtual ::comphelper::DocPasswordVerifierResult
+                        verifyPassword( const OUString& rPassword );
+
+    inline const sal_uInt8* getKey() const { return &maKey.front(); }
+
+private:
+    const PackageEncryptionInfo& mrEncryptInfo;
+    ::std::vector< sal_uInt8 > maKey;
+};
+
+PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) :
+    mrEncryptInfo( rEncryptInfo ),
+    maKey( static_cast< size_t >( rEncryptInfo.mnKeySize / 8 ), 0 )
+{
+}
+
+::comphelper::DocPasswordVerifierResult PasswordVerifier::verifyPassword( const OUString& rPassword )
+{
+    // verifies the password and writes the related decryption key into maKey
+    return lclGenerateEncryptionKey( mrEncryptInfo, rPassword, &maKey.front(), maKey.size() ) ?
+        ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const
+{
+    if( mxFactory.is() )
     {
+        // try the plain input stream
+        Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY );
+        if( !xInStrm.is() || lclIsZipPackage( mxFactory, xInStrm ) )
+            return xInStrm;
+
+        // check if a temporary file is passed in the 'ComponentData' property
+        Sequence< NamedValue > aCompData = rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_COMPONENTDATA(), Sequence< NamedValue >() );
+        SequenceAsHashMap aCompDataMap( aCompData );
+        Reference< XStream > xDecrypted = aCompDataMap.getUnpackedValueOrDefault( CREATE_OUSTRING( "DecryptedPackage" ), Reference< XStream >() );
+        if( xDecrypted.is() )
+        {
+            Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream();
+            if( lclIsZipPackage( mxFactory, xDecrInStrm ) )
+                return xDecrInStrm;
+        }
+
+        // try to decrypt an encrypted OLE package
+        OleStorage aOleStorage( mxFactory, xInStrm, false );
+        if( aOleStorage.isStorage() ) try
+        {
+            // open the required input streams in the encrypted package
+            Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW );
+            Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW );
+
+            // read the encryption info stream
+            PackageEncryptionInfo aEncryptInfo;
+            BinaryXInputStream aInfoStrm( xEncryptionInfo, true );
+            bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm );
+
+            // check flags and agorithm IDs, requiered are AES128 and SHA-1
+            bool bImplemented = bValidInfo &&
+                getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) &&
+                getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) &&
+                // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
+                ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) &&
+                // hash algorithm ID 0 defaults to SHA-1 too
+                ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) &&
+                (aEncryptInfo.mnVerifierHashSize == 20);
+
+            if( bImplemented )
+            {
+                /*  "VelvetSweatshop" is the built-in default encryption
+                    password used by MS Excel for the "workbook protection"
+                    feature with password. Try this first before prompting the
+                    user for a password. */
+                ::std::vector< OUString > aDefaultPasswords;
+                aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
+
+                /*  Use the comphelper password helper to request a password.
+                    This helper returns either with the correct password
+                    (according to the verifier), or with an empty string if
+                    user has cancelled the password input dialog. */
+                PasswordVerifier aVerifier( aEncryptInfo );
+                OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+                    aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
+
+                if( aPassword.getLength() == 0 )
+                {
+                    rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true;
+                }
+                else
+                {
+                    // create temporary file for unencrypted package
+                    Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
+                    Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW );
+                    BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true );
+                    BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true );
+
+                    EVP_CIPHER_CTX aes_ctx;
+                    EVP_CIPHER_CTX_init( &aes_ctx );
+                    EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 );
+                    EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );
+
+                    sal_uInt8 pnInBuffer[ 1024 ];
+                    sal_uInt8 pnOutBuffer[ 1024 ];
+                    sal_Int32 nInLen;
+                    int nOutLen;
+                    aEncryptedPackage.skip( 8 ); // decrypted size
+                    while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 )
+                    {
+                        EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen );
+                        aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );
+                    }
+                    EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen );
+                    aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );
+
+                    EVP_CIPHER_CTX_cleanup( &aes_ctx );
+                    xDecryptedPackage->flush();
+                    aDecryptedPackage.seekToStart();
+
+                    // store temp file in media descriptor to keep it alive
+                    Sequence< NamedValue > aPropSeq( 1 );
+                    aPropSeq[ 0 ].Name = CREATE_OUSTRING( "DecryptedPackage" );
+                    aPropSeq[ 0 ].Value <<= xTempFile;
+                    rMediaDesc[ MediaDescriptor::PROP_COMPONENTDATA() ] <<= aPropSeq;
+
+                    Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream();
+                    if( lclIsZipPackage( mxFactory, xDecrInStrm ) )
+                        return xDecrInStrm;
+                }
+            }
+        }
+        catch( Exception& )
+        {
+        }
     }
 
-    return aFilter;
+    return Reference< XInputStream >();
 }
 
 // com.sun.star.lang.XServiceInfo interface -----------------------------------
@@ -378,6 +601,62 @@ Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames() throw( Ru
     return FilterDetect_getSupportedServiceNames();
 }
 
+// com.sun.star.document.XExtendedFilterDetection interface -------------------
+
+OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq ) throw( RuntimeException )
+{
+    OUString aFilterName;
+    MediaDescriptor aMediaDesc( rMediaDescSeq );
+
+    /*  Check that the user has not choosen to abort detection, e.g. by hitting
+        'Cancel' in the password input dialog. This may happen because this
+        filter detection is used by different filters. */
+    bool bAborted = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_ABORTED(), false );
+    if( !bAborted && mxFactory.is() ) try
+    {
+        aMediaDesc.addInputStream();
+
+        /*  Get the unencrypted input stream. This may include creation of a
+            temporary file that contains the decrypted package. This temporary
+            file will be stored in the 'ComponentData' property of the media
+            descriptor. */
+        Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW );
+
+        // try to detect the file type, must be a ZIP package
+        ZipStorage aZipStorage( mxFactory, xInStrm );
+        if( aZipStorage.isStorage() )
+        {
+            Reference< XFastParser > xParser( mxFactory->createInstance(
+                CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW );
+
+            xParser->setFastDocumentHandler( new FilterDetectDocHandler( aFilterName ) );
+            xParser->setTokenHandler( new FastTokenHandler );
+
+            xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS );
+            xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS );
+            xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/content-types" ), NMSP_CONTENT_TYPES );
+
+            // Parse _rels/.rels to get the target path.
+            InputSource aParserInput;
+            aParserInput.sSystemId = CREATE_OUSTRING( "_rels/.rels" );
+            aParserInput.aInputStream = aZipStorage.openInputStream( aParserInput.sSystemId );
+            xParser->parseStream( aParserInput );
+
+            // Parse [Content_Types].xml to determine the content type of the part at the target path.
+            aParserInput.sSystemId = CREATE_OUSTRING( "[Content_Types].xml" );
+            aParserInput.aInputStream = aZipStorage.openInputStream( aParserInput.sSystemId );
+            xParser->parseStream( aParserInput );
+        }
+    }
+    catch( Exception& )
+    {
+    }
+
+    // write back changed media descriptor members
+    aMediaDesc >> rMediaDescSeq;
+    return aFilterName;
+}
+
 // ============================================================================
 
 } // namespace core
diff --git a/oox/source/core/makefile.mk b/oox/source/core/makefile.mk
index 3443bd3..51804e1 100644
--- a/oox/source/core/makefile.mk
+++ b/oox/source/core/makefile.mk
@@ -42,6 +42,10 @@ ENABLE_EXCEPTIONS=TRUE
 .INCLUDE :  settings.mk
 .INCLUDE: $(PRJ)$/util$/makefile.pmk
 
+.IF "$(SYSTEM_OPENSSL)" == "YES"
+CFLAGS+= $(OPENSSL_CFLAGS)
+.ENDIF
+
 # --- Files --------------------------------------------------------
 
 SLOFILES =	\
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index 88a1e6b..0abc437 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -28,16 +28,7 @@
  *
  ************************************************************************/
 
-#include "properties.hxx"
 #include "oox/core/xmlfilterbase.hxx"
-#include "oox/core/fasttokenhandler.hxx"
-#include "oox/core/fragmenthandler.hxx"
-#include "oox/core/namespaces.hxx"
-#include "oox/core/recordparser.hxx"
-#include "oox/core/relationshandler.hxx"
-#include "oox/helper/containerhelper.hxx"
-#include "oox/helper/propertyset.hxx"
-#include "oox/helper/zipstorage.hxx"
 
 #include <cstdio>
 
@@ -47,9 +38,19 @@
 #include <com/sun/star/xml/sax/InputSource.hpp>
 #include <com/sun/star/xml/sax/XFastParser.hpp>
 #include <com/sun/star/document/XDocumentProperties.hpp>
+#include <comphelper/mediadescriptor.hxx>
 #include <sax/fshelper.hxx>
-
+#include "properties.hxx"
 #include "tokens.hxx"
+#include "oox/helper/containerhelper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/zipstorage.hxx"
+#include "oox/core/fasttokenhandler.hxx"
+#include "oox/core/filterdetect.hxx"
+#include "oox/core/fragmenthandler.hxx"
+#include "oox/core/namespaces.hxx"
+#include "oox/core/recordparser.hxx"
+#include "oox/core/relationshandler.hxx"
 
 using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
@@ -76,6 +77,7 @@ using ::com::sun::star::xml::sax::InputSource;
 using ::com::sun::star::xml::sax::SAXException;
 using ::com::sun::star::document::XDocumentProperties;
 using ::com::sun::star::util::DateTime;
+using ::comphelper::MediaDescriptor;
 using ::sax_fastparser::FastSerializerHelper;
 using ::sax_fastparser::FSHelperPtr;
 
@@ -323,7 +325,7 @@ writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const DateTime& rTime )
     if ( ( nXmlElement >> 16 ) != XML_dcterms )
         pDoc->startElement( nXmlElement, FSEND );
     else
-        pDoc->startElement( nXmlElement, 
+        pDoc->startElement( nXmlElement,
                 FSNS( XML_xsi, XML_type ), "dcterms:W3CDTF",
                 FSEND );
 
@@ -468,7 +470,7 @@ XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProp
             ::com::sun::star::uno::Any aValue = aStats[ i ].Value;
             ::rtl::OUString sValue;
             bool bHaveString = aValue >>= sValue;
-            printf ("#\t%s=%s [%s]\n", 
+            printf ("#\t%s=%s [%s]\n",
                     OUStringToOString( aStats[ i ].Name, RTL_TEXTENCODING_UTF8 ).getStr(),
                     bHaveString
                         ? OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr()
@@ -479,16 +481,27 @@ XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProp
     return *this;
 }
 
-StorageRef XmlFilterBase::implCreateStorage(
-        Reference< XInputStream >& rxInStream, Reference< XStream >& rxOutStream ) const
+// protected ------------------------------------------------------------------
+
+Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const
 {
-    StorageRef xStorage;
-    if( rxInStream.is() )
-        xStorage.reset( new ZipStorage( getGlobalFactory(), rxInStream ) );
-    else if( rxOutStream.is() )
-        xStorage.reset( new ZipStorage( getGlobalFactory(), rxOutStream ) );
+    /*  Get the input stream directly from the media descriptor, or decrypt the
+        package again. The latter is needed e.g. when the document is reloaded.
+        All this is implemented in the detector service. */
+    FilterDetect aDetector( getGlobalFactory() );
+    return aDetector.extractUnencryptedPackage( rMediaDesc );
+}
+
+// private --------------------------------------------------------------------
+
+StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
+{
+    return StorageRef( new ZipStorage( getGlobalFactory(), rxInStream ) );
+}
 
-    return xStorage;
+StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
+{
+    return StorageRef( new ZipStorage( getGlobalFactory(), rxOutStream ) );
 }
 
 // ============================================================================
diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx
index 95b7da8..f4a53a4 100644
--- a/oox/source/dump/biffdumper.cxx
+++ b/oox/source/dump/biffdumper.cxx
@@ -50,6 +50,7 @@ using ::com::sun::star::uno::Reference;
 using ::com::sun::star::util::DateTime;
 using ::com::sun::star::lang::XMultiServiceFactory;
 using ::com::sun::star::io::XInputStream;
+using ::comphelper::MediaDescriptor;
 using ::oox::core::FilterBase;
 
 using namespace ::oox::xls;
@@ -326,14 +327,6 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos,
     ornRecPos = mxBiffStrm->tellBase() - 4;
     ornRecId = mxBiffStrm->getRecId();
 
-    // record specific settings
-    switch( mxBiffStrm->getRecId() )
-    {
-        case BIFF_ID_CHEND:
-            out().decIndent();
-        break;
-    }
-
     // special CONTINUE handling
     mxBiffStrm->resetRecord( mbMergeContRec );
     if( mbMergeContRec ) switch( mxBiffStrm->getRecId() )
@@ -350,6 +343,21 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos,
         break;
     }
 
+    // record specific settings
+    switch( mxBiffStrm->getRecId() )
+    {
+        case BIFF2_ID_BOF:
+        case BIFF3_ID_BOF:
+        case BIFF4_ID_BOF:
+        case BIFF5_ID_BOF:
+        case BIFF_ID_INTERFACEHDR:
+            mxBiffStrm->enableDecoder( false );
+        break;
+        case BIFF_ID_CHEND:
+            out().decIndent();
+        break;
+    }
+
     ornRecSize = mxBiffStrm->getLength();
     return bValid;
 }
@@ -2183,6 +2191,52 @@ void WorkbookStreamObject::implDumpRecordBody()
             }
         break;
 
+        case BIFF_ID_FILEPASS:
+        {
+            rStrm.enableDecoder( false );
+            if( eBiff == BIFF8 )
+            {
+                switch( dumpDec< sal_uInt16 >( "type", "FILEPASS-TYPE" ) )
+                {
+                    case 0:
+                        dumpHex< sal_uInt16 >( "key" );
+                        dumpHex< sal_uInt16 >( "verifier" );
+                    break;
+                    case 1:
+                    {
+                        sal_uInt16 nMajor = dumpDec< sal_uInt16 >( "major-version", "FILEPASS-MAJOR" );
+                        dumpDec< sal_uInt16 >( "minor-version" );
+                        switch( nMajor )
+                        {
+                            case 1:
+                                dumpArray( "salt", 16 );
+                                dumpArray( "verifier", 16 );
+                                dumpArray( "verifier-hash", 16 );
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            else
+            {
+                dumpHex< sal_uInt16 >( "key" );
+                dumpHex< sal_uInt16 >( "verifier" );
+            }
+            rStrm.seekToStart();
+            BiffDecoderRef xDecoder = BiffCodecHelper::implReadFilePass( rStrm, eBiff );
+            if( xDecoder.get() )
+                cfg().requestPassword( *xDecoder );
+            setBinaryOnlyMode( !xDecoder || !xDecoder->isValid() );
+        }
+        break;
+
+        case BIFF_ID_FILESHARING:
+            dumpBool< sal_uInt16 >( "recommend-read-only" );
+            dumpHex< sal_uInt16 >( "password-hash" );
+            dumpString( "password-creator", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
+        break;
+
         case BIFF2_ID_FONT:
         case BIFF3_ID_FONT:
             dumpFontRec();
@@ -2602,9 +2656,14 @@ void WorkbookStreamObject::implDumpRecordBody()
         break;
 
         case BIFF_ID_SHEET:
-            if( eBiff >= BIFF5 ) dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" );
-            if( eBiff >= BIFF5 ) dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" );
-            if( eBiff >= BIFF5 ) dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" );
+            if( eBiff >= BIFF5 )
+            {
+                rStrm.enableDecoder( false );
+                dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" );
+                rStrm.enableDecoder( true );
+                dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" );
+                dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" );
+            }
             dumpString( "sheet-name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
         break;
 
@@ -3682,7 +3741,8 @@ Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Refere
     if( rxFactory.is() && rxInStrm.is() )
     {
         StorageRef xStrg( new OleStorage( rxFactory, rxInStrm, true ) );
-        ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName ) );
+        MediaDescriptor aMediaDesc;
+        ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
         DumperBase::construct( xCfg );
     }
 }
diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini
index 069e18d..df9518e 100644
--- a/oox/source/dump/biffdumper.ini
+++ b/oox/source/dump/biffdumper.ini
@@ -1093,6 +1093,11 @@ constlist=EXTERNSHEET-IDX-BIFF8
   -2=special
 end
 
+# FILEPASS -------------------------------------------------------------------
+
+shortlist=FILEPASS-TYPE,0,xor,rc4
+shortlist=FILEPASS-MAJOR,1,rc4,crypto-api-2003,crypto-api-2007
+
 # FONT -----------------------------------------------------------------------
 
 flagslist=FONT-FLAGS
diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx
index e3a553f..81f6306 100644
--- a/oox/source/dump/dumperbase.cxx
+++ b/oox/source/dump/dumperbase.cxx
@@ -39,6 +39,7 @@
 #include <com/sun/star/io/XTextOutputStream.hpp>
 #include <rtl/math.hxx>
 #include <osl/file.hxx>
+#include <comphelper/docpasswordhelper.hxx>
 #include "oox/helper/binaryoutputstream.hxx"
 #include "oox/core/filterbase.hxx"
 #include "oox/xls/biffhelper.hxx"
@@ -51,8 +52,8 @@ using ::rtl::OStringToOUString;
 using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
 using ::rtl::OUStringToOString;
-using ::com::sun::star::uno::Reference;
 using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Reference;
 using ::com::sun::star::uno::UNO_QUERY_THROW;
 using ::com::sun::star::util::DateTime;
 using ::com::sun::star::lang::XMultiServiceFactory;
@@ -60,9 +61,10 @@ using ::com::sun::star::ucb::XSimpleFileAccess;
 using ::com::sun::star::io::XActiveDataSink;
 using ::com::sun::star::io::XActiveDataSource;
 using ::com::sun::star::io::XInputStream;
-using ::com::sun::star::io::XTextInputStream;
 using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::io::XTextInputStream;
 using ::com::sun::star::io::XTextOutputStream;
+using ::comphelper::MediaDescriptor;
 using ::oox::core::FilterBase;
 
 namespace oox {
@@ -1465,11 +1467,14 @@ NameListRef NameListWrapper::getNameList( const Config& rCfg ) const
 // ============================================================================
 
 SharedConfigData::SharedConfigData( const OUString& rFileName,
-        const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName ) :
+        const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg,
+        const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) :
     mxFactory( rxFactory ),
     mxRootStrg( rxRootStrg ),
     maSysFileName( rSysFileName ),
-    mbLoaded( false )
+    mrMediaDesc( rMediaDesc ),
+    mbLoaded( false ),
+    mbPwCancelled( false )
 {
     OUString aFileUrl = InputOutputHelper::convertFileNameToUrl( rFileName );
     if( aFileUrl.getLength() > 0 )
@@ -1515,6 +1520,20 @@ NameListRef SharedConfigData::getNameList( const OUString& rListName ) const
     return xList;
 }
 
+OUString SharedConfigData::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier )
+{
+    OUString aPassword;
+    if( !mbPwCancelled )
+    {
+        ::std::vector< OUString > aDefaultPasswords;
+        aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
+        aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
+            rVerifier, mrMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
+        mbPwCancelled = aPassword.getLength() == 0;
+    }
+    return aPassword;
+}
+
 bool SharedConfigData::implIsValid() const
 {
     return mbLoaded && mxFactory.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0);
@@ -1614,9 +1633,9 @@ Config::Config( const sal_Char* pcEnvVar, const FilterBase& rFilter )
     construct( pcEnvVar, rFilter );
 }
 
-Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName )
+Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
 {
-    construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName );
+    construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName, rMediaDesc );
 }
 
 Config::~Config()
@@ -1631,14 +1650,14 @@ void Config::construct( const Config& rParent )
 void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter )
 {
     if( rFilter.getFileUrl().getLength() > 0 )
-        construct( pcEnvVar, rFilter.getGlobalFactory(), rFilter.getStorage(), rFilter.getFileUrl() );
+        construct( pcEnvVar, rFilter.getGlobalFactory(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() );
 }
 
-void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName )
+void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
 {
     if( pcEnvVar && rxRootStrg.get() && (rSysFileName.getLength() > 0) )
         if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) )
-            mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName ) );
+            mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName, rMediaDesc ) );
 }
 
 void Config::setStringOption( const String& rKey, const String& rData )
@@ -1683,6 +1702,16 @@ NameListRef Config::getNameList( const String& rListName ) const
     return implGetNameList( rListName );
 }
 
+OUString Config::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier )
+{
+    return mxCfgData->requestPassword( rVerifier );
+}
+
+bool Config::isPasswordCancelled() const
+{
+    return mxCfgData->isPasswordCancelled();
+}
+
 bool Config::implIsValid() const
 {
     return isValid( mxCfgData );
@@ -3050,7 +3079,7 @@ void RecordObjectBase::implDump()
         sal_Int64 nRecPos = in().tell();
 
         // record body
-        if( cfg().hasName( xRecNames, mnRecId ) )
+        if( !mbBinaryOnly && cfg().hasName( xRecNames, mnRecId ) )
         {
             ItemFormatMap::const_iterator aIt = aSimpleRecs.find( mnRecId );
             if( aIt != aSimpleRecs.end() )
@@ -3081,6 +3110,7 @@ void RecordObjectBase::constructRecObjBase( const BinaryInputStreamRef& rxBaseSt
     maRecNames = rRecNames;
     maSimpleRecs = rSimpleRecs;
     mnRecPos = mnRecId = mnRecSize = 0;
+    mbBinaryOnly = false;
     if( InputObjectBase::implIsValid() )
         mbShowRecPos = cfg().getBoolOption( "show-record-position", true );
 }
@@ -3166,6 +3196,11 @@ bool DumperBase::isImportEnabled() const
     return !isValid() || cfg().isImportEnabled();
 }
 
+bool DumperBase::isImportCancelled() const
+{
+    return isValid() && cfg().isPasswordCancelled();
+}
+
 void DumperBase::construct( const ConfigRef& rxConfig )
 {
     if( isValid( rxConfig ) && rxConfig->isDumperEnabled() )
diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx
index d169400..0e04cb8 100644
--- a/oox/source/dump/pptxdumper.cxx
+++ b/oox/source/dump/pptxdumper.cxx
@@ -41,6 +41,7 @@ using ::rtl::OUString;
 using ::com::sun::star::uno::Reference;
 using ::com::sun::star::lang::XMultiServiceFactory;
 using ::com::sun::star::io::XInputStream;
+using ::comphelper::MediaDescriptor;
 using ::oox::core::FilterBase;
 
 namespace oox {
@@ -127,7 +128,8 @@ Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Refere
     if( rxFactory.is() && rxInStrm.is() )
     {
         StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) );
-        ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName ) );
+        MediaDescriptor aMediaDesc;
+        ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
         DumperBase::construct( xCfg );
     }
 }
diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx
index 819aff6..3db91fd 100644
--- a/oox/source/dump/xlsbdumper.cxx
+++ b/oox/source/dump/xlsbdumper.cxx
@@ -48,6 +48,7 @@ using ::com::sun::star::uno::Reference;
 using ::com::sun::star::util::DateTime;
 using ::com::sun::star::lang::XMultiServiceFactory;
 using ::com::sun::star::io::XInputStream;
+using ::comphelper::MediaDescriptor;
 using ::oox::core::FilterBase;
 
 using namespace ::oox::xls;
@@ -1492,6 +1493,12 @@ void RecordStreamObject::implDumpRecordBody()
                 dumpString( "#sheet-name" );
         break;
 
+        case OOBIN_ID_FILESHARING:
+            dumpBool< sal_uInt16 >( "recommend-read-only" );
+            dumpHex< sal_uInt16 >( "password-hash" );
+            dumpString( "password-creator" );
+        break;
+
         case OOBIN_ID_FILL:
             dumpDec< sal_Int32 >( "fill-pattern", "FILLPATTERNS" );
             dumpColor( "fg-color" );
@@ -2267,7 +2274,8 @@ Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Refere
     if( rxFactory.is() && rxInStrm.is() )
     {
         StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) );
-        ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName ) );
+        MediaDescriptor aMediaDesc;
+        ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
         DumperBase::construct( xCfg );
     }
 }
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index e583248..d586196 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -319,7 +319,7 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS
     if( !maShapeModel.mxClientData.get() || !mrDrawing.convertShapeClientAnchor( aShapeRect, maShapeModel.mxClientData->maAnchor ) )
         aShapeRect = getRectangle( pParentAnchor );
     // convert the shape, if the calculated rectangle is not empty
-    if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) && rxShapes.is() )
+    if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
         xShape = implConvertAndInsert( rxShapes, aShapeRect );
     return xShape;
 }
diff --git a/oox/source/xls/biffcodec.cxx b/oox/source/xls/biffcodec.cxx
index b76f51a..a589b1b 100644
--- a/oox/source/xls/biffcodec.cxx
+++ b/oox/source/xls/biffcodec.cxx
@@ -31,95 +31,89 @@
 #include "oox/xls/biffcodec.hxx"
 #include <osl/thread.h>
 #include <string.h>
+#include "oox/core/filterbase.hxx"
 #include "oox/xls/biffinputstream.hxx"
 
 using ::rtl::OString;
 using ::rtl::OUString;
 using ::rtl::OStringToOUString;
+using ::oox::core::FilterBase;
 
 namespace oox {
 namespace xls {
 
 // ============================================================================
 
-BiffDecoderBase::BiffDecoderBase( const WorkbookHelper& rHelper ) :
-    WorkbookHelper( rHelper ),
-    mnError( CODEC_ERROR_UNSUPP_CRYPT )
+BiffDecoderBase::BiffDecoderBase() :
+    mbValid( false )
 {
 }
 
-BiffDecoderBase::BiffDecoderBase( const BiffDecoderBase& rDecoder ) :
-    WorkbookHelper( rDecoder ),
-    mnError( rDecoder.mnError )
+BiffDecoderBase::~BiffDecoderBase()
 {
 }
 
-BiffDecoderBase::~BiffDecoderBase()
+::comphelper::DocPasswordVerifierResult BiffDecoderBase::verifyPassword( const OUString& rPassword )
 {
+    mbValid = implVerify( rPassword );
+    return mbValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
 }
 
 void BiffDecoderBase::decode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
 {
     if( pnDestData && pnSrcData && (nBytes > 0) )
     {
-        if( isValid() )
+        if( mbValid )
             implDecode( pnDestData, pnSrcData, nStreamPos, nBytes );
         else
             memcpy( pnDestData, pnSrcData, nBytes );
     }
 }
 
-void BiffDecoderBase::setHasValidPassword( bool bValid )
-{
-    mnError = bValid ? CODEC_OK : CODEC_ERROR_WRONG_PASS;
-}
-
 // ============================================================================
 
-BiffDecoder_XOR::BiffDecoder_XOR( const WorkbookHelper& rHelper, sal_uInt16 nKey, sal_uInt16 nHash ) :
-    BiffDecoderBase( rHelper ),
+BiffDecoder_XOR::BiffDecoder_XOR( sal_uInt16 nKey, sal_uInt16 nHash ) :
     maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
+    maPassword( 16 ),
     mnKey( nKey ),
     mnHash( nHash )
 {
-    init( BiffCodecHelper::getBiff5WbProtPassword() );
-    if( !isValid() )
-        init( OUStringToOString( getCodecHelper().queryPassword(), osl_getThreadTextEncoding() ) );
 }
 
 BiffDecoder_XOR::BiffDecoder_XOR( const BiffDecoder_XOR& rDecoder ) :
-    BiffDecoderBase( rDecoder ),
+    BiffDecoderBase(),  // must be called to prevent compiler warning
     maCodec( ::oox::core::BinaryCodec_XOR::CODEC_EXCEL ),
+    maPassword( rDecoder.maPassword ),
     mnKey( rDecoder.mnKey ),
     mnHash( rDecoder.mnHash )
 {
-    init( rDecoder.maPass );
+    if( isValid() )
+        maCodec.initKey( &maPassword.front() );
 }
 
-void BiffDecoder_XOR::init( const OString& rPass )
+BiffDecoder_XOR* BiffDecoder_XOR::implClone()
 {
-    maPass = rPass;
-    sal_Int32 nLen = maPass.getLength();
-    bool bValid = (0 < nLen) && (nLen < 16);
+    return new BiffDecoder_XOR( *this );
+}
 
-    if( bValid )
+bool BiffDecoder_XOR::implVerify( const OUString& rPassword )
+{
+    /*  Convert password to a byte string. TODO: this needs some finetuning
+        according to the spec... */
+    OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() );
+    sal_Int32 nLen = aBytePassword.getLength();
+    if( (0 < nLen) && (nLen < 16) )
     {
         // copy byte string to sal_uInt8 array
-        sal_uInt8 pnPassw[ 16 ];
-        memset( pnPassw, 0, sizeof( pnPassw ) );
-        memcpy( pnPassw, maPass.getStr(), static_cast< size_t >( nLen ) );
+        maPassword.clear();
+        maPassword.resize( 16, 0 );
+        memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) );
 
         // init codec
-        maCodec.initKey( pnPassw );
-        bValid = maCodec.verifyKey( mnKey, mnHash );
+        maCodec.initKey( &maPassword.front() );
+        return maCodec.verifyKey( mnKey, mnHash );
     }
-
-    setHasValidPassword( bValid );
-}
-
-BiffDecoder_XOR* BiffDecoder_XOR::implClone()
-{
-    return new BiffDecoder_XOR( *this );
+    return false;
 }
 
 void BiffDecoder_XOR::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
@@ -149,55 +143,49 @@ sal_Int32 lclGetRcfOffset( sal_Int64 nStreamPos )
 
 // ----------------------------------------------------------------------------
 
-BiffDecoder_RCF::BiffDecoder_RCF( const WorkbookHelper& rHelper,
-        sal_uInt8 pnDocId[ 16 ], sal_uInt8 pnSaltData[ 16 ], sal_uInt8 pnSaltHash[ 16 ] ) :
-    BiffDecoderBase( rHelper ),
-    maDocId( pnDocId, pnDocId + 16 ),
-    maSaltData( pnSaltData, pnSaltData + 16 ),
-    maSaltHash( pnSaltHash, pnSaltHash + 16 )
+BiffDecoder_RCF::BiffDecoder_RCF( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) :
+    maPassword( 16, 0 ),
+    maSalt( pnSalt, pnSalt + 16 ),
+    maVerifier( pnVerifier, pnVerifier + 16 ),
+    maVerifierHash( pnVerifierHash, pnVerifierHash + 16 )
 {
-    init( BiffCodecHelper::getBiff8WbProtPassword() );
-    if( !isValid() )
-        init( getCodecHelper().queryPassword() );
 }
 
 BiffDecoder_RCF::BiffDecoder_RCF( const BiffDecoder_RCF& rDecoder ) :
-    BiffDecoderBase( rDecoder ),
-    maDocId( rDecoder.maDocId ),
-    maSaltData( rDecoder.maSaltData ),
-    maSaltHash( rDecoder.maSaltHash )
+    BiffDecoderBase(),  // must be called to prevent compiler warning
+    maPassword( rDecoder.maPassword ),
+    maSalt( rDecoder.maSalt ),
+    maVerifier( rDecoder.maVerifier ),
+    maVerifierHash( rDecoder.maVerifierHash )
 {
-    init( rDecoder.maPass );
+    if( isValid() )
+        maCodec.initKey( &maPassword.front(), &maSalt.front() );
 }
 
-void BiffDecoder_RCF::init( const OUString& rPass )
+BiffDecoder_RCF* BiffDecoder_RCF::implClone()
 {
-    maPass = rPass;
-    sal_Int32 nLen = maPass.getLength();
-    bool bValid = (0 < nLen) && (nLen < 16);
+    return new BiffDecoder_RCF( *this );
+}
 
-    if( bValid )
+bool BiffDecoder_RCF::implVerify( const OUString& rPassword )
+{
+    sal_Int32 nLen = rPassword.getLength();
+    if( (0 < nLen) && (nLen < 16) )
     {
         // copy string to sal_uInt16 array
-        sal_uInt16 pnPassw[ 16 ];
-        memset( pnPassw, 0, sizeof( pnPassw ) );
-        const sal_Unicode* pcChar = maPass.getStr();
+        maPassword.clear();
+        maPassword.resize( 16, 0 );
+        const sal_Unicode* pcChar = rPassword.getStr();
         const sal_Unicode* pcCharEnd = pcChar + nLen;
-        sal_uInt16* pnCurrPass = pnPassw;
-        for( ; pcChar < pcCharEnd; ++pcChar, ++pnCurrPass )
-            *pnCurrPass = static_cast< sal_uInt16 >( *pcChar );
+        ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin();
+        for( ; pcChar < pcCharEnd; ++pcChar, ++aIt )
+            *aIt = static_cast< sal_uInt16 >( *pcChar );
 
         // init codec
-        maCodec.initKey( pnPassw, &maDocId.front() );
-        bValid = maCodec.verifyKey( &maSaltData.front(), &maSaltHash.front() );
+        maCodec.initKey( &maPassword.front(), &maSalt.front() );
+        return maCodec.verifyKey( &maVerifier.front(), &maVerifierHash.front() );
     }
-
-    setHasValidPassword( bValid );
-}
-
-BiffDecoder_RCF* BiffDecoder_RCF::implClone()
-{
-    return new BiffDecoder_RCF( *this );
+    return false;
 }
 
 void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcData, sal_Int64 nStreamPos, sal_uInt16 nBytes )
@@ -229,130 +217,117 @@ void BiffDecoder_RCF::implDecode( sal_uInt8* pnDestData, const sal_uInt8* pnSrcD
 
 namespace {
 
-const sal_uInt16 BIFF_FILEPASS_BIFF2        = 0x0000;
-const sal_uInt16 BIFF_FILEPASS_BIFF8        = 0x0001;
-const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF    = 0x0001;
-const sal_uInt16 BIFF_FILEPASS_BIFF8_STRONG = 0x0002;
+const sal_uInt16 BIFF_FILEPASS_XOR                  = 0;
+const sal_uInt16 BIFF_FILEPASS_RCF                  = 1;
 
-} // namespace
+const sal_uInt16 BIFF_FILEPASS_BIFF8_RCF            = 1;
+const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003 = 2;
+const sal_uInt16 BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007 = 3;
 
 // ----------------------------------------------------------------------------
 
-BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) :
-    WorkbookHelper( rHelper ),
-    mbHasPassword( false )
-{
-}
-
-const OString& BiffCodecHelper::getBiff5WbProtPassword()
-{
-    static const OString saPass( "VelvetSweatshop" );
-    return saPass;
-}
-
-const OUString& BiffCodecHelper::getBiff8WbProtPassword()
+BiffDecoderRef lclReadFilePass_XOR( BiffInputStream& rStrm )
 {
-    static const OUString saPass = OStringToOUString( getBiff5WbProtPassword(), RTL_TEXTENCODING_ASCII_US );
-    return saPass;
-}
-
-OUString BiffCodecHelper::queryPassword()
-{
-    if( !mbHasPassword )
-    {
-        //! TODO
-        maPassword = OUString();
-        // set to true, even if dialog has been cancelled (never ask twice)
-        mbHasPassword = true;
-    }
-    return maPassword;
-}
-
-bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm )
-{
-    OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" );
-    rStrm.enableDecoder( false );
-    mxDecoder.reset();
-    if( getBiff() == BIFF8 ) importFilePass8( rStrm ); else importFilePass2( rStrm );
-
-    // set decoder at import stream
-    rStrm.setDecoder( mxDecoder );
-    //! TODO remember encryption state for export
-//    mrStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true;
-
-    return mxDecoder.get() && mxDecoder->isValid();
-}
-
-void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm )
-{
-    if( mxDecoder.get() )
-        rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) );
-}
-
-// private --------------------------------------------------------------------
-
-void BiffCodecHelper::importFilePass_XOR( BiffInputStream& rStrm )
-{
-    OSL_ENSURE( rStrm.getRemaining() == 4, "BiffCodecHelper::importFilePass_XOR - wrong record size" );
+    BiffDecoderRef xDecoder;
+    OSL_ENSURE( rStrm.getRemaining() == 4, "lclReadFilePass_XOR - wrong record size" );
     if( rStrm.getRemaining() == 4 )
     {
         sal_uInt16 nBaseKey, nHash;
         rStrm >> nBaseKey >> nHash;
-        mxDecoder.reset( new BiffDecoder_XOR( *this, nBaseKey, nHash ) );
+        xDecoder.reset( new BiffDecoder_XOR( nBaseKey, nHash ) );
     }
+    return xDecoder;
 }
 
-void BiffCodecHelper::importFilePass_RCF( BiffInputStream& rStrm )
+BiffDecoderRef lclReadFilePass_RCF( BiffInputStream& rStrm )
 {
-    OSL_ENSURE( rStrm.getRemaining() == 48, "BiffCodecHelper::importFilePass_RCF - wrong record size" );
+    BiffDecoderRef xDecoder;
+    OSL_ENSURE( rStrm.getRemaining() == 48, "lclReadFilePass_RCF - wrong record size" );
     if( rStrm.getRemaining() == 48 )
     {
-        sal_uInt8 pnDocId[ 16 ];
-        sal_uInt8 pnSaltData[ 16 ];
-        sal_uInt8 pnSaltHash[ 16 ];
-        rStrm.readMemory( pnDocId, 16 );
-        rStrm.readMemory( pnSaltData, 16 );
-        rStrm.readMemory( pnSaltHash, 16 );
-        mxDecoder.reset( new BiffDecoder_RCF( *this, pnDocId, pnSaltData, pnSaltHash ) );
+        sal_uInt8 pnSalt[ 16 ];
+        sal_uInt8 pnVerifier[ 16 ];
+        sal_uInt8 pnVerifierHash[ 16 ];
+        rStrm.readMemory( pnSalt, 16 );
+        rStrm.readMemory( pnVerifier, 16 );
+        rStrm.readMemory( pnVerifierHash, 16 );
+        xDecoder.reset( new BiffDecoder_RCF( pnSalt, pnVerifier, pnVerifierHash ) );
     }
+    return xDecoder;
 }
 
-void BiffCodecHelper::importFilePass_Strong( BiffInputStream& /*rStrm*/ )
+BiffDecoderRef lclReadFilePass_CryptoApi( BiffInputStream& /*rStrm*/ )
 {
     // not supported
+    return BiffDecoderRef();
 }
 
-void BiffCodecHelper::importFilePass2( BiffInputStream& rStrm )
-{
-    importFilePass_XOR( rStrm );
-}
-
-void BiffCodecHelper::importFilePass8( BiffInputStream& rStrm )
+BiffDecoderRef lclReadFilePassBiff8( BiffInputStream& rStrm )
 {
+    BiffDecoderRef xDecoder;
     switch( rStrm.readuInt16() )
     {
-        case BIFF_FILEPASS_BIFF2:
-            importFilePass_XOR( rStrm );
+        case BIFF_FILEPASS_XOR:
+            xDecoder = lclReadFilePass_XOR( rStrm );
         break;
 
-        case BIFF_FILEPASS_BIFF8:
+        case BIFF_FILEPASS_RCF:
+        {
+            sal_uInt16 nMajor = rStrm.readuInt16();
             rStrm.skip( 2 );
-            switch( rStrm.readuInt16() )
+            switch( nMajor )
             {
                 case BIFF_FILEPASS_BIFF8_RCF:
-                    importFilePass_RCF( rStrm );
+                    xDecoder = lclReadFilePass_RCF( rStrm );
                 break;
-                case BIFF_FILEPASS_BIFF8_STRONG:
-                    importFilePass_Strong( rStrm );
+                case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2003:
+                case BIFF_FILEPASS_BIFF8_CRYPTOAPI_2007:
+                    xDecoder = lclReadFilePass_CryptoApi( rStrm );
                 break;
                 default:
-                    OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown BIFF8 encryption sub mode" );
+                    OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown BIFF8 encryption sub mode" );
             }
+        }
         break;
 
         default:
-            OSL_ENSURE( false, "BiffCodecHelper::importFilePass8 - unknown encryption mode" );
+            OSL_ENSURE( false, "lclReadFilePassBiff8 - unknown encryption mode" );
     }
+    return xDecoder;
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+BiffCodecHelper::BiffCodecHelper( const WorkbookHelper& rHelper ) :
+    WorkbookHelper( rHelper )
+{
+}
+
+/*static*/ BiffDecoderRef BiffCodecHelper::implReadFilePass( BiffInputStream& rStrm, BiffType eBiff )
+{
+    rStrm.enableDecoder( false );
+    BiffDecoderRef xDecoder = (eBiff == BIFF8) ? lclReadFilePassBiff8( rStrm ) : lclReadFilePass_XOR( rStrm );
+    rStrm.setDecoder( xDecoder );
+    return xDecoder;
+}
+
+bool BiffCodecHelper::importFilePass( BiffInputStream& rStrm )
+{
+    OSL_ENSURE( !mxDecoder, "BiffCodecHelper::importFilePass - multiple FILEPASS records" );
+    mxDecoder = implReadFilePass( rStrm, getBiff() );
+    // request and verify a password (decoder implements IDocPasswordVerifier)
+    if( mxDecoder.get() )
+        getBaseFilter().requestPassword( *mxDecoder );
+    // correct password is indicated by isValid() function of decoder
+    return mxDecoder.get() && mxDecoder->isValid();
+}
+
+void BiffCodecHelper::cloneDecoder( BiffInputStream& rStrm )
+{
+    if( mxDecoder.get() )
+        rStrm.setDecoder( BiffDecoderRef( mxDecoder->clone() ) );
 }
 
 // ============================================================================
diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx
index d590487..1779cb4 100644
--- a/oox/source/xls/workbookfragment.cxx
+++ b/oox/source/xls/workbookfragment.cxx
@@ -101,8 +101,9 @@ ContextHandlerRef OoxWorkbookFragment::onCreateContext( sal_Int32 nElement, cons
                 case XLS_TOKEN( definedNames ):
                 case XLS_TOKEN( pivotCaches ):          return this;
 
-                case XLS_TOKEN( workbookPr ):           getWorkbookSettings().importWorkbookPr( rAttribs ); break;
-                case XLS_TOKEN( calcPr ):               getWorkbookSettings().importCalcPr( rAttribs );     break;
+                case XLS_TOKEN( fileSharing ):          getWorkbookSettings().importFileSharing( rAttribs );    break;
+                case XLS_TOKEN( workbookPr ):           getWorkbookSettings().importWorkbookPr( rAttribs );     break;
+                case XLS_TOKEN( calcPr ):               getWorkbookSettings().importCalcPr( rAttribs );         break;
             }
         break;
 
@@ -151,6 +152,7 @@ ContextHandlerRef OoxWorkbookFragment::onCreateRecordContext( sal_Int32 nRecId,
                 case OOBIN_ID_EXTERNALREFS:
                 case OOBIN_ID_PIVOTCACHES:      return this;
 
+                case OOBIN_ID_FILESHARING:      getWorkbookSettings().importFileSharing( rStrm );   break;
                 case OOBIN_ID_WORKBOOKPR:       getWorkbookSettings().importWorkbookPr( rStrm );    break;
                 case OOBIN_ID_CALCPR:           getWorkbookSettings().importCalcPr( rStrm );        break;
                 case OOBIN_ID_DEFINEDNAME:      getDefinedNames().importDefinedName( rStrm );       break;
@@ -402,7 +404,8 @@ bool BiffWorkbookFragment::importFragment()
     }
 
     // final conversions, e.g. calculation settings and view settings
-    finalizeWorkbookImport();
+    if( bRet )
+        finalizeWorkbookImport();
 
     return bRet;
 }
@@ -509,33 +512,35 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress
 
                 case BIFF3: switch( nRecId )
                 {
-                    case BIFF_ID_CRN:           bExtLinkRec = true;                     break;
-                    case BIFF3_ID_DEFINEDNAME:  bExtLinkRec = true;                     break;
-                    case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true;                     break;
-                    case BIFF_ID_EXTERNSHEET:   bExtLinkRec = true;                     break;
-                    case BIFF3_ID_FONT:         rStyles.importFont( mrStrm );           break;
-                    case BIFF2_ID_FORMAT:       rStyles.importFormat( mrStrm );         break;
-                    case BIFF_ID_HIDEOBJ:       rWorkbookSett.importHideObj( mrStrm );  break;
-                    case BIFF_ID_PALETTE:       rStyles.importPalette( mrStrm );        break;
-                    case BIFF_ID_STYLE:         rStyles.importStyle( mrStrm );          break;
-                    case BIFF_ID_XCT:           bExtLinkRec = true;                     break;
-                    case BIFF3_ID_XF:           rStyles.importXf( mrStrm );             break;
+                    case BIFF_ID_CRN:           bExtLinkRec = true;                         break;
+                    case BIFF3_ID_DEFINEDNAME:  bExtLinkRec = true;                         break;
+                    case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true;                         break;
+                    case BIFF_ID_EXTERNSHEET:   bExtLinkRec = true;                         break;
+                    case BIFF_ID_FILESHARING:   rWorkbookSett.importFileSharing( mrStrm );  break;
+                    case BIFF3_ID_FONT:         rStyles.importFont( mrStrm );               break;
+                    case BIFF2_ID_FORMAT:       rStyles.importFormat( mrStrm );             break;
+                    case BIFF_ID_HIDEOBJ:       rWorkbookSett.importHideObj( mrStrm );      break;
+                    case BIFF_ID_PALETTE:       rStyles.importPalette( mrStrm );            break;
+                    case BIFF_ID_STYLE:         rStyles.importStyle( mrStrm );              break;
+                    case BIFF_ID_XCT:           bExtLinkRec = true;                         break;
+                    case BIFF3_ID_XF:           rStyles.importXf( mrStrm );                 break;
                 }
                 break;
 
                 case BIFF4: switch( nRecId )
                 {
-                    case BIFF_ID_CRN:           bExtLinkRec = true;                     break;
-                    case BIFF3_ID_DEFINEDNAME:  bExtLinkRec = true;                     break;
-                    case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true;                     break;
-                    case BIFF_ID_EXTERNSHEET:   bExtLinkRec = true;                     break;
-                    case BIFF3_ID_FONT:         rStyles.importFont( mrStrm );           break;
-                    case BIFF4_ID_FORMAT:       rStyles.importFormat( mrStrm );         break;
-                    case BIFF_ID_HIDEOBJ:       rWorkbookSett.importHideObj( mrStrm );  break;
-                    case BIFF_ID_PALETTE:       rStyles.importPalette( mrStrm );        break;
-                    case BIFF_ID_STYLE:         rStyles.importStyle( mrStrm );          break;
-                    case BIFF_ID_XCT:           bExtLinkRec = true;                     break;
-                    case BIFF4_ID_XF:           rStyles.importXf( mrStrm );             break;
+                    case BIFF_ID_CRN:           bExtLinkRec = true;                         break;
+                    case BIFF3_ID_DEFINEDNAME:  bExtLinkRec = true;                         break;
+                    case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true;                         break;
+                    case BIFF_ID_EXTERNSHEET:   bExtLinkRec = true;                         break;
+                    case BIFF_ID_FILESHARING:   rWorkbookSett.importFileSharing( mrStrm );  break;
+                    case BIFF3_ID_FONT:         rStyles.importFont( mrStrm );               break;
+                    case BIFF4_ID_FORMAT:       rStyles.importFormat( mrStrm );             break;
+                    case BIFF_ID_HIDEOBJ:       rWorkbookSett.importHideObj( mrStrm );      break;
+                    case BIFF_ID_PALETTE:       rStyles.importPalette( mrStrm );            break;
+                    case BIFF_ID_STYLE:         rStyles.importStyle( mrStrm );              break;
+                    case BIFF_ID_XCT:           bExtLinkRec = true;                         break;
+                    case BIFF4_ID_XF:           rStyles.importXf( mrStrm );                 break;
                 }
                 break;
 
@@ -546,6 +551,7 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress
                     case BIFF5_ID_DEFINEDNAME:  bExtLinkRec = true;                         break;
                     case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true;                         break;
                     case BIFF_ID_EXTERNSHEET:   bExtLinkRec = true;                         break;
+                    case BIFF_ID_FILESHARING:   rWorkbookSett.importFileSharing( mrStrm );  break;
                     case BIFF5_ID_FONT:         rStyles.importFont( mrStrm );               break;
                     case BIFF4_ID_FORMAT:       rStyles.importFormat( mrStrm );             break;
                     case BIFF_ID_HIDEOBJ:       rWorkbookSett.importHideObj( mrStrm );      break;
@@ -567,6 +573,7 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress
                     case BIFF_ID_EXTERNALBOOK:  bExtLinkRec = true;                         break;
                     case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true;                         break;
                     case BIFF_ID_EXTERNSHEET:   bExtLinkRec = true;                         break;
+                    case BIFF_ID_FILESHARING:   rWorkbookSett.importFileSharing( mrStrm );  break;
                     case BIFF5_ID_FONT:         rStyles.importFont( mrStrm );               break;
                     case BIFF4_ID_FORMAT:       rStyles.importFormat( mrStrm );             break;
                     case BIFF_ID_HIDEOBJ:       rWorkbookSett.importHideObj( mrStrm );      break;
@@ -591,8 +598,11 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress
 
     // finalize global buffers
     rProgressBar.setPosition( 0.5 );
-    rSharedStrings.finalizeImport();
-    rStyles.finalizeImport();
+    if( bRet )
+    {
+        rSharedStrings.finalizeImport();
+        rStyles.finalizeImport();
+    }
 
     /*  Import external link data (EXTERNSHEET, EXTERNALNAME, DEFINEDNAME)
         which need existing internal sheets (SHEET records). The SHEET records
diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx
index b91315f..e4de0ff 100644
--- a/oox/source/xls/workbooksettings.cxx
+++ b/oox/source/xls/workbooksettings.cxx
@@ -32,10 +32,12 @@
 #include <com/sun/star/util/Date.hpp>
 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
 #include <com/sun/star/sheet/XCalculatable.hpp>
+#include <comphelper/mediadescriptor.hxx>
 #include "properties.hxx"
 #include "oox/helper/attributelist.hxx"
 #include "oox/helper/propertyset.hxx"
 #include "oox/helper/recordinputstream.hxx"
+#include "oox/core/filterbase.hxx"
 #include "oox/xls/biffinputstream.hxx"
 #include "oox/xls/unitconverter.hxx"
 
@@ -45,6 +47,7 @@ using ::com::sun::star::uno::UNO_QUERY;
 using ::com::sun::star::util::Date;
 using ::com::sun::star::util::XNumberFormatsSupplier;
 using ::com::sun::star::sheet::XCalculatable;
+using ::oox::core::CodecHelper;
 
 namespace oox {
 namespace xls {
@@ -73,6 +76,14 @@ const sal_Int16 API_SHOWMODE_PLACEHOLDER        = 2;        /// Show placeholder
 
 // ============================================================================
 
+FileSharingModel::FileSharingModel() :
+    mnPasswordHash( 0 ),
+    mbRecommendReadOnly( false )
+{
+}
+
+// ============================================================================
+
 WorkbookSettingsModel::WorkbookSettingsModel() :
     mnShowObjectMode( XML_all ),
     mnUpdateLinksMode( XML_userSet ),
@@ -113,6 +124,13 @@ WorkbookSettings::WorkbookSettings( const WorkbookHelper& rHelper ) :
 {
 }
 
+void WorkbookSettings::importFileSharing( const AttributeList& rAttribs )
+{
+    maFileSharing.maUserName          = rAttribs.getXString( XML_userName, OUString() );
+    maFileSharing.mnPasswordHash      = CodecHelper::getPasswordHash( rAttribs, XML_reservationPassword );
+    maFileSharing.mbRecommendReadOnly = rAttribs.getBool( XML_readOnlyRecommended, false );
+}
+
 void WorkbookSettings::importWorkbookPr( const AttributeList& rAttribs )
 {
     maBookSettings.maCodeName          = rAttribs.getString( XML_codePage, OUString() );
@@ -138,6 +156,12 @@ void WorkbookSettings::importCalcPr( const AttributeList& rAttribs )
     maCalcSettings.mbConcurrent    = rAttribs.getBool( XML_concurrentCalc, true );
 }
 
+void WorkbookSettings::importFileSharing( RecordInputStream& rStrm )
+{
+    maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0;
+    rStrm >> maFileSharing.mnPasswordHash >> maFileSharing.maUserName;
+}
+
 void WorkbookSettings::importWorkbookPr( RecordInputStream& rStrm )
 {
     sal_uInt32 nFlags;
@@ -170,6 +194,23 @@ void WorkbookSettings::setSaveExtLinkValues( bool bSaveExtLinks )
     maBookSettings.mbSaveExtLinkValues = bSaveExtLinks;
 }
 
+void WorkbookSettings::importFileSharing( BiffInputStream& rStrm )
+{
+    maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0;
+    rStrm >> maFileSharing.mnPasswordHash;
+    if( getBiff() == BIFF8 )
+    {
+        sal_uInt16 nStrLen = rStrm.readuInt16();
+        // there is no string flags field if string is empty
+        if( nStrLen > 0 )
+            maFileSharing.maUserName = rStrm.readUniStringBody( nStrLen );
+    }
+    else
+    {
+        maFileSharing.maUserName = rStrm.readByteStringUC( false, getTextEncoding() );
+    }
+}
+
 void WorkbookSettings::importBookBool( BiffInputStream& rStrm )
 {
     // value of 0 means save external values, value of 1 means strip external values
@@ -254,6 +295,10 @@ void WorkbookSettings::finalizeImport()
         break;
     }
 
+    // write protection
+    if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) )
+        getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true;
+
     // calculation settings
     Date aNullDate = getNullDate();
 
diff --git a/oox/source/xls/worksheetsettings.cxx b/oox/source/xls/worksheetsettings.cxx
index 48cc9c3..d791e48 100644
--- a/oox/source/xls/worksheetsettings.cxx
+++ b/oox/source/xls/worksheetsettings.cxx
@@ -41,6 +41,7 @@ using ::com::sun::star::uno::Exception;
 using ::com::sun::star::uno::Reference;
 using ::com::sun::star::uno::UNO_QUERY_THROW;
 using ::com::sun::star::util::XProtectable;
+using ::oox::core::CodecHelper;
 
 namespace oox {
 namespace xls {
@@ -112,16 +113,6 @@ SheetProtectionModel::SheetProtectionModel() :
 
 // ============================================================================
 
-namespace {
-
-sal_uInt16 lclGetCheckedHash( sal_Int32 nHash )
-{
-    OSL_ENSURE( (0 <= nHash) && (nHash <= SAL_MAX_UINT16), "lclGetCheckedHash - invalid password hash" );
-    return getLimitedValue< sal_uInt16, sal_Int32 >( nHash, 0, SAL_MAX_UINT16 );
-}
-
-} // namespace
-
 WorksheetSettings::WorksheetSettings( const WorksheetHelper& rHelper ) :
     WorksheetHelper( rHelper ),
     maPhoneticSett( rHelper )
@@ -153,7 +144,7 @@ void WorksheetSettings::importOutlinePr( const AttributeList& rAttribs )
 
 void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs )
 {
-    maSheetProt.mnPasswordHash     = lclGetCheckedHash( rAttribs.getIntegerHex( XML_password, 0 ) );
+    maSheetProt.mnPasswordHash     = CodecHelper::getPasswordHash( rAttribs, XML_password );
     maSheetProt.mbSheet            = rAttribs.getBool( XML_sheet, false );
     maSheetProt.mbObjects          = rAttribs.getBool( XML_objects, false );
     maSheetProt.mbScenarios        = rAttribs.getBool( XML_scenarios, false );
@@ -174,7 +165,7 @@ void WorksheetSettings::importSheetProtection( const AttributeList& rAttribs )
 
 void WorksheetSettings::importChartProtection( const AttributeList& rAttribs )
 {
-    maSheetProt.mnPasswordHash = lclGetCheckedHash( rAttribs.getIntegerHex( XML_password, 0 ) );
+    maSheetProt.mnPasswordHash = CodecHelper::getPasswordHash( rAttribs, XML_password );
     maSheetProt.mbSheet        = rAttribs.getBool( XML_content, false );
     maSheetProt.mbObjects      = rAttribs.getBool( XML_objects, false );
 }
diff --git a/oox/util/makefile.mk b/oox/util/makefile.mk
index f98003b..93669d2 100644
--- a/oox/util/makefile.mk
+++ b/oox/util/makefile.mk
@@ -74,6 +74,20 @@ SHL1STDLIBS= \
         $(BASEGFXLIB)	\
         $(SAXLIB)
 
+# link openssl, copied this bit from ucb/source/ucp/webdav/makefile.mk
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS+= $(OPENSSLLIB)
+.ELSE # WNT
+.IF "$(OS)"=="SOLARIS"
+SHL1STDLIBS+= -lnsl -lsocket -ldl
+.ENDIF # SOLARIS
+.IF "$(SYSTEM_OPENSSL)"=="YES"
+SHL1STDLIBS+= $(OPENSSLLIB)
+.ELSE
+SHL1STDLIBS+= $(OPENSSLLIBST)
+.ENDIF
+.ENDIF # WNT
+
 SHL1DEF=    $(MISC)$/$(SHL1TARGET).def
 SHL1LIBS=   $(LIB1TARGET)
 DEF1NAME    =$(SHL1TARGET)
diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx
index b67b7dd..af27bac 100644
--- a/writerfilter/source/filter/ImportFilter.cxx
+++ b/writerfilter/source/filter/ImportFilter.cxx
@@ -32,6 +32,8 @@
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/io/XInputStream.hpp>
+#include <comphelper/mediadescriptor.hxx>
+#include <oox/core/filterdetect.hxx>
 #include <dmapper/DomainMapper.hxx>
 #include <WriterFilter.hxx>
 #include <doctok/WW8Document.hxx>
@@ -44,6 +46,7 @@
 #include <resourcemodel/TagLogger.hxx>
 using namespace ::rtl;
 using namespace ::com::sun::star;
+using ::comphelper::MediaDescriptor;
 
 /*-- 09.06.2006 10:15:20---------------------------------------------------
 
@@ -62,28 +65,29 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes
         if (!xExprtr.is() || !xFltr.is())
             return sal_False;
         xExprtr->setSourceDocument(m_xSrcDoc);
-        if (xFltr->filter(aDescriptor))
-            return sal_True;
-        return sal_False;
+        return xFltr->filter(aDescriptor);
     }
     else if (m_xDstDoc.is())
     {
-
-    sal_Int32 nLength = aDescriptor.getLength();
-    const beans::PropertyValue * pValue = aDescriptor.getConstArray();
-    uno::Reference < io::XInputStream > xInputStream;
-    ::rtl::OUString sFilterName;
-    for ( sal_Int32 i = 0 ; i < nLength; i++)
-    {
-        if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
-            pValue[i].Value >>= xInputStream;
-        else if( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "FilterName" ) ) )
-            pValue[i].Value >>= sFilterName;
-    }
-    if ( !xInputStream.is() )
-    {
-        return sal_False;
-    }
+        MediaDescriptor aMediaDesc( aDescriptor );
+        OUString sFilterName = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_FILTERNAME(), OUString() );
+
+        uno::Reference< io::XInputStream > xInputStream;
+        try
+        {
+            // use the oox.core.FilterDetect implementation to extract the decrypted ZIP package
+            uno::Reference< lang::XMultiServiceFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_QUERY_THROW );
+            ::oox::core::FilterDetect aDetector( xFactory );
+            xInputStream = aDetector.extractUnencryptedPackage( aMediaDesc );
+        }
+        catch( uno::Exception& )
+        {
+        }
+
+        if ( !xInputStream.is() )
+        {
+            return sal_False;
+        }
 
 #ifdef DEBUG_ELEMENT
     writerfilter::TagLogger::Pointer_t debugLogger
diff --git a/writerfilter/util/makefile.mk b/writerfilter/util/makefile.mk
index 08033ab..4e99764 100644
--- a/writerfilter/util/makefile.mk
+++ b/writerfilter/util/makefile.mk
@@ -1,7 +1,7 @@
 #************************************************************************
 #
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
+#
 # Copyright 2008 by Sun Microsystems, Inc.
 #
 # OpenOffice.org - a multi-platform office productivity suite
@@ -63,7 +63,8 @@ SHL1STDLIBS=\
     $(CPPUHELPERLIB)    \
     $(COMPHELPERLIB)    \
     $(CPPULIB)          \
-    $(SALLIB)
+    $(SALLIB)			\
+    $(OOXLIB)
 
 
 SHL1DEPN=


More information about the ooo-build-commit mailing list