public SCardReaderList(uint Scope, string Groups) { _scope = Scope; _groups = Groups; _reader_names = SCARD.GetReaderList(Scope, Groups); _auto_update_list = true; }
public bool Write(byte address, CardBuffer buffer) { _last_error = SCARD.MifUlC_Write4(hCard, address, buffer.GetBytes()); if (_last_error != 0) { return(false); } return(true); }
public bool Authenticate(CardBuffer key) { _last_error = SCARD.MifUlC_Authenticate(hCard, key.GetBytes()); if (_last_error != 0) { return(false); } return(true); }
public bool ChangeKey(CardBuffer key) { _last_error = SCARD.MifUlC_ChangeKey(hCard, key.GetBytes()); if (_last_error != 0) { return(false); } return(true); }
public CardBuffer Read(byte address) { byte[] buffer = new byte[16]; _last_error = SCARD.MifUlC_Read(hCard, address, buffer); if (_last_error != 0) { return(null); } return(new CardBuffer(buffer)); }
private void Instanciate(uint Scope, string ReaderName) { uint rc; rc = SCARD.EstablishContext(Scope, IntPtr.Zero, IntPtr.Zero, ref _hContext); if (rc != SCARD.S_SUCCESS) { _hContext = IntPtr.Zero; _last_error = rc; } _reader_name = ReaderName; }
/**m* SCardChannel/Transmit * * NAME * SCardChannel.Transmit() * * SYNOPSIS * bool Transmit() * RAPDU Transmit(CAPDU capdu) * bool Transmit(CAPDU capdu, out RAPDU rapdu) * void Transmit(CAPDU capdu, TransmitDoneCallback callback) * * DESCRIPTION * Sends a command APDU (CAPDU) to the connected card, and retrieves its response APDU (RAPDU) * * SOURCE * * SCardChannel card = new SCardChannel( ... reader ... ); * if (!card.Connect( SCARD.PROTOCOL_T0|SCARD.PROTOCOL_T1 )) * { * // handle error * } * * * // Example 1 * // --------- * * card.Command = new CAPDU("00 A4 00 00 02 3F 00"); * if (!card.Transmit()) * { * // handle error * } * MessageBox.Show("Card answered: " + card.Response.AsString(" ")); * * * // Example 2 * // --------- * * RAPDU response = card.Transmit(new CAPDU("00 A4 00 00 02 3F 00"))) * if (response == null) * { * // handle error * } * MessageBox.Show("Card answered: " + response.AsString(" ")); * * * // Example 3 * // --------- * * CAPDU command = new CAPDU("00 A4 00 00 02 3F 00"); * RAPDU response = new RAPDU(); * if (!card.Transmit(command, out response)) * { * // handle error * } * MessageBox.Show("Card answered: " + response.AsString(" ")); * * * // Example 4 * // --------- * * // In this example the Transmit is performed by a background thread * // We supply a delegate so the main class (window/form) will be notified * // when Transmit will return * * delegate void OnTransmitDoneInvoker(RAPDU response); * * void OnTransmitDone(RAPDU response) * { * // Ensure we're back in the context of the main thread (application's message pump) * if (this.InvokeRequired) * { * this.BeginInvoke(new OnTransmitDoneInvoker(OnTransmitDone), response); * return; * } * * if (response == null) * { * // handle error * } * * MessageBox.Show("Card answered: " + response.AsString(" ")); * } * * card.Transmit(new CAPDU("00 A4 00 00 02 3F 00"), new SCardChannel.TransmitDoneCallback(OnTransmitDone)); * * * SEE ALSO * SCardChannel.Connect * SCardChannel.Transmit * SCardChannel.Command * SCardChannel.Response * **/ #region Transmit public virtual bool Transmit() { uint rsp_length = 32 * 1024; byte[] rsp_buffer = new byte[rsp_length]; uint rc; IntPtr SendPci = IntPtr.Zero; switch (_active_protocol) { case SCARD.PROTOCOL_T0: SendPci = SCARD.PCI_T0(); break; case SCARD.PROTOCOL_T1: SendPci = SCARD.PCI_T1(); break; case SCARD.PROTOCOL_RAW: SendPci = SCARD.PCI_RAW(); break; default: break; } _rapdu = null; Trace.WriteLine("Transmit << " + _capdu.AsString()); rc = SCARD.Transmit(_hCard, SendPci, _capdu.GetBytes(), (uint)_capdu.Length, IntPtr.Zero, /* RecvPci is likely to remain NULL */ rsp_buffer, ref rsp_length); if (rc != SCARD.S_SUCCESS) { Trace.WriteLine("Transmit : " + rc); _last_error = rc; return(false); } _rapdu = new RAPDU(rsp_buffer, (int)rsp_length); Trace.WriteLine("Transmit >> " + _rapdu.AsString()); return(true); }
private void UpdateState() { uint rc; IntPtr hContext = IntPtr.Zero; _reader_state = SCARD.STATE_UNAWARE; _card_atr = null; rc = SCARD.EstablishContext(_scope, 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; try { rc = SCARD.GetStatusChange(hContext, 0, states, 1); } catch (ThreadInterruptedException) { rc = SCARD.E_CANCELLED; } 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); } }
public static string[] GetReaderList(uint Scope, string Groups) { IntPtr hContext = IntPtr.Zero; uint rc; rc = SCARD.EstablishContext(Scope, IntPtr.Zero, IntPtr.Zero, ref hContext); if (rc != SCARD.S_SUCCESS) { return(null); } string[] readers = GetReaderList(hContext, Groups); SCARD.ReleaseContext(hContext); return(readers); }
public virtual byte[] Control(byte[] cctrl) { byte[] rctrl = new byte[280]; uint rl = 0; uint rc; Trace.WriteLine("Control << " + (new CardBuffer(cctrl)).AsString()); rc = SCARD.Control(_hCard, SCARD.IOCTL_CSB6_PCSC_ESCAPE, cctrl, (uint)cctrl.Length, rctrl, 280, ref rl); if (rc == 1) { rc = SCARD.Control(_hCard, SCARD.IOCTL_MS_CCID_ESCAPE, cctrl, (uint)cctrl.Length, rctrl, 280, ref rl); } if (rc != SCARD.S_SUCCESS) { Trace.WriteLine("Control: " + rc); _last_error = rc; rctrl = null; return(null); } byte[] r = new byte[rl]; for (int i = 0; i < rl; i++) { r[i] = rctrl[i]; } Trace.WriteLine("Control >> " + (new CardBuffer(r)).AsString()); return(r); }
/**m* SCardReaderList/StopMonitor * * NAME * SCardReaderList.StopMonitor() * * DESCRIPTION * Stop the background thread previously launched by SCardReaderList.StartMonitor(). * **/ public void StopMonitor() { _status_change_callback = null; _status_change_running = false; if (_status_change_thread != null) { if (_status_change_context != IntPtr.Zero) { SCARD.Cancel(_status_change_context); } else { _status_change_thread.Interrupt(); } _status_change_thread.Join(); _status_change_thread = null; } }
/**m* SCardChannel/Reconnect * * NAME * SCardChannel.Reconnect() * * SYNOPSIS * bool Reconnect() * bool Reconnect(uint disposition) * * DESCRIPTION * Re-open the connection channel to the smartcard * * INPUTS * The disposition parameter must take one of the following values: * - SCARD.EJECT_CARD * - SCARD.UNPOWER_CARD * - SCARD.RESET_CARD * - SCARD.LEAVE_CARD * If this parameter is omitted, it defaults to SCARD.RESET_CARD * * OUTPUT * Returns true if the connection has been successfully re-established. * Returns false if not. See LastError for details. * * SEE ALSO * SCardChannel.Connect * SCardChannel.Disconnect * **/ public virtual bool Reconnect(uint disposition) { uint rc; if (!Connected) { return(false); } rc = SCARD.Reconnect(_hCard, _share_mode, _want_protocols, disposition, ref _active_protocol); if (rc != SCARD.S_SUCCESS) { _hCard = IntPtr.Zero; _last_error = rc; return(false); } UpdateState(); return(true); }
/**m* SCardChannel/Disconnect * * NAME * SCardChannel.Disconnect() * * SYNOPSIS * bool Disconnect() * bool Disconnect(uint disposition) * * DESCRIPTION * Close the connection channel * * INPUTS * The disposition parameter must take one of the following values: * - SCARD.EJECT_CARD * - SCARD.UNPOWER_CARD * - SCARD.RESET_CARD * - SCARD.LEAVE_CARD * If this parameter is omitted, it defaults to SCARD.RESET_CARD * * SEE ALSO * SCardChannel.Connect * **/ public virtual bool Disconnect(uint disposition) { uint rc; Trace.WriteLine("Disconnect, disposition=" + disposition); rc = SCARD.Disconnect(_hCard, disposition); if (rc != SCARD.S_SUCCESS) { _last_error = rc; } _hCard = IntPtr.Zero; if (rc != SCARD.S_SUCCESS) { return(false); } return(true); }
/**m* SCardChannel/Connect * * NAME * SCardChannel.Connect() * * SYNOPSIS * bool Connect() * * DESCRIPTION * Open the connection channel to the smartcard (according to the specified Protocol, default is either T=0 or T=1) * * OUTPUT * Returns true if the connection has been successfully established. * Returns false if not. See LastError for details. * * SEE ALSO * SCardChannel.CardPresent * SCardChannel.CardAtr * SCardChannel.Protocol * SCardChannel.Transmit * **/ public virtual bool Connect() { uint rc; if (Connected) { return(false); } Trace.WriteLine("Connect to '" + _reader_name + "', share=" + _share_mode + ", protocol=" + _want_protocols); rc = SCARD.Connect(_hContext, _reader_name, _share_mode, _want_protocols, ref _hCard, ref _active_protocol); if (rc != SCARD.S_SUCCESS) { Trace.WriteLine(String.Format("Connect error {0:X08} ({0})", rc)); _hCard = IntPtr.Zero; _last_error = rc; return(false); } UpdateState(); return(true); }
public static string[] GetReaderList(IntPtr hContext, string Groups) { int i, j = 0; string s = ""; uint rc; uint readers_size = 0; int readers_count = 0; rc = SCARD.ListReaders(hContext, Groups, null, ref readers_size); if (rc != SCARD.S_SUCCESS) { return(null); } string readers_str = new string(' ', (int)readers_size); rc = SCARD.ListReaders(hContext, Groups, readers_str, ref readers_size); if (rc != SCARD.S_SUCCESS) { return(null); } for (i = 0; i < readers_size; i++) { if (readers_str[i] == '\0') { if (i > 0) { readers_count++; } if (readers_str[i + 1] == '\0') { break; } } } string[] readers = new string[readers_count]; if (readers_count > 0) { for (i = 0; i < readers_size; i++) { if (readers_str[i] == '\0') { readers[j++] = s; if (readers_str[i + 1] == '\0') { break; } s = ""; } else { s = s + readers_str[i]; } } } return(readers); }
private void InitList() { _reader_names = SCARD.GetReaderList(_scope, _groups); }
private void StatusChangeMonitor() { try { _last_error = SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref _status_change_context); if (_last_error != SCARD.S_SUCCESS) { _status_change_callback(null, 0, null); return; } uint global_notification_state = SCARD.STATE_UNAWARE; while (_status_change_running) { if (_status_change_context == IntPtr.Zero) { _last_error = SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref _status_change_context); if (_last_error != SCARD.S_SUCCESS) { _status_change_callback(null, 0, null); return; } } /* Construct the list of readers we'll have to monitor */ /* --------------------------------------------------- */ bool global_notification_fired = false; int monitor_count = 0; if (_auto_update_list) { if (_reader_names != null) { monitor_count = _reader_names.Length; if (monitor_count > 10) { Trace.WriteLine("PC/SC: not able to monitor more than 10 readers (Windows limitation)"); monitor_count = 10; } } monitor_count += 1; } else { if (_reader_names == null) { SCARD.ReleaseContext(_status_change_context); _status_change_context = IntPtr.Zero; _status_change_callback(null, 0, null); return; } monitor_count = _reader_names.Length; if (monitor_count > 10) { Trace.WriteLine("PC/SC: not able to monitor more than 10 readers (Windows limitation)"); monitor_count = 10; } } SCARD.READERSTATE[] states = new SCARD.READERSTATE[monitor_count]; for (int i = 0; i < states.Length; i++) { states[i] = new SCARD.READERSTATE(); if (_auto_update_list && (i == 0)) { /* Magic string to be notified of reader arrival/removal */ states[i].szReader = "\\\\?PNP?\\NOTIFICATION"; states[i].dwCurrentState = global_notification_state; } else { /* Reader name */ states[i].szReader = _reader_names[i - 1]; states[i].dwCurrentState = SCARD.STATE_UNAWARE; } states[i].dwEventState = 0; states[i].cbAtr = 0; states[i].rgbAtr = null; states[i].pvUserData = IntPtr.Zero; } /* Now wait for an event */ /* --------------------- */ while (_status_change_running && !global_notification_fired) { uint rc = SCARD.GetStatusChange(_status_change_context, 250, states, (uint)states.Length); if ((rc == SCARD.E_SERVICE_STOPPED) || (rc == SCARD.E_NO_SERVICE)) { Trace.WriteLine("PC/SC: no service"); SCARD.ReleaseContext(_status_change_context); _status_change_context = IntPtr.Zero; continue; } if (!_status_change_running) { break; } if (rc == SCARD.E_TIMEOUT) { continue; } if (rc != SCARD.S_SUCCESS) { Trace.WriteLine("PC/SC: monitor failed with error " + rc); _last_error = rc; /* Broadcast a message saying we have a problem! */ for (int i = 0; i < states.Length; i++) { states[i].dwEventState = 0 | SCARD.STATE_CHANGED; } } for (int i = 0; i < states.Length; i++) { if ((states[i].dwEventState & SCARD.STATE_CHANGED) != 0) { /* This reader has fired an event */ /* ------------------------------ */ if (_auto_update_list && (i == 0)) { /* Not a reader but \\\\?PNP?\\NOTIFICATION */ /* ---------------------------------------- */ Trace.WriteLine("PC/SC: the list of readers has changed"); global_notification_fired = true; global_notification_state = states[0].dwEventState; SCARD.ReleaseContext(_status_change_context); _last_error = SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref _status_change_context); if (_last_error != SCARD.S_SUCCESS) { _status_change_callback(null, 0, null); return; } /* Refresh the list of readers */ _reader_names = SCARD.GetReaderList(_status_change_context, _groups); /* Notify the application that the list of readers has changed */ try { _status_change_callback(null, global_notification_state & ~SCARD.STATE_CHANGED, null); } catch {} } else { /* This is a reader */ /* ---------------- */ Trace.WriteLine("PC/SC: status of reader " + states[i].szReader + " has changed"); states[i].dwCurrentState = states[i].dwEventState; if ((states[i].dwCurrentState & SCARD.STATE_IGNORE) != 0) { states[i].dwCurrentState = SCARD.STATE_UNAVAILABLE; } CardBuffer card_atr = null; /* Is there a card involved ? */ if ((states[i].dwEventState & SCARD.STATE_PRESENT) != 0) { try { card_atr = new CardBuffer(states[i].rgbAtr, (int)states[i].cbAtr); } catch {} } try { _status_change_callback(states[i].szReader, states[i].dwEventState & ~SCARD.STATE_CHANGED, card_atr); } catch {} } } } } } SCARD.ReleaseContext(_status_change_context); _status_change_context = IntPtr.Zero; } catch (ThreadInterruptedException) { } /* Hide Interrupt */ }
protected virtual void StatusChangeMonitor() { uint rc; IntPtr hContext = IntPtr.Zero; _reader_state = SCARD.STATE_UNAWARE; _card_atr = null; rc = SCARD.EstablishContext(_scope, 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) { try { rc = SCARD.GetStatusChange(hContext, 1000, states, 1); } catch (ThreadInterruptedException) { break; } 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; } if ((states[0].dwEventState & SCARD.STATE_CHANGED) != 0) { states[0].dwCurrentState = states[0].dwEventState; 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); }
public SCardMifareUltraLightC(SCardChannel card_channel) { hCard = card_channel.hCard; _last_error = SCARD.MifUlC_AttachLibrary(hCard); }
protected virtual 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; try { rc = SCARD.GetStatusChange(_hContext, 0, states, 1); } catch (ThreadInterruptedException) { rc = SCARD.E_CANCELLED; } 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 SCardReaderList() { _reader_names = SCARD.GetReaderList(); _auto_update_list = true; }