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

LONG SCardBeginTransaction ( SCARDHANDLE  hCard  ) 

This function establishes a temporary exclusive access mode for doing a series of commands or transaction.

You might want to use this when you are selecting a few files and then writing a large file so you can make sure that another application will not change the current file. If another application has a lock on this reader or this application is in SCARD_SHARE_EXCLUSIVE there will be no action taken.

Parameters:
[in] hCard Connection made from SCardConnect.
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 * /

Definition at line 1010 of file winscard_clnt.c.

References rxSharedSegment::data, begin_struct::hCard, PCSCLITE_CLIENT_ATTEMPTS, PCSCLITE_MAX_READERS_CONTEXTS, _psContextMap::psChannelMap, psContextMap, _psChannelMap::readerName, begin_struct::rv, SCardCheckDaemonAvailability(), SHMClientRead(), SYS_MutexLock(), SYS_MutexUnLock(), SYS_USleep(), and WrapSHMWrite().

{

      LONG rv;
      begin_struct scBeginStruct;
      int i;
      sharedSegmentMsg msgStruct;
      DWORD dwContextIndex, dwChannelIndex;

      PROFILE_START

      if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
            return SCARD_E_NO_SERVICE;

      /*
       * Make sure this handle has been opened
       */
      rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);

      if (rv == -1)
            return SCARD_E_INVALID_HANDLE;

      SYS_MutexLock(psContextMap[dwContextIndex].mMutex);   

      for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
      {
            char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;

            /* by default r == NULL */
            if (r && strcmp(r, (readerStates[i])->readerName) == 0)
                  break;
      }

      if (i == PCSCLITE_MAX_READERS_CONTEXTS)
      {
            SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 
            return SCARD_E_READER_UNAVAILABLE;
      }

      scBeginStruct.hCard = hCard;

      /*
       * Query the server every so often until the sharing violation ends
       * and then hold the lock for yourself.
       */

      do
      {
            /*
             * Look to see if it is locked before polling the server for
             * admission to the readers resources
             */
            if ((readerStates[i])->lockState != 0)
            {
                  int randnum = 0;
                  int j;

                  for (j = 0; j < 100; j++)
                  {
                        /*
                         * This helps prevent starvation
                         */
                        randnum = SYS_RandomInt(1000, 10000);
                        SYS_USleep(randnum);

                        if ((readerStates[i])->lockState == 0)
                        {
                              break;
                        }
                  }
            }

            rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
                  sizeof(scBeginStruct),
                  PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);

            if (rv == -1)
            {
                  
                  SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 
                  return SCARD_E_NO_SERVICE;
            }

            /*
             * Read a message from the server
             */
            rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);


            memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));

            if (rv == -1)
            {
                  
                  SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 
                  return SCARD_F_COMM_ERROR;
            }

      }
      while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);

      SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 

      PROFILE_END

      return scBeginStruct.rv;
}


Generated by  Doxygen 1.6.0   Back to index