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

发布于 2024-12-17 17:12:54 字数 224 浏览 7 评论 0原文

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

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

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

提前致谢!

I want to listen for the insert and remove event of a smart cart... The application is for windows and the smart card is using x.509 certificates. The reader I use is standard card readers that is inserted in most new laptops and you can also buy them for usb use..

One thing I have found is:
cryptware.it/apidoc/scapi/index.html
but it cant be the only way and I just wanted to know my options...

Does anyone know what's the best way to do this?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧时浪漫 2024-12-24 17:12:54

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 说明

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

The Windows API has this function:

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

You can then check if the rgReaderStates contains SCARD_STATE_EMPTY or SCARD_STATE_PRESENT. Read the details here: MSDN description

It is strictly speaking not event-driven but it blocks execution until a change happened. So by creating a separate thread that calls this in a loop, you can easily generate an event yourself.

那请放手 2024-12-24 17:12:54

一个例子。

这应该合并到以时间间隔(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;
}

A example.

This should be incorporated in thread function which runs this function at a time interval (1 second). The thread function should use this and sends a notification to the application that the driver has changed.

WARNING: UGLY CODE. PLEASE USE THIS AS AN EXAMPLE AND IMPROVE IT AS YOU SEE FIT.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文