sdkcreationmw/sdkruntimes/scard/src/Winscard.cpp
changeset 0 b26acd06ea60
equal deleted inserted replaced
-1:000000000000 0:b26acd06ea60
       
     1 /*
       
     2 * Copyright (c) 2003-2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #define g_rgSCardT0Pci  _g_rgSCardT0Pci
       
    20 #define g_rgSCardT1Pci  _g_rgSCardT1Pci
       
    21 #define g_rgSCardRawPci _g_rgSCardRawPci
       
    22 #define WINSCARDDATA
       
    23 #define WINSCARDAPI
       
    24 
       
    25 #define TRACE_PREFIX "SCARD: [WinsCard] "
       
    26 #include "SdkCardDebug.h"
       
    27 
       
    28 #include <windows.h>
       
    29 #include <winioctl.h>
       
    30 #undef FILE_DEVICE_SMARTCARD /* redefined in <winscard.h> */
       
    31 #include <winscard.h>
       
    32 
       
    33 #undef g_rgSCardT0Pci
       
    34 #undef g_rgSCardT1Pci
       
    35 #undef g_rgSCardRawPci
       
    36 
       
    37 /**
       
    38  * We can't use TRACE macros here because some of these functions may be
       
    39  * called from within Emulator::Escape()/Reenter() block.
       
    40  */
       
    41 #ifdef _REALLY_DEBUG
       
    42 #  define WINSCARD_TRACE(s) OutputDebugStringA(TRACE_PREFIX s "\n")
       
    43 #else 
       
    44 #  define WINSCARD_TRACE(s)
       
    45 #endif // _REALLY_DEBUG
       
    46 
       
    47 /* *************************************************************************
       
    48  *  Support for WINSCARD.DLL
       
    49  *  This code will run on the systems that don't have WINSCARD.DLL installed
       
    50  * *************************************************************************/
       
    51 
       
    52 /* handle to WINSCARD.DLL */
       
    53 static HMODULE WINSCARD_handle = NULL;
       
    54 
       
    55 /*
       
    56  * This flag is set to TRUE if we determine that WINSCARD.DLL is missing
       
    57  * or unusable (i.e. some required exports are missing), so that we don't 
       
    58  * try to load it more than once.
       
    59  */
       
    60 static BOOL WINSCARD_missing = FALSE; 
       
    61 
       
    62 static LPCSTR WINSCARD_DLL = "WINSCARD.DLL";
       
    63 
       
    64 /* 
       
    65  * these are entry points used by this module. These are NOT all entry
       
    66  * points exported by WINSCARD.DLL, just those we need here
       
    67  */
       
    68 
       
    69 /* SCardConnectW */
       
    70 #define WINSCARD_PROC_CONNECT_W  "SCardConnectW"
       
    71 #define WINSCARD_PROC_CONNECT WINSCARD_PROC_CONNECT_W
       
    72 #define WINSCARD_CONNECT WINSCARD_CONNECT_W
       
    73 #define WINSCARD_Connect WINSCARD_ConnectW
       
    74 typedef LONG (WINAPI * WINSCARD_CONNECT_W)(
       
    75     IN      SCARDCONTEXT hContext,
       
    76     IN      LPCWSTR szReader,
       
    77     IN      DWORD dwShareMode,
       
    78     IN      DWORD dwPreferredProtocols,
       
    79     OUT     LPSCARDHANDLE phCard,
       
    80     OUT     LPDWORD pdwActiveProtocol);
       
    81 
       
    82 /* SCardDisconnect */
       
    83 #define WINSCARD_PROC_DISCONNECT "SCardDisconnect"
       
    84 typedef LONG (WINAPI * WINSCARD_DISCONNECT)(
       
    85     IN      SCARDHANDLE hCard,
       
    86     IN      DWORD dwDisposition);
       
    87 
       
    88 /* SCardEstablishContext */
       
    89 #define WINSCARD_PROC_ESTABLISH_CONTEXT "SCardEstablishContext"
       
    90 typedef LONG (WINAPI * WINSCARD_ESTABLISH_CONTEXT)(
       
    91     IN  DWORD dwScope,
       
    92     IN  LPCVOID pvReserved1,
       
    93     IN  LPCVOID pvReserved2,
       
    94     OUT LPSCARDCONTEXT phContext);
       
    95 
       
    96 /* SCardListReadersW */
       
    97 #define WINSCARD_PROC_LIST_READERS_W "SCardListReadersW"
       
    98 #define WINSCARD_PROC_LIST_READERS WINSCARD_PROC_LIST_READERS_W
       
    99 #define WINSCARD_LIST_READERS WINSCARD_LIST_READERS_W
       
   100 #define WINSCARD_ListReaders WINSCARD_ListReadersW
       
   101 typedef LONG (WINAPI * WINSCARD_LIST_READERS_W)(
       
   102     IN      SCARDCONTEXT hContext,
       
   103     IN      LPCWSTR mszGroups,
       
   104     OUT     LPWSTR mszReaders,
       
   105     IN OUT  LPDWORD pcchReaders);
       
   106 
       
   107 /* SCardReleaseContext */
       
   108 #define WINSCARD_PROC_RELEASE_CONTEXT "SCardReleaseContext"
       
   109 typedef LONG (WINAPI * WINSCARD_RELEASE_CONTEXT)(
       
   110     IN      SCARDCONTEXT hContext);
       
   111 
       
   112 /* SCardTransmit */
       
   113 #define WINSCARD_PROC_TRANSMIT "SCardTransmit"
       
   114 typedef LONG (WINAPI * WINSCARD_TRANSMIT)(
       
   115     IN SCARDHANDLE hCard,
       
   116     IN LPCSCARD_IO_REQUEST pioSendPci,
       
   117     IN LPCBYTE pbSendBuffer,
       
   118     IN DWORD cbSendLength,
       
   119     IN OUT LPSCARD_IO_REQUEST pioRecvPci,
       
   120     OUT LPBYTE pbRecvBuffer,
       
   121     IN OUT LPDWORD pcbRecvLength);
       
   122 
       
   123 /* SCardStatusW */
       
   124 #define WINSCARD_PROC_STATUS_W "SCardStatusW"
       
   125 #define WINSCARD_PROC_STATUS WINSCARD_PROC_STATUS_W
       
   126 #define WINSCARD_STATUS WINSCARD_STATUS_W
       
   127 #define WINSCARD_Status WINSCARD_StatusW
       
   128 typedef LONG (WINAPI * WINSCARD_STATUS_W)(
       
   129     IN SCARDHANDLE hCard,
       
   130     OUT LPWSTR szReaderName,
       
   131     IN OUT LPDWORD pcchReaderLen,
       
   132     OUT LPDWORD pdwState,
       
   133     OUT LPDWORD pdwProtocol,
       
   134     OUT LPBYTE pbAtr,
       
   135     OUT LPDWORD pcbAtrLen);
       
   136 
       
   137 /* SCardGetStatusChangeW */
       
   138 #define WINSCARD_PROC_GET_STATUS_CHANGE_W "SCardGetStatusChangeW"
       
   139 #define WINSCARD_PROC_GET_STATUS_CHANGE WINSCARD_PROC_GET_STATUS_CHANGE_W
       
   140 #define WINSCARD_GET_STATUS_CHANGE WINSCARD_GET_STATUS_CHANGE_W
       
   141 #define WINSCARD_GetStatusChange WINSCARD_GetStatusChangeW
       
   142 typedef LONG (WINAPI * WINSCARD_GET_STATUS_CHANGE_W)(
       
   143     IN SCARDCONTEXT hContext,
       
   144     IN DWORD dwTimeout,
       
   145     IN OUT LPSCARD_READERSTATE_W rgReaderStates,
       
   146     IN DWORD cReaders);
       
   147 
       
   148 /* SCardCancel */
       
   149 #define WINSCARD_PROC_CANCEL "SCardCancel"
       
   150 typedef LONG (WINAPI * WINSCARD_CANCEL)(
       
   151     IN SCARDCONTEXT hContext);
       
   152 
       
   153 /* addresses of functions */
       
   154 static WINSCARD_CONNECT             WINSCARD_Connect            = NULL;
       
   155 static WINSCARD_DISCONNECT          WINSCARD_Disconnect         = NULL;
       
   156 static WINSCARD_ESTABLISH_CONTEXT   WINSCARD_EstablishContext   = NULL;
       
   157 static WINSCARD_LIST_READERS        WINSCARD_ListReaders        = NULL;
       
   158 static WINSCARD_RELEASE_CONTEXT     WINSCARD_ReleaseContext     = NULL;
       
   159 static WINSCARD_TRANSMIT            WINSCARD_Transmit           = NULL;
       
   160 static WINSCARD_STATUS              WINSCARD_Status             = NULL;
       
   161 static WINSCARD_GET_STATUS_CHANGE   WINSCARD_GetStatusChange    = NULL;
       
   162 static WINSCARD_CANCEL              WINSCARD_Cancel             = NULL;
       
   163 
       
   164 /* and some variables, too */
       
   165 static SCARD_IO_REQUEST * WINSCARD_g_rgSCardT0Pci  = NULL;
       
   166 static SCARD_IO_REQUEST * WINSCARD_g_rgSCardT1Pci  = NULL;
       
   167 static SCARD_IO_REQUEST * WINSCARD_g_rgSCardRawPci = NULL;
       
   168 
       
   169 extern "C" SCARD_IO_REQUEST g_rgSCardT0Pci;
       
   170 extern "C" SCARD_IO_REQUEST g_rgSCardT1Pci;
       
   171 extern "C" SCARD_IO_REQUEST g_rgSCardRawPci;
       
   172 
       
   173 SCARD_IO_REQUEST g_rgSCardT0Pci;
       
   174 SCARD_IO_REQUEST g_rgSCardT1Pci;
       
   175 SCARD_IO_REQUEST g_rgSCardRawPci;
       
   176 
       
   177 static struct _WINSCARD_Export {
       
   178     const char* name;
       
   179     FARPROC * value_ptr;
       
   180 } WINSCARD_exports [] = {
       
   181 
       
   182     /* functions */
       
   183     {WINSCARD_PROC_CONNECT,             (FARPROC*)&WINSCARD_Connect},
       
   184     {WINSCARD_PROC_DISCONNECT,          (FARPROC*)&WINSCARD_Disconnect},
       
   185     {WINSCARD_PROC_ESTABLISH_CONTEXT,   (FARPROC*)&WINSCARD_EstablishContext},
       
   186     {WINSCARD_PROC_LIST_READERS,        (FARPROC*)&WINSCARD_ListReaders},
       
   187     {WINSCARD_PROC_RELEASE_CONTEXT,     (FARPROC*)&WINSCARD_ReleaseContext},
       
   188     {WINSCARD_PROC_TRANSMIT,            (FARPROC*)&WINSCARD_Transmit},
       
   189     {WINSCARD_PROC_STATUS,              (FARPROC*)&WINSCARD_Status},
       
   190     {WINSCARD_PROC_GET_STATUS_CHANGE,   (FARPROC*)&WINSCARD_GetStatusChange},
       
   191     {WINSCARD_PROC_CANCEL,              (FARPROC*)&WINSCARD_Cancel},
       
   192 
       
   193     /* variables */
       
   194     {"g_rgSCardT0Pci",                  (FARPROC*)&WINSCARD_g_rgSCardT0Pci},
       
   195     {"g_rgSCardT1Pci",                  (FARPROC*)&WINSCARD_g_rgSCardT1Pci},
       
   196     {"g_rgSCardRawPci",                 (FARPROC*)&WINSCARD_g_rgSCardRawPci},
       
   197 };
       
   198 
       
   199 #define COUNT(array) (sizeof(array)/sizeof(array[0]))
       
   200 
       
   201 /**
       
   202  * Checks if WINSCARD.DLL has been loaded; if not, attempts to load it
       
   203  * Returns TRUE if WINSCARD.DLL has been successfully loaded, FALSE 
       
   204  * it the DLL or some entry points are missing.
       
   205  */
       
   206 static BOOL WINSCARD_IsAvailable()
       
   207 {
       
   208     if (!WINSCARD_handle && !WINSCARD_missing)
       
   209     {
       
   210         HINSTANCE handle = LoadLibraryA(WINSCARD_DLL);
       
   211         if (handle)
       
   212         {
       
   213             int i;
       
   214             for( i=0; i<COUNT(WINSCARD_exports); i++)
       
   215             {
       
   216                 LPCSTR name = WINSCARD_exports[i].name;
       
   217                 FARPROC addr = GetProcAddress(handle,name);
       
   218                 if (addr)
       
   219                 {
       
   220                     *(WINSCARD_exports[i].value_ptr) = addr;
       
   221                 }
       
   222                 else
       
   223                 {
       
   224                     TRACE2("ERROR: export %hs is missing from %hs\n",
       
   225                                name, WINSCARD_DLL);
       
   226 
       
   227                     /* bad library, don't use it */
       
   228                     WINSCARD_missing = TRUE;
       
   229                     FreeLibrary(handle);
       
   230                     handle = NULL;
       
   231                     break;
       
   232                 }
       
   233             }
       
   234             g_rgSCardT0Pci = *WINSCARD_g_rgSCardT0Pci;
       
   235             g_rgSCardT1Pci = *WINSCARD_g_rgSCardT1Pci;
       
   236             g_rgSCardRawPci = *WINSCARD_g_rgSCardRawPci;
       
   237             WINSCARD_handle = handle;
       
   238         }
       
   239         else
       
   240         {
       
   241             TRACE1("ERROR: failed to load %hs\n",WINSCARD_DLL);
       
   242             WINSCARD_missing = TRUE;
       
   243         }
       
   244     }
       
   245     return (WINSCARD_handle != NULL);
       
   246 }
       
   247 
       
   248 /* *************************************************************************
       
   249  *  Functions that redirect WINSCARD calls to the real DLL if possible
       
   250  * *************************************************************************/
       
   251 
       
   252 LONG WINAPI
       
   253 SCardConnectW(
       
   254     IN      SCARDCONTEXT hContext,
       
   255     IN      LPCWSTR szReader,
       
   256     IN      DWORD dwShareMode,
       
   257     IN      DWORD dwPreferredProtocols,
       
   258     OUT     LPSCARDHANDLE phCard,
       
   259     OUT     LPDWORD pdwActiveProtocol)
       
   260 {
       
   261     WINSCARD_TRACE("SCardConnect");
       
   262     if (WINSCARD_IsAvailable())
       
   263     {
       
   264         return WINSCARD_ConnectW(hContext,szReader,dwShareMode,
       
   265                                  dwPreferredProtocols, phCard,
       
   266                                  pdwActiveProtocol);
       
   267     }
       
   268     return SCARD_E_NO_SERVICE;
       
   269 }
       
   270 
       
   271 LONG WINAPI
       
   272 SCardDisconnect(
       
   273     IN      SCARDHANDLE hCard,
       
   274     IN      DWORD dwDisposition)
       
   275 {
       
   276     WINSCARD_TRACE("SCardDisconnect");
       
   277     if (WINSCARD_IsAvailable())
       
   278     {
       
   279         return WINSCARD_Disconnect(hCard,dwDisposition);
       
   280     }
       
   281     return SCARD_E_NO_SERVICE;
       
   282 }
       
   283 
       
   284 LONG WINAPI
       
   285 SCardEstablishContext(
       
   286     IN  DWORD dwScope,
       
   287     IN  LPCVOID pvReserved1,
       
   288     IN  LPCVOID pvReserved2,
       
   289     OUT LPSCARDCONTEXT phContext)
       
   290 {
       
   291     WINSCARD_TRACE("SCardEstablishContext");
       
   292     if (WINSCARD_IsAvailable())
       
   293     {
       
   294         return WINSCARD_EstablishContext(dwScope,pvReserved1,
       
   295                                          pvReserved2,phContext);
       
   296     }
       
   297     return SCARD_E_NO_SERVICE;
       
   298 }
       
   299 
       
   300 LONG WINAPI
       
   301 SCardListReadersW(
       
   302     IN      SCARDCONTEXT hContext,
       
   303     IN      LPCWSTR mszGroups,
       
   304     OUT     LPWSTR mszReaders,
       
   305     IN OUT  LPDWORD pcchReaders)
       
   306 {
       
   307     WINSCARD_TRACE("SCardListReaders");
       
   308     if (WINSCARD_IsAvailable())
       
   309     {
       
   310         return WINSCARD_ListReadersW(hContext,mszGroups,
       
   311                                      mszReaders,pcchReaders);
       
   312     }
       
   313     return SCARD_E_NO_SERVICE;
       
   314 }
       
   315 
       
   316 LONG WINAPI
       
   317 SCardReleaseContext(
       
   318     IN      SCARDCONTEXT hContext)
       
   319 {
       
   320     WINSCARD_TRACE("SCardReleaseContext");
       
   321     if (WINSCARD_IsAvailable())
       
   322     {
       
   323         return WINSCARD_ReleaseContext(hContext);
       
   324     }
       
   325     return SCARD_E_NO_SERVICE;
       
   326 }
       
   327 
       
   328 LONG WINAPI
       
   329 SCardTransmit(
       
   330     IN SCARDHANDLE hCard,
       
   331     IN LPCSCARD_IO_REQUEST pioSendPci,
       
   332     IN LPCBYTE pbSendBuffer,
       
   333     IN DWORD cbSendLength,
       
   334     IN OUT LPSCARD_IO_REQUEST pioRecvPci,
       
   335     OUT LPBYTE pbRecvBuffer,
       
   336     IN OUT LPDWORD pcbRecvLength)
       
   337 {
       
   338     WINSCARD_TRACE("SCardTransmit");
       
   339     if (WINSCARD_IsAvailable())
       
   340     {
       
   341         return WINSCARD_Transmit(hCard, pioSendPci, pbSendBuffer, 
       
   342                                  cbSendLength, pioRecvPci, pbRecvBuffer,
       
   343                                  pcbRecvLength);
       
   344     }
       
   345     return SCARD_E_NO_SERVICE;
       
   346 }
       
   347 
       
   348 LONG WINAPI
       
   349 SCardStatusW(
       
   350     IN SCARDHANDLE hCard,
       
   351     OUT LPWSTR szReaderName,
       
   352     IN OUT LPDWORD pcchReaderLen,
       
   353     OUT LPDWORD pdwState,
       
   354     OUT LPDWORD pdwProtocol,
       
   355     OUT LPBYTE pbAtr,
       
   356     OUT LPDWORD pcbAtrLen)
       
   357 {
       
   358     WINSCARD_TRACE("SCardStatus");
       
   359     if (WINSCARD_IsAvailable())
       
   360     {
       
   361         return WINSCARD_StatusW(hCard, szReaderName, pcchReaderLen,
       
   362                                 pdwState, pdwProtocol, pbAtr, pcbAtrLen);
       
   363     }
       
   364     return SCARD_E_NO_SERVICE;
       
   365 }
       
   366 
       
   367 LONG WINAPI
       
   368 SCardGetStatusChangeW(
       
   369     IN SCARDCONTEXT hContext,
       
   370     IN DWORD dwTimeout,
       
   371     IN OUT LPSCARD_READERSTATE_W rgReaderStates,
       
   372     IN DWORD cReaders)
       
   373 {
       
   374     //WINSCARD_TRACE("SCardGetStatusChange");
       
   375     if (WINSCARD_IsAvailable())
       
   376     {
       
   377         return WINSCARD_GetStatusChangeW(hContext, dwTimeout, rgReaderStates,
       
   378                                          cReaders);
       
   379     }
       
   380     return SCARD_E_NO_SERVICE;
       
   381 }
       
   382 
       
   383 LONG WINAPI
       
   384 SCardCancel(
       
   385     IN SCARDCONTEXT hContext)
       
   386 {
       
   387     WINSCARD_TRACE("SCardCancel");
       
   388     if (WINSCARD_IsAvailable())
       
   389     {
       
   390         return WINSCARD_Cancel(hContext);
       
   391     }
       
   392     return SCARD_E_NO_SERVICE;
       
   393 }