2013-01-10 40 views
3

只有在Windows> = XP上使用winscard纔有PCSC閱讀器的句柄和上下文,是否有某種方法可以獲取其設備實例ID或其他可用於SetupDi* API來找出爲所述讀取器加載哪個驅動程序。如何查找PCSC閱讀器的設備實例ID

SCardGetReaderDeviceInstanceId僅在Windows 8上可用,所以不幸不適合我。

作爲計劃B,所有智能卡讀卡器都可以在SetupDi中使用智能卡讀卡器類guid進行枚舉。但是,然後我需要一個獨特的屬性,以便能夠將API讀取器與SCard* API之間關聯起來。例如,序列號聽起來很不錯,但並非所有制造商都使用它。

任何想法?

+0

從什麼我的研究可能的simularity告訴,沒有獨特的屬性來關聯「讀取器名稱」(如智能卡API給出的)和任何設備節點屬性。對不起,這在一定程度上困擾着我們。 – Ilya

回答

0

從我的測試中,它的接縫是SCARD服務順序分配名稱:
一)SPDRP_FRIENDLYNAME如果存在
B)SPDRP_DEVICEDESC

這樣,我就能夠匹配SCardListReaders()的名字適當的設備/驅動程序。

希望這有助於...與設置匹配SCARD

+0

這是不完全正確的,按照本文 - http://technet.microsoft.com/en-US/library/ff404292(v=ws.10).aspx - 智能卡讀卡器名稱是從檢索的字符串該驅動程序可能與上述devnode字符串完全不同。 – Ilya

0

一種方法是打開驅動程序,然後使用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; 
}