jellyfin-server/Emby.Common.Implementations/IO/SharpCifs/Smb/SmbComTransactionResponse.cs
2017-04-01 20:36:06 -04:00

207 lines
6.7 KiB
C#

// This code is derived from jcifs smb client library <jcifs at samba dot org>
// Ported by J. Arturo <webmaster at komodosoft dot net>
//
// 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;
}
}
}