private void StatusChangeMonitor()
        {
            uint rc;

              IntPtr hContext = IntPtr.Zero;

              _reader_state = SCARD.STATE_UNAWARE;
              _card_atr = null;

              rc =
            SCARD.EstablishContext(SCARD.SCOPE_SYSTEM, IntPtr.Zero,
                               IntPtr.Zero, ref hContext);
              if (rc != SCARD.S_SUCCESS)
            return;

              SCARD.READERSTATE[] states = new SCARD.READERSTATE[1];

              states[0] = new SCARD.READERSTATE();
              states[0].szReader = _reader_name;
              states[0].pvUserData = IntPtr.Zero;
              states[0].dwCurrentState = 0;
              states[0].dwEventState = 0;
              states[0].cbAtr = 0;
              states[0].rgbAtr = null;

              while (_status_change_running)
              {
            rc = SCARD.GetStatusChange(hContext, 250, states, 1);

            if (!_status_change_running)
              break;

            if (rc == SCARD.E_TIMEOUT)
              continue;

            if (rc != SCARD.S_SUCCESS)
            {
              _last_error = rc;

              SCARD.ReleaseContext(hContext);
              if (_status_change_callback != null)
            _status_change_callback(0, null);
              break;
            }

            states[0].dwCurrentState = states[0].dwEventState;

            if ((states[0].dwEventState & SCARD.STATE_CHANGED) != 0)
            {
              if (_status_change_callback != null)
              {
            CardBuffer card_atr = null;

            if ((states[0].dwEventState & SCARD.STATE_PRESENT) != 0)
              card_atr =
                new CardBuffer(states[0].rgbAtr, (int)states[0].cbAtr);

            _status_change_callback(states[0].dwEventState & ~SCARD.
                                    STATE_CHANGED, card_atr);
              }
            }
              }

              SCARD.ReleaseContext(hContext);
        }
        private void UpdateState()
        {
            uint rc;

              IntPtr hContext = IntPtr.Zero;

              _reader_state = SCARD.STATE_UNAWARE;
              _card_atr = null;

              rc =
            SCARD.EstablishContext(SCARD.SCOPE_SYSTEM, IntPtr.Zero,
                               IntPtr.Zero, ref hContext);
              if (rc != SCARD.S_SUCCESS)
              {
            _last_error = rc;
            return;
              }

              SCARD.READERSTATE[] states = new SCARD.READERSTATE[1];

              states[0] = new SCARD.READERSTATE();
              states[0].szReader = _reader_name;
              states[0].pvUserData = IntPtr.Zero;
              states[0].dwCurrentState = 0;
              states[0].dwEventState = 0;
              states[0].cbAtr = 0;
              states[0].rgbAtr = null;

              rc = SCARD.GetStatusChange(hContext, 0, states, 1);
              if (rc != SCARD.S_SUCCESS)
              {
            SCARD.ReleaseContext(hContext);
            return;
              }

              SCARD.ReleaseContext(hContext);

              _reader_state = states[0].dwEventState;

              if ((_reader_state & SCARD.STATE_PRESENT) != 0)
              {
            _card_atr = new CardBuffer(states[0].rgbAtr, (int)states[0].cbAtr);
              }
        }
        private void decode_apdu()
        {
            if (_bytes == null)
            return;

              if (_bytes.Length < 4)
            return;

              _cla = _bytes[0];
              _ins = _bytes[1];
              _p1 = _bytes[2];
              _p2 = _bytes[3];

              if (_bytes.Length == 4)
              {
            _data = null;
            _le_defined = false;
            _le = 0;
              }
              else if (_bytes.Length == 5)
              {
            _data = null;
            _le_defined = true;
            _le = _bytes[4];
              }
              else
              {
            if (_bytes.Length == (5 + _bytes[4]))
            {
              _le_defined = false;
              _le = 0;
            }
            else if (_bytes.Length == (6 + _bytes[4]))
            {
              _le_defined = true;
              _le = _bytes[_bytes.Length - 1];
            }
            else
            {
              return;
            }

            _data = new CardBuffer(_bytes, 5, _bytes[4]);
              }
        }
        private void UpdateState()
        {
            uint rc;

              _reader_state = SCARD.STATE_UNAWARE;
              _card_atr = null;

              if (Connected)
              {
            byte[] atr_buffer = new byte[36];
            uint atr_length = 36;

            uint dummy = 0;

            rc =
              SCARD.Status(_hCard, IntPtr.Zero, ref dummy,
                       ref _reader_state, ref _active_protocol, atr_buffer,
                       ref atr_length);
            if (rc != SCARD.S_SUCCESS)
            {
              _last_error = rc;
              return;
            }

            _card_atr = new CardBuffer(atr_buffer, (int)atr_length);

              }
              else
              {
            SCARD.READERSTATE[] states = new SCARD.READERSTATE[1];

            states[0] = new SCARD.READERSTATE();
            states[0].szReader = _reader_name;
            states[0].pvUserData = IntPtr.Zero;
            states[0].dwCurrentState = 0;
            states[0].dwEventState = 0;
            states[0].cbAtr = 0;
            states[0].rgbAtr = null;

            rc = SCARD.GetStatusChange(_hContext, 0, states, 1);
            if (rc != SCARD.S_SUCCESS)
            {
              _last_error = rc;
              return;
            }

            _reader_state = states[0].dwEventState;

            if ((_reader_state & SCARD.STATE_PRESENT) != 0)
            {
              _card_atr = new CardBuffer(states[0].rgbAtr, (int)states[0].cbAtr);
            }
              }
        }
        public CardBuffer Control(CardBuffer cctrl)
        {
            _cctrl = cctrl;

              if (!Control())
            return null;

              return _rctrl;
        }
        public bool Control(CardBuffer cctrl, ref CardBuffer rctrl)
        {
            _cctrl = cctrl;

              if (!Control())
            return false;

              rctrl = _rctrl;
              return true;
        }
        public bool Control()
        {
            byte[] rsp_buffer = new byte[258];
              uint rsp_length = 0;
              uint rc;

              _rctrl = null;

              rc = SCARD.Control(_hCard,
                         SCARD.IOCTL_CSB6_PCSC_ESCAPE,
                         _cctrl.Bytes,
                         _cctrl.Size, rsp_buffer, 258, ref rsp_length);

              if (rc == 1)
              {
            rc = SCARD.Control(_hCard,
                           SCARD.IOCTL_MS_CCID_ESCAPE,
                           _cctrl.Bytes,
                           _cctrl.Size, rsp_buffer, 258, ref rsp_length);

              }

              if (rc != SCARD.S_SUCCESS)
              {
            _last_error = rc;
            return false;
              }

              _rctrl = new CardBuffer(rsp_buffer, (int)rsp_length);
              return true;
        }