public void TestByteStreamReading() { // Test bytes using (ByteStream stream = new ByteStream(testData)) { for (int i = 0; i < testData.Length; i++) { Assert.AreEqual(testData[i], stream.ReadByte(), "ReadByte returned incorrect value"); } } // Test ushorts using (ByteStream stream = new ByteStream(testData)) { Assert.AreEqual(0x0841, stream.ReadUshort()); Assert.AreEqual(0x6472, stream.ReadUshort()); Assert.AreEqual(0x6965, stream.ReadUshort()); Assert.AreEqual(0x6e6e, stream.ReadUshort()); } // Test uints using (ByteStream stream = new ByteStream(testData)) { Assert.AreEqual(0x08416472, stream.ReadUint()); Assert.AreEqual(0x69656e6e, stream.ReadUint()); } // Test string using (ByteStream stream = new ByteStream(testData)) { Assert.AreEqual("Adrienne", stream.ReadString(stream.ReadByte(), Encoding.ASCII)); } }
/// <summary> /// Processes the received message /// </summary> private void EndReadHeader(IAsyncResult res) { byte[] odcheader = null; try { odcheader = (byte[])res.AsyncState; socket.EndRead(res); } catch (Exception ex) { Logging.WriteString(String.Format("Exception in DirectIMConnection.EndReadHeader: {0}", ex)); DisconnectFromServer(true); } // Verify that this is an ODC header if (Encoding.ASCII.GetString(odcheader, 0, 4) != "ODC2") { // Huh... return; } ushort datalen = (ushort)((odcheader[4] << 8) | odcheader[5]); if (datalen < 6) { // Oh return; } ByteStream messageheader = ReadPacket(datalen - 6); if (messageheader == null) { // Tum ta tiddily tumpa turr return; } // Extract various members from the message header messageheader.AdvanceToPosition(6); byte[] cookie = messageheader.ReadByteArray(8); messageheader.AdvanceToPosition(22); uint datalength = messageheader.ReadUint(); ushort charset = messageheader.ReadUshort(); ushort subcharset = messageheader.ReadUshort(); DirectIMFlags flags = (DirectIMFlags)messageheader.ReadUint(); messageheader.AdvanceToPosition(38); string screenname = messageheader.ReadString(16, Encoding.ASCII); if ((flags & DirectIMFlags.TypingPacket) != 0) { // Determine the type of typing packet this is if ((flags & DirectIMFlags.UserTyping) != 0) { //_parent.OnTypingNotification(screenname, TypingNotification.TypingStarted); } else if ((flags & DirectIMFlags.UserTyped) != 0) { //_parent.OnTypingNotification(screenname, TypingNotification.TextTyped); } else { // TODO: restore these // _parent.OnTypingNotification(screenname, TypingNotification.TypingFinished); } // Probably no data, but read it in anyway to make sure we're not missing anything ReadPacket((int)datalength); } else if ((flags & DirectIMFlags.ConfirmationPacket) != 0 && datalength == 0) { // Do we really do anything here? I don't think so. } else { // Create a new instant message DirectIM dim = new DirectIM(Other.ScreenName, this); dim.Cookie = csammisrun.OscarLib.Cookie.GetReceivedCookie(cookie); dim.IsAutoResponse = ((flags & DirectIMFlags.AutoResponse) != 0); dim.Encoding = IM.GetEncodingFromCharset(charset, subcharset); // Create a spooler to incrementally read in a DirectIM packet, // then restart the read sequence when it's done DirectIMDataReader reader = new DirectIMDataReader(this, dim); reader.DataReaderComplete += new DataReaderCompleteHandler(delegate { parent.OnDirectIMReceived( reader.Message); reader.Dispose(); ReadHeader(); }); reader.Read(datalength); return; } // Restart the read sequence ReadHeader(); }
/// <summary> /// Creates a Capabilities enumeration from a CLSID array /// </summary> /// <param name="buffer">A byte array containing the CLSIDs of the capabilities</param> /// <returns>A Capabilities enumeration</returns> public static Capabilities ProcessCLSIDList(byte[] buffer) { Capabilities retval = Capabilities.None; if (buffer == null) { return(retval); } using (ByteStream bstream = new ByteStream(buffer)) { uint word1 = 0; uint word2 = 0; uint word3 = 0; uint word4 = 0; while (bstream.HasMoreData) { word1 = bstream.ReadUint(); word2 = bstream.ReadUint(); word3 = bstream.ReadUint(); word4 = bstream.ReadUint(); if (word1 == 0x09461341 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.VoiceChat; } else if (word1 == 0x09461342 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.DirectPlay; } else if (word1 == 0x09461343 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.SendFiles; } else if (word1 == 0x09461344 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.RouteFinder; } else if (word1 == 0x09461345 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.DirectIM; } else if (word1 == 0x09461346 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.BuddyIcon; } else if (word1 == 0x09461347 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.StocksAddIn; } else if (word1 == 0x09461348 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.GetFiles; } else if (word1 == 0x09461349 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.Channel2Ext; } else if (word1 == 0x0946134A && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.Games; } else if (word1 == 0x0946134B && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.BuddyListTransfer; } else if (word1 == 0x0946134D && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.AIMtoICQ; } else if (word1 == 0x0946134E && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.UTF8; } else if (word1 == 0x09460000 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.iChat; } else if (word1 == 0x97B12751 && word2 == 0x243C4334 && word3 == 0xAD22D6AB && word4 == 0xF73F1492) { retval |= Capabilities.RTF; } else if (word1 == 0xA0E93F37 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.Unknown1; } else if (word1 == 0x10CF40D1 && word2 == 0x4C7F11D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.Unknown2; } else if (word1 == 0x2E7A6475 && word2 == 0xFADF4DC8 && word3 == 0x886FEA35 && word4 == 0x95FDB6DF) { retval |= Capabilities.Unknown3; } else if (word1 == 0x563FC809 && word2 == 0x0B6f41BD && word3 == 0x9F794226 && word4 == 0x09DFA2F3) { retval |= Capabilities.Unknown4; } else if (word1 == 0x748F2420 && word2 == 0x628711D1 && word3 == 0x82224445 && word4 == 0x53540000) { retval |= Capabilities.Chat; } else if (word1 == 0xF2E7C7F4 && word2 == 0xFEAD4DFB && word3 == 0xB2353679 && word4 == 0x8BDF0000) { retval |= Capabilities.TrillianSecureIM; } else if (word1 == 0x97B12751 && word2 == 0x243C4334 && word3 == 0xAD22D6AB && word4 == 0xF73F1400) { retval |= Capabilities.SIMKopete; } else if (word1 == 0x09191982 && word2 == 0xDEADBEEF && word2 == 0xCAFE4445 && word4 == 0x53540000) { retval |= Capabilities.OscarLib; } } } return(retval); }
/// <summary> /// Performs TLV 0x2711 processing for direct connect (sendfiles, DirectIM) negotiation /// </summary> private void ProcessDirectConnectionRequest(DirectConnection conn, ByteStream stream) { if (conn.Type == RendezvousType.Accept) { // They're accepting, which means we're going to get a connection on the // listener socket set up in FileTransferManager. Do nothing here } else if (conn.Type == RendezvousType.Cancel) { DirectConnection cancelled = parent.Connections.GetDirectConnectionByCookie(conn.Cookie); if (cancelled != null) { if (cancelled is FileTransferConnection) { (cancelled as FileTransferConnection).CancelFileTransfer( "Remote user cancelled direct connection"); } else if (cancelled is DirectIMConnection) { parent.OnDirectIMSessionCancelled(cancelled, "Remote user cancelled direct connection"); } } return; } else if (conn.Type == RendezvousType.Invite) { // AIM sends a type 0x0000 when accepting...huh. if (conn.Sequence == RendezvousSequence.DirectOrStage1) { if (stream.HasMoreData && conn is FileTransferConnection) { FileTransferConnection ftconn = conn as FileTransferConnection; ftconn.SubType = stream.ReadUshort(); ftconn.TotalFiles = stream.ReadUshort(); ftconn.TotalFileSize = stream.ReadUint(); int strlen = 0; byte[] servicedata = stream.ReadByteArrayToEnd(); // The filename in an RD invite is null-terminated ASCII while (servicedata[strlen++] != 0x00) ; ftconn.FileHeader.Name = Encoding.ASCII.GetString(servicedata, 0, strlen - 1); } parent.OnDirectConnectionRequestReceived(conn.Cookie); } else if (conn.Sequence == RendezvousSequence.Stage2) { // The receipient of a previous invite wants a stage 2 proxy redirection // Shut down the server socket, we won't be getting a connection on it conn.StopListeningSocket(); SendDirectConnectionAccept(conn); conn.StartSendThroughStage2AolProxy(); } else if (conn.Sequence == RendezvousSequence.Stage3) { // Direct connection and proxy 2 failed, the sender's trying to proxy it now conn.Method = DirectConnectionMethod.Proxied; conn.ConnectToServer(); } } }