Logo Search packages:      
Sourcecode: pcsc-lite version File versions  Download package

PCSC_API LONG SCardConnect ( SCARDCONTEXT  hContext,
LPCSTR  szReader,
DWORD  dwShareMode,
DWORD  dwPreferredProtocols,
LPSCARDHANDLE  phCard,
LPDWORD  pdwActiveProtocol 
)

This function establishes a connection to the friendly name of the reader specified in szReader. The first connection will power up and perform a reset on the card.

Parameters:
[in] hContext Connection context to the PC/SC Resource Manager.
[in] szReader Reader name to connect to.
[in] dwShareMode Mode of connection type: exclusive or shared.
  • SCARD_SHARE_SHARED - This application will allow others to share the reader.
  • SCARD_SHARE_EXCLUSIVE - This application will NOT allow others to share the reader.
  • SCARD_SHARE_DIRECT - Direct control of the reader, even without a card. SCARD_SHARE_DIRECT can be used before using SCardControl() to send control commands to the reader even if a card is not present in the reader.
[in] dwPreferredProtocols Desired protocol use.
  • SCARD_PROTOCOL_T0 - Use the T=0 protocol.
  • SCARD_PROTOCOL_T1 - Use the T=1 protocol.
  • SCARD_PROTOCOL_RAW - Use with memory type cards.
dwPreferredProtocols is a bit mask of acceptable protocols for the connection. You can use (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if you do not have a preferred protocol.
[out] phCard Handle to this connection.
[out] pdwActiveProtocol Established protocol to this connection.
Returns:
Error code.
Return values:
SCARD_S_SUCCESS Successful.
SCARD_E_INVALID_HANDLE Invalid hContext handle.
SCARD_E_INVALID_VALUE Invalid sharing mode, requested protocol, or reader name.
SCARD_E_NOT_READY Could not allocate the desired port.
SCARD_E_READER_UNAVAILABLE Could not power up the reader or card.
SCARD_E_SHARING_VIOLATION Someone else has exclusive rights.
SCARD_E_UNSUPPORTED_FEATURE Protocol not supported.
Test:
 SCARDCONTEXT hContext;
 SCARDHANDLE hCard;
 DWORD dwActiveProtocol;
 LONG rv;
 ...
 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
 rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);

Definition at line 185 of file winscard.c.

References rxSharedSegment::data, connect_struct::dwPreferredProtocols, connect_struct::dwShareMode, connect_struct::hContext, PCSCLITE_CLIENT_ATTEMPTS, PCSCLITE_STATUS_POLL_RATE, connect_struct::pdwActiveProtocol, connect_struct::phCard, psContextMap, SCARD_EXCLUSIVE_CONTEXT, SCARD_NO_CONTEXT, SCARD_PRESENT, SCARD_PROTOCOL_ANY_OLD, SCARD_PROTOCOL_RAW, SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1, SCARD_PROTOCOL_UNSET, SCARD_SHARE_DIRECT, SCARD_SHARE_EXCLUSIVE, SCARD_SHARE_SHARED, SCardCheckDaemonAvailability(), SCardGetContextIndice(), SCardLockThread(), SCardUnlockThread(), SHMClientRead(), SYS_MutexLock(), SYS_MutexUnLock(), SYS_USleep(), connect_struct::szReader, and WrapSHMWrite().

Referenced by MSGFunctionDemarshall().

{
      LONG rv;
      PREADER_CONTEXT rContext = NULL;
      DWORD dwStatus;

      /*
       * Check for NULL parameters
       */
      if (szReader == NULL || phCard == NULL || pdwActiveProtocol == NULL)
            return SCARD_E_INVALID_PARAMETER;
      else
            *phCard = 0;

      if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
                  !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
                  !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
                  !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
            return SCARD_E_PROTO_MISMATCH;

      if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
                  dwShareMode != SCARD_SHARE_SHARED &&
                  dwShareMode != SCARD_SHARE_DIRECT)
            return SCARD_E_INVALID_VALUE;

      Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d",
            szReader, dwPreferredProtocols);

      rv = RFReaderInfo((LPSTR) szReader, &rContext);

      if (rv != SCARD_S_SUCCESS)
      {
            Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
            return rv;
      }

      /*
       * Make sure the reader is working properly
       */
      rv = RFCheckReaderStatus(rContext);
      if (rv != SCARD_S_SUCCESS)
            return rv;

      /*******************************************
       *
       * This section checks for simple errors
       *
       *******************************************/

      /*
       * Connect if not exclusive mode
       */
      if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
      {
            Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
            return SCARD_E_SHARING_VIOLATION;
      }

      /*******************************************
       *
       * This section tries to determine the
       * presence of a card or not
       *
       *******************************************/
      dwStatus = rContext->readerState->readerState;

      if (dwShareMode != SCARD_SHARE_DIRECT)
      {
            if (!(dwStatus & SCARD_PRESENT))
            {
                  Log1(PCSC_LOG_ERROR, "Card Not Inserted");
                  return SCARD_E_NO_SMARTCARD;
            }
      }

      /*******************************************
       *
       * This section tries to decode the ATR
       * and set up which protocol to use
       *
       *******************************************/
      if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
            rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW;
      else
      {
            if (dwShareMode != SCARD_SHARE_DIRECT)
            {
                  /* the protocol is not yet set (no PPS yet) */
                  if (SCARD_PROTOCOL_UNSET == rContext->readerState->cardProtocol)
                  {
                        UCHAR ucAvailable, ucDefault;
                        int ret;

                        ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr,
                              rContext->readerState->cardAtrLength);
                        ucAvailable =
                              PHGetAvailableProtocols(rContext->readerState->cardAtr,
                                          rContext->readerState->cardAtrLength);

                        /*
                         * If it is set to ANY let it do any of the protocols
                         */
                        if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
                              dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;

                        ret = PHSetProtocol(rContext, dwPreferredProtocols,
                              ucAvailable, ucDefault);

                        /* keep cardProtocol = SCARD_PROTOCOL_UNSET in case of error  */
                        if (SET_PROTOCOL_PPS_FAILED == ret)
                              return SCARD_W_UNRESPONSIVE_CARD;

                        if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
                              return SCARD_E_PROTO_MISMATCH;

                        /* use negociated protocol */
                        rContext->readerState->cardProtocol = ret;
                  }
                  else
                  {
                        if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
                              return SCARD_E_PROTO_MISMATCH;
                  }
            }
      }

      *pdwActiveProtocol = rContext->readerState->cardProtocol;

      if (dwShareMode != SCARD_SHARE_DIRECT)
      {
            if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0)
                  && (*pdwActiveProtocol != SCARD_PROTOCOL_T1))
                  Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d",
                        *pdwActiveProtocol);
            else
                  Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
                        (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
      }
      else
            Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");

      /*
       * Prepare the SCARDHANDLE identity
       */
      *phCard = RFCreateReaderHandle(rContext);

      Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard);

      /*******************************************
       *
       * This section tries to set up the
       * exclusivity modes. -1 is exclusive
       *
       *******************************************/

      if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
      {
            if (rContext->dwContexts == SCARD_NO_CONTEXT)
            {
                  rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
                  RFLockSharing(*phCard);
            }
            else
            {
                  RFDestroyReaderHandle(*phCard);
                  *phCard = 0;
                  return SCARD_E_SHARING_VIOLATION;
            }
      }
      else
      {
            /*
             * Add a connection to the context stack
             */
            rContext->dwContexts += 1;
      }

      /*
       * Add this handle to the handle list
       */
      rv = RFAddReaderHandle(rContext, *phCard);

      if (rv != SCARD_S_SUCCESS)
      {
            /*
             * Clean up - there is no more room
             */
            RFDestroyReaderHandle(*phCard);
            if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
                  rContext->dwContexts = SCARD_NO_CONTEXT;
            else
                  if (rContext->dwContexts > SCARD_NO_CONTEXT)
                        rContext->dwContexts -= 1;

            *phCard = 0;
            return SCARD_F_INTERNAL_ERROR;
      }

      /*
       * Allow the status thread to convey information
       */
      SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);

      return SCARD_S_SUCCESS;
}


Generated by  Doxygen 1.6.0   Back to index