如何在 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_EMPTY
或SCARD_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++ 中监听智能卡插入和删除事件?的主要内容,如果未能解决你的问题,请参考以下文章