Пример #1
0
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        /// <remarks>
        /// This method severely breaks encapsulating the chain, however it does
        /// so because the requirement breaks encapsulation and the original design
        /// of the class only consider streams not properties.  The requirement is
        /// that as we transition to/from a protected document we copy properties
        /// between the layers.  It was least risk to compromise the design here
        /// then extend it.
        /// </remarks>
        bool IDocumentController.SavePreperation(Document document)
        {
            // we don't have to check packageDoc for because we are only responsible
            // for PackageDocuments
            PackageDocument packageDoc = (PackageDocument)document;
            RightsDocument  rightsDoc  = document.Dependency as RightsDocument;

            if (rightsDoc != null)
            {
                bool isDestinationProtected = rightsDoc.IsDestinationProtected();
                bool isSourceProtected      = rightsDoc.IsSourceProtected();

                // the only time we don't need to copy properties is when
                // neither source nor destination is protected as OPC properties
                // are copied as parts

                // if the source was protected and the destination is not
                // then we need to copy properties to the package
                if (isSourceProtected && !isDestinationProtected)
                {
                    DocumentProperties.Copy(
                        new SuppressedProperties(rightsDoc.SourcePackage),
                        packageDoc.Package.PackageProperties);
                }

                // if the source was not protected and the destination is
                // then we need to copy properties from the package to the envelope
                if (!isSourceProtected && isDestinationProtected)
                {
                    DocumentProperties.Copy(
                        packageDoc.Package.PackageProperties,
                        new SuppressedProperties(rightsDoc.DestinationPackage));
                }

                // if they were both protected we need to copy properties
                // from the old envelope to the new
                if (isDestinationProtected && isSourceProtected)
                {
                    DocumentProperties.Copy(
                        new SuppressedProperties(rightsDoc.SourcePackage),
                        new SuppressedProperties(rightsDoc.DestinationPackage));
                }
            }
            return(true);
        }
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.SavePreperation(Document document)
        {
            bool handled = false;

            RightsDocument doc      = (RightsDocument)document; // see class remarks on why this is ok
            Stream         ciphered = doc.Dependency.Destination;
            Stream         clear    = ciphered;

            // We protect the actual decrypted content (if necessary) using the
            // RightsManagementSuppressedStream that prevents callers from writing
            // to it. This still allows us to save an acquired use license back to
            // the package even if the user does not have the permissions to modify
            // the document itself. It also means that there is no need to check if
            // the user has permission to save before starting the operation.

            // If we are encrypted and the destination stream is identical to the
            // source stream, there is no need to create a new envelope. Instead we
            // can simply open the envelope on the destination stream, which
            // already contains the complete encrypted envelope that was the source
            // file.
            //
            // It doesn't actually matter to this class why the flag was set, but
            // we know the destination is identical to the source in two situations:
            //  1) The source and the destination are the same file, and since the
            //     publish license didn't change there is no need to write to a
            //     temporary file first
            //  2) The destination file was copied directly from the source file.
            if (doc.IsDestinationProtected() && doc.IsDestinationIdenticalToSource)
            {
                // we can't reuse protections because EncryptedPackage caches the
                // original permissions for the stream (if we re-open the package r/w
                // the Encrypted package will still be r/o)

                doc.DestinationPackage = OpenEnvelopeOnStream(
                    doc.Dependency.Destination);

                doc.DestinationPackage.RightsManagementInformation.CryptoProvider =
                    doc.SourcePackage.RightsManagementInformation.CryptoProvider;

                clear = DecryptEnvelopeAndSuppressStream(
                    doc.DestinationPackage,
                    DocumentRightsManagementManager.Current.HasPermissionToEdit);
                doc.DestinationProxy = new StreamProxy(clear);

                // save the use license in case the user acquired one
                _provider.Value.SaveUseLicense(doc.DestinationPackage);

                handled = true;

                Trace.SafeWrite(
                    Trace.Rights,
                    "Reused CryptoProvider as underlying stream is the same.");
            }
            else // we are not protected and/or the RM protections have changed
            {
                bool canEdit =
                    DocumentRightsManagementManager.Current.HasPermissionToEdit;

                // canEdit should always be true here - either the document is not
                // protected, or the protections have been changed.  In the latter
                // case, the user has to have Owner permissions to change the
                // protections, and that of course includes Edit permissions.
                Invariant.Assert(
                    canEdit,
                    "Cannot save with changes if Edit permission was not granted.");

                EncryptedPackageEnvelope encryptedPackage =
                    _provider.Value.EncryptPackage(ciphered);

                // the destination is intended to be encrypted when a non-null
                // value is returned

                if (encryptedPackage != null)
                {
                    clear = DecryptEnvelopeAndSuppressStream(
                        encryptedPackage,
                        canEdit);
                    doc.DestinationPackage = encryptedPackage;
                }

                Trace.SafeWriteIf(
                    encryptedPackage == null,
                    Trace.Rights,
                    "Destination package is unprotected.");

                doc.DestinationProxy = new StreamProxy(clear);

                // If the destination file is not identical to the source file, we
                // need to copy the (possibly decrypted) source stream to the
                // destination here.
                if (!doc.IsDestinationIdenticalToSource)
                {
                    StreamHelper.CopyStream(doc.Source, doc.Destination);

                    doc.DestinationProxy.Flush();

                    Trace.SafeWrite(
                        Trace.Rights,
                        "Copied Source contents to Destination.");
                }

                handled = true;
            }

            return(handled);
        }