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

LONG SCardControl ( SCARDHANDLE  hCard,
DWORD  dwControlCode,
LPCVOID  pbSendBuffer,
DWORD  cbSendLength,
LPVOID  pbRecvBuffer,
DWORD  cbRecvLength,
LPDWORD  lpBytesReturned 
)

This function sends a command directly to the IFD Handler (reader driver) to be processed by the reader.

This is useful for creating client side reader drivers for functions like PIN pads, biometrics, or other extensions to the normal smart card reader that are not normally handled by PC/SC.

Note:
the API of this function changed. In pcsc-lite 1.2.0 and before the API was not Windows(R) PC/SC compatible. This has been corrected.
Parameters:
[in] hCard Connection made from SCardConnect().
[in] dwControlCode Control code for the operation.
Click here for a list of supported commands by some drivers.
[in] pbSendBuffer Command to send to the reader.
[in] cbSendLength Length of the command.
[out] pbRecvBuffer Response from the reader.
[in] cbRecvLength Length of the response buffer.
[out] lpBytesReturned Length of the response.
Returns:
Error code.
Return values:
SCARD_S_SUCCESS Successful (SCARD_S_SUCCESS)
SCARD_E_INSUFFICIENT_BUFFER cbSendLength or cbRecvLength are too big (SCARD_E_INSUFFICIENT_BUFFER)
SCARD_E_INVALID_HANDLE Invalid hCard handle (SCARD_E_INVALID_HANDLE)
SCARD_E_INVALID_PARAMETER pbSendBuffer is NULL or cbSendLength is null and the IFDHandler is version 2.0 (without dwControlCode) (SCARD_E_INVALID_PARAMETER)
SCARD_E_INVALID_VALUE Invalid value was presented (SCARD_E_INVALID_VALUE)
SCARD_E_NO_SERVICE The server is not runing (SCARD_E_NO_SERVICE)
SCARD_E_NOT_TRANSACTED Data exchange not successful (SCARD_E_NOT_TRANSACTED)
SCARD_E_READER_UNAVAILABLE The reader has been removed(SCARD_E_READER_UNAVAILABLE)
SCARD_E_UNSUPPORTED_FEATURE Driver does not support (SCARD_E_UNSUPPORTED_FEATURE)
SCARD_F_COMM_ERROR An internal communications error has been detected (SCARD_F_COMM_ERROR)
SCARD_W_REMOVED_CARD The card has been removed from the reader(SCARD_W_REMOVED_CARD)
SCARD_W_RESET_CARD The card has been reset by another application (SCARD_W_RESET_CARD)
 LONG rv;
 SCARDCONTEXT hContext;
 SCARDHANDLE hCard;
 DWORD dwActiveProtocol, dwSendLength, dwRecvLength;
 BYTE pbRecvBuffer[10];
 BYTE pbSendBuffer[] = { 0x06, 0x00, 0x0A, 0x01, 0x01, 0x10 0x00 };
 ...
 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
 rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED,
          SCARD_PROTOCOL_RAW, &hCard, &dwActiveProtocol);
 dwSendLength = sizeof(pbSendBuffer);
 dwRecvLength = sizeof(pbRecvBuffer);
 rv = SCardControl(hCard, 0x42000001, pbSendBuffer, dwSendLength,
          pbRecvBuffer, sizeof(pbRecvBuffer), &dwRecvLength);

Definition at line 2378 of file winscard_clnt.c.

References control_struct::cbRecvLength, control_struct::cbSendLength, control_struct::dwBytesReturned, control_struct::dwControlCode, control_struct::hCard, IFDControl(), MAX_BUFFER_SIZE_EXTENDED, PCSCLITE_READ_TIMEOUT, PCSCLITE_WRITE_TIMEOUT, control_struct::rv, SCARD_CONTROL, SCARD_E_INSUFFICIENT_BUFFER, SCARD_E_INVALID_HANDLE, SCARD_E_INVALID_PARAMETER, SCARD_E_NO_SERVICE, SCARD_E_UNSUPPORTED_FEATURE, SCARD_F_COMM_ERROR, SCARD_S_SUCCESS, SHMMessageReceive(), SHMMessageSend(), and SHMMessageSendWithHeader().

{
      LONG rv;
      struct control_struct scControlStruct;
      SCONTEXTMAP * currentContextMap;
      CHANNEL_MAP * pChannelMap;

      PROFILE_START

      /* 0 bytes received by default */
      if (NULL != lpBytesReturned)
            *lpBytesReturned = 0;

      CHECK_SAME_PROCESS

      /*
       * Make sure this handle has been opened
       */
      rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
            &pChannelMap);
      if (rv == -1)
      {
            PROFILE_END(SCARD_E_INVALID_HANDLE)
            return SCARD_E_INVALID_HANDLE;
      }

      (void)pthread_mutex_lock(currentContextMap->mMutex);

      /* check the handle is still valid */
      rv = SCardGetContextAndChannelFromHandle(hCard, &currentContextMap,
            &pChannelMap);
      if (rv == -1)
            /* the handle is now invalid
             * -> another thread may have called SCardReleaseContext
             * -> so the mMutex has been unlocked */
            return SCARD_E_INVALID_HANDLE;

      if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
            || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
      {
            rv = SCARD_E_INSUFFICIENT_BUFFER;
            goto end;
      }

      scControlStruct.hCard = hCard;
      scControlStruct.dwControlCode = dwControlCode;
      scControlStruct.cbSendLength = cbSendLength;
      scControlStruct.cbRecvLength = cbRecvLength;

      rv = SHMMessageSendWithHeader(SCARD_CONTROL,
            currentContextMap->dwClientID,
            sizeof(scControlStruct), PCSCLITE_READ_TIMEOUT, &scControlStruct);

      if (rv == -1)
      {
            rv = SCARD_E_NO_SERVICE;
            goto end;
      }

      /* write the sent buffer */
      rv = SHMMessageSend((char *)pbSendBuffer, cbSendLength,
            currentContextMap->dwClientID, PCSCLITE_WRITE_TIMEOUT);

      if (rv == -1)
      {
            rv = SCARD_E_NO_SERVICE;
            goto end;
      }

      /*
       * Read a message from the server
       */
      rv = SHMMessageReceive(SCARD_CONTROL, &scControlStruct, sizeof(scControlStruct),
            currentContextMap->dwClientID,
            PCSCLITE_READ_TIMEOUT);

      if (rv < 0)
      {
            rv = SCARD_F_COMM_ERROR;
            goto end;
      }

      if (SCARD_S_SUCCESS == scControlStruct.rv)
      {
            /* read the received buffer */
            rv = SHMMessageReceive(SCARD_CONTROL, pbRecvBuffer, scControlStruct.dwBytesReturned,
                  currentContextMap->dwClientID,
                  PCSCLITE_READ_TIMEOUT);

            if (rv < 0)
            {
                  rv = SCARD_E_NO_SERVICE;
                  goto end;
            }

      }

      if (NULL != lpBytesReturned)
            *lpBytesReturned = scControlStruct.dwBytesReturned;

      rv = scControlStruct.rv;

end:
      (void)pthread_mutex_unlock(currentContextMap->mMutex);

      PROFILE_END(rv)

      return rv;
}


Generated by  Doxygen 1.6.0   Back to index