diff options
Diffstat (limited to 'Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs')
| -rw-r--r-- | Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs new file mode 100644 index 000000000..e78bff9d0 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/AndXServerMessageBlock.cs @@ -0,0 +1,221 @@ +// 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 SharpCifs.Util; +using SharpCifs.Util.Sharpen; + +namespace SharpCifs.Smb +{ + internal abstract class AndXServerMessageBlock : ServerMessageBlock + { + private const int AndxCommandOffset = 1; + + private const int AndxReservedOffset = 2; + + private const int AndxOffsetOffset = 3; + + private byte _andxCommand = unchecked(unchecked(0xFF)); + + private int _andxOffset; + + internal ServerMessageBlock Andx; + + public AndXServerMessageBlock() + { + } + + internal AndXServerMessageBlock(ServerMessageBlock andx) + { + if (andx != null) + { + this.Andx = andx; + _andxCommand = andx.Command; + } + } + + internal virtual int GetBatchLimit(byte command) + { + return 0; + } + + internal override int Encode(byte[] dst, int dstIndex) + { + int start = HeaderStart = dstIndex; + dstIndex += WriteHeaderWireFormat(dst, dstIndex); + dstIndex += WriteAndXWireFormat(dst, dstIndex); + Length = dstIndex - start; + if (Digest != null) + { + Digest.Sign(dst, HeaderStart, Length, this, Response); + } + return Length; + } + + internal override int Decode(byte[] buffer, int bufferIndex) + { + int start = HeaderStart = bufferIndex; + bufferIndex += ReadHeaderWireFormat(buffer, bufferIndex); + bufferIndex += ReadAndXWireFormat(buffer, bufferIndex); + Length = bufferIndex - start; + return Length; + } + + internal virtual int WriteAndXWireFormat(byte[] dst, int dstIndex) + { + int start = dstIndex; + WordCount = WriteParameterWordsWireFormat(dst, start + AndxOffsetOffset + 2); + WordCount += 4; + // for command, reserved, and offset + dstIndex += WordCount + 1; + WordCount /= 2; + dst[start] = unchecked((byte)(WordCount & unchecked(0xFF))); + ByteCount = WriteBytesWireFormat(dst, dstIndex + 2); + dst[dstIndex++] = unchecked((byte)(ByteCount & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((ByteCount >> 8) & unchecked(0xFF))); + dstIndex += ByteCount; + if (Andx == null || SmbConstants.UseBatching == false || BatchLevel >= GetBatchLimit(Andx.Command + )) + { + _andxCommand = unchecked(unchecked(0xFF)); + Andx = null; + dst[start + AndxCommandOffset] = unchecked(unchecked(0xFF)); + dst[start + AndxReservedOffset] = unchecked(unchecked(0x00)); + // dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00; + // dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00; + dst[start + AndxOffsetOffset] = unchecked(unchecked(0xde)); + dst[start + AndxOffsetOffset + 1] = unchecked(unchecked(0xde)); + // andx not used; return + return dstIndex - start; + } + Andx.BatchLevel = BatchLevel + 1; + dst[start + AndxCommandOffset] = _andxCommand; + dst[start + AndxReservedOffset] = unchecked(unchecked(0x00)); + _andxOffset = dstIndex - HeaderStart; + WriteInt2(_andxOffset, dst, start + AndxOffsetOffset); + Andx.UseUnicode = UseUnicode; + if (Andx is AndXServerMessageBlock) + { + Andx.Uid = Uid; + dstIndex += ((AndXServerMessageBlock)Andx).WriteAndXWireFormat(dst, dstIndex + ); + } + else + { + // the andx smb is not of type andx so lets just write it here and + // were done. + int andxStart = dstIndex; + Andx.WordCount = Andx.WriteParameterWordsWireFormat(dst, dstIndex); + dstIndex += Andx.WordCount + 1; + Andx.WordCount /= 2; + dst[andxStart] = unchecked((byte)(Andx.WordCount & unchecked(0xFF))); + Andx.ByteCount = Andx.WriteBytesWireFormat(dst, dstIndex + 2); + dst[dstIndex++] = unchecked((byte)(Andx.ByteCount & unchecked(0xFF))); + dst[dstIndex++] = unchecked((byte)((Andx.ByteCount >> 8) & unchecked(0xFF) + )); + dstIndex += Andx.ByteCount; + } + return dstIndex - start; + } + + internal virtual int ReadAndXWireFormat(byte[] buffer, int bufferIndex) + { + int start = bufferIndex; + WordCount = buffer[bufferIndex++]; + if (WordCount != 0) + { + _andxCommand = buffer[bufferIndex]; + _andxOffset = ReadInt2(buffer, bufferIndex + 2); + if (_andxOffset == 0) + { + _andxCommand = unchecked(unchecked(0xFF)); + } + if (WordCount > 2) + { + ReadParameterWordsWireFormat(buffer, bufferIndex + 4); + if (Command == SmbComNtCreateAndx && ((SmbComNtCreateAndXResponse)this).IsExtended) + { + WordCount += 8; + } + } + bufferIndex = start + 1 + (WordCount * 2); + } + ByteCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (ByteCount != 0) + { + int n; + n = ReadBytesWireFormat(buffer, bufferIndex); + bufferIndex += ByteCount; + } + if (ErrorCode != 0 || _andxCommand == unchecked(unchecked(0xFF))) + { + _andxCommand = unchecked(unchecked(0xFF)); + Andx = null; + } + else + { + if (Andx == null) + { + _andxCommand = unchecked(unchecked(0xFF)); + throw new RuntimeException("no andx command supplied with response"); + } + bufferIndex = HeaderStart + _andxOffset; + Andx.HeaderStart = HeaderStart; + Andx.Command = _andxCommand; + Andx.ErrorCode = ErrorCode; + Andx.Flags = Flags; + Andx.Flags2 = Flags2; + Andx.Tid = Tid; + Andx.Pid = Pid; + Andx.Uid = Uid; + Andx.Mid = Mid; + Andx.UseUnicode = UseUnicode; + if (Andx is AndXServerMessageBlock) + { + bufferIndex += ((AndXServerMessageBlock)Andx).ReadAndXWireFormat(buffer + , bufferIndex); + } + else + { + buffer[bufferIndex++] = unchecked((byte)(Andx.WordCount & unchecked(0xFF)) + ); + if (Andx.WordCount != 0) + { + if (Andx.WordCount > 2) + { + bufferIndex += Andx.ReadParameterWordsWireFormat(buffer, bufferIndex); + } + } + Andx.ByteCount = ReadInt2(buffer, bufferIndex); + bufferIndex += 2; + if (Andx.ByteCount != 0) + { + Andx.ReadBytesWireFormat(buffer, bufferIndex); + bufferIndex += Andx.ByteCount; + } + } + Andx.Received = true; + } + return bufferIndex - start; + } + + public override string ToString() + { + return base.ToString() + ",andxCommand=0x" + Hexdump.ToHexString(_andxCommand + , 2) + ",andxOffset=" + _andxOffset; + } + } +} |
