public static List <string> ListModWinsCards()
        {
            int           _context = -1;
            List <string> lst      = new List <string>();
            int           retCode  = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref _context);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return(null);
            }
            if (_context == -1)
            {
                return(null);
            }
            int readerCount = 255;

            Byte[] bytes = new Byte[readerCount];

            retCode = ModWinsCard.SCardListReaders(_context, null, bytes, ref readerCount);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return(null);
            }

            try
            {
                string[] readerArr = System.Text.ASCIIEncoding.ASCII.GetString(bytes, 0, readerCount).Split('\0');
                foreach (string readerName in readerArr)
                {
                    if (!string.IsNullOrEmpty(readerName) && readerName.Length > 1)
                    {
                        // http://stackoverflow.com/questions/6940824/getting-pcsc-reader-serial-number-with-winscard
                        int readerHandle = 0;

                        int protocol = 0;
                        int ret      = ModWinsCard.SCardConnect(_context, readerName, ModWinsCard.SCARD_SHARE_DIRECT, ModWinsCard.SCARD_PROTOCOL_UNDEFINED, ref readerHandle, ref protocol);

                        byte[] data = new byte[128];
                        int    leng = 128;
                        ret = ModWinsCard.SCardGetAttrib(readerHandle, ModWinsCard.SCARD_ATTR_VENDOR_IFD_SERIAL_NO, data, ref leng);

                        string serialNo = System.Text.ASCIIEncoding.ASCII.GetString(data, 0, leng);

                        //int b = ModWinsCard.SCardFreeMemory(_context, data);

                        ModWinsCard.SCardDisconnect(readerHandle, ModWinsCard.SCARD_LEAVE_CARD);

                        lst.Add(serialNo);
                    }
                }
            }
            catch
            {
                return(null);
            }
            return(lst);
        }
        private void GetReady()
        {
            int retCode = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref _context);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {
                this._canRead = false;
                return;
            }
            if (_context == -1)
            {
                this._canRead = false;
                return;
            }
            int readerCount = 255;

            Byte[] bytes = new Byte[readerCount];

            retCode = ModWinsCard.SCardListReaders(_context, null, bytes, ref readerCount);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {
                this._canRead = false;
                return;
            }

            try
            {
                string[] readerArr = System.Text.ASCIIEncoding.ASCII.GetString(bytes, 0, readerCount).Split('\0');
                foreach (string readerName in readerArr)
                {
                    GetSerialNumber(readerName, (res, b) =>
                    {
                        if (b && res == this._info.SerialNumber)
                        {
                            this._info.DeviceName = readerName;
                            this._canRead         = true;
                            return;
                        }
                    });
                }
            }
            catch
            {
                this._canRead = false;
                return;
            }
        }
        private void ReadingThread()
        {
            try
            {
                SCARD_READERSTATE readerState;
                readerState.RdrCurrState  = ModWinsCard.SCARD_STATE_UNAWARE;
                readerState.RdrEventState = ModWinsCard.SCARD_STATE_UNKNOWN;
                readerState.UserData      = new IntPtr(0);
                readerState.ATRLength     = 0;
                readerState.ATRValue      = new byte[36];
                readerState.RdrName       = this._info.DeviceName;
                while (true)
                {
                    if (_canRead && _state == CardState.IsReady)
                    {
                        DateTime tmp = DateTime.Now;
                        if (connectTime <= tmp)
                        {
                            connectTime = tmp.AddMilliseconds(2);
                            try
                            {
                                int retCode = ModWinsCard.SCardGetStatusChange(_context, ModWinsCard.INFINITE, ref readerState, 1);

                                if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                                {
                                    readerState.RdrCurrState  = ModWinsCard.SCARD_STATE_UNAWARE;
                                    readerState.RdrEventState = ModWinsCard.SCARD_STATE_UNKNOWN;
                                    readerState.UserData      = new IntPtr(0);
                                    readerState.ATRLength     = 0;
                                    readerState.ATRValue      = new byte[36];
                                    readerState.RdrName       = this._info.DeviceName;

                                    ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref _context);
                                    Thread.Sleep(1000);

                                    //ReadingCompleted(this, new GreenCardReaderEventArgs() { CardID = string.Empty, CardReader = this, ex = new Exception("Reading failed") });
                                    continue;
                                }

                                if ((readerState.RdrEventState & ModWinsCard.SCARD_STATE_CHANGED) == ModWinsCard.SCARD_STATE_CHANGED)
                                {
                                    if ((readerState.RdrEventState & ModWinsCard.SCARD_STATE_EMPTY) == ModWinsCard.SCARD_STATE_EMPTY)
                                    {
                                        if (TakingOffCompleted != null)
                                        {
                                            TakingOffCompleted(this, new GreenCardReaderEventArgs()
                                            {
                                                CardID = string.Empty, CardReader = this
                                            });
                                        }
                                    }
                                    else if (((readerState.RdrEventState & ModWinsCard.SCARD_STATE_PRESENT) == ModWinsCard.SCARD_STATE_PRESENT) &&
                                             ((readerState.RdrEventState & ModWinsCard.SCARD_STATE_PRESENT) != (readerState.RdrCurrState & ModWinsCard.SCARD_STATE_PRESENT)))
                                    {
                                        GetCardId();
                                        //GetCardIdLisa();
                                    }
                                }

                                readerState.RdrCurrState = readerState.RdrEventState;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("BUGGG: {0}", ex.Message);
                                this.DisConnect();
                                GetReady();
                                Thread.Sleep(1000);
                                this.Connect();
                            }
                        }
                    }
                    else
                    {
                        this.DisConnect();
                        GetReady();
                        Thread.Sleep(1000);
                        this.Connect();
                    }
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine("BUGGG: {0}", exception.Message);
                this.DisConnect();
                GetReady();
                System.Threading.Thread.Sleep(1000);
                this.Connect();
            }
        }