/// <summary> /// Power On smartcard /// </summary> /// <returns> /// Empty or error message /// </returns> public bool AnswerToReset() //ref string response) { string retContext = ""; // check for selected reader if (SelectedReader == "") { log.Error("Reader not set"); return(false); } // close connection and context CloseConnection(); System.Threading.Thread.Sleep(20); ReleaseContext(); // delay before power on System.Threading.Thread.Sleep(200); // Try to create new context retContext = CreateContext(); if (retContext != "") { // error detected return(false); } System.Threading.Thread.Sleep(20); // Connect to smartcard int ret = WinSCard.SCardConnect(nContext, SelectedReader, (uint)WinSCard.SCARD_SHARE.SCARD_SHARE_SHARED, (uint)WinSCard.SCARD_PROTOCOL.SCARD_PROTOCOL_T0 | (uint)WinSCard.SCARD_PROTOCOL.SCARD_PROTOCOL_T1, ref nCard, ref nActiveProtocol); if (ret != 0) { // Error detected log.Error("AnswerToReset " + WinSCard.ParseError(ret)); return(false); } // Get ATR bool retStatus = ReaderStatus(); if (!retStatus) { log.Error("AnswerToReset - Error getting ATR"); return(false); } return(true); }
/// <summary> /// Updates list of readers /// </summary> private void UpdateListReaders() { byte[] readersBuf = new byte[0]; IntPtr readersBufLen = IntPtr.Zero; List <byte> lreaders = new List <byte>(); List <string> lstreaders = new List <string>(); //First time to retrieve the len of buffer for readers name ret = WinSCard.SCardListReaders(nContext, null, readersBuf, out readersBufLen); // Redim buffer readersBuf = new byte[readersBufLen.ToInt32()]; // Second time to retrieve readers name ret = WinSCard.SCardListReaders(nContext, null, readersBuf, out readersBufLen); if (ret != 0) { // Error detected log.Error("PcscReader::UpdateListReaders: SCardListReaders " + WinSCard.ParseError(ret)); return; } if (readersBuf.Length < 5) { // No readers founded return; } // Loop to detect readers for (int j = 0; j < readersBuf.Length; j++) { // check for first null byte if (readersBuf[j] != 0x00) { // Add byte to byte list lreaders.Add(readersBuf[j]); } else { //check for second null byte (end of list) if (readersBuf[j - 1] == 0x00) { break; } // Update readers list lstreaders.Add(Encoding.ASCII.GetString(lreaders.ToArray())); lreaders = new List <byte>(); } } // update public list Readers = lstreaders; }
/// <summary> /// Release PCSC context /// </summary> private void ReleaseContext() { if (nContext.ToInt64() != 0) { // Release PCSC context ret = WinSCard.SCardReleaseContext(nContext); log.Debug("ReleaseContext " + WinSCard.ParseError(ret)); nContext = IntPtr.Zero; } }
/// <summary> /// Disconnect smartcard from reader /// </summary> public void CloseConnection() { // check for card context if (nCard.ToInt64() != 0) { // disconnect ret = WinSCard.SCardDisconnect(nCard, (uint)WinSCard.SCARD_DISPOSITION.SCARD_UNPOWER_CARD); log.Debug("CloseConnection " + ret.ToString()); nCard = IntPtr.Zero; } }
private string CreateContext() { // Create PCSC context int ret = WinSCard.SCardEstablishContext(WinSCard.SCARD_SCOPE_SYSTEM, nNotUsed1, nNotUsed2, ref nContext); if (ret != 0) { // Error detected nContext = IntPtr.Zero; log.Error("CreateContext " + WinSCard.ParseError(ret)); return(WinSCard.ParseError(ret)); } log.Debug("CreateContext " + WinSCard.ParseError(ret)); return(""); }
/// <summary> /// Exchange data with smartcard /// </summary> /// <returns> /// Empty or error message /// </returns> public bool SendReceive(string command, ref string response) { // check for selected reader if (SelectedReader == "") { log.Error("Card reader not selected"); return(false); } IntPtr retCommandLen = new IntPtr(261); // remove unused digits command = command.Trim().Replace("0x", "").Replace(" ", ""); // Set input command byte array byte[] inCommandByte = Utility.GetBytesFromHex(command); byte[] outCommandByte = new byte[261]; // Prepare structures WinSCard.SCARD_IO_REQUEST pioSend = new WinSCard.SCARD_IO_REQUEST(); WinSCard.SCARD_IO_REQUEST pioRecv = new WinSCard.SCARD_IO_REQUEST(); pioSend.dwProtocol = (uint)cardProtocol; pioSend.cbPciLength = (uint)8; pioRecv.dwProtocol = (uint)cardProtocol; pioRecv.cbPciLength = 0; // exchange data with smartcard int ret = WinSCard.SCardTransmit(nCard, ref pioSend, inCommandByte, inCommandByte.Length, IntPtr.Zero, outCommandByte, out retCommandLen); if (ret != 0) { // Error detected log.Error("PcScReader.IReader::SendReceive: SCardTransmit " + WinSCard.ParseError(ret)); return(false); } // Extract response response = Utility.GetHexFromBytes(outCommandByte, 0, retCommandLen.ToInt32()).Trim(); return(true); }
/// <summary> /// Get ATR and smartcard status /// </summary> /// <returns> /// Empty or error message /// </returns> public bool ReaderStatus() //ref string response) { // set empty byte array atrValue = new byte[33]; byte[] retRName = new byte[64]; readerNameLen = new IntPtr(64); atrLen = new IntPtr(33); cardProtocol = 1; uint readerState = 0; // firts time to set sizes ret = WinSCard.SCardStatus(nCard, retRName, ref readerNameLen, out readerState, out cardProtocol, atrValue, ref atrLen); if (ret != 0) { // reset byte array to returned length and retry atrValue = new byte[atrLen.ToInt32()]; retRName = new byte[readerNameLen.ToInt32()]; ret = WinSCard.SCardStatus(nCard, retRName, ref readerNameLen, out readerState, out cardProtocol, atrValue, ref atrLen); } if (ret != 0) { // Error detected log.Error("ReaderStatus " + WinSCard.ParseError(ret)); return(false); } // Extract ATR value var response = Utility.GetHexFromBytes(atrValue, 0, atrLen.ToInt32()); log.Debug("ATR value: " + response); return(true); }