/// <summary> /// decode packet from bytes /// </summary> /// <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 DecodeSmbRequestFromBytes( byte[] messageBytes, out int consumedLength) { consumedLength = 0; SmbPacket smbRequest = null; using (MemoryStream memoryStream = new MemoryStream(messageBytes, false)) { using (Channel channel = new Channel(null, memoryStream)) { smbRequest = CreateSmbRequestPacket(messageBytes); if (smbRequest == null) { return(null); } // decode smb header SmbHeader smbHeader = channel.Read <SmbHeader>(); consumedLength += smbRequest.HeaderSize; // set packet header smbRequest.SmbHeader = smbHeader; // read SmbParameters: consumedLength += smbRequest.ReadParametersFromChannel(channel); // read SmbData: consumedLength += smbRequest.ReadDataFromChannel(channel); // read andx: SmbBatchedRequestPacket smbBatchedRequest = smbRequest as SmbBatchedRequestPacket; if (smbBatchedRequest != null) { consumedLength += DecodeBatchedRequest(channel, smbBatchedRequest); } } } return(smbRequest); }
/// <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); }