Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / AppModel / OleCmdHelper.cs / 1305600 / OleCmdHelper.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // This is a helper class used for interop to process the // IOleCommandTarget calls in browser hosting scenario // // History: // 06/09/03: kusumav Moved from Application.cs to separate file. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Threading; using System.Windows; using System.Security; using System.Security.Permissions; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Navigation; using System.Windows.Controls; using MS.Internal.Documents; // DocumentApplicationDocumentViewer using MS.Internal.PresentationFramework; // SecurityHelper using MS.Internal.KnownBoxes; using MS.Win32; namespace MS.Internal.AppModel { #region OleCmdHelper class //// OleCmd helper class for processing IOleCommandTarget calls in browser hosting scenario // internal sealed class OleCmdHelper : MarshalByRefObject { internal const int OLECMDERR_E_NOTSUPPORTED = unchecked((int)0x80040100), OLECMDERR_E_DISABLED = unchecked((int)0x80040101), OLECMDERR_E_UNKNOWNGROUP = unchecked((int)0x80040104); internal const uint CommandUnsupported = 0; internal const uint CommandEnabled = (uint)(UnsafeNativeMethods.OLECMDF.OLECMDF_ENABLED | UnsafeNativeMethods.OLECMDF.OLECMDF_SUPPORTED); internal const uint CommandDisabled = (uint)UnsafeNativeMethods.OLECMDF.OLECMDF_SUPPORTED; // IMPORTANT: Keep this in [....] with wcp\host\inc\hostservices.idl internal static readonly Guid CGID_ApplicationCommands = new Guid(0xebbc8a63, 0x8559, 0x4892, 0x97, 0xa8, 0x31, 0xe9, 0xb0, 0xe9, 0x85, 0x91); internal static readonly Guid CGID_EditingCommands = new Guid(0xc77ce45, 0xd1c, 0x4f2a, 0xb2, 0x93, 0xed, 0xd5, 0xe2, 0x7e, 0xba, 0x47); internal OleCmdHelper() { } ////// Critical: This code calls into _DoqueryStatus /// ////// The native code passes queries here only for the recognized command groups: /// standard (NULL), ApplicaitonCommands, EditingCommands. /// [SecurityCritical] internal void QueryStatus(Guid guidCmdGroup, uint cmdId, ref uint flags) { /***IMPORTANT: Make sure to return allowed and appropriate values according to the specification of IOleCommandTarget::QueryStatus(). In particular: - OLECMDF_SUPPORTED without OLECMDF_ENABLED should not be blindly returned for unrecognized commands. - Some code in IE treats OLECMDERR_E_xxx differently from generic failures. - E_NOTIMPL is not an acceptable return value. */ if (Application.Current == null || Application.IsShuttingDown == true) { Marshal.ThrowExceptionForHR(NativeMethods.E_FAIL); } // Get values from mapping here else mark them as disabled ==> // i.e "supported but not enabled" and is the equivalent of disabled since // there is no explicit "disabled" OLECMD flag IDictionary oleCmdMappingTable = GetOleCmdMappingTable(guidCmdGroup); if (oleCmdMappingTable == null) { Marshal.ThrowExceptionForHR(OleCmdHelper.OLECMDERR_E_UNKNOWNGROUP); } CommandWithArgument command = oleCmdMappingTable[cmdId] as CommandWithArgument; if (command == null) { flags = CommandUnsupported; return; } // Go through the Dispatcher in order to use its SynchronizationContext and also // so that any application exception caused during event routing is reported via // Dispatcher.UnhandledException. // The above code is not in the callback, because it throws, and we don't want the // application to get these exceptions. (The COM Interop layer turns them into HRESULTs.) bool enabled = (bool)Application.Current.Dispatcher.Invoke( DispatcherPriority.Send, new DispatcherOperationCallback(QueryEnabled), command); flags = enabled ? CommandEnabled : CommandDisabled; } ////// Critical: Calls the critical CommandWithArgument.QueryEnabled(). /// [SecurityCritical] private object QueryEnabled(object command) { if (Application.Current.MainWindow == null) return false; IInputElement target = FocusManager.GetFocusedElement(Application.Current.MainWindow); if (target == null) { // This will always succeed because Window is IInputElement target = (IInputElement)Application.Current.MainWindow; } return BooleanBoxes.Box(((CommandWithArgument)command).QueryEnabled(target, null)); } ////// Critical: This code calls into ExecCommandCallback helper /// ////// The native code passes here only commands of the recognized command groups: /// standard (NULL), ApplicaitonCommands, EditingCommands. /// [SecurityCritical] internal void ExecCommand(Guid guidCmdGroup, uint commandId, object arg) { if (Application.Current == null || Application.IsShuttingDown == true) { Marshal.ThrowExceptionForHR(NativeMethods.E_FAIL); } int hresult = (int)Application.Current.Dispatcher.Invoke( DispatcherPriority.Send, new DispatcherOperationCallback(ExecCommandCallback), new object[] { guidCmdGroup, commandId, arg }); // Note: ExecCommandCallback() returns an HRESULT instead of throwing for the reason // explained in QueryStatus(). if(hresult < 0) { Marshal.ThrowExceptionForHR(hresult); } } ////// Critical:This API calls into Execute /// [SecurityCritical] private object ExecCommandCallback(object arguments) { object[] args = (object[])arguments; Invariant.Assert(args.Length == 3); Guid guidCmdGroup = (Guid)args[0]; uint commandId = (uint)args[1]; object arg = args[2]; IDictionary oleCmdMappingTable = GetOleCmdMappingTable(guidCmdGroup); if (oleCmdMappingTable == null) return OLECMDERR_E_UNKNOWNGROUP; CommandWithArgument command = oleCmdMappingTable[commandId] as CommandWithArgument; if (command == null) return OLECMDERR_E_NOTSUPPORTED; if (Application.Current.MainWindow == null) return OLECMDERR_E_DISABLED; IInputElement target = FocusManager.GetFocusedElement(Application.Current.MainWindow); if (target == null) { // This will always succeed because Window is IInputElement target = (IInputElement)Application.Current.MainWindow; } return command.Execute(target, arg) ? NativeMethods.S_OK : OLECMDERR_E_DISABLED; } ////// Critical:This API accesses the commandmapping table and returns it /// TreatAsSafe: It returns a copy which is safe /// [SecurityCritical, SecurityTreatAsSafe] private IDictionary GetOleCmdMappingTable(Guid guidCmdGroup) { IDictionary mappingTable = null; if (guidCmdGroup.Equals(CGID_ApplicationCommands)) { EnsureApplicationCommandsTable(); mappingTable = _applicationCommandsMappingTable.Value; } else if(guidCmdGroup.Equals(Guid.Empty)) { EnsureOleCmdMappingTable(); mappingTable = _oleCmdMappingTable.Value; } else if (guidCmdGroup.Equals(CGID_EditingCommands)) { EnsureEditingCommandsTable(); mappingTable = _editingCommandsMappingTable.Value; } return mappingTable; } ////// Critical: This code initializes the OleCmdMappingTable which is a critical for /// set data structure /// TreatAsSafe: All the values that it adds are predefined handlers in this class /// no external values /// [SecurityCritical,SecurityTreatAsSafe] private void EnsureOleCmdMappingTable() { if (_oleCmdMappingTable.Value == null) { _oleCmdMappingTable.Value = new SortedList(10); //Add applevel commands here _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_SAVE, new CommandWithArgument(ApplicationCommands.Save)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_SAVEAS, new CommandWithArgument(ApplicationCommands.SaveAs)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_PRINT, new CommandWithArgument(ApplicationCommands.Print)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_CUT, new CommandWithArgument(ApplicationCommands.Cut)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_COPY, new CommandWithArgument(ApplicationCommands.Copy)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_PASTE, new CommandWithArgument(ApplicationCommands.Paste)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_PROPERTIES, new CommandWithArgument(ApplicationCommands.Properties)); //Set the Enabled property of Stop and Refresh commands correctly _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_REFRESH, new CommandWithArgument(NavigationCommands.Refresh)); _oleCmdMappingTable.Value.Add((uint)UnsafeNativeMethods.OLECMDID.OLECMDID_STOP, new CommandWithArgument(NavigationCommands.BrowseStop)); } } ////// Critical: This code initializes the OleCmdMappingTable which is a critical for /// set data structure /// TreatAsSafe: All the values that it adds are predefined handlers in this class /// no external values /// [SecurityCritical, SecurityTreatAsSafe] private void EnsureApplicationCommandsTable() { if (_applicationCommandsMappingTable.Value == null) { /* we want to possible add 26 entries, so the capacity should be * 26/0.72 = 19 for default of 1.0 load factor*/ _applicationCommandsMappingTable.Value = new Hashtable(19); //Add applevel commands here // Note: The keys are added as uint type so that the default container comparer works // when we try to look up a command by a uint cmdid. _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Cut, new CommandWithArgument(ApplicationCommands.Cut)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Copy, new CommandWithArgument(ApplicationCommands.Copy)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Paste, new CommandWithArgument(ApplicationCommands.Paste)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_SelectAll, new CommandWithArgument(ApplicationCommands.SelectAll)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Find, new CommandWithArgument(ApplicationCommands.Find)); // Add standard navigation commands _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Refresh, new CommandWithArgument(NavigationCommands.Refresh)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Stop, new CommandWithArgument(NavigationCommands.BrowseStop)); // add document viewer commands _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Digitalsignatures_SignDocument, new CommandWithArgument(DocumentApplicationDocumentViewer.Sign)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Digitalsignatures_RequestSignature, new CommandWithArgument(DocumentApplicationDocumentViewer.RequestSigners)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Digitalsignatures_ViewSignature, new CommandWithArgument(DocumentApplicationDocumentViewer.ShowSignatureSummary)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Permission_Set, new CommandWithArgument(DocumentApplicationDocumentViewer.ShowRMPublishingUI)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Permission_View, new CommandWithArgument(DocumentApplicationDocumentViewer.ShowRMPermissions)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.Edit_Permission_Restrict, new CommandWithArgument(DocumentApplicationDocumentViewer.ShowRMCredentialManager)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_In, new CommandWithArgument(NavigationCommands.IncreaseZoom)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_Out, new CommandWithArgument(NavigationCommands.DecreaseZoom)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_400, new CommandWithArgument(NavigationCommands.Zoom, 400)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_250, new CommandWithArgument(NavigationCommands.Zoom, 250)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_150, new CommandWithArgument(NavigationCommands.Zoom, 150)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_100, new CommandWithArgument(NavigationCommands.Zoom, 100)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_75, new CommandWithArgument(NavigationCommands.Zoom, 75)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_50, new CommandWithArgument(NavigationCommands.Zoom, 50)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_25, new CommandWithArgument(NavigationCommands.Zoom, 25)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_PageWidth, new CommandWithArgument(DocumentViewer.FitToWidthCommand)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_WholePage, new CommandWithArgument(DocumentViewer.FitToHeightCommand)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_TwoPages, new CommandWithArgument(DocumentViewer.FitToMaxPagesAcrossCommand, 2)); _applicationCommandsMappingTable.Value.Add((uint)AppCommands.View_Zoom_Thumbnails, new CommandWithArgument(DocumentViewer.ViewThumbnailsCommand)); } } ////// Critical: Initializes _editingCommandsMappingTable, which is a critical for set. /// TreatAsSafe: Only predefined commands are used. EditingCommands are enabled in partial trust. /// [SecurityCritical, SecurityTreatAsSafe] private void EnsureEditingCommandsTable() { if (_editingCommandsMappingTable.Value == null) { _editingCommandsMappingTable.Value = new SortedList(2); // Note: The keys are added as uint type so that the default container comparer works // when we try to look up a command by a uint cmdid. _editingCommandsMappingTable.Value.Add((uint)EditingCommandIds.Backspace, new CommandWithArgument(System.Windows.Documents.EditingCommands.Backspace)); _editingCommandsMappingTable.Value.Add((uint)EditingCommandIds.Delete, new CommandWithArgument(System.Windows.Documents.EditingCommands.Delete)); } } private SecurityCriticalDataForSet_oleCmdMappingTable; private SecurityCriticalDataForSet _applicationCommandsMappingTable; private SecurityCriticalDataForSet _editingCommandsMappingTable; } #endregion OleCmdHelper class #region CommandAndArgument class /// /// This wrapper class helps store default arguments for commands. /// The primary scenario for this class is the Zoom command where we /// have multiple menu items and want to fire a single event with an /// argument. We cannot attach an argument value to the native menu /// item so when we do the translation we add it. /// internal class CommandWithArgument { ////// Critical: This can be used to spoof paste command /// [SecurityCritical] public CommandWithArgument(RoutedCommand command) : this(command, null) { } ////// Critical: This can be used to spoof paste command /// [SecurityCritical] public CommandWithArgument(RoutedCommand command, object argument) { _command = new SecurityCriticalDataForSet(command); _argument = argument; } /// /// Critical:This API calls into ExecuteCore and CriticalCanExecute /// [SecurityCritical] public bool Execute(IInputElement target, object argument) { if (argument == null) { argument = _argument; } // ISecureCommand is used to enforce user-initiated invocation. Cut, Copy and Paste // are marked as such. See ApplicationCommands.GetRequiredPermissions. if (_command.Value is ISecureCommand) { bool unused; if (_command.Value.CriticalCanExecute(argument, target, /* trusted: */ true, out unused)) { _command.Value.ExecuteCore(argument, target, /* userInitiated: */ true); return true; } return false; } if (_command.Value.CanExecute(argument, target)) { _command.Value.Execute(argument, target); return true; } return false; } ////// Critical: This code calls into Routedcommand.QueryStatus /// with a trusted bit, that can be used to cause an elevation. /// [SecurityCritical] public bool QueryEnabled(IInputElement target, object argument) { if (argument == null) { argument = _argument; } // ISecureCommand is used to enforce user-initiated invocation. Cut, Copy and Paste // are marked as such. See ApplicationCommands.GetRequiredPermissions. if (_command.Value is ISecureCommand) { bool unused; return _command.Value.CriticalCanExecute(argument, target, /* trusted: */ true, out unused); } return _command.Value.CanExecute(argument, target); } public RoutedCommand Command { get { return _command.Value; } } private object _argument; ////// Critical: This data is critical for set since it is used to make a security decision /// private SecurityCriticalDataForSet_command; } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ResXResourceWriter.cs
- File.cs
- DesignerLoader.cs
- IDispatchConstantAttribute.cs
- ExceptionTrace.cs
- IdnElement.cs
- ConsoleKeyInfo.cs
- TextBlockAutomationPeer.cs
- StorageEntityContainerMapping.cs
- Utils.cs
- PathSegment.cs
- QilXmlReader.cs
- SqlBuilder.cs
- LocalizationParserHooks.cs
- FragmentQueryKB.cs
- InfoCardRSAPKCS1SignatureFormatter.cs
- DoubleAnimationBase.cs
- SurrogateEncoder.cs
- TextSelectionProcessor.cs
- ActiveXSite.cs
- AutomationElement.cs
- WebPartConnectionsConnectVerb.cs
- IfAction.cs
- ComponentCollection.cs
- ProcessModelSection.cs
- mactripleDES.cs
- WorkflowOperationErrorHandler.cs
- _SSPISessionCache.cs
- XmlSequenceWriter.cs
- LoginName.cs
- DBParameter.cs
- CommonXSendMessage.cs
- DataSourceHelper.cs
- Command.cs
- ResizeGrip.cs
- MasterPageBuildProvider.cs
- FontUnit.cs
- EventProxy.cs
- grammarelement.cs
- PrintController.cs
- HttpHeaderCollection.cs
- XmlWriterDelegator.cs
- Utils.cs
- FormatException.cs
- ScriptingProfileServiceSection.cs
- TypedDatasetGenerator.cs
- ComplexType.cs
- IsolatedStorageFile.cs
- HttpCookieCollection.cs
- FormViewActionList.cs
- IApplicationTrustManager.cs
- DBConnectionString.cs
- SecurityElement.cs
- SoapProtocolReflector.cs
- XmlIterators.cs
- DataGridParentRows.cs
- SortExpressionBuilder.cs
- Memoizer.cs
- AuthenticationSection.cs
- MonitoringDescriptionAttribute.cs
- SqlCommandSet.cs
- __Filters.cs
- Int64AnimationBase.cs
- IDataContractSurrogate.cs
- TrimSurroundingWhitespaceAttribute.cs
- ThreadAttributes.cs
- HttpResponse.cs
- x509utils.cs
- TimeSpanValidatorAttribute.cs
- BrowserInteropHelper.cs
- WebServiceFaultDesigner.cs
- HtmlTernaryTree.cs
- SystemIcons.cs
- BaseDataListActionList.cs
- ElementMarkupObject.cs
- WebBrowser.cs
- Registry.cs
- AdPostCacheSubstitution.cs
- TriggerAction.cs
- WindowsAuthenticationModule.cs
- HttpContext.cs
- Process.cs
- Thickness.cs
- Int32CollectionConverter.cs
- FacetChecker.cs
- MethodBody.cs
- ControlAdapter.cs
- DotNetATv1WindowsLogEntrySerializer.cs
- Logging.cs
- RequestQueryParser.cs
- TcpHostedTransportConfiguration.cs
- RowCache.cs
- ItemsPanelTemplate.cs
- ConfigurationLockCollection.cs
- DesignerSerializationOptionsAttribute.cs
- NavigationCommands.cs
- Int64Animation.cs
- ServiceMetadataPublishingElement.cs
- MailAddressCollection.cs
- Ray3DHitTestResult.cs