internal static SMBMessage[] CreateChunkedMessages(byte[] messageObject) { int numberOfMessages = (messageObject.Length / maxMessageSize) + 1; SMBMessage[] results = new SMBMessage[numberOfMessages]; string id = Guid.NewGuid().ToString(); for (int i = 0; i < results.Length; i++) { SMBMessage msg = new SMBMessage() { MessageID = id, MaxMessages = numberOfMessages, MessageType = "chunked_message", MessageNumber = i }; byte[] msgData; if ((i + 1) == results.Length) { int bytesToCopy = messageObject.Length - (maxMessageSize * (results.Length - 1)); msgData = new byte[bytesToCopy]; System.Buffer.BlockCopy(messageObject, i * maxMessageSize, msgData, 0, bytesToCopy); } else { msgData = new byte[maxMessageSize]; System.Buffer.BlockCopy(messageObject, i * maxMessageSize, msgData, 0, maxMessageSize); } msg.MessageObject = msgData; results[i] = msg; } return(results); }
// Chunked send internal bool Send(string id, string message) { SMBMessage[] messagesToSend; string chunkGuidString; int i = 0; int curIndex = 0; chunkGuidString = Guid.NewGuid().ToString(); List <SMBMessage> smbMsgs = new List <SMBMessage>(); do { i++; string part; if (curIndex + ChunkSize >= message.Length) { part = message.Substring(curIndex, message.Length - curIndex); } else { part = message.Substring(curIndex, ChunkSize); } curIndex += ChunkSize; smbMsgs.Add(new SMBMessage() { MessageType = string.Format("chunk_{0}_{1}", chunkGuidString, i), MessageObject = Encoding.UTF8.GetBytes(cryptor.Encrypt(part)) }); } while (curIndex < message.Length); messagesToSend = smbMsgs.ToArray(); try { writeMutex.WaitOne(); if (messagesToSend.Length > 1) { string chunkRegistrationMessage = String.Format("{0}_{1}", chunkGuidString, messagesToSend.Length); string chunkTitle = "new_chunked_message"; SMBMessage msg = new SMBMessage() { MessageObject = Encoding.UTF8.GetBytes(cryptor.Encrypt(chunkRegistrationMessage)), MessageType = chunkTitle }; bf.Serialize(PipeStream, msg); } for (int j = 0; j < messagesToSend.Length; j++) { bf.Serialize(PipeStream, messagesToSend[j]); } } finally { writeMutex.ReleaseMutex(); } return(true); }
internal SMBMessage ReadMessage() { SMBMessage msg = new SMBMessage(); try { readMutex.WaitOne(); msg = (SMBMessage)bf.Deserialize(PipeStream); if (msg.MessageType == "new_chunked_message") { string info = cryptor.Decrypt(Encoding.UTF8.GetString((byte[])msg.MessageObject)); string[] infoParts = info.Split('_'); if (infoParts.Length != 2) { throw new Exception("Invalid format of new_chunked_message"); } string guid = infoParts[0]; string lengthStr = infoParts[1]; int length = 0; if (!int.TryParse(lengthStr, out length)) { throw new Exception(String.Format("Failed to convert {0} to int", lengthStr)); } byte[][] smbMessages = new byte[length][]; int finalArrayLength = 0; for (int i = 0; i < length; i++) { msg = (SMBMessage)bf.Deserialize(PipeStream); infoParts = msg.MessageType.Split('_'); if (infoParts.Length != 3) { throw new Exception("Received out of sequence message."); } if (infoParts[1] != guid) { throw new Exception("Received out of sequence message due to GUID mismatch."); } int index = 0; if (!int.TryParse(infoParts[2], out index)) { throw new Exception(String.Format("Invalid index given for chunked message: {0}", infoParts[2])); } smbMessages[index] = (byte[])msg.MessageObject; finalArrayLength += ((byte[])msg.MessageObject).Length; } byte[] finalArray = new byte[finalArrayLength]; int lastIndex = 0; for (int i = 0; i < smbMessages.Length; i++) { System.Array.Copy(smbMessages[i], 0, finalArray, lastIndex, smbMessages[i].Length); lastIndex += smbMessages[i].Length; } msg.MessageObject = finalArray; msg.MessageType = ""; } } finally { readMutex.ReleaseMutex(); } return(msg); }