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 的 NotificationIrp 成员 -> OsData 回到 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 文档中也介绍了 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 函数,库将复制结构。

要求

要求 价值
标头 smclib.h (包括 Smclib.h)