/// <summary> /// Wraps the PCSC function /// LONG SCardReleaseContext( /// IN SCARDCONTEXT hContext /// ); /// </summary> public void ReleaseContext() { if (PCSC.SCardIsValidContext(context) == PCSC.SCARD_S_SUCCESS) { lastError = PCSC.SCardReleaseContext(context); ThrowSmartcardException("SCardReleaseContext", lastError); context = IntPtr.Zero; } }
/// <summary> /// Wraps the PCSC function /// LONG SCardReleaseContext( /// IN SCARDCONTEXT hContext /// ); /// </summary> private static void ReleaseContext(IntPtr hContext) { if (PCSC.SCardIsValidContext(hContext) == PCSC.SCARD_S_SUCCESS) { int lastError = PCSC.SCardReleaseContext(hContext); ThrowSmartcardException("SCardReleaseContext", lastError); //Marshal.FreeHGlobal(hContext); hContext = IntPtr.Zero; } }
/// <summary> /// This function must implement a card detection mechanism. /// /// When card insertion is detected, it must call the method CardInserted() /// When card removal is detected, it must call the method CardRemoved() /// /// </summary> protected override void RunCardDetection(string reader) { bool bFirstLoop = true; IntPtr hContext = IntPtr.Zero; // Local context IntPtr phContext; phContext = Marshal.AllocHGlobal(Marshal.SizeOf(hContext)); if (PCSC.SCardEstablishContext((uint)SCOPE.User, IntPtr.Zero, IntPtr.Zero, phContext) == 0) { hContext = Marshal.ReadIntPtr(phContext); Marshal.FreeHGlobal(phContext); UInt32 nbReaders = 1; PCSC.SCard_ReaderState[] readerState = new PCSC.SCard_ReaderState[nbReaders]; readerState[0].CurrentState = (UInt32)PCSC.CARD_STATE.UNAWARE; readerState[0].Reader = reader; UInt32 eventState; UInt32 currentState = readerState[0].CurrentState; // Card detection loop do { if (PCSC.SCardGetStatusChange(hContext, WAIT_TIME , readerState, nbReaders) == 0) { eventState = readerState[0].EventState; currentState = readerState[0].CurrentState; if (bFirstLoop) { // Check if a card is already inserted if ((eventState & (uint)PCSC.CARD_STATE.PRESENT) == (uint)PCSC.CARD_STATE.PRESENT) { CardInserted(reader); } } else if (((eventState & (uint)PCSC.CARD_STATE.CHANGED) == (uint)PCSC.CARD_STATE.CHANGED) && !bFirstLoop) { // State has changed if ((eventState & (uint)PCSC.CARD_STATE.EMPTY) == (uint)PCSC.CARD_STATE.EMPTY) { // There is no card, card has been removed -> Fire CardRemoved event CardRemoved((string)reader); } if (((eventState & (uint)PCSC.CARD_STATE.PRESENT) == (uint)PCSC.CARD_STATE.PRESENT) && ((eventState & (uint)PCSC.CARD_STATE.PRESENT) != (currentState & (uint)PCSC.CARD_STATE.PRESENT))) { // There is a card in the reader -> Fire CardInserted event CardInserted(reader); } if ((eventState & (uint)PCSC.CARD_STATE.ATRMATCH) == (uint)PCSC.CARD_STATE.ATRMATCH) { // There is a card in the reader and it matches the ATR we were expecting-> Fire CardInserted event CardInserted(reader); } } // The current stateis now the event state readerState[0].CurrentState = eventState; bFirstLoop = false; } Thread.SpinWait(50000); if (cancellationToken.IsCancellationRequested) { break; } }while (true); // Exit on request } else { Marshal.FreeHGlobal(phContext); throw new Exception("PC/SC error"); } PCSC.SCardReleaseContext(hContext); cancellationToken.ThrowIfCancellationRequested(); }