示例#1
0
        ListenerExceptionStatus IConnectionRegister.Register(Version version, int processId, BaseUriWithWildcard path, int queueId, Guid token, string eventName)
        {
            if (TD.MessageQueueRegisterStartIsEnabled())
            {
                TD.MessageQueueRegisterStart(this.EventTraceActivity);
            }

            Debug.Print("WorkerProcess.Register() version: " + version + " processId: " + processId + " path: " + path + " queueId: " + queueId + " token: " + token + " eventName: " + eventName);

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueRegisterCalled, SR.GetString(SR.TraceCodeMessageQueueRegisterCalled), new StringTraceRecord("Path", path.ToString()), this, null);
            }

            // Get the callback channel
            this.connectionDuplicator = OperationContext.Current.GetCallbackChannel <IConnectionDuplicator>();

            // Prevent this duplicate operation from timing out, faulting the pipe, and stopping any further communication with w3wp
            // we're gated by MaxPendingAccepts + MaxPendingConnection. see CSD Main bug 193390 for details
            ((IContextChannel)this.connectionDuplicator).OperationTimeout = TimeSpan.MaxValue;

            ListenerExceptionStatus status = ListenerExceptionStatus.Success;
            bool abortInstance             = false;

            if (path == null || eventName == null)
            {
                status        = ListenerExceptionStatus.InvalidArgument;
                abortInstance = true;
                goto FAILED;
            }

            // Vista only: validate remote process ID
            if (OSEnvironmentHelper.IsVistaOrGreater)
            {
                status = ListenerExceptionStatus.InvalidArgument;
                object property = OperationContext.Current.IncomingMessage.Properties[ConnectionMessageProperty.Name];
                Fx.Assert(property != null, "WorkerProcess.Register() ConnectionMessageProperty not found!");

                IConnection connection = property as IConnection;
                Fx.Assert(connection != null, "WorkerProcess.Register() ConnectionMessageProperty is not IConnection!");

                PipeHandle pipe = connection.GetCoreTransport() as PipeHandle;
                Fx.Assert(pipe != null, "WorkerProcess.Register() CoreTransport is not PipeHandle!");

                if (processId != pipe.GetClientPid())
                {
                    status        = ListenerExceptionStatus.InvalidArgument;
                    abortInstance = true;
                    goto FAILED;
                }
            }

            // validate version
            Version ourVersion = Assembly.GetExecutingAssembly().GetName().Version;

            if (version > ourVersion)
            {
                // VERSIONING
                // in V1 we assume that we can handle earlier versions
                // this might not be true when we ship later releases.
                Debug.Print("WorkerProcess.Register() unsupported version ourVersion: " + ourVersion + " version: " + version);
                status = ListenerExceptionStatus.VersionUnsupported;
                goto FAILED;
            }

            if (queueId == 0 && path == null)
            {
                status        = ListenerExceptionStatus.InvalidArgument;
                abortInstance = true;
                goto FAILED;
            }

            this.processId = processId;
            this.queueId   = 0;
            if (queueId != 0)
            {
                this.queueId = queueId;
                status       = ActivatedMessageQueue.Register(queueId, token, this);
            }
            else
            {
                status = MessageQueue.Register(path, this);
            }

            if (status == ListenerExceptionStatus.Success)
            {
                foreach (IChannel channel in OperationContext.Current.InstanceContext.IncomingChannels)
                {
                    channel.Faulted += new EventHandler(WorkerProcess_Faulted);
                    channel.Closed  += new EventHandler(WorkerProcess_Closed);
                }

                try
                {
                    using (EventWaitHandle securityEvent = EventWaitHandle.OpenExisting(ListenerConstants.GlobalPrefix + eventName, EventWaitHandleRights.Modify))
                    {
                        securityEvent.Set();
                    }
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }

                    DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);

                    status        = ListenerExceptionStatus.InvalidArgument;
                    abortInstance = true;
                }
            }

            if (status != ListenerExceptionStatus.Success)
            {
                goto FAILED;
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueRegisterSucceeded, SR.GetString(SR.TraceCodeMessageQueueRegisterSucceeded), new StringTraceRecord("Path", path.ToString()), this, null);
            }
            if (TD.MessageQueueRegisterCompletedIsEnabled())
            {
                TD.MessageQueueRegisterCompleted(this.EventTraceActivity, path.ToString());
            }
FAILED:
            if (abortInstance)
            {
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueRegisterFailed, SR.GetString(SR.TraceCodeMessageQueueRegisterFailed),
                                                    new StringTraceRecord("Register", SR.GetString(SR.SharingRegistrationFailedAndAbort, status.ToString())), this, null);
                }
                if (TD.MessageQueueRegisterAbortIsEnabled())
                {
                    TD.MessageQueueRegisterAbort(this.EventTraceActivity,
                                                 status.ToString(),
                                                 (path != null) ? path.ToString() : string.Empty);
                }

                AbortServiceInstance();
            }
            else if (status != ListenerExceptionStatus.Success)
            {
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueRegisterFailed, SR.GetString(SR.TraceCodeMessageQueueRegisterFailed),
                                                    new StringTraceRecord("Register", SR.GetString(SR.SharingRegistrationFailed, status.ToString())), this, null);
                }
                if (TD.MessageQueueRegisterFailedIsEnabled())
                {
                    TD.MessageQueueRegisterFailed(this.EventTraceActivity,
                                                  (path != null) ? path.ToString() : string.Empty,
                                                  status.ToString());
                }

                InitiateClosingServiceInstance();
            }

            return(status);
        }