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 used in the SetupDi*
API to find out which driver is loaded for said reader.
SCardGetReaderDeviceInstanceId
is only available on Windows 8, so unfortunately not for me.
As a plan B, all smart card readers could be enumerated in SetupDi
using the smart card reader class guid. But then I would need a unique attribute to be able to correlate a reader between SCard*
API and SetupDi*
API. For example, the serial number sounds like a good candidate, but not all manufacturers use it.
Any ideas?
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
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 ...