Beispiel #1
0
 public static DeltaEventEntry TryCreate(IntPtr contactHandle, DBEVENTINFO dbEventInfo, byte[] eventBlob)
 {
     try
     {
         return new DeltaEventEntry(contactHandle, dbEventInfo, eventBlob);
     }
     catch
     {
         return null;
     }
 }
Beispiel #2
0
        private unsafe void GatherNewEvents(LinkedList<DeltaEntry> entries)
        {
            MirandaContext context = MirandaContext.Current;

            foreach (KeyValuePair<IntPtr, IntPtr> contactEventPair in DatabaseSnapshot.EventHandles)
            {
                UIntPtr wEventHandle = Translate.ToHandle(contactEventPair.Value);
                InteropBuffer buffer = InteropBufferPool.AcquireBuffer();

                try
                {
                    while (AdvanceToNextEvent(ref wEventHandle, contactEventPair.Key))
                    {
                        int blobSize = context.CallService(MS_DB_EVENT_GETBLOBSIZE, wEventHandle, IntPtr.Zero);

                        if (blobSize == -1)
                            continue;

                        PrepareBlobBuffer(ref buffer, blobSize);
                        DBEVENTINFO dbEventInfo = new DBEVENTINFO(blobSize, buffer.IntPtr);

                        if (context.CallService(MS_DB_EVENT_GET, wEventHandle, new IntPtr(&dbEventInfo)) != 0)
                            continue;

                        byte[] blob = new byte[blobSize];
                        Marshal.Copy(buffer.IntPtr, blob, 0, blob.Length);

                        DeltaEventEntry entry = DeltaEventEntry.TryCreate(contactEventPair.Key, dbEventInfo, blob);

                        if (entry == null)
                            continue;

                        entries.AddLast(entry);
                    }
                }
                finally
                {
                    if (buffer.Locked)
                        buffer.Unlock();

                    InteropBufferPool.ReleaseBuffer(buffer);
                }
            }
        }
Beispiel #3
0
        private unsafe void SimulateNewEvent()
        {
            DBEVENTINFO info = new DBEVENTINFO(0, IntPtr.Zero);
            info.Module = Translate.ToHandle("ICQ", StringEncoding.Ansi).IntPtr;
            UnmanagedStringHandle str = new UnmanagedStringHandle("aěščřšžšž", StringEncoding.MirandaDefault);
            info.BlobSize = (uint)str.Size;
            info.BlobPtr = str;
            info.EventType = 0;
            info.Flags = 0;
            info.Timestamp = Utilities.GetTimestamp();

            IntPtr result = new IntPtr(MirandaContext.Current.CallService("DB/Event/Add", Translate.ToHandle(MirandaContext.Current.MirandaDatabase.FindContact("177147220", ContactInfoProperty.UniqueID, StringEncoding.Ansi).MirandaHandle), new UnmanagedStructHandle<DBEVENTINFO>(ref info)));
        }
Beispiel #4
0
        public IntPtr AddEvent(ContactInfo associatedContact, object data, string owner, DatabaseEventType type, DatabaseEventProperties flags, DateTime? timestamp, bool throwOnFailure)
        {
            if (associatedContact == null)
                throw new ArgumentNullException("associatedContact");

            if (String.IsNullOrEmpty(owner))
                throw new ArgumentNullException("owner");

            if (data == null)
                throw new ArgumentNullException("data");

            IntPtr pBlob = IntPtr.Zero;
            UnmanagedStructHandle<DBEVENTINFO> nativeStruct = UnmanagedStructHandle<DBEVENTINFO>.Empty;

            try
            {
                int totalBytes;

                if (data is string)
                {
                    totalBytes = DBEVENTINFO.LayoutAnsiUniString((string)data, out pBlob);
                }
                else if (data is byte[])
                {
                    byte[] dataBytes = (byte[])data;
                    totalBytes = dataBytes.Length;

                    pBlob = Marshal.AllocHGlobal(totalBytes);
                    Marshal.Copy(dataBytes, 0, pBlob, dataBytes.Length);
                }
                else
                    throw new ArgumentOutOfRangeException("data");

                DBEVENTINFO info = new DBEVENTINFO(0, IntPtr.Zero);
                info.Module = Translate.ToHandle(owner, StringEncoding.Ansi).IntPtr;
                info.BlobSize = (uint)totalBytes;
                info.BlobPtr = pBlob;
                info.EventType = (ushort)type;
                info.Flags = (uint)flags;
                info.Timestamp = Utilities.GetTimestamp(timestamp.HasValue ? timestamp.Value : DateTime.Now);

                nativeStruct = new UnmanagedStructHandle<DBEVENTINFO>(ref info, pBlob, info.Module);
                IntPtr eventHandle = (IntPtr)MirandaContext.Current.CallService(MS_DB_EVENT_ADD, associatedContact.MirandaHandle, nativeStruct.IntPtr);

                if (eventHandle == IntPtr.Zero && throwOnFailure)
                    throw new MirandaException(String.Format(TextResources.ExceptionMsg_Formatable2_MirandaServiceReturnedFailure, MS_DB_EVENT_ADD, eventHandle.ToString()));
                else
                    return eventHandle;
            }
            finally
            {
                nativeStruct.Free();
            }
        }
Beispiel #5
0
        /// <summary>
        /// Gets the event data.
        /// </summary>
        /// <param name="dbEventInfo">[REF] <see cref="DBEVENTINFO"/> struct.</param>
        /// <returns>Event data.</returns>
        private unsafe static string GetEventData(ref DBEVENTINFO dbEventInfo)
        {
            string data;

            DBEVENTGETTEXT dbGetText = new DBEVENTGETTEXT();
            dbGetText.Codepage = 0;
            dbGetText.DataType = (int)DatabaseSettingType.UnicodeString;

            IntPtr pText;

            fixed (void* pDbEventInfo = &dbEventInfo)
            {
                dbGetText.DbEventInfoPtr = new IntPtr(pDbEventInfo);
                pText = (IntPtr)MirandaContext.Current.CallServiceUnsafe(MS_DB_EVENT_GETTEXT, null, &dbGetText);
            }

            if (pText != IntPtr.Zero)
            {
                data = Translate.ToString(pText, StringEncoding.Unicode);
                MirandaContext.Current.MirandaMemoryManager.Free(pText);
            }
            else
                throw new MirandaException(String.Format(TextResources.ExceptionMsg_Formatable2_MirandaServiceReturnedFailure, MS_DB_EVENT_GETTEXT, "null"));

            return data;
        }
Beispiel #6
0
        /// <summary>
        /// Gets the event module.
        /// </summary>
        /// <param name="dbEventInfo">[REF] <see cref=">DBEVENTINFO"/> struct.</param>
        /// <returns>Event module.</returns>
        private static Protocol GetEventModule(ref DBEVENTINFO dbEventInfo)
        {
            Protocol owningModule;
            bool moduleFound = false;

            if (dbEventInfo.Module != IntPtr.Zero)
                moduleFound = MirandaContext.Current.Protocols.TryGetValue(Translate.ToString(dbEventInfo.Module, StringEncoding.Ansi), out owningModule);
            else
                owningModule = Protocol.UnknownProtocol;

            if (!moduleFound)
                owningModule = Protocol.UnknownProtocol;

            return owningModule;
        }
Beispiel #7
0
        /// <summary>
        /// Gets the event timestamp.
        /// </summary>
        /// <param name="dbEventInfo">[REF] <see cref="DBEVENTINFO"/> struct.</param>
        /// <param name="blobBuffer">Buffer to reuse.</param>
        /// <param name="timestamp">[OUT] Timestamp.</param>
        private static void GetEventTimestamp(ref DBEVENTINFO dbEventInfo, InteropBuffer blobBuffer, out DateTime timestamp)
        {
            try
            {
                DBTIMETOSTRING timeToString = new DBTIMETOSTRING("s D");
                timeToString.MaxBytes = blobBuffer.Size;
                timeToString.Output = blobBuffer.IntPtr;

                unsafe
                {
                    MirandaContext.Current.CallServiceUnsafe(MS_DB_TIME_TIMESTAMPTOSTRING, (void*)dbEventInfo.Timestamp, &timeToString);
                }

                timestamp = DateTime.Parse(Translate.ToString(timeToString.Output, StringEncoding.Ansi));
            }
            catch (FormatException)
            {
                timestamp = DateTime.MinValue;
            }
        }
Beispiel #8
0
        /// <summary>
        /// Populates the blob buffer set by the <see cref="DBEVENTINFO"/> parameter. 
        /// </summary>
        /// <param name="dbEventInfo">[REF] <see cref="DBEVENTINFO"/> struct identifiing the buffer.</param>
        /// <param name="eventHandle">Event handle.</param>
        /// <exception cref="MirandaException">Buffer could bet populated.</exception>
        private unsafe static void PopulateBlobBuffer(ref DBEVENTINFO dbEventInfo, IntPtr eventHandle)
        {
            int result;

            fixed (void* pDbEventInfo = &dbEventInfo)
                result = MirandaContext.Current.CallServiceUnsafe(MS_DB_EVENT_GET, eventHandle.ToPointer(), pDbEventInfo);

            if (result != 0)
                throw new MirandaException(String.Format(TextResources.ExceptionMsg_Formatable2_MirandaServiceReturnedFailure, MS_DB_EVENT_GET, result.ToString()));
        }
Beispiel #9
0
        /// <summary>
        /// Get the event information from a <see cref="DBEVENTINFO"/> struct.
        /// </summary>
        /// <param name="dbEventInfo">[REF] <see cref="DBEVENTINFO"/> struct.</param>
        /// <param name="mirandaHandle">Event handle (the blob buffer will be populated if not null).</param>
        /// <param name="blobBuffer">Buffer to use for blob marshaling.</param>
        /// <param name="type">[OUT] Event type.</param>
        /// <param name="flags">[OUT] Event flags.</param>
        /// <param name="data">[OUT] Event data.</param>
        /// <param name="owningModule">[OUT] Event related module.</param>
        /// <param name="timestamp">[OUT] Event timestamp.</param>
        private static void GetEventInfo(ref DBEVENTINFO dbEventInfo, IntPtr eventHandle, InteropBuffer blobBuffer, out DatabaseEventType type, out DatabaseEventProperties flags, out string data, out Protocol owningModule, out DateTime timestamp)
        {
            MirandaContext context = MirandaContext.Current;

            unsafe
            {
                // If the event handle is set, we probably want to populate the blob buffer...
                if (eventHandle != IntPtr.Zero)
                    PopulateBlobBuffer(ref dbEventInfo, eventHandle);

                type = (DatabaseEventType)dbEventInfo.EventType;
                flags = (DatabaseEventProperties)dbEventInfo.Flags;
                data = GetEventData(ref dbEventInfo);
            }

            owningModule = GetEventModule(ref dbEventInfo);
            GetEventTimestamp(ref dbEventInfo, blobBuffer, out timestamp);
        }
Beispiel #10
0
        /// <summary>
        /// Prepares the <see cref="DBEVENTINFO"/> for information extraction and the blob buffer.
        /// </summary>
        /// <param name="eventHandle">Event handle.</param>
        /// <param name="dbEventInfo">[OUT] DB event info to marshal data into.</param>
        /// <param name="buffer">[OUT] Locked Blob buffer.</param>
        private unsafe static void PrepareDbEventInfo(IntPtr eventHandle, out DBEVENTINFO dbEventInfo, out InteropBuffer buffer)
        {
            int blobSize = MirandaContext.Current.CallServiceUnsafe(MS_DB_EVENT_GETBLOBSIZE, eventHandle.ToPointer(), null);

            if (blobSize == -1)
                throw new MirandaException(String.Format(TextResources.ExceptionMsg_Formatable2_MirandaServiceReturnedFailure, MS_DB_EVENT_GETBLOBSIZE, blobSize.ToString()));

            // Acquire a buffer for the blob
            buffer = InteropBufferPool.AcquireBuffer(blobSize);
            buffer.Lock();

            dbEventInfo = new DBEVENTINFO(blobSize, buffer.IntPtr);
        }
Beispiel #11
0
 private DeltaEventEntry(IntPtr contactHandle, DBEVENTINFO dbEventInfo, byte[] eventBlob) : base(contactHandle)
 {
     EventInfo = dbEventInfo;
     EventBlob = eventBlob;
     EventModule = Translate.ToString(dbEventInfo.Module, StringEncoding.Ansi);
 }