当我这么做时:
#define CM_IOCTL_GET_FEATURE_REQUEST 0x313520
lReturn = SCardControl(hCardHandle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, NULL, bRecvBuffer, sizeof(bRecvBuffer), &dwRecvLength);此方法正确地返回卡片功能,没有错误。
但是,当我使用任何APDU或低级命令时,例如:
#define CM_IOCTL_GET_FEATURE_REQUEST_NOT_WORK 0x00B0XXXX它返回错误,不工作。
Windows如何确定诸如第一行智能卡控制代码的值/格式?
发布于 2022-09-25 17:48:24
我在这件事上绞尽脑汁,我认为这可能值得将来的读者回答。
TL;DR
只有在使用本机Windows实现( 0x313520 API)或其周围的任何包装器时,才会使用WinSCard值。
冗长的答案
PC/SC第10部分标准为GET_FEATURE_REQUEST定义了一个控制代码(3400)。
但是,Windows并不像与设备通信时那样发送此控制代码,而是将其包装在IOCTL结构系统中。IOCTL是Windows提供统一通用接口的大致意思,它可以向各种设备的驱动程序发送控制代码。
Windows包装设备特定控制代码的方式在winioctl.h标头( Windows的一部分)的宏中定义:
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)在我们的案例中:
DeviceType是:#define FILE_DEVICE_SMARTCARD 0x00000031Access是#define FILE_ANY_ACCESS 0x00000000Function是我们实际的控制代码值(3400)。Method是NULL,在我们的例子中是(0x00000000)剩下的就是使用bitwise OR,根据前面提到的CTL_CODE宏,移动这些值并将它们放在一起。
因此,实际上在我们的例子中:
((0x00000031) << 16) | ((0x00000000) << 14) | ((3400) << 2) | (0)它等于0x313520,一个看似神奇的数字,但实际上是一个包含控制代码本身的结构,以及将其发送到设备驱动程序所需的一些东西和参数。这就是为什么您不能直接将此值发送到您的阅读器,因为该值需要首先由设备驱动程序处理,该驱动程序将提取参数,然后实际控制代码(3400)将通过USB发送到设备固件(使用CCID )。
PS: --在我们处理智能卡的情况下,CTL_CODE宏有一个更短、更手工的版本,即:SCARD_CTL_CODE() (在winscard.h中定义)。它确实用固定的参数调用CTL_CODE。
PC/SC标准第10部分告诉我们要定义以下内容:
#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)这将给我们通过PCSC库与设备驱动程序一起使用的系统的值(0x313520)。请注意,如果您在PCSC石中使用Linux,它将产生一个不同的SCARD_CTL_CODE(3400)值(0x42000D48),因为它处理这个问题的方式有点不同。
https://stackoverflow.com/questions/59380079
复制相似问题