jellyfin/Emby.Common.Implementations/IO/SharpCifs/Dcerpc/Ndr/NdrBuffer.cs
2017-04-01 20:36:06 -04:00

306 lines
5.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;
using SharpCifs.Util;
using SharpCifs.Util.Sharpen;
namespace SharpCifs.Dcerpc.Ndr
{
public class NdrBuffer
{
internal int Referent;
internal Hashtable Referents;
internal class Entry
{
internal int Referent;
internal object Obj;
}
public byte[] Buf;
public int Start;
public int Index;
public int Length;
public NdrBuffer Deferred;
public NdrBuffer(byte[] buf, int start)
{
this.Buf = buf;
this.Start = Index = start;
Length = 0;
Deferred = this;
}
public virtual NdrBuffer Derive(int idx)
{
NdrBuffer nb = new NdrBuffer(Buf, Start);
nb.Index = idx;
nb.Deferred = Deferred;
return nb;
}
public virtual void Reset()
{
Index = Start;
Length = 0;
Deferred = this;
}
public virtual int GetIndex()
{
return Index;
}
public virtual void SetIndex(int index)
{
this.Index = index;
}
public virtual int GetCapacity()
{
return Buf.Length - Start;
}
public virtual int GetTailSpace()
{
return Buf.Length - Index;
}
public virtual byte[] GetBuffer()
{
return Buf;
}
public virtual int Align(int boundary, byte value)
{
int n = Align(boundary);
int i = n;
while (i > 0)
{
Buf[Index - i] = value;
i--;
}
return n;
}
public virtual void WriteOctetArray(byte[] b, int i, int l)
{
Array.Copy(b, i, Buf, Index, l);
Advance(l);
}
public virtual void ReadOctetArray(byte[] b, int i, int l)
{
Array.Copy(Buf, Index, b, i, l);
Advance(l);
}
public virtual int GetLength()
{
return Deferred.Length;
}
public virtual void SetLength(int length)
{
Deferred.Length = length;
}
public virtual void Advance(int n)
{
Index += n;
if ((Index - Start) > Deferred.Length)
{
Deferred.Length = Index - Start;
}
}
public virtual int Align(int boundary)
{
int m = boundary - 1;
int i = Index - Start;
int n = ((i + m) & ~m) - i;
Advance(n);
return n;
}
public virtual void Enc_ndr_small(int s)
{
Buf[Index] = unchecked((byte)(s & unchecked(0xFF)));
Advance(1);
}
public virtual int Dec_ndr_small()
{
int val = Buf[Index] & unchecked(0xFF);
Advance(1);
return val;
}
public virtual void Enc_ndr_short(int s)
{
Align(2);
Encdec.Enc_uint16le((short)s, Buf, Index);
Advance(2);
}
public virtual int Dec_ndr_short()
{
Align(2);
int val = Encdec.Dec_uint16le(Buf, Index);
Advance(2);
return val;
}
public virtual void Enc_ndr_long(int l)
{
Align(4);
Encdec.Enc_uint32le(l, Buf, Index);
Advance(4);
}
public virtual int Dec_ndr_long()
{
Align(4);
int val = Encdec.Dec_uint32le(Buf, Index);
Advance(4);
return val;
}
public virtual void Enc_ndr_hyper(long h)
{
Align(8);
Encdec.Enc_uint64le(h, Buf, Index);
Advance(8);
}
public virtual long Dec_ndr_hyper()
{
Align(8);
long val = Encdec.Dec_uint64le(Buf, Index);
Advance(8);
return val;
}
public virtual void Enc_ndr_string(string s)
{
Align(4);
int i = Index;
int len = s.Length;
Encdec.Enc_uint32le(len + 1, Buf, i);
i += 4;
Encdec.Enc_uint32le(0, Buf, i);
i += 4;
Encdec.Enc_uint32le(len + 1, Buf, i);
i += 4;
try
{
Array.Copy(Runtime.GetBytesForString(s, "UTF-16LE"), 0, Buf, i, len
* 2);
}
catch (UnsupportedEncodingException)
{
}
i += len * 2;
Buf[i++] = unchecked((byte)('\0'));
Buf[i++] = unchecked((byte)('\0'));
Advance(i - Index);
}
/// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception>
public virtual string Dec_ndr_string()
{
Align(4);
int i = Index;
string val = null;
int len = Encdec.Dec_uint32le(Buf, i);
i += 12;
if (len != 0)
{
len--;
int size = len * 2;
try
{
if (size < 0 || size > unchecked(0xFFFF))
{
throw new NdrException(NdrException.InvalidConformance);
}
val = Runtime.GetStringForBytes(Buf, i, size, "UTF-16LE");
i += size + 2;
}
catch (UnsupportedEncodingException)
{
}
}
Advance(i - Index);
return val;
}
private int GetDceReferent(object obj)
{
Entry e;
if (Referents == null)
{
Referents = new Hashtable();
Referent = 1;
}
if ((e = (Entry)Referents.Get(obj)) == null)
{
e = new Entry();
e.Referent = Referent++;
e.Obj = obj;
Referents.Put(obj, e);
}
return e.Referent;
}
public virtual void Enc_ndr_referent(object obj, int type)
{
if (obj == null)
{
Enc_ndr_long(0);
return;
}
switch (type)
{
case 1:
case 3:
{
Enc_ndr_long(Runtime.IdentityHashCode(obj));
return;
}
case 2:
{
Enc_ndr_long(GetDceReferent(obj));
return;
}
}
}
public override string ToString()
{
return "start=" + Start + ",index=" + Index + ",length=" + GetLength();
}
}
}