/// <summary> /// Deep copy constructor. /// </summary> public SmbReadRawRequestPacket(SmbReadRawRequestPacket packet) : base(packet) { this.InitDefaultValue(); this.smbParameters.WordCount = packet.SmbParameters.WordCount; this.smbParameters.FID = packet.SmbParameters.FID; this.smbParameters.Offset = packet.SmbParameters.Offset; this.smbParameters.MaxCountOfBytesToReturn = packet.SmbParameters.MaxCountOfBytesToReturn; this.smbParameters.MinCountOfBytesToReturn = packet.SmbParameters.MinCountOfBytesToReturn; this.smbParameters.Timeout = packet.SmbParameters.Timeout; this.smbParameters.Reserved = packet.SmbParameters.Reserved; this.smbParameters.OffsetHigh = packet.SmbParameters.OffsetHigh; this.smbData.ByteCount = packet.SmbData.ByteCount; }
/// <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> /// to create a ReadRaw request packet. /// </summary> /// <param name="messageId">This field SHOULD be the multiplex ID that is used to associate a response with a /// request.</param> /// <param name="uid">This field SHOULD identify the authenticated instance of the user.</param> /// <param name="treeId">This field identifies the subdirectory (or tree) on the server that the client is /// accessing.</param> /// <param name="flags">An 8-bit field of 1-bit flags describing various features in effect for the /// message</param> /// <param name="flags2">A 16-bit field of 1-bit flags that represent various features in effect for the /// message. Unspecified bits are reserved and MUST be zero.</param> /// <param name="fid">This field MUST be a valid 16-bit signed integer indicating the file from which the data /// MUST be read.</param> /// <param name="offset">The offset in bytes from the start of the file at which the read MUST begin. This is /// the lower 32 bits of a 64 bit value if the WordCount is 10</param> /// <param name="maxCountOfBytesToReturn">The requested maximum number of bytes to read from the file and /// return to the client. The value MAY exceed the negotiated buffer size</param> /// <param name="minCountOfBytesToReturn">The requested minimum number of bytes to read from the file and /// return to the client. This field is used only when reading from a named pipe or a device. It is ignored /// when reading from a standard file</param> /// <param name="timeout">Support for this field is optional and this field is used only when reading from a /// named pipe or i/o device.</param> /// <param name="offsetHigh">the upper 32 bits of the offset in bytes from the start of the file at which /// the read MUST start.</param> /// <returns>a ReadRaw request packet</returns> public SmbReadRawRequestPacket CreateReadRawRequest( ushort messageId, ushort uid, ushort treeId, SmbFlags flags, SmbFlags2 flags2, ushort fid, uint offset, ushort maxCountOfBytesToReturn, ushort minCountOfBytesToReturn, uint timeout, uint offsetHigh) { SmbReadRawRequestPacket packet = new SmbReadRawRequestPacket(); packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_READ_RAW, messageId, uid, treeId, flags, flags2); SMB_COM_READ_RAW_Request_SMB_Parameters smbParameters = new SMB_COM_READ_RAW_Request_SMB_Parameters(); smbParameters.FID = fid; smbParameters.Offset = offset; smbParameters.MaxCountOfBytesToReturn = maxCountOfBytesToReturn; smbParameters.MinCountOfBytesToReturn = minCountOfBytesToReturn; smbParameters.Timeout = timeout; smbParameters.Reserved = 0; smbParameters.OffsetHigh = offsetHigh; smbParameters.WordCount = (byte)(Marshal.SizeOf(smbParameters) / NumBytesOfWord); SMB_COM_READ_RAW_Request_SMB_Data smbData = new SMB_COM_READ_RAW_Request_SMB_Data(); smbData.ByteCount = 0; packet.SmbParameters = smbParameters; packet.SmbData = smbData; return packet; }