如何在 C++ 中监听智能卡插入和删除事件?

Posted

技术标签:

【中文标题】如何在 C++ 中监听智能卡插入和删除事件?【英文标题】:How do I listen for smart card insert and remove event in C++? 【发布时间】:2011-11-23 07:55:29 【问题描述】:

我想监听智能购物车的插入和删除事件...该应用程序适用于 Windows,智能卡使用 x.509 证书。我使用的读卡器是大多数新笔记本电脑中插入的标准读卡器,您也可以购买它们以供 USB 使用..

我发现的一件事是: cryptware.it/apidoc/scapi/index.html 但这不是唯一的方法,我只是想知道我的选择......

有谁知道最好的方法是什么?

提前致谢!

【问题讨论】:

我们在这里讨论的是哪个平台、设备、驱动程序和操作系统? 我的错...我现在已经编辑了问题 What have you tried? 您还需要了解什么?操作系统:Windows 7,但该应用程序也应该适用于较旧的 Windows 版本。设备:大多数新笔记本电脑中插入的标准读卡器,您也可以购买它们以供 USB 使用。我已经尝试谷歌它,我发现的唯一东西是:cryptware.it/apidoc/scapi/index.html 但它不是唯一的方法,我只是想知道我的选择... 我找到了很多使用 c# 和 java 的方法,但很少有 c++ 解决方案... 【参考方案1】:

Windows API 有这个功能:

LONG WINAPI SCardGetStatusChange(
  __in     SCARDCONTEXT hContext,
  __in     DWORD dwTimeout,
  __inout  LPSCARD_READERSTATE rgReaderStates,
  __in     DWORD cReaders
);

然后您可以检查rgReaderStates 是否包含SCARD_STATE_EMPTYSCARD_STATE_PRESENT。在此处阅读详细信息:MSDN description

严格来说,它不是事件驱动的,但它会阻止执行,直到发生更改。因此,通过创建一个单独的线程来循环调用它,您可以轻松地自己生成一个事件。

【讨论】:

谢谢,我会调查的! 由于某种原因,此功能对我的卡没有反应......它找到了正确的读卡器,但它对任何状态变化都没有反应......我尝试了一个用 c# 构建的示例项目。网也是,由于某种原因,它也找到了读卡器,但它不会对任何事件做出反应...... @Alioooop 我认为您的测试代码中可能有错误,因为 java 实现除了调用此方法之外什么都不做,正如您在 Java-Source 中看到的那样。您是否正确填写了LPSCARD_READERSTATE 并提供了dwCurrentState 值,也许尝试将其设置为SCARD_STATE_UNAWARE 以轮询它的当前状态,在这种情况下它应该立即返回。 @PeterT:请看这里:***.com/questions/18918963/monitor-smart-card-state【参考方案2】:

一个例子。

这应该包含在线程函数中,该函数以时间间隔(1 秒)运行此函数。线程函数应该使用它并向应用程序发送驱动程序已更改的通知。

警告:丑陋的代码。请以此为例,并在您认为合适的情况下对其进行改进。

BOOL CheckDirProperties(const CString& path, BOOL& bReadOnly, BOOL& bRemovable)

    DWORD   FileAttributes;
    DWORD   DriveAttributes;
    UINT    uDriveType;

    if( path.GetLength() < 2 ||path.GetAt( 1 ) != ':' )
    
        // invalid path, abort
        return FALSE;
    
//Ugly path handling

    CString szFormattedDrivePath("C:\\"); // string of length 3 where drive letter will be replaced
// Replace the drive letter with the drive letter from the path
    szFormattedDrivePath.SetAt( 0, path.GetAt( 0 ) ); 

    DriveAttributes = GetFileAttributes( szFormattedDrivePath );
    FileAttributes  = GetFileAttributes( path);
    uDriveType      = GetDriveType( szFormattedDrivePath );

    if( !(FileAttributes  & FILE_ATTRIBUTE_DIRECTORY) || 
        !(DriveAttributes & FILE_ATTRIBUTE_DIRECTORY) )
       // Not a directory
        return FALSE;
    

    if( (FileAttributes  & FILE_ATTRIBUTE_ARCHIVE) || 
        (DriveAttributes & FILE_ATTRIBUTE_ARCHIVE) ||
        (FileAttributes  & FILE_ATTRIBUTE_ENCRYPTED) || 
        (DriveAttributes & FILE_ATTRIBUTE_ENCRYPTED) ||
        (FileAttributes  & FILE_ATTRIBUTE_OFFLINE) || 
        (DriveAttributes & FILE_ATTRIBUTE_OFFLINE) ||
        (FileAttributes  & FILE_ATTRIBUTE_OFFLINE) || 
        (DriveAttributes & FILE_ATTRIBUTE_OFFLINE) )
       // Not a directory
        TRACE("The directory %s on drive %s has unexpected file attributes. Problems may occur.\n",path, szFormattedDrivePath );
       

    // To set m_bReadOnly to true, we need to know that the entire subtree is readonly.
    // Even if the drive or the directory has the FILE_ATTRIBUTE_READONLY set, the content may not be read-only.
    // Therefore the default value of bReadOnly must be FALSE.
    bReadOnly    = FALSE;

    switch( uDriveType )
    
        case DRIVE_FIXED: 
        case DRIVE_REMOTE:
            bRemovable = FALSE;
            break;
        case DRIVE_CDROM:
            bRemovable = TRUE;
            bReadOnly    = TRUE; // We know that a CD-ROM drive is always read-only
            break;
        case DRIVE_REMOVABLE: 
        case DRIVE_RAMDISK:
            bRemovable = TRUE;
            break;
        case DRIVE_NO_ROOT_DIR: // fall through
        case DRIVE_UNKNOWN:     // fall through
        default:
            bRemovable = TRUE; // assume it is removable if we don't know what value to set
            break;
    

    return TRUE;

【讨论】:

感谢您的努力。如果我想创建自己的循环线程,我已经解决了它,因为我已经创建了一个函数来检查是否插入了正确类型的智能卡:) 但我想要一个带有某种事件的解决方案发送所以我可以听它,而不仅仅是循环和检查...... @Alioooop:现在将是有用的信息,可以包含在您的问题中。

以上是关于如何在 C++ 中监听智能卡插入和删除事件?的主要内容,如果未能解决你的问题,请参考以下文章

cpp-ethereum/aleth 监听智能合约事件问题

持续监听智能合约事件

智能卡读卡器插件(插入卡)事件

如果插入智能卡,则 WPF 捕获事件

从 Java 应用程序调用智能合约函数,无需监听事件

凭据提供程序 Vista+ 智能卡移除事件