diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2009-09-17 13:53:54 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2009-09-17 13:53:54 +0000 |
commit | ca929afbdb49345507f6d3eb122a521dbb05ebdd (patch) | |
tree | 03fe827cd61b36b44dde8dc4e78fc7aff5ec0c6e | |
parent | e6c689f43a50e1dbda83f88ae1e0e43689cbe0c7 (diff) |
CWS-TOOLING: integrate CWS encsig09
2009-09-14 15:11:29 +0200 oc r276125 : #i105049# MacroSignatur needs Macro
2009-09-09 17:09:46 +0200 jl r276005 : #i103989# could not signe encrypted doc containing a formular object
2009-09-09 13:11:24 +0200 jl r275985 : #i103989# could not signe encrypted doc containing a formular object
2009-09-08 15:54:02 +0200 mav r275934 : #i103906# fix the automation test scenario ( tempfile should be writable for the user )
2009-09-07 14:01:39 +0200 mav r275895 : #i103906# fix the problem with reload
2009-09-07 09:34:48 +0200 mav r275871 : #i104786# do the ODF version check only for ODF documents
2009-09-07 08:19:06 +0200 mav r275870 : #i104389# fix text
2009-09-06 22:24:21 +0200 mav r275867 : #i104786# check the consistency of ODF version
2009-09-06 22:23:24 +0200 mav r275866 : #i104786# check the consistency of ODF version
2009-09-06 22:23:00 +0200 mav r275865 : #i104786# check the consistency of ODF version
2009-09-06 22:22:36 +0200 mav r275864 : #i104786# check the consistency of ODF version
2009-09-06 22:22:03 +0200 mav r275863 : #i104786# check the consistency of ODF version
2009-09-02 17:09:30 +0200 mav r275722 : #i104715# let repairing mechanics use the streams correctly
2009-09-01 16:52:49 +0200 mav r275670 : #i104389# notify user not to trust the corrupted document
2009-09-01 16:31:37 +0200 mav r275668 : #i104389# use vnd.sun.star.zip: protocol to access zip files
2009-09-01 16:30:32 +0200 mav r275667 : #i104389# use vnd.sun.star.zip: protocol to access zip files
2009-09-01 16:22:13 +0200 jl r275666 : #i104339# small content change
2009-09-01 14:20:42 +0200 jl r275660 : #i103519# remove some debug output
2009-09-01 13:51:52 +0200 jl r275659 : #i103519# NSS uses '\' for escaping in distinguished names
2009-09-01 12:49:47 +0200 mav r275655 : #i104389# use zip-mode to read from jar files
2009-09-01 12:40:22 +0200 mav r275653 : #i104389# use zip-mode to read from jar files
2009-09-01 12:32:29 +0200 mav r275652 : #i104389# use constants
2009-08-31 21:58:00 +0200 mav r275637 : #i10000# fix warning
2009-08-31 21:11:17 +0200 mav r275636 : #i104227# adding of scripting signature removes the document signature
2009-08-31 20:55:05 +0200 mav r275635 : #i103905# ZipStorage supports Compressed property
2009-08-31 20:53:55 +0200 mav r275634 : #i103905# adjust macro signature transfer to usage of ZipStorage
2009-08-31 15:30:49 +0200 jl r275609 : #i103989# warning is shown as long the user does not click 'OK'
2009-08-31 14:36:10 +0200 jl r275608 : #i103989# changed warning text when signing macro and there is a document signature. This warning is only displayed once
2009-08-31 13:34:41 +0200 mav r275603 : #i104452# disable macros in repaired documents
2009-08-31 13:33:42 +0200 mav r275602 : #i104452# disable macros in repaired documents
2009-08-31 13:03:56 +0200 jl r275600 : #i45212# signature dialog could not be started when using read-only documents
2009-08-31 09:26:13 +0200 mav r275583 : #i104578# store the additional entry as the last one to workaround parsing problem in OOo3.1 and later
2009-08-30 20:54:25 +0200 mav r275562 : #i10000# adopt for unix
2009-08-30 10:56:00 +0200 mav r275561 : CWS-TOOLING: rebase CWS encsig09 to trunk@275331 (milestone: DEV300:m56)
2009-08-28 16:34:00 +0200 mav r275539 : #i104578# write necessary info in manifest.xml for ODF1.2 encrypted document
2009-08-28 14:04:22 +0200 mav r275533 : #104587# fix handling of readonly streams
2009-08-28 13:58:10 +0200 mav r275531 : #i104389# fix the broken document handling
2009-08-28 11:40:39 +0200 mav r275522 : #i104389# fix the signature streams check
2009-08-27 21:48:12 +0200 mav r275509 : #i103927# show the warning
2009-08-27 21:47:48 +0200 mav r275508 : #i103927# show the warning
2009-08-27 16:45:59 +0200 jl r275495 : #i45212# remove unused variable
2009-08-27 16:34:00 +0200 jl r275494 : #i103989#
2009-08-27 13:54:28 +0200 jl r275482 : #i103519# fixed replacement of 'S' by 'ST'
2009-08-27 12:32:21 +0200 mav r275472 : #i10000# fix warning
2009-08-27 11:58:11 +0200 mav r275467 : #i104389# handle the entry path correctly
2009-08-26 17:18:35 +0200 jl r275438 : #i103519# subject and issuer distinguished names were not properly displayed. The strings were obtained by system functions (Windows, NSS), which use quotes to escape the values, when they contain special characters
2009-08-26 11:00:20 +0200 mav r275403 : #i10000# fix warnings
2009-08-26 08:25:45 +0200 mav r275392 : #i10000# fix warning
2009-08-26 08:02:22 +0200 mav r275391 : #i10000# adopt for linux
2009-08-26 07:40:30 +0200 mav r275390 : #i10000# fix warning
2009-08-26 07:35:28 +0200 mav r275389 : #i10000# use correct include file name
2009-08-25 15:01:41 +0200 jl r275356 : #i103989# better check for mimetype of streams
2009-08-25 09:07:09 +0200 mav r275335 : CWS-TOOLING: rebase CWS encsig09 to trunk@274622 (milestone: DEV300:m54)
2009-08-24 18:17:02 +0200 mav r275329 : #i103927# check the nonencrypted streams
2009-08-24 18:14:14 +0200 mav r275328 : #i103927# check the nonencrypted streams
2009-08-24 17:59:34 +0200 mav r275327 : #i103927#,#i104389# check the package consistency and nonencrypted streams
2009-08-24 16:18:28 +0200 jl r275323 : #i103989# added comment
2009-08-24 13:08:47 +0200 jl r275305 : #i45212# #i66276# only write the X509Certificate element once and allow to add remove several certificates at a time
2009-08-21 12:57:28 +0200 ufi r275239 : 104339
2009-08-21 08:39:05 +0200 jl r275213 : #i10398# comparing URIs of signed files with the 'element list'
2009-08-20 13:39:47 +0200 jl r275178 : #i10398# displaying 'new partially signed' status in the status bar
2009-08-20 13:35:39 +0200 jl r275177 : #i10398# displaying 'new partially signed' status in the status bar
2009-08-20 13:29:06 +0200 jl r275176 : #i10398# displaying 'new partially signed' status in the status bar
2009-08-20 13:26:21 +0200 jl r275175 : #i10398# displaying 'new partially signed' status in the status bar
2009-08-20 12:05:09 +0200 ufi r275170 : i104339
2009-08-19 12:24:54 +0200 jl r275146 : #i10398# displaying 'old signature' icon and status in signature dialog
2009-08-18 15:18:48 +0200 jl r275111 : #i103989# document signatures containing manifest.xml are now validated according to the final ODF1.2 spec
2009-08-18 11:41:06 +0200 mav r275087 : #i103927# detect if encrypted ODF1.2 document contains nonencrypted streams
2009-08-18 11:35:13 +0200 mav r275085 : #i103927# detect if encrypted ODF1.2 document contains nonencrypted streams
2009-08-14 17:32:41 +0200 jl r274999 : #i103989# using c14n tranformation for XML streams
2009-08-14 15:27:43 +0200 jl r274987 : #i103989# remove special handling for encrypted document streams in UriBindingHelper::OpenInputStream, since we use zip storage this is not necessary anymore
2009-08-14 15:08:10 +0200 jl r274983 : #i103989# Showing a message when adding or removing a macro signature, that the document signature will be removed
2009-08-14 14:57:27 +0200 jl r274982 : #i103989# accesing Sequence at invalid index
2009-08-11 08:55:02 +0200 mav r274846 : #i103905# let signing service know if there is already a valid document signature
2009-08-10 11:33:37 +0200 jl r274799 : #i103905# do not truncate the stream
2009-08-10 10:43:47 +0200 mav r274797 : #i103905# provide the storage version
2009-08-07 16:58:46 +0200 jl r274780 : #i103989#
2009-08-07 16:56:19 +0200 jl r274779 : #i103989# using odf version string etc.
2009-08-07 15:20:53 +0200 mav r274771 : #i103905# provide the storage version
2009-08-07 15:19:12 +0200 mav r274770 : #i103905# provide the storage version
2009-08-07 12:41:45 +0200 mav r274758 : #103930# do not store thumbnail in case of encrypted document
2009-08-07 12:36:52 +0200 mav r274757 : #i103905# provide the storage version
2009-08-07 12:15:54 +0200 mav r274754 : #i103760# the signed state is not lost on saving
2009-08-07 12:06:19 +0200 mav r274753 : #i103760# avoid warning regarding signature removal on export
2009-08-07 12:06:01 +0200 mav r274752 : #i103760# avoid warning regarding signature removal on export
2009-08-06 08:47:34 +0200 mav r274703 : #i103905# allow to transport ODF version to the signing component
2009-08-05 21:34:42 +0200 mav r274701 : #i103905# allow to transport ODF version to the signing component
2009-08-05 15:48:17 +0200 mav r274683 : #i103905# allow to transport ODF version to the signing component
2009-08-05 14:58:12 +0200 jl r274673 : #i103989# documentsignature now signes all streams except documentsignatures.xml, all streams are processed as binary files
2009-08-05 12:00:32 +0200 mav r274648 : #i103905# allow to transport ODF version to the signing component
2009-08-04 10:57:04 +0200 jl r274612 : #i103989# added XInitialization
2009-07-31 10:32:27 +0200 mav r274516 : #i103905# use zip storage to sign documents
2009-07-30 14:01:33 +0200 mav r274489 : #i103906# optimize the usage of temporary medium
2009-07-30 14:00:28 +0200 mav r274488 : #i103906# optimize the usage of temporary medium
2009-07-30 13:59:09 +0200 mav r274487 : #i103906# optimize the usage of temporary medium
2009-07-30 13:50:44 +0200 mav r274485 : #i103906# optimize the usage of temporary medium
2009-07-30 13:49:53 +0200 mav r274484 : #i103906# optimize the usage of temporary medium
2009-07-30 13:49:13 +0200 mav r274483 : #i103906# optimize the usage of temporary medium
2009-07-30 13:47:09 +0200 mav r274482 : #i103905#,#i103906# let the signing process use zip-storage; optimize the usage of temporary medium
2009-07-21 09:10:31 +0200 mav r274159 : CWS-TOOLING: rebase CWS encsig09 to trunk@273468 (milestone: DEV300:m51)
2009-05-05 08:39:01 +0200 mav r271496 : #i100832# allow to sign macros only when there are any
35 files changed, 943 insertions, 1116 deletions
diff --git a/sfx2/inc/guisaveas.hxx b/sfx2/inc/guisaveas.hxx index 13ac7a2350..f1de3d8fea 100644 --- a/sfx2/inc/guisaveas.hxx +++ b/sfx2/inc/guisaveas.hxx @@ -41,6 +41,7 @@ #include <com/sun/star/frame/XModuleManager.hpp> #include <comphelper/sequenceashashmap.hxx> +#include <sfx2/signaturestate.hxx> namespace com { namespace sun { namespace star { @@ -78,7 +79,8 @@ public: const ::rtl::OUString& aSlotName, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgsSequence, sal_Bool bPreselectPassword, - ::rtl::OUString aUserSelectedName ); + ::rtl::OUString aUserSelectedName, + sal_uInt16 nDocumentSignatureState = SIGNATURESTATE_NOSIGNATURES ); static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SearchForFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery >& xFilterQuery, diff --git a/sfx2/inc/sfx2/docfile.hxx b/sfx2/inc/sfx2/docfile.hxx index c92891acd5..ad63ad325c 100644 --- a/sfx2/inc/sfx2/docfile.hxx +++ b/sfx2/inc/sfx2/docfile.hxx @@ -199,8 +199,6 @@ public: void SetDataAvailableLink( const Link& rLink ); Link GetDataAvailableLink( ) const; - void SetClassFilter( const SvGlobalName & rFilterClass ); - sal_uInt32 GetMIMEAndRedirect( String& ); sal_uInt32 GetErrorCode() const; sal_uInt32 GetError() const @@ -227,17 +225,14 @@ public: SvEaMgr* GetEaMgr(); sal_Bool Commit(); - sal_Bool TryStorage(); - SAL_DLLPRIVATE ErrCode Unpack_Impl( const String& ); sal_Bool IsStorage(); sal_Int8 ShowLockedDocumentDialog( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aData, sal_Bool bIsLoading, sal_Bool bOwnLock ); sal_Bool LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ); void UnlockFile(); - ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetStorage(); + ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetStorage( sal_Bool bCreateTempIfNo = sal_True ); ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetOutputStorage(); - const SvGlobalName& GetClassFilter(); void ResetError(); sal_Bool UsesCache() const; void SetUsesCache( sal_Bool ); @@ -253,9 +248,8 @@ public: ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetInputStream(); - void CreateTempFile(); + void CreateTempFile( sal_Bool bReplace = sal_True ); void CreateTempFileNoCopy(); - void TryToSwitchToRepairedTemp(); ::rtl::OUString SwitchDocumentToTempFile(); sal_Bool SwitchDocumentToFile( ::rtl::OUString aURL ); @@ -264,24 +258,19 @@ public: ::rtl::OUString GetBaseURL( bool bForSaving=false ); #if _SOLAR__PRIVATE -//REMOVE // the storage will be truncated, if it is still not open then the stream will be truncated -//REMOVE ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetOutputStorage_Impl(); - SAL_DLLPRIVATE ::rtl::OUString GetOutputStorageURL_Impl(); SAL_DLLPRIVATE BOOL HasStorage_Impl() const; - SAL_DLLPRIVATE sal_Bool BasedOnOriginalFile_Impl(); SAL_DLLPRIVATE void StorageBackup_Impl(); SAL_DLLPRIVATE ::rtl::OUString GetBackup_Impl(); - SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetLastCommitReadStorage_Impl(); - SAL_DLLPRIVATE void CloseReadStorage_Impl(); + SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetZipStorageToSign_Impl( sal_Bool bReadOnly = sal_True ); + SAL_DLLPRIVATE void CloseZipStorage_Impl(); // the storage that will be returned by the medium on GetStorage request SAL_DLLPRIVATE void SetStorage_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xNewStorage ); SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetInputStream_Impl(); SAL_DLLPRIVATE void CloseAndReleaseStreams_Impl(); -//REMOVE SvStorage* GetStorage_Impl( BOOL bUCBStorage ); SAL_DLLPRIVATE void RefreshName_Impl(); SAL_DLLPRIVATE sal_uInt16 AddVersion_Impl( com::sun::star::util::RevisionTag& rVersion ); SAL_DLLPRIVATE sal_Bool TransferVersionList_Impl( SfxMedium& rMedium ); @@ -320,7 +309,6 @@ public: SAL_DLLPRIVATE void DataAvailable_Impl(); SAL_DLLPRIVATE void Cancel_Impl(); SAL_DLLPRIVATE void SetPhysicalName_Impl(const String& rName); - SAL_DLLPRIVATE void MoveTempTo_Impl( SfxMedium* pMedium ); SAL_DLLPRIVATE void CanDisposeStorage_Impl( sal_Bool bDisposeStorage ); SAL_DLLPRIVATE sal_Bool WillDisposeStorageOnClose_Impl(); @@ -340,7 +328,7 @@ public: const INetURLObject& aDest, const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv ); - SAL_DLLPRIVATE sal_Bool SignContents_Impl( sal_Bool bScriptingContent ); + SAL_DLLPRIVATE sal_Bool SignContents_Impl( sal_Bool bScriptingContent, const ::rtl::OUString& aODFVersion, sal_Bool bHasValidDocumentSignature ); // the following two methods must be used and make sence only during saving currently // TODO/LATER: in future the signature state should be controlled by the medium not by the document @@ -353,6 +341,9 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage ); static sal_Bool EqualURLs( const ::rtl::OUString& aFirstURL, const ::rtl::OUString& aSecondURL ); static ::rtl::OUString CreateTempCopyWithExt( const ::rtl::OUString& aURL ); + static sal_Bool CallApproveHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler, ::com::sun::star::uno::Any aRequest, sal_Bool bAllowAbort ); + + static sal_Bool SetWritableForUserOnly( const ::rtl::OUString& aURL ); }; SV_DECL_IMPL_REF( SfxMedium ) diff --git a/sfx2/inc/sfx2/docmacromode.hxx b/sfx2/inc/sfx2/docmacromode.hxx index 256c4cc1a3..1b45385f0a 100644 --- a/sfx2/inc/sfx2/docmacromode.hxx +++ b/sfx2/inc/sfx2/docmacromode.hxx @@ -114,10 +114,11 @@ namespace sfx2 virtual ::rtl::OUString getDocumentLocation() const = 0; - /** returns the storage to which the document has last been committed to, for read-only - access + /** returns a zip-storage based on the last commited version of the document, + for readonly access - An implementation is allowed to return <NULL/> here if and only if the document + The storage is intended to be used for signing. An implementation is + allowed to return <NULL/> here if and only if the document does not support signing the script storages. @todo @@ -126,7 +127,7 @@ namespace sfx2 XStorageBasedDocument. */ virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > - getLastCommitDocumentStorage() = 0; + getZipStorageToSign() = 0; /** checks whether the document's storage contains sub storages with macros or scripts @@ -161,7 +162,20 @@ namespace sfx2 @seealso <sfx2/signaturestate.hxx> */ virtual sal_Int16 - getScriptingSignatureState() const = 0; + getScriptingSignatureState() = 0; + + /** allows to detect whether there is a trusted scripting signature + + Note: On the medium run, the signature handling of a document should be outsourced + into a dedicated class, instead of being hard-wired into the SfxObjectShell. This + class could then be used outside the SfxObjectShell (e.g. in Base documents), too. + When this happens, this method here should be replaced by a method at this + new class. + + @seealso <sfx2/signaturestate.hxx> + */ + virtual sal_Bool + hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor ) = 0; /** shows a warning that the document's signature is broken diff --git a/sfx2/inc/sfx2/objsh.hxx b/sfx2/inc/sfx2/objsh.hxx index 3c2c0f2d7e..a2c1e1eb68 100644 --- a/sfx2/inc/sfx2/objsh.hxx +++ b/sfx2/inc/sfx2/objsh.hxx @@ -43,6 +43,7 @@ #include <com/sun/star/embed/XStorage.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/security/DocumentSignatureInformation.hpp> +#include <com/sun/star/security/XDocumentDigitalSignatures.hpp> #include <com/sun/star/task/XInteractionHandler.hpp> #include <com/sun/star/beans/XPropertySet.hpp> @@ -236,10 +237,6 @@ private: //REMOVE sal_Bool SaveInfoAndConfig_Impl( SvStorageRef pNewStg ); - SAL_DLLPRIVATE sal_uInt16 ImplCheckSignaturesInformation( - const ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignatureInformation >& aInfos ); - - //#endif protected: @@ -733,6 +730,9 @@ public: SAL_DLLPRIVATE void BreakMacroSign_Impl( sal_Bool bBreakMacroSing ); SAL_DLLPRIVATE void CheckSecurityOnLoading_Impl(); SAL_DLLPRIVATE void CheckForBrokenDocSignatures_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ); + SAL_DLLPRIVATE sal_uInt16 ImplCheckSignaturesInformation( + const ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignatureInformation >& aInfos ); + SAL_DLLPRIVATE void CheckEncryption_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ); SAL_DLLPRIVATE static SEQUENCE< OUSTRING > GetEventNames_Impl(); SAL_DLLPRIVATE void InitBasicManager_Impl(); @@ -797,6 +797,13 @@ public: SAL_DLLPRIVATE SfxAcceleratorManager* GetAccMgr_Impl(); SAL_DLLPRIVATE SfxToolBoxConfig* GetToolBoxConfig_Impl(); SAL_DLLPRIVATE sal_uInt16 ImplGetSignatureState( sal_Bool bScriptingContent = FALSE ); + + SAL_DLLPRIVATE ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignatureInformation > + ImplAnalyzeSignature( + sal_Bool bScriptingContent, + const ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures >& xSigner + = ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures >() ); + SAL_DLLPRIVATE void ImplSign( sal_Bool bScriptingContent = FALSE ); SAL_DLLPRIVATE sal_Bool QuerySaveSizeExceededModules_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ); //#endif diff --git a/sfx2/inc/sfx2/signaturestate.hxx b/sfx2/inc/sfx2/signaturestate.hxx index b6a0b83d0d..a75114ea98 100644 --- a/sfx2/inc/sfx2/signaturestate.hxx +++ b/sfx2/inc/sfx2/signaturestate.hxx @@ -36,7 +36,12 @@ #define SIGNATURESTATE_NOSIGNATURES (sal_Int16)0 #define SIGNATURESTATE_SIGNATURES_OK (sal_Int16)1 #define SIGNATURESTATE_SIGNATURES_BROKEN (sal_Int16)2 -#define SIGNATURESTATE_SIGNATURES_INVALID (sal_Int16)3 // State was SIGNATURES_OK, but doc is modified now -#define SIGNATURESTATE_SIGNATURES_NOTVALIDATED (sal_Int16)4 // signature is OK, but certificate could not be validated +// State was SIGNATURES_OK, but doc is modified now +#define SIGNATURESTATE_SIGNATURES_INVALID (sal_Int16)3 +// signature is OK, but certificate could not be validated +#define SIGNATURESTATE_SIGNATURES_NOTVALIDATED (sal_Int16)4 +//signatur and certificate are ok,but not al files are signed, as was the case in +//OOo 2.x - OOo 3.1.1. This state is only used together with document signatures. +#define SIGNATURESTATE_SIGNATURES_PARTIAL_OK (sal_Int16)5 #endif // SFX2_SIGNATURESTATE_HXX diff --git a/sfx2/source/appl/appopen.cxx b/sfx2/source/appl/appopen.cxx index 669a76ba0c..17b7b432eb 100644 --- a/sfx2/source/appl/appopen.cxx +++ b/sfx2/source/appl/appopen.cxx @@ -311,7 +311,7 @@ sal_uInt32 CheckPasswd_Impl if( ( !pFile->GetFilter() || pFile->IsStorage() ) ) { - uno::Reference< embed::XStorage > xStorage = pFile->GetStorage(); + uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( sal_True ); if( xStorage.is() ) { uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY ); @@ -392,7 +392,7 @@ ULONG SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const String &rFil const SfxFilter* pFilter = NULL; SfxMedium aMedium( rFileName, ( STREAM_READ | STREAM_SHARE_DENYNONE ), FALSE ); - if ( !aMedium.GetStorage().is() ) + if ( !aMedium.GetStorage( sal_True ).is() ) aMedium.GetInStream(); if ( aMedium.GetError() ) diff --git a/sfx2/source/bastyp/helper.cxx b/sfx2/source/bastyp/helper.cxx index ce486552f2..80ac52b902 100644 --- a/sfx2/source/bastyp/helper.cxx +++ b/sfx2/source/bastyp/helper.cxx @@ -820,39 +820,6 @@ ULONG SfxContentHelper::GetSize( const String& rContent ) } // ----------------------------------------------------------------------- - -sal_Bool SfxContentHelper::IsYounger( const String& rIsYoung, const String& rIsOlder ) -{ - DateTime aYoungDate, aOlderDate; - INetURLObject aYoungObj( rIsYoung ); - DBG_ASSERT( aYoungObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); - INetURLObject aOlderObj( rIsOlder ); - DBG_ASSERT( aOlderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); - try - { - uno::Reference< ucb::XCommandEnvironment > aCmdEnv; - ::ucbhelper::Content aYoung( aYoungObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); - util::DateTime aTempYoungDate; - aYoung.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempYoungDate; - CONVERT_DATETIME( aTempYoungDate, aYoungDate ); - ::ucbhelper::Content aOlder( aOlderObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); - util::DateTime aTempOlderDate; - aOlder.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aTempOlderDate; - CONVERT_DATETIME( aTempOlderDate, aOlderDate ); - } - catch( ucb::CommandAbortedException& ) - { - DBG_ERRORFILE( "CommandAbortedException" ); - } - catch( uno::Exception& ) - { - DBG_ERRORFILE( "Any other exception" ); - } - - return ( aYoungDate > aOlderDate ); -} - -// ----------------------------------------------------------------------- // please don't use it (only used in appbas.cxx and appcfg.cxx) sal_Bool SfxContentHelper::Exists( const String& rContent ) { diff --git a/sfx2/source/bastyp/progress.cxx b/sfx2/source/bastyp/progress.cxx index 092dc73cf0..06791f4435 100644 --- a/sfx2/source/bastyp/progress.cxx +++ b/sfx2/source/bastyp/progress.cxx @@ -117,20 +117,8 @@ struct SfxProgress_Impl : public SfxCancellable #define aTypeLibInfo aProgressTypeLibImpl //======================================================================== -#if defined(_MSC_VER) && (_MSC_VER < 1300) -inline ULONG Get10ThSec() -{ -#if defined (MSC) && defined (WIN) - ULONG n10Ticks = 10 * (ULONG)GetTickCount(); -#else - ULONG n10Ticks = 10 * (ULONG)clock(); -#endif - - return n10Ticks / CLOCKS_PER_SEC; -} -#else extern ULONG Get10ThSec(); -#endif + // ----------------------------------------------------------------------- void SfxProgress_Impl::Enable_Impl( BOOL bEnable ) diff --git a/sfx2/source/dialog/dinfdlg.cxx b/sfx2/source/dialog/dinfdlg.cxx index d3839f7986..d6be5de2a1 100644 --- a/sfx2/source/dialog/dinfdlg.cxx +++ b/sfx2/source/dialog/dinfdlg.cxx @@ -899,7 +899,7 @@ void SfxDocumentPage::ImplUpdateSignatures() { String s; Sequence< security::DocumentSignatureInformation > aInfos; - aInfos = xD->verifyDocumentContentSignatures( pMedium->GetLastCommitReadStorage_Impl(), + aInfos = xD->verifyDocumentContentSignatures( pMedium->GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() ); if( aInfos.getLength() > 1 ) { diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 0683eaa415..f44ac7c3ec 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -84,6 +84,7 @@ #include <unotools/tempfile.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/componentcontext.hxx> +#include <framework/interaction.hxx> #include <unotools/streamhelper.hxx> #include <unotools/localedatawrapper.hxx> #ifndef _MSGBOX_HXX //autogen @@ -106,6 +107,7 @@ #include <unotools/streamwrap.hxx> #include <rtl/logfile.hxx> +#include <osl/file.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -373,10 +375,9 @@ public: uno::Sequence < util::RevisionTag > aVersions; - ::utl::TempFile* pTempDir; ::utl::TempFile* pTempFile; - uno::Reference < embed::XStorage > m_xReadStorage; + uno::Reference < embed::XStorage > m_xZipStorage; Reference < XInputStream > xInputStream; Reference < XStream > xStream; @@ -452,7 +453,6 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP ) nFileVersion( 0 ), pOrigFilter( 0 ), aExpireTime( Date() + 10, Time() ), - pTempDir( NULL ), pTempFile( NULL ), nLastStorageError( 0 ), m_bRemoveBackup( sal_False ), @@ -470,9 +470,6 @@ SfxMedium_Impl::~SfxMedium_Impl() if ( pTempFile ) delete pTempFile; - - if ( pTempDir ) - delete pTempDir; } //================================================================ @@ -491,18 +488,6 @@ SfxMedium_Impl::~SfxMedium_Impl() pOutStream( 0 ) //------------------------------------------------------------------ -/* -const SvGlobalName& SfxMedium::GetClassFilter() -{ - GetMedium_Impl(); - if( GetError() ) - return aFilterClass; - if( !bSetFilter && GetStorage() ) - SetClassFilter( GetStorage()->GetClassName() ); - return aFilterClass; -}*/ - -//------------------------------------------------------------------ void SfxMedium::ResetError() { eError = SVSTREAM_OK; @@ -557,15 +542,6 @@ sal_uInt32 SfxMedium::GetErrorCode() const } //------------------------------------------------------------------ -long SfxMedium::GetFileVersion() const -{ - if ( !pImp->nFileVersion && pFilter ) - return pFilter->GetVersion(); - else - return pImp->nFileVersion; -} - -//------------------------------------------------------------------ void SfxMedium::CheckFileDate( const util::DateTime& aInitDate ) { GetInitFileDate( sal_True ); @@ -665,6 +641,7 @@ Reference < XContent > SfxMedium::GetContent() const return pImp->aContent.get(); } +//------------------------------------------------------------------ ::rtl::OUString SfxMedium::GetBaseURL( bool bForSaving ) { ::rtl::OUString aBaseURL; @@ -703,7 +680,7 @@ SvStream* SfxMedium::GetInStream() if ( pInStream ) return pInStream; - if ( pImp->pTempFile || pImp->pTempDir ) + if ( pImp->pTempFile ) { pInStream = new SvFileStream( aName, nStorOpenMode ); @@ -747,7 +724,7 @@ void SfxMedium::CloseInStream_Impl() if ( pInStream && !GetContent().is() ) { - CreateTempFile(); + CreateTempFile( sal_True ); return; } @@ -755,7 +732,7 @@ void SfxMedium::CloseInStream_Impl() if ( pSet ) pSet->ClearItem( SID_INPUTSTREAM ); - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); pImp->xInputStream = uno::Reference< io::XInputStream >(); if ( !pOutStream ) @@ -775,8 +752,7 @@ SvStream* SfxMedium::GetOutStream() { // Create a temp. file if there is none because we always // need one. - if ( !pImp->pTempFile ) - CreateTempFile(); + CreateTempFile( sal_False ); if ( pImp->pTempFile ) { @@ -844,8 +820,7 @@ void SfxMedium::CreateFileStream() GetInStream(); if( pInStream ) { - if ( !pImp->pTempFile ) - CreateTempFile(); + CreateTempFile( sal_False ); pImp->bIsTemp = sal_True; CloseInStream_Impl(); } @@ -942,82 +917,17 @@ sal_Bool SfxMedium::IsPreview_Impl() } //------------------------------------------------------------------ -sal_Bool SfxMedium::TryStorage() -{ - GetStorage(); - - if ( pImp->xStorage.is() ) - return sal_True; - - // this code will be removed when binary filter components are available! - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() ); - ::com::sun::star::uno::Reference< ::com::sun::star::util::XArchiver > - xPacker( xSMgr->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.util.Archiver" ) ), ::com::sun::star::uno::UNO_QUERY ); - - if( !xPacker.is() ) - return sal_False; - - // extract extra data - ::rtl::OUString aPath = GetURLObject().PathToFileName(); - ::rtl::OUString aExtraData = xPacker->getExtraData( aPath ); - const ::rtl::OUString aSig1( DEFINE_CONST_UNICODE( "private:" ) ); - String aTmp( '?' ); - aTmp += String::CreateFromAscii("simpress");//pFilter->GetFilterContainer()->GetName(); - const ::rtl::OUString aSig2( aTmp ); - sal_Int32 nIndex1 = aExtraData.indexOf( aSig1 ); - sal_Int32 nIndex2 = aExtraData.indexOf( aSig2 ); - - if( nIndex1 != 0 || nIndex2 == -1 ) - return sal_False; - - nIndex1 += aSig1.getLength(); - ::rtl::OUString aTempDoku = aExtraData.copy( nIndex1, nIndex2 - nIndex1 ); - - // create a temp dir to unpack to - pImp->pTempDir = new ::utl::TempFile( NULL, sal_True ); - pImp->pTempDir->EnableKillingFile( sal_True ); - - // unpack all files to temp dir - ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; - com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler(); - if (xInteractionHandler.is()) - { - aArgs.realloc(1); - aArgs.getArray()[0].Name = DEFINE_CONST_UNICODE( "InteractionHandler" ); - aArgs.getArray()[0].Value <<= xInteractionHandler ; - } - ::com::sun::star::uno::Sequence< ::rtl::OUString > files(0); - - if( !xPacker->unpack( pImp->pTempDir->GetURL(), aPath, files, aArgs ) ) - return sal_False; - - String aNewName = pImp->pTempDir->GetURL(); - aNewName += '/'; - aNewName += String( aTempDoku ); - CloseInStream_Impl(); - String aTemp; - ::utl::LocalFileHelper::ConvertURLToPhysicalName( aNewName, aTemp ); - SetPhysicalName_Impl( aTemp ); - GetStorage(); - - return pImp->xStorage.is(); -} - -//------------------------------------------------------------------ -sal_Bool SfxMedium::BasedOnOriginalFile_Impl() -{ - return ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode ) - && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength() - && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) - && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ); -} - -//------------------------------------------------------------------ void SfxMedium::StorageBackup_Impl() { ::ucbhelper::Content aOriginalContent; Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv; - if ( BasedOnOriginalFile_Impl() && !pImp->m_aBackupURL.getLength() + + sal_Bool bBasedOnOriginalFile = ( !pImp->pTempFile && !( aLogicName.Len() && pImp->m_bSalvageMode ) + && GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).getLength() + && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) + && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ); + + if ( bBasedOnOriginalFile && !pImp->m_aBackupURL.getLength() && ::ucbhelper::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aOriginalContent ) ) { DoInternalBackup_Impl( aOriginalContent ); @@ -1036,26 +946,6 @@ void SfxMedium::StorageBackup_Impl() } //------------------------------------------------------------------ -::rtl::OUString SfxMedium::GetOutputStorageURL_Impl() -{ - String aStorageName; - - if ( aName.Len() ) - { - if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) ) - { - DBG_ERROR("Physical name not convertable!"); - } - } - else - { - aStorageName = GetURLObject().GetMainURL( INetURLObject::NO_DECODE ); - } - - return aStorageName; -} - -//------------------------------------------------------------------ uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage() { if ( GetError() ) @@ -1249,7 +1139,9 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ) try { // MediaDescriptor does this check also, the duplication should be avoided in future - pImp->aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly; + Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aContent( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + aContent.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ) >>= bContentReadonly; } catch( uno::Exception ) {} @@ -1420,222 +1312,82 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ) } //------------------------------------------------------------------ -uno::Reference < embed::XStorage > SfxMedium::GetStorage() +uno::Reference < embed::XStorage > SfxMedium::GetStorage( sal_Bool bCreateTempIfNo ) { if ( pImp->xStorage.is() || bTriedStorage ) return pImp->xStorage; uno::Sequence< uno::Any > aArgs( 2 ); - String aStorageName; - if ( pImp->pTempFile || pImp->pTempDir ) - { - // open storage from the temporary file - if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) ) - { - DBG_ERROR("Physical name not convertable!"); - } + // the medium should be retrieved before temporary file creation + // to let the MediaDescriptor be filled with the streams + GetMedium_Impl(); - CloseOutStream(); - // create the set of the streams based on the temporary file - GetMedium_Impl(); + if ( bCreateTempIfNo ) + CreateTempFile( sal_False ); - OSL_ENSURE( pImp->xStream.is(), "It must be possible to create read write stream access!" ); - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - CloseStreams_Impl(); - aArgs[0] <<= ::rtl::OUString( aName ); - pImp->bStorageBasedOnInStream = sal_False; - } + GetMedium_Impl(); - aArgs[1] <<= ( nStorOpenMode&STREAM_WRITE ? embed::ElementModes::READWRITE : embed::ElementModes::READ ); + if ( GetError() ) + return pImp->xStorage; - try - { - pImp->xStorage = uno::Reference< embed::XStorage >( - ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), - uno::UNO_QUERY ); - } - catch( uno::Exception& ) - { - //TODO/LATER: error handling; Error and LastStorageError - } - } - else + SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False); + if ( pRepairItem && pRepairItem->GetValue() ) { - // open the storage from original location - { - GetMedium_Impl(); - if ( GetError() ) - return pImp->xStorage; - - try - { - if ( IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( aLogicName ) ) - { - //TODO/LATER: performance problem if not controlled by special Mode in SfxMedium - //(should be done only for permanently open storages) - // create a copy, the following method will close all existing streams - CreateTempFile(); - - // create the set of the streams based on the temporary file - GetMedium_Impl(); - - OSL_ENSURE( pImp->xStream.is(), "It must be possible to create read write stream access!" ); - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - CloseStreams_Impl(); - aArgs[0] <<= ::rtl::OUString( aName ); - pImp->bStorageBasedOnInStream = sal_False; - } - - aArgs[1] <<= embed::ElementModes::READWRITE; - - } - else - { - // there is no explicit request to open the document readonly - - // create a storage on the stream - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - aArgs[1] <<= ( ( nStorOpenMode & STREAM_WRITE ) ? - embed::ElementModes::READWRITE : embed::ElementModes::READ ); - - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - // no readwrite stream, but it can be a case of http protocol - sal_Bool bReadOnly = sal_False; - - if ( aLogicName.CompareToAscii( "private:stream", 14 ) != COMPARE_EQUAL - && GetContent().is() ) - { - // unfortunately the content can not always have the interaction handler - // so in some cases it has to be set for some time - Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv; - Reference < ::com::sun::star::ucb::XCommandEnvironment > xOldEnv; - Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler = ((SfxMedium*)this)->GetInteractionHandler(); - if ( xInteractionHandler.is() ) - xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, - Reference< ::com::sun::star::ucb::XProgressHandler >() ); - - if ( xEnv.is() ) - { - xOldEnv = pImp->aContent.getCommandEnvironment(); - pImp->aContent.setCommandEnvironment( xEnv ); - } - - try - { - Any aAny = pImp->aContent.getPropertyValue( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsReadOnly" )) ); - - if ( ( aAny >>= bReadOnly ) && bReadOnly ) - { - GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, sal_True)); - SetOpenMode( SFX_STREAM_READONLY, sal_False, sal_True ); - } - } - catch( uno::Exception& ) - {} - - if ( xEnv.is() ) - pImp->aContent.setCommandEnvironment( xOldEnv ); - } - - // if the document is opened as readonly the copy should be done according to selected approach - // if the document is opened for editing the copy should be done to use it as a temporary location for changes before the final transfer - // the following method will close all existing streams - CreateTempFile(); - - // create the set of the streams based on the temporary file - GetMedium_Impl(); - - OSL_ENSURE( pImp->xStream.is(), "It must be possible to create read write stream access!" ); - if ( pImp->xStream.is() ) - { - aArgs[0] <<= pImp->xStream; - pImp->bStorageBasedOnInStream = sal_True; - } - else - { - CloseStreams_Impl(); - aArgs[0] <<= ::rtl::OUString( aName ); - pImp->bStorageBasedOnInStream = sal_False; - } + // the storage should be created for repairing mode + CreateTempFile( sal_False ); + GetMedium_Impl(); - if ( bReadOnly ) - aArgs[1] <<= embed::ElementModes::READ; - else - aArgs[1] <<= embed::ElementModes::READWRITE; - } - } + Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler; + Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator; - SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False); - if ( pRepairItem && pRepairItem->GetValue() ) - { - // the storage should be created for repairing mode - CreateTempFile(); - Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler; - Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator; - - SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False ); - if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) ) - xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >( - new utl::ProgressHandlerWrap( xStatusIndicator ) ); - - uno::Sequence< beans::PropertyValue > aAddProps( 2 ); - aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" ); - aAddProps[0].Value <<= (sal_Bool)sal_True; - aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" ); - aAddProps[1].Value <<= xProgressHandler; - - aArgs.realloc( 3 ); - aArgs[0] <<= ::rtl::OUString( aName ); - aArgs[1] <<= embed::ElementModes::READWRITE; - aArgs[2] <<= aAddProps; + SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False ); + if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) ) + xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >( + new utl::ProgressHandlerWrap( xStatusIndicator ) ); - pImp->bStorageBasedOnInStream = sal_False; - } + uno::Sequence< beans::PropertyValue > aAddProps( 2 ); + aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" ); + aAddProps[0].Value <<= (sal_Bool)sal_True; + aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" ); + aAddProps[1].Value <<= xProgressHandler; - pImp->xStorage = uno::Reference< embed::XStorage >( - ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), - uno::UNO_QUERY ); + // the first arguments will be filled later + aArgs.realloc( 3 ); + aArgs[2] <<= aAddProps; + } - if ( !pImp->xStorage.is() ) - throw uno::RuntimeException(); + if ( pImp->xStream.is() ) + { + // since the storage is based on temporary stream we open it always read-write + aArgs[0] <<= pImp->xStream; + aArgs[1] <<= embed::ElementModes::READWRITE; + pImp->bStorageBasedOnInStream = sal_True; + } + else if ( pImp->xInputStream.is() ) + { + // since the storage is based on temporary stream we open it always read-write + aArgs[0] <<= pImp->xInputStream; + aArgs[1] <<= embed::ElementModes::READ; + pImp->bStorageBasedOnInStream = sal_True; + } + else + { + CloseStreams_Impl(); + aArgs[0] <<= ::rtl::OUString( aName ); + aArgs[1] <<= embed::ElementModes::READ; + pImp->bStorageBasedOnInStream = sal_False; + } - if ( pRepairItem && pRepairItem->GetValue() ) - { - // in repairing mode the mediatype required by filter should be used - ::rtl::OUString aMediaType; - ::rtl::OUString aMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); - uno::Reference < beans::XPropertySet > xPropSet( pImp->xStorage, uno::UNO_QUERY_THROW ); - xPropSet->getPropertyValue( aMediaTypePropName ) >>= aMediaType; - if ( !aMediaType.getLength() && pFilter ) - xPropSet->setPropertyValue( aMediaTypePropName, - uno::makeAny( ::rtl::OUString( pFilter->GetMimeType() ) ) ); - } - } - catch ( uno::Exception& ) - { - //TODO/MBA: error handling; Error and LastStorageError - pImp->bStorageBasedOnInStream = sal_False; - } - } + try + { + pImp->xStorage = uno::Reference< embed::XStorage >( + ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), + uno::UNO_QUERY ); + } + catch( uno::Exception& ) + { + // impossibility to create the storage is no error } if( ( pImp->nLastStorageError = GetError() ) != SVSTREAM_OK ) @@ -1643,13 +1395,12 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage() pImp->xStorage = 0; if ( pInStream ) pInStream->Seek(0); - return NULL; + return uno::Reference< embed::XStorage >(); } bTriedStorage = sal_True; - //TODO/MBA: error handling; Error and LastStorageError - //if ( aStorage->GetError() == SVSTREAM_OK ) + // TODO/LATER: Get versionlist on demand if ( pImp->xStorage.is() ) { SetPasswordToStorage_Impl(); @@ -1716,15 +1467,6 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage() bResetStorage = TRUE; } - //TODO/MBA: error handling; Error and LastStorageError - if ( pImp->xStorage.is() ) - { /* - if( ( pImp->nLastStorageError = aStorage->GetError() ) != SVSTREAM_OK ) - bResetStorage = TRUE; - else if ( GetFilter() ) - aStorage->SetVersion( GetFilter()->GetVersion() );*/ - } - if ( bResetStorage ) { pImp->xStorage = 0; @@ -1737,28 +1479,25 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage() } //------------------------------------------------------------------ -uno::Reference< embed::XStorage > SfxMedium::GetLastCommitReadStorage_Impl() +uno::Reference< embed::XStorage > SfxMedium::GetZipStorageToSign_Impl( sal_Bool bReadOnly ) { - if ( !GetError() && !pImp->m_xReadStorage.is() ) + if ( !GetError() && !pImp->m_xZipStorage.is() ) { + // very careful!!! + // if bReadOnly == sal_False and there is no temporary file the original file might be used GetMedium_Impl(); try { - if ( pImp->xInputStream.is() ) + // we can not sign document if there is no stream + // should it be possible at all? + if ( !bReadOnly && pImp->xStream.is() ) { - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[0] <<= pImp->xInputStream; - aArgs[1] <<= embed::ElementModes::READ; - pImp->m_xReadStorage = uno::Reference< embed::XStorage >( - ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ), - uno::UNO_QUERY ); + pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream, embed::ElementModes::READWRITE ); } - else if ( GetStorage().is() ) + else if ( pImp->xInputStream.is() ) { - uno::Reference< embed::XStorage > xTempStor = ::comphelper::OStorageHelper::GetTemporaryStorage(); - GetStorage()->copyLastCommitTo( xTempStor ); - pImp->m_xReadStorage = xTempStor; + pImp->m_xZipStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( ZIP_STORAGE_FORMAT_STRING, pImp->xInputStream ); } } catch( uno::Exception& ) @@ -1770,20 +1509,20 @@ uno::Reference< embed::XStorage > SfxMedium::GetLastCommitReadStorage_Impl() ResetError(); } - return pImp->m_xReadStorage; + return pImp->m_xZipStorage; } //------------------------------------------------------------------ -void SfxMedium::CloseReadStorage_Impl() +void SfxMedium::CloseZipStorage_Impl() { - if ( pImp->m_xReadStorage.is() ) + if ( pImp->m_xZipStorage.is() ) { try { - pImp->m_xReadStorage->dispose(); + pImp->m_xZipStorage->dispose(); } catch( uno::Exception& ) {} - pImp->m_xReadStorage = uno::Reference< embed::XStorage >(); + pImp->m_xZipStorage = uno::Reference< embed::XStorage >(); } } @@ -1885,11 +1624,12 @@ sal_Bool SfxMedium::StorageCommit_Impl() try { xTrans->commit(); - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); bResult = sal_True; } catch ( embed::UseBackupException& aBackupExc ) { + // since the temporary file is created always now, the scenario is close to be impossible if ( !pImp->pTempFile ) { OSL_ENSURE( pImp->m_aBackupURL.getLength(), "No backup on storage commit!\n" ); @@ -1936,9 +1676,6 @@ sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource, Reference< XOutputStream > aDestStream; ::ucbhelper::Content aOriginalContent; -// actualy it should work even for contents different from file content -// DBG_ASSERT( ::utl::LocalFileHelper::IsLocalFile( aDest.GetMainURL( INetURLObject::NO_DECODE ) ), -// "SfxMedium::TransactedTransferForFS() should be used only for local contents!" ); try { aOriginalContent = ::ucbhelper::Content( aDest.GetMainURL( INetURLObject::NO_DECODE ), xComEnv ); @@ -2241,57 +1978,10 @@ void SfxMedium::Transfer_Impl() catch ( uno::Exception& ) { //TODO/MBA: error handling - //if ( !GetError() ) - // SetError( xStor->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) ); } return; } - if ( pFilter && SOFFICE_FILEFORMAT_60 <= pFilter->GetVersion() ) - { - //TODO/LATER: how?! - /* - SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_UNPACK, sal_False); - if ( pItem && pItem->GetValue() ) - { - // this file must be stored without packing into a JAR file - // check for an existing unpacked storage - SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( GetName(), STREAM_STD_READ ); - if ( !pStream->GetError() ) - { - String aURL = UCBStorage::GetLinkedFile( *pStream ); - if ( aURL.Len() ) - // remove a possibly existing old folder - ::utl::UCBContentHelper::Kill( aURL ); - - DELETEZ( pStream ); - } - - // create a new folder based storage - SvStorageRef xStor = new SvStorage( TRUE, GetName(), STREAM_STD_READWRITE, STORAGE_CREATE_UNPACKED ); - - // copy package into unpacked storage - if ( xStor->GetError() == ERRCODE_NONE && GetStorage()->copyToStorage( xStor ) ) - { - // commit changes, writing will happen now - xStor->Commit(); - - // take new unpacked storage as own storage - if ( pImp->xStorage.is() ) - CloseStorage(); - - CloseStreams_Impl(); - - DELETEZ( pImp->pTempFile ); - ::utl::LocalFileHelper::ConvertURLToPhysicalName( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), aName ); - SetStorage_Impl( xStor ); - } - else if ( !GetError() ) - SetError( xStor->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) ); - return; - }*/ - } - INetURLObject aDest( GetURLObject() ); // source is the temp file written so far @@ -2606,7 +2296,7 @@ void SfxMedium::GetMedium_Impl() // in case the temporary file exists the streams should be initialized from it, // but the original MediaDescriptor should not be changed - sal_Bool bFromTempFile = ( pImp->pTempFile || pImp->pTempDir ); + sal_Bool bFromTempFile = ( pImp->pTempFile != NULL ); if ( !bFromTempFile ) { @@ -2703,54 +2393,6 @@ void SfxMedium::CancelTransfers() pImp->xCancelManager->Cancel(); } -//---------------------------------------------------------------- -/* -String SfxMedium::GetStatusString( const SvProgressArg* pArg ) -{ - String aString; - StringList_Impl aSL( SfxResId( RID_DLSTATUS2 ), (USHORT)pArg->eStatus ); - USHORT nTotal = 0; - - if ( pArg->eStatus == SVBINDSTATUS_ENDDOWNLOADDATA && nTotal <= 1 ) - return aString; - - if( aSL ) - { - INetURLObject aObj( pArg->rStatus ); - aString = aSL.GetString(); - aString.SearchAndReplaceAscii( "$(HOST)", aObj.GetHost() ); - String aTarget = aObj.GetFull(); - if( aTarget.Len() <= 1 && pArg->eStatus != SVBINDSTATUS_CONNECTING ) - aTarget = aObj.GetHost(); - if( pArg->nMax ) - { - aTarget += DEFINE_CONST_UNICODE( " (" ); - AddNumber_Impl( aTarget, pArg->nMax ); - aTarget += ')'; - } - - aString.SearchAndReplaceAscii( "$(TARGET)",aTarget ); - String aNumber; - AddNumber_Impl( aNumber, pArg->nProgress ); - if( pArg->nRate ) - { - aNumber+= DEFINE_CONST_UNICODE( " (" ); - AddNumber_Impl( aNumber, (ULONG)pArg->nRate ); - aNumber+= DEFINE_CONST_UNICODE( "/s)" ); - } - if( pArg->nMax && pArg->nProgress && pArg->nMax != pArg->nProgress ) - { - aNumber += DEFINE_CONST_UNICODE( " [" ); - float aPerc = pArg->nProgress / (float)pArg->nMax; - aNumber += String::CreateFromInt32( (USHORT)(aPerc * 100) ); - aNumber += DEFINE_CONST_UNICODE( "%]" ); - } - aString.SearchAndReplaceAscii( "$(BYTE)", aNumber ); - } - return aString; -} -*/ - sal_Bool SfxMedium::IsRemote() { return bRemote; @@ -2910,7 +2552,7 @@ SfxMedium::SfxMedium( const SfxMedium& rMedium, sal_Bool bTemporary ) pFilter = rMedium.pFilter; Init_Impl(); if( bTemporary ) - CreateTempFile(); + CreateTempFile( sal_True ); } //------------------------------------------------------------------ @@ -2989,7 +2631,7 @@ void SfxMedium::Close() const SvStream *pStream = aStorage->GetSvStream(); if ( pStream && pStream == pInStream ) { - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); pInStream = NULL; pImp->xInputStream = Reference < XInputStream >(); pImp->xLockBytes.Clear(); @@ -3022,7 +2664,7 @@ void SfxMedium::CloseAndRelease() const SvStream *pStream = aStorage->GetSvStream(); if ( pStream && pStream == pInStream ) { - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); pInStream = NULL; pImp->xInputStream = Reference < XInputStream >(); pImp->xLockBytes.Clear(); @@ -3062,7 +2704,7 @@ void SfxMedium::UnlockFile() void SfxMedium::CloseAndReleaseStreams_Impl() { - CloseReadStorage_Impl(); + CloseZipStorage_Impl(); uno::Reference< io::XInputStream > xInToClose = pImp->xInputStream; uno::Reference< io::XOutputStream > xOutToClose; @@ -3184,26 +2826,6 @@ void SfxMedium::SetPhysicalName_Impl( const String& rNameP ) } } -//---------------------------------------------------------------- -void SfxMedium::MoveTempTo_Impl( SfxMedium* pMedium ) -{ - if ( pMedium && pMedium != this && pImp->pTempFile ) - { - if( pMedium->pImp->pTempFile ) - delete pMedium->pImp->pTempFile; - pMedium->pImp->pTempFile = pImp->pTempFile; - - pImp->pTempFile->EnableKillingFile( sal_True ); - pImp->pTempFile = NULL; - - pMedium->aName = pMedium->pImp->pTempFile->GetFileName(); - - pMedium->CloseInStream(); - pMedium->CloseStorage(); - pMedium->pImp->aContent = ::ucbhelper::Content(); - } -} - //------------------------------------------------------------------ void SfxMedium::SetTemporary( sal_Bool bTemp ) { @@ -3407,22 +3029,15 @@ SfxMedium::~SfxMedium() delete pURLObj; delete pImp; } -//------------------------------------------------------------------ +//------------------------------------------------------------------ void SfxMedium::SetItemSet(SfxItemSet *pNewSet) { delete pSet; pSet = pNewSet; } -//------------------------------------------------------------------ -void SfxMedium::SetClassFilter( const SvGlobalName & rFilterClass ) -{ - bSetFilter = sal_True; - aFilterClass = rFilterClass; -} //---------------------------------------------------------------- - const INetURLObject& SfxMedium::GetURLObject() const { if( !pURLObj ) @@ -3755,131 +3370,122 @@ sal_Bool SfxMedium::IsReadOnly() } //---------------------------------------------------------------- -void SfxMedium::TryToSwitchToRepairedTemp() +sal_Bool SfxMedium::SetWritableForUserOnly( const ::rtl::OUString& aURL ) { - // the medium should be opened in repair mode - SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, FALSE ); - if ( pRepairItem && pRepairItem->GetValue() ) + // UCB does not allow to allow write access only for the user, + // use osl API + sal_Bool bResult = sal_False; + + ::osl::DirectoryItem aDirItem; + if ( ::osl::DirectoryItem::get( aURL, aDirItem ) == ::osl::FileBase::E_None ) { - DBG_ASSERT( pImp->xStorage.is(), "Possible performance problem" ); - if ( GetStorage().is() ) + ::osl::FileStatus aFileStatus( FileStatusMask_Attributes ); + if ( aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None + && aFileStatus.isValid( FileStatusMask_Attributes ) ) { - ::utl::TempFile* pTmpFile = new ::utl::TempFile(); - pTmpFile->EnableKillingFile( sal_True ); - ::rtl::OUString aNewName = pTmpFile->GetFileName(); + sal_uInt64 nAttributes = aFileStatus.getAttributes(); - if( aNewName.getLength() ) - { - try - { - uno::Reference < embed::XStorage > xNewStorage = comphelper::OStorageHelper::GetStorageFromURL( aNewName, - embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); - //SvStorageRef aNewStorage = new SvStorage( sal_True, aNewName, STREAM_WRITE | STREAM_TRUNC, STORAGE_TRANSACTED ); - - pImp->xStorage->copyToStorage( xNewStorage ); - //if ( aNewStorage->GetError() == SVSTREAM_OK ) - { - CloseInStream(); - CloseStorage(); - if ( pImp->pTempFile ) - DELETEZ( pImp->pTempFile ); + nAttributes &= ~(Attribute_OwnWrite | + Attribute_GrpWrite | + Attribute_OthWrite | + Attribute_ReadOnly); + nAttributes |= Attribute_OwnWrite; - pImp->pTempFile = pTmpFile; - aName = aNewName; - } - } - catch ( uno::Exception& ) - { - //TODO/MBA: error handling - //SetError( aNewStorage->GetError(, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) )) ); - } - } - else - SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); - - if (pImp->pTempFile != pTmpFile) - delete pTmpFile; + bResult = ( osl::File::setAttributes( aURL, nAttributes ) == ::osl::FileBase::E_None ); } - else - SetError( ERRCODE_IO_CANTREAD, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); } + + return bResult; } //---------------------------------------------------------------- -void SfxMedium::CreateTempFile() +void SfxMedium::CreateTempFile( sal_Bool bReplace ) { if ( pImp->pTempFile ) { + if ( !bReplace ) + return; + DELETEZ( pImp->pTempFile ); aName = String(); } - StreamMode nOpenMode = nStorOpenMode; - BOOL bCopy = ( nStorOpenMode == nOpenMode && ! ( nOpenMode & STREAM_TRUNC ) ); - if ( bCopy && !pInStream ) - { - if ( GetContent().is() ) - { - try - { - // make sure that the desired file exists before trying to open - SvMemoryStream aStream(0,0); - ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream ); - Reference< XInputStream > xInput( pInput ); - - InsertCommandArgument aInsertArg; - aInsertArg.Data = xInput; - - aInsertArg.ReplaceExisting = sal_False; - Any aCmdArg; - aCmdArg <<= aInsertArg; - pImp->aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg ); - } - catch ( Exception& ) - { - // it is NOT an error when the stream already exists! - GetInStream(); - } - } - } - - nStorOpenMode = nOpenMode; - ResetError(); - pImp->pTempFile = new ::utl::TempFile(); pImp->pTempFile->EnableKillingFile( sal_True ); aName = pImp->pTempFile->GetFileName(); - if ( !aName.Len() ) + ::rtl::OUString aTmpURL = pImp->pTempFile->GetURL(); + if ( !aName.Len() || !aTmpURL.getLength() ) { SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); return; } - if ( bCopy && pInStream ) + if ( !( nStorOpenMode & STREAM_TRUNC ) ) { - GetOutStream(); - if ( pOutStream ) + if ( GetContent().is() + && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) + && ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ) { - char *pBuf = new char [8192]; - sal_uInt32 nErr = ERRCODE_NONE; - - pInStream->Seek(0); - pOutStream->Seek(0); + // if there is already such a document, we should copy it + // if it is a file system use OS copy process + sal_Bool bTransferSuccess = sal_False; + try + { + uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv; + INetURLObject aTmpURLObj( aTmpURL ); + ::rtl::OUString aFileName = aTmpURLObj.getName( INetURLObject::LAST_SEGMENT, + true, + INetURLObject::DECODE_WITH_CHARSET ); + if ( aFileName.getLength() && aTmpURLObj.removeSegment() ) + { + ::ucbhelper::Content aTargetContent( aTmpURLObj.GetMainURL( INetURLObject::NO_DECODE ), xComEnv ); + if ( aTargetContent.transferContent( pImp->aContent, ::ucbhelper::InsertOperation_COPY, aFileName, NameClash::OVERWRITE ) ) + { + SetWritableForUserOnly( aTmpURL ); + bTransferSuccess = sal_True; + } + } + } + catch( uno::Exception& ) + {} - while( !pInStream->IsEof() && nErr == ERRCODE_NONE ) + if ( !bTransferSuccess ) { - sal_uInt32 nRead = pInStream->Read( pBuf, 8192 ); - nErr = pInStream->GetError(); - pOutStream->Write( pBuf, nRead ); + SetError( ERRCODE_IO_CANTWRITE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); + return; } - delete[] pBuf; + CloseOutStream(); CloseInStream(); } - CloseOutStream_Impl(); + else if ( pInStream ) + { + // the case when there is no URL-access available or this is a remote protocoll + // but there is an input stream + GetOutStream(); + if ( pOutStream ) + { + char *pBuf = new char [8192]; + sal_uInt32 nErr = ERRCODE_NONE; + + pInStream->Seek(0); + pOutStream->Seek(0); + + while( !pInStream->IsEof() && nErr == ERRCODE_NONE ) + { + sal_uInt32 nRead = pInStream->Read( pBuf, 8192 ); + nErr = pInStream->GetError(); + pOutStream->Write( pBuf, nRead ); + } + + delete[] pBuf; + CloseInStream(); + } + CloseOutStream_Impl(); + } + else + CloseInStream(); } - else - CloseInStream(); CloseStorage(); } @@ -3887,6 +3493,7 @@ void SfxMedium::CreateTempFile() //---------------------------------------------------------------- void SfxMedium::CreateTempFileNoCopy() { + // this call always replaces the existing temporary file if ( pImp->pTempFile ) delete pImp->pTempFile; @@ -3944,100 +3551,120 @@ void SfxMedium::SetCharset( ::rtl::OUString aChs ) pImp->aCharset = aChs; } -sal_Bool SfxMedium::SignContents_Impl( sal_Bool bScriptingContent ) +sal_Bool SfxMedium::SignContents_Impl( sal_Bool bScriptingContent, const ::rtl::OUString& aODFVersion, sal_Bool bHasValidDocumentSignature ) { - DBG_ASSERT( GetStorage().is(), "SfxMedium::SignContents_Impl - Storage doesn't exist!" ); - sal_Bool bChanges = FALSE; - ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures > xD( - comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), ::com::sun::star::uno::UNO_QUERY ); - - // TODO/LATER: error handling - if ( xD.is() && GetStorage().is() ) + // the medium should be closed to be able to sign, the caller is responsible to close it + if ( !IsOpen() && !GetError() ) { - sal_Int32 nEncrMode = IsReadOnly() ? embed::ElementModes::READ - : embed::ElementModes::READWRITE; + // The component should know if there was a valid document signature, since + // it should show a warning in this case + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[0] <<= aODFVersion; + aArgs[1] <<= bHasValidDocumentSignature; + ::com::sun::star::uno::Reference< ::com::sun::star::security::XDocumentDigitalSignatures > xSigner( + comphelper::getProcessServiceFactory()->createInstanceWithArguments( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), + aArgs ), + ::com::sun::star::uno::UNO_QUERY ); - try + if ( xSigner.is() ) { - uno::Reference< embed::XStorage > xMetaInf = GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - nEncrMode ); - if ( !xMetaInf.is() ) - throw uno::RuntimeException(); - - if ( bScriptingContent ) + uno::Reference< embed::XStorage > xWriteableZipStor; + if ( !IsReadOnly() ) { - if ( !IsReadOnly() ) + // we can reuse the temporary file if there is one already + CreateTempFile( sal_False ); + GetMedium_Impl(); + + try { - uno::Reference< io::XStream > xStream = xMetaInf->openStreamElement( - xD->getScriptingContentSignatureDefaultStreamName(), - nEncrMode ); - if ( !xStream.is() ) + if ( !pImp->xStream.is() ) throw uno::RuntimeException(); - try + xWriteableZipStor = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ZIP_STORAGE_FORMAT_STRING, pImp->xStream ); + if ( !xWriteableZipStor.is() ) + throw uno::RuntimeException(); + + uno::Reference< embed::XStorage > xMetaInf = xWriteableZipStor->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), + embed::ElementModes::READWRITE ); + if ( !xMetaInf.is() ) + throw uno::RuntimeException(); + + if ( bScriptingContent ) { - // to leave the stream unencrypted as before - uno::Reference< beans::XPropertySet > xStrmProps( xStream, uno::UNO_QUERY_THROW ); - xStrmProps->setPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ), - uno::makeAny( (sal_Bool)sal_False ) ); + // If the signature has already the document signature it will be removed + // after the scripting signature is inserted. + uno::Reference< io::XStream > xStream( + xMetaInf->openStreamElement( xSigner->getScriptingContentSignatureDefaultStreamName(), + embed::ElementModes::READWRITE ), + uno::UNO_SET_THROW ); + + if ( xSigner->signScriptingContent( GetZipStorageToSign_Impl(), xStream ) ) + { + // remove the document signature if any + ::rtl::OUString aDocSigName = xSigner->getDocumentContentSignatureDefaultStreamName(); + if ( aDocSigName.getLength() && xMetaInf->hasByName( aDocSigName ) ) + xMetaInf->removeElement( aDocSigName ); + + uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW ); + xTransact->commit(); + xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW ); + xTransact->commit(); + + // the temporary file has been written, commit it to the original file + Commit(); + bChanges = TRUE; + } } - catch ( uno::Exception& ) - {} - - if ( xD->signScriptingContent( GetLastCommitReadStorage_Impl(), xStream ) ) + else { - uno::Reference< embed::XTransactedObject > xTrans( xMetaInf, uno::UNO_QUERY ); - xTrans->commit(); - Commit(); - bChanges = TRUE; + uno::Reference< io::XStream > xStream( + xMetaInf->openStreamElement( xSigner->getDocumentContentSignatureDefaultStreamName(), + embed::ElementModes::READWRITE ), + uno::UNO_SET_THROW ); + + if ( xSigner->signDocumentContent( GetZipStorageToSign_Impl(), xStream ) ) + { + uno::Reference< embed::XTransactedObject > xTransact( xMetaInf, uno::UNO_QUERY_THROW ); + xTransact->commit(); + xTransact.set( xWriteableZipStor, uno::UNO_QUERY_THROW ); + xTransact->commit(); + + // the temporary file has been written, commit it to the original file + Commit(); + bChanges = TRUE; + } } } - else - xD->showScriptingContentSignatures( GetLastCommitReadStorage_Impl(), uno::Reference< io::XInputStream >() ); + catch ( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" ); + } + + CloseAndRelease(); } else { - if ( !IsReadOnly() ) + try { - uno::Reference< io::XStream > xStream = xMetaInf->openStreamElement( - xD->getDocumentContentSignatureDefaultStreamName(), - nEncrMode ); - if ( !xStream.is() ) - throw uno::RuntimeException(); - - try - { - // to leave the stream unencrypted as before - uno::Reference< beans::XPropertySet > xStrmProps( xStream, uno::UNO_QUERY_THROW ); - xStrmProps->setPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ), - uno::makeAny( (sal_Bool)sal_False ) ); - } - catch ( uno::Exception& ) - {} - - if ( xD->signDocumentContent( GetLastCommitReadStorage_Impl(), xStream ) ) - { - uno::Reference< embed::XTransactedObject > xTrans( xMetaInf, uno::UNO_QUERY ); - xTrans->commit(); - Commit(); - bChanges = TRUE; - } - + if ( bScriptingContent ) + xSigner->showScriptingContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() ); + else + xSigner->showDocumentContentSignatures( GetZipStorageToSign_Impl(), uno::Reference< io::XInputStream >() ); + } + catch( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" ); } - else - xD->showDocumentContentSignatures( GetLastCommitReadStorage_Impl(), uno::Reference< io::XInputStream >() ); } } - catch( uno::Exception& ) - { - OSL_ENSURE( sal_False, "Couldn't use signing functionality!\n" ); - } + + ResetError(); } + return bChanges; } @@ -4152,6 +3779,38 @@ BOOL SfxMedium::IsOpen() const return aResult; } +sal_Bool SfxMedium::CallApproveHandler( const uno::Reference< task::XInteractionHandler >& xHandler, uno::Any aRequest, sal_Bool bAllowAbort ) +{ + sal_Bool bResult = sal_False; + + if ( xHandler.is() ) + { + try + { + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( bAllowAbort ? 2 : 1 ); + + ::rtl::Reference< ::framework::ContinuationApprove > pApprove( new ::framework::ContinuationApprove() ); + aContinuations[ 0 ] = pApprove.get(); + + if ( bAllowAbort ) + { + ::rtl::Reference< ::framework::ContinuationAbort > pAbort( new ::framework::ContinuationAbort() ); + aContinuations[ 1 ] = pAbort.get(); + } + + uno::Reference< task::XInteractionRequest > xRequest( new ::framework::InteractionRequest( aRequest, aContinuations ) ); + xHandler->handle( xRequest ); + + bResult = pApprove->isSelected(); + } + catch( const Exception& ) + { + } + } + + return bResult; +} + ::rtl::OUString SfxMedium::SwitchDocumentToTempFile() { // the method returns empty string in case of failure @@ -4189,7 +3848,7 @@ BOOL SfxMedium::IsOpen() const GetMedium_Impl(); LockOrigFileOnDemand( sal_False, sal_False ); - CreateTempFile(); + CreateTempFile( sal_True ); GetMedium_Impl(); if ( pImp->xStream.is() ) @@ -4247,7 +3906,7 @@ sal_Bool SfxMedium::SwitchDocumentToFile( ::rtl::OUString aURL ) // open the temporary file based document GetMedium_Impl(); LockOrigFileOnDemand( sal_False, sal_False ); - CreateTempFile(); + CreateTempFile( sal_True ); GetMedium_Impl(); if ( pImp->xStream.is() ) diff --git a/sfx2/source/doc/docmacromode.cxx b/sfx2/source/doc/docmacromode.cxx index b74eabd1ab..a2e2963479 100644 --- a/sfx2/source/doc/docmacromode.cxx +++ b/sfx2/source/doc/docmacromode.cxx @@ -33,6 +33,7 @@ #include "sfx2/docmacromode.hxx" #include "sfx2/signaturestate.hxx" +#include "sfx2/docfile.hxx" /** === begin UNO includes === **/ #include <com/sun/star/document/MacroExecMode.hpp> @@ -85,14 +86,14 @@ namespace sfx2 //==================================================================== struct DocumentMacroMode_Data { - IMacroDocumentAccess& rDocumentAccess; - sal_Bool bMacroDisabledMessageShown; - sal_Bool bDocMacroDisabledMessageShown; - - DocumentMacroMode_Data( IMacroDocumentAccess& _rDocumentAccess ) - :rDocumentAccess( _rDocumentAccess ) - ,bMacroDisabledMessageShown( sal_False ) - ,bDocMacroDisabledMessageShown( sal_False ) + IMacroDocumentAccess& m_rDocumentAccess; + sal_Bool m_bMacroDisabledMessageShown; + sal_Bool m_bDocMacroDisabledMessageShown; + + DocumentMacroMode_Data( IMacroDocumentAccess& rDocumentAccess ) + :m_rDocumentAccess( rDocumentAccess ) + ,m_bMacroDisabledMessageShown( sal_False ) + ,m_bDocMacroDisabledMessageShown( sal_False ) { } }; @@ -103,85 +104,37 @@ namespace sfx2 namespace { //................................................................ - /** calls the given interaction handler with the given interaction request, offering - the two continuations "Approve" and "Abort" - - @return - <TRUE/> if and only if the given handler handled the the request, and the "Approve" - continuation was selected. - */ - sal_Bool lcl_callInterActionHandler( const Reference< XInteractionHandler >& _rxHandler, const Any& _rRequest ) + void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& rxHandler, const sal_Int32 nSfxErrorCode, sal_Bool& rbAlreadyShown ) { - if ( !_rxHandler.is() ) - return sal_False; - - try - { - Sequence< Reference< XInteractionContinuation > > aContinuations(2); - - ::rtl::Reference< ::framework::ContinuationAbort > pAbort( new ::framework::ContinuationAbort() ); - aContinuations[ 0 ] = pAbort.get(); - - ::rtl::Reference< ::framework::ContinuationApprove > pApprove( new ::framework::ContinuationApprove() ); - aContinuations[ 1 ] = pApprove.get(); - - Reference< XInteractionRequest > xRequest( new ::framework::InteractionRequest( _rRequest, aContinuations ) ); - _rxHandler->handle( xRequest ); - - if ( pApprove->isSelected() ) - return sal_True; - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - return sal_False; - } - - //................................................................ - void lcl_showGeneralSfxErrorOnce( const Reference< XInteractionHandler >& _rxHandler, const sal_Int32 _nSfxErrorCode, sal_Bool& _rbAlreadyShown ) - { - if ( _rbAlreadyShown ) + if ( rbAlreadyShown ) return; ErrorCodeRequest aErrorCodeRequest; - aErrorCodeRequest.ErrCode = _nSfxErrorCode; - - _rbAlreadyShown = lcl_callInterActionHandler( _rxHandler, makeAny( aErrorCodeRequest ) ); - } + aErrorCodeRequest.ErrCode = nSfxErrorCode; - //................................................................ - void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& _rxHandler, sal_Bool& _rbAlreadyShown ) - { - lcl_showGeneralSfxErrorOnce( _rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, _rbAlreadyShown ); + SfxMedium::CallApproveHandler( rxHandler, makeAny( aErrorCodeRequest ), sal_False ); + rbAlreadyShown = sal_True; } //................................................................ - void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& _rxHandler, sal_Bool& _rbAlreadyShown ) + void lcl_showMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown ) { - lcl_showGeneralSfxErrorOnce( _rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, _rbAlreadyShown ); + lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_MACROS_SUPPORT_DISABLED, rbAlreadyShown ); } //................................................................ - sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& _rxHandler, - const ::rtl::OUString& _rDocumentLocation ) + void lcl_showDocumentMacrosDisabledError( const Reference< XInteractionHandler >& rxHandler, sal_Bool& rbAlreadyShown ) { - DocumentMacroConfirmationRequest aRequest; - aRequest.DocumentURL = _rDocumentLocation; - return lcl_callInterActionHandler( _rxHandler, makeAny( aRequest ) ); + lcl_showGeneralSfxErrorOnce( rxHandler, ERRCODE_SFX_DOCUMENT_MACRO_DISABLED, rbAlreadyShown ); } //................................................................ - sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& _rxHandler, - const ::rtl::OUString& _rDocumentLocation, const Reference< XStorage >& _rxDocStor, - const Sequence< DocumentSignatureInformation >& _rDocSigInfo ) + sal_Bool lcl_showMacroWarning( const Reference< XInteractionHandler >& rxHandler, + const ::rtl::OUString& rDocumentLocation ) { DocumentMacroConfirmationRequest aRequest; - aRequest.DocumentURL = _rDocumentLocation; - aRequest.DocumentStorage = _rxDocStor; - aRequest.DocumentSignatureInformation = _rDocSigInfo; - aRequest.Classification = InteractionClassification_QUERY; - return lcl_callInterActionHandler( _rxHandler, makeAny( aRequest ) ); + aRequest.DocumentURL = rDocumentLocation; + return SfxMedium::CallApproveHandler( rxHandler, makeAny( aRequest ), sal_True ); } } @@ -189,8 +142,8 @@ namespace sfx2 //= DocumentMacroMode //==================================================================== //-------------------------------------------------------------------- - DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& _rDocumentAccess ) - :m_pData( new DocumentMacroMode_Data( _rDocumentAccess ) ) + DocumentMacroMode::DocumentMacroMode( IMacroDocumentAccess& rDocumentAccess ) + :m_pData( new DocumentMacroMode_Data( rDocumentAccess ) ) { } @@ -202,26 +155,26 @@ namespace sfx2 //-------------------------------------------------------------------- sal_Bool DocumentMacroMode::allowMacroExecution() { - m_pData->rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN ); + m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::ALWAYS_EXECUTE_NO_WARN ); return sal_True; } //-------------------------------------------------------------------- sal_Bool DocumentMacroMode::disallowMacroExecution() { - m_pData->rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE ); + m_pData->m_rDocumentAccess.setCurrentMacroExecMode( MacroExecMode::NEVER_EXECUTE ); return sal_False; } //-------------------------------------------------------------------- - sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& _rxInteraction ) + sal_Bool DocumentMacroMode::adjustMacroMode( const Reference< XInteractionHandler >& rxInteraction ) { - sal_uInt16 nMacroExecutionMode = m_pData->rDocumentAccess.getCurrentMacroExecMode(); + sal_uInt16 nMacroExecutionMode = m_pData->m_rDocumentAccess.getCurrentMacroExecMode(); if ( SvtSecurityOptions().IsMacroDisabled() ) { // no macro should be executed at all - lcl_showMacrosDisabledError( _rxInteraction, m_pData->bMacroDisabledMessageShown ); + lcl_showMacrosDisabledError( rxInteraction, m_pData->m_bMacroDisabledMessageShown ); return disallowMacroExecution(); } @@ -273,9 +226,10 @@ namespace sfx2 try { - ::rtl::OUString sReferrer( m_pData->rDocumentAccess.getDocumentLocation() ); + ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() ); // get document location from medium name and check whether it is a trusted one + // the service is created ohne document version, since it is not of interest here ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); Reference< XDocumentDigitalSignatures > xSignatures; if ( aContext.createComponent( "com.sun.star.security.DocumentDigitalSignatures", xSignatures ) ) @@ -295,61 +249,35 @@ namespace sfx2 // at this point it is clear that the document is not in the secure location if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_NO_WARN ) { - lcl_showDocumentMacrosDisabledError( _rxInteraction, m_pData->bDocMacroDisabledMessageShown ); + lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown ); return disallowMacroExecution(); } // check whether the document is signed with trusted certificate - if ( xSignatures.is() && nMacroExecutionMode != MacroExecMode::FROM_LIST ) + if ( nMacroExecutionMode != MacroExecMode::FROM_LIST ) { - Sequence< DocumentSignatureInformation > aScriptingSignatureInformations; - Reference < XStorage > xStore( m_pData->rDocumentAccess.getLastCommitDocumentStorage() ); + // the trusted macro check will also retrieve the signature state ( small optimization ) + sal_Bool bHasTrustedMacroSignature = m_pData->m_rDocumentAccess.hasTrustedScriptingSignature( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ); - sal_uInt16 nSignatureState = m_pData->rDocumentAccess.getScriptingSignatureState(); + sal_uInt16 nSignatureState = m_pData->m_rDocumentAccess.getScriptingSignatureState(); if ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN ) { + // the signature is broken, no macro execution if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) - { - m_pData->rDocumentAccess.showBrokenSignatureWarning( _rxInteraction ); - return disallowMacroExecution(); - } + m_pData->m_rDocumentAccess.showBrokenSignatureWarning( rxInteraction ); + + return disallowMacroExecution(); } - else + else if ( bHasTrustedMacroSignature ) { - if ( ( ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK ) - || ( nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) - ) - && xStore.is() - ) - { - aScriptingSignatureInformations = - xSignatures->verifyScriptingContentSignatures( xStore, NULL ); - } + // there is trusted macro signature, allow macro execution + return allowMacroExecution(); } - - sal_Int32 nNumOfInfos = aScriptingSignatureInformations.getLength(); - - // from now on sReferrer is the system file path - // sReferrer = INetURLObject::decode( sReferrer, '%', INetURLObject::DECODE_WITH_CHARSET ); - ::rtl::OUString aSystemFileURL; - if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None ) - sReferrer = aSystemFileURL; - - if ( nNumOfInfos ) + else if ( nSignatureState == SIGNATURESTATE_SIGNATURES_OK + || nSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) { - for ( sal_Int32 i = 0; i < nNumOfInfos; i++ ) - if ( xSignatures->isAuthorTrusted( aScriptingSignatureInformations[i].Signer ) ) - { - // there's at least one author we trust which signed the doc - return allowMacroExecution(); - } - - if ( nMacroExecutionMode != MacroExecMode::FROM_LIST_AND_SIGNED_NO_WARN ) - { - sal_Bool bApproved = lcl_showMacroWarning( _rxInteraction, - sReferrer, xStore, aScriptingSignatureInformations ); - return ( bApproved ? allowMacroExecution() : disallowMacroExecution() ); - } + // there is valid signature, but it is not from the trusted author + return disallowMacroExecution(); } } @@ -359,9 +287,8 @@ namespace sfx2 ) { if ( nMacroExecutionMode == MacroExecMode::FROM_LIST_AND_SIGNED_WARN ) - { - lcl_showDocumentMacrosDisabledError( _rxInteraction, m_pData->bDocMacroDisabledMessageShown ); - } + lcl_showDocumentMacrosDisabledError( rxInteraction, m_pData->m_bDocMacroDisabledMessageShown ); + return disallowMacroExecution(); } } @@ -381,13 +308,13 @@ namespace sfx2 if ( eAutoConfirm == eNoAutoConfirm ) { - ::rtl::OUString sReferrer( m_pData->rDocumentAccess.getDocumentLocation() ); + ::rtl::OUString sReferrer( m_pData->m_rDocumentAccess.getDocumentLocation() ); ::rtl::OUString aSystemFileURL; if ( osl::FileBase::getSystemPathFromFileURL( sReferrer, aSystemFileURL ) == osl::FileBase::E_None ) sReferrer = aSystemFileURL; - bSecure = lcl_showMacroWarning( _rxInteraction, sReferrer ); + bSecure = lcl_showMacroWarning( rxInteraction, sReferrer ); } else bSecure = ( eAutoConfirm == eAutoConfirmApprove ); @@ -398,7 +325,7 @@ namespace sfx2 //-------------------------------------------------------------------- sal_Bool DocumentMacroMode::isMacroExecutionDisallowed() const { - return m_pData->rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE; + return m_pData->m_rDocumentAccess.getCurrentMacroExecMode() == MacroExecMode::NEVER_EXECUTE; } //-------------------------------------------------------------------- @@ -407,7 +334,7 @@ namespace sfx2 sal_Bool bHasMacroLib = sal_False; try { - Reference< XEmbeddedScripts > xScripts( m_pData->rDocumentAccess.getEmbeddedDocumentScripts() ); + Reference< XEmbeddedScripts > xScripts( m_pData->m_rDocumentAccess.getEmbeddedDocumentScripts() ); Reference< XLibraryContainer > xContainer; if ( xScripts.is() ) xContainer.set( xScripts->getBasicLibraries(), UNO_QUERY_THROW ); @@ -457,21 +384,21 @@ namespace sfx2 } //-------------------------------------------------------------------- - sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& _rxStorage ) + sal_Bool DocumentMacroMode::storageHasMacros( const Reference< XStorage >& rxStorage ) { sal_Bool bHasMacros = sal_False; - if ( _rxStorage.is() ) + if ( rxStorage.is() ) { try { static const ::rtl::OUString s_sBasicStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ) ); static const ::rtl::OUString s_sScriptsStorageName( ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) ) ); - bHasMacros =( ( _rxStorage->hasByName( s_sBasicStorageName ) - && _rxStorage->isStorageElement( s_sBasicStorageName ) + bHasMacros =( ( rxStorage->hasByName( s_sBasicStorageName ) + && rxStorage->isStorageElement( s_sBasicStorageName ) ) - || ( _rxStorage->hasByName( s_sScriptsStorageName ) - && _rxStorage->isStorageElement( s_sScriptsStorageName ) + || ( rxStorage->hasByName( s_sScriptsStorageName ) + && rxStorage->isStorageElement( s_sScriptsStorageName ) ) ); } @@ -484,7 +411,7 @@ namespace sfx2 } //-------------------------------------------------------------------- - sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& _rxInteraction ) + sal_Bool DocumentMacroMode::checkMacrosOnLoading( const Reference< XInteractionHandler >& rxInteraction ) { sal_Bool bAllow = sal_False; if ( SvtSecurityOptions().IsMacroDisabled() ) @@ -494,9 +421,9 @@ namespace sfx2 } else { - if ( m_pData->rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) + if ( m_pData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) { - bAllow = adjustMacroMode( _rxInteraction ); + bAllow = adjustMacroMode( rxInteraction ); } else if ( !isMacroExecutionDisallowed() ) { diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx index 921d56539d..e55654043b 100644 --- a/sfx2/source/doc/guisaveas.cxx +++ b/sfx2/source/doc/guisaveas.cxx @@ -87,6 +87,8 @@ #include <sfxtypes.hxx> #include "alienwarn.hxx" +#include "../appl/app.hrc" + #define DOCPROPSNUM 17 // flags that specify requested operation @@ -1227,7 +1229,8 @@ sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& const ::rtl::OUString& aSlotName, uno::Sequence< beans::PropertyValue >& aArgsSequence, sal_Bool bPreselectPassword, - ::rtl::OUString aSuggestedName ) + ::rtl::OUString aSuggestedName, + sal_uInt16 nDocumentSignatureState ) { ModelData_Impl aModelData( *this, xModel, aArgsSequence ); @@ -1308,6 +1311,24 @@ sal_Bool SfxStoringHelper::GUIStoreModel( const uno::Reference< frame::XModel >& } } + if ( !( nStoreMode & EXPORT_REQUESTED ) ) + { + // if it is no export, warn user that the signature will be removed + if ( SIGNATURESTATE_SIGNATURES_OK == nDocumentSignatureState + || SIGNATURESTATE_SIGNATURES_INVALID == nDocumentSignatureState + || SIGNATURESTATE_SIGNATURES_NOTVALIDATED == nDocumentSignatureState + || SIGNATURESTATE_SIGNATURES_PARTIAL_OK == nDocumentSignatureState) + { + if ( QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE ) ).Execute() != RET_YES ) + { + // the user has decided not to store the document + throw task::ErrorCodeIOException( ::rtl::OUString(), + uno::Reference< uno::XInterface >(), + ERRCODE_IO_ABORT ); + } + } + } + // preselect a filter for the storing process uno::Sequence< beans::PropertyValue > aFilterProps = aModelData.GetPreselectedFilter_Impl( nStoreMode ); diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index 3b03a9d4ff..847ae205cb 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -87,6 +87,8 @@ #include <comphelper/configurationhelper.hxx> #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> +#include <com/sun/star/task/DocumentMacroConfirmationRequest2.hpp> +#include <com/sun/star/task/InteractionClassification.hpp> #include <com/sun/star/frame/XModel.hpp> using namespace ::com::sun::star; @@ -120,6 +122,7 @@ using namespace ::com::sun::star::container; #include <vcl/svapp.hxx> #include <framework/interaction.hxx> #include <comphelper/storagehelper.hxx> +#include <comphelper/documentconstants.hxx> #include <sfx2/signaturestate.hxx> #include <sfx2/app.hxx> @@ -285,8 +288,6 @@ sal_uInt32 SfxObjectShell::GetErrorCode() const sal_uInt32 lError=pImp->lErr; if(!lError && GetMedium()) lError=GetMedium()->GetErrorCode(); -//REMOVE if(!lError && HasStorage()) -//REMOVE lError= GetStorage()->GetErrorCode(); return lError; } @@ -301,9 +302,6 @@ void SfxObjectShell::ResetError() SfxMedium * pMed = GetMedium(); if( pMed ) pMed->ResetError(); -//REMOVE SvStorage *pStor= HasStorage() ? GetStorage() : 0; -//REMOVE if( pStor ) -//REMOVE pStor->ResetError(); } //------------------------------------------------------------------------- @@ -1234,10 +1232,52 @@ void SfxObjectShell::CheckSecurityOnLoading_Impl() if ( GetMedium() ) xInteraction = GetMedium()->GetInteractionHandler(); - // check macro security - pImp->aMacroMode.checkMacrosOnLoading( xInteraction ); // check if there is a broken signature... CheckForBrokenDocSignatures_Impl( xInteraction ); + + CheckEncryption_Impl( xInteraction ); + + // check macro security + pImp->aMacroMode.checkMacrosOnLoading( xInteraction ); +} + +//------------------------------------------------------------------------- +void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler ) +{ + ::rtl::OUString aVersion; + sal_Bool bIsEncrypted = sal_False; + sal_Bool bHasNonEncrypted = sal_False; + + try + { + uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion; + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasEncryptedEntries" ) ) ) >>= bIsEncrypted; + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasNonEncryptedEntries" ) ) ) >>= bHasNonEncrypted; + } + catch( uno::Exception& ) + { + } + + if ( aVersion.compareTo( ODFVER_012_TEXT ) >= 0 ) + { + // this is ODF1.2 or later + if ( bIsEncrypted && bHasNonEncrypted ) + { + if ( !pImp->m_bIncomplEncrWarnShown ) + { + // this is an encrypted document with nonencrypted streams inside, show the warning + ::com::sun::star::task::ErrorCodeRequest aErrorCode; + aErrorCode.ErrCode = ERRCODE_SFX_INCOMPLETE_ENCRYPTION; + + SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False ); + pImp->m_bIncomplEncrWarnShown = sal_True; + } + + // broken signatures imply no macro execution at all + pImp->aMacroMode.disallowMacroExecution(); + } + } } //------------------------------------------------------------------------- @@ -1476,7 +1516,7 @@ void SfxObjectShell::TemplateDisconnectionAfterLoad() { // some further initializations for templates SetTemplate_Impl( aName, aTemplateName, this ); - pTmpMedium->CreateTempFile(); + pTmpMedium->CreateTempFile( sal_True ); } // templates are never readonly @@ -2086,14 +2126,16 @@ void SfxObjectShell::Invalidate( USHORT nId ) Invalidate_Impl( pFrame->GetBindings(), nId ); } -bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool _bSuppressUI ) +bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool bSuppressUI ) { uno::Reference< task::XInteractionHandler > xInteraction; - if ( pMedium && !_bSuppressUI ) + if ( pMedium && !bSuppressUI ) xInteraction = pMedium->GetInteractionHandler(); CheckForBrokenDocSignatures_Impl( xInteraction ); + CheckEncryption_Impl( xInteraction ); + return pImp->aMacroMode.adjustMacroMode( xInteraction ); } @@ -2325,16 +2367,15 @@ sal_Bool SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode ) return sLocation; } -uno::Reference< embed::XStorage > SfxObjectShell_Impl::getLastCommitDocumentStorage() +uno::Reference< embed::XStorage > SfxObjectShell_Impl::getZipStorageToSign() { Reference < embed::XStorage > xStore; SfxMedium* pMedium( rDocShell.GetMedium() ); OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getLastCommitDocumentStorage: no medium!" ); if ( pMedium ) - { - xStore = pMedium->GetLastCommitReadStorage_Impl(); - } + xStore = pMedium->GetZipStorageToSign_Impl(); + return xStore; } @@ -2348,7 +2389,7 @@ Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY ); } -sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState() const +sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState() { sal_Int16 nSignatureState( rDocShell.GetScriptingSignatureState() ); @@ -2361,6 +2402,72 @@ sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState() const return nSignatureState; } +sal_Bool SfxObjectShell_Impl::hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor ) +{ + sal_Bool bResult = sal_False; + + try + { + ::rtl::OUString aVersion; + try + { + uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW ); + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion; + } + catch( uno::Exception& ) + { + } + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= aVersion; + + uno::Reference< security::XDocumentDigitalSignatures > xSigner( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW ); + + if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN + || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK + || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + { + uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.ImplAnalyzeSignature( sal_True, xSigner ); + + if ( aInfo.getLength() ) + { + if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN ) + nScriptingSignatureState = rDocShell.ImplCheckSignaturesInformation( aInfo ); + + if ( nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK + || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + { + for ( sal_Int32 nInd = 0; !bResult && nInd < aInfo.getLength(); nInd++ ) + { + bResult = xSigner->isAuthorTrusted( aInfo[nInd].Signer ); + } + + if ( !bResult && bAllowUIToAddAuthor ) + { + uno::Reference< task::XInteractionHandler > xInteraction; + if ( rDocShell.GetMedium() ) + xInteraction = rDocShell.GetMedium()->GetInteractionHandler(); + + if ( xInteraction.is() ) + { + task::DocumentMacroConfirmationRequest2 aRequest; + aRequest.DocumentURL = getDocumentLocation(); + aRequest.DocumentZipStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl(); + aRequest.DocumentSignatureInformation = aInfo; + aRequest.DocumentVersion = aVersion; + aRequest.Classification = task::InteractionClassification_QUERY; + bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), sal_True ); + } + } + } + } + } + } + catch( uno::Exception& ) + {} + + return bResult; +} + void SfxObjectShell_Impl::showBrokenSignatureWarning( const uno::Reference< task::XInteractionHandler >& _rxInteraction ) const { if ( !bSignatureErrorIsShown ) diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index c090f45a22..8cf35d3533 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -525,16 +525,6 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) { SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ??? - // xmlsec05, check with SFX team - sal_uInt16 nState = GetDocumentSignatureState(); - if ( SIGNATURESTATE_SIGNATURES_OK == nState - || SIGNATURESTATE_SIGNATURES_INVALID == nState - || SIGNATURESTATE_SIGNATURES_NOTVALIDATED == nState ) - { - if ( QueryBox( NULL, SfxResId( RID_XMLSEC_QUERY_LOSINGSIGNATURE ) ).Execute() != RET_YES ) - return; - } - if ( nId == SID_SAVEASDOC ) { // in case of plugin mode the SaveAs operation means SaveTo @@ -644,7 +634,8 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) ::rtl::OUString::createFromAscii( pSlot->GetUnoName() ), aDispatchArgs, bPreselectPassword, - GetSharedFileURL() ); + GetSharedFileURL(), + GetDocumentSignatureState() ); } else { @@ -654,11 +645,6 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) ERRCODE_IO_ABORT ); } - // the scripting signature might be preserved - // pImp->nScriptingSignatureState = SIGNATURESTATE_NOSIGNATURES; - pImp->nDocumentSignatureState = SIGNATURESTATE_NOSIGNATURES; - pImp->bSignatureErrorIsShown = sal_False; - // merge aDispatchArgs to the request SfxAllItemSet aResultParams( GetPool() ); TransformParameters( nId, @@ -1085,7 +1071,11 @@ void SfxObjectShell::GetState_Impl(SfxItemSet &rSet) } case SID_MACRO_SIGNATURE: { - rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) ); + // the slot makes sense only if there is a macro in the document + if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() ) + rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) ); + else + rSet.DisableItem( nWhich ); break; } } @@ -1269,6 +1259,7 @@ sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< sal_Bool bCertValid = sal_True; sal_uInt16 nResult = SIGNATURESTATE_NOSIGNATURES; int nInfos = aInfos.getLength(); + bool bCompleteSignature = true; if( nInfos ) { //These errors of certificates are allowed @@ -1293,11 +1284,14 @@ sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< nResult = SIGNATURESTATE_SIGNATURES_BROKEN; break; // we know enough } + bCompleteSignature &= !aInfos[n].PartialDocumentSignature; } } if ( nResult == SIGNATURESTATE_SIGNATURES_OK && !bCertValid ) nResult = SIGNATURESTATE_SIGNATURES_NOTVALIDATED; + else if ( nResult == SIGNATURESTATE_SIGNATURES_OK && bCertValid && !bCompleteSignature) + nResult = SIGNATURESTATE_SIGNATURES_PARTIAL_OK; // this code must not check whether the document is modified // it should only check the provided info @@ -1305,41 +1299,61 @@ sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< return nResult; } -sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent ) +uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( sal_Bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner ) { - sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState; + uno::Sequence< security::DocumentSignatureInformation > aResult; + uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner; - if ( *pState == SIGNATURESTATE_UNKNOWN ) + if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() ) { - *pState = SIGNATURESTATE_NOSIGNATURES; - - if ( GetMedium() && GetMedium()->GetName().Len() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() ) + try { - try + if ( !xLocSigner.is() ) { - uno::Reference< security::XDocumentDigitalSignatures > xD( - comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY ); - - if ( xD.is() ) + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= ::rtl::OUString(); + try { - ::com::sun::star::uno::Sequence< security::DocumentSignatureInformation > aInfos; - if ( bScriptingContent ) - aInfos = xD->verifyScriptingContentSignatures( GetMedium()->GetLastCommitReadStorage_Impl(), - uno::Reference< io::XInputStream >() ); - else - aInfos = xD->verifyDocumentContentSignatures( GetMedium()->GetLastCommitReadStorage_Impl(), - uno::Reference< io::XInputStream >() ); - - *pState = ImplCheckSignaturesInformation( aInfos ); + uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW ); + aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ); } + catch( uno::Exception& ) + { + } + + xLocSigner.set( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW ); + } - catch( com::sun::star::uno::Exception& ) - { - } + + if ( bScriptingContent ) + aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), + uno::Reference< io::XInputStream >() ); + else + aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(), + uno::Reference< io::XInputStream >() ); + } + catch( com::sun::star::uno::Exception& ) + { } } - if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + return aResult; +} + +sal_uInt16 SfxObjectShell::ImplGetSignatureState( sal_Bool bScriptingContent ) +{ + sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState; + + if ( *pState == SIGNATURESTATE_UNKNOWN ) + { + *pState = SIGNATURESTATE_NOSIGNATURES; + + uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent ); + *pState = ImplCheckSignaturesInformation( aInfos ); + } + + if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || *pState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) { if ( IsModified() ) *pState = SIGNATURESTATE_SIGNATURES_INVALID; @@ -1415,7 +1429,6 @@ void SfxObjectShell::ImplSign( sal_Bool bScriptingContent ) //When the document is modified then we must not show the digital signatures dialog //If we have come here then the user denied to save. if (!bHasSign) - bNoSig = true; } } @@ -1437,18 +1450,42 @@ void SfxObjectShell::ImplSign( sal_Bool bScriptingContent ) bAllowModifiedBack = sal_True; } - if ( ! bNoSig && GetMedium()->SignContents_Impl( bScriptingContent ) ) + // we have to store to the original document, the original medium should be closed for this time + if ( !bNoSig + && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) ) { - if ( bScriptingContent ) - pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check - else - pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check + GetMedium()->CloseAndRelease(); + + // We sign only ODF1.2, that means that if this point has been reached, + // the ODF1.2 signing process should be used. + // This code still might be called to show the signature of ODF1.1 document. + sal_Bool bSigned = GetMedium()->SignContents_Impl( + bScriptingContent, + aODFVersion, + pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_OK + || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK); + + DoSaveCompleted( GetMedium() ); + + if ( bSigned ) + { + if ( bScriptingContent ) + { + pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check - pImp->bSignatureErrorIsShown = sal_False; + // adding of scripting signature removes existing document signature + pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check + } + else + pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check - Invalidate( SID_SIGNATURE ); - Invalidate( SID_MACRO_SIGNATURE ); - Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) ); + pImp->bSignatureErrorIsShown = sal_False; + + Invalidate( SID_SIGNATURE ); + Invalidate( SID_MACRO_SIGNATURE ); + Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) ); + } } if ( bAllowModifiedBack ) diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 7e15963b63..52e00f3b36 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -36,6 +36,7 @@ #endif #include <svtools/eitem.hxx> #include <svtools/stritem.hxx> +#include <svtools/intitem.hxx> #include <tools/zcodec.hxx> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/frame/XModel.hpp> @@ -665,11 +666,14 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed ) xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) ) >>= bWarnMediaTypeFallback; - if ( bWarnMediaTypeFallback && pRepairPackageItem && pRepairPackageItem->GetValue() ) + if ( pRepairPackageItem && pRepairPackageItem->GetValue() ) { + // the macros in repaired documents should be disabled + pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, document::MacroExecMode::NEVER_EXECUTE ) ); + // the mediatype was retrieved by using fallback solution but this is a repairing mode // so it is acceptable to open the document if there is no contents that required manifest.xml - bWarnMediaTypeFallback = sal_False; //!NoDependencyFromManifest_Impl( xStorage ); + bWarnMediaTypeFallback = sal_False; } if ( bWarnMediaTypeFallback || !xStorage->getElementNames().getLength() ) @@ -1175,7 +1179,7 @@ sal_Bool SfxObjectShell::SaveTo_Impl sal_Bool bStoreToSameLocation = sal_False; // the detection whether the script is changed should be done before saving - sal_Bool bTryToPreservScriptSignature = sal_False; + sal_Bool bTryToPreserveScriptSignature = sal_False; // no way to detect whether a filter is oasis format, have to wait for saving process sal_Bool bNoPreserveForOasis = sal_False; if ( bOwnSource && bOwnTarget @@ -1186,8 +1190,10 @@ sal_Bool SfxObjectShell::SaveTo_Impl AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "MacroSignaturePreserving" ) ) ); // the checking of the library modified state iterates over the libraries, should be done only when required - bTryToPreservScriptSignature = !pImp->pBasicManager->isAnyContainerModified(); - if ( bTryToPreservScriptSignature ) + // currently the check is commented out since it is broken, we have to check the signature every time we save + // TODO/LATER: let isAnyContainerModified() work! + bTryToPreserveScriptSignature = sal_True; // !pImp->pBasicManager->isAnyContainerModified(); + if ( bTryToPreserveScriptSignature ) { // check that the storage format stays the same SvtSaveOptions aSaveOpt; @@ -1203,7 +1209,7 @@ sal_Bool SfxObjectShell::SaveTo_Impl {} // preserve only if the same filter has been used - bTryToPreservScriptSignature = pMedium->GetFilter() && pFilter && pMedium->GetFilter()->GetFilterName() == pFilter->GetFilterName(); + bTryToPreserveScriptSignature = pMedium->GetFilter() && pFilter && pMedium->GetFilter()->GetFilterName() == pFilter->GetFilterName(); bNoPreserveForOasis = ( (aODFVersion.equals( ODFVER_012_TEXT ) && nVersion == SvtSaveOptions::ODFVER_011) || @@ -1473,9 +1479,10 @@ sal_Bool SfxObjectShell::SaveTo_Impl } - if ( bOk && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) + if ( bOk && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED && !bPasswdProvided ) { // store the thumbnail representation image + // the thumbnail is not stored in case of encrypted document AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Thumbnail creation." ) ) ); if ( !GenerateAndStoreThumbnail( bPasswdProvided, sal_False, @@ -1594,120 +1601,115 @@ sal_Bool SfxObjectShell::SaveTo_Impl bOk = SaveChildren( TRUE ); } - // if ODF version of oasis format changes on saving the signature should not be preserved - if ( bOk && bTryToPreservScriptSignature && bNoPreserveForOasis ) - bTryToPreservScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 ); - - uno::Reference< security::XDocumentDigitalSignatures > xDDSigns; - sal_Bool bScriptSignatureIsCopied = sal_False; - if ( bOk && bTryToPreservScriptSignature ) + if ( bOk ) { - // if the scripting code was not changed and it is signed the signature should be preserved - // unfortunately at this point we have only information whether the basic code has changed or not - // so the only way is to check the signature if the basic was not changed - try - { - xDDSigns = uno::Reference< security::XDocumentDigitalSignatures >( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), - uno::UNO_QUERY_THROW ); + // if ODF version of oasis format changes on saving the signature should not be preserved + if ( bOk && bTryToPreserveScriptSignature && bNoPreserveForOasis ) + bTryToPreserveScriptSignature = ( SotStorage::GetVersion( rMedium.GetStorage() ) == SOFFICE_FILEFORMAT_60 ); - ::rtl::OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName(); + uno::Reference< security::XDocumentDigitalSignatures > xDDSigns; + if ( bOk && bTryToPreserveScriptSignature ) + { + AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Copying scripting signature." ) ) ); - if ( aScriptSignName.getLength() ) + // if the scripting code was not changed and it is signed the signature should be preserved + // unfortunately at this point we have only information whether the basic code has changed or not + // so the only way is to check the signature if the basic was not changed + try { - uno::Reference< embed::XStorage > xMetaInf = GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - embed::ElementModes::READ ); - uno::Reference< embed::XStorage > xTargetMetaInf = rMedium.GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - embed::ElementModes::WRITE ); - - if ( xMetaInf.is() && xTargetMetaInf.is() ) + // get the ODF version of the new medium + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= ::rtl::OUString(); + try + { + uno::Reference < beans::XPropertySet > xPropSet( rMedium.GetStorage(), uno::UNO_QUERY_THROW ); + aArgs[0] = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ); + } + catch( uno::Exception& ) { - xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName ); - - // after loading the UseCommonStoragePassword property might be set to true - // set it to false here, since this is a rare case when it must be so - // TODO/LATER: in future it should be done on loading probably - uno::Reference< beans::XPropertySet > xTargetSignPropSet( - xTargetMetaInf->openStreamElement( aScriptSignName, embed::ElementModes::WRITE ), - uno::UNO_QUERY_THROW ); - xTargetSignPropSet->setPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ), - uno::makeAny( (sal_Bool)sal_False ) ); - - uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); - if ( xTransact.is() ) - xTransact->commit(); - bScriptSignatureIsCopied = sal_True; } - } - } - catch( uno::Exception& ) - { - } - } - - if ( bOk ) - { - AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Medium commit." ) ) ); - // transfer data to its destinated location - // the medium commits the storage or the stream it is based on - RegisterTransfer( rMedium ); - bOk = rMedium.Commit(); + xDDSigns = uno::Reference< security::XDocumentDigitalSignatures >( + comphelper::getProcessServiceFactory()->createInstanceWithArguments( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), + aArgs ), + uno::UNO_QUERY_THROW ); - if ( bOk && bScriptSignatureIsCopied ) - { - AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Script signature check." ) ) ); + ::rtl::OUString aScriptSignName = xDDSigns->getScriptingContentSignatureDefaultStreamName(); - // if the script signature was copied it should be checked now - // usually it should be ok, so no additional actions will be done - // but if for any reasong ( f.e. binshell change ) it is broken it should be removed here - // in result the behaviour will work in optimized way in most cases, means in case of signed basic scripts - OSL_ENSURE( !bScriptSignatureIsCopied || xDDSigns.is(), "The signing could not be done without the service!\n" ); - if ( xDDSigns.is() ) - { - try + if ( aScriptSignName.getLength() ) { - bOk = sal_False; - ::com::sun::star::uno::Sequence< security::DocumentSignatureInformation > aInfos = - xDDSigns->verifyScriptingContentSignatures( rMedium.GetLastCommitReadStorage_Impl(), - uno::Reference< io::XInputStream >() ); - sal_uInt16 nState = ImplCheckSignaturesInformation( aInfos ); - if ( nState == SIGNATURESTATE_SIGNATURES_OK || nState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) - { - rMedium.SetCachedSignatureState_Impl( nState ); - bOk = sal_True; - } - else + pMedium->Close(); + + // target medium is still not commited, it should not be closed + // commit the package storage and close it, but leave the streams open + rMedium.StorageCommit_Impl(); + rMedium.CloseStorage(); + + uno::Reference< embed::XStorage > xReadOrig = pMedium->GetZipStorageToSign_Impl(); + if ( !xReadOrig.is() ) + throw uno::RuntimeException(); + uno::Reference< embed::XStorage > xMetaInf = xReadOrig->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), + embed::ElementModes::READ ); + + uno::Reference< embed::XStorage > xTarget = rMedium.GetZipStorageToSign_Impl( sal_False ); + if ( !xTarget.is() ) + throw uno::RuntimeException(); + uno::Reference< embed::XStorage > xTargetMetaInf = xTarget->openStorageElement( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), + embed::ElementModes::READWRITE ); + + if ( xMetaInf.is() && xTargetMetaInf.is() ) { - // the signature is broken, remove it - rMedium.SetCachedSignatureState_Impl( SIGNATURESTATE_NOSIGNATURES ); - uno::Reference< embed::XStorage > xTargetMetaInf = rMedium.GetStorage()->openStorageElement( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) ), - embed::ElementModes::WRITE ); + xMetaInf->copyElementTo( aScriptSignName, xTargetMetaInf, aScriptSignName ); + + uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); - if ( xTargetMetaInf.is() ) + xTargetMetaInf->dispose(); + + // now check the copied signature + uno::Sequence< security::DocumentSignatureInformation > aInfos = + xDDSigns->verifyScriptingContentSignatures( xTarget, + uno::Reference< io::XInputStream >() ); + sal_uInt16 nState = ImplCheckSignaturesInformation( aInfos ); + if ( nState == SIGNATURESTATE_SIGNATURES_OK || nState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || nState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) { - xTargetMetaInf->removeElement( xDDSigns->getScriptingContentSignatureDefaultStreamName() ); - uno::Reference< embed::XTransactedObject > xTransact( xTargetMetaInf, uno::UNO_QUERY ); + rMedium.SetCachedSignatureState_Impl( nState ); + + // commit the ZipStorage from target medium + xTransact.set( xTarget, uno::UNO_QUERY ); if ( xTransact.is() ) xTransact->commit(); - - bOk = rMedium.Commit(); + } + else + { + // it should not happen, the copies signature is invalid! + // throw the changes away + OSL_ASSERT( "An invalid signature was copied!" ); } } } - catch( uno::Exception ) - { - OSL_ENSURE( sal_False, "This exception must not happen!" ); - } } + catch( uno::Exception& ) + { + } + + pMedium->Close(); + rMedium.CloseZipStorage_Impl(); } + AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Medium commit." ) ) ); + + // transfer data to its destinated location + // the medium commits the storage or the stream it is based on + RegisterTransfer( rMedium ); + bOk = rMedium.Commit(); + if ( bOk ) { AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Storing is successful." ) ) ); diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index 569c22cef8..d5292df407 100644 --- a/sfx2/source/doc/objxtor.cxx +++ b/sfx2/source/doc/objxtor.cxx @@ -265,6 +265,7 @@ SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell ) ,m_bCreateTempStor( sal_False ) ,m_xDocInfoListener() ,m_bIsInit( sal_False ) + ,m_bIncomplEncrWarnShown( sal_False ) { } @@ -368,7 +369,7 @@ SfxObjectShell::~SfxObjectShell() pImp->xModel = ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > (); // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned! - if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage() == pImp->m_xDocStorage ) + if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage ) pMedium->CanDisposeStorage_Impl( sal_False ); if ( pImp->mpObjectContainer ) diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index cf755231bc..8b5c32feeb 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -2850,19 +2850,9 @@ void SfxBaseModel::impl_store( const ::rtl::OUString& sURL // TODO/LATER: a general way to set the error context should be available SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, m_pData->m_pObjectShell->GetTitle() ); - ::com::sun::star::uno::Any aInteraction; - ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1); - ::framework::ContinuationApprove* pApprove = new ::framework::ContinuationApprove(); - lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >(static_cast< ::com::sun::star::task::XInteractionContinuation* >(pApprove), uno::UNO_QUERY); - ::com::sun::star::task::ErrorCodeRequest aErrorCode; aErrorCode.ErrCode = nErrCode; - aInteraction <<= aErrorCode; - - ::framework::InteractionRequest* pRequest = new ::framework::InteractionRequest(aInteraction,lContinuations); - ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest > xRequest(static_cast< ::com::sun::star::task::XInteractionRequest* >(pRequest), uno::UNO_QUERY); - - xHandler->handle(xRequest); + SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False ); } } diff --git a/sfx2/source/inc/helper.hxx b/sfx2/source/inc/helper.hxx index cf86ba33ca..78f9071c41 100644 --- a/sfx2/source/inc/helper.hxx +++ b/sfx2/source/inc/helper.hxx @@ -70,7 +70,6 @@ public: static sal_Bool MakeFolder( const String& rFolder ); static ErrCode QueryDiskSpace( const String& rPath, sal_Int64& rFreeBytes ); static ULONG GetSize( const String& rContent ); - static sal_Bool IsYounger( const String& rIsYoung, const String& rIsOlder ); // please don't use this! static sal_Bool Exists( const String& rContent ); diff --git a/sfx2/source/inc/objshimp.hxx b/sfx2/source/inc/objshimp.hxx index 77d8cae84b..54a5f2eca6 100644 --- a/sfx2/source/inc/objshimp.hxx +++ b/sfx2/source/inc/objshimp.hxx @@ -171,6 +171,9 @@ struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess ::com::sun::star::uno::Reference< ::com::sun::star::logging::XSimpleLogRing > m_xLogRing; + sal_Bool m_bIncomplEncrWarnShown; + + SfxObjectShell_Impl( SfxObjectShell& _rDocShell ); virtual ~SfxObjectShell_Impl(); @@ -180,10 +183,12 @@ struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess virtual sal_Int16 getCurrentMacroExecMode() const; virtual sal_Bool setCurrentMacroExecMode( sal_uInt16 nMacroMode ); virtual ::rtl::OUString getDocumentLocation() const; - virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getLastCommitDocumentStorage(); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getZipStorageToSign(); virtual sal_Bool documentStorageHasMacros() const; virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const; - virtual sal_Int16 getScriptingSignatureState() const; + virtual sal_Int16 getScriptingSignatureState(); + + virtual sal_Bool hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor ); virtual void showBrokenSignatureWarning( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxInteraction ) const; }; diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 2c026abc44..2ad6ea9377 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -77,6 +77,7 @@ #include <rtl/ustrbuf.hxx> #include <unotools/localfilehelper.hxx> +#include <unotools/ucbhelper.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/configurationhelper.hxx> @@ -453,7 +454,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) // to the logical one, then on file system it can be checked that the copy is still newer than the original and no document reload is required if ( ( !bNeedsReload && ( (aMedObj.GetProtocol() == INET_PROT_FILE && aMedObj.getFSysPath(INetURLObject::FSYS_DETECT) != aPhysObj.getFSysPath(INetURLObject::FSYS_DETECT) && - SfxContentHelper::IsYounger( aPhysObj.GetMainURL( INetURLObject::NO_DECODE ), aMedObj.GetMainURL( INetURLObject::NO_DECODE ) )) + !::utl::UCBContentHelper::IsYounger( aMedObj.GetMainURL( INetURLObject::NO_DECODE ), aPhysObj.GetMainURL( INetURLObject::NO_DECODE ) )) || pMed->IsRemote() ) ) || pVersionItem ) { @@ -716,7 +717,9 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) // eigentliches Reload //pNewSet->Put( SfxFrameItem ( SID_DOCFRAME, GetFrame() ) ); - //pNewSet->Put( SfxBoolItem( SID_SILENT, sal_True ) ); + + if ( pSilentItem && pSilentItem->GetValue() ) + pNewSet->Put( SfxBoolItem( SID_SILENT, sal_True ) ); SFX_ITEMSET_ARG(pNewSet, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, FALSE); SFX_ITEMSET_ARG(pNewSet, pMacroExecItem , SfxUInt16Item, SID_MACROEXECMODE , FALSE); @@ -820,6 +823,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) } xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_RELOAD ); + xNewObj->GetMedium()->GetItemSet()->ClearItem( SID_SILENT ); UpdateDocument_Impl(); } diff --git a/svx/inc/svx/dialogs.hrc b/svx/inc/svx/dialogs.hrc index de1fd8e671..c97d7bb74f 100644 --- a/svx/inc/svx/dialogs.hrc +++ b/svx/inc/svx/dialogs.hrc @@ -600,6 +600,7 @@ #define RID_SVXSTR_XMLSEC_SIG_OK_NO_VERIFY (RID_SVX_START + 223) #define RID_SVXSTR_XMLSEC_SIG_NOT_OK (RID_SVX_START + 224) #define RID_SVXSTR_XMLSEC_NO_SIG (RID_SVX_START + 225) +#define RID_SVXSTR_XMLSEC_SIG_CERT_OK_PARTIAL_SIG (RID_SVX_START + 226) // Strings von der Hatch-Tabpage #define RID_SVXSTR_WRITE_DATA_ERROR (RID_SVX_START + 229) diff --git a/svx/source/stbctrls/stbctrls.src b/svx/source/stbctrls/stbctrls.src index b4dac873bf..70ac1d96b8 100644 --- a/svx/source/stbctrls/stbctrls.src +++ b/svx/source/stbctrls/stbctrls.src @@ -1,4 +1,4 @@ -/************************************************************************* +/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -87,6 +87,11 @@ String RID_SVXSTR_XMLSEC_NO_SIG Text [ en-US ] = "Digital Signature: The document is not signed."; }; +String RID_SVXSTR_XMLSEC_SIG_CERT_OK_PARTIAL_SIG +{ + Text [ en-US ] = "Digital Signature: The document signature and the certificate are OK, but not all parts of the document are signed."; +}; + // PopupMenu ------------------------------------------------------------- Menu RID_SVXMNU_ZOOM { diff --git a/svx/source/stbctrls/xmlsecctrl.cxx b/svx/source/stbctrls/xmlsecctrl.cxx index e6f4f7e592..554366c9f1 100644 --- a/svx/source/stbctrls/xmlsecctrl.cxx +++ b/svx/source/stbctrls/xmlsecctrl.cxx @@ -143,6 +143,9 @@ void XmlSecStatusBarControl::StateChanged( USHORT nSID, SfxItemState eState, con nResId = RID_SVXSTR_XMLSEC_SIG_NOT_OK; else if ( mpImpl->mnState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) nResId = RID_SVXSTR_XMLSEC_SIG_OK_NO_VERIFY; + else if ( mpImpl->mnState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK ) + nResId = RID_SVXSTR_XMLSEC_SIG_CERT_OK_PARTIAL_SIG; + GetStatusBar().SetQuickHelpText( GetId(), SVX_RESSTR( nResId ) ); } @@ -192,7 +195,8 @@ void XmlSecStatusBarControl::Paint( const UserDrawEvent& rUsrEvt ) ++aRect.Top(); pDev->DrawImage( aRect.TopLeft(), mpImpl->maImageBroken ); } - else if( mpImpl->mnState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED ) + else if( mpImpl->mnState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED + || mpImpl->mnState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK) { ++aRect.Top(); pDev->DrawImage( aRect.TopLeft(), mpImpl->maImageNotValidated ); diff --git a/svx/source/svxlink/fileobj.cxx b/svx/source/svxlink/fileobj.cxx index a97efb3d70..a77c8852bb 100644 --- a/svx/source/svxlink/fileobj.cxx +++ b/svx/source/svxlink/fileobj.cxx @@ -121,37 +121,6 @@ BOOL SvFileObject::GetData( ::com::sun::star::uno::Any & rData, // relativen Datei Links aufzuloesen!!!! Wird ueber den // LinkManager und damit von dessen Storage erledigt. rData <<= rtl::OUString( sFileNm ); - -/* -=========================================================================== -JP 28.02.96: noch eine Baustelle: - Idee: hier das Medium und die DocShell anlegen, Doc laden - und ueber OLE-SS (GetObj(...)) den Bereich als - PseudoObject erfragen. Dieses mit den Daten oder - dessen Daten verschicken. - -=========================================================================== - - SfxMedium aMed( aFileNm.GetFull(), STREAM_READ, TRUE ); - aMed.DownLoad(); // nur mal das Medium anfassen (DownLoaden) - - if( aMed.IsStorage() ) - pSvData->SetData( SvStorageRef( aMed.GetStorage() ), - TRANSFER_COPY ); - else - { - SvStream* pStream = aMed.GetInStream(); - if( !pStream ) - return FALSE; - - UINT32 nLen = pStream->Seek( STREAM_SEEK_TO_END ); - pStream->Seek( STREAM_SEEK_TO_BEGIN ); - - void* pData = SvMemAlloc( nLen ); - pStream->Read( pData, nLen ); - pSvData->SetData( pData, nLen, TRANSFER_MOVE ); - } -*/ } break; diff --git a/svx/source/xml/xmlxtimp.cxx b/svx/source/xml/xmlxtimp.cxx index d5d2041060..fb10ef3e8e 100644 --- a/svx/source/xml/xmlxtimp.cxx +++ b/svx/source/xml/xmlxtimp.cxx @@ -394,7 +394,7 @@ sal_Bool SvxXMLXTableImport::load( const OUString& rUrl, const uno::Reference< X if( aMedium.IsStorage() ) { - uno::Reference < embed::XStorage > xStorage( aMedium.GetStorage(), uno::UNO_QUERY_THROW ); + uno::Reference < embed::XStorage > xStorage( aMedium.GetStorage( sal_False ), uno::UNO_QUERY_THROW ); const String aContentStmName( RTL_CONSTASCII_USTRINGPARAM( "Content.xml" ) ); xIStm.set( xStorage->openStreamElement( aContentStmName, embed::ElementModes::READ ), uno::UNO_QUERY_THROW ); diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx index 7f384a70f3..1315b32bd5 100644 --- a/uui/source/iahndl.cxx +++ b/uui/source/iahndl.cxx @@ -68,6 +68,8 @@ #include "com/sun/star/task/ErrorCodeRequest.hpp" #include "com/sun/star/task/MasterPasswordRequest.hpp" #include "com/sun/star/task/NoMasterException.hpp" +#include "com/sun/star/task/DocumentMacroConfirmationRequest.hpp" +#include "com/sun/star/task/DocumentMacroConfirmationRequest2.hpp" #include "com/sun/star/task/XInteractionAbort.hpp" #include "com/sun/star/task/XInteractionApprove.hpp" #include "com/sun/star/task/XInteractionDisapprove.hpp" @@ -113,6 +115,7 @@ #include "svtools/sfxecode.hxx" #include "toolkit/helper/vclunohelper.hxx" #include "comphelper/sequenceashashmap.hxx" +#include "comphelper/documentconstants.hxx" #include "unotools/configmgr.hxx" #include "ids.hrc" @@ -1255,7 +1258,23 @@ bool UUIInteractionHelper::handleErrorHandlerRequests( if (aAnyRequest >>= aMacroConfirmRequest) { handleMacroConfirmRequest( - aMacroConfirmRequest, + aMacroConfirmRequest.DocumentURL, + aMacroConfirmRequest.DocumentStorage, + ODFVER_012_TEXT, + aMacroConfirmRequest.DocumentSignatureInformation, + rRequest->getContinuations() + ); + return true; + } + + star::task::DocumentMacroConfirmationRequest2 aMacroConfirmRequest2; + if (aAnyRequest >>= aMacroConfirmRequest2) + { + handleMacroConfirmRequest( + aMacroConfirmRequest2.DocumentURL, + aMacroConfirmRequest2.DocumentZipStorage, + aMacroConfirmRequest2.DocumentVersion, + aMacroConfirmRequest2.DocumentSignatureInformation, rRequest->getContinuations() ); return true; @@ -3044,13 +3063,13 @@ UUIInteractionHelper::handleGenericErrorRequest( ErrCode nError = (ErrCode)nErrorCode; sal_Bool bWarning = !ERRCODE_TOERROR(nError); - if ( nError == ERRCODE_SFX_BROKENSIGNATURE ) + if ( nError == ERRCODE_SFX_BROKENSIGNATURE + || nError == ERRCODE_SFX_INCOMPLETE_ENCRYPTION ) { - // the broken signature warning needs a special title + // the security warning need a special title String aErrorString; ErrorHandler::GetErrorString( nErrorCode, aErrorString ); - std::auto_ptr< ResMgr > xManager( ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); ::rtl::OUString aTitle; @@ -3064,7 +3083,8 @@ UUIInteractionHelper::handleGenericErrorRequest( } catch( star::uno::Exception& ) {} - ::rtl::OUString aErrTitle = String( ResId( STR_WARNING_BROKENSIGNATURE_TITLE, *xManager.get() ) ); + ::rtl::OUString aErrTitle = String( ResId( nError == ERRCODE_SFX_BROKENSIGNATURE ? STR_WARNING_BROKENSIGNATURE_TITLE : STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE, *xManager.get() ) ); + if ( aTitle.getLength() && aErrTitle.getLength() ) aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " - " ) ); aTitle += aErrTitle; @@ -3100,7 +3120,10 @@ namespace void UUIInteractionHelper::handleMacroConfirmRequest( - const star::task::DocumentMacroConfirmationRequest& _rRequest, + const ::rtl::OUString& aDocumentURL, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xZipStorage, + const ::rtl::OUString& aDocumentVersion, + const ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignatureInformation > aSignInfo, star::uno::Sequence< star::uno::Reference< star::task::XInteractionContinuation > > const & rContinuations ) @@ -3114,17 +3137,17 @@ UUIInteractionHelper::handleMacroConfirmRequest( std::auto_ptr< ResMgr > pResMgr( ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) ); if ( pResMgr.get() ) { - bool bShowSignatures = _rRequest.DocumentSignatureInformation.getLength() > 0; + bool bShowSignatures = aSignInfo.getLength() > 0; MacroWarning aWarning( getParentProperty(), bShowSignatures, *pResMgr.get() ); - aWarning.SetDocumentURL( _rRequest.DocumentURL ); - if ( _rRequest.DocumentSignatureInformation.getLength() > 1 ) + aWarning.SetDocumentURL( aDocumentURL ); + if ( aSignInfo.getLength() > 1 ) { - aWarning.SetStorage( _rRequest.DocumentStorage, _rRequest.DocumentSignatureInformation ); + aWarning.SetStorage( xZipStorage, aDocumentVersion, aSignInfo ); } - else if ( _rRequest.DocumentSignatureInformation.getLength() == 1 ) + else if ( aSignInfo.getLength() == 1 ) { - aWarning.SetCertificate( _rRequest.DocumentSignatureInformation[ 0 ].Signer ); + aWarning.SetCertificate( aSignInfo[ 0 ].Signer ); } bApprove = aWarning.Execute() == RET_OK; diff --git a/uui/source/iahndl.hxx b/uui/source/iahndl.hxx index ba09ba30a1..4a40445a55 100644 --- a/uui/source/iahndl.hxx +++ b/uui/source/iahndl.hxx @@ -36,13 +36,15 @@ #define INCLUDED_VECTOR #endif #include "osl/mutex.hxx" -#include "com/sun/star/beans/Optional.hpp" #include "com/sun/star/uno/Reference.hxx" #include "com/sun/star/uno/Sequence.hxx" + +#include "com/sun/star/beans/Optional.hpp" +#include "com/sun/star/embed/XStorage.hpp" #include "com/sun/star/task/InteractionClassification.hpp" #include "com/sun/star/task/PasswordRequestMode.hpp" -#include "com/sun/star/task/DocumentMacroConfirmationRequest.hpp" #include "com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp" +#include "com/sun/star/security/DocumentSignatureInformation.hpp" #include "tools/solar.h" #include "tools/errcode.hxx" #include "vcl/wintypes.hxx" @@ -360,7 +362,10 @@ private: void handleMacroConfirmRequest( - const ::com::sun::star::task::DocumentMacroConfirmationRequest& _rRequest, + const ::rtl::OUString& aDocumentURL, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xZipStorage, + const ::rtl::OUString& aDocumentVersion, + const ::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignatureInformation > aSignInfo, com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::task::XInteractionContinuation > > const & diff --git a/uui/source/ids.hrc b/uui/source/ids.hrc index 677767bde4..bbfcaf7764 100644 --- a/uui/source/ids.hrc +++ b/uui/source/ids.hrc @@ -87,7 +87,8 @@ #define STR_ALREADYOPEN_SAVE_MSG (RID_UUI_START + 50) #define STR_ALREADYOPEN_RETRY_SAVE_BTN (RID_UUI_START + 51) #define STR_ALREADYOPEN_SAVE_BTN (RID_UUI_START + 52) -#define RID_DLG_NEWER_VERSION_WARNING (RID_UUI_START + 36) +#define RID_DLG_NEWER_VERSION_WARNING (RID_UUI_START + 53) +#define STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE (RID_UUI_START + 54) #define ERRCODE_UUI_IO_ABORT (ERRCODE_AREA_UUI + 0) #define ERRCODE_UUI_IO_ACCESSDENIED (ERRCODE_AREA_UUI + 1) diff --git a/uui/source/ids.src b/uui/source/ids.src index ad2a1b5926..0d38a5fd0a 100644 --- a/uui/source/ids.src +++ b/uui/source/ids.src @@ -50,6 +50,11 @@ String( STR_WARNING_BROKENSIGNATURE_TITLE ) Text [ en-US ] = "Invalid Document Signature" ; }; +String( STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE ) +{ + Text [ en-US ] = "Non-Encrypted Streams" ; +}; + Resource RID_UUI_ERRHDL { String (ERRCODE_UUI_IO_ABORT & ERRCODE_RES_MASK) @@ -313,7 +318,7 @@ Resource RID_UUI_ERRHDL String (ERRCODE_UUI_IO_BROKENPACKAGE & ERRCODE_RES_MASK) { - Text [ en-US ] = "The file '$(ARG1)' is corrupt and therefore cannot be opened. Should %PRODUCTNAME repair the file?"; + Text [ en-US ] = "The file '$(ARG1)' is corrupt and therefore cannot be opened. %PRODUCTNAME can try to repair the file.\n\nThe corruption could be the result of document manipulation or of structural document damage due to data transmission.\n\nWe recommend that you do not trust the content of the repaired document.\nExecution of macros is disabled for this document.\n\nShould %PRODUCTNAME repair the file?\n"; }; String (ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR & ERRCODE_RES_MASK) diff --git a/uui/source/secmacrowarnings.cxx b/uui/source/secmacrowarnings.cxx index 8545b5de5d..db272a88f9 100644 --- a/uui/source/secmacrowarnings.cxx +++ b/uui/source/secmacrowarnings.cxx @@ -32,6 +32,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/security/XDocumentDigitalSignatures.hpp> #include <comphelper/sequence.hxx> +#include "comphelper/documentconstants.hxx" #include <comphelper/processfactory.hxx> #include <vcl/msgbox.hxx> @@ -122,8 +123,10 @@ IMPL_LINK( MacroWarning, ViewSignsBtnHdl, void*, EMPTYARG ) { DBG_ASSERT( mxCert.is(), "*MacroWarning::ViewSignsBtnHdl(): no certificate set!" ); + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] = uno::makeAny( maODFVersion ); uno::Reference< security::XDocumentDigitalSignatures > xD( - comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY ); + comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY ); if( xD.is() ) { if( mxCert.is() ) @@ -139,8 +142,10 @@ IMPL_LINK( MacroWarning, EnableBtnHdl, void*, EMPTYARG ) { if( mbSignedMode && maAlwaysTrustCB.IsChecked() ) { // insert path into trusted path list + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] = uno::makeAny( maODFVersion ); uno::Reference< security::XDocumentDigitalSignatures > xD( - comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY ); + comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY ); if( xD.is() ) { if( mxCert.is() ) @@ -337,21 +342,23 @@ void MacroWarning::FitControls() } void MacroWarning::SetStorage( const cssu::Reference < css::embed::XStorage >& rxStore, - const cssu::Sequence< security::DocumentSignatureInformation >& _rInfos ) + const ::rtl::OUString& aODFVersion, + const cssu::Sequence< security::DocumentSignatureInformation >& rInfos ) { mxStore = rxStore; - sal_Int32 nCnt = _rInfos.getLength(); + maODFVersion = aODFVersion; + sal_Int32 nCnt = rInfos.getLength(); if( mxStore.is() && nCnt > 0 ) { - mpInfos = &_rInfos; + mpInfos = &rInfos; String aCN_Id( String::CreateFromAscii( "CN" ) ); String s; - s = GetContentPart( _rInfos[ 0 ].Signer->getSubjectName(), aCN_Id ); + s = GetContentPart( rInfos[ 0 ].Signer->getSubjectName(), aCN_Id ); for( sal_Int32 i = 1 ; i < nCnt ; ++i ) { s.AppendAscii( "\n" ); - s += GetContentPart( _rInfos[ i ].Signer->getSubjectName(), aCN_Id ); + s += GetContentPart( rInfos[ i ].Signer->getSubjectName(), aCN_Id ); } maSignsFI.SetText( s ); diff --git a/uui/source/secmacrowarnings.hxx b/uui/source/secmacrowarnings.hxx index ce4515f9d4..bce3f96a0c 100644 --- a/uui/source/secmacrowarnings.hxx +++ b/uui/source/secmacrowarnings.hxx @@ -60,6 +60,7 @@ private: cssu::Reference< css::security::XCertificate > mxCert; cssu::Reference< css::embed::XStorage > mxStore; + ::rtl::OUString maODFVersion; const cssu::Sequence< css::security::DocumentSignatureInformation >* mpInfos; FixedImage maSymbolImg; @@ -96,6 +97,7 @@ public: void SetDocumentURL( const String& rDocURL ); void SetStorage( const cssu::Reference < css::embed::XStorage >& rxStore, + const ::rtl::OUString& aODFVersion, const cssu::Sequence< css::security::DocumentSignatureInformation >& _rInfos ); void SetCertificate( const cssu::Reference< css::security::XCertificate >& _rxCert ); }; diff --git a/xmlhelp/source/cxxhelp/provider/databases.cxx b/xmlhelp/source/cxxhelp/provider/databases.cxx index 17b8714952..e4ab2e199b 100644 --- a/xmlhelp/source/cxxhelp/provider/databases.cxx +++ b/xmlhelp/source/cxxhelp/provider/databases.cxx @@ -52,6 +52,7 @@ #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/ucb/XCommandEnvironment.hpp> #include <com/sun/star/beans/Optional.hpp> +#include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/frame/XConfigManager.hpp> #include <com/sun/star/util/XMacroExpander.hpp> #include <com/sun/star/uri/XUriReferenceFactory.hpp> @@ -60,6 +61,7 @@ #include <comphelper/locale.hxx> #include <transex3/compilehelp.hxx> +#include <comphelper/storagehelper.hxx> #include "databases.hxx" #include "urlparameter.hxx" @@ -1085,7 +1087,7 @@ Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& ja zipFile = getInstallPathAsURL() + key; } - Sequence< Any > aArguments( 1 ); + Sequence< Any > aArguments( 2 ); XInputStream_impl* p = new XInputStream_impl( zipFile ); if( p->CtorSuccess() ) @@ -1099,6 +1101,12 @@ Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& ja aArguments[ 0 ] <<= zipFile; } + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + Reference< XInterface > xIfc = m_xSMgr->createInstanceWithArgumentsAndContext( rtl::OUString::createFromAscii( @@ -1867,9 +1875,15 @@ Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage try { - Sequence< Any > aArguments( 1 ); + Sequence< Any > aArguments( 2 ); aArguments[ 0 ] <<= zipFile; + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); Reference< XInterface > xIfc = xSMgr->createInstanceWithArgumentsAndContext( diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx index 3c6a8ea0a2..f597429a3e 100644 --- a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx +++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx @@ -749,8 +749,8 @@ fileMatch(const char * URI) { } static int -pkgMatch(const char * URI) { - if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.pkg:/", 18)) +zipMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18)) return 1; return 0; } @@ -770,7 +770,7 @@ fileOpen(const char *URI) { } static void * -pkgOpen(const char * /*URI*/) { +zipOpen(const char * /*URI*/) { rtl::OUString language,jar,path; if( ugblData->m_pInitial->get_eid().getLength() ) @@ -855,7 +855,7 @@ helpRead(void * context, char * buffer, int len) { } static int -pkgRead(void * context, char * buffer, int len) { +zipRead(void * context, char * buffer, int len) { if( ugblData->m_pInitial->get_eid().getLength() ) { ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len); @@ -1080,7 +1080,7 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, ugblData = &userData; - xmlRegisterInputCallbacks(pkgMatch, pkgOpen, pkgRead, uriClose); + xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose); xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose); xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose); //xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction ); @@ -1088,7 +1088,7 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, xsltStylesheetPtr cur = xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr()); - xmlDocPtr doc = xmlParseFile("vnd.sun.star.pkg:/"); + xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/"); xmlDocPtr res = xsltApplyStylesheet(cur, doc, parameter); if (res) @@ -1101,7 +1101,7 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, } xmlPopInputCallbacks(); //filePatch xmlPopInputCallbacks(); //helpPatch - xmlPopInputCallbacks(); //pkgMatch + xmlPopInputCallbacks(); //zipMatch xmlFreeDoc(res); xmlFreeDoc(doc); xsltFreeStylesheet(cur); diff --git a/xmloff/inc/xmloff/xmlimp.hxx b/xmloff/inc/xmloff/xmlimp.hxx index 5cc2734cf9..93b32254f8 100644 --- a/xmloff/inc/xmloff/xmlimp.hxx +++ b/xmloff/inc/xmloff/xmlimp.hxx @@ -175,6 +175,8 @@ protected: void SetAutoStyles( SvXMLStylesContext *pAutoStyles ); void SetMasterStyles( SvXMLStylesContext *pMasterStyles ); + sal_Bool IsODFVersionConsistent( const ::rtl::OUString& aODFVersion ); + const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedObjectResolver >& GetEmbeddedResolver() const { return mxEmbeddedResolver; } inline void SetEmbeddedResolver( com::sun::star::uno::Reference< com::sun::star::document::XEmbeddedObjectResolver >& _xEmbeddedResolver ); diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx index 9e37af91b7..df5c7d2987 100644 --- a/xmloff/source/core/xmlimp.cxx +++ b/xmloff/source/core/xmlimp.cxx @@ -58,13 +58,17 @@ #include <com/sun/star/lang/ServiceNotRegisteredException.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/document/XBinaryStreamResolver.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/xml/sax/XLocator.hpp> +#include <com/sun/star/packages/zip/ZipIOException.hpp> #include <comphelper/namecontainer.hxx> #include <rtl/logfile.hxx> #include <tools/string.hxx> // used in StartElement for logging #include <cppuhelper/implbase1.hxx> #include <comphelper/extract.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/documentconstants.hxx> +#include <comphelper/storagehelper.hxx> #include <vcl/fontcvt.hxx> #include <com/sun/star/rdf/XMetadatable.hpp> @@ -653,6 +657,21 @@ void SAL_CALL SvXMLImport::startElement( const OUString& rName, if ( rAttrName.equalsAscii("office:version") ) { mpImpl->aODFVersion = xAttrList->getValueByIndex( i ); + + // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2 + if ( mpImpl->mStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ) ) + && !IsODFVersionConsistent( mpImpl->aODFVersion ) ) + { + throw xml::sax::SAXException( + ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "Inconsistent ODF versions in content.xml and manifest.xml!" ) ), + uno::Reference< uno::XInterface >(), + uno::makeAny( + packages::zip::ZipIOException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "Inconsistent ODF versions in content.xml and manifest.xml!" ) ), + Reference< XInterface >() ) ) ); + } } else if( ( rAttrName.getLength() >= 5 ) && ( rAttrName.compareToAscii( sXML_xmlns, 5 ) == 0 ) && @@ -1602,6 +1621,50 @@ OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue) const return rValue; } +sal_Bool SvXMLImport::IsODFVersionConsistent( const ::rtl::OUString& aODFVersion ) +{ + // the check returns sal_False only if the storage version could be retrieved + sal_Bool bResult = sal_True; + + if ( aODFVersion.getLength() && aODFVersion.compareTo( ODFVER_012_TEXT ) >= 0 ) + { + // check the consistency only for the ODF1.2 and later ( according to content.xml ) + try + { + uno::Reference< document::XStorageBasedDocument > xDoc( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< embed::XStorage > xStor = xDoc->getDocumentStorage(); + uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW ); + + // the check should be done only for OASIS format + ::rtl::OUString aMediaType; + xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ) >>= aMediaType; + if ( ::comphelper::OStorageHelper::GetXStorageFormat( xStor ) >= SOFFICE_FILEFORMAT_8 ) + { + sal_Bool bRepairPackage = sal_False; + try + { + xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ) ) + >>= bRepairPackage; + } catch ( uno::Exception& ) + {} + + // check only if not in Repair mode + if ( !bRepairPackage ) + { + ::rtl::OUString aStorVersion; + xStorProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) + >>= aStorVersion; + bResult = aODFVersion.equals( aStorVersion ); + } + } + } + catch( uno::Exception& ) + {} + } + + return bResult; +} + void SvXMLImport::_CreateNumberFormatsSupplier() { DBG_ASSERT( !mxNumberFormatsSupplier.is(), |