How to find the device instance id of a PCSC reader

前端 未结 2 808
余生分开走
余生分开走 2021-01-06 07:27

Having only a handle and context to a PCSC reader using winscard on Windows >= XP, is there some way to get its device instance id or something else that can be

相关标签:
2条回答
  • 2021-01-06 07:47

    From my tests, it seams that scard service assigns the name in this order:
    a) SPDRP_FRIENDLYNAME if present
    b) SPDRP_DEVICEDESC

    This way, I was able to match the SCardListReaders() names with the rigth Device/Driver.

    Hope this helps ...

    0 讨论(0)
  • 2021-01-06 07:48

    One way to match SCard with Setup is to open the driver, then use IOCTL_SMARTCARD_GET_ATTRIBUTE to query SCARD_ATTR_DEVICE_SYSTEM_NAME and match it with the one via SCard API.

    There is only one tiny problem. The Smartcard service opens all smartcard drivers without sharing. You first need to stop the Smartcard service before being able to open the device driver.

    Another solution is to use the SCardControl function to call the driver via IOCTL_xxx calls from within the SCard API.

    The problem here is that until so far I haven't found a IOCTL_xxx call which I can use to match with any property from the Setup API.

    I tried a brute force loop to scan for supported IOCTL_xxx calls but the SCard api crashes when doing so, and reporting every failing IOCTL_xxx call to the event viewer.

    -- update --

    The IOCTL supports the following tags:

    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

    Below is the code to generate the smartcard device name from either the IOCTL, and via SCARD also to demonstrate the simularity between two methods

    //------------------------------------------------------------------------------
    // 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;
    }
    
    0 讨论(0)
提交回复
热议问题