/// <summary> /// Will try to connect to _connectedReader and read the card. /// </summary> /// <returns>Either the data from the card or the error message. Or if 'uidOnly' is true, just the UID prefixed with 'UID^' and ending with '^'</returns> public string ReadCard(bool uidOnly = false) { SCardContext context = new SCardContext(); context.Establish(SCardScope.System); SCardReader reader = new SCardReader(context); SCardError result = reader.Connect(_connectedReader, SCardShareMode.Shared, SCardProtocol.Any); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("No card is detected (or reader reserved by another application){0}{1}", Environment.NewLine, SCardHelper.StringifyError(result)); } string[] readerNames; SCardProtocol protocol; SCardState state; byte[] atr; result = reader.Status(out readerNames, out state, out protocol, out atr); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("Unable to read from card.{0}{1}", Environment.NewLine, SCardHelper.StringifyError(result)); } string message = string.Format("Card detected:{0}Protocol: {1}{0}State: {2}{0}ATR: {3}{0}", Environment.NewLine, protocol, state, BitConverter.ToString(atr ?? new byte[0])); CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol) { CLA = 0xFF, Instruction = InstructionCode.GetData, P1 = 0x00, P2 = 0x00, Le = 0 }; result = reader.BeginTransaction(); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("Cannot start transaction.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)); } SCardPCI recievePci = new SCardPCI(); IntPtr sendPci = SCardPCI.GetPci(reader.ActiveProtocol); byte[] recieveBuffer = new byte[256]; result = reader.Transmit(sendPci, apdu.ToArray(), recievePci, ref recieveBuffer); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("Cannot transmit data.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)); } var responseApdu = new ResponseApdu(recieveBuffer, IsoCase.Case2Short, reader.ActiveProtocol); message += string.Format("SW1: {1}{0}SW2: {2}{0}", Environment.NewLine, responseApdu.SW1, responseApdu.SW2); string data = responseApdu.HasData ? BitConverter.ToString(responseApdu.GetData()) : "--"; if (uidOnly) { context.Dispose(); reader.Dispose(); return string.Format("UID^{0}^", data); } message += string.Format("UID: {0}",data); reader.EndTransaction(SCardReaderDisposition.Leave); reader.Disconnect(SCardReaderDisposition.Reset); context.Dispose(); reader.Dispose(); return message; }
static void Main(string[] args) { SCardContext ctx = new SCardContext(); ctx.Establish(SCardScope.System); // retrieve all reader names string[] readernames = ctx.GetReaders(); if (readernames != null) { // get the card status of each reader that is currently connected foreach (string readername in readernames) { SCardReader reader = new SCardReader(ctx); Console.Write("Trying to connect to reader " + readername + ".."); SCardError serr = reader.Connect(readername, SCardShareMode.Shared, SCardProtocol.Any); if (serr == SCardError.Success) { // SmartCard inserted, reader is now connected. Console.WriteLine(" done."); string[] tmpreadernames; SCardProtocol proto; SCardState state; byte[] atr; serr = reader.Status( out tmpreadernames, // contains the reader name(s) out state, // contains the current state (flags) out proto, // contains the currently used communication protocol out atr); // contains the card ATR if (serr == SCardError.Success) { Console.WriteLine("Connected with protocol " + proto + " in state " + state); if (atr != null && atr.Length > 0) { Console.Write("Card ATR: "); foreach (byte b in atr) Console.Write("{0:X2}", b); Console.WriteLine(); } Console.WriteLine(); } else { Console.WriteLine("Unable to retrieve card status.\nError message: " + SCardHelper.StringifyError(serr) + ".\n"); } reader.Disconnect(SCardReaderDisposition.Reset); } else { /* SmardCard not inserted or reader is reserved exclusively by another application. */ Console.WriteLine(" failed.\nError message: " + SCardHelper.StringifyError(serr) + ".\n"); } } } return; }
/// <summary> /// Will try to connect to the _connectedReader, see if there is a card present, and if so try to read the data. /// </summary> /// <returns>Either the error message or data from the card.</returns> public string TryToReadCard() { SCardContext context = new SCardContext(); context.Establish(SCardScope.System); SCardReader reader = new SCardReader(context); SCardError result = SCardError.InternalError; try { result = reader.Connect(_connectedReader, SCardShareMode.Shared, SCardProtocol.Any); } catch (Exception) { context.Dispose(); reader.Dispose(); return SCardHelper.StringifyError(result); } string message; if (result == SCardError.Success) { string[] readerNames; SCardProtocol protocol; SCardState state; byte[] atr; result = reader.Status(out readerNames, out state, out protocol, out atr); if (result == SCardError.Success) message = string.Format("Card detected:{0} Protocol: {1}{0} State: {2}{0} ATR: {3}", Environment.NewLine, protocol, state, BitConverter.ToString(atr ?? new byte[0])); else message = string.Format("Unable to read from card.{0}{1}", Environment.NewLine, SCardHelper.StringifyError(result)); } else message = string.Format("No card is detected (or reader reserved by another application){0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)); context.Dispose(); reader.Dispose(); return message; }
public Boolean Open(string readerName = null) { try { // Establish SCard context _hContext = new SCardContext(); _hContext.Establish(SCardScope.System); // Create a _reader object using the existing context _reader = new SCardReader(_hContext); // Connect to the card if (readerName == null || readerName == String.Empty) { // Retrieve the list of Smartcard _readers string[] szReaders = _hContext.GetReaders(); if (szReaders.Length <= 0) throw new PCSCException(SCardError.NoReadersAvailable, "Could not find any Smartcard _reader."); _err = _reader.Connect(szReaders[0], SCardShareMode.Exclusive, SCardProtocol.T0 | SCardProtocol.T1); CheckErr(_err); } else { _err = _reader.Connect(readerName, SCardShareMode.Exclusive, SCardProtocol.T0 | SCardProtocol.T1); CheckErr(_err); } _pioSendPci = new IntPtr(); switch (_reader.ActiveProtocol) { case SCardProtocol.T0: _pioSendPci = SCardPCI.T0; break; case SCardProtocol.T1: _pioSendPci = SCardPCI.T1; break; default: throw new PCSCException(SCardError.ProtocolMismatch, "Protocol not supported: " + _reader.ActiveProtocol.ToString()); } string[] readerNames; SCardProtocol proto; SCardState state; byte[] atr; var sc = _reader.Status( out readerNames, // contains the reader name(s) out state, // contains the current state (flags) out proto, // contains the currently used communication protocol out atr); // contains the ATR if (atr == null || atr.Length < 2) { return false; } if (atr[0] == 0x3B && atr[1] == 0x68) //Smart card tested with old type (Figure A.) { _apdu = new APDU_THAILAND_IDCARD_3B68(); } else if (atr[0] == 0x3B && atr[1] == 0x78) //Smart card tested with new type (figure B.) { _apdu = new APDU_THAILAND_IDCARD_3B68(); } else if (atr[0] == 0x3B && atr[1] == 0x67) { _apdu = new APDU_THAILAND_IDCARD_3B67(); } else { _error_code = ECODE_UNSUPPORT_CARD; _error_message = "Card not support"; Console.WriteLine(_error_message); return false; } return true; } catch (PCSCException ex) { _error_code = ECODE_SCardError; _error_message = "Err: " + ex.Message + " (" + ex.SCardError.ToString() + ")"; Console.WriteLine(_error_message); return false; } }