Smart Card Drivers Overview

This overview describes the development of WDM and VxD smart card drivers. It describes:

  • The IOCTL interface for a smart card driver
  • The development of WDM and VxD smart card drivers
  • The use of the WDM and VxD smart card driver libraries

The following topics are covered:

  • Smart Card Driver Environment
  • Smart Card Driver IOCTL Codes
  • Smart Card Driver Data Structures
  • Smart Card Driver Libraries
  • WDM Smart Card Driver Registry Entries
  • VxD Smart Card Driver Registry Entries
  • Smart Card Driver Device Names
  • Smart Card Driver Debugging


Smart Card Driver Environment

The following figure illustrates the standard environment for a smart card driver. The driver resides in kernel space and is only called by the smart card resource manager that resides in user space. The interface used by the resource manager and the driver is based on IOCTL calls.


Smart Card Driver IOCTL Codes

This section describes the various IOCTL codes that are used to communicate with a smart card reader/card system.

VxD Note The smart card resource manager can communicate with WDM and VxD drivers. To have consistent error values from both drivers, use the Microsoft® Windows NT® status values that are described in this document (the smart card libraries work with Windows NT status values); not with Win32® error values. The MapNtStatusToWinError (VxD) function can be used to map Windows NT status values to Win32 error values.

Usually, all parameters that come from a Win32 call to the driver are passed in a DIOCPARAMETERS structure. These parameters are transferred by the library to the internal structures of the SMARTCARD_EXTENSION structure. Use this structure to access all parameters.

For information on how to use the smart card driver libraries see:

  • WDM Smart Card Driver Library
  • VxD Smart Card Driver Library

These libraries provides support functions that simplify the development of smart card drivers.


Win32 IOCTL Calls

Use DeviceIoControl to call a driver from the Win32 environment.

BOOL
DeviceIoControl(
  HANDLE hDevice,
  DWORD dwIoControlCode,
  LPVOID lpInBuffer,
  DWORD nInBufferSize,
  LPVOID lpOutBuffer,
  DWORD nOutBufferSize,
  LPDWORD lpBytesReturned,
  LPOVERLAPPED lpOverlapped
);

Parameters

dwIoControlCode
Contains one of the control codes referred to in this document.
lpInBuffer
Contains either a minor I/O control code or data to be sent to a smart card.
nInBufferSize
The number of bytes to be sent to the card.
lpOutBuffer
Receives the result from the smart card.
nOutBufferSize
The size of the buffer.
lpBytesReturned
The number of bytes returned by this particular call.

Refer to the Platform SDK for more information and descriptions of the remaining parameters.


IOCTL Codes

The following table lists the available smart card IOCTL codes. With the exception of IOCTL_SMARTCARD_GET_LAST_ERROR, these codes apply to both WDM and VxD drivers.

IOCTL Code | Description
IOCTL_SMARTCARD_EJECT | Ejects the currently inserted smart card from the smart card reader.
IOCTL_SMARTCARD_GET_ATTRIBUTE | Queries smart card and smart card reader attributes
IOCTL_SMARTCARD_GET_LAST_ERROR | VxD drivers only. Retrieves the error code of the last operation.
IOCTL_SMARTCARD_GET_STATE | Gets the current status of the smart card reader.
IOCTL_SMARTCARD_IS_ABSENT | Either returns immediately if no card is currently inserted, or installs an event handler to track card removals.
IOCTL_SMARTCARD_IS_PRESENT | Either returns immediately if no card is currently inserted, or installs an event handler to track card insertions.
IOCTL_SMARTCARD_POWER | Either powers down or warm resets the card.
IOCTL_SMARTCARD_SET_ATTRIBUTE | Sets various attributes in the driver.
IOCTL_SMARTCARD_SET_PROTOCOL | Sets the protocol to be used with the currently inserted card.
IOCTL_SMARTCARD_SWALLOW | Causes the reader to swallow the card.
IOCTL_SMARTCARD_TRANSMIT | Transmits data to and receives data from the currently inserted smart card.


Smart Card Driver Data Structures

The following table lists the data structures you can use to hold driver internal data. These structures are mandatory for the WDM and VxD Smart Card Driver Libraries.

Data Structure | Description
SCARD_CARD_CAPABILITIES | Holds all information about the currently inserted smart card.
SCARD_READER_CAPABILITIES | Holds state information about the reader.
T1_DATA | Used by the smart card driver library for processing T1 I/O.
SCARD_VENDOR_ATTR | Holds all information about the reader.
SMARTCARD_EXTENSION | Used by the driver to access all the previously listed data structures, and additional information. This structure is passed to all callback functions.

For information on how to use the smart card driver libraries see:

  • WDM Smart Card Driver Library
  • VxD Smart Card Driver Library


Smart Card Driver Libraries

The smart card driver libraries supports a driver in performing the following actions:

  • Creation of device names needed by the smart card resource manager
  • Parameter checking and error detection for IOCTL calls
  • ATR parsing and parameter conversion
  • Support for the ISO protocols T=0 and T=1
  • Support for inverse convention
  • Event logging
  • Synchronizing access to the driver

The smart card driver library consists of the following files.

File | Description
smclib.h | Contains driver-specific definitions.
smcnt.h | Contains operating-specific definitions for WDM drivers.
smcvxd.h | Contains operating-specific definitions for VxD drivers.
winsmcrd.h | Global include file for drivers and applications.
smclib.sys | The smart card driver library for WDM drivers.
smclib.vxd | The smart card driver library for VxD drivers.

For information on a specific library, see:

  • WDM Smart Card Driver Library
  • VxD Smart Card Driver Library


WDM Smart Card Driver Library

Every WDM driver needs the following routines:

  • DriverEntry
  • DriverUnload
  • Create and Close
  • Cleanup
  • DeviceControl

The DriverEntry routine creates a device that is used to talk to the reader and uses the support functions SmartcardLogError_(WDM) and SmartcardCreateLink (WDM). The DriverUnload function removes the driver from the system. The resource manager calls Create to establish a connection to the reader, and Cleanup is used to cancel pending I/O requests.

DeviceControl is the main entry point for smart card requests. If the driver is a lowest-level driver, it should also have a StartIo routine.

DeviceControl should immediately call the smart card driver library. If the library is unable to handle the call because this IOCTL call is driver-specific, the driver's callback for unknown IOCTL codes is called.

A driver's IOCTL function usually looks like the following:

NTSTATUS
DriverDeviceControl(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp
    )
{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

    return SmartcardDeviceControl(
        &(deviceExtension->SmartcardExtension),
        Irp
        );
}


VxD Smart Card Driver Library

The smart card driver library supports a driver in performing the following actions:

  • Creation of device names needed by the smart card resource manager
  • Card insertion and removal notification
  • Parameter checking and error detection for IOCTL calls
  • ATR parsing and parameter conversion
  • Support for the ISO protocols T=0 and T=1
  • Support for inverse convention
  • Event logging (future version of the library)
  • Synchronizing access to the driver

The smart card driver library is implemented as a single VxD. To call the library functions, use the interface that is implemented in the smcvxd.h header file.

Every driver needs the DriverName_DeviceIoControl VxD routine; it is the main entry point for smart card requests.

The library offers functionality that is common for all smart card drivers. The principle of the library is based on callbacks. This means when the driver's DriverName_DeviceIoControl routine is called, it calls the library function SmartcardDeviceControl (VxD) using VxDCall. This routine does parameter checking and returns either if the call is invalid or if the library can handle the call without the driver. Otherwise, it calls back one of the driver's functions.


Smart Card Driver IOCTL Calling Scheme

The following figure shows the calling scheme of an IOCTL call:

This is the process that takes place in the calling scheme:

The resource manager calls the driver (1). The driver calls the library (2). The library checks the parameters of this call. If the driver's help is not needed to satisfy the call, the library returns the requested data, or an error code, to the caller (3a). If the driver's help is needed to satisfy the call, for example if I/O is required or if this is a vendor-specific call, the library calls the driver with all parameters set up correctly (3b). The driver performs I/O and uses support functions of the library (4 and 5). The driver then completes the request and returns the call to the resource manager (6).

The smart card library synchronizes access to your driver. No two callback functions will be called at the same time. However, card insertion and removal event handling must be processed asynchronously.


Smart Card Driver Library Function Reference

The following table lists the smart card driver library functions.

Function | Description
MapNtStatusToWinError (VxD) | Maps a Windows NT status code to a Win32® error code. Not available for WDM drivers.
SmartcardCompleteCardTracking (VxD) | Informs the caller of a card insertion or removal event. Not available for WDM drivers.
SmartcardCompleteRequest (VxD) | Informs the caller of the completion of a request, unlocks memory, and enables further calls to the smart card library. Not available for WDM drivers.
SmartcardCreateLink (WDM) -or- SmartcardCreateLink (VxD) | WDM: Creates a DOS device name that the smart card resource manager uses to access the driver. VxD: Creates a registry entry that is used by the smart card resource manager to access a device.
SmartcardDeleteLink (WDM) -or- SmartcardDeleteLink (VXD) | Deletes the link that was created with SmartcardCreateLink.
SmartcardDeviceControl (WDM) -or- SmartcardDeviceControl (VxD) | The main entry function for the smart card driver library. Performs parameter checking and completes calls that do not require I/O with the reader.
SmartcardExit (WDM) -or- SmartcardExit (VxD) | Frees buffers that were allocated during a call to SmartcardInitialize.
SmartcardInitialize (WDM) -or- SmartcardInitialize (VxD) | Allocates internal buffers for the library.
SmartcardLogError (WDM) | Writes an error message to the event log. Not available for VxD drivers.
SmartcardRawReply (WDM) -or- SmartcardRawReply (VxD) | Transfers the data received from the card to the user buffer.
SmartcardRawRequest (WDM) -or- SmartcardRawRequest (VxD) | Copies data from the user buffer to a send buffer.
SmartcardT0Reply (WDM) -or- SmartcardT0Reply (VxD) | Transfers the data received from the card to the user buffer.
SmartcardT0Request (WDM) -or- SmartcardT0Request (VxD) | Copies data from the user buffer to a send buffer.
SmartcardT1Reply (WDM) -or- SmartcardT1Reply (VxD) | Copies data from the user buffer to a send buffer and checks the T=1 protocol status.
SmartcardT1Request (WDM) -or- SmartcardT1Request (VxD) | Copies data from the user buffer to a send buffer and checks the T=1 protocol status.
SmartcardUpdateCardCapabilities_(WDM) -or- SmartcardUpdateCardCapabilities (VxD) | Translates an ATR string into the SCARD_CARD_CAPABILITIES structure that can be used by the driver.
VxD_CreateDevice (VxD) | Creates a new instance of a device. Not available for WDM drivers.
VxD_DeleteDevice (VxD) | Deletes a device that was created using VxD_CreateDevice. Not available for WDM drivers.


Smart Card Driver Library Callback Function Reference

The driver can set up several callback functions in the SMARTCARD_EXTENSION structure. The member ReaderFunction is an array of function pointers. Each array member is used for a specific callback. To set up one of these members, the driver has to assign a function pointer to the desired array member. For example:

SmartcardExtension->ReaderFunction[RDF_CARD_POWER] =
DriverCardPower;

This sets up a callback for the card power request. When the library receives such an IOCTL code, it sets up all parameters and then calls this function. If a member function is NULL, the driver will return STATUS_NOT_SUPPORTED to the caller. This is useful, for example, if your driver does not support card ejecting or card swallowing. If you do not set up a function for these calls, the library simply returns STATUS_NOT_SUPPORTED.


Smart Card Callback Parameters

Before the library calls a member function, it sets up the following members in the SMARTCARD_EXTENSION structure for every control request, except IOCTL_SMARTCARD_IS_ABSENT and IOCTL_SMARTCARD_IS_PRESENT.

Members | Description
IoRequest.RequestBuffer | Points to the user buffer that contains the user data to be sent to the card.
IoRequest.RequestBufferLength | The length of the user buffer.
IoRequest.ReplyBuffer | Points to the buffer that receives the data returned by the smart card.
IoRequest.ReplyBufferLength | The size of the reply buffer.
IoRequest.Information | Points to a ULONG that receives the number of bytes actually received from the card.
MajorIoControlCode | Contains the major I/O control code of this call.
MinorIoControlCode | Contains the minor I/O control code of this call (if any).

WDM Note In addition, the structure SmartcardExtension->OsData will be set up as follows:

Member | Description
CurrentIrp | Receives a pointer to the requesting IRP for every control request, except IOCTL_SMARTCARD_IS_ABSENT and IOCTL_SMARTCARD_IS_PRESENT.
NotificationIrp | Receives a pointer to the requesting IRP for the control request IOCTL_SMARTCARD_IS_ABSENT or IOCTL_SMARTCARD_IS_PRESENT.

The following table lists the callback function available from both libraries. Some functions are mandatory and others are optional. The driver needs to set up only mandatory functions. Every function that has not been set up will return STATUS_NOT_SUPPORTED to the smart card resource manager.

Callback Function | Description
RDF_CARD_POWER | Resets or powers down an inserted smart card.
RDF_CARD_EJECT | Ejects an inserted smart card.
RDF_CARD_TRACKING | Installs an event handler to track card insertions and removals.
RDF_IOCTL_VENDOR | Performs vendor-specific IOCTL operations.
RDF_READER_SWALLOW | Does a mechanical swallow.
RDF_SET_PROTOCOL | Selects a transmission protocol for the currently inserted card.
RDF_TRANSMIT | Performs data transmissions.

When calling these functions, the driver should retrieve calling parameters from the members described under Input Values. It should store data to the members described under Output Values in each reference page.

VxD Note If your driver returns STATUS_PENDING to any of the callbacks except RDF_CARD_TRACKING, the smart card library will refuse any further call to the driver and will return STATUS_DEVICE_BUSY. Call SmartcardCompleteRequest to finish a call that returned STATUS_PENDING. This function informs the caller of the completion and unlocks memory that had been locked by the smart card driver library. It also enables further requests to your driver.

If you do not call SmartcardCompleteRequest, the library will block any further call to your driver.


WDM Smart Card Driver Registry Entries

Each device driver needs several entries in the registry to make the driver visible to the device manager and to enable event logging.


Registering the Driver

To make the driver visible to the device manager, a driver needs to have the following entries in the registry under a specific path:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SmartCardDriver

Start
DWORD:0x0000002

A value of 2 makes the driver start automatically. During development, it is recommended to use a Start value of 3, which makes the driver start manually.

Type
DWORD:0x0000001

A value of 1 identifies the driver as a kernel-mode driver.

Group
"Smart Card Reader"

Every driver has to be a member of the Group "Smart Card Reader", since the smart card resource manager waits for this group to start.

ErrorControl
DWORD:0x0000001

A value of 1 lets the system continue to boot even if the driver fails, but it shows an error message if the driver fails to load.


Preparing Event Logging on Windows NT

Every driver must write event messages to the system event logger to give the system administrator enough information about why a driver is unable to work properly.

The event log needs an additional entry in the registry under:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\System\SmartCardDriver

EventMessageFile
"%SystemRoot%\System32\SmartCardDriver.sys"

Note The registry path names never contain the extension of the file name. The EventMessageFile needs that extension.

TypesSupported
DWORD:0x00000007


VxD Smart Card Driver Registry Entries

To enable the smart card resource manager to access your device, a symbolic link is created in the registry under:

HKLM\System\CurrentControlSet\VxD\Scmlib\Devices

Each entry has the form:

SCReaderN=Driver.vxd

When you call SmartcardCreateLink (VxD), this entry is generated automatically. SmartcardDeleteLink (VxD) removes the entry.

The name that your driver supplies to SmartcardCreateLink must be either the full name of the driver, including the VXD extension, or the name that has been used in a call to VxD_CreateDevice (VxD).


Smart Card Driver Device Names

Every WDM and VxD device driver has two names. WDM device drivers use kernel device name and DOS device name while VxD device drivers use driver device name and link name.

WDM Device Driver Names

For WDM device drivers the kernel device name is the device name that is known only in the name space of the kernel. The DOS device name is the name that a Win32® application uses to communicate with the driver.

Kernel Device Name: The name that is known only in the kernel name space can be chosen by the driver developer, but it should follow Windows NT device name naming conventions, in which a device name looks like this:

\Device\DeviceName[Unit]

where DeviceName is a name that reflects the type of driver and Unit is the zero-based unit number of that driver. The unit number is used to distinguish the device if more than one device of that type is installed in a system.

DOS Device Name: Since every driver must communicate with the smart card resource manager, it must have a specific name for the Win32 name space. This name must be:

\DosDevices\SCReader[Unit]

The unit number does not need to be the same as the one for the kernel name space. It should be the first available unit number. Use SmartcardCreateLink (WDM) to generate the DOS device name. The smart card driver library is able to create such a name automatically.

VxD Device Driver Names

For VxD device drivers use the driver device name and the link name.

Driver Device Name: The driver device name is specific to the driver. As with every other VxD name, an application that needs to access a device needs to know the driver name in order to open the device. A device name usually looks like DEVICE.VXD.

Link Name: Since every driver must communicate with the smart card resource manager, the resource manager needs a way to map a generic name to a specific driver name. This mapping is done through the registry. The registry contains the generic name as the key to the specific driver name:

SCReader[Unit]

The smart card driver library is able to create such a name automatically.


Smart Card Driver Debugging

Both libraries supports several debugging features. These debugging features let you see what the library does internally and let you write debugging output to a connected debugger. To set up a remote debug session under Windows NT, refer to the Windows NT DDK documentation. The header file smclib.h defines the following constants used for debugging:

#define DEBUG_IOCTL     ((ULONG) 0x00000001)
#define DEBUG_ATR       ((ULONG) 0x00000002)
#define DEBUG_PROTOCOL  ((ULONG) 0x00000004)
#define DEBUG_DRIVER    ((ULONG) 0x00000008)
#define DEBUG_TRACE     ((ULONG) 0x00000010)
#define DEBUG_ERROR     ((ULONG) 0x00000020)
#define DEBUG_BREAK     ((ULONG) 0x80000000)
#define DEBUG_ALL       ((ULONG) 0x7FFFFFFF)

These can be used to select the level of debugging that you want. You can either use the function,

SmartcardSetDebugLevel(
    ULONG DebugLevel
);

in your driver and provide a mask of constants that are combined with the bitwise OR operator to select the level of debugging that you want, or you can use the smart card driver test program scdrvtst that comes with the smart card DDK. Note that you must have installed the checked version of Windows NT and the checked version of the driver to get debugging messages.

To write your own driver debugging messages, it is recommended that you use the function,

SmartcardDebug(
    ULONG DebugLevel,
    PCHAR Message
);

This lets you write messages to the remote debugger. To write error messages, use the constant DEBUG_ERROR for the DebugLevel. To write standard driver messages, use the constant DEBUG_DRIVER. To write trace messages, such as when entering and exiting a function, use DEBUG_TRACE as the DebugLevel.

It is recommended during development of your driver that you use the checked version of the smart card driver library and set the debugging level to the maximum using SmartcardSetDebugLevel(DEBUG_ALL) in your DriverEntry routine.


IOCTL_SMARTCARD_EJECT

WDM driver version:

The IOCTL_SMARTCARD_EJECT DeviceIoControl operation ejects the currently inserted smart card from the smart card reader.

I/O Status Block

Information is set to zero. Status can be:

Status | Meaning
STATUS_SUCCESS | Card successfully ejected.
STATUS_NO_MEDIA | No card in reader.
STATUS_NOT_SUPPORTED | Reader does not support card eject.
STATUS_IO_TIMEOUT | Operation has timed out.

VxD driver version:

The IOCTL_SMARTCARD_EJECT DeviceIoControl operation ejects the currently inserted smart card from the smart card reader.

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | Card successfully ejected.
STATUS_NO_MEDIA | No card in reader.
STATUS_NOT_SUPPORTED | Reader does not support card eject.
STATUS_IO_TIMEOUT | Operation has timed out.


IOCTL_SMARTCARD_GET_ATTRIBUTE

WDM driver version:

The IOCTL_SMARTCARD_GET_ATTRIBUTE DeviceIoControl operation queries smart card and smart card reader attributes. For a list of all defined attributes, refer to Part 3 of the Interoperability Specification for ICCs and Personal Computer Systems (see Documents at http://www.smartcardsys.com/).

Input

Irp->AssociatedIrp.SystemBuffer
Contains a tag value describing the data to be retrieved.
Parameters.DeviceIoControl.InputBufferLength
Must be sizeof(ULONG).
Parameters.DeviceIoControl.OutputBufferLength
The size of the output buffer, which receives the result. The size depends on the type of attribute to be retrieved.

Output

Irp->AssociatedIrp.SystemBuffer
Receives the data.

I/O Status

Information must be set to the number of bytes returned. The trailing null byte should not be included in strings. Since these calls are all mandatory for all drivers, Status must be set to STATUS_SUCCESS. However, if a driver does not support a particular attribute, the driver must set Status to STATUS_NOT_SUPPORTED.

VxD driver version:

The IOCTL_SMARTCARD_GET_ATTRIBUTE DeviceIoControl operation queries smart card and smart card reader attributes. For a list of all defined attributes, refer to Part 3 of the Interoperability Specification for ICCs and Personal Computer Systems (see Documents at http://www.smartcardsys.com/).

Input

DiocParams->lpvInBuffer
Contains a tag value describing the data to be retrieved.
DiocParams->cbInBuffer
Must be sizeof(ULONG).
DiocParams->cbOutBuffer
The size of the output buffer, which receives the result. The size depends on the type of attribute to be retrieved.

Output

DiocParams->lpvOutBuffer
Receives the data.
DiocParams->lpcbBytesReturned
Must be set to the number of bytes returned. The trailing null byte should not be included in strings.

Return Values

Since these calls are all mandatory for all drivers, status must be set to STATUS_SUCCESS. However, if a driver does not support a particular attribute, the driver must set status to STATUS_NOT_SUPPORTED.


IOCTL_SMARTCARD_GET_LAST_ERROR

WDM driver version:

None.

VxD driver version:

There is no option to return an error code on completing an overlapped operation. Use IOCTL_SMARTCARD_GET_LAST_ERROR to get the error code of the last operation.

Input

DiocParams->cbOutBuffer
The size of the output buffer. Must be at least sizeof(ULONG).

Output

DiocParams->lpvOutBuffer
Receives the error code.
DiocParams->lpcbBytesReturned
Must be set to sizeof(ULONG).

Return Values

This call must return STATUS_SUCCESS.

Note When your driver uses the smart card driver library, you should store the result of the last overlapped operation in the smart card extension. The library will answer this call automatically using your stored value.


IOCTL_SMARTCARD_GET_STATE

WDM driver version:

The IOCTL_SMARTCARD_GET_STATE DeviceIoControl operation gets the current status of the smart card reader.

Input

Parameters.DeviceIoControl.OutputBufferLength
The size of the output buffer. Must be at least sizeof(ULONG).

Output

Irp->AssociatedIrp.SystemBuffer
Receives the status of the card. The status can be:
Status | Meaning
SCARD_UNKNOWN | The reader does not know the status.
SCARD_ABSENT | No card is currently inserted.
SCARD_PRESENT | A card is inserted.
SCARD_SWALLOWED | A card is inserted and the reader has swallowed it.
SCARD_POWERED | The card is powered but the reader does not know its mode.
SCARD_NEGOTIABLE | A card is inserted and awaits protocol negotiation.
SCARD_SPECIFIC | A card is inserted and a protocol has been selected.

I/O Status

Information must be set to sizeof(ULONG). Status must be STATUS_SUCCESS.

VxD driver version:

The IOCTL_SMARTCARD_GET_STATE DeviceIoControl operation gets the current status of the smart card reader.

Input

DiocParams->cbOutBuffer
The size of the output buffer. Must be at least sizeof(ULONG).

Output

DiocParams->lpvOutBuffer
Receives the status of the reader. The status can be:
Value | Meaning
SCARD_UNKNOWN | The reader does not know the status.
SCARD_ABSENT | No card is currently inserted.
SCARD_PRESENT | A card is inserted.
SCARD_SWALLOWED | A card is inserted and the reader has swallowed it. If the reader does not support swallowing, it should go to this status after card insertion.
SCARD_POWERED | The card is powered, but the reader does not know its mode.
SCARD_NEGOTIABLE | A card is inserted and awaits protocol negotiation.
SCARD_SPECIFIC | A card is inserted and a protocol has been selected.

DiocParams->lpcbBytesReturned
Must be set to sizeof(ULONG).

Return Values

The return value must be set to STATUS_SUCCESS.


IOCTL_SMARTCARD_IS_ABSENT

WDM driver version:

The IOCTL_SMARTCARD_IS_ABSENT DeviceIoControl operation either returns immediately if no card is currently inserted, or it installs an event handler to track card removals.

The operation either returns immediately with STATUS_SUCCESS, which indicates that no card is in the reader, or it returns with STATUS_PENDING. This indicates that a card is currently in the reader and the driver will inform the caller of card removal through an I/O completion. Waiting for I/O completion can be accomplished with the following code fragment:

success = GetOverlappedResult(
    hDevice,
    &lpOverlapped,
    &lpBytesReturned,
    TRUE
    );

Completing the call in the driver can be accomplished with the following code fragment:

IoCompleteRequest(
    Irp,
    IO_NO_INCREMENT
    );

return STATUS_SUCCESS;

I/O Status

Information must be set to zero. Status can be:

Status | Meaning
STATUS_SUCCESS | A smart card is inserted.
STATUS_PENDING | The driver is waiting for a card to be inserted.
STATUS_DEVICE_BUSY | Event tracking is already active.
STATUS_INVALID_DEVICE_STATE | The device cannot accept the request.

VxD driver version:

The IOCTL_SMARTCARD_IS_ABSENT DeviceIoControl operation either returns immediately if no card is currently inserted, or it installs an event handler to track card removals.

The operation either returns immediately with STATUS_SUCCESS, which indicates that no card is in the reader, or it returns with STATUS_PENDING. This indicates that a card is currently in the reader and the driver will inform the caller of card removal through an I/O completion. Waiting for I/O completion can be accomplished with the following code fragment:

success = GetOverlappedResult(
    hDevice,
    &lpOverlapped,
    &lpBytesReturned,
    TRUE
    );

Completing the call in the driver can be accomplished with the following code fragment:

SmartcardCompleteCardTracking(
  SmartcardExtension
);

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | A smart card is inserted.
STATUS_PENDING | The driver is waiting for a card to be inserted.
STATUS_DEVICE_BUSY | Event tracking is already active.
STATUS_INVALID_DEVICE_STATE | The device cannot accept the request.


IOCTL_SMARTCARD_IS_PRESENT

WDM driver version:

The IOCTL_SMARTCARD_IS_PRESENT DeviceIoControl operation either returns immediately if no card is currently inserted, or it installs an event handler to track card insertions.

The operation either returns immediately with STATUS_SUCCESS, which indicates that a card is already in the reader, or it returns with STATUS_PENDING, which indicates that no card is currently in the reader. In this case, the driver then informs the caller of card insertion through an I/O completion. Waiting for I/O completion can be accomplished with the following code fragment:

success = GetOverlappedResult(
    hDevice,
    &lpOverlapped,
    &lpBytesReturned,
    TRUE);

I/O Status

Information must be set to zero. Status can be:

Status | Meaning
STATUS_SUCCESS | No smart card is currently inserted.
STATUS_PENDING | The driver is waiting for a card to be removed.
STATUS_DEVICE_BUSY | Event tracking is already active.
STATUS_INVALID_DEVICE_STATE | The device cannot accept the request.

VxD driver version:

The IOCTL_SMARTCARD_IS_PRESENT DeviceIoControl operation either returns immediately if no card is currently inserted, or it installs an event handler to track card insertions.

The operation either returns immediately with STATUS_SUCCESS, which indicates that a card is already in the reader, or it returns with STATUS_PENDING, which indicates that no card is currently in the reader. In this case, the driver then informs the caller of card insertion through an I/O completion. Waiting for I/O completion can be accomplished with the following code fragment:

success = GetOverlappedResult(
    hDevice,
    &lpOverlapped,
    &lpBytesReturned,
    TRUE);

Completing the call in the driver can be accomplished with the following code fragment:

SmartcardCompleteCardTracking(
  SmartcardExtension
);

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | No smart card is currently inserted.
STATUS_PENDING | The driver is waiting for a card to be removed.
STATUS_DEVICE_BUSY | Event tracking is already active.
STATUS_INVALID_DEVICE_STATE | The device cannot accept the request.


IOCTL_SMARTCARD_POWER

WDM driver version:

The IOCTL_SMARTCARD_POWER DeviceIoControl operation consists of three minor IOCTL codes. This code can be:

Code | Meaning
SCARD_COLD_RESET | Power down the card and power it up again.
SCARD_WARM_RESET | Perform a warm reset of the card.
SCARD_POWER_DOWN | Switch off the card power.

Input

Irp->AssociatedIrp.SystemBuffer
Contains the minor IOCTL code.
Parameters.DeviceIoControl.OutputBufferLength
The size of the output buffer. Must be at least 33 bytes to hold a complete ATR. (Does not apply to power down code.)

Output

Irp->AssociatedIrp.SystemBuffer
Used by SCARD_COLD_RESET and SCARD_WARM_RESET to store the ATR coming from the card.

I/O Status Block

Information is set to the length of the ATR returned by the card. Status is set to:

Status | Meaning
STATUS_SUCCESS | Successful operation.
STATUS_UNRECOGNIZED_MEDIA | Unknown or unsupported card inserted.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.

VxD driver version:

The IOCTL_SMARTCARD_POWER DeviceIoControl operation consists of three minor IOCTL codes. This code can be:

Code | Meaning
SCARD_COLD_RESET | Power down the card and power it up again.
SCARD_WARM_RESET | Perform a warm reset of the card.
SCARD_POWER_DOWN | Switch off the card power.

Input

DiocParams->lpvInBuffer
Contains the minor IOCTL code.
DiocParams->cbOutBuffer
The size of the output buffer. Must be at least 33 bytes to hold a complete ATR.

Output

DiocParams->lpvOutBuffer
Used by SCARD_COLD_RESET and SCARD_WARM_RESET to store the ATR coming from the card.
DiocParams->lpcbBytesReturned
Must be set to the length of the ATR returned by the card. (Does not apply to power down code.)

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | Successful operation.
STATUS_UNRECOGNIZED_MEDIA | Unknown or unsupported card inserted.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.


IOCTL_SMARTCARD_SET_ATTRIBUTE

WDM driver version:

The IOCTL_SMARTCARD_SET_ATTRIBUTE DeviceIoControl operation sets various attributes in the driver. For a list of all defined attributes, refer to Part 3 of the Interoperability Specification for ICCs and Personal Computer Systems (see Documents at http://www.smartcardsys.com/).

Input

Irp->AssociatedIrp.SystemBuffer
Contains the tag and value to be set.
Parameters.DeviceIoControl.InputBufferLength
Contains the length of the whole TLV structure.

I/O Status

Information must be set to sizeof(ULONG). Status can be:

Status | Meaning
STATUS_SUCCESS | The attribute has been set successfully.
STATUS_NOT_SUPPORTED | The attribute is not supported.
STATUS_INVALID_PARAMETER | The attribute to be set is in the wrong format.

VxD driver version:

The IOCTL_SMARTCARD_SET_ATTRIBUTE DeviceIoControl operation sets various attributes in the driver. For a list of all defined attributes, refer to Part 3 of the Interoperability Specification for ICCs and Personal Computer Systems (see Documents at http://www.smartcardsys.com/).

Input

DiocParams->lpvInBuffer
Contains the tag and value to be set.
DiocParams->cbInBuffer
Contains the length of the whole TLV structure.

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | The attribute has been set successfully.
STATUS_NOT_SUPPORTED | The attribute is not supported.
STATUS_INVALID_PARAMETER | The attribute to be set is in the wrong format.


IOCTL_SMARTCARD_SET_PROTOCOL

WDM driver version:

The IOCTL_SMARTCARD_SET_PROTOCOL DeviceIoControl operation sets the protocol to be used with the currently inserted card.

Input

Irp->AssociatedIrp.SystemBuffer
Contains a mask of protocols that are acceptable for the following transmissions. This mask can be any of the following, which can be combined by using the bitwise OR operator:
  • SCARD_PROTOCOL_RAW
  • SCARD_PROTOCOL_T0
  • SCARD_PROTOCOL_T1
  • SCARD_PROTOCOL_DEFAULT
  • SCARD_PROTOCOL_OPTIMAL

The last two values are additional bit definitions telling the driver either to explicitly perform PTS selection (SCARD_PROTOCOL_OPTIMAL) with the best possible communication parameters or to use the implicit protocol of the card (SCARD_PROTOCOL_DEFAULT) with standard parameters. If the card supports only one protocol with one set of communication parameters, these bits are ignored.

Parameters.DeviceIoControl.InputBufferLength
Must be set to sizeof(ULONG). The driver decides which protocol out of the mask to use with the currently inserted card.
Parameters.DeviceIoControl.OutputBufferLength
Must be sizeof(ULONG).

Output

Irp->AssociatedIrp.SystemBuffer
The driver stores the selected protocol here. Only one bit out of the mask can be set.

I/O Status

Information must be set to sizeof(ULONG). Status can be:

Status | Meaning
STATUS_SUCCESS | One protocol has been successfully selected.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.
STATUS_NOT_SUPPORTED | The card does not support any of the requested protocols.
STATUS_INVALID_DEVICE_REQUEST | The mask contains no known protocol.

VxD driver version:

The IOCTL_SMARTCARD_SET_PROTOCOL DeviceIoControl operation sets the protocol to be used with the currently inserted card.

Input

DiocParams->lpvInBuffer
Contains a mask of protocols that are acceptable for the following transmissions. This mask can be any of the following, which can be combined by using the bitwise OR operator:
  • SCARD_PROTOCOL_RAW
  • SCARD_PROTOCOL_T0
  • SCARD_PROTOCOL_T1
  • SCARD_PROTOCOL_DEFAULT
  • SCARD_PROTOCOL_OPTIMAL

The last two values are additional bit definitions telling the driver either to explicitly perform PTS selection (SCARD_PROTOCOL_OPTIMAL) with the best possible communication parameters or to use the implicit protocol of the card (SCARD_PROTOCOL_DEFAULT) with standard parameters. If the card supports only one protocol with one set of communication parameters, these bits are ignored.

DiocParams->cbInBuffer
Must be set to sizeof(ULONG). The driver decides which protocol out of the mask to use with the currently inserted card.
DiocParams->cbOutBuffer
Must be sizeof(ULONG).

Output

DiocParams->lpvInBuffer
The driver stores the selected protocol here. Only one bit out of the mask can be set.
DiocParams->lpcbBytesReturned
Must be set to sizeof(ULONG).

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | One protocol has been successfully selected.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.
STATUS_NOT_SUPPORTED | The card does not support any of the requested protocols.
STATUS_INVALID_DEVICE_REQUEST | The mask contains no known protocol.


IOCTL_SMARTCARD_SWALLOW

WDM driver version:

The IOCTL_SMARTCARD_SWALLOW DeviceIoControl operation causes the reader to swallow the card.

I/O Status

Information must be set to zero. Status can be:

Status | Meaning
STATUS_SUCCESS | The card was swallowed.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.
STATUS_NOT_SUPPORTED | The reader does not support swallowing.

VxD driver version:

The IOCTL_SMARTCARD_SWALLOW DeviceIoControl operation causes the reader to swallow the card.

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | The card was swallowed.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.
STATUS_NOT_SUPPORTED | The reader does not support swallowing.


IOCTL_SMARTCARD_TRANSMIT

WDM driver version:

The IOCTL_SMARTCARD_TRANSMIT DeviceIoControl operation transmits data to and receives data from the currently inserted smart card.

Input

Irp->AssociatedIrp.SystemBuffer
Points to an SCARD_IO_REQUEST structure followed by the data to be transmitted. An SCARD_IO_REQUEST structure has the following definition:
typedef struct _SCARD_IO_REQUEST{
    DWORD dwProtocol;   // Protocol identifier
    DWORD cbPciLength;  // Protocol Control Information Length
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
Irp->AssociatedIrp.SystemBuffer
Contains the data to be transmitted to the currently inserted smart card.
Parameters.DeviceIoControl.InputBufferLength
Contains the size of the structure plus the length of trailing data bytes (if any). The member dwProtocol must be set to the previously selected protocol, and cbPciLength must be set to the size of the SCARD_IO_REQUEST structure itself (usually eight). The structure will be used for future protocols. Any data that is to be transmitted to the card must immediately follow this structure.
Parameters.DeviceIoControl.OutputBufferLength
Contains the length of the output buffer.

Output

Irp->AssociatedIrp.SystemBuffer
Receives the result of the transmission. This buffer must also begin with an SCARD_IO_REQUEST structure. Any data that was received from the card must be stored immediately after the structure.

Since the input buffer and the output buffer are pointing to the same memory area, it is the driver's responsibility to avoid overwriting the input data. Use the Smart Card Driver Library to ensure that the input data is not overwritten.

I/O Status

Information receives the size of the SCARD_IO_REQUEST structure plus the number of bytes received from the card. Status can be:

Status | Meaning
STATUS_SUCCESS | The transmission was successful.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.
STATUS_INVALID_DEVICE_STATE | The protocol in the header does not match the previously selected card protocol.

VxD driver version:

The IOCTL_SMARTCARD_TRANSMIT DeviceIoControl operation transmits data to and receives data from the currently inserted smart card.

Input

DiocParams->lpvInBuffer
Points to an SCARD_IO_REQUEST structure, which has the following definition:
typedef struct _SCARD_IO_REQUEST{
    DWORD dwProtocol;   // Protocol identifier
    DWORD cbPciLength;  // Protocol Control Information Length
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
DiocParams->cbInBuffer
Contains the size of the structure plus the length of trailing data bytes (if any). The member dwProtocol must be set to the previously selected protocol, and cbPciLength must be set to the size of the SCARD_IO_REQUEST structure itself (usually eight). The structure will be used for future protocols. Any data that is to be transmitted to the card must immediately follow this structure.
DiocParams->cbOutBuffer
Contains the length of the output buffer.

Output

DiocParams->lpvOutBuffer
Receives the result of the transmission. This buffer must also begin with an SCARD_IO_REQUEST structure. Any data that was received from the card must be stored immediately after the structure.
DiocParams->lpcbBytesReturned
Receives the size of the SCARD_IO_REQUEST structure plus the number of bytes received from the card.

Return Values

Following are possible return values.

Value | Meaning
STATUS_SUCCESS | The transmission was successful.
STATUS_NO_MEDIA | No card in reader.
STATUS_IO_TIMEOUT | The operation has timed out.
STATUS_INVALID_DEVICE_STATE | The protocol in the header does not match the previously selected card protocol.


Vendor-specific IOCTL Calls

For information on vendor-specific IOCTL operations, see RDF_IOCTL_VENDOR.


SCARD_CARD_CAPABILITIES

The SCARD_CARD_CAPABILITIES structure holds all information about the currently inserted smart card.

typedef struct _SCARD_CARD_CAPABILITIES{

     //
    // Flag that indicates that the current card uses inverse convention
    //
    BOOLEAN InversConvention;

    //
    // Calculated etu
    //
    ULONG    etu;

    //
    // Answer To Reset string returned by card.
    //
    struct {

        UCHAR Buffer[64];
        UCHAR Length;

    } ATR;

    struct {

        UCHAR Buffer[16];
        UCHAR Length;

    } HistoricalChars;

    // !!! DO NOT MODIFY ANY OF THE BELOW VALUES
    // OTHERWISE THE LIBRARY WON'T WORK PROPERLY

    //
    // The following 2 tables are provided to give
    // the driver access to the ISO definitions
    //
    PCLOCK_RATE_CONVERSION     ClockRateConversion;
    PBIT_RATE_ADJUSTMENT     BitRateAdjustment;

    // Clock rate conversion
    UCHAR Fl;

    // Bit rate adjustment
    UCHAR Dl;

    // Maximum programming current
    UCHAR II;

    // Programming voltage in .1 Volts
    UCHAR P;

    // Extra guard time in etu
    UCHAR N;

    // Calculated guard time in micro seconds
    ULONG GT;

    struct {

        // This is a bit mask of the supported protocols
        ULONG Supported;
        // The currently selected protocol
        ULONG Selected;

    } Protocol;

    //
    // T=0 specific data
    //
    struct {

        // Waiting integer
        UCHAR WI;

        // Waiting time in micro seconds
        ULONG WT;

    } T0;

    //
    // T=1 specific data
    //
    struct {

        // Information field size of card
        UCHAR IFSC;

        // Character waiting integer and block waiting integer
        UCHAR CWI;
        UCHAR BWI;

        // Error detection code
        UCHAR EDC;

        // Character and block waiting time in micro seconds
        ULONG CWT;
        ULONG BWT;

        // Block guarding time in micro seconds
        ULONG BGT;

    } T1;

    //
    // Reserved, do not use
    //
    ULONG Reserved[25];

} SCARD_CARD_CAPABILITIES, *PSCARD_CARD_CAPABILITIES;

Members

The following members must be maintained by the driver:

ATR.Buffer
Receives the ATR bytes after a warm or cold reset.
ATR.Length
Receives the actual length of the ATR.

The following members should be used by the driver:

GT
The guard time, in microseconds (including the extra guard time). This is the minimum delay between two consecutive characters.
T0.WT
The T=0 work waiting time, in microseconds. This is the maximum delay between two consecutive characters.
T1.BWT
The T=1 block waiting time, in microseconds. This is the maximum delay between the end of a block and the start of the next block sent in the opposite direction.
T1.CWT
The T=1 character waiting time, in microseconds. This is the maximum delay between two consecutive characters.
T1.BGT
The T=1 block guarding time, in microseconds. This is the minimum delay between the end of a block and the start of the next block sent in the opposite direction.

Comments

SCARD_CARD_CAPABILITIES holds information about the currently inserted smart card. If the driver uses the Smart Card Driver Library, then ATR is the only member that the driver must fill in. Fill ATR.Buffer with the ATR characters and ATR.Length with the number of ATR bytes returned by the card. The Smart Card Driver Library will automatically update all other fields when a call is made to IOCTL_SMARTCARD_SET_PROTOCOL.


SCARD_READER_CAPABILITIES

The SCARD_READER_CAPABILITIES structure holds state information about the reader. It must be completely maintained by the driver.

typedef struct _SCARD_READER_CAPABILITIES {

    //
    // Supported protocol by the reader/driver
    //
    struct {

        ULONG    Async;
        ULONG     Sync;

    } SupportedProtocols;

    //
    // Type of reader (Serial/USB/PCMCIA/Keyboard etc.)
    //
    ULONG    ReaderType;

    //
    // Mechanical characteristics like SCARD_READER_SWALLOWS etc.
    //
    ULONG    MechProperties;

    //
    // Current state of reader (card present/removed/activated)
    //
    ULONG     CurrentState;

    //
    // The channel ID the reader uses depending on the type of reader:
    //     - Port number for serial reader
    //    - Port number for par reader
    //    - Scsi id for scsi reader
    //    - 0 for keyboard reader
    //    - device number for USB
    //
    ULONG    Channel;

    //
    // Clock rates in KHz encoded as little endian
    // (I.e. 3.58MHz is encoded as 3580)
    //
    struct {

        ULONG Default;
        ULONG Max;

    } CLKFrequency;

    //
    // Data rates in bps encoded as little endian
    //
    struct {

        ULONG Default;
        ULONG Max;

    } DataRate;

    //
    // Maximum IFSD supported by IFD
    //
    ULONG   MaxIFSD;

    //
    // Type of power management the card supports
    // (0 = IFD does not support power management)
    //
    ULONG   PowerMgmtSupport;

    //
    // Reserved, do not use
    //
    ULONG   Reserved[25];

} SCARD_READER_CAPABILITIES, *PSCARD_READER_CAPABILITIES;

Members

The following members must be maintained by the driver:

SupportedProtocols
Mandatory. Must be set to a bit mask that reflects the protocols that this driver/reader supports (in hardware and software).
ReaderType
Mandatory. The type of this reader.
Type | Meaning
SCARD_READER_TYPE_SERIAL | Serial reader.
SCARD_READER_TYPE_PCMCIA | PCMCIA reader.
SCARD_READER_TYPE_KEYBOARD | Keyboard attached reader.
SCARD_READER_TYPE_USB | USB reader.

CurrentState
Mandatory. Contains the status of the card.
Status | Meaning
SCARD_UNKNOWN | The reader does not know the status.
SCARD_ABSENT | No card is currently inserted.
SCARD_PRESENT | A card is inserted.
SCARD_SWALLOWED | A card is inserted and the reader has swallowed it.
SCARD_POWERED | The card is powered, but the reader does not know its mode.
SCARD_NEGOTIABLE | A card is inserted and awaits protocol negotiation.
SCARD_SPECIFIC | A card is inserted and a protocol has been selected.

MechProperties
Optional. Contains a mask of reader properties combined with the bitwise OR operator:
Property | Meaning
SCARD_READER_SWALLOWS | Reader has a swallowing mechanism.
SCARD_READER_EJECTS | Reader is able to eject the card.
SCARD_READER_CONFISCATES | Reader is able to capture the card.

Channel
Mandatory. Contains the logical channel number according to Part 3 of the Interoperability Specification for ICCs and Personal Computer Systems (see Documents at http://www.smartcardsys.com/).
ClkFrequency.Default
Mandatory. This is the standard clock frequency that the reader runs at, in KHz.
ClkFrequency.Max
Mandatory. This is the maximum clock frequency that the reader can run at, in KHz.
DataRate.Default
Mandatory. This is the standard data rate of the reader, in bps.
DataRate.Max
Mandatory. This is the maximum data rate of the reader, in bps.
MaxIFSD
Mandatory. This is the maximum buffer size of the reader. This value is used to inform the smart card at the beginning of a T=1 transmission about the maximum number of bytes that can be received in one packet.


T1_DATA

The T1_DATA structure is used by the Smart Card Driver Library for processing T1 I/O. It should not be directly modified by a driver.

typedef struct _T1_DATA {

    //
    // Current information field size that can be transmitted
    //
    UCHAR    InfSize;

    //
    // Number of bytes already received from smart card
    //
    ULONG    BytesReceived;

    //
    // Number of bytes already sent to the card;
    //
    ULONG    BytesSent;

    //
    // Total number of bytes still to send
    //
    ULONG    BytesToSend;

    //
    // T1 error code of last received block
    //
    UCHAR    LastError;

    //
    // This is the node address byte to be sent to the card
    //
    UCHAR     NAD;

    //
    // State before error occurred
    //
    ULONG    PrevState;

    //
    // Resend counter
    //
    UCHAR    Resend;

    //
    // Resync counter
    //
    UCHAR    Resynch;

    //
    // The Send Sequence Number is either 0 or 1 as defined in ISO 7816-3
    //
    UCHAR    SSN;

    //
    // Current state of protocol
    //
    ULONG    State;

    //
    // Waiting time extension requested by the smart card
    // This value should be used by the driver to extend block waiting time.
    //
    UCHAR    Wtx;

} T1_DATA, *PT1_DATA;

Members

The following member is important for the driver:

Wtx
Contains the waiting time extension for a T=1 transmission. If nonzero, this is a multiplier for the block waiting time. Usually, the driver should time out if the block waiting time expires. Several smart card operations need longer time, so the smart card answers with a waiting time extension, and therefore the block waiting time must be multiplied with the Wtx value. Note that this value only applies as a waiting extension if the value is nonzero.


SCARD_VENDOR_ATTR

The SCARD_VENDOR_ATTR structure holds all information about the reader. The driver is responsible for filling in all members.

typedef struct _VENDOR_ATTR {

    //
    // Manufacturer name
    //
    struct {

        USHORT Length;
        UCHAR  Buffer[MAXIMUM_ATTR_STRING_LENGTH];
    } VendorName;

    //
    // Name (designation) of reader
    //
    struct {

        USHORT Length;
        UCHAR  Buffer[MAXIMUM_ATTR_STRING_LENGTH];
    } IfdType;

    //
    // If more than one reader of the same type are installed
    // this unit number is used to distinguish these readers
    //
    ULONG    UnitNo;

    //
    // IFD Version number
    //
    struct {

        USHORT  BuildNumber;
        UCHAR   VersionMinor;
        UCHAR   VersionMajor;
    } IfdVersion;

    //
    // IFD Serial number
    //
    struct {

        USHORT Length;
        UCHAR  Buffer[MAXIMUM_ATTR_STRING_LENGTH];
    } IfdSerialNo;

    //
    // Reserved, do not use
    //
    ULONG   Reserved[25];

} VENDOR_ATTR, *PVENDOR_ATTR;

Members

The following members must be maintained by the driver:

VendorName
Mandatory. Contains the ANSI-coded name of the vendor. Since a length field is provided, no terminating NULL character is necessary.
IfdType
Mandatory. Contains the ANSI-coded designation of the reader (that is, the reader name).
UnitNo
Mandatory. This is the zero-based number of this unit. Since it is possible to have more than one reader of this type installed in a system, UnitNo is used to distinguish the readers.
IfdVersion
Optional. The version number of the reader. This member can be used for support purposes. It should be maintained only if the reader allows the value to be queried.
IfdSerialNumber
Optional. The serial number of the connected reader. This field should only be maintained if the reader allows the serial number to be queried.


SMARTCARD_EXTENSION

The SMARTCARD_EXTENSION structure is used by the driver to access all the other smart card data structures, and additional information. This structure is passed to all callback functions.

typedef struct _SMARTCARD_EXTENSION {

    //
    // Version of this structure
    //
    ULONG           Version;

    //
    // Mandatory reader info
    //
    VENDOR_ATTR        VendorAttr;

    //
    // Array of callback reader functions
    //
    NTSTATUS (*ReaderFunction[16])(PSMARTCARD_EXTENSION);

    //
    // Capabilities of the current inserted card
    //
    SCARD_CARD_CAPABILITIES    CardCapabilities;

    //
    // This is used to store the last error of an overlapped operation
    // (Used only for Win9x VxDs)
    //
    ULONG LastError;

    //
    // This structure holds the data of the users IO request
    //
    struct {

        //
        // Number of bytes returned
        //
        PULONG    Information;

        //
        // Pointer to data to send to the card
        //
        PUCHAR    RequestBuffer;

        //
        // Number of bytes to send
        //
        ULONG    RequestBufferLength;

        //
        // Pointer to buffer that receives the answer
        //
        PUCHAR    ReplyBuffer;

        //
        // Size of reply buffer
        //
        ULONG    ReplyBufferLength;

    } IoRequest;

    //
    // Major and minor IO control code for current request
    //
    ULONG    MajorIoControlCode;
    ULONG    MinorIoControlCode;

    //
    // OS dependent data
    //
    POS_DEP_DATA    OsData;

    //
    // Capabilities of the keyboard-reader
    //
    SCARD_READER_CAPABILITIES    ReaderCapabilities;

    //
    // Reader specific data
    //
    PREADER_EXTENSION    ReaderExtension;

    //
    // The reader stores all replies from the card here
    //
    SMARTCARD_REPLY        SmartcardReply;

    //
    // Current command that will be sent to the smart card
    //
    SMARTCARD_REQUEST    SmartcardRequest;

    //
    // Data for T=0
    //
    T0_DATA    T0;

    //
    // Data for T=1
    //
    T1_DATA    T1;

    //
    // Reserved, do not use
    //
    ULONG   Reserved[25];

} SMARTCARD_EXTENSION, *PSMARTCARD_EXTENSION;

Members

OsData
This structure contains information dependent on the driver type.
WDM driver version:
typedef struct _OS_DEP_DATA {

    //
    // Pointer to the device object
    //
    PDEVICE_OBJECT DeviceObject;

    //
    // This is the current Irp to be processed
    //
    PIRP CurrentIrp;

    //
    // Irp to be notified of card insertion/removal
    //
    PIRP NotificationIrp;

    //
    // Used to synchronize access to the driver
    //
    KMUTANT Mutex;

} OS_DEP_DATA, *POS_DEP_DATA;

This structure will be allocated by a call to SmartcardInitialize (WDM). After this call, copy the pointer of your device object to DeviceObject. Otherwise, the Smart Card Driver Library will not work. You cannot use this structure to store driver-dependent information. However, when one of your callback functions is called, CurrentIrp is set to the requesting Irp for every request, except card-tracking requests. For card-tracking requests, NotificationIrp is set to the requesting Irp. See RDF_CARD_TRACKING for more information about card tracking.

VxD driver version:
typedef struct _OS_DEP_DATA {

    //
    // Pointer to the smartcard extension
    //
    PSMARTCARD_EXTENSION SmartcardExtension;

    //
    // Current DiocParams to be processed
    //
    PDIOCPARAMETERS CurrentDiocParams;

    //
    // This overlapped is used for card tracking completion
    //
    OVERLAPPED *NotificationOverlappedData;

    //
    // This is used to synchronize access to the driver
    //
    PVMMMUTEX Mutex;

} OS_DEP_DATA, *POS_DEP_DATA;

This structure will be allocated by a call to SmartcardInitialize (VxD). You cannot use this structure to store driver-dependent information. However, when one of your callback functions is called, CurrentDiocParams is set to the requesting parameters for every request, except card-tracking requests. For card-tracking requests, NotificationOverlappedData is set to the overlapped structure of the caller.


VxD Driver Functions

The following functions can be used when developing VxD drivers.

Function | Description
SmartcardCompleteCardTracking (VxD) | Informs the caller of a card insertion or removal event.
SmartcardCompleteRequest (VxD) | Informs the caller of the completion of a request.
SmartcardCreateLink (VxD) | Creates a registry entry that is used by the smart card resource manager to access a device.
SmartcardDeleteLink (VxD) | Deletes the link that was created with SmartcardCreateLink (VxD).
SmartcardDeviceControl (VxD) | Checks parameters and completes calls that do not require I/O with the reader.
SmartcardExit (VxD) | Frees buffers allocated during a call to SmartcardInitialize (VxD).
SmartcardInitialize (VxD) | Allocates internal buffers for the library.
SmartcardRawReply (VxD) | Copies data from the receive buffer to the user buffer.
SmartcardRawRequest (VxD) | Copies data from the user buffer to the send buffer for transmitting data to the reader.
SmartcardT0Reply (VxD) | Copies data from the receive buffer to the user buffer.
SmartcardT0Request (VxD) | Copies data from the user buffer to the send buffer for transmitting data to the reader.
SmartcardT1Reply (VxD) | Copies data from the receive buffer to the user buffer and checks the T=1 protocol status.
SmartcardT1Request (VxD) | Copies data from the user buffer to the send buffer and checks the T=1 protocol status.
SmartcardUpdateCardCapabilities (VxD) | Translates an ATR string into a SCARD_CARD_CAPABILITIES structure that can be used by the driver.
MapNtStatusToWinError (VxD) | Maps a Microsoft® Windows NT® status code to a Win32® error code.
VxD_CreateDevice (VxD) | Creates a new instance of a device.
VxD_DeleteDevice (VxD) | Deletes a device that was created using VxD_CreateDevice (VxD).

For a list of the functions that can be used when developing WDM drivers, see WDM Driver Functions.


SmartcardCompleteCardTracking (VxD)

The SmartcardCompleteCardTracking function informs the caller of a card insertion or removal event.

VOID
SmartcardCompleteCardTracking(
  IN PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card structure of the driver.

Remarks

Use this function to inform the caller that a smart card has been either inserted or removed. This function automatically unlocks memory that was locked before the callback function RDF_CARD_TRACKING was called. Use this function when your driver detects that a card has been inserted or removed and the structure member SmartcardExtension->OsData->NotificationOverlappedData is not NULL.

This function is not available when developing WDM drivers. For a list of the functions that can be used, see WDM Driver Functions.


SmartcardCompleteRequest (VxD)

The SmartcardCompleteRequest function informs the caller of the completion of a request, unlocks memory, and enables further calls to the smart card library.

VOID
SmartcardCompleteRequest(
  IN PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card structure of the driver.

Remarks

Use this function to inform the caller and the smart card library that a pending smart card I/O has been finished. If your driver is unable to satisfy a request immediately and one of your callbacks returns STATUS_PENDING, you must call this function at the end of the I/O with the reader. Use the structure member SmartcardExtension->IoRequest when you want to access the caller's memory area. This function automatically unlocks memory that was locked before the callback function was called. The following simplified example illustrates the use of this function:

DriverTransmitCallback(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
{
    // Write data to the reader
    WriteDataToReader();

    // The reader will interrupt when data is available
    return STATUS_PENDING;
}

DriverInterrupt(..)
{
    // store incoming data into SmartcardExtension->IoRequest->ReplyBuffer
    ReadDataFromReader();

    // Now we're done with this request and can complete it.
    SmartcardCompleteRequest(SmartcardExtension);
}

This function is not available when developing WDM drivers. For a list of the functions that can be used, see WDM Driver Functions.


SmartcardCreateLink (VxD)

The SmartcardCreateLink function creates a registry entry that is used by the smart card resource manager to access a device.

NTSTATUS
SmartcardCreateLink(
  IN OUT PSTR LinkName,
  IN PSTR DeviceName
);

Parameters

LinkName
Points to a 64-byte area that receives the result.
DeviceName
Points to the name of the device (the name of your VxD) for which the link should be created.

Remarks

This function creates an entry in the registry that the smart card resource manager uses to access the device. The name is usually a string like SCReaderN, where N is a zero-based reader number. This function does not allocate a buffer to hold the link name. It is the responsibility of the driver to provide this 64-byte buffer.

It is strongly recommended that you use this function to create the link to your driver. Otherwise, the smart card resource manager will not be able to access your driver.

For information on the SmartcardCreateLink function for WDM drivers, see SmartcardCreateLink (WDM).


SmartcardDeleteLink (VxD)

The SmartcardDeleteLink function deletes the link that was created with SmartcardCreateLink (VxD).

NTSTATUS
SmartcardDeleteLink(
  IN PSTR LinkName
);

Parameters

LinkName
Points to the name to be removed from the registry.

Remarks

Use this function to remove the link to the driver from the registry when a dynamically loaded driver unloads.

This function is not available when developing WDM drivers. For a list of the functions that can be used, see WDM Driver Functions.


SmartcardDeviceControl (VxD)

The SmartcardDeviceControl function is the main entry function for the smart card driver library. It checks parameters and completes calls that do not require I/O with the reader.

NTSTATUS
SmartcardDeviceControl(
  IN PSMARTCARD_EXTENSION SmartcardExtension,
  IN LPDIOC DiocParams
);

Parameters

SmartcardExtension
Points to the smart card structure of the driver.
DiocParams
Points to the requesting DIOCPARAMETERS structure.

Return Values

SmartcardDeviceControl returns the NTSTATUS value of the called routine.

Remarks

The driver's DeviceControl routine must call this function to let the library check parameters and complete calls that do not need to do I/O with the reader.

The smart card driver library checks the version of the SMARTCARD_EXTENSION structure. Before calling SmartcardDeviceControl, the driver must assign the Version member of SMARTCARD_EXTENSION the value SMCLIB_VERSION. This is usually done in the DriverEntry routine.

A DeviceControl function should look like the following:

DWORD
DriverName_DeviceIoControl(
  DWORD  dwService,
  DWORD  dwDDB,
  DWORD  hDevice,
  LPDIOC lpDiocParms)
)
{
    NTSTATUS status;

    // Let the library check parameters
    // If the library requires the help of the driver it'll call
    // the driver using a call back mechanism
    status = SmartcardDeviceControl(
        &SmartcardExtension,
        lpDiocParams
        );

    return MapNtStatusToWinError(status);
}

For information on the SmartcardDeviceControl function for WDM drivers, see SmartcardDeviceControl (WDM).


SmartcardExit (VxD)

The SmartcardExit function frees buffers that were allocated during a call to SmartcardInitialize (VxD).

VOID
SmartcardExit(
  IN PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Remarks

The library allocates internal buffers during a call to SmartcardInitialize (VxD). SmartcardExit frees these buffers.

SmartcardExit functions the same for WDM and VxD drivers.


SmartcardInitialize (VxD)

The SmartcardInitialize function allocates internal buffers for the library.

NTSTATUS
SmartcardInitialize(
  IN PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.
SmartcardExtension->SmartcardRequest.BufferSize
This value must be set to the number of bytes to be allocated for the request buffer. The minimum size for this buffer is MIN_BUFFER_SIZE. If this value is smaller, MIN_BUFFER_SIZE will be allocated automatically.
SmartcardExtension->SmartcardReply.BufferSize
This value must be set to the number of bytes to be allocated for the receive buffer. The minimum size for this buffer is MIN_BUFFER_SIZE. If this value is smaller, MIN_BUFFER_SIZE will be allocated automatically.

Return Values

SmartcardInitialize returns an NTSTATUS value.

Value | Meaning
STATUS_INSUFFICIENT_RESOURCES | Out of memory

Remarks

The library uses internal buffers for sending SmartcardExtension->SmartcardRequest.Buffer and receiving SmartcardExtension->SmartcardReply.Buffer data. SmartcardInitialize allocates these buffers. Call SmartcardExit_(VxD) in your DriverUnload routine to free these internal buffers. Your driver should use those buffers for transferring data to and from the card.

The smart card driver library checks the version of the SMARTCARD_EXTENSION structure. Before calling SmartcardInitialize, the driver must assign to the Version member of SMARTCARD_EXTENSION the value SMCLIB_VERSION. This is usually done in the DriverEntry routine.

SmartcardInitialize functions the same for WDM and VxD drivers.


SmartcardRawReply (VxD)

The SmartcardRawReply function transfers the data received from the card to the user buffer.

NTSTATUS
SmartcardRawReply(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardRawReply returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

The driver must store the data coming from the reader into SmartcardExtension->SmartcardReply.Buffer and store the number of bytes returned from the card into SmartcardExtension->SmartcardReply.BufferLength. SmartcardRawReply then checks the validity of the data and copies the buffer back to the user buffer, including the protocol header.

SmartcardRawReply functions the same for WDM and VxD drivers.


SmartcardRawRequest (VxD)

The SmartcardRawRequest function copies data from the user buffer to the send buffer that the driver uses to transmit data to the reader.

NTSTATUS
SmartcardRawRequest(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardRawRequest returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Buffer successfully set up.
STATUS_BUFFER_OVERFLOW | The internal buffer is too small to hold the data to send to the smart card. To fix this error, allocate a larger send buffer. See SmartcardInitialize (VxD) for details.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

This function copies data from the user buffer to SmartcardExtension->SmartcardRequest.Buffer and adjusts SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes to be transmitted to the smart card. The driver then simply writes this buffer to the card and reads the bytes coming from the card into SmartcardExtension->SmartcardReply.Buffer, as described in SmartcardRawReply (WDM).

For information on the SmartcardRawRequest function for VxD drivers, see SmartcardRawRequest (VxD).


SmartcardT0Reply (VxD)

The SmartcardT0Reply function transfers the data received from the card to the user buffer.

NTSTATUS
SmartcardT0Reply(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT0Reply returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_DEVICE_PROTOCOL_ERROR | The card did not return a T=0 status word.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

The driver must store the data coming from the reader into SmartcardExtension->SmartcardReply.Buffer and store the number of bytes returned from the card into SmartcardExtension->SmartcardReply.BufferLength. SmartcardT0Reply then checks the validity of the data and copies the buffer back to the user buffer, including the protocol header. See SmartcardT0Request (VxD) for sample code.

SmartcardT0Reply functions the same for WDM and VxD drivers.


SmartcardT0Request (VxD)

The SmartcardT0Request function copies data from the user buffer to the send buffer that the driver uses to transmit data to the reader.

NTSTATUS
SmartcardT0Request(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT0Request returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Buffer successfully set up.
STATUS_BUFFER_OVERFLOW | The internal buffer is too small to hold the data to send to the smart card. To fix this error, allocate a larger send buffer. See SmartcardInitialize for details.

Remarks

This function copies data from the user buffer to SmartcardExtension->SmartcardRequest.Buffer and adjusts SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes to be transmitted to the smart card. The driver then simply writes this buffer to the card and reads the bytes coming from the card into SmartcardExtension->SmartcardReply.Buffer, as described in SmartcardT0Reply (VxD).

If your driver needs to send header data to the reader before the actual T=0 data, set SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes you need for your header before you call this function. The packet will look like this:

You can copy your header data to the buffer either before or after a call to SmartcardT0Request, depending on which is easier to do in your driver.

A usual T=0 transmission can be done in the following way:

// Copy data from user buffer to SmartcardExtension->SmartcardRequest.Buffer
status = SmartcardT0Request(
        SmartcardExtension
        );
if (status != STATUS_SUCCESS)
    return status;

// Transmit SmartcardExtension->SmartcardRequest.Buffer to smart card
status = DriverSendDataToSmartcard(…);
if (status != STATUS_SUCCESS)
return status;

// Receive data from smart card into SmartcardExtension->SmartcardReply.Buffer
status = DriverReceiveDataFromSmartcard(…);
if (status != STATUS_SUCCESS)
    return status;

// Copy data from SmartcardExtension->SmartcardReply.Buffer back to user buffer
// and return to caller
return SmartcardT0Reply(
SmartcardExtension
);

SmartcardT0Reply does not handle the T=0 protocol data exchange for VxD drivers. Refer to the driver example scrcp8t.c, which is part of the Microsoft® Windows NT® DDK, or refer to ISO 7816 part 3, section 8.

For information on the SmartcardT0Request function for WDM drivers, see SmartcardT0Request (WDM).


SmartcardT1Reply (VxD)

The SmartcardT1Reply function copies data from the receive buffer to the user buffer and checks the T=1 protocol status.

NTSTATUS
SmartcardT1Reply(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT1Reply returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_DEVICE_PROTOCOL_ERROR | Too many transmission errors.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.
STATUS_MORE_PROCESSING_REQUIRED | The protocol requires additional transmissions.

Remarks

SmartcardT1Reply must be called after the driver has received data coming from the smart card. The driver must store received smart card data in SmartcardExtension->SmartcardReply.Buffer and the number of received bytes in SmartcardExtension->SmartcardReply.BufferLength. SmartcardT1Reply checks the protocol status and copies any smart card data to the user buffer. If the transmission is not yet finished, SmartcardT1Reply returns STATUS_MORE_PROCESSING_REQUIRED, indicating the necessity to call SmartcardT1Request (VxD) again, which sets up a new buffer to be sent to the smart card.

SmartcardT1Reply functions the same for WDM and VxD drivers.


SmartcardT1Request (VxD)

The SmartcardT1Request function copies data from the user buffer to a send buffer and checks the T=1 protocol status.

NTSTATUS
SmartcardT1Request(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT1Request returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Buffer successfully set up.

Remarks

Do not change any members of the T1_DATA structure. They will be initialized automatically. The only member that can be safely modified is the NAD value. Changing any member might lead to protocol errors.

SmartcardT1Request copies the data from the user buffer to SmartcardExtension->SmartcardRequest.Buffer embedded in a T=1 protocol frame and adjusts SmartcardExtension->SmartcardRequest.BufferLength. The driver must send this buffer to the smart card and read the answer of the card into SmartcardExtension->SmartcardReply.Buffer. The driver must then call SmartcardT1Reply (VxD), which checks the incoming protocol frame.

You can copy your header data to the buffer either before or after a call to SmartcardT1Request, depending on which is easier to do in your driver. If your driver needs to send header data to the reader before the actual T=1 data, you should set SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes you need for your header before you call this function. The packet will look like this:

A usual T=1 transmission can be done in the following way:

// Run this loop as long as the protocol requires to send data
do {
    // Copy data to SmartcardExtension->SmartcardRequest.Buffer
    // embedded in a T=1 frame
    status = SmartcardT1Request(SmartcardExtension);
    if (status != STATUS_SUCCESS)
        return status;

    // Send T=1 frame to smart card
    status = DriverSendDataToSmartcard(…);
    if (status != STATUS_SUCCESS)
        return status;

// Now set appropiate timeout (This example calculates. the time-out in ms)
// Timeout = SmartcardExtension->CardCapabilities.T1.BWT *
//    (SmartcardExtension->T1.Wtx ? SmartcardExtension->T1.Wtx : 1);

    // receive T=1 frame from smart card
    status = DriverReceiveDataFromSmartcard(…);
    if (status != STATUS_SUCCESS)
        return status;

    // Check T=1 protocol status and copy any data back to user buffer
    status = SmartcardT1Reply(SmartcardExtension);

} while (status == STATUS_MORE_PROCESSING_REQUIRED);

return status;

SmartcardT1Request functions the same for WDM and VxD drivers.


SmartcardUpdateCardCapabilities (VxD)

The SmartcardUpdateCardCapabilities function translates an ATR string into the SCARD_CARD_CAPABILITIES structure that can be used by the driver.

NTSTATUS
SmartcardUpdateCardCapabilities(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardUpdateCardCapabilities returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | ATR successfully translated.
STATUS_UNRECOGNIZED_MEDIA | The ATR neither starts with 0x3B nor 0x3F. It is also possible that the ATR contains non-ISO-conforming values for Fl or Dl, or the ATR checksum for T=1 is wrong.

Remarks

This function should be called by the driver just after the driver has read the ATR into the ATR member of the SCARD_CARD_CAPABILITIES structure. The ATR bytes must be stored in Buffer, and Length must be adjusted to the actual length of the ATR returned by the card.

This function can handle only T=0 and T=1 cards.

//
// Answer To Reset string returned by card.
//
struct {
    UCHAR Buffer[64];
    UCHAR Length;
} ATR;

The function converts the ATR string into the values defined by ISO 7816-3. These values are all stored in the SCARD_CARD_CAPABILITIES structure. All time values in that structure are in microseconds, not in seconds.

SmartcardUpdateCardCapabilities functions the same for WDM and VxD drivers.


MapNtStatusToWinError (VxD)

The MapNtStatusToWinError function maps a Microsoft® Windows NT® status code to a Win32® error code.

ULONG
MapNtStatusToWinError(
  NTSTATUS Status
);

Parameters

Status
The Windows NT status value that is to be translated into a Win32 error code.

Return Values

MapNtStatusToWinError returns the translated Win32 error code.

Remarks

Internally, your driver should work with Windows NT status values and not with Win32 error codes. The smart card resource manager, however, needs Win32 error codes. You can use this function in your device I/O control routine to map the Windows NT status value to a Win32 error code. Following is an example:

DWORD
DriverName_DeviceIoControl(
  DWORD  dwService,
  DWORD  dwDDB,
  DWORD  hDevice,
  LPDIOC lpDiocParms)
)
{
    NTSTATUS status;

    // Let the library do parameter checking
    // If the library requires the help of the driver it'll call
    // the driver using a call back mechanism
    status = SmartcardDeviceControl(
        &SmartcardExtension,
        lpDiocParams
        );

    return MapNtStatusToWinError(status);
}

This function is not available when developing WDM drivers. For a list of the functions that can be used, see WDM Driver Functions.


VxD_CreateDevice (VxD)

The VxD_CreateDevice function creates a new instance of a device. This function can be used if your driver supports multiple devices of the same type (for example, serial smart card reader).

PVMMDDB VXDINLINE
VxD_CreateDevice(
  char *Device,
  void (*ControlProc)(void)
);

Parameters

Device
The name of the device to be created. Should not exceed eight characters.
ControlProc
The address of your driver's control procedure (usually located in an assembly language module). Do not confuse this with the driver's DeviceIoControl procedure.

Return Values

VxD_CreateDevice returns a pointer to a device description block.

Remarks

Store the returned device description block in the operating-system-dependent data structure of your device extension. You can use this value in your DeviceIoControl routine to distinguish the device instance, since you should usually use the same DeviceIoControl routine for all your instances.

This function is not available when developing WDM drivers. For a list of the functions that can be used, see WDM Driver Functions.


VxD_DeleteDevice (VxD)

The VxD_DeleteDevice function deletes a device that was created using VxD_CreateDevice (VxD).

BOOL VXDINLINE
VxD_DeleteDevice(
  PVMMDDB DDB
);

Parameters

DDB
The device description block that was returned by a call to VxD_CreateDevice.

Return Values

VxD_DeleteDevice returns TRUE if the device has been successfully deleted.

Remarks

Use this function only in your driver's exit routine to delete all additional device instances.

This function is not available when developing WDM drivers. For a list of the functions that can be used, see WDM Driver Functions.


WDM Driver Functions

The following functions can be used when developing WDM drivers.

Function | Description
SmartcardCreateLink (WDM) | Creates a DOS device name.
SmartcardDeleteLink (WDM) | Deletes the link that was created with SmartcardCreateLink (WDM).
SmartcardDeviceControl (WDM) | Checks parameters and completes calls that do not require I/O with the reader.
SmartcardExit (WDM) | Frees buffers allocated during a call to SmartcardInitialize (WDM).
SmartcardInitialize (WDM) | Allocates internal buffers for the library.
SmartcardLogError (WDM) | Writes an error message to the event log.
SmartcardRawReply (WDM) | Copies data from the receive buffer to the user buffer.
SmartcardRawRequest (WDM) | Copies data from the user buffer to the send buffer for transmitting data to the reader.
SmartcardT0Reply (WDM) | Copies data from the receive buffer to the user buffer.
SmartcardT0Request (WDM) | Copies data from the user buffer to the send buffer for transmitting data to the reader.
SmartcardT1Reply (WDM) | Copies data from the receive buffer to the user buffer and checks the T=1 protocol status.
SmartcardT1Request (WDM) | Copies data from the user buffer to the send buffer and checks the T=1 protocol status.
SmartcardUpdateCardCapabilities (WDM) | Translates an ATR string into a SCARD_CARD_CAPABILITIES structure that can be used by the driver.

For a list of the functions that can be used when developing VxD drivers, see VxD Driver Functions.


SmartcardCreateLink (WDM)

The SmartcardCreateLink function creates a DOS device name that the smart card resource manager uses to access the device.

NTSTATUS
SmartcardCreateLink(
  IN OUT PUNICODE_STRING LinkName,
  IN PUNICODE_STRING DeviceName
);

Parameters

LinkName
Points to an uninitialized UNICODE_STRING that receives the result.
DeviceName
Points to an existing device name for which the link should be created.

Remarks

SmartcardCreateLink creates a DOS device name and a symbolic link that the smart card resource manager can access. The name is usually a string like \DosDevices\SCReaderN, where N is a zero-based reader number. This function allocates a buffer that is large enough to hold the DOS device name. It is not necessary to provide a buffer. When the driver unloads the buffer, LinkName->Buffer must be freed. This function is commonly used in the DriverEntry routine.

For information on the SmartcardCreateLink function for VxD drivers, see SmartcardCreateLink (VxD).


SmartcardDeleteLink (WDM)

The SmartcardDeleteLink function deletes the link that was created with SmartcardCreateLink (WDM).

NTSTATUS
SmartcardDeleteLink(
  IN PUNICODE_STRING LinkName
);

Parameters

LinkName
Points to the name to be removed from the registry.

Remarks

Use this function to remove the link to the driver from the registry when a dynamically loaded driver unloads.

For information on the SmartcardDeleteLink function for VxD drivers, see SmartcardDeleteLink (VxD).


SmartcardDeviceControl (WDM)

The SmartcardDeviceControl function is the main entry function for the smart card driver library. It performs parameter checking and completes calls that do not require I/O with the reader.

NTSTATUS
SmartcardDeviceControl(
  IN PSMARTCARD_EXTENSION SmartcardExtension,
  IN PIRP Irp
);

Parameters

SmartcardExtension
Points to the smart card structure of the driver.
Irp
Points to the requesting IRP.

Return Values

SmartcardDeviceControl returns the NTSTATUS value of the called routine.

Remarks

The driver's DeviceControl routine must call this function to let the library check parameters and complete calls that do not need to do I/O with the reader.

The smart card driver library checks the version of the SMARTCARD_EXTENSION structure. Before calling SmartcardDeviceControl, the driver must assign to the Version member of SMARTCARD_EXTENSION the value SMCLIB_VERSION. This is usually done in the DriverEntry routine.

A DeviceControl function should look like the following:

NTSTATUS
DeviceControl(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp
    )
{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;

    // Let the library check parameters
    // If the library requires the help of the driver it'll call
    // the driver using a call back mechanism
    return SmartcardDeviceControl(
        &(deviceExtension->SmartcardExtension),
        Irp
        );
}

For information on the SmartcardDeviceControl function for VxD drivers, see SmartcardDeviceControl (VxD).


SmartcardExit (WDM)

The SmartcardExit function frees buffers that were allocated during a call to SmartcardInitialize (WDM).

VOID
SmartcardExit(
  IN PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Remarks

The library allocates internal buffers during a call to SmartcardInitialize (WDM). SmartcardExit frees these buffers.

SmartcardExit functions the same for WDM and VxD drivers.


SmartcardInitialize (WDM)

The SmartcardInitialize function allocates internal buffers for the library.

NTSTATUS
SmartcardInitialize(
  IN PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.
SmartcardExtension->SmartcardRequest.BufferSize
This value must be set to the number of bytes to be allocated for the request buffer. The minimum size for this buffer is MIN_BUFFER_SIZE. If this value is smaller, MIN_BUFFER_SIZE will be allocated automatically.
SmartcardExtension->SmartcardReply.BufferSize
This value must be set to the number of bytes to be allocated for the receive buffer. The minimum size for this buffer is MIN_BUFFER_SIZE. If this value is smaller, MIN_BUFFER_SIZE will be allocated automatically.

Return Values

SmartcardInitialize returns an NTSTATUS value.

Value | Meaning
STATUS_INSUFFICIENT_RESOURCES | Out of memory

Remarks

The library uses internal buffers for sending SmartcardExtension->SmartcardRequest.Buffer and receiving SmartcardExtension->SmartcardReply.Buffer data. SmartcardInitialize allocates these buffers. Call SmartcardExit_(WDM) in your DriverUnload routine to free these internal buffers. Your driver should use those buffers for transferring data to and from the card.

The smart card driver library checks the version of the SMARTCARD_EXTENSION structure. Before calling SmartcardInitialize, the driver must assign to the Version member of SMARTCARD_EXTENSION the value SMCLIB_VERSION. This is usually done in the DriverEntry routine.

SmartcardInitialize functions the same for WDM and VxD drivers.


SmartcardLogError (WDM)

The SmartcardLogError function writes an error message to the event log.

VOID
SmartcardLogError(
  IN PVOID Object,
  IN NTSTATUS ErrorCode,
  IN PUNICODE_STRING Insertion,
  IN ULONG DumpData
);

Parameters

Object
Points either to the driver object, before you have created a device object, or to your device object.
ErrorCode
Error code of a function.
Insertion
An insertion string to be written to the event log. Your message file must have a place holder for the insertion. For example, serial port %2 is either not available or used by another device. In this example, %2 will be replaced by the insertion string. Note that %1 is reserved for the file name.
DumpData
A ULONG that appears in the data window of the event log.

Remarks

SmartcardLogError provides a convenient way to write error messages to the system event log. Refer to Preparing Event Logging on Windows NT for information on how to set up event logging.

This function is not available when developing VxD drivers. For a list of the functions that can be used, see VxD Driver Functions.


SmartcardRawReply (WDM)

The SmartcardRawReply function transfers the data received from the card to the user buffer.

NTSTATUS
SmartcardRawReply(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardRawReply returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

The driver must store the data coming from the reader into SmartcardExtension->SmartcardReply.Buffer and store the number of bytes returned from the card into SmartcardExtension->SmartcardReply.BufferLength. SmartcardRawReply then checks the validity of the data and copies the buffer back to the user buffer, including the protocol header.

SmartcardRawReply functions the same for WDM and VxD drivers.


SmartcardRawRequest (WDM)

The SmartcardRawRequest function copies data from the user buffer to the send buffer that the driver uses to transmit data to the reader.

NTSTATUS
SmartcardRawRequest(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardRawRequest returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Buffer successfully set up.
STATUS_BUFFER_OVERFLOW | The internal buffer is too small to hold the data to send to the smart card. To fix this error, allocate a larger send buffer. See SmartcardInitialize (WDM) for details.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

This function copies data from the user buffer to SmartcardExtension->SmartcardRequest.Buffer and adjusts SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes to be transmitted to the smart card. The driver then simply writes this buffer to the card and reads the bytes coming from the card into SmartcardExtension->SmartcardReply.Buffer, as described in SmartcardRawReply (WDM).

For information on the SmartcardRawRequest function for VxD drivers, see SmartcardRawRequest (VxD).


SmartcardT0Reply (WDM)

The SmartcardT0Reply function transfers the data received from the card to the user buffer.

NTSTATUS
SmartcardT0Reply(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT0Reply returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_DEVICE_PROTOCOL_ERROR | The card did not return a T=0 status word.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

The driver must store the data coming from the reader into SmartcardExtension->SmartcardReply.Buffer and store the number of bytes returned from the card into SmartcardExtension->SmartcardReply.BufferLength. SmartcardT0Reply then checks the validity of the data and copies the buffer back to the user buffer, including the protocol header. See SmartcardT0Request (WDM) for sample code.

SmartcardT0Reply functions the same for WDM and VxD drivers.


SmartcardT0Request (WDM)

The SmartcardT0Request function copies data from the user buffer to the send buffer that the driver uses to transmit data to the reader.

NTSTATUS
SmartcardT0Request(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT0Request returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Buffer successfully set up.
STATUS_BUFFER_OVERFLOW | The internal buffer is too small to hold the data to send to the smart card. To fix this error, allocate a larger send buffer. See SmartcardInitialize (WDM) for details.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.

Remarks

This function copies data from the user buffer to SmartcardExtension->SmartcardRequest.Buffer and adjusts SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes to be transmitted to the smart card. The driver then simply writes this buffer to the card and reads the bytes coming from the card into SmartcardExtension->SmartcardReply.Buffer, as described in SmartcardT0Reply (WDM).

If your driver needs to send header data to the reader before the actual T=0 data, you should set SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes you need for your header before you call this function. The packet will look like this:

A usual T=0 transmission can be done in the following way:

// Copy data from user buffer to
SmartcardExtension->SmartcardRequest.Buffer
status = SmartcardT0Request(
        SmartcardExtension
        );
if (status != STATUS_SUCCESS)
    return status;

// Transmit SmartcardExtension->SmartcardRequest.Buffer to smart card
status = DriverSendDataToSmartcard(…);
if (status != STATUS_SUCCESS)
return status;

// Receive data from smart card into
SmartcardExtension->SmartcardReply.Buffer
status = DriverReceiveDataFromSmartcard(…);
if (status != STATUS_SUCCESS)
    return status;

// Copy data from SmartcardExtension->SmartcardReply.Buffer back to user buffer
// and return to caller
return SmartcardT0Reply(
SmartcardExtension
);

For information on the SmartcardT0Request function for VxD drivers, see SmartcardT0Request (VxD).


SmartcardT1Reply (WDM)

The SmartcardT1Reply function copies data from the receive buffer to the user buffer and checks the T=1 protocol status.

NTSTATUS
SmartcardT1Reply(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT1Reply returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_DEVICE_PROTOCOL_ERROR | Too many transmission errors.
STATUS_BUFFER_TOO_SMALL | The user buffer is too small to hold the data.
STATUS_MORE_PROCESSING_REQUIRED | The protocol requires additional transmissions.

Remarks

SmartcardT1Reply must be called after the driver has received data coming from the smart card. The driver must store received smart card data in SmartcardExtension->SmartcardReply.Buffer and the number of received bytes in SmartcardExtension->SmartcardReply.BufferLength. SmartcardT1Reply checks the protocol status and copies any smart card data to the user buffer. If the transmission is not yet finished, SmartcardT1Reply returns STATUS_MORE_PROCESSING_REQUIRED, indicating the necessity to call SmartcardT1Request (WDM) again, which sets up a new buffer to be sent to the smart card.

SmartcardT1Reply functions the same for WDM and VxD drivers.


SmartcardT1Request (WDM)

The SmartcardT1Request function copies data from the user buffer to a send buffer and checks the T=1 protocol status.

NTSTATUS
SmartcardT1Request(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardT1Request returns an NTSTATUS value.

Value | Meaning
STATUS_SUCCESS | Buffer successfully set up.

Remarks

Do not change any members of the T1_DATA structure. They will be initialized automatically. The only member that can be safely modified is the NAD value. Changing of any member might lead to protocol errors.

SmartcardT1Request copies the data from the user buffer to SmartcardExtension->SmartcardRequest.Buffer embedded in a T=1 protocol frame and adjusts SmartcardExtension->SmartcardRequest.BufferLength. The driver must send this buffer to the smart card and read the answer of the card into SmartcardExtension->SmartcardReply.Buffer. The driver must then call SmartcardT1Reply (WDM), which checks the incoming protocol frame.

You can copy your header data to the buffer either before or after a call to SmartcardT1Request, depending on which is easier to do in your driver. If your driver needs to send header data to the reader before the actual T=1 data, you should set SmartcardExtension->SmartcardRequest.BufferLength to the number of bytes you need for your header before you call this function. The packet will look like this:

A usual T=1 transmission can be done in the following way:

// Run this loop as long as the protocol requires to send data
do {
    // Copy data to SmartcardExtension->SmartcardRequest.Buffer
    // embedded in a T=1 frame
    status = SmartcardT1Request(SmartcardExtension);
    if (status != STATUS_SUCCESS)
        return status;

    // Send T=1 frame to smart card
    status = DriverSendDataToSmartcard(…);
    if (status != STATUS_SUCCESS)
        return status;

// Now set appropiate timeout (This example calculates. the time-out in ms)
// Timeout = SmartcardExtension->CardCapabilities.T1.BWT *
//    (SmartcardExtension->T1.Wtx ? SmartcardExtension->T1.Wtx : 1);

    // receive T=1 frame from smart card
    status = DriverReceiveDataFromSmartcard(…);
    if (status != STATUS_SUCCESS)
        return status;

    // Check T=1 protocol status and copy any data back to user buffer
    status = SmartcardT1Reply(SmartcardExtension);

} while (status == STATUS_MORE_PROCESSING_REQUIRED);

return status;

SmartcardT1Request functions the same for WDM and VxD drivers.


SmartcardUpdateCardCapabilities (WDM)

The SmartcardUpdateCardCapabilities function translates an ATR string into the SCARD_CARD_CAPABILITIES structure that can be used by the driver.

NTSTATUS
SmartcardUpdateCardCapabilities(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Return Values

SmartcardUpdateCardCapabilities returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | ATR successfully translated.
STATUS_UNRECOGNIZED_MEDIA | The ATR neither starts with 0x3B nor 0x3F. It is also possible that the ATR contains non-ISO-conforming values for Fl or Dl, or the ATR checksum for T=1 is wrong.

Remarks

This function should be called by the driver just after the driver has read the ATR into the ATR member of the SCARD_CARD_CAPABILITIES structure. The ATR bytes must be stored in Buffer, and Length must be adjusted to the actual length of the ATR returned by the card.

This function can handle only T=0 and T=1 cards.

//
// Answer To Reset string returned by card.
//
struct {
    UCHAR Buffer[64];
    UCHAR Length;
} ATR;

The function converts the ATR string into the values defined by ISO 7816-3. These values are all stored in the SCARD_CARD_CAPABILITIES structure. All time values in that structure are in microseconds, not in seconds.

SmartcardUpdateCardCapabilities functions the same for WDM and VxD drivers.


RDF_CARD_POWER (Mandatory)

The RDF_CARD_POWER callback function resets or powers down an inserted smart card.

NTSTATUS
(*ReaderFunction[RDF_CARD_POWER])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values

SmartcardExtension->MajorIoControlCode
Contains IOCTL_SMARTCARD_POWER.
SmartcardExtension->MinorIoControlCode
Contains one of the following minor codes, depending on the function to be performed.
Minor Code | Meaning
SCARD_COLD_RESET | Performs a cold reset of the card.
SCARD_WARM_RESET | Performs a warm reset of the card.
SCARD_POWER_DOWN | Switches off card power.

SmartcardExtension->IoRequest.ReplyBufferLength
Contains the length of the reply buffer.

Output Values

SmartcardExtension->IoRequest.ReplyBuffer
This buffer receives the ATR returned by the card. In addition, you must transfer the ATR to SmartcardExtension->CardCapabilities.ATR.Buffer to let the library parse the ATR.
SmartcardExtension->IoRequest.Information
Receives the actual length of the ATR. In addition you must transfer the length of the ATR to SmartcardExtension->CardCapabilities.ATR.Length.

Return Values

This function returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Function successfully executed.
STATUS_NO_MEDIA | No card is in the reader.
STATUS_IO_TIMEOUT | The request has timed out.
STATUS_BUFFER_TOO_SMALL | The user buffer is not large enough to hold the ATR.


RDF_CARD_EJECT (Optional)

The RDF_CARD_EJECT callback function ejects an inserted smart card.

NTSTATUS
(*ReaderFunction[RDF_CARD_EJECT])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values

SmartcardExtension->MajorIoControlCode
Contains IOCTL_SMARTCARD_EJECT.

Return Values

This function returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Function successfully executed.
STATUS_NO_MEDIA | No card is in the reader.
STATUS_IO_TIMEOUT | The request has timed out.


RDF_CARD_TRACKING (Mandatory)

WDM driver version:

The RDF_CARD_TRACKING callback function installs an event handler to track card insertions and removals.

NTSTATUS
(*ReaderFunction[RDF_CARD_TRACKING])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values for WDM Device Drivers

SmarcardExtension->OsData->NotificationIrp
Contains the IRP that is to be informed of the insertion/removal event.

Input Values for VxD device Drivers

SmarcardExtension->OsData->NotificationOverlappedData
Points to the overlapped structure of the caller to be informed of the insertion/removal event.

Return Values

This function returns an NTSTATUS value. Possible values for WDM and VxD device drivers are the following.

Value | Meaning
STATUS_PENDING | Card tracking has been started.
STATUS_INVALID_DEVICE_STATE | The device cannot accept the request.
STATUS_SUCCESS | Card status matches the requested tracking call.
STATUS_DEVICE_BUSY | A card tracking event is already pending.

Remarks for WDM Device Drivers

Before the library calls RDF_CARD_TRACKING, it checks if the status already matches the current card status. (That is, a card is inserted and the caller sends an IOCTL_SMARTCARD_IS_PRESENT code.) In this case, the library returns STATUS_SUCCESS without calling this function.

Otherwise, the driver will be called and it should start card tracking. The smart card library fills SmarcardExtension->OsData->NotificationIrp in its extension because this is the IRP that will be informed of insertions or removals. Usually, the driver returns STATUS_PENDING to this call since the current card status does not match the status to check for. The driver must complete this call as soon as it detects the insertion or removal. This is done by a call to IoCompleteRequest. After the call to IoCompleteRequest, you must set the member NotificationIrp back to NULL. This tells the smart card library that your driver can accept further card-tracking requests.

Note It is important to mark this IRP as cancelable, because this call can be of an indefinite duration and the caller can terminate before this call can be satisfied.

Remarks for VxD Device Drivers

Before the library calls RDF_CARD_TRACKING, it checks if the status already matches the current card status. (That is, a card is inserted and the caller sends an IOCTL_SMARTCARD_IS_PRESENT code.) In this case, the library returns STATUS_SUCCESS without calling this function. Otherwise, the driver will be called and it should start card tracking.

Note Since this function will be called only when the current card status is the opposite of the status the caller wants to be informed of, your driver only needs to return STATUS_PENDING. In your driver function that is used to supervise the card, use the structure member OsData->NotificationOverlappedData and check it for a non-NULL value. If the value is non-NULL, call SmartcardCompleteCardTracking (VxD) to inform the caller of the card insertion/removal event.

Following is some sample code:

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

        SmartcardCompleteCardTracking(SmartcardExtension);
    }
    //
    // Do additional tasks
    //
}


RDF_IOCTL_VENDOR (Optional)

The RDF_IOCTL_VENDOR callback function performs vendor-specific IOCTL operations.

NTSTATUS
(*ReaderFunction[RDF_IOCTL_VENDOR])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values

SmartcardExtension->MajorIoControlCode
Contains a vendor-specific IOCTL code. Refer to the macro SCARD_CTL_CODE in winsmcrd.h for information on how to define a vendor-specific IOCTL code. Note that the code must be between 2048 and 4095.
SmartcardExtension->IoRequest.RequestBuffer
Points to the user's input buffer.
SmartcardExtension->IoRequest.RequestBufferLength
The size of the user's input buffer.
SmartcardExtension->IoRequest.ReplyBuffer
Points to the user's output buffer.
SmartcardExtension->IoRequest.ReplyBufferLength
The size of the user's output buffer.

Output Values

SmartcardExtension->IoRequest.Information
Must be set to the number of bytes returned.

Return Values

This function returns an NTSTATUS value. The value returned depends upon the function performed, since RDF_IOCTL_VENDOR is a vendor-defined IOCTL call. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Function successfully executed.
STATUS_NO_MEDIA | No card is in the reader.
STATUS_IO_TIMEOUT | The request has timed out.
STATUS_BUFFER_TOO_SMALL | The user's reply buffer is too small.
STATUS_INVALID_DEVICE_REQUEST | The request is not valid for this IOCTL.
STATUS_PENDING | The operation is pending.


RDF_READER_SWALLOW (Optional)

The RDF_READER_SWALLOW callback function does a mechanical swallow.

NTSTATUS
(*ReaderFunction[RDF_READER_SWALLOW])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values

SmartcardExtension->MajorIoControlCode
Contains IOCTL_SMARTCARD_SWALLOW.

Return Values

This function returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Function successfully executed.
STATUS_NO_MEDIA | No card is in the reader.
STATUS_IO_TIMEOUT | The request has timed out.


RDF_SET_PROTOCOL (Mandatory)

The RDF_SET_PROTOCOL callback function selects a transmission protocol for the currently inserted card.

NTSTATUS
(*ReaderFunction[RDF_SET_PROTOCOL])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values

SmartcardExtension->MajorIoControlCode
Contains IOCTL_SMARTCARD_SET_PROTOCOL.
SmartcardExtension->MinorIoControlCode
Contains a mask of protocols combined with the bitwise OR operator that the caller accepts for further transmissions.
Value | Meaning
SCARD_PROTOCOL_RAW | Selects raw protocol.
SCARD_PROTOCOL_T0 | Selects the ISO T=0 protocol.
SCARD_PROTOCOL_T1 | Selects the ISO T=1 protocol.
SCARD_PROTOCOL_DEFAULT | Do not do PTS selection even if the card only supports one protocol.
SCARD_PROTOCOL_OPTIMAL | Do PTS selection.

SmartcardExtension->IoRequest.ReplyBufferLength
Contains the length of the reply buffer.

Output Values

SmartcardExtension->IoRequest.ReplyBuffer
This buffer receives the selected protocol.
SmartcardExtension->IoRequest.Information
Set to sizeof(ULONG).

Remarks

The caller can supply a mask of protocols that it accepts. It is the driver's decision to select one protocol out of the mask. After the driver has selected a protocol, it must return the selected protocol in SmartcardExtension->IoRequest.ReplyBuffer.

Return Values

This function returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | A protocol was successfully selected.
STATUS_NO_MEDIA | No card is in the reader.
STATUS_IO_TIMEOUT | The request has timed out.
STATUS_BUFFER_TOO_SMALL | The user buffer is not large enough to hold a ULONG.
STATUS_INVALID_DEVICE_STATE | The reader is not in the correct state to select a protocol. This is the case when a card is inserted, but not reset.
STATUS_INVALID_DEVICE_REQUEST | The mask contains an unknown protocol.


RDF_TRANSMIT (Mandatory)

The RDF_TRANSMIT callback function performs data transmissions.

NTSTATUS
(*ReaderFunction[RDF_TRANSMIT])(
  PSMARTCARD_EXTENSION SmartcardExtension
);

Parameters

SmartcardExtension
Points to the smart card extension of the device.

Input Values

SmartcardExtension->MajorIoControlCode
Contains IOCTL_SMARTCARD_TRANSMIT.
SmartcardExtension->IoRequest.RequestBuffer
Points to an SCARD_IO_REQUEST structure followed by data to be transmitted to the card.
SmartcardExtension->IoRequest.RequestBufferLength
The number of bytes to be transmitted to the card.
SmartcardExtension->IoRequest.ReplyBufferLength
The size of the reply buffer.

Output Values

SmartcardExtension->IoRequest.ReplyBuffer
Points to the buffer that receives the SCARD_IO_REQUEST structure, plus the result of the card.
SmartcardExtension->IoRequest.Information
Receives the actual number of bytes returned by the card, plus the size of SCARD_IO_REQUEST structure.

Remarks

When this function is called, SmartcardExtension->IoRequest.RequestBuffer points to a SCARD_IO_REQUEST structure followed by data to be transmitted:

typedef struct _SCARD_IO_REQUEST{
    DWORD dwProtocol;   // Protocol identifier
    DWORD cbPciLength;  // Protocol Control Information Length
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;

The dwProtocol member must contain the protocol identifier that was returned by a call to IOCTL_SMARTCARD_SET_PROTOCOL.

The cbPciLength member contains the size of this structure, which is usually eight. This structure will be used mainly for future implementations.

The structure is followed by (protocol) data to be transmitted to the card. Depending on the protocol to be used for this transmission, the library offers several support functions. See SmartcardT0Request (WDM), SmartcardT0Request (VxD), and SmartcardT1Request (WDM), SmartcardT1Request (VxD).

Note RequestBuffer and ReplyBuffer point to the same system buffer. If you use the library function SmartcardxxRequest and SmartcardxxReply, you do not have to worry that you might overwrite the input buffer. If you do not use these functions, make a copy of the RequestBuffer before you start transmissions.

The implementation requires you to copy the SCARD_IO_REQUEST structure to the ReplyBuffer, followed by the data received from the card. Again, if you use the SmartcardxxRequest and SmartcardxxReply functions, you do not need to copy the structure because the library does this.

Return Values

This function returns an NTSTATUS value. Possible values are the following.

Value | Meaning
STATUS_SUCCESS | Transmission successful.
STATUS_NO_MEDIA | No card is in the reader.
STATUS_IO_TIMEOUT | The request has timed out.
STATUS_INVALID_DEVICE_REQUEST | The protocol defined by dwProtocol is invalid.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.