RightsManagementManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / TrustUi / MS / Internal / documents / RightsManagementManager.cs / 1 / RightsManagementManager.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//    DocumentRightsManagementManager is an internal API for Mongoose to deal
//    with Rights Management. 
//
// History:
// 06/14/05 - [....] created
// 
//---------------------------------------------------------------------------
 
#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings 

using System; 
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Security; 
using System.Security.Permissions;
using System.Security.RightsManagement; 
using System.Text; 
using System.Threading;
using System.Windows.Forms; 
using System.Windows.Threading;
using System.Windows.TrustUI;

using MS.Internal.Documents.Application; 
using MS.Internal.PresentationUI;
 
namespace MS.Internal.Documents 
{
    ///  
    /// RightsManagementManager is a internal Avalon class used to expose the RM Document API .
    /// 
    /// 
    /// This class serves as the controller that is between the UI and the facade for 
    /// the RM APIs.
    ///  
    [FriendAccessAllowed] 
    internal sealed class DocumentRightsManagementManager
    { 
        #region Constructors
        //-----------------------------------------------------
        // Constructors
        //----------------------------------------------------- 

        ///  
        /// A constructor that takes the RM provider to use 
        /// 
        ///  
        ///     Critical - Since the rmProvider is considered critical data.
        /// 
        [SecurityCritical]
        private DocumentRightsManagementManager(IRightsManagementProvider rmProvider) 
        {
            if (rmProvider != null) 
            { 
                _rmProviderCache.Value = rmProvider;
            } 
            else
            {
                throw new ArgumentNullException("rmProvider");
            } 

            //Create dictionary for Credential Management 
            //used to map between CredManResources and RM Users 
            _userMap = new Dictionary();
 
            // notify the documentmanager when the license changes
            PublishLicenseChange += DocumentManager.OnModify;
        }
 
        #endregion Constructors
 
        #region Internal Methods 
        //------------------------------------------------------
        // Internal Methods 
        //-----------------------------------------------------

        /// 
        /// Initializes a new singleton instance of the DocumentRightsManagementManager 
        /// 
        /// The provider underlying the manager 
        ///  
        ///     Critical - Creating a new manager and saving the current instance
        ///                are both critical operations. 
        /// 
        [SecurityCritical]
        internal static void Initialize(IRightsManagementProvider rmProvider)
        { 
             Trace.SafeWrite(Trace.Rights, "Initializing RightsManagementManager");
 
             System.Diagnostics.Debug.Assert( 
                 _currentManager.Value == null,
                 "RightsManagementManager initialized twice."); 

             if (_currentManager.Value == null)
             {
                 _currentManager.Value = new DocumentRightsManagementManager(rmProvider); 
             }
        } 
 
        /// 
        /// Decrypts the encrypted document using the appropriate credentials. 
        /// Returns null if the document is not actually encrypted or the
        /// encrypted document could not be decrypted.
        /// 
        /// A decrypted stream containing an XPS document. 
        internal Stream DecryptPackage()
        { 
            // If the RM client is not installed, prompt the user to install it. 
            // If the user accepts, this will cause a navigation to the install site
            // in a separate window. 
            if (!IsRMClientInstalled())
            {
                PromptToInstallRM();
 
                // Return null to abort document loading.
                return null; 
            } 

            Stream returnPackage = null; 

            if (_rmProvider.IsProtected)
            {
                Trace.SafeWrite(Trace.Rights, "Document is protected."); 

                // Try to get a set of credentials so we can try to decrypt 
                // the document. If we can't choose any credentials at all, 
                // we can't decrypt the document.
                if (ChooseCredentials(true)) 
                {
                    // See if the set of credentials chosen has permission to
                    // view the document.
                    RightsManagementLicense license = GetUseLicense(); 

                    if (license != null && 
                        license.HasPermission(RightsManagementPermissions.AllowView)) 
                    {
                        Trace.SafeWrite( 
                            Trace.Rights,
                            "User has enough rights; decrypting package.");

                        try 
                        {
                            returnPackage = _rmProvider.DecryptPackage(); 
                        } 
                        catch (RightsManagementException exception)
                        { 
                            RightsManagementErrorHandler.HandleOrRethrowException(
                                RightsManagementOperation.Decrypt,
                                exception);
                        } 
                    }
                } 
            } 

            return returnPackage; 
        }

        /// 
        /// Forces an Evaluate which will result in RMPolicy event being fired.  This is 
        /// only valid after a decrypted Package is available (i.e. either the protected
        /// package has been decrypted, or the package was never protected). 
        ///  
        ///
        /// Critical 
        ///  1) Determines the current RMPolicy and issues an event with the
        ///     resulting policy.
        /// TreatAsSafe
        ///  1) The resulting policy is either hardcoded or acquired from the 
        ///     _rmProvider, which is critical for set.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void Evaluate()
        { 
            RightsManagementStatus calcRMStatus = RightsManagementStatus.Unprotected;
            RightsManagementPolicy calcRMPolicy = RightsManagementPolicy.AllowView;

            //Check to see if document is protected. 
            if (_rmProvider.IsProtected)
            { 
                calcRMStatus = RightsManagementStatus.Protected; 

                // Get the rights granted from the RM license 
                RightsManagementLicense rmLicense = GetUseLicense();

                if (rmLicense == null)
                { 
                    calcRMPolicy = RightsManagementPolicy.AllowNothing;
                } 
                else 
                {
                    calcRMPolicy = rmLicense.ConvertToPolicy(); 
                }
            }
            else
            { 
                Trace.SafeWrite(
                    Trace.Rights, 
                    "Evaluate: Document is not protected; using default policy."); 

                //There is no RM policy applied to this document. 
                calcRMPolicy =
                    RightsManagementPolicy.AllowAnnotate |
                    RightsManagementPolicy.AllowCopy |
                    RightsManagementPolicy.AllowSign | 
                    RightsManagementPolicy.AllowPrint |
                    RightsManagementPolicy.AllowView; 
            } 

            //Fire the events. 
            OnRMStatusChange(calcRMStatus);
            OnRMPolicyChange(calcRMPolicy);
        }
 
        /// 
        /// Sets the EncryptedPackageEnvelope on the provider to a new value 
        /// and invalidates the saved publish and use licenses if necessary. 
        /// The package passed can be null to indicate that the new package is
        /// not protected. 
        /// 
        /// The new encrypted package (possibly null)
        /// 
        ///  
        /// Critical
        ///  1) Calling SecurityCritical function SetEncryptedPackage on the 
        ///     provider with an external parameter. 
        /// 
        [SecurityCritical] 
        internal void SetEncryptedPackage(EncryptedPackageEnvelope newPackage)
        {
            bool publishLicenseChanged = true;
 
            try
            { 
                _rmProvider.SetEncryptedPackage( 
                    newPackage,
                    out publishLicenseChanged); 
            }
            catch (RightsManagementException exception)
            {
                RightsManagementErrorHandler.HandleOrRethrowException( 
                    RightsManagementOperation.Decrypt,
                    exception); 
 
                // On an exception here we can't continue; rethrow it in an
                // XPSViewer exception 
                throw new XpsViewerException(
                    SR.Get(SRID.XpsViewerRightsManagementException),
                    exception);
            } 

            if (_rmProvider.IsProtected) 
            { 
                // Get a use license for the new package
                RightsManagementLicense license = GetUseLicense(); 

                if (license == null ||
                    !license.HasPermission(RightsManagementPermissions.AllowView))
                { 
                    throw new XpsViewerException(
                        SR.Get(SRID.RMProviderExceptionNoRightsToDocument)); 
                } 
            }
 
            if (publishLicenseChanged)
            {
                // Fire the event to indicate a new publish license
                OnPublishLicenseChange(); 
            }
 
            // Evaluate the status of the new package (to fire events) 
            Evaluate();
        } 

        /// 
        /// Displays the Credential Management UI.
        ///  
        internal void ShowCredentialManagementUI()
        { 
            ShowCredentialManagementUI(false); 
        }
 
        /// 
        /// Displays the Credential Management UI.
        /// 
        /// Whether the dialog is being shown in the 
        /// process of decrypting the document for the first time
        /// The result of the credential management dialog 
        ///  
        /// Critical
        ///  1) Calls critical methods GetCredentialManagerResourceList and 
        ///     GetDefaultCredentialManagementResource to get the list of user
        ///     accounts to pass to the dialog.
        ///  2) Elevation to show a top level window.
        ///  3) Sets _credManagerDialog which is critical 
        /// TreatAsSafe
        ///  1) The lists are passed to the Credential Manager dialog, which is 
        ///     a WinForms dialog. The handle to the dialog is critical for 
        ///     get.
        ///  2) The window is the blessed internal Credential Manager dialog, 
        ///     which uses Windows Forms instead of Avalon. As above, the
        ///     handle is saved in a critical for get member variable.
        ///  3) _credManagerDialog is set to an actual CredentialManagerDialog.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal DialogResult ShowCredentialManagementUI(bool decrypting) 
        { 
            DialogResult result = DialogResult.Cancel;
 
            IList accountList = GetCredentialManagementResourceList();
            string userAccount = GetDefaultCredentialManagementResource();
            RightsManagementUser previousDefaultUser = _rmProvider.GetDefaultCredentials();
 
            _credManagerDialog = null;
 
            (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //BlessedAssert 
            try
            { 
                _credManagerDialog = new CredentialManagerDialog(accountList, userAccount, this);
                result = _credManagerDialog.ShowDialog();
            }
            finally 
            {
                UIPermission.RevertAssert(); 
 
                if (_credManagerDialog != null)
                { 
                    _credManagerDialog.Dispose();
                }
            }
 
            RightsManagementUser newDefaultUser = _rmProvider.GetDefaultCredentials();
 
            // When a new rm account is added a new SecureEnvironment is created in order 
            // to validate the new account.  If a document is currently protected this will
            // mean that the existing SecureEnvironment is destroyed, which puts the document 
            // in an unreliable state.  The only way to correct this is to reload the document.
            // Check if the document is done decrypting, is protected, and if the
            // SecureEnvironment is in an unreliable state or the default user has been
            // changed.  If so reload the document. 
            if (!decrypting && _rmProvider.IsProtected &&
                (!_isSecureEnvironmentReliable || !previousDefaultUser.Equals(newDefaultUser))) 
            { 
                DocumentManager.CreateDefault().Reload(null);
            } 
            // Check if the default user has changed, and setup an environment for this user.
            // This case will only be hit for unprotected, or undecrypted documents (by the
            // previous if statement) where it is reliable to create a new SecureEnvironment.
            else if (!previousDefaultUser.Equals(newDefaultUser)) 
            {
                try 
                { 
                    _rmProvider.InitializeEnvironment(newDefaultUser);
                } 
                catch (RightsManagementException exception)
                {
                    bool handled = RightsManagementErrorHandler.HandleOrRethrowException(
                        RightsManagementOperation.Other, 
                        exception);
                } 
            } 

 
            return result;
        }

 
        /// 
        /// ShowEnrollment:  Displays the RM enrollment. 
        ///  
        /// 
        ///     Critical - Elevation to show a top level window. 
        ///     TreatAsSafe - The window is a blessed internal window that uses purely Windows Forms rather than Avalon.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal void ShowEnrollment() 
        {
            DialogResult result = DialogResult.Cancel; 
            EnrollmentAccountType enrollmentAccountType = EnrollmentAccountType.None; 

            (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //Blessed 
            try
            {
                // skip first page if already enrolled
                if (_rmProvider.CurrentUser != null || _rmProvider.GetDefaultCredentials() != null) 
                {
                    result = DialogResult.OK; 
                } 
                else
                { 
                    //Show the First page
                    using (RMEnrollmentPage1 page1 = new RMEnrollmentPage1())
                    {
                        result = page1.ShowDialog(); 
                    }
                } 
 
                if (result == DialogResult.OK)
                { 
                    using (RMEnrollmentPage2 page2 = new RMEnrollmentPage2())
                    {
                        //Show the second page
                        result = page2.ShowDialog(); 
                        enrollmentAccountType = page2.AccountTypeSelected;
                    } 
                } 
            }
            finally 
            {
                UIPermission.RevertAssert();
            }
 
            if (result == System.Windows.Forms.DialogResult.OK)
            { 
                //It is now time to enroll. 
                Enroll(enrollmentAccountType);
            } 
        }

        /// 
        /// Enroll. 
        /// 
        /// The account type to enroll 
        /// Whether or not enrollment succeeded 
        /// 
        ///     Critical - Elevation to show a top level window. 
        /// 
        [SecurityCritical]
        internal bool Enroll(EnrollmentAccountType accountType)
        { 
            bool rtn = false;
            RMEnrollmentPage3 rmEnrollmentPage3 = null; 
 
            //User has selected to proceed.  Now we need to Enroll.  This will
            //Require two thing.  1) start the blocking enroll call 
            //(call QueueWorkItem) and 2) showing a status/progress Dialog while
            //we are enrolling.
            (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //BlessedAssert
            try 
            {
                rmEnrollmentPage3 = new RMEnrollmentPage3(); 
 
            }
            finally 
            {
                UIPermission.RevertAssert();
            }
 
            RightsManagementEnrollThreadInfo rmEnrollThreadInfo = new RightsManagementEnrollThreadInfo();
 
            //Setup Fields 
            rmEnrollThreadInfo.AccountType = accountType;
            rmEnrollThreadInfo.ProgressForm = rmEnrollmentPage3; 

            // Pass work off so UI doesn't block.
            // We use WaitCallback here because that is the delegate that is
            // supposed to be passed to QueueUserWorkItem 
            if (ThreadPool.QueueUserWorkItem(new WaitCallback(RMEnrollThreadProc), rmEnrollThreadInfo))
            { 
                (new UIPermission(UIPermissionWindow.AllWindows)).Assert(); //BlessedAssert 
                try
                { 
                    rmEnrollmentPage3.ShowDialog();
                }
                finally
                { 
                    UIPermission.RevertAssert();
                } 
 
                rtn = (_rmProvider.CurrentUser != null);
            } 

            // Since we've called the enrollment, the current SecureEnvironment is not reliable.
            _isSecureEnvironmentReliable = false;
 
            return rtn;
        } 
 
        /// 
        /// Launches the My Permissions UI. 
        /// 
        /// 
        /// Critical
        ///  1) Elevation to show a top level window. 
        ///  2) Calls _rmProvider.GetAllAccessRights.
        ///  3) Constructs an RMPermissions dialog using critical data. 
        /// TreatAsSafe 
        ///  1) The window is an internal window that uses purely Windows Forms
        ///     instead of Avalon.  The data shown in the window is also 
        ///     retrieved directly from the provider and protected.
        ///  2,3) The data returned from GetAllAccessRights is passed directly
        ///     to the UI (rmPermissionsPage).
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal void ShowPermissions() 
        { 
            RightsManagementLicense rmLicense = GetUseLicense();
 
            // A null license means the user has no rights to the document, and
            // this should never have been called.
            Invariant.Assert(
                rmLicense != null, 
                "Permissions dialog requested with no rights on the document.");
 
            // If this is the owner call ShowPublishing instead. 
            if (rmLicense.HasPermission(RightsManagementPermissions.AllowOwner))
            { 
                ShowPublishing();
            }
            else
            { 
                // User wants to view the My Permissions dialog.
                RMPermissionsDialog rmPermissionsPage = null; 
 
                new UIPermission(UIPermissionWindow.AllWindows).Assert(); //BlessedAssert
                try 
                {
                    rmPermissionsPage = new RMPermissionsDialog(rmLicense);
                    rmPermissionsPage.ShowDialog();
                } 
                finally
                { 
                    UIPermission.RevertAssert(); 

                    if (rmPermissionsPage != null) 
                    {
                        rmPermissionsPage.Dispose();
                    }
                } 
            }
        } 
 
        /// 
        /// Displays the publishing UI. 
        /// 
        /// 
        /// Critical
        ///  1) Elevation to show a top level window. 
        ///  2) Call to critical GetAllAccessRights function in the provider
        ///  3) Call to critical CurrentUser property of the provider 
        ///  4) Calls to critical SaveCurrentLicenses and RevertToSavedLicenses 
        ///     on the provider
        ///  5) Call to critical Licenses property of RMPublishingDialog 
        ///  6) Call to critical ProcessRMLicenses
        ///  7) Call to critical Template property of the RMPublishingDialog
        ///  8) Call to critical ProcessRMTemplate
        /// TreatAsSafe 
        ///  1) The window is an internal window that uses purely Windows
        ///     Forms instead of Avalon.  The data shown in the window is 
        ///     also retrieved directly from the provider and protected. 
        ///  2) The data from this call is not saved anywhere.  It is only
        ///     passed to the critical constructor of the RM publishing 
        ///     dialog.
        ///  3) The data is propagated only to the critical constructor of
        ///     an internal dialog.
        ///  4) These calls are used for their intended purpose -- reverting to 
        ///     the previous state after an error.
        ///  5) Licenses to grant are passed directly into the provider and 
        ///     not saved at this level or exposed. 
        ///  6) Data going into this call comes directly from the UI and
        ///     is then validated. 
        ///  7) Template uri is taken directly from the dialog, and not
        ///     stored or exposed.
        ///  8) The template filename acquired through critical means on the
        ///     RMPublishingDialog is used to open a text file and read in data. 
        ///     The data is validated by the RM API's.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void ShowPublishing()
        { 
            if (!ChooseCredentials(false))
            {
                // If there are no credentials, and we can't select any, we
                // should just bail out.  If there was an error somewhere 
                // during choosing credentials, an explanatory message box
                // should already have been shown. 
                return; 
            }
 
            if (_rmProvider.IsProtected)
            {
                RightsManagementLicense license = GetUseLicense();
                if (license == null || 
                    !(license.HasPermission(RightsManagementPermissions.AllowOwner)))
                { 
                    throw new InvalidOperationException( 
                        SR.Get(SRID.RMProviderExceptionNotOwnerOfDocument));
                } 
            }

            IDictionary allRights = null;
            if (_rmProvider.IsProtected) 
            {
                allRights = _rmProvider.GetAllAccessRights(); 
            } 

            // Create the publishing dialog outside of the while loop so that it is only 
            // constructed once, rather than on each loop.
            RMPublishingDialog rmPublish = null;
            bool statusChanged = false;
 
            try
            { 
                // Elevate to create the actual dialog. 
                new UIPermission(UIPermissionWindow.AllWindows).Assert(); //BlessedAssert
                try 
                {
                    rmPublish =
                        new RMPublishingDialog(_rmProvider.CurrentUser, allRights);
                } 
                finally
                { 
                    UIPermission.RevertAssert(); 
                }
 
                // Keep showing the dialog until it succeeds or the user cancels
                while (true)
                {
                    DialogResult result = DialogResult.Cancel; 

                    // Display the dialog to the user. 
                    result = rmPublish.ShowDialog(); 

                    // If the user canceled out of the dialog, break out of the loop and 
                    // do not apply changes.
                    if (result != DialogResult.OK)
                    {
                        break; 
                    }
 
                    bool publishingSuccess = false; 
                    bool publishLicenseChanged = false;
                    bool exitDialog = false; 

                    // Save the current set of licenses for rollback
                    _rmProvider.SaveCurrentLicenses();
 
                    // If a template exists on the publishing dialog then user has selected
                    // a template rather than individual settings. 
                    if (rmPublish.Template != null) 
                    {
                        publishingSuccess = ProcessRMTemplate(rmPublish.Template, out exitDialog); 
                        publishLicenseChanged = true;
                    }
                    // Template was not selected, so carry on with individual permissions.
                    else 
                    {
                        publishingSuccess = ProcessRMLicenses( 
                            rmPublish.Licenses, 
                            out exitDialog,
                            out publishLicenseChanged); 
                    }

                    // Check if a signed publish license was successfully created.
                    // If not take the appropriate action. 
                    if (!publishingSuccess)
                    { 
                        // If exitDialog is true, then an error has happened that is severe 
                        // enough to stop running the Publish dialog.
                        if (exitDialog) 
                        {
                            return;
                        }
                        // Otherwise continue with running the dialog for another attempt 
                        // to get the settings correct.
                        else 
                        { 
                            continue;
                        } 
                    }

                    // If the publish license actually changed during the
                    // publishing operation, fire the event to indicate this 
                    if (publishLicenseChanged)
                    { 
                        OnPublishLicenseChange(); 
                    }
 
                    // Save the protected document.
                    DocumentManager docManager = DocumentManager.CreateDefault();
                    bool saveSuccess = false;
 
                    if (docManager != null)
                    { 
                        if (rmPublish.IsSaveAs) 
                        {
                            saveSuccess = docManager.SaveAs(null); 
                        }
                        else
                        {
                            saveSuccess = docManager.Save(null); 
                        }
                    } 
 
                    if (publishingSuccess && !saveSuccess)
                    { 
                        _rmProvider.RevertToSavedLicenses();
                        continue;
                    }
 
                    statusChanged =
                        publishingSuccess && saveSuccess && publishLicenseChanged; 
 
                    break;
                } // end while(true) 
            }
            finally
            {
                if (rmPublish != null) 
                {
                    rmPublish.Dispose(); 
                } 
            }
 
            // If the status changed, call Evaluate to re-evaluate the RM
            // status of the document and fire the appropriate events
            if (statusChanged)
            { 
                Evaluate();
            } 
        } 

        ///  
        /// Get User account from credentialManagementResources and sets as default.
        /// 
        /// 
        /// Critical 
        ///  1) Method uses critical data stored in _userMap.
        ///  2) Calls critical function SetDefaultCredentials with the user 
        ///     object corresponding to a string passed in as an argument. 
        /// 
        [SecurityCritical] 
        internal void OnCredentialManagementSetDefault(string defaultAccount)
        {
            //Get user from user name
            RightsManagementUser user = _userMap[defaultAccount]; 

            //if found set default 
            if (user != null) 
            {
                _rmProvider.SetDefaultCredentials(user); 
            }
        }

        ///  
        /// Removes user from available user list.
        ///  
        ///  
        /// Critical
        ///  1) Uses critical data stored in _userMap. 
        ///  2) Calls critical function RemoveCredentials with a user object
        ///     created from a string passed in as an argument.
        ///  3) Calls critical methods GetCredentialManagementResourceList and
        ///     GetDefaultCredentialManagementResource. 
        ///  4) Calls a method on critical _credManagerDialog, but does not
        ///     read or save any critical user information from it. 
        ///  
        [SecurityCritical]
        internal void OnCredentialManagementRemove(string accountName) 
        {
            //Get user from hash
            RightsManagementUser user = _userMap[accountName];
 
            //if found remove (if this user isn't in use, if it is in use warn user)
            if (user != null && !user.Equals(_rmProvider.CurrentUser)) 
            { 
                try
                { 
                    _rmProvider.RemoveCredentials(user);

                    if (_credManagerDialog != null)
                    { 
                        //Set the data source for the listbox
                        _credManagerDialog.SetCredentialManagementList( 
                            GetCredentialManagementResourceList(), 
                            GetDefaultCredentialManagementResource());
                    } 
                }
                catch (RightsManagementException exception)
                {
                    RightsManagementErrorHandler.HandleOrRethrowException( 
                        RightsManagementOperation.Other,
                        exception); 
 
                    // If the remove failed just bail out
                    return; 
                }
            }
            else
            { 
                System.Windows.MessageBox.Show(
                    SR.Get(SRID.RightsManagementWarnErrorFailedToRemoveUser), 
                    SR.Get(SRID.RightsManagementWarnErrorTitle), 
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Exclamation 
                    );
            }
        }
 
        /// 
        /// Calls the Enrollment and refreshes the listbox. 
        ///  
        /// 
        /// Critical 
        ///  1) Calls critical methods GetCredentialManagementResourceList and
        ///     GetDefaultCredentialManagementResource.
        ///  4) Calls a method on critical _credManagerDialog, but does not
        ///     read or save any critical user information from it. 
        /// 
        [SecurityCritical] 
        internal void OnCredentialManagementShowEnrollment() 
        {
            ShowEnrollment(); 

            if (_credManagerDialog != null)
            {
                //Set the data source for the listbox 
                _credManagerDialog.SetCredentialManagementList(
                    GetCredentialManagementResourceList(), 
                    GetDefaultCredentialManagementResource()); 
            }
        } 

        /// 
        /// Prompts the user to see if he or she would like to install the RM Client.
        /// If the user so chooses, we will then start a top-level navigation to 
        /// the external install location for the RM Client.
        ///  
        /// 
        ///    Critical
        ///       1) Makes the determination if we should navigate to an external Uri. 
        ///       2) Kicks off a top-level navigation to a known external Uri.
        ///    TreatAsSafe
        ///       1) The top level navigation is user initiated
        ///       2) The navigation is to a predefined, hardcoded Uri. 
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        internal void PromptToInstallRM() 
        {
            // Notify the user that RM is not installed, and ask 
            // if they would like to install it now.
            System.Windows.MessageBoxResult dialogResult = System.Windows.MessageBox.Show(
                                SR.Get(SRID.RightsManagementWarnErrorRMNotInstalled),
                                SR.Get(SRID.RightsManagementWarnErrorTitle), 
                                System.Windows.MessageBoxButton.YesNo,
                                System.Windows.MessageBoxImage.Warning); 
 
            if (dialogResult == System.Windows.MessageBoxResult.Yes)
            { 
                // Navigate to the install location
                const string rmClientInstallLocation = "http://go.microsoft.com/fwlink/?LinkID=18134";
                NavigationHelper.NavigateToExternalUri(new Uri(rmClientInstallLocation));
            } 
        }
 
        ///  
        /// Gets a List of CredentialManagmentResources.
        ///  
        /// 
        /// Critical
        ///  1) Calling critical code RMProvider::GetAvailableCredentials.
        ///  2) Calling critical code GetCredentialManagementResources 
        ///  3) Setting critical data _userMap from the list of users returned
        ///     by GetAvailableCredentials 
        ///  4) Returns a list of user names 
        /// 
        [SecurityCritical] 
        internal IList GetCredentialManagementResourceList()
        {
            _userMap.Clear();
 
            //create list for CredentialManagementResources
            IList accountList = new List(); 
 
            //Loop through each user and create listbox string and add to return list
            foreach (RightsManagementUser user in _rmProvider.GetAvailableCredentials()) 
            {
                string accountName =
                    RightsManagementResourceHelper.GetCredentialManagementResources(user);
 
                if (!accountList.Contains(accountName))
                { 
                    //Add to map and to list. 
                    _userMap.Add(accountName, user);
                    accountList.Add(accountName); 
                }
            }

            return accountList; 
        }
 
        ///  
        /// Gets default CredentialManagmentResources.
        ///  
        /// 
        /// Critical
        ///  1) Calling critical code RMProvider::GetDefaultCredentials.
        ///  2) Calling critical code GetCredentialManagementResources 
        /// 
        [SecurityCritical] 
        internal string GetDefaultCredentialManagementResource() 
        {
            string userAccount = null; 

            RightsManagementUser user = _rmProvider.GetDefaultCredentials();

            if (user != null) 
            {
                userAccount = RightsManagementResourceHelper.GetCredentialManagementResources(user); 
            } 

            return userAccount; 
        }

        #endregion Internal Methods
 
        #region Internal Properties
        //------------------------------------------------------ 
        // Internal Properties 
        //------------------------------------------------------
 
        /// 
        /// Gets the current singleton instance of the DocumentRightsManagementManager
        /// 
        internal static DocumentRightsManagementManager Current 
        {
            get 
            { 
                return _currentManager.Value;
            } 
        }

        /// 
        /// Gets the current publish license associated with the document. 
        /// 
        internal PublishLicense PublishLicense 
        { 
            // Commented out since not used, but left to show that a set only property
            // was implemented by design. 
            // get { return _rmProvider.CurrentPublishLicense; }
            set
            {
                if (_rmProvider.CurrentPublishLicense != value) 
                {
                    _rmProvider.CurrentPublishLicense = value; 
                    OnPublishLicenseChange(); 
                }
            } 
        }

        /// 
        /// Gets whether or not the user has permission to save the document. 
        /// 
        ///  
        /// Critical 
        ///  1) Makes a policy enforcement decision
        /// TreatAsSafe 
        ///  1) The data used for the decision comes from the critical for set
        ///     provider.
        /// 
        internal bool HasPermissionToSave 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get 
            {
                return 
                    !_rmProvider.IsProtected ||
                    GetUseLicense().HasPermission(RightsManagementPermissions.AllowCopy);
            }
        } 

        ///  
        /// Gets whether or not the user has permission to edit the document. 
        /// 
        ///  
        /// Critical
        ///  1) Makes a policy enforcement decision
        /// TreatAsSafe
        ///  1) The data used for the decision comes from the critical for set 
        ///     provider.
        ///  
        internal bool HasPermissionToEdit 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            {
                return
                    !_rmProvider.IsProtected || 
                    GetUseLicense().HasPermission(RightsManagementPermissions.AllowEdit);
            } 
        } 

        ///  
        /// Returns true if we find the RM Client is installed on the machine.
        /// 
        /// 
        /// We only make the actual check if RM is installed 
        /// once per application instance. Is this okay? Or should we keep
        /// checking to see if this gets installed over the course of the 
        /// application? 
        /// 
        internal bool IsRMInstalled 
        {
            get
            {
                if (! _determinedRMInstallState) 
                {
                    // Find out if the RM Client is installed. 
                    _isRMInstalled = IsRMClientInstalled(); 
                    _determinedRMInstallState = true;
                } 

                return _isRMInstalled;
            }
        } 

        #endregion Internal Properties 
 
        #region Internal Event
        //----------------------------------------------------- 
        // Internal Event
        //------------------------------------------------------

        internal event RMStatusChangeHandler RMStatusChange; 

        internal event EventHandler PublishLicenseChange; 
 
        internal event RMPolicyChangeHandler RMPolicyChange;
 
        #endregion Internal Event

        #region Internal Delegate
        //----------------------------------------------------- 
        // Internal Delegate
        //----------------------------------------------------- 
 
        internal delegate void RMStatusChangeHandler(object sender,
                                                     RightsManagementStatusEventArgs args 
                                                     );

        internal delegate void RMPolicyChangeHandler(object sender,
                                                     RightsManagementPolicyEventArgs args 
                                                     );
 
        #endregion Internal Delegate 

        #region Private Methods 
        //-----------------------------------------------------
        // Private Methods
        //------------------------------------------------------
 
        /// 
        /// Saves the use license back into the package. 
        ///  
        private void SaveUseLicense()
        { 
            //This action should occur after other work has been completed.
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                (DispatcherOperationCallback)delegate(object arg)
                { 
                    DocumentManager docManager = DocumentManager.CreateDefault();
                    if (docManager.CanSave) 
                    { 
                        Trace.SafeWrite(
                            Trace.Rights, 
                            "Re-opening document for edit before saving Use License");
                        docManager.EnableEdit(null);
                    }
 
                    // Check if saving is still possible (i.e. the file could
                    // be reopened for edit). 
                    // 
                    // This breaks encapsulation -- we happen to know that
                    // docManager.CanSave indicates only that the file could 
                    // be opened writeable. We also know that saving an RM
                    // protected document will save the use license back to
                    // the file.
                    if (docManager.CanSave) 
                    {
                        Trace.SafeWrite( 
                            Trace.Rights, 
                            "Opened original file writeable; saving Use License");
                        docManager.Save(null); 
                    }

                    return null;
                }, null /* DispatcherOperation argument, none specified */); 
        }
 
        ///  
        /// Determines if the RM client is installed by looking for
        /// MSDRM.DLL in the user's system folder. 
        /// 
        /// Whether RM Client DLL, msdrm.dll, was found
        /// 
        /// Critical 
        ///  1) Asserts for FileIOPermission to get the system path.
        ///  2) Asserts for FileIOPermission to check if the file, MSDRM.DLL exists. 
        /// 
        /// TreatAsSafe
        ///  1) The system path value does not leave this method. 
        ///  2) This path information used to determine if the file exists
        ///         never leaves this method.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private bool IsRMClientInstalled()
        { 
            bool foundRMClient = false; 
            string systemPath = string.Empty;
 
            // Build the path for the MSDRM.DLL

            // Environment.GetFolderPath() requires FileIOPermission - PathDiscovery
            FileIOPermission getSystemPath = new FileIOPermission(PermissionState.None); 
            getSystemPath.AllLocalFiles = FileIOPermissionAccess.PathDiscovery;
            getSystemPath.Assert(); //BlessedAssert 
            try 
            {
                systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System); 
            }
            finally
            {
                FileIOPermission.RevertAssert(); 
            }
 
            // Append the DLL filename. 
            const string msdrmDLLName = "MSDRM.DLL";
            string msdrmdllPath = Path.Combine(systemPath, msdrmDLLName); 

            // Check if the DLL exists.
            new FileIOPermission(FileIOPermissionAccess.Read,
                msdrmdllPath).Assert(); // BlessedAssert 
            try
            { 
                foundRMClient = File.Exists(msdrmdllPath); 
            }
            finally 
            {
                FileIOPermission.RevertAssert();
            }
 
            return foundRMClient;
        } 
 
        /// 
        /// Attempts to automatically choose the credentials to use to access 
        /// the RM-protected document or add RM protection to an existing
        /// document.
        /// 
        /// Whether or not we are choosing credentials 
        /// to decrypt or encrypt a document
        /// Whether or not credentials were successfully chosen 
        ///  
        /// Critical
        ///  1) accesses Critical property CurrentUser 
        ///  2) accesses Critical function GetDefaultCredentials
        ///  3) calls SecurityCritical function InitializeEnvironment(User)
        /// TreatAsSafe
        ///  1) The value returned from CurrentUser is not saved or propagated; 
        ///     it is only checked for null.
        ///  2) The returned values from GetDefaultCredentials are not saved. 
        ///     They are only passed to the critical function 
        ///     InitializeEnvironment.
        ///  3) Parameter comes directly from the list of credentials available 
        ///     to the user returned from critical call GetDefaultCredentials
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private bool ChooseCredentials(bool decrypting) 
        {
            bool foundCredentials = false; 
 
            // If there already is a user selected there is no need to select
            // credentials again 
            if (_rmProvider.CurrentUser != null)
            {
                return true;
            } 

            //Get default user 
            RightsManagementUser user = _rmProvider.GetDefaultCredentials(); 

            // Save whether or not RM has been initialized so that we don't do 
            // it twice
            bool initialized = false;

            //Check to see if we have a user.  If we don't we need to enroll. 
            if (user == null)
            { 
                //Show enrollment UI 
                ShowEnrollment();
 
                // Get the current user.  If we don't have one after enrollment
                // that means the user cancelled enrollment or something else
                // went wrong.
                user = _rmProvider.CurrentUser; 

                // If the enrollment was successful 
                if (user != null) 
                {
                    // Set the enrolled user as the default user in the registry 
                    _rmProvider.SetDefaultCredentials(user);
                    initialized = true;
                }
            } 

            // Now we will see if this user account has rights for the document 
            while (user != null) 
            {
                if (!initialized) 
                {
                    try
                    {
                        // Attempt to initialize the environment 
                        _rmProvider.InitializeEnvironment(user);
 
                        initialized = true; 
                    }
                    catch (RightsManagementException exception) 
                    {
                        bool handled =
                            RightsManagementErrorHandler.HandleOrRethrowException(
                                decrypting ? 
                                    RightsManagementOperation.Initialize :
                                    RightsManagementOperation.Other, 
                                exception); 

                        // If the error couldn't be handled cleanly, give up 
                        if (!handled)
                        {
                            break;
                        } 
                    }
                } 
 
                // If the initialization succeeded and the document is
                // protected by RM, check if the current user can view the 
                // document
                if (initialized && _rmProvider.IsProtected)
                {
                    RightsManagementLicense license = GetUseLicense(); 

                    // Check if the user has permissions to view the document 
                    if (license != null && 
                        license.HasPermission(RightsManagementPermissions.AllowView))
                    { 
                        foundCredentials = true;
                        break;
                    }
 
                    // The current user doesn't have permissions
                    else 
                    { 
                        // Ask the user whether we should try a different set of
                        // credentials or just give up. 

                        System.Windows.MessageBoxResult result =
                            System.Windows.MessageBox.Show(
                                SR.Get(SRID.RightsManagementWarnErrorNoPermission), 
                                SR.Get(SRID.RightsManagementWarnErrorTitle),
                                System.Windows.MessageBoxButton.YesNo, 
                                System.Windows.MessageBoxImage.Exclamation 
                                );
 
                        // If the user didn't want to continue, bail out
                        if (result != System.Windows.MessageBoxResult.Yes)
                        {
                            break; 
                        }
                    } 
                } 
                // If the document is not protected, there is no need to check
                // whether the user can view the document as long as the 
                // environment was properly initialized
                else if (initialized)
                {
                    foundCredentials = true; 
                    break;
                } 
 
                // The current default user doesn't have permission to view
                // this container, or there was an error when attempting to 
                // initialize the environment with the current default user.
                //
                // Show the CredMan to allow user to change default account
                if(ShowCredentialManagementUI(decrypting) != DialogResult.OK) 
                {
                    break; 
                } 

                //Get new default user. 
                user = _rmProvider.GetDefaultCredentials();

                // The provider's CurrentUser property is set only when an
                // environment has been initialized. As a result comparing the 
                // credentials we will use to the provider's CurrentUser can
                // tell us whether or not the provider has been initialized for 
                // that user. 
                initialized = (user.Equals(_rmProvider.CurrentUser));
            } 

            return foundCredentials;
        }
 
        /// 
        /// Retrieves the use license for the document and returns the rights granted to 
        /// the current user.  Returns null if the user does not have rights to the 
        /// document.
        ///  
        /// The rights granted to the user.
        /// 
        /// Critical - 1) accesses Critical property CurrentUser
        /// TreatAsSafe - 1) The value returned from CurrentUser is not saved or 
        ///                  propagated; it is only checked for null.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private RightsManagementLicense GetUseLicense()
        { 
            if (_rmProvider.IsProtected &&
                _rmProvider.CurrentUseLicense == null)
            {
                Invariant.Assert( 
                    _rmProvider.CurrentUser != null,
                    "No user for whom to get a license."); 
 
                try
                { 
                    if (_rmProvider.LoadUseLicense())
                    {
                        _rmProvider.BindUseLicense();
                    } 
                    else if (_rmProvider.AcquireUseLicense())
                    { 
                        // We have just acquired a new use license; this needs to be stored back 
                        // into the package.
                        _rmProvider.BindUseLicense(); 
                        SaveUseLicense();
                    }
                    else
                    { 
                        // No use license was found, which means that the
                        // current user has no rights to the document. We 
                        // return null and let the caller decide what to do. 
                    }
                } 
                catch (RightsManagementException exception)
                {
                    // Whether or not the exception was handled is irrelevant,
                    // since if the use license wasn't bound, the function will 
                    // return null
                    RightsManagementErrorHandler.HandleOrRethrowException( 
                        RightsManagementOperation.Decrypt, 
                        exception);
                } 
            }

            return _rmProvider.CurrentUseLicense;
        } 

        ///  
        /// Checks if the grants listed in the licenses passed in as an argument are 
        /// different from the ones already granted on the document.
        ///  
        /// A list of new grants to compare with the existing
        /// set
        /// 
        /// Can be thrown by the RM APIs when there is an error when getting 
        /// all existing access rights on the document
        /// Whether or not the new grants are different 
        ///  
        /// Critical - 1) Calls Critical function GetAllAccessRights to compare rights
        ///               passed in as an argument to existing rights. 
        /// TreatAsSafe - 1) The list of existing grants is not saved or exposed.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private bool HasPublishLicenseChanged(IList newGrants) 
        {
            // If the desired state is that the document will not be protected (i.e. no 
            // licenses are specified), we check if the document was already not 
            // protected.
            if (newGrants == null || newGrants.Count == 0) 
            {
                return _rmProvider.IsProtected;
            }
 
            // Check if we are adding protection to an unprotected document
            if (!_rmProvider.IsProtected) 
            { 
                return true;
            } 

            // This might throw, but it will be caught in the caller
            IDictionary allRights =
                _rmProvider.GetAllAccessRights(); 

            // Check if the number of licenses is different 
            if (newGrants.Count != allRights.Count) 
            {
                return true; 
            }

            // Look through each license to see if it is different from the old ones.
            // We already know that the number of licenses is the same in both lists of 
            // licenses, so any other differences will be detected here.
            foreach (RightsManagementLicense newLicense in newGrants) 
            { 
                if (!allRights.ContainsKey(newLicense.LicensedUser))
                { 
                    return true;
                }

                RightsManagementLicense existingLicense = allRights[newLicense.LicensedUser]; 

                // Check if both licenses grant the same permissions 
                if (newLicense.LicensePermissions != 
                    existingLicense.LicensePermissions)
                { 
                    return true;
                }

                if (DateTime.Compare( 
                    newLicense.ValidUntil,
                    existingLicense.ValidUntil) != 0) 
                { 
                    return true;
                } 

                if (!Uri.Equals(
                    newLicense.ReferralInfoUri,
                    existingLicense.ReferralInfoUri)) 
                {
                    return true; 
                } 

            } 

            return false;
        }
 
        /// 
        /// The thread operation that enrolls a new Rights Management user. 
        ///  
        private void RMEnrollThreadProc(Object stateInfo)
        { 
            Trace.SafeWrite(Trace.Rights, "Enrollment thread started.");

            //Get Thread Info
            RightsManagementEnrollThreadInfo rmEnrollThreadInfo = (RightsManagementEnrollThreadInfo)stateInfo; 

            //Enroll 
            try 
            {
                _rmProvider.InitializeEnvironment(rmEnrollThreadInfo.AccountType); 
                //Enrollment is done.  Let's close the Progress dialog.
                rmEnrollThreadInfo.ProgressForm.Invoke(new MethodInvoker(rmEnrollThreadInfo.ProgressForm.Close));
            }
            catch (RightsManagementException exception) 
            {
                rmEnrollThreadInfo.ProgressForm.Invoke(new MethodInvoker(rmEnrollThreadInfo.ProgressForm.Close)); 
                RightsManagementOperation operation = 
                    RightsManagementOperation.Other;
 
                if (rmEnrollThreadInfo.AccountType == EnrollmentAccountType.NET)
                {
                    operation = RightsManagementOperation.PassportActivation;
                } 

                RightsManagementErrorHandler.HandleOrRethrowException( 
                    operation, 
                    exception);
            } 
            // Close the progress dialog in the event of any exception.  This prevents the
            // dialog from remaining open when the error page appears.  We cannot use a finally
            // block here because in the case of an uncaught exception the unhandled exception
            // handler will get the exception (and show the error page) before the block runs. 
            catch
            { 
                rmEnrollThreadInfo.ProgressForm.Invoke(new MethodInvoker(rmEnrollThreadInfo.ProgressForm.Close)); 
                throw;
            } 

            Trace.SafeWrite(Trace.Rights, "Enrollment thread ended.");
        }
 
        /// 
        /// Creates an appropriate EventArgs and sends the RMStatusChange event. 
        ///  
        /// The RM status to put in the EventArgs
        ///  
        /// 
        /// This sends an event to update the UI which displays whether or not
        /// a document is signed, which may be used for a trust decision by the
        /// user. However, since the UI is currently displayed in an Avalon 
        /// control, making the events themselves critical does not add any
        /// protection. 
        ///  
        private void OnRMStatusChange(RightsManagementStatus newStatus)
        { 
            Trace.SafeWrite(Trace.Rights, "RightsManagementStatus changed.");

            RightsManagementStatusEventArgs args = new RightsManagementStatusEventArgs(
                newStatus); 

            RaiseRMStatusChange(args); 
        } 

        ///  
        /// Raises an RMStatusChange event with the given arguments.
        /// 
        /// The event arguments
        private void RaiseRMStatusChange(RightsManagementStatusEventArgs args) 
        {
            if (RMStatusChange != null) 
            { 
                RMStatusChange(this, args);
            } 
        }

        /// 
        /// Creates an appropriate EventArgs and sends the RMPolicyChange event. 
        /// 
        /// The RM policy to put in the EventArgs 
        ///  
        /// 
        /// Critical 
        ///  1) The RaiseRMPolicyChange event is fired, and the parameter
        ///     newPolicy is used within the EventArgs.
        /// 
        [SecurityCritical] 
        private void OnRMPolicyChange(RightsManagementPolicy newPolicy)
        { 
            Trace.SafeWrite(Trace.Rights, "RightsManagementPolicy changed."); 
            RightsManagementPolicyEventArgs args = new RightsManagementPolicyEventArgs(newPolicy);
 
            RaiseRMPolicyChange(args);
        }

        ///  
        /// Raises an RMPolicyChange event with the given arguments.
        ///  
        /// The event arguments 
        private void RaiseRMPolicyChange(RightsManagementPolicyEventArgs args)
        { 
            if (RMPolicyChange != null)
            {
                RMPolicyChange(this, args);
            } 
        }
 
        ///  
        /// Fires the event that indicates that the publish license has changed.
        ///  
        private void OnPublishLicenseChange()
        {
            Trace.SafeWrite(Trace.Rights, "Publish License changed.");
 
            RaisePublishLicenseChange(null);
        } 
 
        /// 
        /// Raises the PublishLicenseChange with the given arguments. 
        /// 
        /// The event arguments
        private void RaisePublishLicenseChange(EventArgs args)
        { 
            if (PublishLicenseChange != null)
            { 
                PublishLicenseChange(this, args); 
            }
        } 

        /// 
        /// Using the provided list of licenses, attempt to setup a signed
        /// publish license for the document. 
        /// 
        /// The licenses to process. 
        /// True if an error has occurred that should 
        /// exit the RMPublishing dialog
        /// True if the grants passed in 
        /// are different from the ones in the document
        /// True on success, false on failure.
        /// 
        /// Critical 
        ///  1) Call to critical GenerateUnsignedPublishLicense function in the
        ///     provider 
        ///  2) Calls IRightsManagementProvider.GenerateUnsignedPublishLicense 
        ///  3) Calls IRightsManagementProvider.SignPublishLicense
        ///  
        [SecurityCritical]
        private bool ProcessRMLicenses(
            IList licenses,
            out bool exitDialog, 
            out bool publishLicenseChanged)
        { 
            // By default exitDialog is true so that on unhandled errors the publish 
            // dialog will not reload.
            exitDialog = true; 

            publishLicenseChanged = true;

            try 
            {
                publishLicenseChanged = HasPublishLicenseChanged(licenses); 
            } 
            catch (RightsManagementException exception)
            { 
                bool handled =
                    RightsManagementErrorHandler.HandleOrRethrowException(
                        RightsManagementOperation.Other,
                        exception); 

                // If there was an exception (that could not be 
                // handled) that occurred in detecting whether the 
                // publish license changed, bail out
                if (!handled) 
                {
                    return false;
                }
            } 

            // If the new publish license is unchanged don't bother 
            // doing anything else 
            if (publishLicenseChanged)
            { 
                if (licenses != null && licenses.Count > 0)
                {
                    try
                    { 
                        _rmProvider.GenerateUnsignedPublishLicense(licenses);
                        _rmProvider.SignPublishLicense(); 
                    } 
                    catch (RightsManagementException exception)
                    { 
                        bool handled =
                            RightsManagementErrorHandler.HandleOrRethrowException(
                                RightsManagementOperation.Other,
                                exception); 

                        // If the exception was handled, don't exit the dialog 
                        if (handled) 
                        {
                            exitDialog = false; 
                        }
                        // Stop processing and post dialog.
                        return false;
                    } 
                }
                else 
                { 
                    this.PublishLicense = null;
                } 
            }

            // If we made it this far then it is considered success
            exitDialog = false; 
            return true;
        } 
 
        /// 
        /// Using the provided template filename, attempt to load the template from 
        /// disk and setup a signed publish license from it.
        /// 
        /// The template file to load.
        /// Used to determine if the RMPublishing 
        /// dialog should exit.
        /// True on success, false on failure. 
        ///  
        /// Critical
        ///  1) Calls GetTemplateFromFile. 
        ///  2) Calls IRightsManagementProvider.GenerateUnsignedPublishLicense
        ///  3) Calls IRightsManagementProvider.SignPublishLicense
        /// 
        [SecurityCritical] 
        private bool ProcessRMTemplate(Uri templateFilename, out bool exitDialog)
        { 
            string template = string.Empty; 

            // With the current template system we should never bail on the dialog 
            // as we will inform the user and allow them to select again.
            exitDialog = false;

            try 
            {
                // Load the template from file. 
                template = GetTemplateFromFile(templateFilename); 
            }
            // This generic catch allows all failures of loading the file to be 
            // directed to our central error handler which will show the
            // appropriate error message to the user.  Since this operation is
            // classified as a critical operation, the error handler will re-throw
            // the exception to allow it to be handled higher on the stack if it 
            // is fatal (which includes all exceptions not specifically handled
            // by the error handler). 
#pragma warning suppress 56500 // suppress PreSharp Warning 56500: Avoid `swallowing errors by catching non-specific exceptions.. 
            catch (Exception exception)
            { 
                // This exception will be thrown if there is a problem
                // reading the template from the file.
                // We need to handle the method and determine the
                // appropriate action. 
                RightsManagementErrorHandler.HandleOrRethrowException(
                    RightsManagementOperation.TemplateAccess, 
                    exception); 

                // Since any exception means the file was not loaded, bail out. 
                return false;
            }
            // Ensure that template was actually loaded.
            if (!string.IsNullOrEmpty(template)) 
            {
                try 
                { 
                    // Generate the license from the template.
                    _rmProvider.GenerateUnsignedPublishLicense(template); 
                    _rmProvider.SignPublishLicense();
                }
                catch (RightsManagementException exception)
                { 
                    // This exception will be thrown if there is a problem
                    // either parsing/loading the template, or signing it. 
                    // In either case a message should be displayed informing 
                    // the user about the invalid template.
                    RightsManagementErrorHandler.HandleOrRethrowException( 
                        RightsManagementOperation.TemplateAccess,
                        exception);

                    // Since any exception means the file was not loaded, bail out. 
                    return false;
                } 
            } 
            else
            { 
                // The template could not be loaded correctly from disk
                // (could be that it was removed, permissions are incorrect,
                // network down, etc), so display an error message.
                RightsManagementErrorHandler.HandleOrRethrowException( 
                    RightsManagementOperation.TemplateAccess,
                    new FileFormatException()); 
 
                // Since any exception means the file was not loaded, bail out.
                return false; 
            }

            // Set exitDialog to false to continue with the signing process.
            exitDialog = false; 
            return true;
        } 
 
        /// 
        /// Open a template file and attempt to load it into _template. 
        /// 
        /// The filename (with path) to load.
        /// The text string read from the file if successful, otherwise
        /// string.Empty 
        /// 
        /// Critical 
        ///  1) Asserts for FileIOPermission. 
        /// 
        [SecurityCritical] 
        private string GetTemplateFromFile(Uri templateFilename)
        {
            // Set the default value, this value will remain if any of the file
            // loading fails. 
            string template = string.Empty;
 
            // If a template exists on the publishing dialog then user has selected 
            // a template rather than individual settings.
            if (templateFilename != null) 
            {
                // Save the path local to this method to guarantee it does not
                // change between the assert and the file access
                string templateLocalPath = templateFilename.LocalPath; 

                // Assert permission and read in template. 
                (new FileIOPermission( 
                    FileIOPermissionAccess.Read, templateLocalPath))
                    .Assert(); //BlessedAssert 
                try
                {
                    // The RM client requires that templates are in UTF16
                    // (Encoding.Unicode) format. 
                    template = File.ReadAllText(templateLocalPath, Encoding.Unicode);
                } 
                finally 
                {
                    FileIOPermission.RevertAssert(); 
                }
            }
            return template;
        } 

        #endregion Private Methods 
 
        #region Private Properties
        //----------------------------------------------------- 
        // Private Properties
        //------------------------------------------------------

        ///  
        /// Setup as a clr property to transparently use CriticalDataForSet.
        ///  
        private IRightsManagementProvider _rmProvider 
        {
            get 
            {
                return _rmProviderCache.Value;
            }
        } 

        #endregion Private Properties 
 
        #region Private Fields
        //------------------------------------------------------ 
        // Private Fields
        //-----------------------------------------------------

        private static SecurityCriticalDataForSet _currentManager; 
        private SecurityCriticalDataForSet _rmProviderCache;
 
        ///  
        /// A handle to a currently open instance of the credential manager dialog
        ///  
        /// 
        /// Critical
        ///  1) This is a pointer to a WinForms dialog which could contain PII.
        ///  
        [SecurityCritical]
        private CredentialManagerDialog _credManagerDialog; 
 
        /// 
        /// True if we have yet determined whether the RM client is installed. 
        /// We cache this to keep us from checking if the RM Client is installed
        /// over and over.
        /// 
        private bool _determinedRMInstallState = false; 

        ///  
        /// True if the RM client is installed. 
        /// 
        private bool _isRMInstalled = false; 

        /// 
        /// False if the SecureEnvironment is not in a reliable state (ie need to reload).
        ///  
        private bool _isSecureEnvironmentReliable = true;
 
        ///  
        /// A dictionary mapping user names to RightsManagementUser objects.
        ///  
        /// 
        /// Critical
        ///  1) hash table holds critical data.
        ///  
        [SecurityCritical]
        private IDictionary _userMap; 
 
        #endregion Private Fields
 
        #region Nested Class
        //------------------------------------------------------
        // Nested Class
        //----------------------------------------------------- 

        ///  
        /// RMStatusEventArgs, object used when firing RMStatus change. 
        /// 
        ///  
        /// This is used to determine what the UI shows and may be the basis for
        /// a trust decision by the user. However, it is not useful to make
        /// this class critical because the actual UI controls are in Avalon and
        /// can be modified directly. 
        /// 
        public class RightsManagementStatusEventArgs : EventArgs 
        { 
            #region Constructors
            //----------------------------------------------------- 
            // Constructors
            //-----------------------------------------------------

            ///  
            /// The constructor
            ///  
            /// Rights Management status 
            /// Resources containing other information
            /// relevant to the document RM status 
            public RightsManagementStatusEventArgs(
                RightsManagementStatus rmStatus)
            {
                _rmStatus = rmStatus; 
                _statusResourcesLoaded = false;
            } 
 
            #endregion Constructors
 
            #region Public Properties
            //------------------------------------------------------
            // Public Properties
            //----------------------------------------------------- 

            ///  
            /// The Rights Management status 
            /// 
            public RightsManagementStatus RMStatus 
            {
                get { return _rmStatus; }
            }
 
            /// 
            /// Property to get the StatusResources.  To improve performance the resources are not loaded 
            /// until the first time they are accessed. 
            /// 
            public DocumentStatusResources StatusResources 
            {
                get
                {
                    if (!_statusResourcesLoaded) 
                    {
                        _statusResources = RightsManagementResourceHelper.GetDocumentLevelResources(_rmStatus); 
                        _statusResourcesLoaded = true; 
                    }
                    return _statusResources; 
                }
            }

            #endregion Public Properties 

            #region Private Fields 
            //------------------------------------------------------ 
            // Private Fields
            //------------------------------------------------------ 

            private RightsManagementStatus _rmStatus;
            private DocumentStatusResources _statusResources;
            private bool _statusResourcesLoaded; 

            #endregion Private Fields 
 
        }
 
        /// 
        /// RMPolicyEventArgs, object used when firing RMPolicy change.
        /// 
        public class RightsManagementPolicyEventArgs : EventArgs 
        {
            #region Constructors 
            //----------------------------------------------------- 
            // Constructors
            //------------------------------------------------------ 

            /// 
            /// The constructor
            ///  
            ///
            ///     Critical - The rmPolicy parameter contains critical data. 
            /// 
            [SecurityCritical]
            internal RightsManagementPolicyEventArgs(RightsManagementPolicy rmPolicy) 
            {
                _rmPolicy = rmPolicy;
            }
 
            #endregion Constructors
 
            #region Public Properties 
            //-----------------------------------------------------
            // Public Properties 
            //-----------------------------------------------------

            /// 
            /// Property to get/set the RMPolicy 
            /// 
            /// 
            ///     Critical    - RMPolicy contains critical data. 
            ///     TreatAsSafe - RMPolicy is safe for read.
            /// 
            public RightsManagementPolicy RMPolicy
            {
                [SecurityCritical, SecurityTreatAsSafe]
                get { return _rmPolicy; } 
            }
 
            #endregion Public Properties 

            #region Private Fields 
            //-----------------------------------------------------
            // Private Fields
            //------------------------------------------------------
 
            ///
            ///     Critical - _rmPolicy contains critical data. 
            /// 
            [SecurityCritical]
            private RightsManagementPolicy _rmPolicy; 

            #endregion Private Fields
        }
 
        /// 
        /// The data passed to the Rights Management enrollment thread. 
        ///  
        private struct RightsManagementEnrollThreadInfo
        { 
            /// 
            /// The account type to enroll
            /// 
            public EnrollmentAccountType AccountType; 

            ///  
            /// A handle to the form that displays enrollment progress 
            /// 
            public Form ProgressForm; 
        }

        #endregion Nested Class
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK