public static SsData ReadArgumentBlock(MemoryRegion data)
        {
            KphSsArgumentBlock argBlock = data.ReadStruct <KphSsArgumentBlock>(0, KphSsArgumentBlock.SizeOf, 0);

            MemoryRegion dataRegion;
            SsData       ssArg = null;

            dataRegion = new MemoryRegion(data, KphSsArgumentBlock.DataOffset);

            // Process the argument block based on its type.
            switch (argBlock.Type)
            {
            case KphSsArgumentType.Int8:
            {
                SsSimple simpleArg = new SsSimple
                {
                    Argument = argBlock.Data.Int8,
                    Type     = typeof(Byte)
                };

                ssArg = simpleArg;
            }
            break;

            case KphSsArgumentType.Int16:
            {
                SsSimple simpleArg = new SsSimple
                {
                    Argument = argBlock.Data.Int16,
                    Type     = typeof(Int16)
                };

                ssArg = simpleArg;
            }
            break;

            case KphSsArgumentType.Int32:
            {
                SsSimple simpleArg = new SsSimple
                {
                    Argument = argBlock.Data.Int32,
                    Type     = typeof(Int32)
                };

                ssArg = simpleArg;
            }
            break;

            case KphSsArgumentType.Int64:
            {
                SsSimple simpleArg = new SsSimple
                {
                    Argument = argBlock.Data.Int64,
                    Type     = typeof(Int64)
                };

                ssArg = simpleArg;
            }
            break;

            case KphSsArgumentType.Handle:
            {
                ssArg = new SsHandle(dataRegion);
            }
            break;

            case KphSsArgumentType.UnicodeString:
            {
                ssArg = new SsUnicodeString(dataRegion);
            }
            break;

            case KphSsArgumentType.ObjectAttributes:
            {
                ssArg = new SsObjectAttributes(dataRegion);
            }
            break;

            case KphSsArgumentType.ClientId:
            {
                ssArg = new SsClientId(dataRegion);
            }
            break;

            case KphSsArgumentType.Bytes:
            {
                ssArg = new SsBytes(dataRegion);
            }
            break;
            }

            ssArg.Index = argBlock.Index;

            return(ssArg);
        }
Beispiel #2
0
        private void BufferWorkerThreadStart()
        {
            int cursor = 0;

            // Open a handle to the current thread so other functions
            // can alert us.
            _bufferWorkerThreadHandle = ThreadHandle.OpenCurrent(ThreadAccess.All);

            // We're ready.
            _bufferWorkerThreadReadyEvent.Set();

            while (!_terminating)
            {
                NtStatus         status;
                KphSsBlockHeader blockHeader;

                // Wait for a block to read (enable alerting so we can
                // be interrupted if someone wants us to stop).
                status = _readSemaphore.Wait(true);

                // Did we get alerted?
                if (status == NtStatus.Alerted)
                {
                    return;
                }

                // Check if we have an implicit cursor reset.
                if (_buffer.Size - cursor < Marshal.SizeOf(typeof(KphSsBlockHeader)))
                {
                    cursor = 0;
                }

                // Read the block header.
                blockHeader = _buffer.ReadStruct <KphSsBlockHeader>(cursor, 0);

                // Check if we have an explicit cursor reset.
                if (blockHeader.Type == KphSsBlockType.Reset)
                {
                    cursor      = 0;
                    blockHeader = _buffer.ReadStruct <KphSsBlockHeader>(cursor, 0);
                }

                // Process the block.
                if (blockHeader.Type == KphSsBlockType.Event)
                {
                    var      eventBlock = _buffer.ReadStruct <KphSsEventBlock>(cursor, 0);
                    int[]    arguments;
                    IntPtr[] stackTrace;

                    // Reconstruct the argument and stack trace arrays.

                    arguments  = new int[eventBlock.NumberOfArguments];
                    stackTrace = new IntPtr[eventBlock.TraceCount];

                    for (int i = 0; i < arguments.Length; i++)
                    {
                        arguments[i] = _buffer.ReadInt32(cursor + eventBlock.ArgumentsOffset, i);
                    }
                    for (int i = 0; i < stackTrace.Length; i++)
                    {
                        stackTrace[i] = _buffer.ReadIntPtr(cursor + eventBlock.TraceOffset, i);
                    }

                    // Create an event object.
                    SsEvent ssEvent = new SsEvent();

                    // Basic information
                    ssEvent.Time       = DateTime.FromFileTime(eventBlock.Time);
                    ssEvent.ThreadId   = eventBlock.ClientId.ThreadId;
                    ssEvent.ProcessId  = eventBlock.ClientId.ProcessId;
                    ssEvent.Arguments  = arguments;
                    ssEvent.StackTrace = stackTrace;

                    // Flags
                    ssEvent.ArgumentsCopyFailed =
                        (eventBlock.Flags & KphSsEventFlags.CopyArgumentsFailed) == KphSsEventFlags.CopyArgumentsFailed;
                    ssEvent.ArgumentsProbeFailed =
                        (eventBlock.Flags & KphSsEventFlags.ProbeArgumentsFailed) == KphSsEventFlags.ProbeArgumentsFailed;
                    ssEvent.CallNumber = eventBlock.Number;

                    if ((eventBlock.Flags & KphSsEventFlags.UserMode) == KphSsEventFlags.UserMode)
                    {
                        ssEvent.Mode = KProcessorMode.UserMode;
                    }
                    else
                    {
                        ssEvent.Mode = KProcessorMode.KernelMode;
                    }

                    // Raise the event.
                    if (this.EventBlockReceived != null)
                    {
                        this.EventBlockReceived(ssEvent);
                    }
                }
                else if (blockHeader.Type == KphSsBlockType.Argument)
                {
                    var          argBlock = _buffer.ReadStruct <KphSsArgumentBlock>(cursor, 0);
                    MemoryRegion dataRegion;
                    SsData       ssArg = null;

                    dataRegion = new MemoryRegion(_buffer, cursor + KphSsArgumentBlock.DataOffset);

                    // Process the argument block based on its type.
                    switch (argBlock.Type)
                    {
                    case KphSsArgumentType.Int8:
                    {
                        SsSimple simpleArg = new SsSimple();

                        simpleArg.Argument = argBlock.Data.Int8;
                        simpleArg.Type     = typeof(Byte);
                        ssArg = simpleArg;
                    }
                    break;

                    case KphSsArgumentType.Int16:
                    {
                        SsSimple simpleArg = new SsSimple();

                        simpleArg.Argument = argBlock.Data.Int16;
                        simpleArg.Type     = typeof(Int16);
                        ssArg = simpleArg;
                    }
                    break;

                    case KphSsArgumentType.Int32:
                    {
                        SsSimple simpleArg = new SsSimple();

                        simpleArg.Argument = argBlock.Data.Int32;
                        simpleArg.Type     = typeof(Int32);
                        ssArg = simpleArg;
                    }
                    break;

                    case KphSsArgumentType.Int64:
                    {
                        SsSimple simpleArg = new SsSimple();

                        simpleArg.Argument = argBlock.Data.Int64;
                        simpleArg.Type     = typeof(Int64);
                        ssArg = simpleArg;
                    }
                    break;

                    case KphSsArgumentType.Handle:
                    {
                        ssArg = new SsHandle(dataRegion);
                    }
                    break;

                    case KphSsArgumentType.UnicodeString:
                    {
                        ssArg = new SsUnicodeString(dataRegion);
                    }
                    break;

                    case KphSsArgumentType.ObjectAttributes:
                    {
                        ssArg = new SsObjectAttributes(dataRegion);
                    }
                    break;

                    case KphSsArgumentType.ClientId:
                    {
                        ssArg = new SsClientId(dataRegion);
                    }
                    break;
                    }

                    ssArg.Index = argBlock.Index;

                    // Raise the event.
                    if (ssArg != null)
                    {
                        if (this.ArgumentBlockReceived != null)
                        {
                            this.ArgumentBlockReceived(ssArg);
                        }
                    }
                }

                // Advance the cursor.
                cursor += blockHeader.Size;
                // Signal that a buffer block is available for writing.
                _writeSemaphore.Release();
            }
        }