// This code is derived from jcifs smb client library // Ported by J. Arturo // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System; namespace SharpCifs.Smb { internal abstract class SmbComTransactionResponse : ServerMessageBlock { private const int SetupOffset = 61; private const int DisconnectTid = unchecked(0x01); private const int OneWayTransaction = unchecked(0x02); private int _pad; private int _pad1; private bool _parametersDone; private bool _dataDone; protected internal int TotalParameterCount; protected internal int TotalDataCount; protected internal int ParameterCount; protected internal int ParameterOffset; protected internal int ParameterDisplacement; protected internal int DataOffset; protected internal int DataDisplacement; protected internal int SetupCount; protected internal int BufParameterStart; protected internal int BufDataStart; internal int DataCount; internal byte SubCommand; internal bool HasMore = true; internal bool IsPrimary = true; internal byte[] TxnBuf; internal int Status; internal int NumEntries; internal IFileEntry[] Results; public SmbComTransactionResponse() { // relative to headerStart TxnBuf = null; } internal override void Reset() { base.Reset(); BufDataStart = 0; IsPrimary = HasMore = true; _parametersDone = _dataDone = false; } public virtual bool MoveNext() { return ErrorCode == 0 && HasMore; } public virtual object Current() { if (IsPrimary) { IsPrimary = false; } return this; } internal override int WriteParameterWordsWireFormat(byte[] dst, int dstIndex) { return 0; } internal override int WriteBytesWireFormat(byte[] dst, int dstIndex) { return 0; } internal override int ReadParameterWordsWireFormat(byte[] buffer, int bufferIndex ) { int start = bufferIndex; TotalParameterCount = ReadInt2(buffer, bufferIndex); if (BufDataStart == 0) { BufDataStart = TotalParameterCount; } bufferIndex += 2; TotalDataCount = ReadInt2(buffer, bufferIndex); bufferIndex += 4; // Reserved ParameterCount = ReadInt2(buffer, bufferIndex); bufferIndex += 2; ParameterOffset = ReadInt2(buffer, bufferIndex); bufferIndex += 2; ParameterDisplacement = ReadInt2(buffer, bufferIndex); bufferIndex += 2; DataCount = ReadInt2(buffer, bufferIndex); bufferIndex += 2; DataOffset = ReadInt2(buffer, bufferIndex); bufferIndex += 2; DataDisplacement = ReadInt2(buffer, bufferIndex); bufferIndex += 2; SetupCount = buffer[bufferIndex] & unchecked(0xFF); bufferIndex += 2; if (SetupCount != 0) { if (Log.Level > 2) { Log.WriteLine("setupCount is not zero: " + SetupCount); } } return bufferIndex - start; } internal override int ReadBytesWireFormat(byte[] buffer, int bufferIndex) { _pad = _pad1 = 0; int n; if (ParameterCount > 0) { bufferIndex += _pad = ParameterOffset - (bufferIndex - HeaderStart); Array.Copy(buffer, bufferIndex, TxnBuf, BufParameterStart + ParameterDisplacement , ParameterCount); bufferIndex += ParameterCount; } if (DataCount > 0) { bufferIndex += _pad1 = DataOffset - (bufferIndex - HeaderStart); Array.Copy(buffer, bufferIndex, TxnBuf, BufDataStart + DataDisplacement, DataCount); bufferIndex += DataCount; } if (!_parametersDone && (ParameterDisplacement + ParameterCount) == TotalParameterCount) { _parametersDone = true; } if (!_dataDone && (DataDisplacement + DataCount) == TotalDataCount) { _dataDone = true; } if (_parametersDone && _dataDone) { HasMore = false; ReadParametersWireFormat(TxnBuf, BufParameterStart, TotalParameterCount); ReadDataWireFormat(TxnBuf, BufDataStart, TotalDataCount); } return _pad + ParameterCount + _pad1 + DataCount; } internal abstract int WriteSetupWireFormat(byte[] dst, int dstIndex); internal abstract int WriteParametersWireFormat(byte[] dst, int dstIndex); internal abstract int WriteDataWireFormat(byte[] dst, int dstIndex); internal abstract int ReadSetupWireFormat(byte[] buffer, int bufferIndex, int len ); internal abstract int ReadParametersWireFormat(byte[] buffer, int bufferIndex, int len); internal abstract int ReadDataWireFormat(byte[] buffer, int bufferIndex, int len); public override string ToString() { return base.ToString() + ",totalParameterCount=" + TotalParameterCount + ",totalDataCount=" + TotalDataCount + ",parameterCount=" + ParameterCount + ",parameterOffset=" + ParameterOffset + ",parameterDisplacement=" + ParameterDisplacement + ",dataCount=" + DataCount + ",dataOffset=" + DataOffset + ",dataDisplacement=" + DataDisplacement + ",setupCount=" + SetupCount + ",pad=" + _pad + ",pad1=" + _pad1; } } }