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

static LONG SCardEstablishContextTH ( DWORD  dwScope,
LPCVOID  pvReserved1,
LPCVOID  pvReserved2,
LPSCARDCONTEXT  phContext 
) [static]

Creates a communication context to the PC/SC Resource Manager.

This function shuld not be called directly. Instead, the thread-safe function SCardEstablishContext() should be called.

Parameters:
[in] dwScope Scope of the establishment. This can either be a local or remote connection.
  • SCARD_SCOPE_USER - Not used.
  • SCARD_SCOPE_TERMINAL - Not used.
  • SCARD_SCOPE_GLOBAL - Not used.
  • SCARD_SCOPE_SYSTEM - Services on the local machine.
[in] pvReserved1 Reserved for future use. Can be used for remote connection.
[in] pvReserved2 Reserved for future use.
[out] phContext Returned reference to this connection.
Returns:
Connection status.
Return values:
SCARD_S_SUCCESS Successful.
SCARD_E_NO_SERVICE The server is not runing
SCARD_E_INVALID_PARAMETER phContext is null.
SCARD_E_INVALID_VALUE Invalid scope type passed.

Definition at line 203 of file winscard_clnt.c.

References rxSharedSegment::command, _psContextMap::contextBlockStatus, rxSharedSegment::data, rxSharedSegment::date, _psContextMap::dwClientID, establish_struct::dwScope, rxSharedSegment::group_id, _psChannelMap::hCard, _psContextMap::hContext, isExecuted, version_struct::major, mapAddr, version_struct::minor, _psContextMap::mMutex, rxSharedSegment::mtype, establish_struct::phContext, PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR, _psContextMap::psChannelMap, psContextMap, _psChannelMap::readerName, establish_struct::rv, SCardAddContext(), SCardCheckDaemonAvailability(), SHMClientRead(), SHMClientSetupSession(), SHMMessageReceive(), SHMMessageSend(), SYS_CloseFile(), SYS_GetPageSize(), SYS_Initialize(), SYS_OpenFile(), SYS_PublicMemoryMap(), rxSharedSegment::user_id, and WrapSHMWrite().

Referenced by SCardEstablishContext().

{
      LONG rv;
      int i;
      establish_struct scEstablishStruct;
      sharedSegmentMsg msgStruct;
      DWORD dwClientID = 0;

      if (phContext == NULL)
            return SCARD_E_INVALID_PARAMETER;
      else
            *phContext = 0;

      /* Check if the server is running */
      if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
            return SCARD_E_NO_SERVICE;

      /*
       * Do this only once:
       * - Initialize debug of need.
       * - Set up the memory mapped structures for reader states.
       * - Allocate each reader structure.
       * - Initialize context struct.
       */
      if (isExecuted == 0)
      {
            int pageSize;

            /*
             * Initialize debug
             */
            if (getenv("MUSCLECARD_DEBUG"))
            {
                  DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);
                  DebugLogSetLevel(PCSC_LOG_DEBUG);
            }

            /*
             * Do any system initilization here
             */
            SYS_Initialize();

            /*
             * Set up the memory mapped reader stats structures
             */
            mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
            if (mapAddr < 0)
            {
                  Log2(PCSC_LOG_CRITICAL, "Cannot open public shared file: %s",
                        PCSCLITE_PUBSHM_FILE);
                  return SCARD_E_NO_SERVICE;
            }

            pageSize = SYS_GetPageSize();

            /*
             * Allocate each reader structure in the memory map
             */
            for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
            {
                  readerStates[i] = (PREADER_STATE)
                        SYS_PublicMemoryMap(sizeof(READER_STATE),
                        mapAddr, (i * pageSize));
                  if (readerStates[i] == NULL)
                  {
                        Log1(PCSC_LOG_CRITICAL, "Cannot public memory map");
                        SYS_CloseFile(mapAddr); /* Close the memory map file */
                        return SCARD_F_INTERNAL_ERROR;
                  }
            }

            /*
             * Initializes the application contexts and all channels for each one
             */
            for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
            {
                  int j;

                  /*
                   * Initially set the context struct to zero
                   */
                  psContextMap[i].dwClientID = 0;
                  psContextMap[i].hContext = 0;
                  psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
                  psContextMap[i].mMutex = NULL;

                  for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
                  {
                        /*
                         * Initially set the hcard structs to zero
                         */
                        psContextMap[i].psChannelMap[j].hCard = 0;
                        psContextMap[i].psChannelMap[j].readerName = NULL;
                  }
            }

      }

      /*
       * Is there a free slot for this connection ?
       */

      for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
      {
            if (psContextMap[i].dwClientID == 0)
                  break;
      }

      if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
      {
            return SCARD_E_NO_MEMORY;
      }

      /* Establishes a connection to the server */
      if (SHMClientSetupSession(&dwClientID) != 0)
      {
            SYS_CloseFile(mapAddr);
            return SCARD_E_NO_SERVICE;
      }

      {     /* exchange client/server protocol versions */
            sharedSegmentMsg msgStruct;
            version_struct *veStr;

            memset(&msgStruct, 0, sizeof(msgStruct));
            msgStruct.mtype = CMD_VERSION;
            msgStruct.user_id = SYS_GetUID();
            msgStruct.group_id = SYS_GetGID();
            msgStruct.command = 0;
            msgStruct.date = time(NULL);

            veStr = (version_struct *) msgStruct.data;
            veStr->major = PROTOCOL_VERSION_MAJOR;
            veStr->minor = PROTOCOL_VERSION_MINOR;

            if (-1 == SHMMessageSend(&msgStruct, dwClientID,
                  PCSCLITE_MCLIENT_ATTEMPTS))
                  return SCARD_E_NO_SERVICE;

            /*
             * Read a message from the server
             */
            if (-1 == SHMMessageReceive(&msgStruct, dwClientID,
                  PCSCLITE_CLIENT_ATTEMPTS))
            {
                  Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
                  return SCARD_F_COMM_ERROR;
            }

            Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
                  veStr->major, veStr->minor);

            isExecuted = 1;
      }


      if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
            dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
      {
            return SCARD_E_INVALID_VALUE;
      }

      /*
       * Try to establish an Application Context with the server
       */
      scEstablishStruct.dwScope = dwScope;
      scEstablishStruct.phContext = 0;
      scEstablishStruct.rv = 0;

      rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
            sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
            (void *) &scEstablishStruct);

      if (rv == -1)
            return SCARD_E_NO_SERVICE;

      /*
       * Read the response from the server
       */
      rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);

      if (rv == -1)
            return SCARD_F_COMM_ERROR;

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

      if (scEstablishStruct.rv != SCARD_S_SUCCESS)
            return scEstablishStruct.rv;

      *phContext = scEstablishStruct.phContext;

      /*
       * Allocate the new hContext - if allocator full return an error
       */
      rv = SCardAddContext(*phContext, dwClientID);

      return rv;
}


Generated by  Doxygen 1.6.0   Back to index