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

C++ 如何在C+;中侦听智能卡插入和删除事件+;?,c++,events,smartcard,C++,Events,Smartcard,我要侦听智能购物车的插入和删除事件。。。该应用程序适用于windows,智能卡使用x.509证书。我使用的读卡器是标准的读卡器,可以插入大多数新的笔记本电脑中,你也可以购买用于usb的读卡器 我发现的一件事是: cryptware.it/apidoc/scapi/index.html 但这不是唯一的办法,我只是想知道我的选择 有人知道最好的方法是什么吗 提前谢谢 一个例子 这应该包含在以时间间隔(1秒)运行此函数的线程函数中。thread函数应该使用此选项,并向应用程序发送驱动程序已更改的通知

我要侦听智能购物车的插入和删除事件。。。该应用程序适用于windows,智能卡使用x.509证书。我使用的读卡器是标准的读卡器,可以插入大多数新的笔记本电脑中,你也可以购买用于usb的读卡器

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

有人知道最好的方法是什么吗

提前谢谢

一个例子

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

警告:丑陋的代码。请以此为例,并根据需要进行改进

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;
}
BOOL CheckDirProperties(常量字符串和路径、BOOL和bReadOnly、BOOL和bReadOnly)
{
DWORD文件属性;
德沃德属性;
UINT-ud型;
if(path.GetLength()<2 | | path.GetAt(1)!=':')
{
//无效路径,中止
返回FALSE;
}
//丑陋的路径处理
CString szFormattedDrivePath(“C:\\”)//将替换驱动器号的长度为3的字符串
//用路径中的驱动器号替换驱动器号
szFormattedDrivePath.SetAt(0,path.GetAt(0));
DriveAttributes=GetFileAttributes(szFormattedDrivePath);
FileAttributes=GetFileAttributes(路径);
UdliveType=GetDriveType(szFormattedDrivePath);
if(!(文件属性和文件属性目录)|
!(驱动器属性和文件属性目录))
{//不是目录
返回FALSE;
}
如果((文件属性和文件属性存档)|
(驱动器属性和文件属性存档)||
(文件属性和文件属性加密)|
(驱动器属性和文件属性加密)||
(文件属性和文件属性脱机)|
(驱动器属性和文件属性脱机)||
(文件属性和文件属性脱机)|
(驱动器属性和文件属性脱机))
{//不是目录
跟踪(“驱动器%s上的目录%s具有意外的文件属性。可能会出现问题。\n”,路径,szFormattedDrivePath);
}   
//要将m_bReadOnly设置为true,我们需要知道整个子树是只读的。
//即使驱动器或目录设置了文件\属性\只读,内容也可能不是只读的。
//因此,bReadOnly的默认值必须为FALSE。
bReadOnly=FALSE;
开关(UD型)
{
机箱驱动单元固定:
机箱驱动单元远程:
b=假;
打破
机箱驱动器光盘:
b=真;
bReadOnly=TRUE;//我们知道CD-ROM驱动器总是只读的
打破
机箱驱动单元可拆卸:
机箱驱动器磁盘:
b=真;
打破
案例驱动\u否\u根\u目录://故障
case DRIVE_未知://故障
违约:
bRemovable=TRUE;//如果我们不知道要设置什么值,则假定它是可移动的
打破
}
返回TRUE;
}

Windows API具有以下功能:

LONG WINAPI SCardGetStatusChange(
  __in     SCARDCONTEXT hContext,
  __in     DWORD dwTimeout,
  __inout  LPSCARD_READERSTATE rgReaderStates,
  __in     DWORD cReaders
);
然后,您可以检查
rgReaderStates
是否包含
SCARD\u STATE\u EMPTY
SCARD\u STATE\u PRESENT
。请阅读此处的详细信息:


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

我们在这里讨论的是哪个平台、设备、驱动程序和操作系统?我的坏。。。我现在编辑了这个问题,你还需要知道什么?操作系统:windows 7,但该应用程序也应适用于较旧的windows版本。设备:标准的读卡器,插入大多数新的笔记本电脑,你也可以购买usb使用。。我尝试过谷歌,我发现的唯一的方法是:但它不是唯一的方法,我只是想知道我的选择…我发现了很多使用C++和java的方法,但是很少有C++解决方案…谢谢你的努力。如果我想制作自己的循环线程,我已经解决了这个问题,因为我已经做了一个功能来检查是否插入了正确类型的智能卡:)但是我想要一个带有某种发送事件的解决方案,这样我就可以监听它,而不是只是循环和检查…@Aliooop:现在,这将是在您的问题中包含的有用信息。谢谢,我会查看到这里面去!由于某种原因,这种功能在我的卡片上不起作用。。。。它找到了正确的读卡器,但对任何状态变化都没有反应。。。我也尝试了在c#.net中构建一个示例项目,出于某种原因,它也会找到读卡器,但它不会对任何事件做出反应…@aliooop我认为您的测试代码中可能有错误,因为java实现除了调用此方法之外什么都不做,如中所示。您是否正确填写了
LPSCARD\u READERSTATE
并提供了
dwCurrentState
值,或者尝试将其设置为
SCARD\u STATE\u
以轮询当前状态,在这种情况下,它应该立即返回。@PeterT:您可以看看这里: