/// <summary> /// Gets the appropriate error message corresponding to an exception /// and detects whether the failure is fatal to the current operation /// (i.e. the user cannot take any action to circumvent the failure). /// If the user should be given the option to take action to circumvent /// the failure, true will be returned as the askUser parameter. If the /// user declines to take action, the exception is fatal if the fatal /// parameter is true. This function basically dispatches exceptions to /// a more specific ParseException function. /// </summary> /// <param name="operation">The current operation</param> /// <param name="exception">The exception to parse</param> /// <param name="askUser">Whether or not the user should be given a /// choice to take action to prevent the failure</param> /// <param name="fatal">Whether or not the failure represented is fatal /// </param> /// <returns>A user-friendly message corresponding to the exception /// </returns> private static string ParseException( RightsManagementOperation operation, Exception exception, out bool askUser, out bool fatal) { askUser = false; fatal = true; // Filter out Template related errors, as they all should receive an // "Invalid Template" type of message. if (operation == RightsManagementOperation.TemplateAccess) { return(ParseTemplateExceptions( exception, out askUser, out fatal)); } // Each handled type of exception has a different handler function else if (exception is RightsManagementException) { return(ParseRightsManagementException( operation, (RightsManagementException)exception, out askUser, out fatal)); } // Any other exception is unknown, so there is no message string // and it is assumed to be fatal else { return(null); } }
//------------------------------------------------------ // Internal Methods //------------------------------------------------------ /// <summary> /// Handles the given exception if possible, showing the correct UI if /// necessary. If the operation is a critical one (i.e. the /// application cannot continue without performing the operation) and /// the exception cannot be handled cleanly, the method rethrows an /// appropriate exception. /// </summary> /// <param name="operation">The operation being performed</param> /// <param name="exception">The exception to try to handle</param> /// <returns>Whether or not the exception was handled</returns> internal static bool HandleOrRethrowException( RightsManagementOperation operation, Exception exception) { if (exception == null) { throw new ArgumentNullException("exception"); } Trace.SafeWrite( Trace.Rights, "ErrorHandler: Hit exception:\n{0}", exception); bool askUser = false; bool fatal = true; string message = ParseException( operation, exception, out askUser, out fatal); // If no message for a message box is provided if (string.IsNullOrEmpty(message)) { // If the exception won't be rethrown, show a generic error // message; otherwise it is something we don't know how to // handle, and we will let it kill the application if (!fatal || !IsCriticalOperation(operation)) { System.Windows.MessageBox.Show( SR.Get(SRID.RightsManagementWarnErrorGenericFailure), SR.Get(SRID.RightsManagementWarnErrorTitle), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning); } } // If there is a message provided and the user gets to decide the // correct course of action else if (askUser) { // Show a message box to ask the user System.Windows.MessageBoxResult result = System.Windows.MessageBox.Show( message, SR.Get(SRID.RightsManagementWarnErrorTitle), System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Warning); // Consider the error fatal if the user declined the mitigation // offered in the message box fatal = fatal && (result != System.Windows.MessageBoxResult.Yes); } // If there is a message provided, but the user has no choice else { // Display the error message box System.Windows.MessageBox.Show( message, SR.Get(SRID.RightsManagementWarnErrorTitle), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning); } // If the exception is fatal and the operation is critical, we // should throw an XPS Viewer exception to be handled higher up // the stack if (fatal && IsCriticalOperation(operation)) { Trace.SafeWrite( Trace.Rights, "ErrorHandler: Could not handle exception. Rethrowing."); throw new XpsViewerException( SR.Get(SRID.XpsViewerRightsManagementException), exception); } Trace.SafeWrite( Trace.Rights, "ErrorHandler: Handled exception."); return(!fatal); }
/// <summary> /// Gets the error message corresponding to a Rights Management /// exception and detects whether it is fatal and whether the user /// should be offered a mitigation. This is a specialized version of /// the ParseException function. /// </summary> /// <param name="operation">The current operation</param> /// <param name="exception">The exception to parse</param> /// <param name="askUser">Whether or not the user should be given a /// choice to take action to prevent the failure</param> /// <param name="fatal">Whether or not the failure represented is fatal /// </param> /// <returns>A user-friendly message corresponding to the exception /// </returns> private static string ParseRightsManagementException( RightsManagementOperation operation, RightsManagementException rmException, out bool askUser, out bool fatal) { askUser = false; fatal = true; RightsManagementFailureCode failureCode = rmException.FailureCode; string result = null; switch (failureCode) { case RightsManagementFailureCode.InvalidLicense: if (operation == RightsManagementOperation.TemplateAccess) { result = SRID.RightsManagementWarnErrorInvalidTemplate; } else { result = SRID.RightsManagementWarnErrorConfigurationError; } break; case RightsManagementFailureCode.InvalidLicenseSignature: if (operation == RightsManagementOperation.Initialize) { result = SRID.RightsManagementWarnErrorConfigurationError; } else { result = SRID.RightsManagementWarnErrorInvalidContent; } break; case RightsManagementFailureCode.RightNotGranted: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.InvalidVersion: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.ClockRollbackDetected: result = SRID.RightsManagementWarnErrorClockModified; break; case RightsManagementFailureCode.BindValidityTimeViolated: result = SRID.RightsManagementWarnErrorExpiredPermission; break; case RightsManagementFailureCode.BrokenCertChain: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.BindPolicyViolation: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.ManifestPolicyViolation: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.BindRevokedLicense: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.BindRevokedIssuer: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.BindRevokedPrincipal: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.BindRevokedResource: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.BindRevokedModule: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.BindAccessUnsatisfied: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.BindMachineNotFoundInGroupIdentity: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.BindRevocationListStale: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.BindNoApplicableRevocationList: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.LicenseAcquisitionFailed: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.NoDistributionPointUrlFound: result = SRID.RightsManagementWarnErrorInvalidContent; break; case RightsManagementFailureCode.NoConnect: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.ActivationFailed: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.Aborted: fatal = (operation != RightsManagementOperation.PassportActivation); break; case RightsManagementFailureCode.OutOfQuota: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.AuthenticationFailed: fatal = false; break; case RightsManagementFailureCode.ServerError: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.HidCorrupted: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.InvalidServerResponse: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.ServiceNotFound: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.UseDefault: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.ServerNotFound: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.InvalidEmail: fatal = false; break; case RightsManagementFailureCode.ValidityTimeViolation: result = SRID.RightsManagementWarnErrorExpiredPermission; break; case RightsManagementFailureCode.OutdatedModule: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.ServiceMoved: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.ServiceGone: result = SRID.RightsManagementWarnErrorServerError; break; case RightsManagementFailureCode.AdEntryNotFound: fatal = false; break; case RightsManagementFailureCode.NotAChain: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.RequestDenied: result = SRID.RightsManagementWarnErrorTemporaryActivationNotSupported; fatal = false; break; case RightsManagementFailureCode.LicenseBindingToWindowsIdentityFailed: result = SRID.RightsManagementWarnErrorNoPermission; askUser = true; break; case RightsManagementFailureCode.InvalidIssuanceLicenseTemplate: result = SRID.RightsManagementWarnErrorInvalidTemplate; fatal = false; break; case RightsManagementFailureCode.ExpiredOfficialIssuanceLicenseTemplate: result = SRID.RightsManagementWarnErrorInvalidTemplate; fatal = false; break; case RightsManagementFailureCode.InvalidClientLicensorCertificate: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.HidInvalid: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.EmailNotVerified: fatal = false; break; case RightsManagementFailureCode.DebuggerDetected: result = SRID.RightsManagementWarnErrorDebuggerDetected; break; case RightsManagementFailureCode.InvalidLockboxType: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.InvalidLockboxPath: result = SRID.RightsManagementWarnErrorConfigurationError; break; case RightsManagementFailureCode.NoAesCryptoProvider: result = SRID.RightsManagementWarnErrorConfigurationError; break; default: return(null); } if (result == null) { return(null); } else { return(SR.Get(result)); } }
//------------------------------------------------------ // Private Methods //------------------------------------------------------ /// <summary> /// Checks whether or not the given operation is a critical one. A /// critical operation is defined as an operation which should stop the /// application if it does not complete cleanly. /// </summary> /// <param name="operation">The operation to check</param> /// <returns></returns> private static bool IsCriticalOperation( RightsManagementOperation operation) { // The only non-critical operation is the generic "other" operation return(operation != RightsManagementOperation.Other); }