예제 #1
0
        internal void OnNotify(MapiNotification notification)
        {
            if (ExTraceGlobals.StorageTracer.IsTraceEnabled(TraceType.DebugTrace))
            {
                ExTraceGlobals.StorageTracer.TraceDebug((long)this.GetHashCode(), "SubscriptionSink::OnNotify. Capacity = {0}, Count = {1}, Notification = {2}, needsNotifyManager = {3}.", new object[]
                {
                    256,
                    this.pendingNotificationCount,
                    (notification == null) ? "<Null>" : notification.NotificationType.ToString(),
                    this.needsNotifyManager
                });
            }
            Notification notification2;

            if (this.subscription == null)
            {
                if (!this.Enqueue(notification))
                {
                    ExTraceGlobals.StorageTracer.TraceError <int, int>((long)this.GetHashCode(), "SubscriptionSink::OnNotify. The sink is full. Capacity = {0}, Count = {1}", 256, this.pendingNotificationCount);
                    this.hasDroppedNotification = true;
                }
                if (this.needsNotifyManager)
                {
                    this.manager.SendNotificationAlert();
                    return;
                }
            }
            else if (this.subscription.TryCreateXsoNotification(notification, out notification2))
            {
                this.subscription.InvokeHandler(notification2);
            }
        }
예제 #2
0
 private void SearchMapiNotificationHandler(MapiNotification notification)
 {
     if (notification.NotificationType == AdviseFlags.SearchComplete)
     {
         this.SearchComplete.Set();
     }
 }
예제 #3
0
        internal void OnNotify(MapiNotification notification)
        {
            Notification state;

            if (this.TryCreateXsoNotification(notification, out state))
            {
                ThreadPool.QueueUserWorkItem(this.waitCallback, state);
            }
        }
예제 #4
0
 private bool Enqueue(MapiNotification mapiNotification)
 {
     if (this.pendingNotificationCount > 256)
     {
         return(false);
     }
     SubscriptionSink.NotificationNode next = new SubscriptionSink.NotificationNode(mapiNotification);
     this.writer.Next = next;
     this.writer      = this.writer.Next;
     Interlocked.Increment(ref this.pendingNotificationCount);
     return(true);
 }
예제 #5
0
 internal bool TryCreateXsoNotification(MapiNotification notification, out Notification xsoNotification)
 {
     xsoNotification = null;
     if (notification.NotificationType == AdviseFlags.TableModified)
     {
         xsoNotification = Subscription.CreateQueryNotification(notification, this.queryResult.Columns);
     }
     else
     {
         xsoNotification = Subscription.CreateNotification(notification);
     }
     return(xsoNotification != null);
 }
예제 #6
0
        private static Notification CreateNotification(MapiNotification notification)
        {
            Notification result;

            if (notification.NotificationType == AdviseFlags.NewMail)
            {
                MapiNewMailNotification mapiNewMailNotification = notification as MapiNewMailNotification;
                result = new NewMailNotification(StoreObjectId.FromProviderSpecificId(mapiNewMailNotification.EntryId, ObjectClass.GetObjectType(mapiNewMailNotification.MessageClass)), StoreObjectId.FromProviderSpecificId(mapiNewMailNotification.ParentId, StoreObjectType.Folder), mapiNewMailNotification.MessageClass, (MessageFlags)mapiNewMailNotification.MessageFlags);
            }
            else if (notification.NotificationType == AdviseFlags.SearchComplete)
            {
                result = new ObjectNotification(null, null, null, null, (NotificationObjectType)0, null, NotificationType.SearchComplete);
            }
            else if (notification.NotificationType == AdviseFlags.ConnectionDropped)
            {
                MapiConnectionDroppedNotification mapiConnectionDroppedNotification = notification as MapiConnectionDroppedNotification;
                result = new ConnectionDroppedNotification(mapiConnectionDroppedNotification.ServerDN, mapiConnectionDroppedNotification.UserDN, mapiConnectionDroppedNotification.TickDeath);
            }
            else
            {
                MapiObjectNotification mapiObjectNotification = notification as MapiObjectNotification;
                if (mapiObjectNotification == null)
                {
                    throw new InvalidOperationException(ServerStrings.ExNotSupportedNotificationType((uint)notification.NotificationType));
                }
                AdviseFlags      notificationType = notification.NotificationType;
                NotificationType type;
                if (notificationType <= AdviseFlags.ObjectDeleted)
                {
                    if (notificationType == AdviseFlags.ObjectCreated)
                    {
                        type = NotificationType.Created;
                        goto IL_10A;
                    }
                    if (notificationType == AdviseFlags.ObjectDeleted)
                    {
                        type = NotificationType.Deleted;
                        goto IL_10A;
                    }
                }
                else
                {
                    if (notificationType == AdviseFlags.ObjectModified)
                    {
                        type = NotificationType.Modified;
                        goto IL_10A;
                    }
                    if (notificationType == AdviseFlags.ObjectMoved)
                    {
                        type = NotificationType.Moved;
                        goto IL_10A;
                    }
                    if (notificationType == AdviseFlags.ObjectCopied)
                    {
                        type = NotificationType.Copied;
                        goto IL_10A;
                    }
                }
                throw new InvalidOperationException(ServerStrings.ExNotSupportedNotificationType((uint)notification.NotificationType));
IL_10A:
                UnresolvedPropertyDefinition[] propertyDefinitions;
                if (mapiObjectNotification.Tags != null)
                {
                    propertyDefinitions = PropertyTagCache.UnresolvedPropertyDefinitionsFromPropTags(mapiObjectNotification.Tags);
                }
                else
                {
                    propertyDefinitions = Array <UnresolvedPropertyDefinition> .Empty;
                }
                result = new ObjectNotification((mapiObjectNotification.EntryId == null) ? null : StoreObjectId.FromProviderSpecificId(mapiObjectNotification.EntryId, StoreObjectType.Unknown), (mapiObjectNotification.ParentId == null) ? null : StoreObjectId.FromProviderSpecificId(mapiObjectNotification.ParentId, StoreObjectType.Folder), (mapiObjectNotification.OldId == null) ? null : StoreObjectId.FromProviderSpecificId(mapiObjectNotification.OldId, StoreObjectType.Unknown), (mapiObjectNotification.OldParentId == null) ? null : StoreObjectId.FromProviderSpecificId(mapiObjectNotification.OldParentId, StoreObjectType.Folder), (NotificationObjectType)mapiObjectNotification.ObjectType, propertyDefinitions, type);
            }
            return(result);
        }
예제 #7
0
        private static Notification CreateQueryNotification(MapiNotification notification, ColumnPropertyDefinitions columns)
        {
            MapiTableNotification mapiTableNotification = notification as MapiTableNotification;
            QueryNotificationType eventType;

            switch (mapiTableNotification.TableEvent)
            {
            case TableEvent.TableChanged:
                eventType = QueryNotificationType.QueryResultChanged;
                break;

            case TableEvent.TableError:
                eventType = QueryNotificationType.Error;
                break;

            case TableEvent.TableRowAdded:
                eventType = QueryNotificationType.RowAdded;
                break;

            case TableEvent.TableRowDeleted:
            case TableEvent.TableRowDeletedExtended:
                eventType = QueryNotificationType.RowDeleted;
                break;

            case TableEvent.TableRowModified:
                eventType = QueryNotificationType.RowModified;
                break;

            case TableEvent.TableSortDone:
                eventType = QueryNotificationType.SortDone;
                break;

            case TableEvent.TableRestrictDone:
                eventType = QueryNotificationType.RestrictDone;
                break;

            case TableEvent.TableSetColDone:
                eventType = QueryNotificationType.SetColumnDone;
                break;

            case TableEvent.TableReload:
                eventType = QueryNotificationType.Reload;
                break;

            default:
                return(null);
            }
            int hresult = mapiTableNotification.HResult;

            byte[] index = mapiTableNotification.Index.GetBytes() ?? Array <byte> .Empty;
            byte[] prior = mapiTableNotification.Prior.GetBytes() ?? Array <byte> .Empty;
            ICollection <PropertyDefinition> propertyDefinitions;

            object[] row;
            if (mapiTableNotification.Row != null && mapiTableNotification.Row.Length > 0)
            {
                if (mapiTableNotification.TableEvent == TableEvent.TableRowDeletedExtended)
                {
                    PropTag[] array = new PropTag[mapiTableNotification.Row.Length];
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = mapiTableNotification.Row[i].PropTag;
                    }
                    propertyDefinitions = Subscription.PropertiesForRowDeletedExtended;
                    ICollection <PropertyDefinition> columns2 = PropertyTagCache.Cache.PropertyDefinitionsFromPropTags(NativeStorePropertyDefinition.TypeCheckingFlag.DoNotCreateInvalidType, null, null, array);
                    QueryResultPropertyBag           queryResultPropertyBag = new QueryResultPropertyBag(null, columns2);
                    queryResultPropertyBag.SetQueryResultRow(mapiTableNotification.Row);
                    row = queryResultPropertyBag.GetProperties(propertyDefinitions);
                }
                else
                {
                    if (!QueryResult.DoPropertyValuesMatchColumns(columns, mapiTableNotification.Row))
                    {
                        ExTraceGlobals.StorageTracer.TraceDebug(0L, "Subcription::CreateQueryNotification. The notification data does not match the columns the client knows about. Dropping notification.");
                        return(null);
                    }
                    QueryResultPropertyBag queryResultPropertyBag2 = new QueryResultPropertyBag(null, columns.SimplePropertyDefinitions);
                    queryResultPropertyBag2.SetQueryResultRow(mapiTableNotification.Row);
                    propertyDefinitions = columns.PropertyDefinitions;
                    row = queryResultPropertyBag2.GetProperties(columns.PropertyDefinitions);
                }
            }
            else
            {
                propertyDefinitions = Array <UnresolvedPropertyDefinition> .Empty;
                row = Array <object> .Empty;
            }
            return(new QueryNotification(eventType, hresult, index, prior, propertyDefinitions, row));
        }
예제 #8
0
 private static void OnDroppedMapiSessionNotify(MapiNotification notification)
 {
     MrsTracer.Provider.Debug("OnDroppedNotify() was called.", new object[0]);
 }
예제 #9
0
 internal NotificationNode(MapiNotification data)
 {
     this.Data = data;
     this.Next = null;
 }
예제 #10
0
        private void DeliverNotifications(object state)
        {
            if (base.IsDisposed)
            {
                return;
            }
            bool flag  = false;
            bool flag2 = false;

            while (!flag2)
            {
                try
                {
                    bool flag3 = true;
                    while (flag3)
                    {
                        flag3 = false;
                        Subscription subscription = null;
                        while (this.RoundRobinSubscriptions(ref subscription))
                        {
                            if (base.IsDisposed)
                            {
                                return;
                            }
                            MapiNotification mapiNotification = subscription.Sink.Dequeue();
                            if (ExTraceGlobals.StorageTracer.IsTraceEnabled(TraceType.DebugTrace))
                            {
                                ExTraceGlobals.StorageTracer.TraceDebug <string>((long)this.GetHashCode(), "SubscriptionManager::DeliverNotifications. notification = {0}.", (mapiNotification == null) ? "<Null>" : mapiNotification.NotificationType.ToString());
                            }
                            if (mapiNotification != null)
                            {
                                flag3 = true;
                                Notification notification;
                                if (subscription.TryCreateXsoNotification(mapiNotification, out notification))
                                {
                                    if (ExTraceGlobals.StorageTracer.IsTraceEnabled(TraceType.DebugTrace))
                                    {
                                        ExTraceGlobals.StorageTracer.TraceDebug <string>((long)this.GetHashCode(), "SubscriptionManager::DeliverNotifications. notification = {0}.", notification.Type.ToString());
                                    }
                                    subscription.InvokeHandler(notification);
                                }
                                else if (ExTraceGlobals.StorageTracer.IsTraceEnabled(TraceType.DebugTrace))
                                {
                                    ExTraceGlobals.StorageTracer.TraceDebug((long)this.GetHashCode(), "SubscriptionManager::DeliverNotifications. notification = <null>.");
                                }
                            }
                        }
                    }
                    flag = true;
                }
                finally
                {
                    bool flag4 = false;
                    lock (this.lockSubscriptionQueue)
                    {
                        flag4 = this.HasAnyNotifications();
                        if (!flag || !flag4)
                        {
                            this.isDeliveryThreadAlive = false;
                            flag2 = true;
                        }
                    }
                    if (ExTraceGlobals.StorageTracer.IsTraceEnabled(TraceType.DebugTrace))
                    {
                        ExTraceGlobals.StorageTracer.TraceDebug <bool, bool, bool>((long)this.GetHashCode(), "SubscriptionManager::DeliverNotifications. Delivery thread is leaving. isOperationSuccess = {0}, hasAnyNotifications = {1}, workDone = {2}.", flag, flag4, flag2);
                    }
                }
            }
        }