Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listing all Smart Card Readers on a system (Alcor Micro reader issues)

I've had this software running in production for years and never seen this problem before. I just received a new laptop (HP EliteBook 8470p) that has a built-in Alcor Micro USB Smart Card Reader.

The code below will list all readers on a system and seems to work fine. Some of our systems will have 3 or 4 readers plugged in to a single computer. It's been tested with a dozen or so models with no issues.

Strangely, the Alcor reader will only get listed when a Smart Card is inserted. If I look at it in Device Manager, it doesn't show up under the "Smart card readers" until a card is inserted, too (unless I go to View > Show Hidden Devices).

Does anyone know why this is or if there's a way to make sure it gets listed in my software?

Thank you.

The code:

[DllImport("WINSCARD.DLL", EntryPoint = "SCardEstablishContext", CharSet = CharSet.Unicode, SetLastError = true)]
static internal extern uint EstablishContext(ScopeOption scope, IntPtr reserved1,
    IntPtr reserved2, ref SmartcardContextSafeHandle context);

[DllImport("WINSCARD.DLL", EntryPoint = "SCardListReaders", CharSet = CharSet.Unicode, SetLastError = true)]
static internal extern uint ListReaders(SmartcardContextSafeHandle context, string groups,
    string readers, ref int size);

private bool EstablishContext()
{
    if ((this.HasContext))
    {
        return true;
    }
    this._lastErrorCode =
        (SmartcardErrorCode)UnsafeNativeMethods.EstablishContext(ScopeOption.System,
        IntPtr.Zero, IntPtr.Zero, ref this._context);
    return (this._lastErrorCode == SmartcardErrorCode.None);
}

public ArrayList ListReaders()
{
    ArrayList result = new ArrayList();

    //Make sure a context has been established before 
    //retrieving the list of smartcard readers.
    if (this.EstablishContext())
    {
        //Ask for the size of the buffer first.
        int size = this.GetReaderListBufferSize();
        //Allocate a string of the proper size in which 
        //to store the list of smartcard readers.
        string readerList = new string('\0', size);
        //Retrieve the list of smartcard readers.
        this._lastErrorCode =
            (SmartcardErrorCode)UnsafeNativeMethods.ListReaders(this._context,
            null, readerList, ref size);

        if ((this._lastErrorCode == SmartcardErrorCode.None))
        {
            //Extract each reader from the returned list.
            //The readerList string will contain a multi-string of 
            //the reader names, i.e. they are seperated by 0x00 
            //characters.
            string readerName = string.Empty;
            for (int i = 0; i <= readerList.Length - 1; i++)
            {
                if ((readerList[i] == '\0'))
                {
                    if ((readerName.Length > 0))
                    {
                        //We have a smartcard reader's name.
                        result.Add(readerName);
                        readerName = string.Empty;
                    }
                }
                else
                {
                    //Append the found character.
                    readerName += new string(readerList[i], 1);
                }
            }
        }
    }
    return result;
}

Btw, this code was written by someone else who I'm guessing (by the over-abundance of comments) found it somewhere else online. I'm somewhat familiar with it but never gotten too deep into it. I've tried making several tweaks to it and can't get it to list that Alcor reader at all.

Thanks!

like image 785
Adam Plocher Avatar asked Oct 05 '22 10:10

Adam Plocher


1 Answers

Ok, I feel really stupid finding the answer immediately after opening the bounty. I spent a while looking at this from a software perspective and gave up for a while - when I came back to revisit this I decided it might be suited for a bounty.

I decided to take a closer look at my BIOS options, and guess what? There's an option in there that says "Power on Smart Card Reader: a) when card is inserted, b) always". I changed it to "Always" and it works. ARGH

It won't let me delete my question since it has a bounty now, but that's basically my answer. Thanks for the comments/advice.

like image 93
Adam Plocher Avatar answered Oct 13 '22 09:10

Adam Plocher