1
votes

I have a trouble with PCSC Reader and Smart card. I am not able to access the card with my GUI application. It works like a charm in the console example app.
I receive Exception:

SCard.Connect Error 0x8010000B: The smart card cannot be accessed because of other connections outstanding!
A first chance exception of type 'GS.SCard.WinSCardException' occurred in GS.CSharpPCSC.dll

But when I remove the card and reinsert it, it works fine.
I've thought that the card is accessed by other process in my Windows machine at the moment of insertion, so I created a while which would catch especially situation when ret value is equal to -2146435061 in WinSCardException and continue the loop, or break if connection is OK.
Steps I do to connect to the card:

PCSCReader reader = new PCSCReader();
string[] readers = reader.SCard.ListReaders(); 
// Returns 3 readers (even though I have 2 connected, but when I once connected the third one it now appears always) - why?
// Here with GUI I choose interested reader (which is really connected)
reader.SCard.ReleaseContext();
reader.Disconnect(); // In case there is any reader connected
// Here I stop my worker so that It will not try to access reader when it is not connected
reader.Connect(readers[1]); // For example let's connect to reader 1
// Now the worker starts working

//...DoWork method of worker:
while(true)
{
  try {reader.ActivateCard(); break;} // break if successfully connected
  // If the ex status is positive then there is some other issue which is handled by bigger try-catch, but for case ret is -2146435061 i want to continue the loop
  catch (WinSCardException ex) {if (ex.Status > -100) throw (ex); }
  // But this throw Exception over and over again

Need help please.
I use this wrapper: http://www.smartcard-magic.net/en/pc-sc-reader/csharppcsc-wrapper/
Example program look almost the same, but does not throw any error.

using System;
using System.Diagnostics;
using GS.Apdu;
using GS.PCSC;
using GS.SCard;
using GS.SCard.Const;
using GS.Util.Hex;

namespace ExamplePCSCReader
{
    class Program
    {
        static void Main( string[] args )
        {
            ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener();
            Trace.Listeners.Add(consoleTraceListener);

            PCSCReader reader = new PCSCReader();

            try
            {
                reader.Connect();
                reader.ActivateCard();

                RespApdu respApdu = reader.Exchange("00 B0 00 00 0A"); // Get Card UID ...
                if (respApdu.SW1SW2 == 0x9000)
                {
                    Console.WriteLine("ICCID  = 0x" + HexFormatting.ToHexString(respApdu.Data, true));
                }
            }
            catch (WinSCardException ex)
            {
                Console.WriteLine( ex.WinSCardFunctionName + " Error 0x" + 
                                   ex.Status.ToString( "X08" ) + ": " + ex.Message );
            }
            catch (Exception ex)
            {
                Console.WriteLine( ex.Message );
            }
            finally
            {
                reader.Disconnect();
                Console.WriteLine( "Please press any key..." );
                Console.ReadLine();
            }
        }
    }
}
}
3
try to use "SCardConnect" function with "SCARD_SHARE_EXCLUSIVE" from Winscard.dll directly.for c# signature go to link pinvoke.net/default.aspx/winscard.scardconnectvikky
Thanks, that work! But still got a problem with list readers. It still return 3 readers.Marek
Which reader you are using?vikky
Gemplus USB Smart Card ReaderMarek
My app returns: Reader 0: Broadcom Corp Contacted SmartCard 0..... Reader 1: Gemplus USB Smart Card Reader 0 ..... Reader 2: Gemplus USB Smart Card Reader 1 When the example program returns only reader 0 and reader 1 and these are connecetdMarek

3 Answers

2
votes

For the problem about accessing reader - the solution is to share the reader with command:

reader.ActivateCard(GS.SCard.Const.SCARD_SHARE_MODE.Shared, GS.SCard.Const.SCARD_PROTOCOL.Tx);

The problem with listing not extisting readers was because if the context was not established, the wrapper was taking list of readers from Windows Registry. When I established context before I list readers - only connected readers appear.

reader.SCard.EstablishContext();
readers = reader.SCard.ListReaders();
0
votes

I have same problem with you... but i found solution.

Change from SCardShareMode.Exclusive to > SCardShareMode.Shared

            _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.Shared,
                            SCardProtocol.T0 | SCardProtocol.T1);
                CheckErr(_err);
             }
0
votes

I know the subject is old but it might help out other people who will face this issue in the future. Sharing the reader is a workaround, it is not a fix. Indeed, the fact that connecting in exclusive mode is not possible due to other connections outstanding means that windows processes are performing actions on the smart card outside your application. This can cause problematic behavior of your application accessing the smart card, especially if using multiple readers/cards at the same time.

A true fix is to change some configurations in the group policy editor when working on a windows machine. It should look like this: enter image description here

The reader should then be able to connect to the card in exclusive or direct mode

Cheers