internal static ListenerExceptionStatus Register(BaseUriWithWildcard path, WorkerProcess worker)
        {
            MessageQueue queue = null;

            lock (registry)
            {
                if (registry.TryGetValue(path, out queue))
                {
                    if (!queue.CanShare)
                    {
                        return(ListenerExceptionStatus.ConflictingRegistration);
                    }
                }
                else
                {
                    queue = new MessageQueue();
                    ListenerExceptionStatus status = ListenerExceptionStatus.FailedToListen;

                    try
                    {
                        status = queue.Register(path);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }

                        if (DiagnosticUtility.ShouldTraceError)
                        {
                            ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.RoutingTableCannotListen, SR.GetString(SR.TraceCodeRoutingTableCannotListen), new StringTraceRecord("Path", path.ToString()), null, exception);
                        }
                    }

                    if (status != ListenerExceptionStatus.Success)
                    {
                        // not setting the worker.queue is not a problem, since we can't use this WorkerProcess
                        return(status);
                    }

                    registry.Add(path, queue);
                }
            }

            queue.OnNewWorkerAvailable(worker);
            return(ListenerExceptionStatus.Success);
        }
            private void Register()
            {
                Version protocolVersion = SharedConnectionListener.ProtocolVersion;
                int     id = Process.GetCurrentProcess().Id;

                this.HandleAllowDupHandlePermission(id);
                ListenerExceptionStatus status = ((IConnectionRegister)this.controlSessionWithListener).Register(protocolVersion, id, this.baseAddress, this.queueId, this.token, this.securityEventName);

                switch (status)
                {
                case ListenerExceptionStatus.ConflictingRegistration:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AddressAlreadyInUseException(System.ServiceModel.SR.GetString("SharedManagerBase", new object[] { this.serviceName, System.ServiceModel.SR.GetString("SharedManagerConflictingRegistration") })));

                case ListenerExceptionStatus.FailedToListen:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AddressAlreadyInUseException(System.ServiceModel.SR.GetString("SharedManagerBase", new object[] { this.serviceName, System.ServiceModel.SR.GetString("SharedManagerFailedToListen") })));

                case ListenerExceptionStatus.Success:
                    return;
                }
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(System.ServiceModel.SR.GetString("SharedManagerBase", new object[] { this.serviceName, System.ServiceModel.SR.GetString("SharedManager" + status) })));
            }
        public ListenerExceptionStatus Register(BaseUriWithWildcard path)
        {
            if (path.BaseAddress.Scheme == Uri.UriSchemeNetTcp)
            {
                if (transportType == TransportType.NamedPipe)
                {
                    return(ListenerExceptionStatus.ProtocolUnsupported);
                }

                maxQueueSize  = ListenerConfig.NetTcp.MaxPendingConnections;
                transportType = TransportType.Tcp;
            }
            else if (path.BaseAddress.Scheme == Uri.UriSchemeNetPipe)
            {
                if (transportType == TransportType.Tcp)
                {
                    return(ListenerExceptionStatus.ProtocolUnsupported);
                }

                maxQueueSize  = ListenerConfig.NetPipe.MaxPendingConnections;
                transportType = TransportType.NamedPipe;
            }
            else
            {
                return(ListenerExceptionStatus.ProtocolUnsupported);
            }

            ListenerExceptionStatus status = RoutingTable.Start(this, path);

            if (status == ListenerExceptionStatus.Success)
            {
                paths.Add(path);
                IncrementUrisRegisteredCounters();
                OnRegisterCompleted();
            }

            return(status);
        }
Exemple #4
0
        bool RegisterBindings(IActivatedMessageQueue queue, int siteId, string[] bindings, string path)
        {
            Debug.Print("ListenerAdapter[" + ProtocolName + "]::RegisterBindings() bindings#: " + bindings.Length);
            BaseUriWithWildcard[] baseAddresses = new BaseUriWithWildcard[bindings.Length];
            // first make sure all the bindings are valid for this protocol
            for (int i = 0; i < bindings.Length; i++)
            {
                string binding  = bindings[i];
                int    index    = binding.IndexOf(':');
                string protocol = binding.Substring(0, index);
                if (string.Compare(this.ProtocolName, protocol, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                                                                  SR.GetString(SR.LAProtocolMismatch, protocol, path, this.ProtocolName)));
                }

                binding = binding.Substring(index + 1);
                try
                {
                    baseAddresses[i] = BaseUriWithWildcard.CreateHostedUri(ProtocolName, binding, path);
                    Debug.Print("ListenerAdapter[" + ProtocolName + "]::RegisterBindings() CreateUrlFromBinding(binding: " + binding + " path: " + path + ") returned baseAddress: " + baseAddresses[i]);
                }
                catch (UriFormatException exception)
                {
                    Debug.Print("ListenerAdapter[" + ProtocolName + "]::RegisterBindings() CreateUrlFromBinding(binding: " + binding + " path: " + path + ") failed with UriFormatException: " + exception.Message);
                    DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);

                    // We only log the event for the site root.
                    if (string.Compare(path, SiteRootPath, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
                                                            (ushort)EventLogCategory.ListenerAdapter,
                                                            (uint)EventLogEventId.BindingError,
                                                            protocol,
                                                            binding,
                                                            siteId.ToString(NumberFormatInfo.CurrentInfo),
                                                            bindings[i],
                                                            ListenerTraceUtility.CreateSourceString(this),
                                                            exception.ToString());
                    }

                    return(false);
                }
            }

            // now make sure all the bindings can be listened on or roll back
            for (int i = 0; i < bindings.Length; i++)
            {
                ListenerExceptionStatus status = ListenerExceptionStatus.FailedToListen;
                Exception exception            = null;
                try
                {
                    status = queue.Register(baseAddresses[i]);
                    Debug.Print("ListenerAdapter[" + ProtocolName + "]::RegisterBindings() registering baseAddress: " + baseAddresses[i] + " with queue returned: " + status);
                }
                catch (Exception ex)
                {
                    if (Fx.IsFatal(ex))
                    {
                        throw;
                    }

                    DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);

                    exception = ex;
                }

                if (status != ListenerExceptionStatus.Success)
                {
                    // We only log the event for the site root.
                    if (string.Compare(path, SiteRootPath, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
                                                            (ushort)EventLogCategory.ListenerAdapter,
                                                            (uint)EventLogEventId.LAFailedToListenForApp,
                                                            activationService.ActivationServiceName,
                                                            ProtocolName,
                                                            siteId.ToString(NumberFormatInfo.CurrentInfo),
                                                            baseAddresses[i].ToString(),
                                                            status.ToString(),
                                                            exception == null ? string.Empty : exception.ToString());
                    }

                    queue.UnregisterAll();
                    return(false);
                }
            }

            return(true);
        }
        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);
        }