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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With