| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 | // 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  USAusing 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;        }    }}
 |