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

LONG MSGFunctionDemarshall ( psharedSegmentMsg  msgStruct,
DWORD  dwContextIndex 
)

Find out which message was sent by the Client and execute the right task.

According to the command type sent by the client (pcsc_msg_commands), cast the message data to the correct struct so that is can be demarshalled. Then call the appropriate function to handle the request.

Possible structs are: establish_struct release_struct connect_struct reconnect_struct disconnect_struct begin_struct cancel_struct end_struct status_struct transmit_struct control_struct getset_struct.

Parameters:
[in] msgStruct Message to be demarshalled and executed.
[in] dwContextIndex 

Definition at line 231 of file winscard_svc.c.

References getset_struct::cbAttrLen, control_struct::cbRecvLength, transmit_struct_extended::cbSendLength, control_struct::cbSendLength, transmit_struct::cbSendLength, rxSharedSegment::command, transmit_struct_extended::data, rxSharedSegment::data, getset_struct::dwAttrId, control_struct::dwBytesReturned, _psContext::dwClientID, control_struct::dwControlCode, end_struct::dwDisposition, disconnect_struct::dwDisposition, reconnect_struct::dwInitialization, reconnect_struct::dwPreferredProtocols, connect_struct::dwPreferredProtocols, establish_struct::dwScope, reconnect_struct::dwShareMode, connect_struct::dwShareMode, transmit_struct_extended::hCard, getset_struct::hCard, control_struct::hCard, transmit_struct::hCard, status_struct::hCard, cancel_struct::hCard, end_struct::hCard, begin_struct::hCard, disconnect_struct::hCard, reconnect_struct::hCard, connect_struct::hContext, release_struct::hContext, MAX_BUFFER_SIZE_EXTENDED, status_struct::mszReaderNames, status_struct::pbAtr, getset_struct::pbAttr, control_struct::pbRecvBuffer, transmit_struct::pbRecvBuffer, control_struct::pbSendBuffer, transmit_struct::pbSendBuffer, status_struct::pcbAtrLen, transmit_struct_extended::pcbRecvLength, transmit_struct::pcbRecvLength, status_struct::pcchReaderLen, PCSCLITE_MAX_MESSAGE_SIZE, PCSCLITE_SERVER_ATTEMPTS, reconnect_struct::pdwActiveProtocol, connect_struct::pdwActiveProtocol, status_struct::pdwProtocol, status_struct::pdwState, connect_struct::phCard, establish_struct::phContext, transmit_struct_extended::pioRecvPci, transmit_struct::pioRecvPci, transmit_struct_extended::pioSendPci, transmit_struct::pioSendPci, psContext, transmit_struct_extended::rv, getset_struct::rv, control_struct::rv, transmit_struct::rv, status_struct::rv, cancel_struct::rv, end_struct::rv, begin_struct::rv, disconnect_struct::rv, reconnect_struct::rv, connect_struct::rv, release_struct::rv, establish_struct::rv, SCardBeginTransaction(), SCardCancelTransaction(), SCardConnect(), SCardControl(), SCardDisconnect(), SCardEndTransaction(), SCardEstablishContext(), SCardGetAttrib(), SCardReconnect(), SCardReleaseContext(), SCardSetAttrib(), SCardStatus(), SCardTransmit(), SHMMessageReceive(), SHMMessageSend(), transmit_struct_extended::size, and connect_struct::szReader.

Referenced by ContextThread().

{
      LONG rv;
      establish_struct *esStr;
      release_struct *reStr;
      connect_struct *coStr;
      reconnect_struct *rcStr;
      disconnect_struct *diStr;
      begin_struct *beStr;
      cancel_struct *caStr;
      end_struct *enStr;
      status_struct *stStr;
      transmit_struct *trStr;
      control_struct *ctStr;
      getset_struct *gsStr;

      /*
       * Zero out everything 
       */
      rv = 0;
      switch (msgStruct->command)
      {

      case SCARD_ESTABLISH_CONTEXT:
            esStr = ((establish_struct *) msgStruct->data);
            esStr->rv = SCardEstablishContext(esStr->dwScope, 0, 0,
                  &esStr->phContext);

            if (esStr->rv == SCARD_S_SUCCESS)
                  esStr->rv =
                        MSGAddContext(esStr->phContext, dwContextIndex);
            break;

      case SCARD_RELEASE_CONTEXT:
            reStr = ((release_struct *) msgStruct->data);
            reStr->rv = SCardReleaseContext(reStr->hContext);

            if (reStr->rv == SCARD_S_SUCCESS)
                  reStr->rv =
                        MSGRemoveContext(reStr->hContext, dwContextIndex);

            break;

      case SCARD_CONNECT:
            coStr = ((connect_struct *) msgStruct->data);
            coStr->rv = SCardConnect(coStr->hContext, coStr->szReader,
                  coStr->dwShareMode, coStr->dwPreferredProtocols,
                  &coStr->phCard, &coStr->pdwActiveProtocol);

            if (coStr->rv == SCARD_S_SUCCESS)
                  coStr->rv =
                        MSGAddHandle(coStr->hContext, coStr->phCard, dwContextIndex);

            break;

      case SCARD_RECONNECT:
            rcStr = ((reconnect_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex);
            if (rv != 0) return rv;

            rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode,
                  rcStr->dwPreferredProtocols,
                  rcStr->dwInitialization, &rcStr->pdwActiveProtocol);
            break;

      case SCARD_DISCONNECT:
            diStr = ((disconnect_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(diStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            diStr->rv = SCardDisconnect(diStr->hCard, diStr->dwDisposition);

            if (diStr->rv == SCARD_S_SUCCESS)
                  diStr->rv =
                        MSGRemoveHandle(diStr->hCard, dwContextIndex);
            break;

      case SCARD_BEGIN_TRANSACTION:
            beStr = ((begin_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(beStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            beStr->rv = SCardBeginTransaction(beStr->hCard);
            break;

      case SCARD_END_TRANSACTION:
            enStr = ((end_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(enStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            enStr->rv =
                  SCardEndTransaction(enStr->hCard, enStr->dwDisposition);
            break;

      case SCARD_CANCEL_TRANSACTION:
            caStr = ((cancel_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(caStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            caStr->rv = SCardCancelTransaction(caStr->hCard);
            break;

      case SCARD_STATUS:
            stStr = ((status_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(stStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames,
                  &stStr->pcchReaderLen, &stStr->pdwState,
                  &stStr->pdwProtocol, stStr->pbAtr, &stStr->pcbAtrLen);
            break;

      case SCARD_TRANSMIT:
            trStr = ((transmit_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            trStr->rv = SCardTransmit(trStr->hCard, &trStr->pioSendPci,
                  trStr->pbSendBuffer, trStr->cbSendLength,
                  &trStr->pioRecvPci, trStr->pbRecvBuffer,
                  &trStr->pcbRecvLength);
            break;

      case SCARD_CONTROL:
            ctStr = ((control_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode,
                  ctStr->pbSendBuffer, ctStr->cbSendLength,
                  ctStr->pbRecvBuffer, ctStr->cbRecvLength,
                  &ctStr->dwBytesReturned);
            break;

      case SCARD_GET_ATTRIB:
            gsStr = ((getset_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            gsStr->rv = SCardGetAttrib(gsStr->hCard, gsStr->dwAttrId,
                  gsStr->pbAttr, &gsStr->cbAttrLen);
            break;

      case SCARD_SET_ATTRIB:
            gsStr = ((getset_struct *) msgStruct->data);
            rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
            if (rv != 0) return rv;
            gsStr->rv = SCardSetAttrib(gsStr->hCard, gsStr->dwAttrId,
                  gsStr->pbAttr, gsStr->cbAttrLen);
            break;

      case SCARD_TRANSMIT_EXTENDED:
            {
                  transmit_struct_extended *treStr;
                  unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
                  unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];

                  treStr = ((transmit_struct_extended *) msgStruct->data);
                  rv = MSGCheckHandleAssociation(treStr->hCard, dwContextIndex);
                  if (rv != 0) return rv;

                  /* on more block to read? */
                  if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
                  {
                        /* copy the first APDU part */
                        memcpy(pbSendBuffer, treStr->data,
                              PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr));

                        /* receive the second block */
                        rv = SHMMessageReceive(
                              pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr),
                              treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
                              psContext[dwContextIndex].dwClientID,
                              PCSCLITE_SERVER_ATTEMPTS);
                        if (rv)
                              Log1(PCSC_LOG_CRITICAL, "reception failed");
                  }
                  else
                        memcpy(pbSendBuffer, treStr->data, treStr->cbSendLength);

                  treStr->rv = SCardTransmit(treStr->hCard, &treStr->pioSendPci,
                        pbSendBuffer, treStr->cbSendLength,
                        &treStr->pioRecvPci, pbRecvBuffer,
                        &treStr->pcbRecvLength);

                  treStr->size = sizeof(*treStr) + treStr->pcbRecvLength;
                  if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
                  {
                        /* two blocks */
                        memcpy(treStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
                              - sizeof(*treStr));

                        rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
                              psContext[dwContextIndex].dwClientID,
                              PCSCLITE_SERVER_ATTEMPTS);
                        if (rv)
                              Log1(PCSC_LOG_CRITICAL, "transmission failed");

                        rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
                              - sizeof(*treStr),
                              treStr->size - PCSCLITE_MAX_MESSAGE_SIZE, 
                              psContext[dwContextIndex].dwClientID,
                              PCSCLITE_SERVER_ATTEMPTS);
                        if (rv)
                              Log1(PCSC_LOG_CRITICAL, "transmission failed");
                  }
                  else
                  {
                        /* one block only */
                        memcpy(treStr->data, pbRecvBuffer, treStr->pcbRecvLength);

                        rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
                              psContext[dwContextIndex].dwClientID,
                              PCSCLITE_SERVER_ATTEMPTS);
                        if (rv)
                              Log1(PCSC_LOG_CRITICAL, "transmission failed");
                  }
            }
            break;

      default:
            Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command);
            return -1;
      }

      return 0;
}


Generated by  Doxygen 1.6.0   Back to index