mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 02:27:18 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			222 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			6.8 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 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;
 | |
| 		}
 | |
| 	}
 | |
| }
 |