gpt4 book ai didi

windows - 如何找到 PCSC 阅读器的设备实例 ID

转载 作者:可可西里 更新时间:2023-11-01 09:34:43 27 4
gpt4 key购买 nike

在 Windows >= XP 上使用 winscard 只有一个 PCSC 阅读器的句柄和上下文,是否有某种方法可以获取其设备实例 ID 或可以在 中使用的其他内容SetupDi* API,用于找出为所述读卡器加载了哪个驱动程序。

SCardGetReaderDeviceInstanceId 仅在 Windows 8 上可用,所以不幸的是不适合我。

作为 B 计划,可以使用智能卡读卡器类 GUID 在 SetupDi 中枚举所有智能卡读卡器。但是我需要一个unique 属性来关联SCard* API 和SetupDi* API 之间的阅读器。例如,序列号听起来不错,但并非所有制造商都使用它。

有什么想法吗?

最佳答案

将 SCard 与 Setup 匹配的一种方法是打开驱动程序,然后使用 IOCTL_SMARTCARD_GET_ATTRIBUTE 查询 SCARD_ATTR_DEVICE_SYSTEM_NAME 并将其与通过 SCard API 匹配。

只有一个小问题。智能卡服务打开所有智能卡驱动程序而不共享。您首先需要停止智能卡服务,然后才能打开设备驱动程序。

另一种解决方案是使用 SCardControl 函数通过 SCard API 中的 IOCTL_xxx 调用来调用驱动程序。

这里的问题是,到目前为止我还没有找到一个 IOCTL_xxx 调用,我可以使用它来匹配来自设置 API 的任何属性。

我尝试了一个强力循环来扫描支持的 IOCTL_xxx 调用,但是 SCard api 在这样做时崩溃,并向事件查看器报告每个失败的 IOCTL_xxx 调用。

-- 更新--

IOCTL 支持以下标签:

SCARD_ATTR_VENDOR_NAMESCARD_ATTR_VENDOR_IFD_TYPESCARD_ATTR_VENDOR_IFD_VERSIONSCARD_ATTR_CHANNEL_IDSCARD_ATTR_PROTOCOL_TYPESSCARD_ATTR_DEFAULT_CLKSCARD_ATTR_MAX_CLKSCARD_ATTR_DEFAULT_DATA_RATESCARD_ATTR_MAX_DATA_RATESCARD_ATTR_MAX_IFSDSCARD_ATTR_POWER_MGMT_SUPPORTSCARD_ATTR_CHARACTERISTICSSCARD_ATTR_ICC_PRESENCESCARD_ATTR_ICC_INTERFACE_STATUSSCARD_ATTR_DEVICE_UNIT

下面是从 IOCTL 生成智能卡设备名称的代码,并通过 SCARD 也证明了两种方法之间的相似性

//------------------------------------------------------------------------------
// PROTOTYPES
//------------------------------------------------------------------------------

/* get the Smartcard DeviceName via IOCTL calls */
BOOL Smc_GetDeviceNameViaIOCTL(HANDLE,TCHAR*,UINT);

/* get the Smartcard DeviceName via SCARD calls */
BOOL Smc_GetDeviceNameViaSCARD(SCARDHANDLE,TCHAR*,UINT);





//------------------------------------------------------------------------------
// IMPLEMENTATIONS
//------------------------------------------------------------------------------




/************************************************/
/* get the Smartcard DeviceName via IOCTL calls */
/************************************************/

BOOL Smc_GetDeviceNameViaIOCTL(HANDLE in_hDev, TCHAR *out_Name, UINT in_MaxLen)
{
/* locals */
UINT lv_Pos;
DWORD lv_InBuf;
DWORD lv_ValLen;
DWORD lv_ChanID;
CHAR lv_OutBuf[256];
BOOL lv_Result;


// reserve space for eos
if (in_MaxLen-- <= 0)
return FALSE;

// init the position
lv_Pos = 0;

// set the tag
lv_InBuf = SCARD_ATTR_VENDOR_NAME;

// get the value
lv_Result = DeviceIoControl(
in_hDev, IOCTL_SMARTCARD_GET_ATTRIBUTE,
&lv_InBuf, sizeof(DWORD), lv_OutBuf, 256, &lv_ValLen, 0);

// fail?
if (!lv_Result)
return FALSE;

// check the length, including space
if (lv_Pos + lv_ValLen + 1 > in_MaxLen)
return FALSE;

// append to output
AChar2TCharCL(lv_OutBuf, lv_ValLen, &out_Name[lv_Pos], in_MaxLen-lv_Pos);

// update position
lv_Pos += lv_ValLen;

// append space
out_Name[lv_Pos++] = ' ';

// set the tag
lv_InBuf = SCARD_ATTR_VENDOR_IFD_TYPE;

// get the value
lv_Result = DeviceIoControl(
in_hDev, IOCTL_SMARTCARD_GET_ATTRIBUTE,
&lv_InBuf, sizeof(DWORD), lv_OutBuf, 256, &lv_ValLen, 0);

// fail?
if (!lv_Result)
return FALSE;

// check the length, including space
if (lv_Pos + lv_ValLen + 1 > in_MaxLen)
return FALSE;

// append to output
AChar2TCharCL(lv_OutBuf, lv_ValLen, &out_Name[lv_Pos], in_MaxLen-lv_Pos);

// update position
lv_Pos += lv_ValLen;

// append space
out_Name[lv_Pos++] = ' ';

// set the tag
lv_InBuf = SCARD_ATTR_DEVICE_UNIT;

// get the value
lv_Result = DeviceIoControl(
in_hDev, IOCTL_SMARTCARD_GET_ATTRIBUTE,
&lv_InBuf, sizeof(DWORD), &lv_ChanID, sizeof(DWORD), &lv_ValLen, 0);

// fail?
if (!lv_Result)
return FALSE;

// format as string
FormatStringA(lv_OutBuf, 256, "%d", lv_ChanID);

// check the length
if (lv_Pos + strlenA(lv_OutBuf) > in_MaxLen)
return FALSE;

// append to output
AChar2TCharC(lv_OutBuf, &out_Name[lv_Pos], in_MaxLen-lv_Pos);

// done
return TRUE;
}





/************************************************/
/* get the Smartcard DeviceName via SCARD calls */
/************************************************/

BOOL Smc_GetDeviceNameViaSCARD(SCARDHANDLE in_hCard, TCHAR *out_Name, UINT in_MaxLen)
{
/* locals */
UINT lv_Pos;
DWORD lv_InBuf;
DWORD lv_ValLen;
DWORD lv_ChanID;
CHAR lv_OutBuf[256];
UINT lv_hResult;


// reserve space for eos
if (in_MaxLen-- <= 0)
return FALSE;

// init the position
lv_Pos = 0;

// set the tag
lv_InBuf = SCARD_ATTR_VENDOR_NAME;
lv_ValLen = 256;

// get the value
lv_hResult = lib_SCardGetAttrib(in_hCard, lv_InBuf, (BYTE*)lv_OutBuf, &lv_ValLen);

// fail?
if (FAILED(lv_hResult))
return FALSE;

// check the length, including space
if (lv_Pos + lv_ValLen + 1 > in_MaxLen)
return FALSE;

// append to output
AChar2TCharCL(lv_OutBuf, lv_ValLen, &out_Name[lv_Pos], in_MaxLen-lv_Pos);

// update position
lv_Pos += lv_ValLen;

// append space
out_Name[lv_Pos++] = ' ';

// set the tag
lv_InBuf = SCARD_ATTR_VENDOR_IFD_TYPE;
lv_ValLen = 256;

// get the value
lv_hResult = lib_SCardGetAttrib(in_hCard, lv_InBuf, (BYTE*)lv_OutBuf, &lv_ValLen);

// fail?
if (FAILED(lv_hResult))
return FALSE;

// check the length, including space
if (lv_Pos + lv_ValLen + 1 > in_MaxLen)
return FALSE;

// append to output
AChar2TCharCL(lv_OutBuf, lv_ValLen, &out_Name[lv_Pos], in_MaxLen-lv_Pos);

// update position
lv_Pos += lv_ValLen;

// append space
out_Name[lv_Pos++] = ' ';

// set the tag
lv_InBuf = SCARD_ATTR_DEVICE_UNIT;
lv_ValLen = sizeof(DWORD);

// get the value
lv_hResult = lib_SCardGetAttrib(in_hCard, lv_InBuf, (BYTE*)&lv_ChanID, &lv_ValLen);

// fail?
if (FAILED(lv_hResult))
return FALSE;

// format as string
FormatStringA(lv_OutBuf, 256, "%d", lv_ChanID);

// check the length
if (lv_Pos + strlenA(lv_OutBuf) > in_MaxLen)
return FALSE;

// append to output
AChar2TCharC(lv_OutBuf, &out_Name[lv_Pos], in_MaxLen-lv_Pos);

// done
return TRUE;
}

关于windows - 如何找到 PCSC 阅读器的设备实例 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14253830/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com