/// <summary> /// decode the batched request packet /// </summary> /// <param name="channel">the channel of bytes to read</param> /// <param name="request">the request of the response.</param> /// <param name="smbBatchedResponse">the batched response</param> /// <returns>the consumed length of batched response packet</returns> protected virtual int DecodeBatchedRequest( Channel channel, SmbPacket request, SmbBatchedResponsePacket smbBatchedResponse) { int batchedConsumedLength = 0; batchedConsumedLength += smbBatchedResponse.ReadAndxFromChannel(request, channel); return(batchedConsumedLength); }
/// <summary> /// Deep copy constructor. /// </summary> protected SmbBatchedResponsePacket(SmbBatchedResponsePacket packet) : base(packet) { lock (packet) { if (packet.AndxPacket != null) { this.andxPacket = packet.AndxPacket.Clone() as SmbPacket; } } }
/// <summary> /// Deep copy constructor. /// </summary> protected SmbBatchedResponsePacket(SmbBatchedResponsePacket packet) : base(packet) { lock (packet) { if (packet.AndxPacket != null) { this.andxPacket = packet.AndxPacket.Clone() as SmbPacket; } } }
/// <summary> /// to read the andx packet from the channel /// </summary> /// <param name="smbRequest">the request of the response.</param> /// <param name="channel">the channel started with the SmbParameters of the andx.</param> /// <returns>the size in bytes of the SmbParameters, SmbData and andx if existed of the andx.</returns> internal int ReadAndxFromChannel(SmbPacket smbRequest, Channel channel) { int consumedLen = 0; if (this.AndxCommand != SmbCommand.SMB_COM_NO_ANDX_COMMAND) { SmbHeader andxHeader = this.SmbHeader; andxHeader.Command = this.AndxCommand; andxHeader.Protocol = CifsMessageUtils.SMB_PROTOCOL_ANDXPACKET; this.andxPacket = CifsMessageUtils.CreateSmbResponsePacket(smbRequest, andxHeader, channel); this.andxPacket.SmbHeader = andxHeader; consumedLen += this.andxPacket.ReadParametersFromChannel(channel); consumedLen += this.andxPacket.ReadDataFromChannel(channel); SmbBatchedResponsePacket batchedResponse = this.andxPacket as SmbBatchedResponsePacket; if (batchedResponse != null) { consumedLen += batchedResponse.ReadAndxFromChannel(smbRequest, channel); } } return(consumedLen); }
/// <summary> /// decode the batched request packet /// </summary> /// <param name="channel">the channel of bytes to read</param> /// <param name="request">the request of the response.</param> /// <param name="smbBatchedResponse">the batched response</param> /// <returns>the consumed length of batched response packet</returns> protected override int DecodeBatchedRequest( Channel channel, SmbPacket request, SmbBatchedResponsePacket smbBatchedResponse) { int result = base.DecodeBatchedRequest(channel, request, smbBatchedResponse); for (SmbBatchedResponsePacket currentPacket = smbBatchedResponse; currentPacket != null && currentPacket.AndxPacket != null; currentPacket = currentPacket.AndxPacket as SmbBatchedResponsePacket) { SmbPacket andxPacket = currentPacket.AndxPacket; // create the smb packet object smbParameters = ObjectUtility.GetFieldValue(currentPacket, "smbParameters"); if (smbParameters != null) { SmbHeader smbHeader = smbBatchedResponse.SmbHeader; smbHeader.Command = (SmbCommand)ObjectUtility.GetFieldValue(smbParameters, "AndXCommand"); andxPacket = CreateSmbResponsePacket(null, smbHeader, null); } // convert from cifs packet to smb packet if (andxPacket != null) { Type smbPacketType = andxPacket.GetType(); andxPacket = ObjectUtility.CreateInstance( smbPacketType.Module.FullyQualifiedName, smbPacketType.FullName, new object[] { currentPacket.AndxPacket }) as SmbPacket; } currentPacket.AndxPacket = andxPacket; } return result; }
/// <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); }
/// <summary> /// decode the batched request packet /// </summary> /// <param name="channel">the channel of bytes to read</param> /// <param name="request">the request of the response.</param> /// <param name="smbBatchedResponse">the batched response</param> /// <returns>the consumed length of batched response packet</returns> protected virtual int DecodeBatchedRequest( Channel channel, SmbPacket request, SmbBatchedResponsePacket smbBatchedResponse) { int batchedConsumedLength = 0; batchedConsumedLength += smbBatchedResponse.ReadAndxFromChannel(request, channel); return batchedConsumedLength; }