/// <summary> /// Wraps the PCSC function /// LONG SCardEstablishContext( /// IN DWORD dwScope, /// IN LPCVOID pvReserved1, /// IN LPCVOID pvReserved2, /// OUT LPSCARDCONTEXT phContext /// ); /// </summary> /// <param name="Scope"></param> public void EstablishContext(SCOPE Scope) { IntPtr hContext = Marshal.AllocHGlobal(Marshal.SizeOf(context)); lastError = PCSC.SCardEstablishContext((uint)Scope, IntPtr.Zero, IntPtr.Zero, hContext); if (lastError != 0) { Marshal.FreeHGlobal(hContext); ThrowSmartcardException("SCardEstablishContext", lastError); } context = Marshal.ReadIntPtr(hContext); Marshal.FreeHGlobal(hContext); }
/// <summary> /// Wraps the PCSC function /// LONG SCardEstablishContext( /// IN DWORD dwScope, /// IN LPCVOID pvReserved1, /// IN LPCVOID pvReserved2, /// OUT LPSCARDCONTEXT phContext /// ); /// </summary> /// <param name="Scope"></param> private static IntPtr EstablishContext(SCOPE Scope) { int lastError = PCSC.SCARD_S_SUCCESS; IntPtr hContextRet = IntPtr.Zero; IntPtr hContext = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); lastError = PCSC.SCardEstablishContext((uint)Scope, IntPtr.Zero, IntPtr.Zero, hContext); if (lastError != 0) { Marshal.FreeHGlobal(hContext); ThrowSmartcardException("SCardEstablishContext", lastError); } hContextRet = Marshal.ReadIntPtr(hContext); Marshal.FreeHGlobal(hContext); return(hContextRet); }
/// <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(); }