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 
)

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.

Parameters:
[in]hCardConnection made from SCardConnect().
[in]dwControlCodeControl code for the operation.
Click here for a list of supported commands by some drivers.
[in]pbSendBufferCommand to send to the reader.
[in]cbSendLengthLength of the command.
[out]pbRecvBufferResponse from the reader.
[in]cbRecvLengthLength of the response buffer.
[out]lpBytesReturnedLength of the response.
Returns:
Error code.
Return values:
SCARD_S_SUCCESSSuccessful (SCARD_S_SUCCESS)
SCARD_E_INSUFFICIENT_BUFFERcbSendLength or cbRecvLength are too big (SCARD_E_INSUFFICIENT_BUFFER)
SCARD_E_INVALID_HANDLEInvalid hCard handle (SCARD_E_INVALID_HANDLE)
SCARD_E_INVALID_PARAMETERpbSendBuffer is NULL or cbSendLength is null and the IFDHandler is version 2.0 (without dwControlCode) (SCARD_E_INVALID_PARAMETER)
SCARD_E_INVALID_VALUEInvalid value was presented (SCARD_E_INVALID_VALUE)
SCARD_E_NO_SERVICEThe server is not running (SCARD_E_NO_SERVICE)
SCARD_E_NOT_TRANSACTEDData exchange not successful (SCARD_E_NOT_TRANSACTED)
SCARD_E_READER_UNAVAILABLEThe reader has been removed(SCARD_E_READER_UNAVAILABLE)
SCARD_E_UNSUPPORTED_FEATUREDriver does not support (SCARD_E_UNSUPPORTED_FEATURE)
SCARD_F_COMM_ERRORAn internal communications error has been detected (SCARD_F_COMM_ERROR)
SCARD_W_REMOVED_CARDThe card has been removed from the reader(SCARD_W_REMOVED_CARD)
SCARD_W_RESET_CARDThe 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 2252 of file winscard_clnt.c.

References IFDControl(), MAX_BUFFER_SIZE_EXTENDED, MessageReceive(), MessageSend(), MessageSendWithHeader(), SCARD_CONTROL, SCARD_E_INSUFFICIENT_BUFFER, SCARD_E_INVALID_HANDLE, SCARD_E_INVALID_PARAMETER, SCARD_E_UNSUPPORTED_FEATURE, SCARD_S_SUCCESS, and ReaderContext::version.

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

      PROFILE_START

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

      /*
       * 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;
      scControlStruct.dwBytesReturned = 0;
      scControlStruct.rv = 0;

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

      if (rv != SCARD_S_SUCCESS)
            goto end;

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

      if (rv != SCARD_S_SUCCESS)
            goto end;

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

      if (rv != SCARD_S_SUCCESS)
            goto end;

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

            if (rv != SCARD_S_SUCCESS)
                  goto end;

      }

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

      rv = scControlStruct.rv;

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

      PROFILE_END(rv)

      return rv;
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index