/// <summary> /// Disconnect the session /// </summary> /// <param name="sessionId">The session id</param> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when disconnect fails /// </exception> public void Disconnect(int sessionId) { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBHANGUP; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_lsn = (byte)sessionId; InvokeNetBios(ref ncb); //if remote machine disconnect the session first, local call disconnect will return NRC_SNUMOUT, //and this is not an error which we need to notify user. if ((ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) && (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_SNUMOUT) && (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_SCLOSED)) { throw new InvalidOperationException("Failed in NCBHANGUP command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Cancel the previous pending listen call /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> public void CancelListen() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } lock (listeningNcbLocker) { if (listeningNcbPtr == IntPtr.Zero) { return; } NCB ncb = new NCB(); NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBCANCEL; ncb.ncb_buffer = listeningNcbPtr; ncb.ncb_length = (ushort)listeningNcbSize; ncb.ncb_lana_num = networkAdapterId; InvokeNetBios(ref ncb); } }
/// <summary> /// Listen to local netbios endpoint /// </summary> /// <returns>The connected session id</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when listen fails /// </exception> public byte Listen() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBLISTEN; ncb.ncb_lana_num = networkAdapterId; //* means it can accept any connection. ncb.ncb_callname = NetbiosUtility.ToNetbiosName("*"); ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBLISTEN command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } return(ncb.ncb_lsn); }
/// <summary> /// Unregister the bios name /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> public void UnRegisterName() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } // if the local name in .ctr is null, exception is thrown, // the gc will dispose the object and this method will be invoked. if (this.localNetbiosName == null) { return; } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBDELNAME; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_num = ncbNum; ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); InvokeNetBios(ref ncb); } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Reset the adapter, it will clear all registered names, and reset the maxsession, /// maxName /// </summary> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when reset adapter fails /// </exception> public void ResetAdapter() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBRESET; ncb.ncb_lana_num = networkAdapterId; Marshal.WriteByte(ncb.ncb_callname, 0, this.maxSessionNum); Marshal.WriteByte(ncb.ncb_callname, 2, this.maxNames); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBRESET command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Register bios name for further call /// </summary> /// <returns>The name index</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when register name fails /// </exception> public byte RegisterName() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBADDNAME; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBADDNAME command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } this.ncbNum = ncb.ncb_num; return(ncb.ncb_num); } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Marshal NCB structure to native buffer /// </summary> /// <param name="ncb">The NCB structure</param> /// <param name="ncbSize">The native buffer size</param> /// <returns>The native buffer point</returns> public static IntPtr MarshalNcb(ref NCB ncb, out int ncbSize) { // size: if (IsWin64()) { ncbSize = NetbiosUtility.Win64NcbStructSize; } else { ncbSize = NetbiosUtility.Win32NcbStructSize; } // the IntPtr used to marshal/unmarshal the NCB struct: IntPtr pNcb = Marshal.AllocHGlobal(ncbSize); // to bytes: byte[] ncbBytes = new byte[ncbSize]; using (MemoryStream stream = new MemoryStream(ncbBytes, true)) { stream.WriteByte((byte)ncb.ncb_command); stream.WriteByte((byte)ncb.ncb_retcode); stream.WriteByte(ncb.ncb_lsn); stream.WriteByte(ncb.ncb_num); if (ncb.ncb_padding0 != null) { stream.Write(ncb.ncb_padding0, 0, ncb.ncb_padding0.Length); } stream.Write(BitConverter.GetBytes(ncb.ncb_buffer.ToInt64()), 0, IntPtr.Size); stream.Write(BitConverter.GetBytes(ncb.ncb_length), 0, 2); stream.Write(ncb.ncb_callname, 0, ncb.ncb_callname.Length); stream.Write(ncb.ncb_name, 0, ncb.ncb_name.Length); stream.WriteByte(ncb.ncb_rto); stream.WriteByte(ncb.ncb_sto); if (ncb.ncb_padding1 != null) { stream.Write(ncb.ncb_padding1, 0, ncb.ncb_padding1.Length); } stream.Write(BitConverter.GetBytes(ncb.ncb_post.ToInt64()), 0, IntPtr.Size); stream.WriteByte(ncb.ncb_lana_num); stream.WriteByte(ncb.ncb_cmd_cplt); stream.Write(ncb.ncb_reserve, 0, ncb.ncb_reserve.Length); if (ncb.ncb_padding2 != null) { stream.Write(ncb.ncb_padding2, 0, ncb.ncb_padding2.Length); } stream.Write(BitConverter.GetBytes(ncb.ncb_event.ToInt64()), 0, IntPtr.Size); Marshal.Copy(ncbBytes, 0, pNcb, ncbSize); } return(pNcb); }
/// <summary> /// Initiate NCB structure /// </summary> /// <param name="ncb">The NCB structure</param> public static void InitNcb(ref NCB ncb) { ncb.ncb_callname = new byte[NetbiosUtility.NCBNAMSZ]; ncb.ncb_name = new byte[NetbiosUtility.NCBNAMSZ]; if (IsWin64()) { ncb.ncb_padding0 = new byte[NetbiosUtility.Win64NcbPaddingSize]; ncb.ncb_padding1 = new byte[NetbiosUtility.Win64NcbPaddingSize]; ncb.ncb_padding2 = new byte[NetbiosUtility.Win64NcbPaddingSize]; ncb.ncb_reserve = new byte[NetbiosUtility.NCBRSVSZ64]; } else { ncb.ncb_reserve = new byte[NetbiosUtility.NCBRSVSZ32]; } }
/// <summary> /// Free native resource the ncb used /// </summary> /// <param name="ncb">The network control block</param> public static void FreeNcbNativeFields(ref NCB ncb) { if (ncb.ncb_buffer != IntPtr.Zero) { Marshal.FreeHGlobal(ncb.ncb_buffer); ncb.ncb_buffer = IntPtr.Zero; } if (ncb.ncb_event != IntPtr.Zero) { Marshal.FreeHGlobal(ncb.ncb_event); ncb.ncb_event = IntPtr.Zero; } if (ncb.ncb_post != IntPtr.Zero) { Marshal.FreeHGlobal(ncb.ncb_post); ncb.ncb_post = IntPtr.Zero; } }
/// <summary> /// Receive data /// </summary> /// <param name="sessionId">Specified the session identify</param> /// <returns>The received data</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when receive encounters error. /// </exception> public byte[] Receive(int sessionId) { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBRECV; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_lsn = (byte)sessionId; ncb.ncb_buffer = Marshal.AllocHGlobal(maxBufferSize); ncb.ncb_length = maxBufferSize; InvokeNetBios(ref ncb); if (ncb.ncb_retcode == (byte)NcbReturnCode.NRC_SCLOSED) { return(null); } if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBRECV command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } byte[] receivedData = new byte[ncb.ncb_length]; Marshal.Copy(ncb.ncb_buffer, receivedData, 0, receivedData.Length); return(receivedData); } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Get the adapter id /// </summary> /// <returns>The adapter id</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when Get adapterId fails /// </exception> public byte GetAdapterId() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBENUM; ncb.ncb_buffer = Marshal.AllocHGlobal(maxBufferSize); ncb.ncb_length = maxBufferSize; InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBENUM command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } LANA_ENUM lenum = new LANA_ENUM(); lenum.length = Marshal.ReadByte(ncb.ncb_buffer, 0); lenum.lanaNum = new byte[lenum.length]; for (int i = 0; i < lenum.length; i++) { lenum.lanaNum[i] = Marshal.ReadByte(ncb.ncb_buffer, i + 1); } return(lenum.lanaNum[adapterIndex]); } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Connect to remote machine /// </summary> /// <param name="remoteName">The remote machine bios name</param> /// <returns>The session id</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when connect fails. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when remoteName is null. /// </exception> public int Connect(string remoteName) { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } if (remoteName == null) { throw new ArgumentNullException("remoteName"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBCALL; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); ncb.ncb_callname = NetbiosUtility.ToNetbiosName(remoteName); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBCALL command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } return(ncb.ncb_lsn); }
/// <summary> /// Send data /// </summary> /// <param name="sessionId">The session id</param> /// <param name="buffer">The data buffer</param> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// throw when the buffer is larger than the max buffer size /// </exception> /// <exception cref="InvalidOperationException"> /// throw when call native netbios api fails /// </exception> public void Send(int sessionId, byte[] buffer) { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBSEND; ncb.ncb_buffer = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, ncb.ncb_buffer, buffer.Length); ncb.ncb_length = (ushort)buffer.Length; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_lsn = (byte)sessionId; InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBSEND command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Call native Netbios interface /// </summary> /// <param name="ncb">The NCB structure</param> private void InvokeNetBios(ref NCB ncb) { IntPtr ncbPtr = IntPtr.Zero; int ncbSize = 0; try { lock (listeningNcbLocker) { ncbPtr = NetbiosUtility.MarshalNcb(ref ncb, out ncbSize); if (ncb.ncb_command == (byte)NcbCommand.NCBLISTEN) { listeningNcbPtr = ncbPtr; listeningNcbSize = ncbSize; } } NetbiosNativeMethods.Netbios(ncbPtr); ncb = NetbiosUtility.UnMarshalNcb(ncbPtr, ncbSize); } finally { lock (listeningNcbLocker) { Marshal.FreeHGlobal(ncbPtr); if (ncb.ncb_command == (byte)NcbCommand.NCBLISTEN) { listeningNcbPtr = IntPtr.Zero; listeningNcbSize = 0; } } } }
/// <summary> /// Un marshal NCB structure from a native buffer /// </summary> /// <param name="ncbPtr">The native buffer point</param> /// <param name="ncbSize">The native buffer size</param> /// <returns>The un-marshaled NCB structure</returns> /// <exception cref="System.InvalidOperationException"> /// Throw when there is no enough data can be unmarshaled. /// </exception> public static NCB UnMarshalNcb(IntPtr ncbPtr, int ncbSize) { NCB ncb = new NCB(); NetbiosUtility.InitNcb(ref ncb); byte[] ncbBytes = new byte[ncbSize]; // to struct: Marshal.Copy(ncbPtr, ncbBytes, 0, ncbBytes.Length); using (MemoryStream stream = new MemoryStream(ncbBytes, false)) { int readedBufferCount = 0; ncb.ncb_command = (byte)stream.ReadByte(); ncb.ncb_retcode = (byte)stream.ReadByte(); ncb.ncb_lsn = (byte)stream.ReadByte(); ncb.ncb_num = (byte)stream.ReadByte(); if (ncb.ncb_padding0 != null) { stream.Read(ncb.ncb_padding0, 0, ncb.ncb_padding0.Length); } byte[] ncbBuffer = new byte[IntPtr.Size]; readedBufferCount = stream.Read(ncbBuffer, 0, ncbBuffer.Length); if (readedBufferCount != ncbBuffer.Length) { throw new InvalidOperationException("No enough data can be read"); } if (!IsWin64()) { ncb.ncb_buffer = new IntPtr(BitConverter.ToInt32(ncbBuffer, 0)); } else { ncb.ncb_buffer = new IntPtr(BitConverter.ToInt64(ncbBuffer, 0)); } byte[] ncbLength = new byte[sizeof(ushort)]; readedBufferCount = stream.Read(ncbLength, 0, ncbLength.Length); if (readedBufferCount != ncbLength.Length) { throw new InvalidOperationException("No enough data can be read"); } ncb.ncb_length = (ushort)BitConverter.ToInt16(ncbLength, 0); readedBufferCount = stream.Read(ncb.ncb_callname, 0, ncb.ncb_callname.Length); if (readedBufferCount != ncb.ncb_callname.Length) { throw new InvalidOperationException("No enough data can be read"); } readedBufferCount = stream.Read(ncb.ncb_name, 0, ncb.ncb_name.Length); if (readedBufferCount != ncb.ncb_name.Length) { throw new InvalidOperationException("No enough data can be read"); } ncb.ncb_rto = (byte)stream.ReadByte(); ncb.ncb_sto = (byte)stream.ReadByte(); if (ncb.ncb_padding1 != null) { stream.Read(ncb.ncb_padding1, 0, ncb.ncb_padding1.Length); } byte[] ncbPost = new byte[IntPtr.Size]; stream.Read(ncbPost, 0, ncbPost.Length); if (!IsWin64()) { ncb.ncb_post = new IntPtr(BitConverter.ToInt32(ncbPost, 0)); } else { ncb.ncb_post = new IntPtr(BitConverter.ToInt64(ncbPost, 0)); } ncb.ncb_lana_num = (byte)stream.ReadByte(); ncb.ncb_cmd_cplt = (byte)stream.ReadByte(); stream.Read(ncb.ncb_reserve, 0, ncb.ncb_reserve.Length); if (ncb.ncb_padding2 != null) { stream.Read(ncb.ncb_padding2, 0, ncb.ncb_padding2.Length); } byte[] ncbEvent = new byte[IntPtr.Size]; readedBufferCount = stream.Read(ncbEvent, 0, ncbEvent.Length); if (readedBufferCount != ncbEvent.Length) { throw new InvalidOperationException("No enough data can be read"); } if (!IsWin64()) { ncb.ncb_event = new IntPtr(BitConverter.ToInt32(ncbEvent, 0)); } else { ncb.ncb_event = new IntPtr(BitConverter.ToInt64(ncbEvent, 0)); } } return(ncb); }
/// <summary> /// Un marshal NCB structure from a native buffer /// </summary> /// <param name="ncbPtr">The native buffer point</param> /// <param name="ncbSize">The native buffer size</param> /// <returns>The un-marshaled NCB structure</returns> /// <exception cref="System.InvalidOperationException"> /// Throw when there is no enough data can be unmarshaled. /// </exception> public static NCB UnMarshalNcb(IntPtr ncbPtr, int ncbSize) { NCB ncb = new NCB(); NetbiosUtility.InitNcb(ref ncb); byte[] ncbBytes = new byte[ncbSize]; // to struct: Marshal.Copy(ncbPtr, ncbBytes, 0, ncbBytes.Length); using (MemoryStream stream = new MemoryStream(ncbBytes, false)) { int readedBufferCount = 0; ncb.ncb_command = (byte)stream.ReadByte(); ncb.ncb_retcode = (byte)stream.ReadByte(); ncb.ncb_lsn = (byte)stream.ReadByte(); ncb.ncb_num = (byte)stream.ReadByte(); if (ncb.ncb_padding0 != null) { stream.Read(ncb.ncb_padding0, 0, ncb.ncb_padding0.Length); } byte[] ncbBuffer = new byte[IntPtr.Size]; readedBufferCount = stream.Read(ncbBuffer, 0, ncbBuffer.Length); if (readedBufferCount != ncbBuffer.Length) { throw new InvalidOperationException("No enough data can be read"); } if (!IsWin64()) { ncb.ncb_buffer = new IntPtr(BitConverter.ToInt32(ncbBuffer, 0)); } else { ncb.ncb_buffer = new IntPtr(BitConverter.ToInt64(ncbBuffer, 0)); } byte[] ncbLength = new byte[sizeof(ushort)]; readedBufferCount = stream.Read(ncbLength, 0, ncbLength.Length); if (readedBufferCount != ncbLength.Length) { throw new InvalidOperationException("No enough data can be read"); } ncb.ncb_length = (ushort)BitConverter.ToInt16(ncbLength, 0); readedBufferCount = stream.Read(ncb.ncb_callname, 0, ncb.ncb_callname.Length); if (readedBufferCount != ncb.ncb_callname.Length) { throw new InvalidOperationException("No enough data can be read"); } readedBufferCount = stream.Read(ncb.ncb_name, 0, ncb.ncb_name.Length); if (readedBufferCount != ncb.ncb_name.Length) { throw new InvalidOperationException("No enough data can be read"); } ncb.ncb_rto = (byte)stream.ReadByte(); ncb.ncb_sto = (byte)stream.ReadByte(); if (ncb.ncb_padding1 != null) { stream.Read(ncb.ncb_padding1, 0, ncb.ncb_padding1.Length); } byte[] ncbPost = new byte[IntPtr.Size]; stream.Read(ncbPost, 0, ncbPost.Length); if (!IsWin64()) { ncb.ncb_post = new IntPtr(BitConverter.ToInt32(ncbPost, 0)); } else { ncb.ncb_post = new IntPtr(BitConverter.ToInt64(ncbPost, 0)); } ncb.ncb_lana_num = (byte)stream.ReadByte(); ncb.ncb_cmd_cplt = (byte)stream.ReadByte(); stream.Read(ncb.ncb_reserve, 0, ncb.ncb_reserve.Length); if (ncb.ncb_padding2 != null) { stream.Read(ncb.ncb_padding2, 0, ncb.ncb_padding2.Length); } byte[] ncbEvent = new byte[IntPtr.Size]; readedBufferCount = stream.Read(ncbEvent, 0, ncbEvent.Length); if (readedBufferCount != ncbEvent.Length) { throw new InvalidOperationException("No enough data can be read"); } if (!IsWin64()) { ncb.ncb_event = new IntPtr(BitConverter.ToInt32(ncbEvent, 0)); } else { ncb.ncb_event = new IntPtr(BitConverter.ToInt64(ncbEvent, 0)); } } return ncb; }
/// <summary> /// Marshal NCB structure to native buffer /// </summary> /// <param name="ncb">The NCB structure</param> /// <param name="ncbSize">The native buffer size</param> /// <returns>The native buffer point</returns> public static IntPtr MarshalNcb(ref NCB ncb, out int ncbSize) { // size: if (IsWin64()) { ncbSize = NetbiosUtility.Win64NcbStructSize; } else { ncbSize = NetbiosUtility.Win32NcbStructSize; } // the IntPtr used to marshal/unmarshal the NCB struct: IntPtr pNcb = Marshal.AllocHGlobal(ncbSize); // to bytes: byte[] ncbBytes = new byte[ncbSize]; using (MemoryStream stream = new MemoryStream(ncbBytes, true)) { stream.WriteByte((byte)ncb.ncb_command); stream.WriteByte((byte)ncb.ncb_retcode); stream.WriteByte(ncb.ncb_lsn); stream.WriteByte(ncb.ncb_num); if (ncb.ncb_padding0 != null) { stream.Write(ncb.ncb_padding0, 0, ncb.ncb_padding0.Length); } stream.Write(BitConverter.GetBytes(ncb.ncb_buffer.ToInt64()), 0, IntPtr.Size); stream.Write(BitConverter.GetBytes(ncb.ncb_length), 0, 2); stream.Write(ncb.ncb_callname, 0, ncb.ncb_callname.Length); stream.Write(ncb.ncb_name, 0, ncb.ncb_name.Length); stream.WriteByte(ncb.ncb_rto); stream.WriteByte(ncb.ncb_sto); if (ncb.ncb_padding1 != null) { stream.Write(ncb.ncb_padding1, 0, ncb.ncb_padding1.Length); } stream.Write(BitConverter.GetBytes(ncb.ncb_post.ToInt64()), 0, IntPtr.Size); stream.WriteByte(ncb.ncb_lana_num); stream.WriteByte(ncb.ncb_cmd_cplt); stream.Write(ncb.ncb_reserve, 0, ncb.ncb_reserve.Length); if (ncb.ncb_padding2 != null) { stream.Write(ncb.ncb_padding2, 0, ncb.ncb_padding2.Length); } stream.Write(BitConverter.GetBytes(ncb.ncb_event.ToInt64()), 0, IntPtr.Size); Marshal.Copy(ncbBytes, 0, pNcb, ncbSize); } return pNcb; }
/// <summary> /// Connect to remote machine /// </summary> /// <param name="remoteName">The remote machine bios name</param> /// <returns>The session id</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when connect fails. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when remoteName is null. /// </exception> public int Connect(string remoteName) { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } if (remoteName == null) { throw new ArgumentNullException("remoteName"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBCALL; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); ncb.ncb_callname = NetbiosUtility.ToNetbiosName(remoteName); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBCALL command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } return ncb.ncb_lsn; }
/// <summary> /// Get the adapter id /// </summary> /// <returns>The adapter id</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when Get adapterId fails /// </exception> public byte GetAdapterId() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBENUM; ncb.ncb_buffer = Marshal.AllocHGlobal(maxBufferSize); ncb.ncb_length = maxBufferSize; InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBENUM command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } LANA_ENUM lenum = new LANA_ENUM(); lenum.length = Marshal.ReadByte(ncb.ncb_buffer, 0); lenum.lanaNum = new byte[lenum.length]; for (int i = 0; i < lenum.length; i++) { lenum.lanaNum[i] = Marshal.ReadByte(ncb.ncb_buffer, i + 1); } return lenum.lanaNum[adapterIndex]; } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Listen to local netbios endpoint /// </summary> /// <returns>The connected session id</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when listen fails /// </exception> public byte Listen() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBLISTEN; ncb.ncb_lana_num = networkAdapterId; //* means it can accept any connection. ncb.ncb_callname = NetbiosUtility.ToNetbiosName("*"); ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBLISTEN command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } return ncb.ncb_lsn; }
/// <summary> /// Receive data /// </summary> /// <param name="sessionId">Specified the session identify</param> /// <returns>The received data</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when receive encounters error. /// </exception> public byte[] Receive(int sessionId) { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBRECV; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_lsn = (byte)sessionId; ncb.ncb_buffer = Marshal.AllocHGlobal(maxBufferSize); ncb.ncb_length = maxBufferSize; InvokeNetBios(ref ncb); if (ncb.ncb_retcode == (byte)NcbReturnCode.NRC_SCLOSED) { return null; } if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBRECV command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } byte[] receivedData = new byte[ncb.ncb_length]; Marshal.Copy(ncb.ncb_buffer, receivedData, 0, receivedData.Length); return receivedData; } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }
/// <summary> /// Register bios name for further call /// </summary> /// <returns>The name index</returns> /// <exception cref="ObjectDisposedException"> /// thrown when this object is disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// throw when register name fails /// </exception> public byte RegisterName() { if (disposed) { throw new ObjectDisposedException("NetbiosTransport"); } NCB ncb = new NCB(); try { NetbiosUtility.InitNcb(ref ncb); ncb.ncb_command = (byte)NcbCommand.NCBADDNAME; ncb.ncb_lana_num = networkAdapterId; ncb.ncb_name = NetbiosUtility.ToNetbiosName(localNetbiosName); InvokeNetBios(ref ncb); if (ncb.ncb_retcode != (byte)NcbReturnCode.NRC_GOODRET) { throw new InvalidOperationException("Failed in NCBADDNAME command, error is " + ((NcbReturnCode)ncb.ncb_retcode).ToString()); } this.ncbNum = ncb.ncb_num; return ncb.ncb_num; } finally { NetbiosUtility.FreeNcbNativeFields(ref ncb); } }