列出系统上的所有智能卡读卡器(Alcor Micro 读卡器问题)

Posted

技术标签:

【中文标题】列出系统上的所有智能卡读卡器(Alcor Micro 读卡器问题)【英文标题】:Listing all Smart Card Readers on a system (Alcor Micro reader issues) 【发布时间】:2013-04-11 00:14:03 【问题描述】:

我已经在生产环境中运行该软件多年,之前从未遇到过这个问题。我刚收到一台内置 Alcor Micro USB 智能卡读卡器的新笔记本电脑 (HP EliteBook 8470p)。

下面的代码将列出系统上的所有阅读器,并且似乎工作正常。我们的一些系统将有 3 或 4 个读卡器插入一台计算机。它已经过十几个模型的测试,没有任何问题。

奇怪的是,Alcor 读卡器只有在插入智能卡时才会被列出。如果我在设备管理器中查看它,在插入卡之前它不会显示在“智能卡读卡器”下(除非我转到查看 > 显示隐藏的设备)。

有谁知道这是为什么,或者是否有办法确保它在我的软件中列出?

谢谢。

代码:

[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;

顺便说一句,这段代码是由我猜的其他人编写的(由于 cmets 的过多)在网上的其他地方找到了它。我对它有些熟悉,但从未深入过它。我已经尝试对其进行一些调整,但根本无法让它列出该 Alcor 阅读器。

谢谢!

【问题讨论】:

这里的读者从未观察到这样的效果。对于非接触式阅读器来说,这尤其令人讨厌。我会向 Alcor 或 HP 投诉以获得驱动程序更新,因为唯一的选择是从 winscard.dll(即资源管理器)级别下降到 USB 设备枚举。 @guidot 感谢您的回复。是的,我多年来一直与读者合作,也从未见过这种行为。正如我所说,它在 Windows 的设备管理器中做同样的事情 - 在插入卡之前它显示为非活动状态,所以它肯定似乎是驱动程序/硬件级别的东西,而不是我的代码......我想我会接受您的建议并向 Alcor 发送电子邮件。 检查智能卡服务是否运行...... 它正在运行。我插入了几个外部 USB 阅读器(一个通过打印机,一个独立)。这两个出现了,但我笔记本电脑上的内部没有,直到我插入智能卡。它在设备管理器中也以这种方式运行 - 在我插入卡之前它显示为非活动读卡器 - 好像 USB 已拔出(尽管它是我笔记本电脑中的内部 USB 读卡器)。我认为这与这个制造商/型号有关。几天前我给他们发了一封电子邮件,但没有收到回音...... 这是非常讨厌的行为。我当然会抱怨。听起来驱动开发者选择了捷径。 【参考方案1】:

好吧,我觉得在打开赏金后立即找到答案真的很愚蠢。我花了一段时间从软件的角度看待这个问题并放弃了一段时间 - 当我回来重新审视这个问题时,我认为它可能适合赏金。

我决定仔细看看我的 Bios 选项,你猜怎么着?那里有一个选项,上面写着“打开智能卡读卡器电源:a)插入卡时,b)总是”。我将其更改为“始终”并且它有效。呸

它不会让我删除我的问题,因为它现在有赏金,但这基本上是我的答案。感谢您的 cmets/建议。

【讨论】:

非常感谢您发布此信息。你为我节省了几个小时,想知道为什么它会这样做,以及为什么我现在工作的代码没有。 另请参阅 MSDN 上的 How to enumerate certificates on Smart Card 和所讨论的 [慢性] Microsoft 错误。

以上是关于列出系统上的所有智能卡读卡器(Alcor Micro 读卡器问题)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 pyscard 列出智能卡上的文件

列出使用智能卡读卡器的进程

在当前阅读器上的智能卡上查找证书

智能卡读卡器是不是支持所有智能卡型号?

NFC 读卡器和卡上匹配 (MOC) 兼容性

支持 pkcs#11 的智能卡和读卡器