// 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 System.Text; using SharpCifs.Util; using SharpCifs.Util.Sharpen; namespace SharpCifs.Netbios { public class Name { private const int TypeOffset = 31; private const int ScopeOffset = 33; private static readonly string DefaultScope = Config.GetProperty("jcifs.netbios.scope" ); internal static readonly string OemEncoding = Config.GetProperty("jcifs.encoding" , Runtime.GetProperty("file.encoding")); public string name; public string Scope; public int HexCode; internal int SrcHashCode; public Name() { } public Name(string name, int hexCode, string scope) { if (name.Length > 15) { name = Runtime.Substring(name, 0, 15); } this.name = name.ToUpper(); this.HexCode = hexCode; this.Scope = !string.IsNullOrEmpty(scope) ? scope : DefaultScope; SrcHashCode = 0; } internal virtual int WriteWireFormat(byte[] dst, int dstIndex) { // write 0x20 in first byte dst[dstIndex] = unchecked(0x20); // write name try { byte[] tmp = Runtime.GetBytesForString(name, OemEncoding ); int i; for (i = 0; i < tmp.Length; i++) { dst[dstIndex + (2 * i + 1)] = unchecked((byte)(((tmp[i] & unchecked(0xF0)) >> 4) + unchecked(0x41))); dst[dstIndex + (2 * i + 2)] = unchecked((byte)((tmp[i] & unchecked(0x0F)) + unchecked(0x41))); } for (; i < 15; i++) { dst[dstIndex + (2 * i + 1)] = unchecked(unchecked(0x43)); dst[dstIndex + (2 * i + 2)] = unchecked(unchecked(0x41)); } dst[dstIndex + TypeOffset] = unchecked((byte)(((HexCode & unchecked(0xF0) ) >> 4) + unchecked(0x41))); dst[dstIndex + TypeOffset + 1] = unchecked((byte)((HexCode & unchecked(0x0F)) + unchecked(0x41))); } catch (UnsupportedEncodingException) { } return ScopeOffset + WriteScopeWireFormat(dst, dstIndex + ScopeOffset); } internal virtual int ReadWireFormat(byte[] src, int srcIndex) { byte[] tmp = new byte[ScopeOffset]; int length = 15; for (int i = 0; i < 15; i++) { tmp[i] = unchecked((byte)(((src[srcIndex + (2 * i + 1)] & unchecked(0xFF)) - unchecked(0x41)) << 4)); tmp[i] |= unchecked((byte)(((src[srcIndex + (2 * i + 2)] & unchecked(0xFF) ) - unchecked(0x41)) & unchecked(0x0F))); if (tmp[i] != unchecked((byte)' ')) { length = i + 1; } } try { name = Runtime.GetStringForBytes(tmp, 0, length, OemEncoding ); } catch (UnsupportedEncodingException) { } HexCode = ((src[srcIndex + TypeOffset] & unchecked(0xFF)) - unchecked(0x41)) << 4; HexCode |= ((src[srcIndex + TypeOffset + 1] & unchecked(0xFF)) - unchecked( 0x41)) & unchecked(0x0F); return ScopeOffset + ReadScopeWireFormat(src, srcIndex + ScopeOffset); } internal int ReadWireFormatDos(byte[] src, int srcIndex) { int length = 15; byte[] tmp = new byte[length]; Array.Copy(src, srcIndex, tmp, 0, length); try { name = Runtime.GetStringForBytes(tmp, 0, length).Trim(); } catch (Exception ex) { } HexCode = src[srcIndex + length]; return length + 1; } internal virtual int WriteScopeWireFormat(byte[] dst, int dstIndex) { if (Scope == null) { dst[dstIndex] = unchecked(unchecked(0x00)); return 1; } // copy new scope in dst[dstIndex++] = unchecked((byte)('.')); try { Array.Copy(Runtime.GetBytesForString(Scope, OemEncoding ), 0, dst, dstIndex, Scope.Length); } catch (UnsupportedEncodingException) { } dstIndex += Scope.Length; dst[dstIndex++] = unchecked(unchecked(0x00)); // now go over scope backwards converting '.' to label length int i = dstIndex - 2; int e = i - Scope.Length; int c = 0; do { if (dst[i] == '.') { dst[i] = unchecked((byte)c); c = 0; } else { c++; } } while (i-- > e); return Scope.Length + 2; } internal virtual int ReadScopeWireFormat(byte[] src, int srcIndex) { int start = srcIndex; int n; StringBuilder sb; if ((n = src[srcIndex++] & unchecked(0xFF)) == 0) { Scope = null; return 1; } try { sb = new StringBuilder(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding)); srcIndex += n; while ((n = src[srcIndex++] & unchecked(0xFF)) != 0) { sb.Append('.').Append(Runtime.GetStringForBytes(src, srcIndex, n, OemEncoding)); srcIndex += n; } Scope = sb.ToString(); } catch (UnsupportedEncodingException) { } return srcIndex - start; } public override int GetHashCode() { int result; result = name.GetHashCode(); result += 65599 * HexCode; result += 65599 * SrcHashCode; if (Scope != null && Scope.Length != 0) { result += Scope.GetHashCode(); } return result; } public override bool Equals(object obj) { Name n; if (!(obj is Name)) { return false; } n = (Name)obj; if (Scope == null && n.Scope == null) { return name.Equals(n.name) && HexCode == n.HexCode; } return name.Equals(n.name) && HexCode == n.HexCode && Scope.Equals(n.Scope); } public override string ToString() { StringBuilder sb = new StringBuilder(); //return ""; string n = name; // fix MSBROWSE name if (n == null) { n = "null"; } else { if (n[0] == unchecked(0x01)) { char[] c = n.ToCharArray(); c[0] = '.'; c[1] = '.'; c[14] = '.'; n = new string(c); } } sb.Append(n).Append("<").Append(Hexdump.ToHexString(HexCode, 2)).Append(">"); if (Scope != null) { sb.Append(".").Append(Scope); } return sb.ToString(); } } }