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

PCSC_API LONG SCardEndTransaction ( SCARDHANDLE  hCard,
DWORD  dwDisposition 
)

This function ends a previously begun transaction.

The calling application must be the owner of the previously begun transaction or an error will occur.

Parameters:
[in] hCard Connection made from SCardConnect.
[in] dwDisposition Action to be taken on the reader. The disposition action is not currently used in this release.
  • SCARD_LEAVE_CARD - Do nothing.
  • SCARD_RESET_CARD - Reset the card.
  • SCARD_UNPOWER_CARD - Unpower the card.
  • SCARD_EJECT_CARD - Eject the card.
Returns:
Error code.
Return values:
SCARD_S_SUCCESS Successful.
SCARD_E_INVALID_HANDLE Invalid hCard handle.
SCARD_E_SHARING_VIOLATION Someone else has exclusive rights.
SCARD_E_READER_UNAVAILABLE The reader has been removed.
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 = SCardBeginTransaction(hCard);
 ...
 / * Do some transmit commands * /
 ...
 rv = SCardEndTransaction(hCard, SCARD_LEAVE_CARD); 

Definition at line 886 of file winscard.c.

References rxSharedSegment::data, end_struct::dwDisposition, end_struct::hCard, MAX_BUFFER_SIZE, PCSCLITE_CLIENT_ATTEMPTS, PCSCLITE_MAX_READERS_CONTEXTS, _psContextMap::psChannelMap, psContextMap, _psChannelMap::readerName, SCARD_ABSENT, SCARD_EJECT_CARD, SCARD_LEAVE_CARD, SCARD_NEGOTIABLE, 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;

      /*
       * Ignoring dwDisposition for now
       */
      if (hCard == 0)
            return SCARD_E_INVALID_HANDLE;

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

      rv = RFReaderInfoById(hCard, &rContext);

      /*
       * Cannot find the hCard in this context
       */
      if (rv != SCARD_S_SUCCESS)
            return rv;

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

      /*
       * Make sure some event has not occurred
       */
      if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
            return rv;

      if (dwDisposition == SCARD_RESET_CARD ||
            dwDisposition == SCARD_UNPOWER_CARD)
      {
            /*
             * Currently pcsc-lite keeps the card always powered
             */
            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
             */
      }

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

      Log2(PCSC_LOG_DEBUG, "Status: %d.", rv);

      return rv;
}


Generated by  Doxygen 1.6.0   Back to index