SMARTCARD_EXTENSION 结构 (smclib.h)

智能卡读取器驱动程序和智能卡驱动程序库都使用SMARTCARD_EXTENSION结构来访问所有其他智能卡数据结构。

语法

typedef struct _SMARTCARD_EXTENSION {
  ULONG                     Version;
  VENDOR_ATTR               VendorAttr;
  NTSTATUS(                 *ReaderFunction[16];
  SCARD_CARD_CAPABILITIES   CardCapabilities;
  ULONG                     LastError;
  struct {
    PULONG Information;
    PUCHAR RequestBuffer;
    ULONG  RequestBufferLength;
    PUCHAR ReplyBuffer;
    ULONG  ReplyBufferLength;
  } IoRequest;
  ULONG                     MajorIoControlCode;
  ULONG                     MinorIoControlCode;
  POS_DEP_DATA              OsData;
  SCARD_READER_CAPABILITIES ReaderCapabilities;
  PREADER_EXTENSION         ReaderExtension;
  SMARTCARD_REPLY           SmartcardReply;
  SMARTCARD_REQUEST         SmartcardRequest;
  T0_DATA                   T0;
  T1_DATA                   T1;
  PPERF_INFO                PerfInfo;
  ULONG                     Reserved[25 - sizeof(PPERF_INFO)];
} *PSMARTCARD_EXTENSION, SMARTCARD_EXTENSION;

成员

Version

指示此结构的版本。

VendorAttr

包含标识读取器驱动程序的信息,例如供应商名称、单位编号和序列号。

ReaderFunction[16]

语法块中的行应为 NTSTATUS (*ReaderFunction[16])(PSMARTCARD_EXTENSION);

指向读取器回调函数数组的指针。 供应商提供的读取器驱动程序可以实现的回调函数。 读取器驱动程序使这些回调函数可供智能卡库例程 SmartcardDeviceControl 调用,方法是将指向它们的指针存储在智能卡设备扩展中。

RDF_ATR_PARSE
RDF_CARD_EJECT
RDF_CARD_POWER
RDF_CARD_TRACKING
RDF_IOCTL_VENDOR
RDF_READER_SWALLOW
RDF_SET_PROTOCOL
RDF_TRANSMIT
有关详细信息,请参阅“备注”。

CardCapabilities

包含插入的智能卡的功能。

LastError

未使用。

IoRequest

具有以下成员的 结构:

IoRequest.Information

包含返回的字节数。

IoRequest.RequestBuffer

指向要发送到卡的用户 I/O 请求中的数据的指针。

IoRequest.RequestBufferLength

指示要发送到卡的字节数。

IoRequest.ReplyBuffer

指向缓冲区的指针,该缓冲区保存 I/O 请求返回的数据。

IoRequest.ReplyBufferLength

指示 I/O 请求返回的数据的字节数。

MajorIoControlCode

包含主要的 I/O 控制代码。

MinorIoControlCode

包含次要 I/O 控制代码。

OsData

包含特定于操作系统和驱动程序类型的信息。

ReaderCapabilities

包含键盘阅读器的功能。

ReaderExtension

包含特定于智能卡读取器的数据。

SmartcardReply

包含来自读取器的数据。

SmartcardRequest

包含当前命令和发送到智能卡的数据。

T0

包含用于 T=0 协议的数据。

T1

包含与 T=1 协议一起使用的数据。

PerfInfo

Reserved[25 - sizeof(PPERF_INFO)]

预留给系统使用。

注解

此结构将传递给所有回调函数。

单个回调函数由一系列常量值标识,这些常量值应用作 ReaderFunction 数组中的索引。

索引 描述
RDF_ATR_PARSE 可选。 当驱动程序库无法识别或分析智能卡驱动程序库时,RDF_ATR_PARSE分析函数会分析智能卡驱动程序库的重置 (ATR) 。
RDF_CARD_EJECT 可选。 RDF_CARD_EJECT 回调函数

RDF_CARD_EJECT回调函数从读取器中弹出插入的智能卡。

RDF_CARD_POWER RDF_CARD_POWER回调函数重置或关闭插入的智能卡。智能卡读取器驱动程序必须实现此回调函数。

输入时, SmartcardExtension 指向的结构应具有以下成员值:

MajorIoControlCode
值应为 IOCTL_SMARTCARD_POWER
IoRequest.ReplyBufferLength
应包含缓冲区的长度。
MinorIoControlCode
应具有以下次要代码之一:
SCARD_COLD_RESET
执行智能卡的冷重置。
SCARD_WARM_RESET
执行智能卡的热重置。
SCARD_POWER_DOWN
关闭智能卡电源。
在输出中, SmartcardExtension 指向的结构应具有以下值:
IoRequest.ReplyBuffer
接收智能卡返回的 ATR。 此外,必须将 ATR 传输到 SmartcardExtension->CardCapabilities.ATR.Buffer ,以便库可以分析 ATR。
IoRequest.Information
接收 ATR 的长度。
CardCapabilities.ATR.Length
包含 ATR 的长度。
RDF_CARD_TRACKING RDF_CARD_TRACKING回调函数安装事件处理程序,用于跟踪每次在卡读取器中插入或删除卡。智能卡读取器驱动程序必须实现此回调函数。

收到IOCTL_SMARTCARD_IS_PRESENT请求后,驱动程序库将确定智能卡是否已存在。 如果存在智能卡,驱动程序库会以STATUS_SUCCESS状态完成请求。 如果没有智能卡,驱动程序库将调用读取器驱动程序的智能卡跟踪回调函数,读取器驱动程序开始查找智能卡。 启动智能卡跟踪后,驱动程序库会将请求标记为具有STATUS_PENDING状态。

驱动程序库完成请求。

WDM 设备驱动程序

相应的 WDM 驱动程序库将指针添加到 SmartcardExtension-OsData-NotificationIrp>> 中的请求。 读取器驱动程序必须在检测到已插入或删除智能卡后立即完成请求。 读取器驱动程序通过调用 IoCompleteRequest 来完成请求,之后,读取器驱动程序必须将 SmartcardExtension -> OsDataNotificationIrp 成员重新设置为 NULL,以通知驱动程序库读取器驱动程序可以接受进一步的智能卡跟踪请求。

由于此调用可能具有无限期的持续时间,并且调用方可以在请求完成之前终止请求,因此将此 IRP 标记为可取消非常重要。

MyDriverCardSupervision(
SmartcardExtension, 
OtherParameters)
//
//    This function is called whenever the card status changes
//    For example, the card has been inserted or the card has been removed
//
{
    if (SmartcardExtension->OsData->NotificationOverlappedData != NULL){

        SmartcardCompleteCardTracking(SmartcardExtension);
    }
    //
    // Do additional tasks
    //
}
RDF_IOCTL_VENDOR RDF_IOCTL_VENDOR回调函数执行供应商特定的 IOCTL 操作。智能卡读取器驱动程序可以选择实现此回调函数。

输入时,调用方必须将以下值传递给函数:

SmartcardExtension->MajorIoControlCode
包含供应商特定的 IOCTL 代码。 有关如何定义特定于供应商的 IOCTL 代码的信息,请参阅 Winsmcrd.h 中的宏SCARD_CTL_CODE。 请注意,代码必须介于 2048 和 4095 之间。
SmartcardExtension->IoRequest.RequestBuffer
指向用户输入缓冲区的指针。
SmartcardExtension->IoRequest.RequestBufferLength
用户输入缓冲区的大小(以字节为单位)。
SmartcardExtension->IoRequest.ReplyBuffer
指向用户输出缓冲区的指针。
SmartcardExtension->IoRequest.ReplyBufferLength
用户输出缓冲区的大小(以字节为单位)。
SmartcardExtension->IoRequest.Information
请求提供的值。 必须设置为返回的字节数。
与所有其他 IOCTL 一样,用户模式应用程序通过调用 DeviceIoControl 函数将供应商定义的 IOCTL 调度到智能卡读取器设备。 但是,当 IOCTL 是供应商定义的时,应用程序必须首先打开读取器设备进行“重叠” (即异步) 访问。 应用程序还必须定义一个 OVERLAPPED 结构,并在 DeviceIoControl 的最后一个参数中将其传递给系统 (在 Windows SDK documentation.) 中也介绍了 OVERLAPPED 结构。 当操作系统调用驱动程序的 I/O 控制调度例程时,它会将 DIOCPARAMETERS 结构传递给驱动程序。 DIOCPARAMETERS 结构的 lpoOverlapped 成员包含指向 OVERLAPPED 结构的指针。
RDF_READER_SWALLOW RDF_READER_SWALLOW回调函数执行机械吞咽,这是智能卡完全插入智能卡读取器时发生的情况。智能卡读取器驱动程序实现此回调函数是可选的。
RDF_SET_PROTOCOL RDF_SET_PROTOCOL回调函数为插入的智能卡选择传输协议。智能卡读取器驱动程序必须实现此回调函数。

在输入时,调用方必须将以下值传递给函数:

SmartcardExtension->MajorIoControlCode
包含 IOCTL_SMARTCARD_SET_PROTOCOL
SmartcardExtension->MinorIoControlCode
包含调用方接受的一个或多个协议的按位 OR。 驱动程序必须选择插入的智能卡支持的协议。 我们建议 T = 1 协议优先于 T = 0 协议。
含义
SCARD_PROTOCOL_RAW 选择原始协议。
SCARD_PROTOCOL_T0 选择 ISO T = 0 协议。
SCARD_PROTOCOL_T1 选择 ISO T = 1 协议。
 
SmartcardExtension->IoRequest.ReplyBufferLength
包含回复缓冲区的长度。
SmartcardExtension->CardCapabilities.PtsData
包含执行 PTS 请求所需的参数。 有关详细信息,请参阅 PTS_DATA
请求返回以下值:
SmartcardExtension->IoRequest.ReplyBuffer
包含所选协议。
SmartcardExtension->IoRequest.Information
将 设置为 sizeof (ULONG) 。
调用方可以提供可接受的协议掩码。 驱动程序的设置协议回调例程选择掩码中的协议之一,并在 SmartcardExtension->IoRequest.ReplyBuffer 中返回所选协议。
RDF_TRANSMIT RDF_TRANSMIT回调函数执行数据传输。智能卡读取器驱动程序必须实现此回调函数。

在输入时,调用方必须将以下值传递给函数:

SmartcardExtension->MajorIoControlCode
包含 IOCTL_SMARTCARD_TRANSMIT
SmartcardExtension->IoRequest.RequestBuffer
指向SCARD_IO_REQUEST结构的指针,后跟要传输到卡的数据。
SmartcardExtension->IoRequest.RequestBufferLength
要传输到卡的字节数。
SmartcardExtension->IoRequest.ReplyBufferLength
回复缓冲区的大小(以字节为单位)。
请求返回以下值:
SmartcardExtension->IoRequest.ReplyBuffer
指向接收SCARD_IO_REQUEST结构的缓冲区以及卡结果的指针。
SmartcardExtension->IoRequest.Information
接收智能卡返回的实际字节数,以及SCARD_IO_REQUEST结构的大小。 有关SCARD_IO_REQUEST结构的定义,请参阅 IOCTL_SMARTCARD_TRANSMIT。
调用此函数时, SmartcardExtension->IoRequest.RequestBuffer 指向SCARD_IO_REQUEST结构,后跟要传输的数据。
typedef struct _SCARD_IO_REQUEST{
  DWORD  dwProtocol;   // Protocol identifier
  DWORD  cbPciLength;  // Protocol Control Information Length
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
    
   

dwProtocol 成员必须包含调用 IOCTL_SMARTCARD_SET_PROTOCOL 返回的协议标识符。

cbPciLength 成员包含SCARD_IO_REQUEST结构的大小(以字节为单位)。 此结构的大小通常为 8 个字节。

SCARD_IO_REQUEST结构后跟 (协议) 要传输到卡的数据。 根据用于传输的协议,该库提供了多个支持函数。 有关这些支持函数的详细信息,请参阅 SmartcardT0Request (WDM) 和 SmartcardT1Request (WDM) 。

RequestBufferReplyBuffer 指向同一系统缓冲区。 如果使用库函数 SmartcardxxRequestSmartcardxxReply,则不会覆盖输入缓冲区。 如果不使用这些函数,请在开始传输之前复制 RequestBuffer

必须将SCARD_IO_REQUEST结构复制到 ReplyBuffer 参数,后跟从卡接收的数据。 同样,如果使用 SmartcardxxRequestSmartcardxxReply 函数,则库将为你复制结构。

要求

要求
Header smclib.h (包括 Smclib.h)