一種方法是打開驅動程序,然後使用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_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_M GMT_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;
}
從什麼我的研究可能的simularity告訴,沒有獨特的屬性來關聯「讀取器名稱」(如智能卡API給出的)和任何設備節點屬性。對不起,這在一定程度上困擾着我們。 – Ilya