internal SerialStream(string resource, int baudRate, Parity parity, int dataBits, StopBits stopBits, int readTimeout, int writeTimeout, Handshake handshake, 
			bool dtrEnable, bool rtsEnable, bool discardNull, byte parityReplace) 
		{
		
			IntPtr tempHandle = Win32API_Serial.CreateFile("\\\\.\\" + resource,
				Win32API_Serial.GENERIC_READ | Win32API_Serial.GENERIC_WRITE,
				0,    
				Win32API_Serial.NULL, 
				Win32API_Serial.OPEN_EXISTING, 
				Win32API_Serial.FILE_FLAG_OVERLAPPED |
				Win32API_Serial.FILE_ATTRIBUTE_NORMAL,    
				Win32API_Serial.NULL  
				);

			if (tempHandle == Win32API_Serial.INVALID_HANDLE_VALUE) 
			{
				int errorCode = Marshal.GetLastWin32Error();
				switch(errorCode) 
				{
					case Win32API_Serial.ERROR_FILE_NOT_FOUND:
						throw new FileNotFoundException("resource", Resources.GetResourceString("IO.FileNotFound_FileName", resource));
		
					case Win32API_Serial.ERROR_ACCESS_DENIED:
						throw new UnauthorizedAccessException(Resources.GetResourceString("UnauthorizedAccess_IODenied_Path", resource));
					default:
						Resources.WinIOError();
						break;
				}
			}
			

			// kd5tfd -- fix Keyspan problem -- Keyspan USB serial adapters return FILE_TYPE_UNKNOWN here so we 
			// allow that to accomodate the Keyspan adapater.  (Sept 2006) 
			int ftype = Win32API_Serial.GetFileType(tempHandle);
			if ( (ftype  != Win32API_Serial.FILE_TYPE_CHAR) && 
			     (ftype  != Win32API_Serial.FILE_TYPE_UNKNOWN) ) 
				throw new ArgumentException("resource", Resources.GetResourceString("Arg_InvalidResourceFile"));
			
			_safeHandle = new __SafeHandle(tempHandle, true);
			
			this.portName = resource;
			this.handshake = handshake;
			this.dtrEnable = dtrEnable;
			this.rtsEnable = rtsEnable;
			this.parityReplace = parityReplace;
			
			tempBuf = new byte[1];			
		
			commProp = new Win32API_Serial.COMMPROP();
			if (Win32API_Serial.GetCommProperties(_safeHandle.Handle, ref commProp) == false) 
			{
				Win32API_Serial.CloseHandle(_safeHandle.Handle);
				Resources.WinIOError();
			}
			if (baudRate > commProp.dwMaxBaud && commProp.dwMaxBaud > 0) 
				throw new ArgumentOutOfRangeException("baudRate", "Requested baud greater than maximum for this device driver = " + commProp.dwMaxBaud);
			
			comStat = new Win32API_Serial.COMSTAT();
			dcb = new Win32API_Serial.DCB();
			
			InitializeDCB(baudRate, parity, dataBits, stopBits, discardNull);
		
			commTimeouts.ReadIntervalTimeout = (readTimeout == SerialPort.InfiniteTimeout) ? 0 : Win32API_Serial.MAXDWORD;
			commTimeouts.ReadTotalTimeoutMultiplier		= (readTimeout > 0 && readTimeout != SerialPort.InfiniteTimeout)
															? Win32API_Serial.MAXDWORD : 0;
			commTimeouts.ReadTotalTimeoutConstant		=  (readTimeout > 0 && readTimeout != SerialPort.InfiniteTimeout) ?
															readTimeout : 0;
			commTimeouts.WriteTotalTimeoutMultiplier	= 0;
			commTimeouts.WriteTotalTimeoutConstant		=  ((writeTimeout == SerialPort.InfiniteTimeout) ?
															0 : writeTimeout);
			if (Win32API_Serial.SetCommTimeouts(_safeHandle.Handle, ref commTimeouts) == false) 
			{
				Win32API_Serial.CloseHandle(_safeHandle.Handle);
				Resources.WinIOError();
			}		
			
			if (!ThreadPool.BindHandle(_safeHandle.Handle)) 
			{
				throw new IOException(Resources.GetResourceString("IO.IO_BindHandleFailed"));
			}
		
			myWaitCommCallback = new WaitEventCallback(WaitForCommEvent);
			myAsyncCallback = new AsyncCallback(EndWaitForCommEvent);
			state = null;	
			
			IAsyncResult ar = myWaitCommCallback.BeginInvoke(myAsyncCallback, state);
		}
Exemplo n.º 2
0
        private HandleProtector _handleProtector; // See the HandleProtector class.

        #endregion Fields

        #region Constructors

        // -----------SECTION: constructor --------------------------*
        // this method is used by SerialPort upon SerialStream's creation
        internal SerialStream(string resource, int baudRate, Parity parity, int dataBits, StopBits stopBits, int readTimeout, int writeTimeout, Handshake handshake,
            bool dtrEnable, bool rtsEnable, bool discardNull, byte parityReplace)
        {
            //Error checking done in SerialPort.

            IntPtr tempHandle = UnsafeNativeMethods.CreateFile("\\\\.\\" + resource,
                NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
                0,    // comm devices must be opened w/exclusive-access
                NativeMethods.NULL, // no security attributes
                UnsafeNativeMethods.OPEN_EXISTING, // comm devices must use OPEN_EXISTING
                UnsafeNativeMethods.FILE_FLAG_OVERLAPPED |
                UnsafeNativeMethods.FILE_ATTRIBUTE_NORMAL,    // async I/O
                NativeMethods.NULL  // hTemplate must be NULL for comm devices
                );

            if (tempHandle == NativeMethods.INVALID_HANDLE_VALUE)
            {
                int errorCode = Marshal.GetLastWin32Error();
                switch (errorCode)
                {
                    case NativeMethods.ERROR_FILE_NOT_FOUND:
                        throw new FileNotFoundException("ERROR_FILE_NOT_FOUND", InternalResources.GetResourceString("IO.FileNotFound_FileName", resource));

                    case NativeMethods.ERROR_ACCESS_DENIED:
                        throw new UnauthorizedAccessException(InternalResources.GetResourceString("UnauthorizedAccess_IODenied_Path", resource));
                    default:
                        InternalResources.WinIOError();
                        break;
                }
            }

            if (UnsafeNativeMethods.GetFileType(tempHandle) != UnsafeNativeMethods.FILE_TYPE_CHAR)
                throw new ArgumentException("INVALID_RESOURCE_FILE", InternalResources.GetResourceString("Arg_InvalidResourceFile"));

            _handleProtector = new __HandleProtector(tempHandle, true);

            // set properties of the stream that exist as members in SerialStream
            this.portName = resource;
            this.handshake = handshake;
            this.dtrEnable = dtrEnable;
            this.rtsEnable = rtsEnable;
            this.parityReplace = parityReplace;

            tempBuf = new byte[1];            // used in ReadByte()

            // fill COMMPROPERTIES struct, which has our maximum allowed baud rate
            commProp = new UnsafeNativeMethods.COMMPROP();
            if (UnsafeNativeMethods.GetCommProperties(_handleProtector.Handle, ref commProp) == false)
            {
                UnsafeNativeMethods.CloseHandle(_handleProtector.Handle);
                InternalResources.WinIOError();
            }
            if (baudRate > commProp.dwMaxBaud)
                throw new ArgumentOutOfRangeException("baudRate", "Requested baud greater than maximum for this device driver = " + commProp.dwMaxBaud);

            comStat = new UnsafeNativeMethods.COMSTAT();
            // create internal DCB structure, initialize according to Platform SDK
            // standard: ms-help://MS.MSNDNQTR.2002APR.1003/hardware/commun_965u.htm
            dcb = new UnsafeNativeMethods.DCB();

            // set constant properties of the DCB
            InitializeDCB(baudRate, parity, dataBits, stopBits, discardNull);

            // set timeout defaults
            commTimeouts.ReadIntervalTimeout = (readTimeout == SerialPort.InfiniteTimeout) ? 0 : NativeMethods.MAXDWORD;
            commTimeouts.ReadTotalTimeoutMultiplier = (readTimeout > 0 && readTimeout != SerialPort.InfiniteTimeout)
                                                            ? NativeMethods.MAXDWORD : 0;
            commTimeouts.ReadTotalTimeoutConstant = (readTimeout > 0 && readTimeout != SerialPort.InfiniteTimeout) ?
                                                            readTimeout : 0;
            commTimeouts.WriteTotalTimeoutMultiplier = 0;
            commTimeouts.WriteTotalTimeoutConstant = ((writeTimeout == SerialPort.InfiniteTimeout) ?
                                                            0 : writeTimeout);
            // note - we cannot have a meaningful conception of a 0 write timeout, since every write takes at
            // least 0 mills.

            // set unmanaged timeout structure
            if (UnsafeNativeMethods.SetCommTimeouts(_handleProtector.Handle, ref commTimeouts) == false)
            {
                UnsafeNativeMethods.CloseHandle(_handleProtector.Handle);
                InternalResources.WinIOError();
            }

            if (!ThreadPool.BindHandle(_handleProtector.Handle))
            {
                throw new IOException(InternalResources.GetResourceString("IO.IO_BindHandleFailed"));
            }

            // prep. for starting event cycle.
            myWaitCommCallback = new WaitEventCallback(WaitForCommEvent);
            myAsyncCallback = new AsyncCallback(EndWaitForCommEvent);
            state = null;    // no need for new object, since we never use it.

            IAsyncResult ar = myWaitCommCallback.BeginInvoke(myAsyncCallback, state);
        }