/// <summary>
        /// to decode the smb data: from the general SmbDada to the concrete Smb Data.
        /// </summary>
        /// <exception cref="NotImplementedException">
        /// TD did not define the SmbParameters for Lan Manager Dialect.
        /// </exception>
        /// <exception cref="NotSupportedException">Unknow SmbParameters structure.</exception>
        protected override void DecodeData()
        {
            if (this.SmbDataBlock.ByteCount > 0)
            {
                this.smbData.ByteCount = this.smbDataBlock.ByteCount;

                if (this.smbParametersBlock.WordCount == WordCountOfNtLanManager)
                {
                    using (MemoryStream stream = new MemoryStream(this.smbDataBlock.Bytes))
                    {
                        using (Channel channel = new Channel(null, stream))
                        {
                            this.smbData.ServerGuid   = channel.Read <Guid>();
                            this.smbData.SecurityBlob = channel.ReadBytes(this.smbData.ByteCount
                                                                          - CifsMessageUtils.GetSize <Guid>(this.smbData.ServerGuid));
                        }
                    }
                }
                else if (this.smbParametersBlock.WordCount == WordCountOfLanManager)
                {
                    throw new NotImplementedException("TD did not define the SmbParameters for Lan Manager Dialect.");
                }
                else if (this.smbParametersBlock.WordCount != WordCountOfCoreProtocol)
                {
                    throw new NotSupportedException("Unknow SmbParameters structure.");
                }
            }
            else
            {
                this.smbData.ByteCount = this.SmbDataBlock.ByteCount;
            }
        }
        /// <summary>
        /// to decode the smb parameters: from the general SmbParameters to the concrete Smb Parameters.
        /// </summary>
        protected override void DecodeParameters()
        {
            // When a client requests extended information, the word count must be 42
            if (this.smbParametersBlock.WordCount == CREATE_EXTENDED_INFORMATION_RESPONSE_LENGTH)
            {
                SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters param =
                    new SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters();

                using (MemoryStream stream = new MemoryStream(
                           CifsMessageUtils.ToBytesArray <ushort>(this.smbParametersBlock.Words)))
                {
                    using (Channel channel = new Channel(null, stream))
                    {
                        param.WordCount         = this.smbParametersBlock.WordCount;
                        param.AndXCommand       = channel.Read <SmbCommand>();
                        param.AndXReserved      = channel.Read <byte>();
                        param.AndXOffset        = channel.Read <ushort>();
                        param.OplockLevel       = channel.Read <OplockLevelValue>();
                        param.FID               = channel.Read <ushort>();
                        param.CreationAction    = channel.Read <uint>();
                        param.CreateTime        = channel.Read <Cifs.FileTime>();
                        param.LastAccessTime    = channel.Read <Cifs.FileTime>();
                        param.LastWriteTime     = channel.Read <Cifs.FileTime>();
                        param.LastChangeTime    = channel.Read <Cifs.FileTime>();
                        param.ExtFileAttributes = channel.Read <uint>();
                        param.AllocationSize    = channel.Read <ulong>();
                        param.EndOfFile         = channel.Read <ulong>();
                        param.ResourceType      = channel.Read <FileTypeValue>();
                        param.NMPipeStatus_or_FileStatusFlags = channel.Read <SMB_NMPIPE_STATUS>();
                        param.Directory = channel.Read <byte>();
                        // VolumeGUID (16 bytes), td defines this length
                        param.VolumeGUID = channel.ReadBytes(CifsMessageUtils.GetSize <Guid>(new Guid()));
                        // if there is more 16 bytes in the channel.
                        if (channel.Stream.Position <= channel.Stream.Length - WINDOWS_BEHAVIOR_ADDITIONAL_DATA_LENGTH)
                        {
                            // FileId (8 bytes), td defines this length
                            param.FileId = channel.ReadBytes(sizeof(ulong));
                            // MaximalAccessRights (4 bytes), td defines this length
                            param.MaximalAccessRights = channel.ReadBytes(sizeof(uint));
                            // GuestMaximalAccessRights (4 bytes), td defines this length
                            param.GuestMaximalAccessRights = channel.ReadBytes(sizeof(uint));
                        }
                    }
                }

                this.SmbParameters = param;
            }
            else
            {
                base.DecodeParameters();

                this.smbParameters = SmbMessageUtils.ConvertSmbComCreatePacketPayload(base.SmbParameters);
            }
        }
예제 #3
0
        /// <summary>
        /// to new a Smb request packet in type of the Command in SmbHeader.
        /// </summary>
        /// <param name="messageBytes">bytes contains packet</param>
        /// <returns>
        /// the new request packet.
        /// the null means that the utility don't know how to create the request.
        /// </returns>
        protected override SmbPacket CreateSmbRequestPacket(byte[] messageBytes)
        {
            SmbPacket smbRequest = null;

            using (MemoryStream stream = new MemoryStream(messageBytes, true))
            {
                using (Channel channel = new Channel(null, stream))
                {
                    // read smb header and new SmbPacket:
                    if (channel.Stream.Position < channel.Stream.Length &&
                        messageBytes.Length >= CifsMessageUtils.GetSize <SmbHeader>(new SmbHeader()))
                    {
                        SmbHeader smbHeader = channel.Read <SmbHeader>();
                        smbRequest = FindTheTargetPacket(smbHeader, channel);
                    }
                }
            }

            return(smbRequest);
        }
        /// <summary>
        /// Encode the struct of NtTransParameters into the byte array in SmbData.NT_Trans_Parameters
        /// </summary>
        protected override void EncodeNtTransParameters()
        {
            if ((this.smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
            {
                int ntTransParameterSize = CifsMessageUtils.GetSize <NT_TRANSACT_CREATE_Request_NT_Trans_Parameters>(
                    this.ntTransParameters) + PaddingSize;
                this.smbData.NT_Trans_Parameters = new byte[ntTransParameterSize];

                using (MemoryStream memoryStream = new MemoryStream(this.smbData.NT_Trans_Parameters))
                {
                    using (Channel channel = new Channel(null, memoryStream))
                    {
                        channel.BeginWriteGroup();
                        channel.Write <NtTransactFlags>(this.ntTransParameters.Flags);
                        channel.Write <uint>(this.ntTransParameters.RootDirectoryFID);
                        channel.Write <NtTransactDesiredAccess>(this.ntTransParameters.DesiredAccess);
                        channel.Write <ulong>(this.ntTransParameters.AllocationSize);
                        channel.Write <SMB_EXT_FILE_ATTR>(this.ntTransParameters.ExtFileAttributes);
                        channel.Write <NtTransactShareAccess>(this.ntTransParameters.ShareAccess);
                        channel.Write <NtTransactCreateDisposition>(this.ntTransParameters.CreateDisposition);
                        channel.Write <NtTransactCreateOptions>(this.ntTransParameters.CreateOptions);
                        channel.Write <uint>(this.ntTransParameters.SecurityDescriptorLength);
                        channel.Write <uint>(this.ntTransParameters.EALength);
                        channel.Write <uint>(this.ntTransParameters.NameLength);
                        channel.Write <NtTransactImpersonationLevel>(this.ntTransParameters.ImpersonationLevel);
                        channel.Write <NtTransactSecurityFlags>(this.ntTransParameters.SecurityFlags);
                        // Padding data
                        channel.WriteBytes(new byte[PaddingSize]);
                        channel.WriteBytes(this.ntTransParameters.Name);
                        channel.EndWriteGroup();
                    }
                }
            }
            else
            {
                this.smbData.NT_Trans_Parameters =
                    CifsMessageUtils.ToBytes <NT_TRANSACT_CREATE_Request_NT_Trans_Parameters>(this.ntTransParameters);
            }
        }
        protected override void EncodeTrans2Data()
        {
            int totalSize = 0;
            int fixedSize = 0; // The fixed size of each structure

            if (this.trans2Data.Data != null)
            {
                Type type = this.trans2Data.Data.GetType();

                if (type == typeof(SMB_INFO_STANDARD_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_INFO_STANDARD_OF_TRANS2_FIND_FIRST2[] standardArray = (
                        SMB_INFO_STANDARD_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;


                    fixedSize = (this.smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) ==
                                SmbFlags2.SMB_FLAGS2_UNICODE ? 26 : 24;
                    ushort resumeKeyLength = 4;

                    if (isResumeKeyExisted)
                    {
                        totalSize = (resumeKeyLength + fixedSize) * standardArray.Length;
                    }
                    else
                    {
                        totalSize = fixedSize * standardArray.Length;
                    }

                    for (int i = 0; i < standardArray.Length; i++)
                    {
                        totalSize += standardArray[i].FileNameLength;
                    }
                    this.smbData.Trans2_Data = new byte[totalSize];
                    using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Data))
                    {
                        using (Channel channel = new Channel(null, memoryStream))
                        {
                            channel.BeginWriteGroup();
                            for (int i = 0; i < standardArray.Length; i++)
                            {
                                if (isResumeKeyExisted)
                                {
                                    channel.Write <uint>(standardArray[i].ResumeKey);
                                }
                                channel.Write <SmbDate>(standardArray[i].CreationDate);
                                channel.Write <SmbTime>(standardArray[i].CreationTime);
                                channel.Write <SmbDate>(standardArray[i].LastAccessDate);
                                channel.Write <SmbTime>(standardArray[i].LastAccessTime);
                                channel.Write <SmbDate>(standardArray[i].LastWriteDate);
                                channel.Write <SmbTime>(standardArray[i].LastWriteTime);
                                channel.Write <uint>(standardArray[i].DataSize);
                                channel.Write <uint>(standardArray[i].AllocationSize);
                                channel.Write <SmbFileAttributes>(standardArray[i].Attributes);
                                channel.Write <byte>(standardArray[i].FileNameLength);

                                if ((this.smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
                                {
                                    channel.Write <byte>(new byte());
                                }
                                channel.WriteBytes(standardArray[i].FileName);

                                if ((this.smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
                                {
                                    channel.Write <ushort>(new ushort());
                                }
                                else
                                {
                                    channel.Write <byte>(new byte());
                                }
                            }
                            channel.EndWriteGroup();
                        }
                    }
                }

                else if (type == typeof(SMB_INFO_QUERY_EA_SIZE_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_INFO_QUERY_EA_SIZE_OF_TRANS2_FIND_FIRST2[] queryEaArray = (
                        SMB_INFO_QUERY_EA_SIZE_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;
                    fixedSize = 28;
                    ushort resumeKeyLength = 4;

                    if (isResumeKeyExisted)
                    {
                        totalSize = (resumeKeyLength + fixedSize) * queryEaArray.Length;
                    }
                    else
                    {
                        totalSize = fixedSize * queryEaArray.Length;
                    }

                    for (int i = 0; i < queryEaArray.Length; i++)
                    {
                        totalSize += queryEaArray[i].FileNameLength;
                    }
                    this.smbData.Trans2_Data = new byte[totalSize];
                    using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Data))
                    {
                        using (Channel channel = new Channel(null, memoryStream))
                        {
                            channel.BeginWriteGroup();
                            for (int i = 0; i < queryEaArray.Length; i++)
                            {
                                if (isResumeKeyExisted)
                                {
                                    channel.Write <uint>(queryEaArray[i].ResumeKey);
                                }
                                channel.Write <SmbDate>(queryEaArray[i].CreationDate);
                                channel.Write <SmbTime>(queryEaArray[i].CreationTime);
                                channel.Write <SmbDate>(queryEaArray[i].LastAccessDate);
                                channel.Write <SmbTime>(queryEaArray[i].LastAccessTime);
                                channel.Write <SmbDate>(queryEaArray[i].LastWriteDate);
                                channel.Write <SmbTime>(queryEaArray[i].LastWriteTime);
                                channel.Write <uint>(queryEaArray[i].DataSize);
                                channel.Write <uint>(queryEaArray[i].AllocationSize);
                                channel.Write <SmbFileAttributes>(queryEaArray[i].Attributes);
                                channel.Write <uint>(queryEaArray[i].EaSize);
                                channel.Write <byte>(queryEaArray[i].FileNameLength);
                                channel.WriteBytes(queryEaArray[i].FileName);
                                channel.Write <byte>(new byte());
                            }
                            channel.EndWriteGroup();
                        }
                    }
                }

                else if (type == typeof(SMB_INFO_QUERY_EAS_FROM_LIST_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_INFO_QUERY_EAS_FROM_LIST_OF_TRANS2_FIND_FIRST2[] queryEaFromListArray = (
                        SMB_INFO_QUERY_EAS_FROM_LIST_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;
                    fixedSize = 24;
                    ushort resumeKeyLength = 4;

                    if (isResumeKeyExisted)
                    {
                        totalSize = (resumeKeyLength + fixedSize) * queryEaFromListArray.Length;
                    }
                    else
                    {
                        totalSize = fixedSize * queryEaFromListArray.Length;
                    }

                    for (int i = 0; i < queryEaFromListArray.Length; i++)
                    {
                        totalSize += (int)(queryEaFromListArray[i].FileNameLength +
                                           queryEaFromListArray[i].EaSize);
                    }
                    this.smbData.Trans2_Data = new byte[totalSize];
                    using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Data))
                    {
                        using (Channel channel = new Channel(null, memoryStream))
                        {
                            channel.BeginWriteGroup();

                            for (int i = 0; i < queryEaFromListArray.Length; i++)
                            {
                                if (isResumeKeyExisted)
                                {
                                    channel.Write <uint>(queryEaFromListArray[i].ResumeKey);
                                }
                                channel.Write <SmbDate>(queryEaFromListArray[i].CreationDate);
                                channel.Write <SmbTime>(queryEaFromListArray[i].CreationTime);
                                channel.Write <SmbDate>(queryEaFromListArray[i].LastAccessDate);
                                channel.Write <SmbTime>(queryEaFromListArray[i].LastAccessTime);
                                channel.Write <SmbDate>(queryEaFromListArray[i].LastWriteDate);
                                channel.Write <SmbTime>(queryEaFromListArray[i].LastWriteTime);
                                channel.Write <uint>(queryEaFromListArray[i].DataSize);
                                channel.Write <uint>(queryEaFromListArray[i].AllocationSize);
                                channel.Write <SmbFileAttributes>(queryEaFromListArray[i].Attributes);
                                channel.Write <uint>(queryEaFromListArray[i].EaSize);

                                if (queryEaFromListArray[i].ExtendedAttributeList != null)
                                {
                                    foreach (SMB_FEA smbEa in queryEaFromListArray[i].ExtendedAttributeList)
                                    {
                                        channel.Write <SMB_FEA>(smbEa);
                                    }
                                }
                                channel.Write <byte>(queryEaFromListArray[i].FileNameLength);
                                channel.WriteBytes(queryEaFromListArray[i].FileName);
                                channel.Write <byte>(new byte());
                            }
                            channel.EndWriteGroup();
                        }
                    }
                }

                else if (type == typeof(SMB_FIND_FILE_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_FIND_FILE_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[] fileInfoArray = (
                        SMB_FIND_FILE_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;
                    fixedSize = 64; // Including the fixed length of this structure.
                    totalSize = fixedSize * fileInfoArray.Length;
                    int pad = 0;

                    for (int i = 0; i < fileInfoArray.Length; i++)
                    {
                        totalSize += (int)(fileInfoArray[i].FileNameLength);
                        pad        = (int)(fileInfoArray[i].NextEntryOffset - fixedSize - fileInfoArray[i].FileNameLength);

                        if (pad > 0)
                        {
                            totalSize += pad;
                        }
                    }
                    this.smbData.Trans2_Data = new byte[totalSize];
                    using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Data))
                    {
                        using (Channel channel = new Channel(null, memoryStream))
                        {
                            channel.BeginWriteGroup();
                            for (int i = 0; i < fileInfoArray.Length; i++)
                            {
                                fixedSize = 64;                                    // Including the fixed length of this structure.
                                channel.Write <SMB_FIND_FILE_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2>(fileInfoArray[i]);
                                fixedSize += (int)fileInfoArray[i].FileNameLength; // Add the length of file name and pad.
                                pad        = (int)(fileInfoArray[i].NextEntryOffset - fixedSize);

                                if (pad > 0)
                                {
                                    channel.WriteBytes(new byte[pad]);
                                }
                            }
                            channel.EndWriteGroup();
                        }
                    }
                }

                else if (type == typeof(SMB_FIND_FILE_FULL_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_FIND_FILE_FULL_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[] fullInfoArray =
                        (SMB_FIND_FILE_FULL_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;
                    fixedSize = 68; // Including the fixed length of this structure.
                    totalSize = fixedSize * fullInfoArray.Length;
                    int pad = 0;

                    for (int i = 0; i < fullInfoArray.Length; i++)
                    {
                        totalSize += (int)(fullInfoArray[i].FileNameLength + fullInfoArray[i].EaSize);
                        pad        = (int)(fullInfoArray[i].NextEntryOffset - fixedSize - fullInfoArray[i].FileNameLength);

                        if (pad > 0)
                        {
                            totalSize += pad;
                        }
                    }
                    this.smbData.Trans2_Data = new byte[totalSize];
                    using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Data))
                    {
                        using (Channel channel = new Channel(null, memoryStream))
                        {
                            channel.BeginWriteGroup();
                            for (int i = 0; i < fullInfoArray.Length; i++)
                            {
                                fixedSize = 68;                                    // Including the fixed length of this structure.
                                channel.Write <SMB_FIND_FILE_FULL_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2>(fullInfoArray[i]);
                                fixedSize += (int)fullInfoArray[i].FileNameLength; // Add the length of file name and pad.
                                pad        = (int)(fullInfoArray[i].NextEntryOffset - fixedSize);

                                if (pad > 0)
                                {
                                    channel.WriteBytes(new byte[pad]);
                                }
                            }
                            channel.EndWriteGroup();
                        }
                    }
                }

                else if (type == typeof(SMB_FIND_FILE_BOTH_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_FIND_FILE_BOTH_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[] bothInfoArray = (
                        SMB_FIND_FILE_BOTH_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;

                    List <byte> buffer = new List <byte>();

                    for (int i = 0; i < bothInfoArray.Length; i++)
                    {
                        SMB_FIND_FILE_BOTH_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2 item = bothInfoArray[i];

                        // update the next entry offset.
                        int len = CifsMessageUtils.GetSize <SMB_FIND_FILE_BOTH_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2>(item);
                        item.NextEntryOffset = (uint)len;
                        if (i + 1 < bothInfoArray.Length)
                        {
                            item.NextEntryOffset += (uint)CifsMessageUtils.CalculatePadLength(len, 8);
                        }

                        byte[] data = CifsMessageUtils.ToBytes <SMB_FIND_FILE_BOTH_DIRECTORY_INFO_OF_TRANS2_FIND_FIRST2>(item);
                        buffer.AddRange(data);

                        if (i + 1 < bothInfoArray.Length)
                        {
                            // 8 bytes align
                            buffer.AddRange(new byte[CifsMessageUtils.CalculatePadLength(data.Length, 8)]);
                        }
                    }

                    this.smbData.Trans2_Data = buffer.ToArray();
                }

                else if (type == typeof(SMB_FIND_FILE_NAMES_INFO_OF_TRANS2_FIND_FIRST2[]))
                {
                    SMB_FIND_FILE_NAMES_INFO_OF_TRANS2_FIND_FIRST2[] namesInfoArray = (
                        SMB_FIND_FILE_NAMES_INFO_OF_TRANS2_FIND_FIRST2[])this.trans2Data.Data;
                    fixedSize = 12; // Including the fixed length of this structure.
                    totalSize = fixedSize * namesInfoArray.Length;
                    int pad = 0;

                    for (int i = 0; i < namesInfoArray.Length; i++)
                    {
                        totalSize += (int)(namesInfoArray[i].FileNameLength);
                        pad        = (int)(namesInfoArray[i].NextEntryOffset - fixedSize - namesInfoArray[i].FileNameLength);

                        if (pad > 0)
                        {
                            totalSize += pad;
                        }
                    }
                    this.smbData.Trans2_Data = new byte[totalSize];
                    using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Data))
                    {
                        using (Channel channel = new Channel(null, memoryStream))
                        {
                            channel.BeginWriteGroup();
                            for (int i = 0; i < namesInfoArray.Length; i++)
                            {
                                fixedSize = 12;                                     // Including the fixed length of this structure.
                                channel.Write <SMB_FIND_FILE_NAMES_INFO_OF_TRANS2_FIND_FIRST2>(namesInfoArray[i]);
                                fixedSize += (int)namesInfoArray[i].FileNameLength; // Add the length of file name.
                                pad        = (int)(namesInfoArray[i].NextEntryOffset - fixedSize);

                                if (pad > 0)
                                {
                                    channel.WriteBytes(new byte[pad]);
                                }
                            }
                            channel.EndWriteGroup();
                        }
                    }
                }
            }
            else
            {
                this.smbData.Trans2_Data = new byte[0];
            }
        }
예제 #6
0
        /// <summary>
        /// convert data to SMB_FIND_FILE_BOTH_DIRECTORY_INFO array.
        /// </summary>
        /// <param name="informationLevel">the information level</param>
        /// <param name="arraySize">the array size</param>
        /// <param name="data">the data</param>
        /// <returns>the unmarshaled result</returns>
        public static object UnmarshalSmbFindInformationLevelPayloads(
            FindInformationLevel informationLevel,
            int arraySize, byte[] data)
        {
            switch ((FindInformationLevel)informationLevel)
            {
            case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
            {
                SMB_FIND_FILE_BOTH_DIRECTORY_INFO[] result =
                    new SMB_FIND_FILE_BOTH_DIRECTORY_INFO[arraySize];

                using (MemoryStream memoryStream = new MemoryStream(data))
                {
                    using (Channel channel = new Channel(null, memoryStream))
                    {
                        for (int i = 0; i < result.Length; i++)
                        {
                            result[i] = channel.Read <SMB_FIND_FILE_BOTH_DIRECTORY_INFO>();
                            int pad = Convert.ToInt32(result[i].NextEntryOffset -
                                                      CifsMessageUtils.GetSize <SMB_FIND_FILE_BOTH_DIRECTORY_INFO>(result[i]));
                            if (pad > 0)
                            {
                                channel.ReadBytes(pad);
                            }
                        }
                    }
                }

                return(result);
            }

            case FindInformationLevel.SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
            {
                SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO[] result =
                    new SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO[arraySize];

                using (MemoryStream memoryStream = new MemoryStream(data))
                {
                    using (Channel channel = new Channel(null, memoryStream))
                    {
                        for (int i = 0; i < result.Length; i++)
                        {
                            result[i] = channel.Read <SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO>();
                            int pad = Convert.ToInt32(result[i].NextEntryOffset -
                                                      CifsMessageUtils.GetSize <SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO>(result[i]));
                            if (pad > 0)
                            {
                                channel.ReadBytes(pad);
                            }
                        }
                    }
                }

                return(result);
            }

            case FindInformationLevel.SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
            {
                SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO[] result =
                    new SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO[arraySize];

                using (MemoryStream memoryStream = new MemoryStream(data))
                {
                    using (Channel channel = new Channel(null, memoryStream))
                    {
                        for (int i = 0; i < result.Length; i++)
                        {
                            result[i] = channel.Read <SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO>();
                            int pad = Convert.ToInt32(result[i].NextEntryOffset -
                                                      CifsMessageUtils.GetSize <SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO>(result[i]));
                            if (pad > 0)
                            {
                                channel.ReadBytes(pad);
                            }
                        }
                    }
                }
                return(result);
            }

            default:

                return(null);
            }
        }
        /// <summary>
        /// decode packet from bytes
        /// </summary>
        /// <param name="connectId">the connection identity.</param>
        /// <param name="messageBytes">bytes contains packet</param>
        /// <param name="consumedLength">the bytes length which are consumed when decode.</param>
        /// <returns>the decoded packet from the bytes array. if failed, return null.</returns>
        protected SmbPacket DecodeSmbResponseFromBytes(
            int connectId,
            byte[] messageBytes,
            out int consumedLength)
        {
            consumedLength = 0;
            SmbPacket smbRequest  = null;
            SmbPacket smbResponse = null;

            using (MemoryStream memoryStream = new MemoryStream(messageBytes, true))
            {
                using (Channel channel = new Channel(null, memoryStream))
                {
                    // read raw response:
                    Collection <SmbPacket> outstandingRequests = this.clientContext.GetOutstandingRequests(connectId);
                    if (outstandingRequests != null && outstandingRequests.Count > 0)
                    {
                        SmbReadRawRequestPacket readRawRequest = outstandingRequests[0] as SmbReadRawRequestPacket;
                        if (readRawRequest != null)
                        {
                            SmbReadRawResponsePacket readRawResponse = this.CreateSmbResponsePacket(
                                readRawRequest, readRawRequest.SmbHeader, channel) as SmbReadRawResponsePacket;
                            if (readRawResponse != null)
                            {
                                byte[] rawData = new byte[messageBytes.Length];
                                Array.Copy(messageBytes, rawData, rawData.Length);
                                readRawResponse.RawData = rawData;
                                consumedLength          = rawData.Length;
                                return(readRawResponse);
                            }
                            else
                            {
                                // discard the none-parsable data silently:
                                consumedLength = messageBytes.Length;
                                return(null);
                            }
                        }
                        else
                        {
                            // No SmbReadRawResponsePacket sent, so the response should not be SmbReadRawResponsePacket.
                            // and do nothing here.
                        }
                    }

                    // read smb header and new SmbPacket:
                    if (channel.Stream.Position < channel.Stream.Length &&
                        messageBytes.Length >= CifsMessageUtils.GetSize <SmbHeader>(new SmbHeader()))
                    {
                        SmbHeader smbHeader = channel.Read <SmbHeader>();
                        smbRequest      = this.clientContext.GetOutstandingRequest(connectId, smbHeader.Mid);
                        smbResponse     = this.CreateSmbResponsePacket(smbRequest, smbHeader, channel);
                        consumedLength += smbResponse.HeaderSize;
                    }
                    else
                    {
                        // The data in the channel is less than the size of SmbHeader. consume nothing and return null:
                        consumedLength = 0;
                        return(null);
                    }

                    // read SmbParameters:
                    consumedLength += smbResponse.ReadParametersFromChannel(channel);

                    // read SmbData:
                    consumedLength += smbResponse.ReadDataFromChannel(channel);

                    // read andx:
                    SmbBatchedResponsePacket smbBatchedResponse = smbResponse as SmbBatchedResponsePacket;
                    if (smbRequest != null && smbBatchedResponse != null)
                    {
                        consumedLength += DecodeBatchedRequest(channel, smbRequest, smbBatchedResponse);
                    }

                    // handle the difference of protocol implementation:
                    SmbWriteAndCloseResponsePacket writeAndCloseResponse = smbResponse as SmbWriteAndCloseResponsePacket;
                    if (writeAndCloseResponse != null)
                    {
                        if (this.clientConfig.IsWriteAndCloseResponseExtraPadding)
                        {
                            // Windows NT Server appends three NULL bytes to this message, following the ByteCount field.
                            // These three bytes are not message data and can safely be discarded.
                            const int PaddingLength = 3;
                            writeAndCloseResponse.PaddingBytes = channel.ReadBytes(PaddingLength);
                            consumedLength += PaddingLength;
                        }
                    }
                }
            }
            return(smbResponse);
        }