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

LONG SCardListReaders ( SCARDCONTEXT  hContext,
LPCSTR  mszGroups,
LPSTR  mszReaders,
LPDWORD  pcchReaders 
)

This function returns a list of currently available readers on the system.

mszReaders is a pointer to a character string that is allocated by the application. If the application sends mszGroups and mszReaders as NULL then this function will return the size of the buffer needed to allocate in pcchReaders.

If *pcchReaders is equal to SCARD_AUTOALLOCATE then the function will allocate itself the needed memory. Use SCardFreeMemory() to release it.

Parameters:
[in]hContextConnection context to the PC/SC Resource Manager.
[in]mszGroupsList of groups to list readers (not used).
[out]mszReadersMulti-string with list of readers.
[in,out]pcchReadersSize of multi-string buffer including NULL's.
Returns:
Connection status.
Return values:
SCARD_S_SUCCESSSuccessful (SCARD_S_SUCCESS)
SCARD_E_INSUFFICIENT_BUFFERReader buffer not large enough (SCARD_E_INSUFFICIENT_BUFFER)
SCARD_E_INVALID_HANDLEInvalid Scope Handle (SCARD_E_INVALID_HANDLE)
SCARD_E_INVALID_PARAMETERpcchReaders is NULL (SCARD_E_INVALID_PARAMETER)
SCARD_E_NO_MEMORYMemory allocation failed (SCARD_E_NO_MEMORY)
SCARD_E_NO_READERS_AVAILABLENo readers available (SCARD_E_NO_READERS_AVAILABLE)
SCARD_E_NO_SERVICEThe server is not runing (SCARD_E_NO_SERVICE)
 SCARDCONTEXT hContext;
 LPSTR mszReaders;
 DWORD dwReaders;
 LONG rv;
 ...
 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
 rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
 mszReaders = malloc(sizeof(char)*dwReaders);
 rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
 SCARDCONTEXT hContext;
 LPSTR mszReaders;
 DWORD dwReaders;
 LONG rv;
 ...
 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
 dwReaders = SCARD_AUTOALLOCATE
 rv = SCardListReaders(hContext, NULL, (LPSTR)&mszReaders, &dwReaders);
 rv = SCardFreeMemory(hContext, mszReaders);

Definition at line 2948 of file winscard_clnt.c.

References PCSCLITE_MAX_READERS_CONTEXTS, SCARD_AUTOALLOCATE, SCARD_E_INSUFFICIENT_BUFFER, SCARD_E_INVALID_HANDLE, SCARD_E_INVALID_PARAMETER, SCARD_E_NO_MEMORY, SCARD_E_NO_READERS_AVAILABLE, SCARD_S_SUCCESS, and SCardGetContext().

{
      DWORD dwReadersLen = 0;
      int i;
      SCONTEXTMAP * currentContextMap;
      LONG rv = SCARD_S_SUCCESS;
      char *buf = NULL;

      (void)mszGroups;
      PROFILE_START
      API_TRACE_IN("%ld", hContext)

      /*
       * Check for NULL parameters
       */
      if (pcchReaders == NULL)
            return SCARD_E_INVALID_PARAMETER;

      CHECK_SAME_PROCESS

      /*
       * Make sure this context has been opened
       */
      currentContextMap = SCardGetContext(hContext);
      if (NULL == currentContextMap)
      {
            PROFILE_END(SCARD_E_INVALID_HANDLE)
            return SCARD_E_INVALID_HANDLE;
      }

      (void)pthread_mutex_lock(currentContextMap->mMutex);

      /* check the context is still opened */
      currentContextMap = SCardGetContext(hContext);
      if (NULL == currentContextMap)
            /* the context is now invalid
             * -> another thread may have called SCardReleaseContext
             * -> so the mMutex has been unlocked */
            return SCARD_E_INVALID_HANDLE;

      /* synchronize reader states with daemon */
      rv = getReaderStates(currentContextMap);
      if (rv != SCARD_S_SUCCESS)
            goto end;

      dwReadersLen = 0;
      for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
            if (readerStates[i].readerName[0] != '\0')
                  dwReadersLen += strlen(readerStates[i].readerName) + 1;

      /* for the last NULL byte */
      dwReadersLen += 1;

      if (1 == dwReadersLen)
      {
            rv = SCARD_E_NO_READERS_AVAILABLE;
            goto end;
      }

      if (SCARD_AUTOALLOCATE == *pcchReaders)
      {
            buf = malloc(dwReadersLen);
            if (NULL == buf)
            {
                  rv = SCARD_E_NO_MEMORY;
                  goto end;
            }
            if (NULL == mszReaders)
            {
                  rv = SCARD_E_INVALID_PARAMETER;
                  goto end;
            }
            *(char **)mszReaders = buf;
      }
      else
      {
            buf = mszReaders;

            /* not enough place to store the reader names */
            if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
            {
                  rv = SCARD_E_INSUFFICIENT_BUFFER;
                  goto end;
            }
      }

      if (mszReaders == NULL) /* text array not allocated */
            goto end;

      for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
      {
            if (readerStates[i].readerName[0] != '\0')
            {
                  /*
                   * Build the multi-string
                   */
                  strcpy(buf, readerStates[i].readerName);
                  buf += strlen(readerStates[i].readerName)+1;
            }
      }
      *buf = '\0';      /* Add the last null */

end:
      /* set the reader names length */
      *pcchReaders = dwReadersLen;

      (void)pthread_mutex_unlock(currentContextMap->mMutex);

      PROFILE_END(rv)
      API_TRACE_OUT("%d", *pcchReaders)

      return rv;
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index