pcsc-lite project is hosted at http://pcsclite.alioth.debian.org/pcsclite.html

The pcsc-lite project uses the BSD 3-clauses license. This license
should be compatible with the TianoCore Contribution Agreement 1.0 (but
I am not a lawyer).

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ludovic Rousseau <ludovic.rouss...@gmail.com>
---
 MdeModulePkg/Library/SmartCardReader/ifdhandler.h | 825 ++++++++++++++++++++++
 MdeModulePkg/Library/SmartCardReader/misc.h       |  88 +++
 MdeModulePkg/Library/SmartCardReader/pcsclite.h   |  65 ++
 MdeModulePkg/Library/SmartCardReader/reader.h     | 285 ++++++++
 MdeModulePkg/Library/SmartCardReader/wintypes.h   | 120 ++++
 5 files changed, 1383 insertions(+)
 create mode 100644 MdeModulePkg/Library/SmartCardReader/ifdhandler.h
 create mode 100644 MdeModulePkg/Library/SmartCardReader/misc.h
 create mode 100644 MdeModulePkg/Library/SmartCardReader/pcsclite.h
 create mode 100644 MdeModulePkg/Library/SmartCardReader/reader.h
 create mode 100644 MdeModulePkg/Library/SmartCardReader/wintypes.h

diff --git a/MdeModulePkg/Library/SmartCardReader/ifdhandler.h 
b/MdeModulePkg/Library/SmartCardReader/ifdhandler.h
new file mode 100644
index 0000000..f47e018
--- /dev/null
+++ b/MdeModulePkg/Library/SmartCardReader/ifdhandler.h
@@ -0,0 +1,825 @@
+/*
+ * MUSCLE SmartCard Development ( 
http://pcsclite.alioth.debian.org/pcsclite.html )
+ *
+ * Copyright (C) 1999-2004
+ *  David Corcoran <corco...@musclecard.com>
+ * Copyright (C) 2003-2004
+ *  Damien Sauveron <damien.sauve...@labri.fr>
+ * Copyright (C) 2002-2011
+ *  Ludovic Rousseau <ludovic.rouss...@free.fr>
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: ifdhandler.h 6965 2014-09-01 14:52:42Z rousseau $
+ */
+
+/**
+ * @file
+ * @defgroup IFDHandler IFDHandler
+ * @brief This provides reader specific low-level calls.
+
+The routines specified hereafter will allow you to write an IFD handler
+for the PC/SC Lite resource manager. Please use the complement
+developer's kit complete with headers and Makefile at:
+http://www.musclecard.com/drivers.html
+
+This gives a common API for communication to most readers in a
+homogeneous fashion. This document assumes that the driver developer is
+experienced with standards such as ISO-7816-(1, 2, 3, 4), EMV and MCT
+specifications. For listings of these specifications please access the
+above web site.
+
+@section UsbReaders USB readers
+
+USB readers use the bundle approach so that the reader can be loaded
+and unloaded upon automatic detection of the device. The bundle
+approach is simple: the actual library is just embedded in a
+directory so additional information can be gathered about the device.
+
+A bundle looks like the following:
+
+@verbatim
+GenericReader.bundle/
+  Contents/
+    Info.plist  - XML file describing the reader
+    MacOS/      - Driver directory for OS X
+    Solaris/    - Driver directory for Solaris
+    Linux/      - Driver directory for Linux
+    HPUX/       - Driver directory for HPUX
+@endverbatim
+
+The @c Info.plist file describes the driver and gives the loader
+all the necessary information. The following must be contained in the
+@c Info.plist file:
+
+@subsection ifdVendorID
+
+The vendor ID of the USB device.
+
+Example:
+
+@verbatim
+    <key>ifdVendorID</key>
+    <string>0x04E6</string>
+@endverbatim
+
+You may have an OEM of this reader in which an additional @c <string>
+can be used like in the below example:
+
+@verbatim
+    <key>ifdVendorID</key>
+    <array>
+      <string>0x04E6</string>
+      <string>0x0973</string>
+    </array>
+@endverbatim
+
+If multiples exist all the other parameters must have a second value
+also. You may chose not to support this feature but it is useful when
+reader vendors OEM products so you only distribute one driver.
+
+
+The CCID driver from Ludovic Rousseau
+http://pcsclite.alioth.debian.org/ccid.html uses this feature since the
+same driver supports many different readers.
+
+@subsection ifdProductID
+
+   The product id of the USB device.
+
+@verbatim
+   <key>ifdProductID</key>
+   <string>0x3437</string>
+@endverbatim
+
+@subsection ifdFriendlyName
+
+   Example:
+
+@verbatim
+   <key>ifdFriendlyName</key>
+   <string>SCM Microsystems USB Reader</string>
+@endverbatim
+
+@subsection CFBundleExecutable
+
+   The executable name which exists in the particular platform's directory.
+
+   Example:
+
+@verbatim
+   <key>CFBundleExecutable</key>
+   <string>libccid.so.0.4.2</string>
+@endverbatim
+
+@subsection ifdCapabilities
+
+   List of capabilities supported by the driver. This is a bit field. Possible 
values are:
+
+- 0
+  No special capabilities
+- 1 IFD_GENERATE_HOTPLUG
+  The driver supports the hot plug feature.
+
+Complete sample file:
+
+@verbatim
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+    "http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
+<plist version="1.0">
+<dict>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>English</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundlePackageType</key>
+    <string>BNDL</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>CFBundleVersion</key>
+    <string>0.0.1d1</string>
+    <key>ifdCapabilities</key>
+    <string>0x00000000</string>
+    <key>ifdProtocolSupport</key>
+    <string>0x00000001</string>
+    <key>ifdVersionNumber</key>
+    <string>0x00000001</string>
+
+    <key>CFBundleExecutable</key>
+    <string>libfoobar.so.x.y</string>
+
+    <key>ifdManufacturerString</key>
+    <string>Foo bar inc.</string>
+
+    <key>ifdProductString</key>
+    <string>Driver for Foobar reader, version x.y</string>
+
+    <key>ifdVendorID</key>
+    <string>0x1234</string>
+
+    <key>ifdProductID</key>
+    <string>0x5678</string>
+
+    <key>ifdFriendlyName</key>
+    <string>Foobar USB reader</string>
+</dict>
+</plist>
+@endverbatim
+
+As indicated in the XML file the DTD is available at
+http://www.apple.com/DTDs/PropertyList-1.0.dtd.
+
+@section SerialReaders Serial readers
+
+Serial drivers must be configured to operate on a particular port and
+respond to a particular name. The @c reader.conf file is used for this
+purpose.
+
+It has the following syntax:
+
+@verbatim
+# Configuration file for pcsc-lite
+# David Corcoran <corco...@musclecard.com>
+
+FRIENDLYNAME  Generic Reader
+DEVICENAME    /dev/ttyS0
+LIBPATH       /usr/lib/pcsc/drivers/libgen_ifd.so
+CHANNELID     1
+@endverbatim
+
+The pound sign # denotes a comment.
+
+@subsection FRIENDLYNAME
+The FRIENDLYNAME field is an arbitrary text used to identify the reader.
+This text is displayed by commands like @c pcsc_scan
+http://ludovic.rousseau.free.fr/softwares/pcsc-tools/ that prints the
+names of all the connected and detected readers.
+
+@subsection DEVICENAME
+The DEVICENAME field was not used for old drivers (using the IFD handler
+version 2.0 or previous). It is now (IFD handler version 3.0) used to
+identify the physical port on which the reader is connected.  This is
+the device name of this port. It is dependent of the OS kernel. For
+example the first serial port device is called @c /dev/ttyS0 under Linux
+and @c /dev/cuaa0 under FreeBSD.
+
+If you want to use IFDHCreateChannel() instead of
+IFDHCreateChannelByName() then do not use any DEVICENAME line in the
+configuration file.  IFDHCreateChannel() will then be called with the
+CHANNELID parameter.
+
+@subsection LIBPATH
+The LIBPATH field is the filename of the driver code. The driver is a
+dynamically loaded piece of code (generally a @c drivername.so* file).
+
+@subsection CHANNELID
+The CHANNELID is no more used for recent drivers (IFD handler 3.0) and
+has been superseded by DEVICENAME.
+
+If you have an old driver this field is used to indicate the port to
+use. You should read your driver documentation to know what information
+is needed here. It should be the serial port number for a serial reader.
+
+CHANNELID was the numeric version of the port in which the reader will
+be located. This may be done by a symbolic link where @c /dev/pcsc/1 is
+the first device which may be a symbolic link to @c /dev/ttyS0 or
+whichever location your reader resides.
+
+ */
+
+#ifndef _ifd_handler_h_
+#define _ifd_handler_h_
+
+#include <wintypes.h>
+#define MAX_ATR_SIZE 33 /* from pcsclite.h */
+
+       /*
+        * List of data structures available to ifdhandler
+        */
+       typedef struct _DEVICE_CAPABILITIES
+       {
+               LPSTR Vendor_Name;              /**< Tag 0x0100 */
+               LPSTR IFD_Type;                 /**< Tag 0x0101 */
+               DWORD IFD_Version;              /**< Tag 0x0102 */
+               LPSTR IFD_Serial;               /**< Tag 0x0103 */
+               DWORD IFD_Channel_ID;   /**< Tag 0x0110 */
+
+               DWORD Asynch_Supported; /**< Tag 0x0120 */
+               DWORD Default_Clock;    /**< Tag 0x0121 */
+               DWORD Max_Clock;                /**< Tag 0x0122 */
+               DWORD Default_Data_Rate;        /**< Tag 0x0123 */
+               DWORD Max_Data_Rate;    /**< Tag 0x0124 */
+               DWORD Max_IFSD;                 /**< Tag 0x0125 */
+               DWORD Synch_Supported;  /**< Tag 0x0126 */
+               DWORD Power_Mgmt;               /**< Tag 0x0131 */
+               DWORD Card_Auth_Devices;        /**< Tag 0x0140 */
+               DWORD User_Auth_Device; /**< Tag 0x0142 */
+               DWORD Mechanics_Supported;      /**< Tag 0x0150 */
+               DWORD Vendor_Features;  /**< Tag 0x0180 - 0x01F0 User Defined. 
*/
+       }
+       DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
+
+       typedef struct _ICC_STATE
+       {
+               UCHAR ICC_Presence;             /**< Tag 0x0300 */
+               UCHAR ICC_Interface_Status;     /**< Tag 0x0301 */
+               UCHAR ATR[MAX_ATR_SIZE];        /**< Tag 0x0303 */
+               UCHAR ICC_Type;                 /**< Tag 0x0304 */
+       }
+       ICC_STATE, *PICC_STATE;
+
+       typedef struct _PROTOCOL_OPTIONS
+       {
+               DWORD Protocol_Type;    /**< Tag 0x0201 */
+               DWORD Current_Clock;    /**< Tag 0x0202 */
+               DWORD Current_F;                /**< Tag 0x0203 */
+               DWORD Current_D;                /**< Tag 0x0204 */
+               DWORD Current_N;                /**< Tag 0x0205 */
+               DWORD Current_W;                /**< Tag 0x0206 */
+               DWORD Current_IFSC;             /**< Tag 0x0207 */
+               DWORD Current_IFSD;             /**< Tag 0x0208 */
+               DWORD Current_BWT;              /**< Tag 0x0209 */
+               DWORD Current_CWT;              /**< Tag 0x020A */
+               DWORD Current_EBC;              /**< Tag 0x020B */
+       }
+       PROTOCOL_OPTIONS, *PPROTOCOL_OPTIONS;
+
+       /**
+        * Use by SCardTransmit()
+        */
+       typedef struct _SCARD_IO_HEADER
+       {
+               DWORD Protocol;
+               DWORD Length;
+       }
+       SCARD_IO_HEADER, *PSCARD_IO_HEADER;
+
+       /*
+        * The list of tags should be alot more but this is all I use in the
+        * meantime
+        */
+#define TAG_IFD_ATR                     0x0303 /**< ATR */
+#define TAG_IFD_SLOTNUM                 0x0180 /**< select a slot */
+#define TAG_IFD_SLOT_THREAD_SAFE        0x0FAC /**< support access to 
different slots of the reader */
+#define TAG_IFD_THREAD_SAFE             0x0FAD /**< driver is thread safe */
+#define TAG_IFD_SLOTS_NUMBER            0x0FAE /**< number of slots of the 
reader */
+#define TAG_IFD_SIMULTANEOUS_ACCESS     0x0FAF /**< number of reader the 
driver can manage */
+#define TAG_IFD_POLLING_THREAD          0x0FB0 /**< not used. See 
TAG_IFD_POLLING_THREAD_WITH_TIMEOUT */
+#define TAG_IFD_POLLING_THREAD_KILLABLE 0x0FB1 /**< the polling thread can be 
killed */
+#define TAG_IFD_STOP_POLLING_THREAD     0x0FB2 /**< method used to stop the 
polling thread (instead of just pthread_kill()) */
+#define TAG_IFD_POLLING_THREAD_WITH_TIMEOUT 0x0FB3     /**< driver uses a 
polling thread with a timeout parameter */
+
+       /*
+        * IFD Handler version number enummerations
+        */
+#define IFD_HVERSION_1_0               0x00010000
+#define IFD_HVERSION_2_0               0x00020000
+#define IFD_HVERSION_3_0               0x00030000
+
+       /*
+        * List of defines available to ifdhandler
+        */
+#define IFD_POWER_UP                   500 /**< power up the card */
+#define IFD_POWER_DOWN                 501 /**< power down the card */
+#define IFD_RESET                      502 /**< warm reset */
+
+#define IFD_NEGOTIATE_PTS1             1   /**< negotiate PTS1 */
+#define IFD_NEGOTIATE_PTS2             2   /**< negotiate PTS2 */
+#define IFD_NEGOTIATE_PTS3              4   /**< negotiate PTS3 */
+
+#define        IFD_SUCCESS                     0   /**< no error */
+#define IFD_ERROR_TAG                  600 /**< tag unknown */
+#define IFD_ERROR_SET_FAILURE          601 /**< set failed */
+#define IFD_ERROR_VALUE_READ_ONLY      602 /**< value is read only */
+#define IFD_ERROR_PTS_FAILURE          605 /**< failed to negotiate PTS */
+#define IFD_ERROR_NOT_SUPPORTED                606
+#define IFD_PROTOCOL_NOT_SUPPORTED     607 /**< requested protocol not 
supported */
+#define IFD_ERROR_POWER_ACTION         608 /**< power up failed */
+#define IFD_ERROR_SWALLOW              609
+#define IFD_ERROR_EJECT                        610
+#define IFD_ERROR_CONFISCATE           611
+#define IFD_COMMUNICATION_ERROR                612 /**< generic error */
+#define IFD_RESPONSE_TIMEOUT           613 /**< timeout */
+#define IFD_NOT_SUPPORTED              614 /**< request is not supported */
+#define IFD_ICC_PRESENT                        615 /**< card is present */
+#define IFD_ICC_NOT_PRESENT            616 /**< card is absent */
+/**
+ * The \ref IFD_NO_SUCH_DEVICE error must be returned by the driver when
+ * it detects the reader is no more present. This will tell pcscd to
+ * remove the reader from the list of available readers.
+ */
+#define IFD_NO_SUCH_DEVICE             617
+#define IFD_ERROR_INSUFFICIENT_BUFFER  618 /**< buffer is too small */
+
+#ifndef RESPONSECODE_DEFINED_IN_WINTYPES_H
+       typedef long RESPONSECODE;
+#endif
+
+       /*
+        * If you want to compile a V2.0 IFDHandler, define IFDHANDLERv2
+        * before you include this file.
+        *
+        * By default it is setup for for most recent version of the API (V3.0)
+        */
+
+#ifndef IFDHANDLERv2
+
+       /*
+        * List of Defined Functions Available to IFD_Handler 3.0
+        *
+        * All the functions of IFD_Handler 2.0 are available
+        * IFDHCreateChannelByName() is new
+        * IFDHControl() API changed
+        */
+
+/**
+This function is required to open a communications channel to the port
+listed by @p DeviceName.
+
+Once the channel is opened the reader must be in a state in which it is
+possible to query IFDHICCPresence() for card status.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number\n
+  Use this for multiple card slots or multiple readers. 0xXXXXYYYY -
+  XXXX multiple readers, YYYY multiple slots. The resource manager will
+  set these automatically. By default the resource manager loads a new
+  instance of the driver so if your reader does not have more than one
+  smart card slot then ignore the Lun in all the functions.\n
+  \n
+  PC/SC supports the loading of multiple readers through one instance of
+  the driver in which XXXX is important. XXXX identifies the unique
+  reader in which the driver communicates to. The driver should set up
+  an array of structures that asociate this XXXX with the underlying
+  details of the particular reader.
+
+@param[in] DeviceName Filename to use by the driver.\n
+  For drivers configured by @p /etc/reader.conf this is the value of the
+  field \ref DEVICENAME.
+  \n
+  For USB drivers the @p DeviceName must start with @p usb:VID/PID. VID
+  is the Vendor ID and PID is the Product ID. Both are a 4-digits hex
+  number.
+
+Typically the string is generated by:
+
+@code
+printf("usb:%04x/%04x", idVendor, idProduct);
+@endcode
+
+The @p DeviceName string may also contain a more specialised
+identification string. This additional information is used to
+differentiate between two identical readers connected at the same time.
+In this case the driver can't differentiate the two readers using VID
+and PID and must use some additional information identifying the USB
+port used by each reader.
+
+- libusb
+
+  For USB drivers using libusb-1.0 http://libusb.sourceforge.net/ for USB
+  abstraction the @p DeviceName the string may be generated by:
+
+  @code
+  printf("usb:%04x/%04x:libusb-1.0:%d:%d:%d",
+    idVendor, idProduct, bus_number, device_address, interface)
+  @endcode
+
+  So it is something like: <tt>usb:08e6/3437:libusb-1.0:7:99:0</tt> under
+  GNU/Linux.
+
+- libudev
+
+  If pcscd is compiled with libudev support instead of libusb (default
+  since pcsc-lite 1.6.8) the string will look like:
+
+  @code
+  printf("usb:%04x/%04x:libudev:%d:%s", idVendor, idProduct,
+               bInterfaceNumber, devpath);
+  @endcode
+
+  bInterfaceNumber is the number of the interface on the device. It is
+  only usefull for devices with more than one CCID interface.
+
+  devpath is the filename of the device on the file system.
+
+  So it is something like:
+  <tt>usb:08e6/3437:libudev:0:/dev/bus/usb/008/047</tt>
+  under GNU/Linux.
+
+- other
+
+  If the driver does not understand the <tt>:libusb:</tt> or
+  <tt>:libudev:</tt> scheme or if a new scheme is used, the driver should
+  ignore the part it does not understand instead of failing.
+
+  The driver shall recognize the <tt>usb:VID/PID</tt> part and, only if
+  possible, the remaining of the DeviceName field.
+
+  It is the responsibility of the driver to correctly identify the reader.
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+  */
+RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR DeviceName);
+
+/**
+This function performs a data exchange with the reader (not the card)
+specified by Lun. It is responsible for abstracting functionality such
+as PIN pads, biometrics, LCD panels, etc. You should follow the MCT and
+CTBCS specifications for a list of accepted commands to implement. This
+function is fully voluntary and does not have to be implemented unless
+you want extended functionality.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+@param[in] dwControlCode Control code for the operation\n
+  This value identifies the specific operation to be performed. This
+  value is driver specific.
+@param[in] TxBuffer Transmit data
+@param[in] TxLength Length of this buffer
+@param[out] RxBuffer Receive data
+@param[in] RxLength Length of the response buffer
+@param[out] pdwBytesReturned Length of response\n
+  This function will be passed the length of the buffer RxBuffer in
+  RxLength and it must set the length of the received data in
+  pdwBytesReturned.
+
+@note
+  @p *pdwBytesReturned should be set to zero on error.
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_RESPONSE_TIMEOUT The response timed out (\ref IFD_RESPONSE_TIMEOUT)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, PUCHAR
+       TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength,
+       LPDWORD pdwBytesReturned);
+
+#else
+
+/**
+ * Available in IFD_Handler 2.0
+ *
+ * @deprecated
+ * You should use the new form of IFDHControl()
+ */
+RESPONSECODE IFDHControl(DWORD Lun, PUCHAR TxBuffer, DWORD TxLength,
+       PUCHAR RxBuffer, PDWORD RxLength);
+
+#endif
+
+       /*
+        * common functions in IFD_Handler 2.0 and 3.0
+        */
+/**
+This function is required to open a communications channel to the port
+listed by Channel. For example, the first serial reader on COM1 would
+link to @p /dev/pcsc/1 which would be a symbolic link to @p /dev/ttyS0
+on some machines This is used to help with inter-machine independence.
+
+On machines with no /dev directory the driver writer may choose to map
+their Channel to whatever they feel is appropriate.
+
+Once the channel is opened the reader must be in a state in which it is
+possible to query IFDHICCPresence() for card status.
+
+USB readers can ignore the @p Channel parameter and query the USB bus
+for the particular reader by manufacturer and product id.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number\n
+  Use this for multiple card slots or multiple readers. 0xXXXXYYYY -
+  XXXX multiple readers, YYYY multiple slots. The resource manager will
+  set these automatically. By default the resource manager loads a new
+  instance of the driver so if your reader does not have more than one
+  smart card slot then ignore the Lun in all the functions.\n
+  \n
+  PC/SC supports the loading of multiple readers through one instance of
+  the driver in which XXXX is important. XXXX identifies the unique
+  reader in which the driver communicates to. The driver should set up
+  an array of structures that associate this XXXX with the underlying
+  details of the particular reader.
+@param[in] Channel Channel ID
+  This is denoted by the following:
+  - 0x000001   @p /dev/pcsc/1
+  - 0x000002   @p /dev/pcsc/2
+  - 0x000003   @p /dev/pcsc/3
+  - 0x000004   @p /dev/pcsc/4
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+
+ */
+RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel);
+
+/**
+This function should close the reader communication channel for the
+particular reader. Prior to closing the communication channel the reader
+should make sure the card is powered down and the terminal is also
+powered down.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+  */
+RESPONSECODE IFDHCloseChannel(DWORD Lun);
+
+/**
+This function should get the slot/card capabilities for a particular
+slot/card specified by Lun. Again, if you have only 1 card slot and
+don't mind loading a new driver for each reader then ignore Lun.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+@param[in] Tag Tag of the desired data value
+- \ref TAG_IFD_ATR
+  Return the ATR and its size (implementation is mandatory).
+- \ref TAG_IFD_SLOTNUM
+  Unused/deprecated
+- \ref SCARD_ATTR_ATR_STRING
+  Same as \ref TAG_IFD_ATR but this one is not mandatory. It is defined
+  in Microsoft PC/SC SCardGetAttrib().
+- \ref TAG_IFD_SIMULTANEOUS_ACCESS
+  Return the number of sessions (readers) the driver can handle in
+  <tt>Value[0]</tt>.
+  This is used for multiple readers sharing the same driver.
+- \ref TAG_IFD_THREAD_SAFE
+  If the driver supports more than one reader (see
+  \ref TAG_IFD_SIMULTANEOUS_ACCESS above) this tag indicates if the
+  driver supports access to multiple readers at the same time.\n
+  <tt>Value[0] = 1</tt> indicates the driver supports simultaneous accesses.
+- \ref TAG_IFD_SLOTS_NUMBER
+  Return the number of slots in this reader in <tt>Value[0]</tt>.
+- \ref TAG_IFD_SLOT_THREAD_SAFE
+  If the reader has more than one slot (see \ref TAG_IFD_SLOTS_NUMBER
+  above) this tag indicates if the driver supports access to multiple
+  slots of the same reader at the same time.\n
+  <tt>Value[0] = 1</tt> indicates the driver supports simultaneous slot
+  accesses.
+- \ref TAG_IFD_POLLING_THREAD
+  Unused/deprecated
+- \ref TAG_IFD_POLLING_THREAD_WITH_TIMEOUT
+  If the driver provides a polling thread then @p Value is a pointer to
+  this function. The function prototype is:
+@verbatim
+  RESPONSECODE foo(DWORD Lun, int timeout);
+@endverbatim
+- \ref TAG_IFD_POLLING_THREAD_KILLABLE
+  Tell if the polling thread can be killed (pthread_kill()) by pcscd
+- \ref TAG_IFD_STOP_POLLING_THREAD
+  Returns a pointer in @p Value to the function used to stop the polling
+  thread returned by \ref TAG_IFD_POLLING_THREAD_WITH_TIMEOUT. The
+  function prototype is:
+@verbatim
+  RESPONSECODE foo(DWORD Lun);
+@endverbatim
+@param[in,out] Length Length of the desired data value
+@param[out] Value Value of the desired data
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_ERROR_TAG Invalid tag given (\ref IFD_ERROR_TAG)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag, PDWORD Length,
+       PUCHAR Value);
+
+/**
+This function should set the slot/card capabilities for a particular
+slot/card specified by @p Lun. Again, if you have only 1 card slot and
+don't mind loading a new driver for each reader then ignore @p Lun.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+@param[in] Tag Tag of the desired data value
+@param[in,out] Length Length of the desired data value
+@param[out] Value Value of the desired data
+
+This function is also called when the application uses the PC/SC
+SCardGetAttrib() function. The list of supported tags is not limited.
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_ERROR_TAG Invalid tag given (\ref IFD_ERROR_TAG)
+@retval IFD_ERROR_SET_FAILURE Could not set value (\ref IFD_ERROR_SET_FAILURE)
+@retval IFD_ERROR_VALUE_READ_ONLY Trying to set read only value (\ref 
IFD_ERROR_VALUE_READ_ONLY)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag, DWORD Length, PUCHAR 
Value);
+
+/**
+This function should set the Protocol Type Selection (PTS) of a
+particular card/slot using the three PTS parameters sent
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+@param[in] Protocol Desired protocol
+- \ref SCARD_PROTOCOL_T0
+  T=0 protocol
+- \ref SCARD_PROTOCOL_T1
+  T=1 protocol
+@param[in] Flags Logical OR of possible values to determine which PTS values
+to negotiate
+- \ref IFD_NEGOTIATE_PTS1
+- \ref IFD_NEGOTIATE_PTS2
+- \ref IFD_NEGOTIATE_PTS3
+@param[in] PTS1 1st PTS Value
+@param[in] PTS2 2nd PTS Value
+@param[in] PTS3 3rd PTS Value\n
+  See ISO 7816/EMV documentation.
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_ERROR_PTS_FAILURE Could not set PTS value (\ref 
IFD_ERROR_PTS_FAILURE)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_PROTOCOL_NOT_SUPPORTED Protocol is not supported (\ref 
IFD_PROTOCOL_NOT_SUPPORTED)
+@retval IFD_NOT_SUPPORTED Action not supported (\ref IFD_NOT_SUPPORTED)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol, UCHAR Flags,
+       UCHAR PTS1, UCHAR PTS2, UCHAR PTS3);
+/**
+This function controls the power and reset signals of the smart card
+reader at the particular reader/slot specified by @p Lun.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+@param[in] Action Action to be taken on the card
+- \ref IFD_POWER_UP
+  Power up the card (store and return Atr and AtrLength)
+- \ref IFD_POWER_DOWN
+  Power down the card (Atr and AtrLength should be zeroed)
+- \ref IFD_RESET
+  Perform a warm reset of the card (no power down). If the card is not powered 
then power up the card (store and return Atr and AtrLength)
+@param[out] Atr Answer to Reset (ATR) of the card\n
+  The driver is responsible for caching this value in case
+  IFDHGetCapabilities() is called requesting the ATR and its length. The
+  ATR length should not exceed \ref MAX_ATR_SIZE.
+@param[in,out] AtrLength Length of the ATR\n
+  This should not exceed \ref MAX_ATR_SIZE.
+
+@note
+Memory cards without an ATR should return \ref IFD_SUCCESS on reset but the
+Atr should be zeroed and the length should be zero Reset errors should
+return zero for the AtrLength and return \ref IFD_ERROR_POWER_ACTION.
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_ERROR_POWER_ACTION Error powering/resetting card (\ref 
IFD_ERROR_POWER_ACTION)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_NOT_SUPPORTED Action not supported (\ref IFD_NOT_SUPPORTED)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action, PUCHAR Atr, PDWORD
+       AtrLength);
+
+/**
+This function performs an APDU exchange with the card/slot specified by
+Lun. The driver is responsible for performing any protocol specific
+exchanges such as T=0, 1, etc. differences. Calling this function will
+abstract all protocol differences.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+@param[in] SendPci contains two structure members
+- Protocol 0, 1, ... 14\n
+  T=0 ... T=14
+- Length\n
+  Not used.
+@param[in] TxBuffer Transmit APDU\n
+      Example: "\x00\xA4\x00\x00\x02\x3F\x00"
+@param[in] TxLength Length of this buffer
+@param[out] RxBuffer Receive APDU\n
+      Example: "\x61\x14"
+@param[in,out] RxLength Length of the received APDU\n
+  This function will be passed the size of the buffer of RxBuffer and
+  this function is responsible for setting this to the length of the
+  received APDU response. This should be ZERO on all errors. The
+  resource manager will take responsibility of zeroing out any temporary
+  APDU buffers for security reasons.
+@param[out] RecvPci contains two structure members
+- Protocol - 0, 1, ... 14\n
+  T=0 ... T=14
+- Length\n
+  Not used.
+
+@note
+The driver is responsible for knowing what type of card it has. If the
+current slot/card contains a memory card then this command should ignore
+the Protocol and use the MCT style commands for support for these style
+cards and transmit them appropriately. If your reader does not support
+memory cards or you don't want to implement this functionality, then
+ignore this.
+@par
+RxLength should be set to zero on error.
+@par
+The driver is not responsible for doing an automatic Get Response
+command for received buffers containing 61 XX.
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_RESPONSE_TIMEOUT The response timed out (\ref IFD_RESPONSE_TIMEOUT)
+@retval IFD_ICC_NOT_PRESENT ICC is not present (\ref IFD_ICC_NOT_PRESENT)
+@retval IFD_NOT_SUPPORTED Action not supported (\ref IFD_NOT_SUPPORTED)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
+       PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD
+       RxLength, PSCARD_IO_HEADER RecvPci);
+
+/**
+This function returns the status of the card inserted in the reader/slot
+specified by @p Lun. In cases where the device supports asynchronous
+card insertion/removal detection, it is advised that the driver manages
+this through a thread so the driver does not have to send and receive a
+command each time this function is called.
+
+@ingroup IFDHandler
+@param[in] Lun Logical Unit Number
+
+@return Error codes
+@retval IFD_SUCCESS Successful (\ref IFD_SUCCESS)
+@retval IFD_COMMUNICATION_ERROR Error has occurred (\ref 
IFD_COMMUNICATION_ERROR)
+@retval IFD_ICC_NOT_PRESENT ICC is not present (\ref IFD_ICC_NOT_PRESENT)
+@retval IFD_NO_SUCH_DEVICE The reader is no more present (\ref 
IFD_NO_SUCH_DEVICE)
+ */
+RESPONSECODE IFDHICCPresence(DWORD Lun);
+
+void SetReaderName(DWORD Lun, CHAR16 *ReaderName);
+#endif
diff --git a/MdeModulePkg/Library/SmartCardReader/misc.h 
b/MdeModulePkg/Library/SmartCardReader/misc.h
new file mode 100644
index 0000000..b5f32af
--- /dev/null
+++ b/MdeModulePkg/Library/SmartCardReader/misc.h
@@ -0,0 +1,88 @@
+/*
+ * This handles GCC attributes
+ *
+ * MUSCLE SmartCard Development ( 
http://pcsclite.alioth.debian.org/pcsclite.html )
+ *
+ * Copyright (C) 2005-2010
+ *  Ludovic Rousseau <ludovic.rouss...@free.fr>
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: misc.h 6851 2014-02-14 15:43:32Z rousseau $
+ */
+
+#ifndef __misc_h__
+#define __misc_h__
+
+/*
+ * Declare the function as internal to the library: the function name is
+ * not exported and can't be used by a program linked to the library
+ *
+ * see 
http://gcc.gnu.org/onlinedocs/gcc-3.3.5/gcc/Function-Attributes.html#Function-Attributes
+ * see http://www.nedprod.com/programs/gccvisibility.html
+ */
+#if defined __GNUC__ && (! defined (__sun)) && (__GNUC__ >= 4 || (__GNUC__ == 
3 && __GNUC_MINOR__ >= 3))
+#define INTERNAL __attribute__ ((visibility("hidden")))
+#define PCSC_API __attribute__ ((visibility("default")))
+#elif (! defined __GNUC__ ) && defined (__sun)
+/* 
http://wikis.sun.com/display/SunStudio/Macros+for+Shared+Library+Symbol+Visibility
 */
+#define INTERNAL __hidden
+#define PCSC_API __global
+#else
+#define INTERNAL
+#define PCSC_API
+#endif
+#define EXTERNAL PCSC_API
+
+#if defined __GNUC__
+
+/* GNU Compiler Collection (GCC) */
+#define CONSTRUCTOR __attribute__ ((constructor))
+#define DESTRUCTOR __attribute__ ((destructor))
+
+#else
+
+/* SUN C compiler does not use __attribute__ but #pragma init (function)
+ * We can't use a # inside a #define so it is not possible to use
+ * #define CONSTRUCTOR_DECLARATION(x) #pragma init (x)
+ * The #pragma is used directly where needed */
+
+/* any other */
+#define CONSTRUCTOR
+#define DESTRUCTOR
+
+#endif
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef COUNT_OF
+#define COUNT_OF(arr) (sizeof(arr)/sizeof(arr[0]))
+#endif
+
+#endif /* __misc_h__ */
diff --git a/MdeModulePkg/Library/SmartCardReader/pcsclite.h 
b/MdeModulePkg/Library/SmartCardReader/pcsclite.h
new file mode 100644
index 0000000..051e367
--- /dev/null
+++ b/MdeModulePkg/Library/SmartCardReader/pcsclite.h
@@ -0,0 +1,65 @@
+/*
+ * MUSCLE SmartCard Development ( 
http://pcsclite.alioth.debian.org/pcsclite.html )
+ *
+ * Copyright (C) 1999-2004
+ *  David Corcoran <corco...@musclecard.com>
+ * Copyright (C) 2002-2011
+ *  Ludovic Rousseau <ludovic.rouss...@free.fr>
+ * Copyright (C) 2005
+ *  Martin Paljak <mar...@paljak.pri.ee>
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: pcsclite.h.in 6851 2014-02-14 15:43:32Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps a list of defines for pcsc-lite.
+ *
+ */
+
+#ifndef __pcsclite_h__
+#define __pcsclite_h__
+
+#include <wintypes.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MAX_ATR_SIZE                   33      /**< Maximum ATR size */
+
+#define SCARD_PROTOCOL_T0              0x0001  /**< T=0 active protocol. */
+#define SCARD_PROTOCOL_T1              0x0002  /**< T=1 active protocol. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/MdeModulePkg/Library/SmartCardReader/reader.h 
b/MdeModulePkg/Library/SmartCardReader/reader.h
new file mode 100644
index 0000000..1e82b70
--- /dev/null
+++ b/MdeModulePkg/Library/SmartCardReader/reader.h
@@ -0,0 +1,285 @@
+/*
+ * MUSCLE SmartCard Development ( 
http://pcsclite.alioth.debian.org/pcsclite.html )
+ *
+ * Copyright (C) 1999-2005
+ *  David Corcoran <corco...@musclecard.com>
+ * Copyright (C) 2005-2009
+ *  Ludovic Rousseau <ludovic.rouss...@free.fr>
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: reader.h 6851 2014-02-14 15:43:32Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps a list of defines shared between the driver and the 
application
+ */
+
+#ifndef __reader_h__
+#define __reader_h__
+
+/*
+ * Tags for requesting card and reader attributes
+ */
+
+#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | 
((ULONG)(Tag)))
+
+#define SCARD_CLASS_VENDOR_INFO     1   /**< Vendor information definitions */
+#define SCARD_CLASS_COMMUNICATIONS  2   /**< Communication definitions */
+#define SCARD_CLASS_PROTOCOL        3   /**< Protocol definitions */
+#define SCARD_CLASS_POWER_MGMT      4   /**< Power Management definitions */
+#define SCARD_CLASS_SECURITY        5   /**< Security Assurance definitions */
+#define SCARD_CLASS_MECHANICAL      6   /**< Mechanical characteristic 
definitions */
+#define SCARD_CLASS_VENDOR_DEFINED  7   /**< Vendor specific definitions */
+#define SCARD_CLASS_IFD_PROTOCOL    8   /**< Interface Device Protocol options 
*/
+#define SCARD_CLASS_ICC_STATE       9   /**< ICC State specific definitions */
+#define SCARD_CLASS_SYSTEM     0x7fff   /**< System-specific definitions */
+
+#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 
0x0100) /**< Vendor name. */
+#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 
0x0101) /**< Vendor-supplied interface device type (model designation of 
reader). */
+#define SCARD_ATTR_VENDOR_IFD_VERSION 
SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102) /**< Vendor-supplied 
interface device version (DWORD in the form 0xMMmmbbbb where MM = major 
version, mm = minor version, and bbbb = build number). */
+#define SCARD_ATTR_VENDOR_IFD_SERIAL_NO 
SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0103) /**< Vendor-supplied 
interface device serial number. */
+#define SCARD_ATTR_CHANNEL_ID SCARD_ATTR_VALUE(SCARD_CLASS_COMMUNICATIONS, 
0x0110) /**< DWORD encoded as 0xDDDDCCCC, where DDDD = data channel type and 
CCCC = channel number */
+#define SCARD_ATTR_ASYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 
0x0120) /**< FIXME */
+#define SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0121) 
/**< Default clock rate, in kHz. */
+#define SCARD_ATTR_MAX_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0122) /**< 
Maximum clock rate, in kHz. */
+#define SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 
0x0123) /**< Default data rate, in bps. */
+#define SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 
0x0124) /**< Maximum data rate, in bps. */
+#define SCARD_ATTR_MAX_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0125) 
/**< Maximum bytes for information file size device. */
+#define SCARD_ATTR_SYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 
0x0126) /**< FIXME */
+#define SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_VALUE(SCARD_CLASS_POWER_MGMT, 
0x0131) /**< Zero if device does not support power down while smart card is 
inserted. Nonzero otherwise. */
+#define SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE 
SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0140) /**< FIXME */
+#define SCARD_ATTR_USER_AUTH_INPUT_DEVICE 
SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0142) /**< FIXME */
+#define SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_VALUE(SCARD_CLASS_MECHANICAL, 
0x0150) /**< DWORD indicating which mechanical characteristics are supported. 
If zero, no special characteristics are supported. Note that multiple bits can 
be set */
+
+#define SCARD_ATTR_CURRENT_PROTOCOL_TYPE 
SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0201) /**< FIXME */
+#define SCARD_ATTR_CURRENT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0202) /**< Current clock rate, in kHz. */
+#define SCARD_ATTR_CURRENT_F SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0203) /**< Clock conversion factor. */
+#define SCARD_ATTR_CURRENT_D SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0204) /**< Bit rate conversion factor. */
+#define SCARD_ATTR_CURRENT_N SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0205) /**< Current guard time. */
+#define SCARD_ATTR_CURRENT_W SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0206) /**< Current work waiting time. */
+#define SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0207) /**< Current byte size for information field size card. */
+#define SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0208) /**< Current byte size for information field size device. */
+#define SCARD_ATTR_CURRENT_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x0209) /**< Current block waiting time. */
+#define SCARD_ATTR_CURRENT_CWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x020a) /**< Current character waiting time. */
+#define SCARD_ATTR_CURRENT_EBC_ENCODING 
SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020b) /**< Current error block 
control encoding. */
+#define SCARD_ATTR_EXTENDED_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 
0x020c) /**< FIXME */
+
+#define SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 
0x0300) /**< Single byte indicating smart card presence */
+#define SCARD_ATTR_ICC_INTERFACE_STATUS 
SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0301) /**< Single byte. Zero if smart 
card electrical contact is not active; nonzero if contact is active. */
+#define SCARD_ATTR_CURRENT_IO_STATE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 
0x0302) /**< FIXME */
+#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) 
/**< Answer to reset (ATR) string. */
+#define SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 
0x0304) /**< Single byte indicating smart card type */
+
+#define SCARD_ATTR_ESC_RESET SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 
0xA000) /**< FIXME */
+#define SCARD_ATTR_ESC_CANCEL SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 
0xA003) /**< FIXME */
+#define SCARD_ATTR_ESC_AUTHREQUEST 
SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA005) /**< FIXME */
+#define SCARD_ATTR_MAXINPUT SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 
0xA007) /**< FIXME */
+
+#define SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0001) 
/**< Instance of this vendor's reader attached to the computer. The first 
instance will be device unit 0, the next will be unit 1 (if it is the same 
brand of reader) and so on. Two different brands of readers will both have zero 
for this value. */
+#define SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0002) 
/**< Reserved for future use. */
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 
0x0003)
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 
0x0004)
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 
0x0005)
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 
0x0006)
+#define SCARD_ATTR_SUPRESS_T1_IFS_REQUEST SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 
0x0007) /**< FIXME */
+
+#ifdef UNICODE
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W /**< 
Reader's display name. */
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W /**< 
Reader's system name. */
+#else
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A /**< 
Reader's display name. */
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A /**< 
Reader's system name. */
+#endif
+
+/**
+ * Provide source compatibility on different platforms
+ */
+#define SCARD_CTL_CODE(code) (0x42000000 + (code))
+
+/**
+ * PC/SC part 10 v2.02.07 March 2010 reader tags
+ */
+#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
+
+#define FEATURE_VERIFY_PIN_START         0x01
+#define FEATURE_VERIFY_PIN_FINISH        0x02
+#define FEATURE_MODIFY_PIN_START         0x03
+#define FEATURE_MODIFY_PIN_FINISH        0x04
+#define FEATURE_GET_KEY_PRESSED          0x05
+#define FEATURE_VERIFY_PIN_DIRECT        0x06 /**< Verify PIN */
+#define FEATURE_MODIFY_PIN_DIRECT        0x07 /**< Modify PIN */
+#define FEATURE_MCT_READER_DIRECT        0x08
+#define FEATURE_MCT_UNIVERSAL            0x09
+#define FEATURE_IFD_PIN_PROPERTIES       0x0A /**< retrieve properties of the 
IFD regarding PIN handling */
+#define FEATURE_ABORT                    0x0B
+#define FEATURE_SET_SPE_MESSAGE          0x0C
+#define FEATURE_VERIFY_PIN_DIRECT_APP_ID 0x0D
+#define FEATURE_MODIFY_PIN_DIRECT_APP_ID 0x0E
+#define FEATURE_WRITE_DISPLAY            0x0F
+#define FEATURE_GET_KEY                  0x10
+#define FEATURE_IFD_DISPLAY_PROPERTIES   0x11
+#define FEATURE_GET_TLV_PROPERTIES       0x12
+#define FEATURE_CCID_ESC_COMMAND         0x13
+#define FEATURE_EXECUTE_PACE             0x20
+
+/* structures used (but not defined) in PC/SC Part 10:
+ * "IFDs with Secure Pin Entry Capabilities" */
+
+#ifdef UEFI_DRIVER
+#ifndef uint8_t
+#define uint8_t UINT8
+#endif
+#define uint16_t UINT16
+#define uint32_t UINT32
+#define ULONG unsigned long
+#else
+#include <inttypes.h>
+#endif
+
+/* Set structure elements aligment on bytes
+ * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */
+#if defined(__APPLE__) | defined(sun)
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+/** the structure must be 6-bytes long */
+typedef struct
+{
+       uint8_t tag;
+       uint8_t length;
+       uint32_t value; /**< This value is always in BIG ENDIAN format as 
documented in PCSC v2 part 10 ch 2.2 page 2. You can use ntohl() for example */
+} PCSC_TLV_STRUCTURE;
+
+/** Since CCID 1.4.1 (revision 5252) the byte order is no more important
+ * These macros are now deprecated and should be removed in the future */
+#define HOST_TO_CCID_16(x) (x)
+#define HOST_TO_CCID_32(x) (x)
+
+/** structure used with \ref FEATURE_VERIFY_PIN_DIRECT */
+typedef struct
+{
+       uint8_t bTimerOut;      /**< timeout is seconds (00 means use default 
timeout) */
+       uint8_t bTimerOut2; /**< timeout in seconds after first key stroke */
+       uint8_t bmFormatString; /**< formatting options */
+       uint8_t bmPINBlockString; /**< bits 7-4 bit size of PIN length in APDU,
+                               * bits 3-0 PIN block size in bytes after
+                               * justification and formatting */
+       uint8_t bmPINLengthFormat; /**< bits 7-5 RFU,
+                                * bit 4 set if system units are bytes, clear if
+                                * system units are bits,
+                                * bits 3-0 PIN length position in system units 
*/
+       uint16_t wPINMaxExtraDigit; /**< 0xXXYY where XX is minimum PIN size in 
digits,
+                                   and YY is maximum PIN size in digits */
+       uint8_t bEntryValidationCondition; /**< Conditions under which PIN 
entry should
+                                        * be considered complete */
+       uint8_t bNumberMessage; /**< Number of messages to display for PIN 
verification */
+       uint16_t wLangId; /**< Language for messages */
+       uint8_t bMsgIndex; /**< Message index (should be 00) */
+       uint8_t bTeoPrologue[3]; /**< T=1 block prologue field to use (fill 
with 00) */
+       uint32_t ulDataLength; /**< length of Data to be sent to the ICC */
+       uint8_t abData
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+       [] /* valid C99 code */
+#else
+       [0] /* non-standard, but usually working code */
+#endif
+       ; /**< Data to send to the ICC */
+} PIN_VERIFY_STRUCTURE;
+
+/** structure used with \ref FEATURE_MODIFY_PIN_DIRECT */
+typedef struct
+{
+       uint8_t bTimerOut;      /**< timeout is seconds (00 means use default 
timeout) */
+       uint8_t bTimerOut2; /**< timeout in seconds after first key stroke */
+       uint8_t bmFormatString; /**< formatting options */
+       uint8_t bmPINBlockString; /**< bits 7-4 bit size of PIN length in APDU,
+                               * bits 3-0 PIN block size in bytes after
+                               * justification and formatting */
+       uint8_t bmPINLengthFormat; /**< bits 7-5 RFU,
+                                * bit 4 set if system units are bytes, clear if
+                                * system units are bits,
+                                * bits 3-0 PIN length position in system units 
*/
+       uint8_t bInsertionOffsetOld; /**< Insertion position offset in bytes for
+                                    the current PIN */
+       uint8_t bInsertionOffsetNew; /**< Insertion position offset in bytes for
+                                    the new PIN */
+       uint16_t wPINMaxExtraDigit;
+                                /**< 0xXXYY where XX is minimum PIN size in 
digits,
+                                   and YY is maximum PIN size in digits */
+       uint8_t bConfirmPIN; /**< Flags governing need for confirmation of new 
PIN */
+       uint8_t bEntryValidationCondition; /**< Conditions under which PIN 
entry should
+                                        * be considered complete */
+       uint8_t bNumberMessage; /**< Number of messages to display for PIN 
verification*/
+       uint16_t wLangId; /**< Language for messages */
+       uint8_t bMsgIndex1; /**< index of 1st prompting message */
+       uint8_t bMsgIndex2; /**< index of 2d prompting message */
+       uint8_t bMsgIndex3; /**< index of 3d prompting message */
+       uint8_t bTeoPrologue[3]; /**< T=1 block prologue field to use (fill 
with 00) */
+       uint32_t ulDataLength; /**< length of Data to be sent to the ICC */
+       uint8_t abData
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+       [] /* valid C99 code */
+#else
+       [0] /* non-standard, but usually working code */
+#endif
+       ; /**< Data to send to the ICC */
+} PIN_MODIFY_STRUCTURE;
+
+/** structure used with \ref FEATURE_IFD_PIN_PROPERTIES */
+typedef struct {
+       uint16_t wLcdLayout; /**< display characteristics */
+       uint8_t bEntryValidationCondition;
+       uint8_t bTimeOut2;
+} PIN_PROPERTIES_STRUCTURE;
+
+/* restore default structure elements alignment */
+#if defined(__APPLE__) | defined(sun)
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+/* properties returned by FEATURE_GET_TLV_PROPERTIES */
+#define PCSCv2_PART10_PROPERTY_wLcdLayout 1
+#define PCSCv2_PART10_PROPERTY_bEntryValidationCondition 2
+#define PCSCv2_PART10_PROPERTY_bTimeOut2 3
+#define PCSCv2_PART10_PROPERTY_wLcdMaxCharacters 4
+#define PCSCv2_PART10_PROPERTY_wLcdMaxLines 5
+#define PCSCv2_PART10_PROPERTY_bMinPINSize 6
+#define PCSCv2_PART10_PROPERTY_bMaxPINSize 7
+#define PCSCv2_PART10_PROPERTY_sFirmwareID 8
+#define PCSCv2_PART10_PROPERTY_bPPDUSupport 9
+#define PCSCv2_PART10_PROPERTY_dwMaxAPDUDataSize 10
+#define PCSCv2_PART10_PROPERTY_wIdVendor 11
+#define PCSCv2_PART10_PROPERTY_wIdProduct 12
+
+#endif
+
diff --git a/MdeModulePkg/Library/SmartCardReader/wintypes.h 
b/MdeModulePkg/Library/SmartCardReader/wintypes.h
new file mode 100644
index 0000000..565dbb8
--- /dev/null
+++ b/MdeModulePkg/Library/SmartCardReader/wintypes.h
@@ -0,0 +1,120 @@
+/*
+ * MUSCLE SmartCard Development ( 
http://pcsclite.alioth.debian.org/pcsclite.html )
+ *
+ * Copyright (C) 1999
+ *  David Corcoran <corco...@musclecard.com>
+ * Copyright (C) 2002-2011
+ *  Ludovic Rousseau <ludovic.rouss...@free.fr>
+ *
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: wintypes.h 6851 2014-02-14 15:43:32Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps a list of Windows(R) types.
+ */
+
+#ifndef __wintypes_h__
+#define __wintypes_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef __APPLE__
+
+#include <stdint.h>
+
+#ifndef BYTE
+    typedef uint8_t BYTE;
+#endif
+    typedef uint8_t UCHAR;
+    typedef UCHAR *PUCHAR;
+    typedef uint16_t USHORT;
+
+#ifndef __COREFOUNDATION_CFPLUGINCOM__
+    typedef uint32_t ULONG;
+    typedef void *LPVOID;
+    typedef int16_t BOOL;
+#endif
+
+    typedef ULONG *PULONG;
+    typedef const void *LPCVOID;
+    typedef uint32_t DWORD;
+    typedef DWORD *PDWORD;
+    typedef uint16_t WORD;
+    typedef int32_t LONG;
+    typedef const char *LPCSTR;
+    typedef const BYTE *LPCBYTE;
+    typedef BYTE *LPBYTE;
+    typedef DWORD *LPDWORD;
+    typedef char *LPSTR;
+
+#else
+
+#ifndef BYTE
+       typedef unsigned char BYTE;
+#endif
+       typedef unsigned char UCHAR;
+       typedef UCHAR *PUCHAR;
+       typedef unsigned short USHORT;
+
+#ifndef __COREFOUNDATION_CFPLUGINCOM__
+       typedef unsigned long ULONG;
+       typedef void *LPVOID;
+#endif
+
+       typedef const void *LPCVOID;
+       typedef unsigned long DWORD;
+       typedef DWORD *PDWORD;
+       typedef long LONG;
+       typedef const char *LPCSTR;
+       typedef const BYTE *LPCBYTE;
+       typedef BYTE *LPBYTE;
+       typedef DWORD *LPDWORD;
+       typedef char *LPSTR;
+
+       /* these types were deprecated but still used by old drivers and
+        * applications. So just declare and use them. */
+       typedef LPSTR LPTSTR;
+       typedef LPCSTR LPCTSTR;
+
+       /* types unused by pcsc-lite */
+       typedef short BOOL;
+       typedef unsigned short WORD;
+       typedef ULONG *PULONG;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
2.1.4


------------------------------------------------------------------------------
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to