如何findPCSC阅读器的设备实例ID

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

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

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

有任何想法吗?

Solutions Collecting From Web of "如何findPCSC阅读器的设备实例ID"

从我的测试中,它接近scard服务按此顺序分配名称:
a)SPDRP_FRIENDLYNAME如果存在
b)SPDRP_DEVICEDESC

这样,我就可以将SCardListReaders()名称与适当的设备/驱动程序进行匹配。

希望这可以帮助 …

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

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

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

这里的问题是,直到目前为止,我还没有找到一个IOCTL_xxx调用,我可以用它来匹配安装程序API的任何属性。

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

– 更新 –

IOCTL支持以下标签:

SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_CHANNEL_ID SCARD_ATTR_PROTOCOL_TYPES SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_MAX_CLK SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_MAX_IFSD SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_ICC_INTERFACE_STATUS SCARD_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; }