/// <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); } }
/// <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]; } }
/// <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); }