// This code is derived from jcifs smb client library // Ported by J. Arturo // // 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); } /// 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(); } } }