Initial commit
This commit is contained in:
		
							
								
								
									
										13
									
								
								PInvokeSerialPort/ASCII.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								PInvokeSerialPort/ASCII.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Byte type with enumeration constants for ASCII control codes.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum ASCII : byte
 | 
			
		||||
    {
 | 
			
		||||
        NULL = 0x00, SOH = 0x01, STH = 0x02, ETX = 0x03, EOT = 0x04, ENQ = 0x05, ACK = 0x06, BELL = 0x07,
 | 
			
		||||
        BS = 0x08, HT = 0x09, LF = 0x0A, VT = 0x0B, FF = 0x0C, CR = 0x0D, SO = 0x0E, SI = 0x0F, DC1 = 0x11,
 | 
			
		||||
        DC2 = 0x12, DC3 = 0x13, DC4 = 0x14, NAK = 0x15, SYN = 0x16, ETB = 0x17, CAN = 0x18, EM = 0x19,
 | 
			
		||||
        SUB = 0x1A, ESC = 0x1B, FS = 0x1C, GS = 0x1D, RS = 0x1E, US = 0x1F, SP = 0x20, DEL = 0x7F
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								PInvokeSerialPort/CommPortException.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								PInvokeSerialPort/CommPortException.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Exception used for all errors.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class CommPortException : ApplicationException
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Constructor for raising direct exceptions
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="desc">Description of error</param>
 | 
			
		||||
        public CommPortException(string desc) : base(desc) { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Constructor for re-raising exceptions from receive thread
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="e">Inner exception raised on receive thread</param>
 | 
			
		||||
        public CommPortException(Exception e) : base("Receive Thread Exception", e) { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								PInvokeSerialPort/Handshake.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								PInvokeSerialPort/Handshake.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Standard handshake methods
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum Handshake
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// No handshaking
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        None,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Software handshaking using Xon / Xoff
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        XonXoff,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Hardware handshaking using CTS / RTS
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        CtsRts,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Hardware handshaking using DSR / DTR
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        DsrDtr
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								PInvokeSerialPort/HsOutput.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										25
									
								
								PInvokeSerialPort/HsOutput.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Uses for RTS or DTR pins
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum HsOutput
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Pin is asserted when this station is able to receive data.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Handshake = 2,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Pin is asserted when this station is transmitting data (RTS on NT, 2000 or XP only).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Gate = 3,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Pin is asserted when this station is online (port is open).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Online = 1,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Pin is never asserted.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        None = 0
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								PInvokeSerialPort/ModemStatus.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								PInvokeSerialPort/ModemStatus.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
using PInvokeSerialPort.Win32PInvoke;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents the status of the modem control input signals.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public struct ModemStatus
 | 
			
		||||
    {
 | 
			
		||||
        private readonly uint _status;
 | 
			
		||||
        internal ModemStatus(uint val) { _status = val; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Condition of the Clear To Send signal.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Cts { get { return ((_status & Win32Com.MS_CTS_ON) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Condition of the Data Set Ready signal.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Dsr { get { return ((_status & Win32Com.MS_DSR_ON) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Condition of the Receive Line Status Detection signal.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Rlsd { get { return ((_status & Win32Com.MS_RLSD_ON) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Condition of the Ring Detection signal.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Ring { get { return ((_status & Win32Com.MS_RING_ON) != 0); } }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										74
									
								
								PInvokeSerialPort/PInvokeSerialPort.csproj
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								PInvokeSerialPort/PInvokeSerialPort.csproj
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
 | 
			
		||||
    <ProductVersion>8.0.30703</ProductVersion>
 | 
			
		||||
    <SchemaVersion>2.0</SchemaVersion>
 | 
			
		||||
    <ProjectGuid>{AEC711A5-AA9B-4127-A82C-C4D8FDA9741A}</ProjectGuid>
 | 
			
		||||
    <OutputType>Library</OutputType>
 | 
			
		||||
    <AppDesignerFolder>Properties</AppDesignerFolder>
 | 
			
		||||
    <RootNamespace>PInvokeSerialPort</RootNamespace>
 | 
			
		||||
    <AssemblyName>PInvokeSerialPort</AssemblyName>
 | 
			
		||||
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
 | 
			
		||||
    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
 | 
			
		||||
    <PlatformTarget>x86</PlatformTarget>
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
    <DebugType>full</DebugType>
 | 
			
		||||
    <Optimize>false</Optimize>
 | 
			
		||||
    <OutputPath>bin\Debug\</OutputPath>
 | 
			
		||||
    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
 | 
			
		||||
    <PlatformTarget>x86</PlatformTarget>
 | 
			
		||||
    <DebugType>pdbonly</DebugType>
 | 
			
		||||
    <Optimize>true</Optimize>
 | 
			
		||||
    <OutputPath>bin\Release\</OutputPath>
 | 
			
		||||
    <DefineConstants>TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <StartupObject />
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Reference Include="System" />
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
    <Reference Include="System.Xml.Linq" />
 | 
			
		||||
    <Reference Include="System.Data.DataSetExtensions" />
 | 
			
		||||
    <Reference Include="Microsoft.CSharp" />
 | 
			
		||||
    <Reference Include="System.Data" />
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="ASCII.cs" />
 | 
			
		||||
    <Compile Include="SerialPort.cs" />
 | 
			
		||||
    <Compile Include="CommPortException.cs" />
 | 
			
		||||
    <Compile Include="ModemStatus.cs" />
 | 
			
		||||
    <Compile Include="QueueStatus.cs" />
 | 
			
		||||
    <Compile Include="Win32PInvoke\COMMPROP.cs" />
 | 
			
		||||
    <Compile Include="Win32PInvoke\COMMTIMEOUTS.cs" />
 | 
			
		||||
    <Compile Include="Win32PInvoke\COMSTAT.cs" />
 | 
			
		||||
    <Compile Include="Win32PInvoke\DCB.cs" />
 | 
			
		||||
    <Compile Include="Handshake.cs" />
 | 
			
		||||
    <Compile Include="HsOutput.cs" />
 | 
			
		||||
    <Compile Include="Win32PInvoke\OVERLAPPED.cs" />
 | 
			
		||||
    <Compile Include="Parity.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="StopBits.cs" />
 | 
			
		||||
    <Compile Include="Win32PInvoke\Win32Com.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
 | 
			
		||||
       Other similar extension points exist, see Microsoft.Common.targets.
 | 
			
		||||
  <Target Name="BeforeBuild">
 | 
			
		||||
  </Target>
 | 
			
		||||
  <Target Name="AfterBuild">
 | 
			
		||||
  </Target>
 | 
			
		||||
  -->
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										29
									
								
								PInvokeSerialPort/Parity.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								PInvokeSerialPort/Parity.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Parity settings
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum Parity
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Characters do not have a parity bit.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        None = 0,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If there are an odd number of 1s in the data bits, the parity bit is 1.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Odd = 1,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If there are an even number of 1s in the data bits, the parity bit is 1.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Even = 2,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The parity bit is always 1.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Mark = 3,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The parity bit is always 0.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Space = 4
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								PInvokeSerialPort/Properties/AssemblyInfo.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								PInvokeSerialPort/Properties/AssemblyInfo.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
// General Information about an assembly is controlled through the following 
 | 
			
		||||
// set of attributes. Change these attribute values to modify the information
 | 
			
		||||
// associated with an assembly.
 | 
			
		||||
[assembly: AssemblyTitle("PInvokeSerialPort")]
 | 
			
		||||
[assembly: AssemblyDescription("")]
 | 
			
		||||
[assembly: AssemblyConfiguration("")]
 | 
			
		||||
[assembly: AssemblyCompany("")]
 | 
			
		||||
[assembly: AssemblyProduct("PInvokeSerialPort")]
 | 
			
		||||
[assembly: AssemblyCopyright("Copyright ©  2012")]
 | 
			
		||||
[assembly: AssemblyTrademark("")]
 | 
			
		||||
[assembly: AssemblyCulture("")]
 | 
			
		||||
 | 
			
		||||
// Setting ComVisible to false makes the types in this assembly not visible 
 | 
			
		||||
// to COM components.  If you need to access a type in this assembly from 
 | 
			
		||||
// COM, set the ComVisible attribute to true on that type.
 | 
			
		||||
[assembly: ComVisible(false)]
 | 
			
		||||
 | 
			
		||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
 | 
			
		||||
[assembly: Guid("a9b6ec41-2cde-4cdb-bd80-3dc730bcd820")]
 | 
			
		||||
 | 
			
		||||
// Version information for an assembly consists of the following four values:
 | 
			
		||||
//
 | 
			
		||||
//      Major Version
 | 
			
		||||
//      Minor Version 
 | 
			
		||||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
// You can specify all the values or you can default the Build and Revision Numbers 
 | 
			
		||||
// by using the '*' as shown below:
 | 
			
		||||
// [assembly: AssemblyVersion("1.0.*")]
 | 
			
		||||
[assembly: AssemblyVersion("1.0.0.0")]
 | 
			
		||||
[assembly: AssemblyFileVersion("1.0.0.0")]
 | 
			
		||||
							
								
								
									
										134
									
								
								PInvokeSerialPort/QueueStatus.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										134
									
								
								PInvokeSerialPort/QueueStatus.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
using System.Text;
 | 
			
		||||
using PInvokeSerialPort.Win32PInvoke;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents the current condition of the port queues.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public struct QueueStatus
 | 
			
		||||
    {
 | 
			
		||||
        private uint status;
 | 
			
		||||
        private uint inQueue;
 | 
			
		||||
        private uint outQueue;
 | 
			
		||||
        private uint inQueueSize;
 | 
			
		||||
        private uint outQueueSize;
 | 
			
		||||
 | 
			
		||||
        internal QueueStatus(uint stat, uint inQ, uint outQ, uint inQs, uint outQs)
 | 
			
		||||
        { status = stat; inQueue = inQ; outQueue = outQ; inQueueSize = inQs; outQueueSize = outQs; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Output is blocked by CTS handshaking.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool ctsHold { get { return ((status & COMSTAT.fCtsHold) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Output is blocked by DRS handshaking.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool dsrHold { get { return ((status & COMSTAT.fDsrHold) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Output is blocked by RLSD handshaking.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool rlsdHold { get { return ((status & COMSTAT.fRlsdHold) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Output is blocked because software handshaking is enabled and XOFF was received.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool xoffHold { get { return ((status & COMSTAT.fXoffHold) != 0); } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Output was blocked because XOFF was sent and this station is not yet ready to receive.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool xoffSent { get { return ((status & COMSTAT.fXoffSent) != 0); } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// There is a character waiting for transmission in the immediate buffer.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool immediateWaiting { get { return ((status & COMSTAT.fTxim) != 0); } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Number of bytes waiting in the input queue.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public long InQueue { get { return inQueue; } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Number of bytes waiting for transmission.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public long OutQueue { get { return outQueue; } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Total size of input queue (0 means information unavailable)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public long InQueueSize { get { return inQueueSize; } }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Total size of output queue (0 means information unavailable)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public long OutQueueSize { get { return outQueueSize; } }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            var m = new StringBuilder("The reception queue is ", 60);
 | 
			
		||||
            if (inQueueSize == 0)
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("of unknown size and ");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m.Append(inQueueSize.ToString() + " bytes long and ");
 | 
			
		||||
            }
 | 
			
		||||
            if (inQueue == 0)
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("is empty.");
 | 
			
		||||
            }
 | 
			
		||||
            else if (inQueue == 1)
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("contains 1 byte.");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("contains ");
 | 
			
		||||
                m.Append(inQueue.ToString());
 | 
			
		||||
                m.Append(" bytes.");
 | 
			
		||||
            }
 | 
			
		||||
            m.Append(" The transmission queue is ");
 | 
			
		||||
            if (outQueueSize == 0)
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("of unknown size and ");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m.Append(outQueueSize.ToString() + " bytes long and ");
 | 
			
		||||
            }
 | 
			
		||||
            if (outQueue == 0)
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("is empty");
 | 
			
		||||
            }
 | 
			
		||||
            else if (outQueue == 1)
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("contains 1 byte. It is ");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m.Append("contains ");
 | 
			
		||||
                m.Append(outQueue.ToString());
 | 
			
		||||
                m.Append(" bytes. It is ");
 | 
			
		||||
            }
 | 
			
		||||
            if (outQueue > 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (ctsHold || dsrHold || rlsdHold || xoffHold || xoffSent)
 | 
			
		||||
                {
 | 
			
		||||
                    m.Append("holding on");
 | 
			
		||||
                    if (ctsHold) m.Append(" CTS");
 | 
			
		||||
                    if (dsrHold) m.Append(" DSR");
 | 
			
		||||
                    if (rlsdHold) m.Append(" RLSD");
 | 
			
		||||
                    if (xoffHold) m.Append(" Rx XOff");
 | 
			
		||||
                    if (xoffSent) m.Append(" Tx XOff");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m.Append("pumping data");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            m.Append(". The immediate buffer is ");
 | 
			
		||||
            if (immediateWaiting)
 | 
			
		||||
                m.Append("full.");
 | 
			
		||||
            else
 | 
			
		||||
                m.Append("empty.");
 | 
			
		||||
            return m.ToString();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										740
									
								
								PInvokeSerialPort/SerialPort.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										740
									
								
								PInvokeSerialPort/SerialPort.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,740 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using PInvokeSerialPort.Win32PInvoke;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// PInvokeSerialPort main class.
 | 
			
		||||
    /// Borrowed from http://msdn.microsoft.com/en-us/magazine/cc301786.aspx ;)
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class SerialPort : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private IntPtr _hPort;
 | 
			
		||||
        private IntPtr _ptrUwo = IntPtr.Zero;
 | 
			
		||||
        private Thread _rxThread;
 | 
			
		||||
        private bool _online;
 | 
			
		||||
        private bool _auto;
 | 
			
		||||
        private bool _checkSends = true;
 | 
			
		||||
        private Exception _rxException;
 | 
			
		||||
        private bool _rxExceptionReported;
 | 
			
		||||
        private int _writeCount;
 | 
			
		||||
        private readonly ManualResetEvent _writeEvent = new ManualResetEvent(false);
 | 
			
		||||
        private int _stateRts = 2;
 | 
			
		||||
        private int _stateDtr = 2;
 | 
			
		||||
        private int _stateBrk = 2;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Class contructor
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public SerialPort(string portName)
 | 
			
		||||
        {
 | 
			
		||||
            PortName = portName;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Class contructor
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public SerialPort(string portName, int baudRate)
 | 
			
		||||
        {
 | 
			
		||||
            PortName = portName;
 | 
			
		||||
            BaudRate = baudRate;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Opens the com port and configures it with the required settings
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>false if the port could not be opened</returns>
 | 
			
		||||
        public bool Open()
 | 
			
		||||
        {
 | 
			
		||||
            var portDcb = new DCB();
 | 
			
		||||
            var commTimeouts = new COMMTIMEOUTS();
 | 
			
		||||
            var wo = new OVERLAPPED();
 | 
			
		||||
 | 
			
		||||
            if (_online) return false;
 | 
			
		||||
 | 
			
		||||
            _hPort = Win32Com.CreateFile(PortName, Win32Com.GENERIC_READ | Win32Com.GENERIC_WRITE, 0, IntPtr.Zero,
 | 
			
		||||
                Win32Com.OPEN_EXISTING, Win32Com.FILE_FLAG_OVERLAPPED, IntPtr.Zero);
 | 
			
		||||
            if (_hPort == (IntPtr)Win32Com.INVALID_HANDLE_VALUE)
 | 
			
		||||
            {
 | 
			
		||||
                if (Marshal.GetLastWin32Error() == Win32Com.ERROR_ACCESS_DENIED)
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                throw new CommPortException("Port Open Failure");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _online = true;
 | 
			
		||||
 | 
			
		||||
            commTimeouts.ReadIntervalTimeout = 0;
 | 
			
		||||
            commTimeouts.ReadTotalTimeoutConstant = 0;
 | 
			
		||||
            commTimeouts.ReadTotalTimeoutMultiplier = 0;
 | 
			
		||||
            commTimeouts.WriteTotalTimeoutConstant = SendTimeoutConstant;
 | 
			
		||||
            commTimeouts.WriteTotalTimeoutMultiplier = SendTimeoutMultiplier;
 | 
			
		||||
            portDcb.Init(((Parity == Parity.Odd) || (Parity == Parity.Even)), TxFlowCts, TxFlowDsr,
 | 
			
		||||
                (int)UseDtr, RxGateDsr, !TxWhenRxXoff, TxFlowX, RxFlowX, (int)UseRts);
 | 
			
		||||
            portDcb.BaudRate = BaudRate;
 | 
			
		||||
            portDcb.ByteSize = (byte)DataBits;
 | 
			
		||||
            portDcb.Parity = (byte)Parity;
 | 
			
		||||
            portDcb.StopBits = (byte)StopBits;
 | 
			
		||||
            portDcb.XoffChar = (byte)XoffChar;
 | 
			
		||||
            portDcb.XonChar = (byte)XonChar;
 | 
			
		||||
            portDcb.XoffLim = (short)RxHighWater;
 | 
			
		||||
            portDcb.XonLim = (short)RxLowWater;
 | 
			
		||||
            if ((RxQueue != 0) || (TxQueue != 0))
 | 
			
		||||
                if (!Win32Com.SetupComm(_hPort, (uint)RxQueue, (uint)TxQueue)) ThrowException("Bad queue settings");
 | 
			
		||||
            if (!Win32Com.SetCommState(_hPort, ref portDcb)) ThrowException("Bad com settings");
 | 
			
		||||
            if (!Win32Com.SetCommTimeouts(_hPort, ref commTimeouts)) ThrowException("Bad timeout settings");
 | 
			
		||||
 | 
			
		||||
            _stateBrk = 0;
 | 
			
		||||
            if (UseDtr == HsOutput.None) _stateDtr = 0;
 | 
			
		||||
            if (UseDtr == HsOutput.Online) _stateDtr = 1;
 | 
			
		||||
            if (UseRts == HsOutput.None) _stateRts = 0;
 | 
			
		||||
            if (UseRts == HsOutput.Online) _stateRts = 1;
 | 
			
		||||
 | 
			
		||||
            _checkSends = CheckAllSends;
 | 
			
		||||
            wo.Offset = 0;
 | 
			
		||||
            wo.OffsetHigh = 0;
 | 
			
		||||
            wo.hEvent = _checkSends ? _writeEvent.Handle : IntPtr.Zero;
 | 
			
		||||
            _ptrUwo = Marshal.AllocHGlobal(Marshal.SizeOf(wo));
 | 
			
		||||
            Marshal.StructureToPtr(wo, _ptrUwo, true);
 | 
			
		||||
            _writeCount = 0;
 | 
			
		||||
 | 
			
		||||
            _rxException = null;
 | 
			
		||||
            _rxExceptionReported = false;
 | 
			
		||||
            _rxThread = new Thread(ReceiveThread)
 | 
			
		||||
                            {
 | 
			
		||||
                                Name = "CommBaseRx",
 | 
			
		||||
                                Priority = ThreadPriority.AboveNormal
 | 
			
		||||
                            };
 | 
			
		||||
            _rxThread.Start();
 | 
			
		||||
            Thread.Sleep(1); //Give rx thread time to start. By documentation, 0 should work, but it does not!
 | 
			
		||||
 | 
			
		||||
            _auto = false;
 | 
			
		||||
            if (AfterOpen())
 | 
			
		||||
            {
 | 
			
		||||
                _auto = AutoReopen;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            Close();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Closes the com port.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Close()
 | 
			
		||||
        {
 | 
			
		||||
            if (_online)
 | 
			
		||||
            {
 | 
			
		||||
                _auto = false;
 | 
			
		||||
                BeforeClose(false);
 | 
			
		||||
                InternalClose();
 | 
			
		||||
                _rxException = null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InternalClose()
 | 
			
		||||
        {
 | 
			
		||||
            Win32Com.CancelIo(_hPort);
 | 
			
		||||
            if (_rxThread != null)
 | 
			
		||||
            {
 | 
			
		||||
                _rxThread.Abort();
 | 
			
		||||
                _rxThread = null;
 | 
			
		||||
            }
 | 
			
		||||
            Win32Com.CloseHandle(_hPort);
 | 
			
		||||
            if (_ptrUwo != IntPtr.Zero) Marshal.FreeHGlobal(_ptrUwo);
 | 
			
		||||
            _stateRts = 2;
 | 
			
		||||
            _stateDtr = 2;
 | 
			
		||||
            _stateBrk = 2;
 | 
			
		||||
            _online = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// For IDisposable
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Dispose() { Close(); }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Destructor (just in case)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        ~SerialPort() { Close(); }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// True if online.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Online { get { return _online && CheckOnline(); } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Block until all bytes in the queue have been transmitted.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Flush()
 | 
			
		||||
        {
 | 
			
		||||
            CheckOnline();
 | 
			
		||||
            CheckResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Use this to throw exceptions in derived classes. Correctly handles threading issues
 | 
			
		||||
        /// and closes the port if necessary.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="reason">Description of fault</param>
 | 
			
		||||
        protected void ThrowException(string reason)
 | 
			
		||||
        {
 | 
			
		||||
            if (Thread.CurrentThread == _rxThread)
 | 
			
		||||
            {
 | 
			
		||||
                throw new CommPortException(reason);
 | 
			
		||||
            }
 | 
			
		||||
            if (_online)
 | 
			
		||||
            {
 | 
			
		||||
                BeforeClose(true);
 | 
			
		||||
                InternalClose();
 | 
			
		||||
            }
 | 
			
		||||
            if (_rxException == null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new CommPortException(reason);
 | 
			
		||||
            }
 | 
			
		||||
            throw new CommPortException(_rxException);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queues bytes for transmission. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="toSend">Array of bytes to be sent</param>
 | 
			
		||||
        public void Write(byte[] toSend)
 | 
			
		||||
        {
 | 
			
		||||
            uint sent;
 | 
			
		||||
            CheckOnline();
 | 
			
		||||
            CheckResult();
 | 
			
		||||
            _writeCount = toSend.GetLength(0);
 | 
			
		||||
            if (Win32Com.WriteFile(_hPort, toSend, (uint)_writeCount, out sent, _ptrUwo))
 | 
			
		||||
            {
 | 
			
		||||
                _writeCount -= (int)sent;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (Marshal.GetLastWin32Error() != Win32Com.ERROR_IO_PENDING) ThrowException("Unexpected failure");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queues string for transmission. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="toSend">Array of bytes to be sent</param>
 | 
			
		||||
        public void Write(string toSend)
 | 
			
		||||
        {
 | 
			
		||||
            Write(new ASCIIEncoding().GetBytes(toSend));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queues a single byte for transmission.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="toSend">Byte to be sent</param>
 | 
			
		||||
        public void Write(byte toSend)
 | 
			
		||||
        {
 | 
			
		||||
            var b = new byte[1];
 | 
			
		||||
            b[0] = toSend;
 | 
			
		||||
            Write(b);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queues a single char for transmission.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="toSend">Byte to be sent</param>
 | 
			
		||||
        public void Write(char toSend)
 | 
			
		||||
        {
 | 
			
		||||
            Write(toSend.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Queues string with a new line ("\r\n") for transmission. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="toSend">Array of bytes to be sent</param>
 | 
			
		||||
        public void WriteLine(string toSend)
 | 
			
		||||
        {
 | 
			
		||||
            Write(new ASCIIEncoding().GetBytes(toSend + Environment.NewLine));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckResult()
 | 
			
		||||
        {
 | 
			
		||||
            if (_writeCount <= 0) return;
 | 
			
		||||
            uint sent;
 | 
			
		||||
            if (Win32Com.GetOverlappedResult(_hPort, _ptrUwo, out sent, _checkSends))
 | 
			
		||||
            {
 | 
			
		||||
                _writeCount -= (int)sent;
 | 
			
		||||
                if (_writeCount != 0) ThrowException("Send Timeout");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (Marshal.GetLastWin32Error() != Win32Com.ERROR_IO_PENDING) ThrowException("Unexpected failure");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sends a protocol byte immediately ahead of any queued bytes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="tosend">Byte to send</param>
 | 
			
		||||
        /// <returns>False if an immediate byte is already scheduled and not yet sent</returns>
 | 
			
		||||
        public void SendImmediate(byte tosend)
 | 
			
		||||
        {
 | 
			
		||||
            CheckOnline();
 | 
			
		||||
            if (!Win32Com.TransmitCommChar(_hPort, tosend)) ThrowException("Transmission failure");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Delay processing.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="milliseconds">Milliseconds to delay by</param>
 | 
			
		||||
        protected void Sleep(int milliseconds)
 | 
			
		||||
        {
 | 
			
		||||
            Thread.Sleep(milliseconds);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the status of the modem control input signals.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>Modem status object</returns>
 | 
			
		||||
        protected ModemStatus GetModemStatus()
 | 
			
		||||
        {
 | 
			
		||||
            uint f;
 | 
			
		||||
 | 
			
		||||
            CheckOnline();
 | 
			
		||||
            if (!Win32Com.GetCommModemStatus(_hPort, out f)) ThrowException("Unexpected failure");
 | 
			
		||||
            return new ModemStatus(f);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get the status of the queues
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>Queue status object</returns>
 | 
			
		||||
        protected QueueStatus GetQueueStatus()
 | 
			
		||||
        {
 | 
			
		||||
            COMSTAT cs;
 | 
			
		||||
            COMMPROP cp;
 | 
			
		||||
            uint er;
 | 
			
		||||
 | 
			
		||||
            CheckOnline();
 | 
			
		||||
            if (!Win32Com.ClearCommError(_hPort, out er, out cs)) ThrowException("Unexpected failure");
 | 
			
		||||
            if (!Win32Com.GetCommProperties(_hPort, out cp)) ThrowException("Unexpected failure");
 | 
			
		||||
            return new QueueStatus(cs.Flags, cs.cbInQue, cs.cbOutQue, cp.dwCurrentRxQueue, cp.dwCurrentTxQueue);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// True if the RTS pin is controllable via the RTS property
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected bool RtSavailable { get { return (_stateRts < 2); } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set the state of the RTS modem control output
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected bool Rts
 | 
			
		||||
        {
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                if (_stateRts > 1) return;
 | 
			
		||||
                CheckOnline();
 | 
			
		||||
                if (value)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Win32Com.EscapeCommFunction(_hPort, Win32Com.SETRTS))
 | 
			
		||||
                        _stateRts = 1;
 | 
			
		||||
                    else
 | 
			
		||||
                        ThrowException("Unexpected Failure");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (Win32Com.EscapeCommFunction(_hPort, Win32Com.CLRRTS))
 | 
			
		||||
                        _stateRts = 1;
 | 
			
		||||
                    else
 | 
			
		||||
                        ThrowException("Unexpected Failure");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return (_stateRts == 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// True if the DTR pin is controllable via the DTR property
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected bool DtrAvailable { get { return (_stateDtr < 2); } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The state of the DTR modem control output
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected bool Dtr
 | 
			
		||||
        {
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                if (_stateDtr > 1) return;
 | 
			
		||||
                CheckOnline();
 | 
			
		||||
                if (value)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Win32Com.EscapeCommFunction(_hPort, Win32Com.SETDTR))
 | 
			
		||||
                        _stateDtr = 1;
 | 
			
		||||
                    else
 | 
			
		||||
                        ThrowException("Unexpected Failure");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (Win32Com.EscapeCommFunction(_hPort, Win32Com.CLRDTR))
 | 
			
		||||
                        _stateDtr = 0;
 | 
			
		||||
                    else
 | 
			
		||||
                        ThrowException("Unexpected Failure");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return (_stateDtr == 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Assert or remove a break condition from the transmission line
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected bool Break
 | 
			
		||||
        {
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                if (_stateBrk > 1) return;
 | 
			
		||||
                CheckOnline();
 | 
			
		||||
                if (value)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Win32Com.EscapeCommFunction(_hPort, Win32Com.SETBREAK))
 | 
			
		||||
                        _stateBrk = 0;
 | 
			
		||||
                    else
 | 
			
		||||
                        ThrowException("Unexpected Failure");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (Win32Com.EscapeCommFunction(_hPort, Win32Com.CLRBREAK))
 | 
			
		||||
                        _stateBrk = 0;
 | 
			
		||||
                    else
 | 
			
		||||
                        ThrowException("Unexpected Failure");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return (_stateBrk == 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to provide processing after the port is openned (i.e. to configure remote
 | 
			
		||||
        /// device or just check presence).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>false to close the port again</returns>
 | 
			
		||||
        protected virtual bool AfterOpen() { return true; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to provide processing prior to port closure.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="error">True if closing due to an error</param>
 | 
			
		||||
        protected virtual void BeforeClose(bool error) { }
 | 
			
		||||
 | 
			
		||||
        public event Action<byte> DataReceived;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to process received bytes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="ch">The byte that was received</param>
 | 
			
		||||
        protected void OnRxChar(byte ch)
 | 
			
		||||
        {
 | 
			
		||||
            if (DataReceived != null)
 | 
			
		||||
                DataReceived(ch);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to take action when transmission is complete (i.e. all bytes have actually
 | 
			
		||||
        /// been sent, not just queued).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual void OnTxDone() { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to take action when a break condition is detected on the input line.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual void OnBreak() { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to take action when a ring condition is signalled by an attached modem.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual void OnRing() { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to take action when one or more modem status inputs change state
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mask">The status inputs that have changed state</param>
 | 
			
		||||
        /// <param name="state">The state of the status inputs</param>
 | 
			
		||||
        protected virtual void OnStatusChange(ModemStatus mask, ModemStatus state) { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Override this to take action when the reception thread closes due to an exception being thrown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="e">The exception which was thrown</param>
 | 
			
		||||
        protected virtual void OnRxException(Exception e) { }
 | 
			
		||||
 | 
			
		||||
        private void ReceiveThread()
 | 
			
		||||
        {
 | 
			
		||||
            var buf = new Byte[1];
 | 
			
		||||
 | 
			
		||||
            var sg = new AutoResetEvent(false);
 | 
			
		||||
            var ov = new OVERLAPPED();
 | 
			
		||||
            var unmanagedOv = Marshal.AllocHGlobal(Marshal.SizeOf(ov));
 | 
			
		||||
            ov.Offset = 0; ov.OffsetHigh = 0;
 | 
			
		||||
            ov.hEvent = sg.Handle;
 | 
			
		||||
            Marshal.StructureToPtr(ov, unmanagedOv, true);
 | 
			
		||||
 | 
			
		||||
            uint eventMask = 0;
 | 
			
		||||
            var uMask = Marshal.AllocHGlobal(Marshal.SizeOf(eventMask));
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                while (true)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!Win32Com.SetCommMask(_hPort, Win32Com.EV_RXCHAR | Win32Com.EV_TXEMPTY | Win32Com.EV_CTS | Win32Com.EV_DSR
 | 
			
		||||
                        | Win32Com.EV_BREAK | Win32Com.EV_RLSD | Win32Com.EV_RING | Win32Com.EV_ERR))
 | 
			
		||||
                    {
 | 
			
		||||
                        throw new CommPortException("IO Error [001]");
 | 
			
		||||
                    }
 | 
			
		||||
                    Marshal.WriteInt32(uMask, 0);
 | 
			
		||||
                    if (!Win32Com.WaitCommEvent(_hPort, uMask, unmanagedOv))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (Marshal.GetLastWin32Error() == Win32Com.ERROR_IO_PENDING)
 | 
			
		||||
                        {
 | 
			
		||||
                            sg.WaitOne();
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            throw new CommPortException("IO Error [002]");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    eventMask = (uint)Marshal.ReadInt32(uMask);
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_ERR) != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        UInt32 errs;
 | 
			
		||||
                        if (Win32Com.ClearCommError(_hPort, out errs, IntPtr.Zero))
 | 
			
		||||
                        {
 | 
			
		||||
                            var s = new StringBuilder("UART Error: ", 40);
 | 
			
		||||
                            if ((errs & Win32Com.CE_FRAME) != 0) s = s.Append("Framing,");
 | 
			
		||||
                            if ((errs & Win32Com.CE_IOE) != 0) s = s.Append("IO,");
 | 
			
		||||
                            if ((errs & Win32Com.CE_OVERRUN) != 0) s = s.Append("Overrun,");
 | 
			
		||||
                            if ((errs & Win32Com.CE_RXOVER) != 0) s = s.Append("Receive Cverflow,");
 | 
			
		||||
                            if ((errs & Win32Com.CE_RXPARITY) != 0) s = s.Append("Parity,");
 | 
			
		||||
                            if ((errs & Win32Com.CE_TXFULL) != 0) s = s.Append("Transmit Overflow,");
 | 
			
		||||
                            s.Length = s.Length - 1;
 | 
			
		||||
                            throw new CommPortException(s.ToString());
 | 
			
		||||
                        }
 | 
			
		||||
                        throw new CommPortException("IO Error [003]");
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_RXCHAR) != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        uint gotbytes;
 | 
			
		||||
                        do
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!Win32Com.ReadFile(_hPort, buf, 1, out gotbytes, unmanagedOv))
 | 
			
		||||
                            {
 | 
			
		||||
                                if (Marshal.GetLastWin32Error() == Win32Com.ERROR_IO_PENDING)
 | 
			
		||||
                                {
 | 
			
		||||
                                    Win32Com.CancelIo(_hPort);
 | 
			
		||||
                                    gotbytes = 0;
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    throw new CommPortException("IO Error [004]");
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            if (gotbytes == 1) OnRxChar(buf[0]);
 | 
			
		||||
                            
 | 
			
		||||
                        } while (gotbytes > 0);
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_TXEMPTY) != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        OnTxDone();
 | 
			
		||||
                    }
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_BREAK) != 0) OnBreak();
 | 
			
		||||
 | 
			
		||||
                    uint i = 0;
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_CTS) != 0) i |= Win32Com.MS_CTS_ON;
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_DSR) != 0) i |= Win32Com.MS_DSR_ON;
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_RLSD) != 0) i |= Win32Com.MS_RLSD_ON;
 | 
			
		||||
                    if ((eventMask & Win32Com.EV_RING) != 0) i |= Win32Com.MS_RING_ON;
 | 
			
		||||
                    if (i != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        uint f;
 | 
			
		||||
                        if (!Win32Com.GetCommModemStatus(_hPort, out f)) throw new CommPortException("IO Error [005]");
 | 
			
		||||
                        OnStatusChange(new ModemStatus(i), new ModemStatus(f));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                if (uMask != IntPtr.Zero) Marshal.FreeHGlobal(uMask);
 | 
			
		||||
                if (unmanagedOv != IntPtr.Zero) Marshal.FreeHGlobal(unmanagedOv);
 | 
			
		||||
                if (!(e is ThreadAbortException))
 | 
			
		||||
                {
 | 
			
		||||
                    _rxException = e;
 | 
			
		||||
                    OnRxException(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool CheckOnline()
 | 
			
		||||
        {
 | 
			
		||||
            if ((_rxException != null) && (!_rxExceptionReported))
 | 
			
		||||
            {
 | 
			
		||||
                _rxExceptionReported = true;
 | 
			
		||||
                ThrowException("rx");
 | 
			
		||||
            }
 | 
			
		||||
            if (_online)
 | 
			
		||||
            {
 | 
			
		||||
                uint f;
 | 
			
		||||
                if (Win32Com.GetHandleInformation(_hPort, out f)) return true;
 | 
			
		||||
                ThrowException("Offline");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            if (_auto)
 | 
			
		||||
            {
 | 
			
		||||
                if (Open()) return true;
 | 
			
		||||
            }
 | 
			
		||||
            ThrowException("Offline");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Port Name
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string PortName { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Baud Rate (default: 2400) unsupported rates will throw "Bad settings"
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int BaudRate = 115200;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The parity checking scheme (default: none)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Parity Parity = Parity.None;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Number of databits 1..8 (default: 8) unsupported values will throw "Bad settings"
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int DataBits = 8;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Number of stop bits (default: one)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public StopBits StopBits = StopBits.one;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, transmission is halted unless CTS is asserted by the remote station (default: false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool TxFlowCts;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, transmission is halted unless DSR is asserted by the remote station (default: false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool TxFlowDsr;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, transmission is halted when Xoff is received and restarted when Xon is received (default: false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool TxFlowX;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If false, transmission is suspended when this station has sent Xoff to the remote station (default: true)
 | 
			
		||||
        /// Set false if the remote station treats any character as an Xon.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool TxWhenRxXoff = true;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, received characters are ignored unless DSR is asserted by the remote station (default: false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool RxGateDsr;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, Xon and Xoff characters are sent to control the data flow from the remote station (default: false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool RxFlowX;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Specifies the use to which the RTS output is put (default: none)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public HsOutput UseRts = HsOutput.None;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Specidies the use to which the DTR output is put (default: none)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public HsOutput UseDtr = HsOutput.None;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The character used to signal Xon for X flow control (default: DC1)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ASCII XonChar = ASCII.DC1;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The character used to signal Xoff for X flow control (default: DC3)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ASCII XoffChar = ASCII.DC3;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The number of free bytes in the reception queue at which flow is disabled (default: 2048)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int RxHighWater = 2048;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The number of bytes in the reception queue at which flow is re-enabled (default: 512)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int RxLowWater = 512;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Multiplier. Max time for Send in ms = (Multiplier * Characters) + Constant
 | 
			
		||||
        /// (default: 0 = No timeout)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int SendTimeoutMultiplier;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Constant.  Max time for Send in ms = (Multiplier * Characters) + Constant (default: 0)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int SendTimeoutConstant;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Requested size for receive queue (default: 0 = use operating system default)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int RxQueue;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Requested size for transmit queue (default: 0 = use operating system default)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int TxQueue;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, the port will automatically re-open on next send if it was previously closed due
 | 
			
		||||
        /// to an error (default: false)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool AutoReopen;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If true, subsequent Send commands wait for completion of earlier ones enabling the results
 | 
			
		||||
        /// to be checked. If false, errors, including timeouts, may not be detected, but performance
 | 
			
		||||
        /// may be better.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool CheckAllSends = true;
 | 
			
		||||
 | 
			
		||||
        private Handshake _handShake;
 | 
			
		||||
        public Handshake Handshake
 | 
			
		||||
        {
 | 
			
		||||
            get { return _handShake; }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                Handshake = value;
 | 
			
		||||
                switch (Handshake)
 | 
			
		||||
                {
 | 
			
		||||
                    case Handshake.None:
 | 
			
		||||
                        TxFlowCts = false; TxFlowDsr = false; TxFlowX = false;
 | 
			
		||||
                        RxFlowX = false; UseRts = HsOutput.Online; UseDtr = HsOutput.Online;
 | 
			
		||||
                        TxWhenRxXoff = true; RxGateDsr = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case Handshake.XonXoff:
 | 
			
		||||
                        TxFlowCts = false; TxFlowDsr = false; TxFlowX = true;
 | 
			
		||||
                        RxFlowX = true; UseRts = HsOutput.Online; UseDtr = HsOutput.Online;
 | 
			
		||||
                        TxWhenRxXoff = true; RxGateDsr = false;
 | 
			
		||||
                        XonChar = ASCII.DC1; XoffChar = ASCII.DC3;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case Handshake.CtsRts:
 | 
			
		||||
                        TxFlowCts = true; TxFlowDsr = false; TxFlowX = false;
 | 
			
		||||
                        RxFlowX = false; UseRts = HsOutput.Handshake; UseDtr = HsOutput.Online;
 | 
			
		||||
                        TxWhenRxXoff = true; RxGateDsr = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case Handshake.DsrDtr:
 | 
			
		||||
                        TxFlowCts = false; TxFlowDsr = true; TxFlowX = false;
 | 
			
		||||
                        RxFlowX = false; UseRts = HsOutput.Online; UseDtr = HsOutput.Handshake;
 | 
			
		||||
                        TxWhenRxXoff = true; RxGateDsr = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								PInvokeSerialPort/StopBits.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										21
									
								
								PInvokeSerialPort/StopBits.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
namespace PInvokeSerialPort
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Stop bit settings
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum StopBits
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Line is asserted for 1 bit duration at end of each character
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        one = 0,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Line is asserted for 1.5 bit duration at end of each character
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        onePointFive = 1,
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Line is asserted for 2 bit duration at end of each character
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        two = 2
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								PInvokeSerialPort/Win32PInvoke/COMMPROP.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								PInvokeSerialPort/Win32PInvoke/COMMPROP.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort.Win32PInvoke
 | 
			
		||||
{
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential)]
 | 
			
		||||
    internal struct COMMPROP
 | 
			
		||||
    {
 | 
			
		||||
        internal UInt16 wPacketLength;
 | 
			
		||||
        internal UInt16 wPacketVersion;
 | 
			
		||||
        internal UInt32 dwServiceMask;
 | 
			
		||||
        internal UInt32 dwReserved1;
 | 
			
		||||
        internal UInt32 dwMaxTxQueue;
 | 
			
		||||
        internal UInt32 dwMaxRxQueue;
 | 
			
		||||
        internal UInt32 dwMaxBaud;
 | 
			
		||||
        internal UInt32 dwProvSubType;
 | 
			
		||||
        internal UInt32 dwProvCapabilities;
 | 
			
		||||
        internal UInt32 dwSettableParams;
 | 
			
		||||
        internal UInt32 dwSettableBaud;
 | 
			
		||||
        internal UInt16 wSettableData;
 | 
			
		||||
        internal UInt16 wSettableStopParity;
 | 
			
		||||
        internal UInt32 dwCurrentTxQueue;
 | 
			
		||||
        internal UInt32 dwCurrentRxQueue;
 | 
			
		||||
        internal UInt32 dwProvSpec1;
 | 
			
		||||
        internal UInt32 dwProvSpec2;
 | 
			
		||||
        internal Byte wcProvChar;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								PInvokeSerialPort/Win32PInvoke/COMMTIMEOUTS.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								PInvokeSerialPort/Win32PInvoke/COMMTIMEOUTS.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort.Win32PInvoke
 | 
			
		||||
{
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential)]
 | 
			
		||||
    internal struct COMMTIMEOUTS
 | 
			
		||||
    {
 | 
			
		||||
        internal Int32 ReadIntervalTimeout;
 | 
			
		||||
        internal Int32 ReadTotalTimeoutMultiplier;
 | 
			
		||||
        internal Int32 ReadTotalTimeoutConstant;
 | 
			
		||||
        internal Int32 WriteTotalTimeoutMultiplier;
 | 
			
		||||
        internal Int32 WriteTotalTimeoutConstant;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								PInvokeSerialPort/Win32PInvoke/COMSTAT.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								PInvokeSerialPort/Win32PInvoke/COMSTAT.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort.Win32PInvoke
 | 
			
		||||
{
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential)]
 | 
			
		||||
    internal struct COMSTAT
 | 
			
		||||
    {
 | 
			
		||||
        internal const uint fCtsHold = 0x1;
 | 
			
		||||
        internal const uint fDsrHold = 0x2;
 | 
			
		||||
        internal const uint fRlsdHold = 0x4;
 | 
			
		||||
        internal const uint fXoffHold = 0x8;
 | 
			
		||||
        internal const uint fXoffSent = 0x10;
 | 
			
		||||
        internal const uint fEof = 0x20;
 | 
			
		||||
        internal const uint fTxim = 0x40;
 | 
			
		||||
        internal UInt32 Flags;
 | 
			
		||||
        internal UInt32 cbInQue;
 | 
			
		||||
        internal UInt32 cbOutQue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								PInvokeSerialPort/Win32PInvoke/DCB.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										41
									
								
								PInvokeSerialPort/Win32PInvoke/DCB.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort.Win32PInvoke
 | 
			
		||||
{
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential)]
 | 
			
		||||
    internal struct DCB
 | 
			
		||||
    {
 | 
			
		||||
        internal Int32 DCBlength;
 | 
			
		||||
        internal Int32 BaudRate;
 | 
			
		||||
        internal Int32 PackedValues;
 | 
			
		||||
        internal Int16 wReserved;
 | 
			
		||||
        internal Int16 XonLim;
 | 
			
		||||
        internal Int16 XoffLim;
 | 
			
		||||
        internal Byte ByteSize;
 | 
			
		||||
        internal Byte Parity;
 | 
			
		||||
        internal Byte StopBits;
 | 
			
		||||
        internal Byte XonChar;
 | 
			
		||||
        internal Byte XoffChar;
 | 
			
		||||
        internal Byte ErrorChar;
 | 
			
		||||
        internal Byte EofChar;
 | 
			
		||||
        internal Byte EvtChar;
 | 
			
		||||
        internal Int16 wReserved1;
 | 
			
		||||
 | 
			
		||||
        internal void Init(bool parity, bool outCts, bool outDsr, int dtr, bool inDsr, bool txc, bool xOut,
 | 
			
		||||
                           bool xIn, int rts)
 | 
			
		||||
        {
 | 
			
		||||
            DCBlength = 28; PackedValues = 0x8001;
 | 
			
		||||
            if (parity) PackedValues |= 0x0002;
 | 
			
		||||
            if (outCts) PackedValues |= 0x0004;
 | 
			
		||||
            if (outDsr) PackedValues |= 0x0008;
 | 
			
		||||
            PackedValues |= ((dtr & 0x0003) << 4);
 | 
			
		||||
            if (inDsr) PackedValues |= 0x0040;
 | 
			
		||||
            if (txc) PackedValues |= 0x0080;
 | 
			
		||||
            if (xOut) PackedValues |= 0x0100;
 | 
			
		||||
            if (xIn) PackedValues |= 0x0200;
 | 
			
		||||
            PackedValues |= ((rts & 0x0003) << 12);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								PInvokeSerialPort/Win32PInvoke/OVERLAPPED.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								PInvokeSerialPort/Win32PInvoke/OVERLAPPED.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort.Win32PInvoke
 | 
			
		||||
{
 | 
			
		||||
    [StructLayout(LayoutKind.Sequential)]
 | 
			
		||||
    internal struct OVERLAPPED
 | 
			
		||||
    {
 | 
			
		||||
        internal UIntPtr Internal;
 | 
			
		||||
        internal UIntPtr InternalHigh;
 | 
			
		||||
        internal UInt32 Offset;
 | 
			
		||||
        internal UInt32 OffsetHigh;
 | 
			
		||||
        internal IntPtr hEvent;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										155
									
								
								PInvokeSerialPort/Win32PInvoke/Win32Com.cs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										155
									
								
								PInvokeSerialPort/Win32PInvoke/Win32Com.cs
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace PInvokeSerialPort.Win32PInvoke
 | 
			
		||||
{
 | 
			
		||||
    internal class Win32Com
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Opening Testing and Closing the Port Handle.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [DllImport("kernel32.dll", SetLastError = true)]
 | 
			
		||||
        internal static extern IntPtr CreateFile(String lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode,
 | 
			
		||||
                                                 IntPtr lpSecurityAttributes, UInt32 dwCreationDisposition, UInt32 dwFlagsAndAttributes,
 | 
			
		||||
                                                 IntPtr hTemplateFile);
 | 
			
		||||
 | 
			
		||||
        //Constants for errors:
 | 
			
		||||
        internal const UInt32 ERROR_FILE_NOT_FOUND = 2;
 | 
			
		||||
        internal const UInt32 ERROR_INVALID_NAME = 123;
 | 
			
		||||
        internal const UInt32 ERROR_ACCESS_DENIED = 5;
 | 
			
		||||
        internal const UInt32 ERROR_IO_PENDING = 997;
 | 
			
		||||
 | 
			
		||||
        //Constants for return value:
 | 
			
		||||
        internal const Int32 INVALID_HANDLE_VALUE = -1;
 | 
			
		||||
 | 
			
		||||
        //Constants for dwFlagsAndAttributes:
 | 
			
		||||
        internal const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
 | 
			
		||||
 | 
			
		||||
        //Constants for dwCreationDisposition:
 | 
			
		||||
        internal const UInt32 OPEN_EXISTING = 3;
 | 
			
		||||
 | 
			
		||||
        //Constants for dwDesiredAccess:
 | 
			
		||||
        internal const UInt32 GENERIC_READ = 0x80000000;
 | 
			
		||||
        internal const UInt32 GENERIC_WRITE = 0x40000000;
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean CloseHandle(IntPtr hObject);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean GetHandleInformation(IntPtr hObject, out UInt32 lpdwFlags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Manipulating the communications settings.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean GetCommState(IntPtr hFile, ref DCB lpDCB);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean GetCommTimeouts(IntPtr hFile, out COMMTIMEOUTS lpCommTimeouts);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean BuildCommDCBAndTimeouts(String lpDef, ref DCB lpDCB, ref COMMTIMEOUTS lpCommTimeouts);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean SetCommState(IntPtr hFile, [In] ref DCB lpDCB);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean SetCommTimeouts(IntPtr hFile, [In] ref COMMTIMEOUTS lpCommTimeouts);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean SetupComm(IntPtr hFile, UInt32 dwInQueue, UInt32 dwOutQueue);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reading and writing.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [DllImport("kernel32.dll", SetLastError = true)]
 | 
			
		||||
        internal static extern Boolean WriteFile(IntPtr fFile, Byte[] lpBuffer, UInt32 nNumberOfBytesToWrite,
 | 
			
		||||
                                                 out UInt32 lpNumberOfBytesWritten, IntPtr lpOverlapped);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean SetCommMask(IntPtr hFile, UInt32 dwEvtMask);
 | 
			
		||||
 | 
			
		||||
        // Constants for dwEvtMask:
 | 
			
		||||
        internal const UInt32 EV_RXCHAR = 0x0001;
 | 
			
		||||
        internal const UInt32 EV_RXFLAG = 0x0002;
 | 
			
		||||
        internal const UInt32 EV_TXEMPTY = 0x0004;
 | 
			
		||||
        internal const UInt32 EV_CTS = 0x0008;
 | 
			
		||||
        internal const UInt32 EV_DSR = 0x0010;
 | 
			
		||||
        internal const UInt32 EV_RLSD = 0x0020;
 | 
			
		||||
        internal const UInt32 EV_BREAK = 0x0040;
 | 
			
		||||
        internal const UInt32 EV_ERR = 0x0080;
 | 
			
		||||
        internal const UInt32 EV_RING = 0x0100;
 | 
			
		||||
        internal const UInt32 EV_PERR = 0x0200;
 | 
			
		||||
        internal const UInt32 EV_RX80FULL = 0x0400;
 | 
			
		||||
        internal const UInt32 EV_EVENT1 = 0x0800;
 | 
			
		||||
        internal const UInt32 EV_EVENT2 = 0x1000;
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll", SetLastError = true)]
 | 
			
		||||
        internal static extern Boolean WaitCommEvent(IntPtr hFile, IntPtr lpEvtMask, IntPtr lpOverlapped);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean CancelIo(IntPtr hFile);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll", SetLastError = true)]
 | 
			
		||||
        internal static extern Boolean ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer, UInt32 nNumberOfBytesToRead,
 | 
			
		||||
                                                out UInt32 nNumberOfBytesRead, IntPtr lpOverlapped);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean TransmitCommChar(IntPtr hFile, Byte cChar);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Control port functions.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean EscapeCommFunction(IntPtr hFile, UInt32 dwFunc);
 | 
			
		||||
 | 
			
		||||
        // Constants for dwFunc:
 | 
			
		||||
        internal const UInt32 SETXOFF = 1;
 | 
			
		||||
        internal const UInt32 SETXON = 2;
 | 
			
		||||
        internal const UInt32 SETRTS = 3;
 | 
			
		||||
        internal const UInt32 CLRRTS = 4;
 | 
			
		||||
        internal const UInt32 SETDTR = 5;
 | 
			
		||||
        internal const UInt32 CLRDTR = 6;
 | 
			
		||||
        internal const UInt32 RESETDEV = 7;
 | 
			
		||||
        internal const UInt32 SETBREAK = 8;
 | 
			
		||||
        internal const UInt32 CLRBREAK = 9;
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean GetCommModemStatus(IntPtr hFile, out UInt32 lpModemStat);
 | 
			
		||||
 | 
			
		||||
        // Constants for lpModemStat:
 | 
			
		||||
        internal const UInt32 MS_CTS_ON = 0x0010;
 | 
			
		||||
        internal const UInt32 MS_DSR_ON = 0x0020;
 | 
			
		||||
        internal const UInt32 MS_RING_ON = 0x0040;
 | 
			
		||||
        internal const UInt32 MS_RLSD_ON = 0x0080;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Status Functions.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [DllImport("kernel32.dll", SetLastError = true)]
 | 
			
		||||
        internal static extern Boolean GetOverlappedResult(IntPtr hFile, IntPtr lpOverlapped,
 | 
			
		||||
                                                           out UInt32 nNumberOfBytesTransferred, Boolean bWait);
 | 
			
		||||
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean ClearCommError(IntPtr hFile, out UInt32 lpErrors, IntPtr lpStat);
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean ClearCommError(IntPtr hFile, out UInt32 lpErrors, out COMSTAT cs);
 | 
			
		||||
 | 
			
		||||
        //Constants for lpErrors:
 | 
			
		||||
        internal const UInt32 CE_RXOVER = 0x0001;
 | 
			
		||||
        internal const UInt32 CE_OVERRUN = 0x0002;
 | 
			
		||||
        internal const UInt32 CE_RXPARITY = 0x0004;
 | 
			
		||||
        internal const UInt32 CE_FRAME = 0x0008;
 | 
			
		||||
        internal const UInt32 CE_BREAK = 0x0010;
 | 
			
		||||
        internal const UInt32 CE_TXFULL = 0x0100;
 | 
			
		||||
        internal const UInt32 CE_PTO = 0x0200;
 | 
			
		||||
        internal const UInt32 CE_IOE = 0x0400;
 | 
			
		||||
        internal const UInt32 CE_DNS = 0x0800;
 | 
			
		||||
        internal const UInt32 CE_OOP = 0x1000;
 | 
			
		||||
        internal const UInt32 CE_MODE = 0x8000;
 | 
			
		||||
        [DllImport("kernel32.dll")]
 | 
			
		||||
        internal static extern Boolean GetCommProperties(IntPtr hFile, out COMMPROP cp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user