private void ParseControlCommand() { List <PacketSlice> slices = new List <PacketSlice>(2); UInt16 cmdTypeRaw, cmdLen; RRACCommand cmdType; string cmdTypeStr; List <PacketSlice> cmdTypeSlices = new List <PacketSlice>(1); List <PacketSlice> cmdLenSlices = new List <PacketSlice>(1); UInt32 u32; byte[] bytes; try { // Command type cmdTypeRaw = stream.ReadU16(cmdTypeSlices); // Command length cmdLen = stream.ReadU16(cmdLenSlices); ParseCommandType(cmdTypeRaw, out cmdType, out cmdTypeStr); TransactionNode cmd = new TransactionNode(cmdTypeStr); cmd.AddField("CommandType", cmdTypeStr, "Command type.", cmdTypeSlices); cmd.AddField("CommandLength", Convert.ToString(cmdLen), "Number of bytes following this field.", cmdLenSlices); if (cmdType != RRACCommand.Response) { cmd.Description = cmd.Name; } bool handled = true; switch (cmdType) { case RRACCommand.GetMetaData: u32 = stream.ReadU32(slices); cmd.AddField("GetMask", Util.FormatFlags(u32), "A bitmask specifying what metadata to get.", slices); pendingReplies[cmdType] = new GetMetaDataCmd(u32); break; case RRACCommand.SetMetaData: u32 = stream.ReadU32(slices); cmd.AddField("PayloadSize", Convert.ToString(u32), "The number of bytes of payload following this field.", slices); u32 = stream.ReadU32(slices); cmd.AddField("MagicValue", Util.FormatFlags(u32), "Magic value that must be 0xF0000001.", slices); u32 = stream.ReadU32(slices); cmd.AddField("SetOid", FormatSetType(u32), "The identifier of the object to set.", slices); pendingReplies[cmdType] = new SetMetaDataCmd(u32); switch (u32) { case SetMetaDataCmd.TYPE_BORING_SSPIDS: bytes = stream.ReadBytes(16, slices); cmd.AddField("FourUnknownDWORDs", Util.FormatByteArray(bytes), "Four unknown DWORDs.", slices); UInt32 numObjects = stream.ReadU32(slices); cmd.AddField("NumBoringObjects", Convert.ToString(numObjects), "Number of boring objects following this field.", slices); TransactionNode boringObjects = new TransactionNode("BoringObjects"); cmd.AddChild(boringObjects); for (int i = 0; i < numObjects; i++) { u32 = stream.ReadU32(slices); boringObjects.AddField(Convert.ToString(i), Util.FormatFlags(u32), "Object type ID.", slices); } break; default: handled = false; cmdLen -= 4 * 3; break; } break; case RRACCommand.Notify: UInt32 notifyType = stream.ReadU32(slices); cmd.AddField("NotifyType", FormatNotifyType(notifyType), "Type of notification.", slices); switch (notifyType) { case NotifyCmd.TYPE_PARTNERSHIPS: u32 = stream.ReadU32(slices); cmd.AddField("Unknown1", Util.FormatFlags(u32), "Unknown field 1.", slices); u32 = stream.ReadU32(slices); cmd.AddField("Unknown2", Util.FormatFlags(u32), "Unknown field 2.", slices); u32 = stream.ReadU32(slices); cmd.AddField("Size", Convert.ToString(u32), "Size of the remaining fields.", slices); u32 = stream.ReadU32(slices); cmd.AddField("PCur", Convert.ToString(u32), "Current partner index.", slices); u32 = stream.ReadU32(slices); cmd.AddField("P1", Util.FormatFlags(u32), "Partner 1 ID.", slices); u32 = stream.ReadU32(slices); cmd.AddField("P2", Util.FormatFlags(u32), "Partner 2 ID.", slices); break; default: handled = false; cmdLen -= 4; break; } break; case RRACCommand.Response: ParseCommandReply(cmd, cmdLen); break; default: handled = false; break; } if (!handled) { if (cmdLen > 0) { bytes = stream.ReadBytes((int)cmdLen, slices); cmd.AddField("UnknownData", Util.FormatByteArray(bytes), "Unknown data.", slices); } } AddTransactionNode(cmd); } catch (EndOfStreamException e) { throw new StreamSessionParseError(e.Message); } }
protected void ParseCommandReply(TransactionNode cmd, int cmdLen) { UInt32 u32; byte[] bytes; string str; List <PacketSlice> slices = new List <PacketSlice>(2); UInt32 replyCmdTypeRaw; RRACCommand replyCmdType; string replyCmdTypeStr; replyCmdTypeRaw = stream.ReadU32(slices); ParseCommandType((UInt16)replyCmdTypeRaw, out replyCmdType, out replyCmdTypeStr); cmd.AddField("ReplyToCommand", replyCmdTypeStr, "Command which this is a reply to.", slices); int replyLen = cmdLen - 4; if (replyCmdType != RRACCommand.UNKNOWN) { if (!pendingReplies.ContainsKey(replyCmdType)) { throw new StreamSessionParseError(String.Format( "Got reply to a command we don't know about: {0} ({1})", replyCmdType, replyCmdTypeRaw)); } } bool handled = true; cmd.Description = String.Format("{0} to {1}", cmd.Name, replyCmdTypeStr); u32 = stream.ReadU32(slices); cmd.AddField("Result", Util.FormatValue(u32), "Result of the request.", slices); u32 = stream.ReadU32(slices); cmd.AddField("ResponseDataSize", Util.FormatValue(u32), "Number of bytes of response data following the next field.", slices); u32 = stream.ReadU32(slices); cmd.AddField("Unknown1", Util.FormatValue(u32), "Unknown field.", slices); replyLen -= 3 * 4; if (replyCmdType == RRACCommand.GetMetaData) { GetMetaDataCmd listCmd = pendingReplies[replyCmdType] as GetMetaDataCmd; switch (listCmd.Flags) { case 0x7c1: u32 = stream.ReadU32(slices); cmd.AddField("MagicValue", Util.FormatFlags(u32), "Magic value that must be 0xF0000001.", slices); u32 = stream.ReadU32(slices); cmd.AddField("Success", Util.FormatBool(u32), "A value that must be TRUE, probably signifying whether the command succeeded.", slices); u32 = stream.ReadU32(slices); cmd.AddField("HasBody", Util.FormatBool(u32), "A BOOL indicating if the response contains a body or is empty.", slices); u32 = stream.ReadU32(slices); cmd.AddField("ResponseTo", Util.FormatValue(u32), "Two to the power of the position of the bit to which this is a response. So for instance " + "if this is the response to bit 4, this field contains the value 16.", slices); UInt32 typeCount = stream.ReadU32(slices); cmd.AddField("TypeCount", Convert.ToString(typeCount), "Number of types following.", slices); TransactionNode objTypes = new TransactionNode("ObjectTypes"); cmd.AddChild(objTypes); for (int i = 0; i < typeCount; i++) { TransactionNode node = new TransactionNode( Convert.ToString(i)); u32 = stream.ReadU32(slices); node.AddField("Flags", Util.FormatValue(u32), "Unknown.", slices); str = stream.ReadCString(200, slices); node.AddField("Name1", str, "Name of the object type.", slices); str = stream.ReadCString(80, slices); node.AddField("Name2", str, "Name/description of the object type.", slices); str = stream.ReadCString(80, slices); node.AddField("Name3", str, "Another name/description of the object type (usually blank).", slices); u32 = stream.ReadU32(slices); node.AddField("SSPId", Util.FormatFlags(u32), "Identifier of the object type.", slices); u32 = stream.ReadU32(slices); node.AddField("Count", Util.FormatValue(u32), "Number of items of this object type on the device.", slices); u32 = stream.ReadU32(slices); node.AddField("TotalSize", Util.FormatValue(u32), "Total size of the items of this object type on the device.", slices); List <PacketSlice> allSlices = new List <PacketSlice>(2); UInt32 timeLow = stream.ReadU32(slices); allSlices.AddRange(slices); UInt32 timeHigh = stream.ReadU32(slices); allSlices.AddRange(slices); UInt64 time = (UInt64)timeLow & ((UInt64)timeHigh << 32); node.AddField("FileTime", String.Format("0x{0:x16}", time), "Time of last modification of any of the items of this object type on the device (?).", allSlices); objTypes.AddChild(node); } break; default: handled = false; break; } } else { handled = false; } if (!handled) { if (replyLen > 0) { bytes = stream.ReadBytes(replyLen, slices); cmd.AddField("UnknownReplyData", Util.FormatByteArray(bytes), "Unknown reply data.", slices); } } pendingReplies.Remove(replyCmdType); }
private void ParseControlCommand() { List<PacketSlice> slices = new List<PacketSlice>(2); UInt16 cmdTypeRaw, cmdLen; RRACCommand cmdType; string cmdTypeStr; List<PacketSlice> cmdTypeSlices = new List<PacketSlice>(1); List<PacketSlice> cmdLenSlices = new List<PacketSlice>(1); UInt32 u32; byte[] bytes; try { // Command type cmdTypeRaw = stream.ReadU16(cmdTypeSlices); // Command length cmdLen = stream.ReadU16(cmdLenSlices); ParseCommandType(cmdTypeRaw, out cmdType, out cmdTypeStr); TransactionNode cmd = new TransactionNode(cmdTypeStr); cmd.AddField("CommandType", cmdTypeStr, "Command type.", cmdTypeSlices); cmd.AddField("CommandLength", Convert.ToString(cmdLen), "Number of bytes following this field.", cmdLenSlices); if (cmdType != RRACCommand.Response) { cmd.Description = cmd.Name; } bool handled = true; switch (cmdType) { case RRACCommand.GetMetaData: u32 = stream.ReadU32(slices); cmd.AddField("GetMask", Util.FormatFlags(u32), "A bitmask specifying what metadata to get.", slices); pendingReplies[cmdType] = new GetMetaDataCmd(u32); break; case RRACCommand.SetMetaData: u32 = stream.ReadU32(slices); cmd.AddField("PayloadSize", Convert.ToString(u32), "The number of bytes of payload following this field.", slices); u32 = stream.ReadU32(slices); cmd.AddField("MagicValue", Util.FormatFlags(u32), "Magic value that must be 0xF0000001.", slices); u32 = stream.ReadU32(slices); cmd.AddField("SetOid", FormatSetType(u32), "The identifier of the object to set.", slices); pendingReplies[cmdType] = new SetMetaDataCmd(u32); switch (u32) { case SetMetaDataCmd.TYPE_BORING_SSPIDS: bytes = stream.ReadBytes(16, slices); cmd.AddField("FourUnknownDWORDs", Util.FormatByteArray(bytes), "Four unknown DWORDs.", slices); UInt32 numObjects = stream.ReadU32(slices); cmd.AddField("NumBoringObjects", Convert.ToString(numObjects), "Number of boring objects following this field.", slices); TransactionNode boringObjects = new TransactionNode("BoringObjects"); cmd.AddChild(boringObjects); for (int i = 0; i < numObjects; i++) { u32 = stream.ReadU32(slices); boringObjects.AddField(Convert.ToString(i), Util.FormatFlags(u32), "Object type ID.", slices); } break; default: handled = false; cmdLen -= 4 * 3; break; } break; case RRACCommand.Notify: UInt32 notifyType = stream.ReadU32(slices); cmd.AddField("NotifyType", FormatNotifyType(notifyType), "Type of notification.", slices); switch (notifyType) { case NotifyCmd.TYPE_PARTNERSHIPS: u32 = stream.ReadU32(slices); cmd.AddField("Unknown1", Util.FormatFlags(u32), "Unknown field 1.", slices); u32 = stream.ReadU32(slices); cmd.AddField("Unknown2", Util.FormatFlags(u32), "Unknown field 2.", slices); u32 = stream.ReadU32(slices); cmd.AddField("Size", Convert.ToString(u32), "Size of the remaining fields.", slices); u32 = stream.ReadU32(slices); cmd.AddField("PCur", Convert.ToString(u32), "Current partner index.", slices); u32 = stream.ReadU32(slices); cmd.AddField("P1", Util.FormatFlags(u32), "Partner 1 ID.", slices); u32 = stream.ReadU32(slices); cmd.AddField("P2", Util.FormatFlags(u32), "Partner 2 ID.", slices); break; default: handled = false; cmdLen -= 4; break; } break; case RRACCommand.Response: ParseCommandReply(cmd, cmdLen); break; default: handled = false; break; } if (!handled) { if (cmdLen > 0) { bytes = stream.ReadBytes((int)cmdLen, slices); cmd.AddField("UnknownData", Util.FormatByteArray(bytes), "Unknown data.", slices); } } AddTransactionNode(cmd); } catch (EndOfStreamException e) { throw new StreamSessionParseError(e.Message); } }