public int CompareTo(Object obj) { VisualTransaction otherTransaction = obj as VisualTransaction; int result = StartTime.CompareTo(otherTransaction.StartTime); if (result != 0) { return(result); } else { return(index.CompareTo(otherTransaction.index)); } }
private VisualTransaction CreateTransactionFromDeviceIoControl (Event ev, XmlElement eventRoot) { XmlNode handleNode = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[1]/value"); XmlNode codeNode = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[2]/value"); XmlNode retValNode = eventRoot.SelectSingleNode ("/event/returnValue/value"); XmlNode lastErrNode = eventRoot.SelectSingleNode ("/event/lastError"); string handleStr = null, codeStr = null, retValStr = null, lastErrStr = null; string headline = "DeviceIoControl"; if (handleNode != null && codeNode != null && retValNode != null && lastErrNode != null) { handleStr = handleNode.Attributes["value"].Value; if (!interestingHandles.Contains (handleStr)) interestingHandles.Add (handleStr); codeStr = codeNode.Attributes["value"].Value; retValStr = retValNode.Attributes["value"].Value; lastErrStr = ErrorCodeToString (Convert.ToUInt32 (lastErrNode.Attributes["value"].Value)); headline += String.Format (" ({0}) => {1}", FunctionCallArgListToString (eventRoot), retValStr.ToUpper ()); } // HACK #2: if (lastErrStr == "ERROR_MORE_DATA") // || lastErrStr == "ERROR_NOT_FOUND" || lastErrStr == "ERROR_SET_NOT_FOUND") return null; VisualTransaction tr = new VisualTransaction (ev.Id, TransactionDirection.Out, ev.Timestamp); tr.ContextID = handleStr; tr.HeadlineText = headline; tr.AddHeaderField ("Id", ev.Id); if (lastErrStr != null) tr.AddHeaderField ("LastError", lastErrStr); ByteArrayReader inBuf = null; ByteArrayReader outBufEnter = null; ByteArrayReader outBufLeave = null; XmlNode node = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[3]/value/value"); if (node != null) inBuf = new ByteArrayReader (Convert.FromBase64String (node.InnerText)); node = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[5]/value/value"); if (node != null) outBufEnter = new ByteArrayReader (Convert.FromBase64String (node.InnerText)); node = eventRoot.SelectSingleNode ("/event/arguments[@direction='out']/argument[1]/value/value"); if (node != null) outBufLeave = new ByteArrayReader (Convert.FromBase64String (node.InnerText)); if (codeStr == "IOCTL_KS_PROPERTY" && inBuf != null) { Guid propSetGuid = inBuf.ReadGuid (); uint rawPropId = inBuf.ReadU32LE (); uint propFlags = inBuf.ReadU32LE (); string propSetStr, propIdStr, propFlagsStr; if (ksPropertySets.ContainsKey (propSetGuid)) { object o = ksPropertySets[propSetGuid]; if (o is string) { propSetStr = o as string; propIdStr = String.Format ("0x{0:x8}", rawPropId); } else { KsPropertySet propSet = o as KsPropertySet; propSetStr = propSet.Name; propIdStr = Enum.GetName (propSet.EnumType, rawPropId); } } else { propSetStr = propSetGuid.ToString ("B"); propIdStr = String.Format ("0x{0:x8}", rawPropId); } propFlagsStr = BitfieldToString (ksPropertyFlags, propFlags); // HACK #3 //if (propFlagsStr == "GET") // return null; if (propSetStr == "KSPROPSETID_Topology") return null; else if (propSetStr == "KSPROPSETID_MediaSeeking" && propIdStr == "TIMEFORMAT" && propFlagsStr == "GET") return null; else if (propSetStr == "KSPROPSETID_Pin" && propFlagsStr == "GET") { List<string> boringIds = new List<string> (new string[] { "CTYPES", "CINSTANCES", "COMMUNICATION", "CONSTRAINEDDATARANGES", "DATAFLOW", "DATARANGES", "DATAINTERSECTION", "NAME" }); if (boringIds.Contains (propIdStr)) return null; } StringBuilder body = new StringBuilder (); body.AppendFormat ("[lpInBuffer]\r\nKSPROPERTY: {0}, {1}, {2}", propSetStr, propIdStr, propFlagsStr); string remainder = inBuf.ReadRemainingBytesAsHexDump (); if (remainder != null) body.AppendFormat ("\r\n{0}", remainder); if (outBufEnter != null) { body.Append ("\r\n\r\n[lpOutBuffer on entry]"); if (propSetStr == "KSPROPSETID_Connection" && propIdStr == "DATAFORMAT") { body.AppendFormat ("\r\n{0}", KsDataFormatToString (outBufEnter)); } remainder = outBufEnter.ReadRemainingBytesAsHexDump (); if (remainder != null) body.AppendFormat ("\r\n{0}", remainder); } if (outBufLeave != null) { body.Append ("\r\n\r\n[lpOutBuffer on exit]"); if (propSetStr == "KSPROPSETID_Connection" && propIdStr == "ALLOCATORFRAMING_EX") { body.Append (KsAllocatorFramingExToString (outBufLeave)); } remainder = outBufLeave.ReadRemainingBytesAsHexDump (); if (remainder != null) body.AppendFormat ("\r\n{0}", remainder); } tr.BodyText = body.ToString (); } else if (codeStr == "IOCTL_KS_READ_STREAM") { XmlNode dataNode = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[5]/value"); string body = KsReadStreamDataToString (dataNode, "in"); if (retValStr.ToUpper () == "TRUE") { dataNode = eventRoot.SelectSingleNode ("/event/arguments[@direction='out']/argument[1]/value"); body += KsReadStreamDataToString (dataNode, "out"); } else if (lastErrStr == "ERROR_IO_PENDING") { pendingReadStreamRequests[ev.Id] = true; } tr.BodyText = body; } else if (codeStr == "IOCTL_KS_ENABLE_EVENT" && inBuf != null) { StringBuilder body = new StringBuilder (); body.AppendFormat ("[lpInBuffer]\r\nKSEVENT: {0} {1} {2}", inBuf.ReadGuid (), inBuf.ReadU32LE (), BitfieldToString (ksEventFlags, inBuf.ReadU32LE ())); string remainder = inBuf.ReadRemainingBytesAsHexDump (); if (remainder != null) body.AppendFormat ("\r\n{0}", remainder); if (outBufEnter != null) { body.Append ("\r\n\r\n[lpOutBuffer on entry]"); remainder = outBufEnter.ReadRemainingBytesAsHexDump (); if (remainder != null) body.AppendFormat ("\r\n{0}", remainder); } if (outBufLeave != null) { body.Append ("\r\n\r\n[lpOutBuffer on exit]"); remainder = outBufLeave.ReadRemainingBytesAsHexDump (); if (remainder != null) body.AppendFormat ("\r\n{0}", remainder); } tr.BodyText = body.ToString (); } else { List<string> blobs = new List<string> (); if (inBuf != null) blobs.Add (inBuf.ReadRemainingBytesAsHexDump ()); if (outBufEnter != null) blobs.Add (outBufEnter.ReadRemainingBytesAsHexDump ()); if (blobs.Count > 0) tr.BodyText = String.Join ("\r\n\r\n", blobs.ToArray ()); } return tr; }
private void VisualizeDump (Dump dump) { Dictionary<uint, VisualSession> sessions = new Dictionary<uint,VisualSession> (); foreach (KeyValuePair<uint, Event> pair in dump.Events) { Event ev = pair.Value; // HACK #1 //if (ev.ThreadId != 7028 && ev.ThreadId != 3152) // continue; //else if (ev.ThreadId == 7028 && ev.Id < 138) // continue; if (ev.Id > 2200) continue; VisualSession session; if (sessions.ContainsKey (ev.ThreadId)) session = sessions[ev.ThreadId]; else { session = new VisualSession (String.Format ("{0}", ev.ThreadId)); sessions[ev.ThreadId] = session; } VisualTransaction tr = null; XmlElement eventRoot = ev.Data; XmlNode node = eventRoot.SelectSingleNode ("/event/name"); if (node != null) { string[] tokens = node.InnerText.Trim ().Split (new string[] { "::" }, 2, StringSplitOptions.None); string funcNameShort = tokens[tokens.Length - 1]; if (funcNameShort == "DeviceIoControl") { tr = CreateTransactionFromDeviceIoControl (ev, eventRoot); } else if (funcNameShort == "GetOverlappedResult") { tr = CreateTransactionFromGetOverlappedResult (ev, eventRoot); } else if (funcNameShort == "KsCreatePin") { tr = CreateTransactionFromKsCreatePin (ev, eventRoot); } else if (funcNameShort == "KsOpenDefaultDevice") { tr = CreateTransactionFromKsOpenDefaultDevice (ev, eventRoot); } else if (funcNameShort == "CloseHandle") { tr = CreateTransactionFromCloseHandle (ev, eventRoot); } else { tr = new VisualTransaction (ev.Id, TransactionDirection.In, ev.Timestamp); tr.HeadlineText = funcNameShort; tr.AddHeaderField ("Id", ev.Id); } } else { tr = new VisualTransaction (ev.Id, ev.Timestamp); tr.HeadlineText = String.Format ("<{0}>", ev.Type); tr.AddHeaderField ("Id", ev.Id); if (ev.Type == DumpEventType.AsyncResult) { uint requestEventId = Convert.ToUInt32 (eventRoot.SelectSingleNode ("/event/requestId").InnerText); tr.AddHeaderField ("RequestId", requestEventId); if (pendingReadStreamRequests.ContainsKey (requestEventId)) { pendingReadStreamRequests.Remove (requestEventId); XmlNode dataNode = eventRoot.SelectSingleNode ("/event/data/value"); tr.BodyText = KsReadStreamDataToString (dataNode, "out"); } } } if (tr != null) session.Transactions.Add (tr); } VisualSession[] sessionsArray = new VisualSession[sessions.Count]; sessions.Values.CopyTo (sessionsArray, 0); view.Sessions = sessionsArray; pendingReadStreamRequests.Clear (); }
private VisualTransaction CreateTransactionFromCloseHandle (Event ev, XmlElement eventRoot) { string handleStr = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[1]/value").Attributes["value"].Value; if (!interestingHandles.Contains (handleStr)) return null; VisualTransaction tr = new VisualTransaction (ev.Id, TransactionDirection.In, ev.Timestamp); tr.AddHeaderField ("Id", ev.Id); string retValStr = eventRoot.SelectSingleNode ("/event/returnValue/value").Attributes["value"].Value; tr.ContextID = handleStr; tr.HeadlineText = String.Format ("CloseHandle ({0}) => {1}", handleStr, retValStr); return tr; }
private VisualTransaction CreateTransactionFromKsOpenDefaultDevice (Event ev, XmlElement eventRoot) { VisualTransaction tr = new VisualTransaction (ev.Id, TransactionDirection.In, ev.Timestamp); XmlNode node = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[1]/value/value"); Guid category = new Guid (Convert.FromBase64String (node.InnerText)); node = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[2]/value"); string access = node.Attributes["value"].Value; node = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[3]/value"); string deviceHandleStr = node.Attributes["value"].Value; node = eventRoot.SelectSingleNode ("/event/arguments[@direction='out']/argument[1]/value/value"); if (node != null) { tr.ContextID = node.Attributes["value"].Value; deviceHandleStr += String.Format (" => {0}", tr.ContextID); } string retValStr = eventRoot.SelectSingleNode ("/event/returnValue/value").Attributes["value"].Value; tr.HeadlineText = String.Format ("KsOpenDefaultDevice ({0}, {1}, {2}) => {3}", CategoryToString (category), access, deviceHandleStr, retValStr); tr.AddHeaderField ("Id", ev.Id); return tr; }
private VisualTransaction CreateTransactionFromKsCreatePin (Event ev, XmlElement eventRoot) { VisualTransaction tr = new VisualTransaction (ev.Id, TransactionDirection.In, ev.Timestamp); string retValStr = eventRoot.SelectSingleNode ("/event/returnValue/value").Attributes["value"].Value; string lastErrStr = ErrorCodeToString (Convert.ToUInt32 (eventRoot.SelectSingleNode ("/event/lastError").Attributes["value"].Value)); XmlNodeList inNodes = eventRoot.SelectNodes ("/event/arguments[@direction='in']/argument/value"); string filterHandle = inNodes[0].Attributes["value"].Value; string desiredAccess = inNodes[2].Attributes["value"].Value; string connHandle = ""; XmlNode outNode = eventRoot.SelectSingleNode ("/event/arguments[@direction='out']/argument/value/value"); if (outNode != null) { connHandle = " => " + outNode.Attributes["value"].Value; } tr.ContextID = filterHandle; tr.HeadlineText = String.Format ("KsCreatePin ({0}, &Connect, {1}, &ConnectionHandle{2}) => {3}", filterHandle, desiredAccess, connHandle, retValStr); tr.AddHeaderField ("Id", ev.Id); tr.AddHeaderField ("LastError", lastErrStr); StringBuilder body = new StringBuilder (); byte[] connBytes = Convert.FromBase64String (inNodes[1].SelectSingleNode ("value[@type='KSPIN_CONNECT']").InnerText); ByteArrayReader connReader = new ByteArrayReader (connBytes); body.Append ("[Connect]:\r\nKSPIN_CONNECT:"); body.AppendFormat ("\r\n Interface: ({0}, {1}, {2})", connReader.ReadGuid (), connReader.ReadU32LE (), connReader.ReadU32LE ()); body.AppendFormat ("\r\n Medium: ({0}, {1}, {2})", connReader.ReadGuid (), connReader.ReadU32LE (), connReader.ReadU32LE ()); body.AppendFormat ("\r\n PinId: {0}", connReader.ReadU32LE ()); body.AppendFormat ("\r\n PinToHandle: {0}", connReader.ReadU32LE ()); body.AppendFormat ("\r\n Priority: ({0}, {1})", connReader.ReadU32LE (), connReader.ReadU32LE ()); if (connReader.Remaining > 0) throw new Exception ("KSPIN_CONNECT parse error"); byte[] formatRaw = Convert.FromBase64String (inNodes[1].SelectSingleNode ("value[@type='KSDATAFORMAT']").InnerText); ByteArrayReader formatReader = new ByteArrayReader (formatRaw); body.AppendFormat ("\r\nKSDATAFORMAT:{0}", KsDataFormatToString (formatReader)); tr.BodyText = body.ToString (); return tr; }
private VisualTransaction CreateTransactionFromGetOverlappedResult (Event ev, XmlElement eventRoot) { VisualTransaction tr = new VisualTransaction (ev.Id, TransactionDirection.In, ev.Timestamp); string retValStr = eventRoot.SelectSingleNode ("/event/returnValue/value").Attributes["value"].Value; string lastErrStr = ErrorCodeToString (Convert.ToUInt32 (eventRoot.SelectSingleNode ("/event/lastError").Attributes["value"].Value)); tr.HeadlineText = String.Format ("GetOverlappedResult ({0}) => {1}", FunctionCallArgListToString (eventRoot), retValStr.ToUpper ()); tr.AddHeaderField ("Id", ev.Id); tr.AddHeaderField ("LastError", lastErrStr); XmlNode handleNode = eventRoot.SelectSingleNode ("/event/arguments[@direction='in']/argument[1]/value"); tr.ContextID = handleNode.Attributes["value"].Value; return tr; }
public void UpdateLayout() { int x = ColumnsStartPos; ruler.Clear(); // First off, create a flat list of all transactions in all sessions, // and make a lookup table for each transaction's column index List <VisualTransaction> transactions = new List <VisualTransaction>(); Dictionary <VisualTransaction, int> transactionToColIndex = new Dictionary <VisualTransaction, int>(); int colIndex = 0; foreach (VisualSession session in msv.Sessions) { foreach (VisualTransaction transaction in session.Transactions) { transactions.Add(transaction); transactionToColIndex.Add(transaction, colIndex); } colIndex++; } // Sort the transactions by StartTime transactions.Sort(); int y = 0; // Now it's time to rock 'n roll! while (transactions.Count > 0) { // Find all transactions with the same time and the height of the highest one of them List <VisualTransaction> sameTime = new List <VisualTransaction>(1); DateTime curTime = transactions[0].StartTime; int highest = 0; for (int i = 0; i < transactions.Count; i++) { VisualTransaction curTransaction = transactions[i]; if (sameTime.Count > 0) { if (curTransaction.StartTime != curTime) { break; } } sameTime.Add(curTransaction); if (curTransaction.Height > highest) { highest = curTransaction.Height; } } // Remove them from the list transactions.RemoveRange(0, sameTime.Count); Dictionary <int, int> columnOffsets = new Dictionary <int, int>(); // Lay them out foreach (VisualTransaction transaction in sameTime) { colIndex = transactionToColIndex[transaction]; transaction.Parent = this; transaction.Left = ColumnsStartPos + (colIndex * (msv.ColumnWidth + msv.ColumnSpacing)); int colY = 0; if (columnOffsets.ContainsKey(colIndex)) { colY = columnOffsets[colIndex] + 10; } transaction.Top = y + colY; columnOffsets[colIndex] = colY + transaction.Height; } foreach (int offset in columnOffsets.Values) { if (offset > highest) { highest = offset; } } y += highest + 10; ruler.AddMark(sameTime[0].StartTime, highest + 10); } realWidth = ruler.Width + (msv.Sessions.Length * (msv.ColumnWidth + msv.ColumnSpacing)); realHeight = y; if (LayoutChanged != null) { LayoutChanged(this, new EventArgs()); } }