Search code examples
c#winscard

C# WinScard.SCardListReaders should list only the connected readers (but it is listing all the past installed reader names which is now not connected)


Please go through my below C# code. I am trying to get the list of Smart Card readers that are now connected to my computer. But this function is returning all the smartcard reader names that was connected in the past (I mean not connected now). I want the list of active (presently) connected readers names only. I am not able to understand where is the issue.

I tried a exe from this website which is written and compiled in C. It is showing only the readers that are connected. I compared the code, but I find no difference. Please help to find a fix.

public static int GetPCSCReaders(out List<string> smartCardReaders, out string errMsg)
{
    errMsg = string.Empty;
    byte[] readersList = null;
    smartCardReaders = new List<string>();

    try
    {
        int hContext = 0;
        int ret = SCardEstablishContext(WinSCard.SCARD_SCOPE_USER, 0, 0, ref hContext);
        if (ret != 0)
        {
            errMsg = "WinSCard GetPCSCReader: EstablishContext Error: " + ret.ToString();
            return ret;
        }

        int byteCnt = 0;
        ret = WinSCard.SCardListReaders(hContext, null, null, ref byteCnt);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: ListReaders Error: " + ret.ToString();
            return ret;
        }

        readersList = new byte[byteCnt];
        ret = WinSCard.SCardListReaders(hContext, null, readersList, ref byteCnt);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: ListReaders Error: " + ret.ToString();
            return ret;
        }

        int indx = 0;
        string readerName = string.Empty;
        int i = 0;

        while (readersList[indx] != 0)
        {
            while (readersList[indx] != 0)
            {
                readerName = readerName + (char)readersList[indx++];
            }

            smartCardReaders.Add(readerName);
            i++;

            readerName = "";
            indx++;
        }

    }
    catch (Exception ex)
    {
        errMsg = ex.Message;
    }
    finally
    {
        readersList = null;
    }
    return 0;
}

Solution

  • It's hard to answer the question without a smartcard reader in hand, although I developed on these code just 3 months ago.

    My previous code is based on this: https://github.com/nicbedford/CardBrowser/blob/master/PCSC/PCSCReader.cs

    It's not working perfectly, you have to detect bugs by yourself. but it exactly helps.

    There are different solutions in different windows platforms.

    1. Window 8.1+:

    https://code.msdn.microsoft.com/windowsapps/Smart-card-sample-c7d342e0#content

    1. Window 10:

    https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/SmartCard

    https://learn.microsoft.com/en-us/uwp/api/windows.devices.smartcards

    1. Windows 7+:

    https://github.com/nicbedford/CardBrowser/tree/master/PCSC

    https://github.com/orouit/SmartcardFramework

    https://github.com/danm-de/pcsc-sharp/tree/master/src/PCSC

    if you meet issue in translating C++ to C#, you can find all functions here: https://www.pinvoke.net/default.aspx/winscard/SCardTransmit.html just search the function from top left.