Beispiel #1
0
        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);
        }