| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | // 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;		}	}}
 |