Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / ClientUIRequest.cs / 1 / ClientUIRequest.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- // // Presharp uses the c# pragma mechanism to supress its warnings. // These are not recognised by the base compiler so we need to explictly // disable the following warnings. See http://winweb/cse/Tools/PREsharp/userguide/default.asp // for details. // #pragma warning disable 1634, 1691 // unknown message, unknown pragma namespace Microsoft.InfoCards { using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; //Win32Exception using System.Diagnostics; using System.IO; //Stream using System.Runtime.InteropServices; using System.Security.Principal; //WindowsIdentity using System.Threading; //ManualResetEvent using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; abstract class ClientUIRequest :ClientRequest { class ProcessHandleDictionary :HandleDictionary{ } static object s_syncRoot = new object(); static ProcessHandleDictionary s_connectedProcesses = new ProcessHandleDictionary(); public enum RequestResult { Pending = 0, // Indicating that the results are still pending. Ok = 1, // Indicating that the request was completed sucessfully Cancel = 2, // Indicating that the request was cancelled by the user Untrusted = 3, // Indicating that the request was cancelled by the user as the recipient was not trusted Error = 4, // Indicating that an error occured during the request processing. UIFailedInitialization = 5, // Indicating that an error occured during initialization of the Ui agent. // for example during creation of the secure desktop. UICrashed = 6, // Indicating that an unexpected error occurred in the agent causing it to crash }; // // Set when the uiagent is done. // ManualResetEvent m_uiAgentDone; // // This connection is made on the root incoming UI request. // This should no be directly used, but is maintained to ensure // that the store is not de-referenced by another call and remains loaded // throughout the entire request. // StoreConnection m_rootStoreReference; volatile InfoCardUIAgent m_uiAgent; InfoCardUIAgent.CallMode m_uiAgentMode; AccessibilityApplicationManager m_atManager = new AccessibilityApplicationManager(); // // Summary: // Base CTOR for client UI requests // // Arguments: // callingProcess - The process in which the caller originated. // callingIdentity - The WindowsIdentity of the caller // uiAgent - The instance of the InfoCardUIAgent class that we should bind to. // rpcHandle - The handle of the native RPC request // inArgs - The stream to read input data from // outArgs - The stream to write output data to // public ClientUIRequest( Process callingProcess, WindowsIdentity callingIdentity, InfoCardUIAgent uiAgent, IntPtr rpcHandle, Stream inArgs, Stream outArgs, InfoCardUIAgent.CallMode callMode, ExceptionList recoverableExceptions ) : base( callingProcess, callingIdentity, rpcHandle, inArgs, outArgs, recoverableExceptions ) { m_uiAgentMode = callMode; m_uiAgentDone = new ManualResetEvent( false ); // // Set the request, and bind to it. // m_uiAgent = uiAgent; m_uiAgent.SetRequest( this ); } // // Summary: // Creates a client rpc context handle that the client can use in a later call to the RPCDispatchClientUIRequest // RPC function. // // Parameters: // rpcHandle - an incoming rpc handle. // context - on return contains the newly created context handle. // // Returns: // An HRESULT. // static public int BindToService( IntPtr rpcHandle, out IntPtr context ) { int status = 0; context = IntPtr.Zero; try { Process callingProcess = GetCallingProcessFromRpcHandle( rpcHandle ); WindowsIdentity identity = NativeMcppMethods.CreateServiceExecutionIdentity( callingProcess ); WindowsImpersonationContext impersonationContext = identity.Impersonate(); try { int id = 0; lock( s_syncRoot ) { try { // // Try to get a new handle under which to store the Process. // try { id = s_connectedProcesses.GetNewHandle(); } catch( IndexOutOfRangeException e ) { throw IDT.ThrowHelperError( new ServiceBusyException( SR.GetString( SR.TooManyClientUIConnections ), e ) ); } // // Store the process and set up the context to return to the client. // s_connectedProcesses[ id ] = callingProcess; context = new IntPtr( id ); // // We are now certain of success so clear these out so that they don't get cleaned up on the way // out. // id = 0; callingProcess = null; } finally { if( null != callingProcess ) { callingProcess.Dispose(); } if( 0 != id ) { s_connectedProcesses.Remove( id ); } } } } finally { impersonationContext.Undo(); } } catch( InfoCardBaseException e ) { status = e.NativeHResult; } return status; } // // Summary: // Retrieves a Process instance that this the process of the client that is bound to the context handle // passed in to this method. // // Parameters: // context - an Rpc context handle. // clear - if set to true then this method will remove the entry from the HandleDictionary before returning. // // Returns: // A process instance that was saved in a previous call to BindToService. // public static Process GetContextMapping( IntPtr context, bool clear ) { int id = context.ToInt32(); Process callingProcess = null; lock( s_syncRoot ) { if( s_connectedProcesses.ContainsHandle( id ) ) { callingProcess = s_connectedProcesses[ id ]; if( clear ) { s_connectedProcesses.Remove( id ); } } } return callingProcess; } // // Summary: // Given an rpc context handle finds the corresponding process isntance that was created in BindToService and // Disposes it. // // Parameters: // context - an rpc context handle created in a previous call to BindToService. // public static void RemoveAndDisposeContextMapping( IntPtr context ) { Process p = GetContextMapping( context, true ); if( null != p ) { p.Dispose(); } } // // Summary: // The ultimate mode we will require in order // to complete this request. // public InfoCardUIAgent.CallMode UIAgentMode { get { return m_uiAgentMode; } } internal InfoCardUIAgent UIAgent { get { return m_uiAgent; } } public int UIAgentPid { get { return (int)UIAgent.ProcessId; } } public string UIAgentLogonSid { get { return UIAgent.TrustedUserSid; } } public bool UIAgentActive { get { return null != UIAgent && UIAgent.IsActive; } } protected override void OnInitializeAsUser() { base.OnInitializeAsUser(); m_rootStoreReference = StoreConnection.CreateConnection(); } // // Summary: // PreProcess the request. // Handle the exceptions // protected override void PreProcessRequest() { try { base.PreProcessRequest(); } catch( UIAgentInitializationException ) { throw; } catch( UserCancelledException ) { throw; } catch( UntrustedRecipientException ) { throw; } catch( UIAgentCrashedException ) { throw new CommunicationException( SR.GetString( SR.UIAgentCrash ) ); } catch( InfoCardBaseException e ) { // // At this point we have set the UI to initialize mode, // so it is showing the progress screen, but we have // encountered an error during the processing of // input arguments. We will signal to the UI that // it should show this error, and wait for the ui to close. // once closed, we will re-throw the same exception to allow it // to return to the client. // throw ShowError( e ); } } // // Summary: // Process the request. // Handle the exceptions // protected override void ProcessRequest() { try { base.ProcessRequest(); } catch( UntrustedRecipientException ) { throw; } catch( UIAgentInitializationException ) { throw; } catch( UserCancelledException ) { throw; } catch( UIAgentCrashedException ) { throw new CommunicationException( SR.GetString( SR.UIAgentCrash ) ); } catch( InfoCardBaseException e ) { // // At this point, we have caught an error that was not // a direct result of a ui operation. We will display // this error in the error dialog, then rethrow the exception // throw ShowError( e ); } } // // Summary: // PostProcess the request. // Handle the exceptions // protected override void PostProcessRequest() { try { base.PostProcessRequest(); } catch( InfoCardBaseException e ) { // // At this point, we have already selected a token or doen our // our Ui work, and we are now attempting to marshal the return // arguments back to the client, but an error occurred. If this happens, // we will show the error over the shutting down progress page, and // then rethrow the error. // throw ShowError( e ); } } // // Summary: // Tells the UI agent to show the information of the specified exception to the user. // // Returns: // The exception that should be thrown to the client. // protected Exception ShowError( Exception ex ) { // // If the agent is in the process of shutting down, there is no UI around to // show the error on. // if( m_uiAgent.IsShuttingDown ) { return ex; } // // Capture the error for the agent. // base.ProcessingException = ex; // // Reset any results we may have already recieved from the agent, as we will // need to wait for them again. // m_uiAgent.ResetUIResult(); // // Show the ui. // RequestResult result = m_uiAgent.ShowUI( InfoCardUIAgent.CallMode.Error ); // // If the user deciced in some way that the recipient is untrusted // we will discard the current processing exception, and throw // a new exception to indicate this. // if( RequestResult.Untrusted == result ) { ex = IDT.ThrowHelperError( new UntrustedRecipientException() ); } base.ProcessingException = null; return ex; } // // Summary: // Start a UI Agent if necessary and assign it this reqeust object. // Wait till the UI Agent is done (i.e. Wait till user has finished interacting with the // UI that is shown to satisfy the client UI request) // protected void StartAndWaitForUIAgent() { // // Take a local lock so that when child requests start asking for UIAgent information we have it // ready for them before they get a null reference exception. // RequestResult result = m_uiAgent.ShowUI( UIAgentMode ); switch( result ) { case RequestResult.Ok: { ;//Nothing to do here. } break; case RequestResult.Cancel: case RequestResult.Error: { // // If the UI ever returns the ERROR state, that means that // the UI had to terminate due to a screensaver, desktop switch, // or some other reason in which it needs to exit the process to // release the desktop. In this case, we return a cancel exception // to the client. When we tear down, we will then tell the agent // to exit gracefully. // throw IDT.ThrowHelperError( new UserCancelledException() ); } case RequestResult.UICrashed: { // // NB: UIAgentCrashedException does NOT derive from InfoCardBaseException. // We'll catch this and throw CommunicationException instead in *ProcessRequest(). // throw IDT.ThrowHelperError( new UIAgentCrashedException() ); } case RequestResult.Untrusted: { throw IDT.ThrowHelperError( new UntrustedRecipientException() ); } case RequestResult.UIFailedInitialization: { throw IDT.ThrowHelperError( new UIAgentInitializationException() ); } case RequestResult.Pending: default: { IDT.Assert( false, "We should never get Pending or invalid state here" ); } break; } } // // Summary: // Start the accessibility applications on the InfoCard desktop. // The ATApplicationFlags parameter is used to indicate if AT Application // support has really been enabled or if we are in this call because // InfoCard is running on TabletPC. // // userATApplicationFlags - If set, AT applications are enabled. // public void StartAccessibilityApplications( uint userATApplicationFlags ) { if( null != m_uiAgent ) { IDT.DebugAssert( false == String.IsNullOrEmpty( m_uiAgent.DesktopName ), "Desktop name should be non-null" ); IDT.DebugAssert( 0 != CallerPid, "CallerPid should not be zero" ); string trustedUserSid = m_uiAgent.TrustedUserSid; m_atManager.RestartOnInfoCardDesktop( userATApplicationFlags, m_uiAgent.TrustedUserToken, ref trustedUserSid, "WinSta0\\" + m_uiAgent.DesktopName, m_uiAgent.TsSessionId, CallerPid, this.RequestorIdentity ); } } // // Summary: // Stop the AT apps on default desktop and start them on user desktop. // Returns a bool value, if true agent needs to start AT apps. // public bool RestartAccessibilityApplications() { m_atManager.Stop(); return m_atManager.RestartOnUsersDesktop( CallerPid, @"WinSta0\Default", RequestorIdentity ); } // // Summary: // Start the accessibility applications on the InfoCard desktop // public void StopAccessibilityApplications() { m_atManager.Stop(); } // // Summary: // Signals that the user has canceled the operation before the UI results are returned. // This allows for local async operations to be canceled. // public void UserCancel( bool untrusted ) { lock( SyncRoot ) { base.CancelServiceAsyncOperation( untrusted ); OnUserCancel(); } } // // Summary: // virtual Handler for UserCancel operatiions. // protected virtual void OnUserCancel() { } // // Summary: // Releases the current UI agent. // void ReleaseUIAgent() { lock( SyncRoot ) { // // Any pending async requests (e.g. GetRecipientLogosAsyncRequest) // must have been already cancelled by now. // CheckIfAllAsyncOpsCompleted(); StopAccessibilityApplications(); if( null != m_uiAgent ) { m_uiAgent.ReleaseUI(); m_uiAgent.ClearRequest( this ); m_uiAgent = null; } } } protected override void OnDisposeAsUser() { base.OnDisposeAsUser(); if( null != m_rootStoreReference ) { m_rootStoreReference.Close(); m_rootStoreReference = null; } } // // Summary: Free any resources held by this class. // Be sure to call base.OnDisposeAsSystem before returning // so that the base class has an opportunity to do its cleanup // protected override void OnDisposeAsSystem() { if( null != m_uiAgentDone ) { m_uiAgentDone.Close(); m_uiAgentDone = null; } // // Capture the use info for after we revert. // RemoveAndDisposeContextMapping( RpcHandle ); // // The agent must be released before calling the base class as the base class disposes of the caller // process which is needed during the SendAgentStatusRequest which may be sent while releasing the // agent. // ReleaseUIAgent(); // // Always call base.OnDispose before returning // base.OnDisposeAsSystem(); } } } // 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
- DataGridViewCellParsingEventArgs.cs
- SessionStateUtil.cs
- BinaryObjectWriter.cs
- FontStretchConverter.cs
- RemotingClientProxy.cs
- PrimitiveXmlSerializers.cs
- ViewDesigner.cs
- ContentOperations.cs
- OleDbRowUpdatingEvent.cs
- SpecialFolderEnumConverter.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- validationstate.cs
- FileCodeGroup.cs
- SqlColumnizer.cs
- BehaviorDragDropEventArgs.cs
- AppDomainGrammarProxy.cs
- SqlMethods.cs
- ScriptingRoleServiceSection.cs
- ParameterBuilder.cs
- CodeDefaultValueExpression.cs
- CodeSnippetCompileUnit.cs
- SudsWriter.cs
- CodeAttributeArgument.cs
- ParallelTimeline.cs
- fixedPageContentExtractor.cs
- ReverseQueryOperator.cs
- BaseTemplateParser.cs
- ThemeDirectoryCompiler.cs
- HtmlTable.cs
- BuildProviderAppliesToAttribute.cs
- ZipIOLocalFileBlock.cs
- WaitHandleCannotBeOpenedException.cs
- XmlSchemaAttributeGroup.cs
- PageVisual.cs
- OdbcReferenceCollection.cs
- PaperSize.cs
- RegexCode.cs
- AddDataControlFieldDialog.cs
- DateTimeSerializationSection.cs
- StreamGeometry.cs
- TokenBasedSet.cs
- _OverlappedAsyncResult.cs
- ParseHttpDate.cs
- SingleConverter.cs
- LateBoundBitmapDecoder.cs
- Asn1IntegerConverter.cs
- RsaSecurityKey.cs
- PropertyInformationCollection.cs
- HttpModuleAction.cs
- DocumentAutomationPeer.cs
- CodeDirectionExpression.cs
- CodeMemberMethod.cs
- OLEDB_Util.cs
- HotSpotCollection.cs
- SchemaObjectWriter.cs
- CultureMapper.cs
- WebDisplayNameAttribute.cs
- ExpressionNode.cs
- CodeSnippetExpression.cs
- PageThemeBuildProvider.cs
- PrintingPermission.cs
- UnsafeNetInfoNativeMethods.cs
- DesignerForm.cs
- SamlDelegatingWriter.cs
- WindowsListViewItemCheckBox.cs
- CodeStatementCollection.cs
- ArrayExtension.cs
- ZoneLinkButton.cs
- WindowPatternIdentifiers.cs
- WebPartManager.cs
- UniqueIdentifierService.cs
- DbModificationCommandTree.cs
- TwoPhaseCommit.cs
- ApplicationManager.cs
- CollectionView.cs
- RenderTargetBitmap.cs
- ElementHostPropertyMap.cs
- ExpressionPrefixAttribute.cs
- PageStatePersister.cs
- EntityException.cs
- MemberBinding.cs
- PropertyDescriptor.cs
- RoutingEndpointTrait.cs
- Baml6Assembly.cs
- COM2ColorConverter.cs
- CodeEntryPointMethod.cs
- GlyphRun.cs
- WmpBitmapDecoder.cs
- HostedNamedPipeTransportManager.cs
- XmlQueryTypeFactory.cs
- WpfKnownTypeInvoker.cs
- DBAsyncResult.cs
- ObjectAnimationBase.cs
- TableRow.cs
- ExplicitDiscriminatorMap.cs
- XmlElementList.cs
- XmlSchemaNotation.cs
- StateChangeEvent.cs
- ProcessThread.cs
- Filter.cs