Name.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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 System.Text;
  19. using SharpCifs.Util;
  20. using SharpCifs.Util.Sharpen;
  21. namespace SharpCifs.Netbios
  22. {
  23. public class Name
  24. {
  25. private const int TypeOffset = 31;
  26. private const int ScopeOffset = 33;
  27. private static readonly string DefaultScope
  28. = Config.GetProperty("jcifs.netbios.scope");
  29. internal static readonly string OemEncoding
  30. = Config.GetProperty("jcifs.encoding", Runtime.GetProperty("file.encoding"));
  31. public string name;
  32. public string Scope;
  33. public int HexCode;
  34. internal int SrcHashCode;
  35. public Name()
  36. {
  37. }
  38. public Name(string name, int hexCode, string scope)
  39. {
  40. if (name.Length > 15)
  41. {
  42. name = Runtime.Substring(name, 0, 15);
  43. }
  44. this.name = name.ToUpper();
  45. this.HexCode = hexCode;
  46. this.Scope = !string.IsNullOrEmpty(scope) ? scope : DefaultScope;
  47. SrcHashCode = 0;
  48. }
  49. internal virtual int WriteWireFormat(byte[] dst, int dstIndex)
  50. {
  51. // write 0x20 in first byte
  52. dst[dstIndex] = unchecked(0x20);
  53. // write name
  54. try
  55. {
  56. byte[] tmp = Runtime.GetBytesForString(name, OemEncoding
  57. );
  58. int i;
  59. for (i = 0; i < tmp.Length; i++)
  60. {
  61. dst[dstIndex + (2 * i + 1)]
  62. = unchecked((byte)(((tmp[i] & unchecked(0xF0)) >> 4) + unchecked(0x41)));
  63. dst[dstIndex + (2 * i + 2)]
  64. = unchecked((byte)((tmp[i] & unchecked(0x0F)) + unchecked(0x41)));
  65. }
  66. for (; i < 15; i++)
  67. {
  68. dst[dstIndex + (2 * i + 1)] = unchecked(unchecked(0x43));
  69. dst[dstIndex + (2 * i + 2)] = unchecked(unchecked(0x41));
  70. }
  71. dst[dstIndex + TypeOffset]
  72. = unchecked((byte)(((HexCode & unchecked(0xF0)) >> 4) + unchecked(0x41)));
  73. dst[dstIndex + TypeOffset + 1]
  74. = unchecked((byte)((HexCode & unchecked(0x0F)) + unchecked(0x41)));
  75. }
  76. catch (UnsupportedEncodingException)
  77. {
  78. }
  79. return ScopeOffset + WriteScopeWireFormat(dst, dstIndex + ScopeOffset);
  80. }
  81. internal virtual int ReadWireFormat(byte[] src, int srcIndex)
  82. {
  83. byte[] tmp = new byte[ScopeOffset];
  84. int length = 15;
  85. for (int i = 0; i < 15; i++)
  86. {
  87. tmp[i] = unchecked(
  88. (byte)(
  89. ((src[srcIndex + (2 * i + 1)] & unchecked(0xFF)) - unchecked(0x41)) << 4
  90. )
  91. );
  92. tmp[i] |= unchecked(
  93. (byte)(
  94. ((src[srcIndex + (2 * i + 2)] & unchecked(0xFF)) - unchecked(0x41))
  95. & unchecked(0x0F)
  96. )
  97. );
  98. if (tmp[i] != unchecked((byte)' '))
  99. {
  100. length = i + 1;
  101. }
  102. }
  103. try
  104. {
  105. name = Runtime.GetStringForBytes(tmp, 0, length, OemEncoding
  106. );
  107. }
  108. catch (UnsupportedEncodingException)
  109. {
  110. }
  111. HexCode = ((src[srcIndex + TypeOffset] & unchecked(0xFF)) - unchecked(0x41)) << 4;
  112. HexCode |= ((src[srcIndex + TypeOffset + 1] & unchecked(0xFF)) - unchecked(0x41))
  113. & unchecked(0x0F);
  114. return ScopeOffset + ReadScopeWireFormat(src, srcIndex + ScopeOffset);
  115. }
  116. internal int ReadWireFormatDos(byte[] src, int srcIndex)
  117. {
  118. int length = 15;
  119. byte[] tmp = new byte[length];
  120. Array.Copy(src, srcIndex, tmp, 0, length);
  121. try
  122. {
  123. name = Runtime.GetStringForBytes(tmp, 0, length).Trim();
  124. }
  125. catch (Exception)
  126. {
  127. }
  128. HexCode = src[srcIndex + length];
  129. return length + 1;
  130. }
  131. internal virtual int WriteScopeWireFormat(byte[] dst, int dstIndex)
  132. {
  133. if (Scope == null)
  134. {
  135. dst[dstIndex] = unchecked(unchecked(0x00));
  136. return 1;
  137. }
  138. // copy new scope in
  139. dst[dstIndex++] = unchecked((byte)('.'));
  140. try
  141. {
  142. Array.Copy(Runtime.GetBytesForString(Scope, OemEncoding),
  143. 0, dst, dstIndex, Scope.Length);
  144. }
  145. catch (UnsupportedEncodingException)
  146. {
  147. }
  148. dstIndex += Scope.Length;
  149. dst[dstIndex++] = unchecked(unchecked(0x00));
  150. // now go over scope backwards converting '.' to label length
  151. int i = dstIndex - 2;
  152. int e = i - Scope.Length;
  153. int c = 0;
  154. do
  155. {
  156. if (dst[i] == '.')
  157. {
  158. dst[i] = unchecked((byte)c);
  159. c = 0;
  160. }
  161. else
  162. {
  163. c++;
  164. }
  165. }
  166. while (i-- > e);
  167. return Scope.Length + 2;
  168. }
  169. internal virtual int ReadScopeWireFormat(byte[] src, int srcIndex)
  170. {
  171. int start = srcIndex;
  172. int n;
  173. StringBuilder sb;
  174. if ((n = src[srcIndex++] & unchecked(0xFF)) == 0)
  175. {
  176. Scope = null;
  177. return 1;
  178. }
  179. try
  180. {
  181. sb = new StringBuilder(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding));
  182. srcIndex += n;
  183. while ((n = src[srcIndex++] & unchecked(0xFF)) != 0)
  184. {
  185. sb.Append('.').Append(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding));
  186. srcIndex += n;
  187. }
  188. Scope = sb.ToString();
  189. }
  190. catch (UnsupportedEncodingException)
  191. {
  192. }
  193. return srcIndex - start;
  194. }
  195. public override int GetHashCode()
  196. {
  197. int result;
  198. result = name.GetHashCode();
  199. result += 65599 * HexCode;
  200. result += 65599 * SrcHashCode;
  201. if (Scope != null && Scope.Length != 0)
  202. {
  203. result += Scope.GetHashCode();
  204. }
  205. return result;
  206. }
  207. public override bool Equals(object obj)
  208. {
  209. Name n;
  210. if (!(obj is Name))
  211. {
  212. return false;
  213. }
  214. n = (Name)obj;
  215. if (Scope == null && n.Scope == null)
  216. {
  217. return name.Equals(n.name) && HexCode == n.HexCode;
  218. }
  219. return name.Equals(n.name) && HexCode == n.HexCode && Scope.Equals(n.Scope);
  220. }
  221. public override string ToString()
  222. {
  223. StringBuilder sb = new StringBuilder();
  224. //return "";
  225. string n = name;
  226. // fix MSBROWSE name
  227. if (n == null)
  228. {
  229. n = "null";
  230. }
  231. else
  232. {
  233. if (n[0] == unchecked(0x01))
  234. {
  235. char[] c = n.ToCharArray();
  236. c[0] = '.';
  237. c[1] = '.';
  238. c[14] = '.';
  239. n = new string(c);
  240. }
  241. }
  242. sb.Append(n).Append("<").Append(Hexdump.ToHexString(HexCode, 2)).Append(">");
  243. if (Scope != null)
  244. {
  245. sb.Append(".").Append(Scope);
  246. }
  247. return sb.ToString();
  248. }
  249. }
  250. }