//Method called on new event public static void EventCallback(TraceEvent eventData) { if (eventData.EventDataLength <= 0) { return; } UsbData usbdata = null; string output = ""; try { if (eventData.PayloadNames.Contains("fid_USBPORT_URB_BULK_OR_INTERRUPT_TRANSFER") || eventData.PayloadNames.Contains("fid_UCX_URB_BULK_OR_INTERRUPT_TRANSFER")) { usbdata = GetData(eventData); } if (usbdata == null) { return; } string idstr = ""; if (usbdata.usbver == 2) { idstr = String.Format("VID_0x{0} PID_0x{1}", usbdata.vid.ToString("X4"), usbdata.pid.ToString("X4")); } //determine what device data comes from and actual length of data (for USB 2.0) bool IsMouse = false; uint len = usbdata.datalen; //(mouse data is 4 or 5 bytes, keyboard - 8 bytes) if (usbdata.datalen < 8) { IsMouse = true; len = usbdata.datalen; } else { if (usbdata.usbver == 2 && usbdata.data[0] == 0 && usbdata.data[1] == 0 && usbdata.data[2] == 4 && usbdata.data[3] == 0) { IsMouse = true; len = 4; } else if (usbdata.usbver == 2 && usbdata.data[0] == 5 && usbdata.data[1] == 0) { IsMouse = true; len = 5; } else { IsMouse = false; } } //Print data if (IsMouse == false && usbdata.data[1] == 0) //second byte must be zero for keyboard { var arr = ParseKeys(usbdata.data); output = String.Format("{0} {1} Keyboard ", usbdata.time, idstr); if (arr != null) { foreach (var s in arr) { output += s + " "; } } } else { sbyte b; output = String.Format("{0} {1} Mouse ", usbdata.time, idstr); uint i_start = usbdata.datalen - len; uint index; bool action = false; for (uint i = i_start; i < usbdata.datalen; i++) { index = i - i_start; b = (sbyte)usbdata.data[i]; switch (index) { case 0: //first byte defines pressed buttons if ((usbdata.data[i] & 0x01) > 0) { output += "Left button press "; action = true; } if ((usbdata.data[i] & 0x02) > 0) { output += "Right button press "; action = true; } if ((usbdata.data[i] & 0x04) > 0) { output += "Middle button press "; action = true; } if ((usbdata.data[i] & 0x08) > 0) { output += "Special button press "; action = true; } if ((usbdata.data[i] & 0xf0) > 0) { output += "Special button press "; action = true; } break; case 1: //second byte is x movement if (usbdata.data[i] != 0 || usbdata.data[i + 1] != 0) { output += "move: "; action = true; } if (usbdata.data[i] != 0) { output += "dx=" + b.ToString() + " "; } break; case 2: //third byte is y movement if (usbdata.data[i] != 0) { output += "dy=" + b.ToString() + " "; } break; case 3: //4th byte (if present) is wheel movement if (usbdata.data[i] != 0) { output += "Wheel Move: Delta=" + b.ToString() + " "; action = true; } break; } /*output += b.ToString() + " ";*/ } if (!action) { output += "Button release"; } } } catch (Exception ex) { output = "Error in callback: " + ex.GetType().ToString() + " " + ex.Message; } if (output != "") { Instance.Print(output); } //datastore.Add(usbdata); }
//Parses usb event data private static UsbData GetData(TraceEvent eventData) { ulong hndl; object field; uint vid = 0, pid = 0; byte usbver = 0; //try to determine device handle and IDs field = GetItem(eventData, "fid_USBPORT_Device"); if (field != null) { Dictionary <string, string> deviceInfo = _expose(field); if (!ulong.TryParse(deviceInfo["DeviceHandle"], out hndl) && hndl <= 0) { return(null); } vid = UInt32.Parse(deviceInfo["idVendor"]); pid = UInt32.Parse(deviceInfo["idProduct"]); } else { hndl = (ulong)GetItem(eventData, "fid_PipeHandle"); if (hndl <= 0) { return(null); } } //try to get event parameters field = GetItem(eventData, "fid_USBPORT_URB_BULK_OR_INTERRUPT_TRANSFER"); //2.0 usbver = 2; if (field == null) { field = GetItem(eventData, "fid_UCX_URB_BULK_OR_INTERRUPT_TRANSFER"); //3.0 usbver = 3; } Dictionary <string, string> urb = _expose(field);//transform parameter string to dictionary //determine transferred data length int xferDataSize = 0; if (!int.TryParse(urb["fid_URB_TransferBufferLength"], out xferDataSize)) { return(null); } if ((xferDataSize > 8) && (usbver == 2)) { xferDataSize = 8; //USB 2.0 sometimes gives wrong size } if (xferDataSize > 8) { return(null); //data is too large for mouse / keyboard } byte[] data2 = eventData.EventData(); byte[] xferData = new byte[xferDataSize]; Array.Copy(data2, eventData.EventDataLength - xferDataSize, xferData, 0, xferDataSize); bool HasNonZero = false; for (int i = 0; i < xferDataSize; i++) { if (xferData[i] != 0) { HasNonZero = true; break; } } if (HasNonZero == false) { return(null); //data is empty } /* Construct UsbData object*/ UsbData data = new UsbData(eventData.TimeStamp, hndl, xferData); data.usbver = usbver; data.datalen = (uint)xferDataSize; data.vid = vid; data.pid = pid; return(data); }