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

PCSC_API LONG SCardDisconnect ( SCARDHANDLE  hCard,
DWORD  dwDisposition 
)

This function terminates a connection to the connection made through SCardConnect(). dwDisposition can have the following values:

Parameters:
[in] hCard Connection made from SCardConnect.
[in] dwDisposition Reader function to execute.
  • SCARD_LEAVE_CARD - Do nothing.
  • SCARD_RESET_CARD - Reset the card (warm reset).
  • SCARD_UNPOWER_CARD - Unpower the card (cold reset).
  • SCARD_EJECT_CARD - Eject the card.
Returns:
Error code.
Return values:
SCARD_S_SUCCESS Successful.
SCARD_E_INVALID_HANDLE Invalid hCard handle.
SCARD_E_INVALID_VALUE - Invalid dwDisposition.
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);
 rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);

Definition at line 683 of file winscard.c.

References rxSharedSegment::data, disconnect_struct::dwDisposition, disconnect_struct::hCard, MAX_BUFFER_SIZE, PCSCLITE_CLIENT_ATTEMPTS, PCSCLITE_STATUS_POLL_RATE, psContextMap, SCARD_ABSENT, SCARD_EJECT_CARD, SCARD_EXCLUSIVE_CONTEXT, SCARD_LEAVE_CARD, SCARD_NEGOTIABLE, SCARD_NO_CONTEXT, SCARD_POWERED, SCARD_PRESENT, SCARD_PROTOCOL_UNSET, SCARD_RESET, SCARD_RESET_CARD, SCARD_SPECIFIC, SCARD_SWALLOWED, SCARD_UNKNOWN, SCARD_UNPOWER_CARD, SCardCheckDaemonAvailability(), SCardLockThread(), SCardUnlockThread(), SHMClientRead(), SYS_MutexLock(), SYS_MutexUnLock(), SYS_USleep(), and WrapSHMWrite().

Referenced by MSGFunctionDemarshall().

{
      LONG rv;
      PREADER_CONTEXT rContext = NULL;

      if (hCard == 0)
            return SCARD_E_INVALID_HANDLE;

      rv = RFReaderInfoById(hCard, &rContext);
      if (rv != SCARD_S_SUCCESS)
            return rv;

      rv = RFFindReaderHandle(hCard);
      if (rv != SCARD_S_SUCCESS)
            return rv;

      if ((dwDisposition != SCARD_LEAVE_CARD)
            && (dwDisposition != SCARD_UNPOWER_CARD)
            && (dwDisposition != SCARD_RESET_CARD)
            && (dwDisposition != SCARD_EJECT_CARD))
            return SCARD_E_INVALID_VALUE;

      /*
       * Unlock any blocks on this context
       */
      RFUnlockSharing(hCard);

      Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->dwContexts);

      if (dwDisposition == SCARD_RESET_CARD ||
            dwDisposition == SCARD_UNPOWER_CARD)
      {
            /*
             * Currently pcsc-lite keeps the card powered constantly
             */
            if (SCARD_RESET_CARD == dwDisposition)
                  rv = IFDPowerICC(rContext, IFD_RESET,
                        rContext->readerState->cardAtr,
                        &rContext->readerState->cardAtrLength);
            else
            {
                  rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
                        rContext->readerState->cardAtr,
                        &rContext->readerState->cardAtrLength);
                  rv = IFDPowerICC(rContext, IFD_POWER_UP,
                        rContext->readerState->cardAtr,
                        &rContext->readerState->cardAtrLength);
            }

            /* the protocol is unset after a power on */
            rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNSET;

            /*
             * Notify the card has been reset
             */
            RFSetReaderEventState(rContext, SCARD_RESET);

            /*
             * Set up the status bit masks on dwStatus
             */
            if (rv == SCARD_S_SUCCESS)
            {
                  rContext->readerState->readerState |= SCARD_PRESENT;
                  rContext->readerState->readerState &= ~SCARD_ABSENT;
                  rContext->readerState->readerState |= SCARD_POWERED;
                  rContext->readerState->readerState |= SCARD_NEGOTIABLE;
                  rContext->readerState->readerState &= ~SCARD_SPECIFIC;
                  rContext->readerState->readerState &= ~SCARD_SWALLOWED;
                  rContext->readerState->readerState &= ~SCARD_UNKNOWN;
            }
            else
            {
                  if (rContext->readerState->readerState & SCARD_ABSENT)
                        rContext->readerState->readerState &= ~SCARD_PRESENT;
                  else
                        rContext->readerState->readerState |= SCARD_PRESENT;
                  /* SCARD_ABSENT flag is already set */
                  rContext->readerState->readerState |= SCARD_SWALLOWED;
                  rContext->readerState->readerState &= ~SCARD_POWERED;
                  rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
                  rContext->readerState->readerState &= ~SCARD_SPECIFIC;
                  rContext->readerState->readerState &= ~SCARD_UNKNOWN;
                  rContext->readerState->cardAtrLength = 0;
            }

            if (rContext->readerState->cardAtrLength > 0)
                  Log1(PCSC_LOG_DEBUG, "Reset complete.");
            else
                  Log1(PCSC_LOG_ERROR, "Error resetting card.");

      }
      else if (dwDisposition == SCARD_EJECT_CARD)
      {
            UCHAR controlBuffer[5];
            UCHAR receiveBuffer[MAX_BUFFER_SIZE];
            DWORD receiveLength;

            /*
             * Set up the CTBCS command for Eject ICC
             */
            controlBuffer[0] = 0x20;
            controlBuffer[1] = 0x15;
            controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1;
            controlBuffer[3] = 0x00;
            controlBuffer[4] = 0x00;
            receiveLength = 2;
            rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
                  &receiveLength);

            if (rv == SCARD_S_SUCCESS)
            {
                  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
                  {
                        Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
                        /*
                         * Successful
                         */
                  }
                  else
                        Log1(PCSC_LOG_ERROR, "Error ejecting card.");
            }
            else
                  Log1(PCSC_LOG_ERROR, "Error ejecting card.");

      }
      else if (dwDisposition == SCARD_LEAVE_CARD)
      {
            /*
             * Do nothing
             */
      }

      /*
       * Remove and destroy this handle
       */
      RFRemoveReaderHandle(rContext, hCard);
      RFDestroyReaderHandle(hCard);

      /*
       * For exclusive connection reset it to no connections
       */
      if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
      {
            rContext->dwContexts = SCARD_NO_CONTEXT;
            return SCARD_S_SUCCESS;
      }

      /*
       * Remove a connection from the context stack
       */
      rContext->dwContexts -= 1;

      if (rContext->dwContexts < 0)
            rContext->dwContexts = 0;

      /*
       * 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