NdrBuffer.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. // This code is derived from jcifs smb client library <jcifs at samba dot org>
  2. // Ported by J. Arturo <webmaster at komodosoft dot net>
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. using System;
  18. using SharpCifs.Util;
  19. using SharpCifs.Util.Sharpen;
  20. namespace SharpCifs.Dcerpc.Ndr
  21. {
  22. public class NdrBuffer
  23. {
  24. internal int Referent;
  25. internal Hashtable Referents;
  26. internal class Entry
  27. {
  28. internal int Referent;
  29. internal object Obj;
  30. }
  31. public byte[] Buf;
  32. public int Start;
  33. public int Index;
  34. public int Length;
  35. public NdrBuffer Deferred;
  36. public NdrBuffer(byte[] buf, int start)
  37. {
  38. this.Buf = buf;
  39. this.Start = Index = start;
  40. Length = 0;
  41. Deferred = this;
  42. }
  43. public virtual NdrBuffer Derive(int idx)
  44. {
  45. NdrBuffer nb = new NdrBuffer(Buf, Start);
  46. nb.Index = idx;
  47. nb.Deferred = Deferred;
  48. return nb;
  49. }
  50. public virtual void Reset()
  51. {
  52. Index = Start;
  53. Length = 0;
  54. Deferred = this;
  55. }
  56. public virtual int GetIndex()
  57. {
  58. return Index;
  59. }
  60. public virtual void SetIndex(int index)
  61. {
  62. this.Index = index;
  63. }
  64. public virtual int GetCapacity()
  65. {
  66. return Buf.Length - Start;
  67. }
  68. public virtual int GetTailSpace()
  69. {
  70. return Buf.Length - Index;
  71. }
  72. public virtual byte[] GetBuffer()
  73. {
  74. return Buf;
  75. }
  76. public virtual int Align(int boundary, byte value)
  77. {
  78. int n = Align(boundary);
  79. int i = n;
  80. while (i > 0)
  81. {
  82. Buf[Index - i] = value;
  83. i--;
  84. }
  85. return n;
  86. }
  87. public virtual void WriteOctetArray(byte[] b, int i, int l)
  88. {
  89. Array.Copy(b, i, Buf, Index, l);
  90. Advance(l);
  91. }
  92. public virtual void ReadOctetArray(byte[] b, int i, int l)
  93. {
  94. Array.Copy(Buf, Index, b, i, l);
  95. Advance(l);
  96. }
  97. public virtual int GetLength()
  98. {
  99. return Deferred.Length;
  100. }
  101. public virtual void SetLength(int length)
  102. {
  103. Deferred.Length = length;
  104. }
  105. public virtual void Advance(int n)
  106. {
  107. Index += n;
  108. if ((Index - Start) > Deferred.Length)
  109. {
  110. Deferred.Length = Index - Start;
  111. }
  112. }
  113. public virtual int Align(int boundary)
  114. {
  115. int m = boundary - 1;
  116. int i = Index - Start;
  117. int n = ((i + m) & ~m) - i;
  118. Advance(n);
  119. return n;
  120. }
  121. public virtual void Enc_ndr_small(int s)
  122. {
  123. Buf[Index] = unchecked((byte)(s & unchecked(0xFF)));
  124. Advance(1);
  125. }
  126. public virtual int Dec_ndr_small()
  127. {
  128. int val = Buf[Index] & unchecked(0xFF);
  129. Advance(1);
  130. return val;
  131. }
  132. public virtual void Enc_ndr_short(int s)
  133. {
  134. Align(2);
  135. Encdec.Enc_uint16le((short)s, Buf, Index);
  136. Advance(2);
  137. }
  138. public virtual int Dec_ndr_short()
  139. {
  140. Align(2);
  141. int val = Encdec.Dec_uint16le(Buf, Index);
  142. Advance(2);
  143. return val;
  144. }
  145. public virtual void Enc_ndr_long(int l)
  146. {
  147. Align(4);
  148. Encdec.Enc_uint32le(l, Buf, Index);
  149. Advance(4);
  150. }
  151. public virtual int Dec_ndr_long()
  152. {
  153. Align(4);
  154. int val = Encdec.Dec_uint32le(Buf, Index);
  155. Advance(4);
  156. return val;
  157. }
  158. public virtual void Enc_ndr_hyper(long h)
  159. {
  160. Align(8);
  161. Encdec.Enc_uint64le(h, Buf, Index);
  162. Advance(8);
  163. }
  164. public virtual long Dec_ndr_hyper()
  165. {
  166. Align(8);
  167. long val = Encdec.Dec_uint64le(Buf, Index);
  168. Advance(8);
  169. return val;
  170. }
  171. public virtual void Enc_ndr_string(string s)
  172. {
  173. Align(4);
  174. int i = Index;
  175. int len = s.Length;
  176. Encdec.Enc_uint32le(len + 1, Buf, i);
  177. i += 4;
  178. Encdec.Enc_uint32le(0, Buf, i);
  179. i += 4;
  180. Encdec.Enc_uint32le(len + 1, Buf, i);
  181. i += 4;
  182. try
  183. {
  184. Array.Copy(Runtime.GetBytesForString(s, "UTF-16LE"), 0, Buf, i, len
  185. * 2);
  186. }
  187. catch (UnsupportedEncodingException)
  188. {
  189. }
  190. i += len * 2;
  191. Buf[i++] = unchecked((byte)('\0'));
  192. Buf[i++] = unchecked((byte)('\0'));
  193. Advance(i - Index);
  194. }
  195. /// <exception cref="SharpCifs.Dcerpc.Ndr.NdrException"></exception>
  196. public virtual string Dec_ndr_string()
  197. {
  198. Align(4);
  199. int i = Index;
  200. string val = null;
  201. int len = Encdec.Dec_uint32le(Buf, i);
  202. i += 12;
  203. if (len != 0)
  204. {
  205. len--;
  206. int size = len * 2;
  207. try
  208. {
  209. if (size < 0 || size > unchecked(0xFFFF))
  210. {
  211. throw new NdrException(NdrException.InvalidConformance);
  212. }
  213. val = Runtime.GetStringForBytes(Buf, i, size, "UTF-16LE");
  214. i += size + 2;
  215. }
  216. catch (UnsupportedEncodingException)
  217. {
  218. }
  219. }
  220. Advance(i - Index);
  221. return val;
  222. }
  223. private int GetDceReferent(object obj)
  224. {
  225. Entry e;
  226. if (Referents == null)
  227. {
  228. Referents = new Hashtable();
  229. Referent = 1;
  230. }
  231. if ((e = (Entry)Referents.Get(obj)) == null)
  232. {
  233. e = new Entry();
  234. e.Referent = Referent++;
  235. e.Obj = obj;
  236. Referents.Put(obj, e);
  237. }
  238. return e.Referent;
  239. }
  240. public virtual void Enc_ndr_referent(object obj, int type)
  241. {
  242. if (obj == null)
  243. {
  244. Enc_ndr_long(0);
  245. return;
  246. }
  247. switch (type)
  248. {
  249. case 1:
  250. case 3:
  251. {
  252. Enc_ndr_long(Runtime.IdentityHashCode(obj));
  253. return;
  254. }
  255. case 2:
  256. {
  257. Enc_ndr_long(GetDceReferent(obj));
  258. return;
  259. }
  260. }
  261. }
  262. public override string ToString()
  263. {
  264. return "start=" + Start + ",index=" + Index + ",length=" + GetLength();
  265. }
  266. }
  267. }