Changeset 3481

Show
Ignore:
Timestamp:
04/20/08 11:59:23 (6 months ago)
Author:
alonbl
Message:

Initial Plug&Play support

Add detect_readers() to reader opts.
Add sc_ctx_detect_readers() that calls readers' detect_readers().
Allow context to be created without readers.
Call sc_ctx_detect_readers() from PKCS#11 C_GetSlotList with NULL_PTR.

Since I broke ABI, I updated the external module version requirement
to match OpenSC version. In the future a separate version should be
maintaind for each interface, this should be unrelated to the package
version.

Location:
branches/alonbl/pnp/src
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • branches/alonbl/pnp/src/libopensc/ctx.c

    r3405 r3481  
    355355        /* verify module version */ 
    356356        version = modversion(); 
    357         if (version == NULL || strncmp(version, "0.9.", strlen("0.9.")) > 0) { 
     357        /* XXX: We really need to have ABI version for each interface */ 
     358        if (version == NULL || strncmp(version, PACKAGE_VERSION, strlen(PACKAGE_VERSION)) != 0) { 
    358359                sc_error(ctx,"dynamic library '%s': invalid module version\n",libname); 
    359360                lt_dlclose(handle); 
     
    638639} 
    639640 
     641int sc_ctx_detect_readers(sc_context_t *ctx) 
     642{ 
     643        int i; 
     644 
     645        sc_mutex_lock(ctx, ctx->mutex); 
     646 
     647        for (i = 0; ctx->reader_drivers[i] != NULL; i++) { 
     648                const struct sc_reader_driver *drv = ctx->reader_drivers[i]; 
     649 
     650                if (drv->ops->detect_readers != NULL) 
     651                        drv->ops->detect_readers(ctx, ctx->reader_drv_data[i]); 
     652        } 
     653 
     654        sc_mutex_unlock(ctx, ctx->mutex); 
     655 
     656        /* XXX: Do not ignore erros? */ 
     657        return SC_SUCCESS; 
     658} 
     659 
    640660sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i) 
    641661{ 
     
    725745        del_drvs(&opts, 0); 
    726746        del_drvs(&opts, 1); 
    727         if (ctx->reader_count == 0) { 
    728                 sc_release_context(ctx); 
    729                 return SC_ERROR_NO_READERS_FOUND; 
    730         } 
     747        sc_ctx_detect_readers(ctx); 
    731748        *ctx_out = ctx; 
    732749        return SC_SUCCESS; 
  • branches/alonbl/pnp/src/libopensc/libopensc.exports

    r3478 r3481  
    3838sc_copy_asn1_entry 
    3939sc_create_file 
     40sc_ctx_detect_readers 
    4041sc_ctx_get_reader 
    4142sc_ctx_get_reader_count 
  • branches/alonbl/pnp/src/libopensc/opensc.h

    r3304 r3481  
    374374         * deallocate the private data and any resources. */ 
    375375        int (*finish)(struct sc_context *ctx, void *priv_data); 
     376        /* Called when library wish to detect new readers 
     377         * should add only new readers. */ 
     378        int (*detect_readers)(struct sc_context *ctx, void *priv_data); 
    376379        /* Called when releasing a reader.  release() has to 
    377380         * deallocate the private data.  Other fields will be 
     
    726729 */ 
    727730int sc_release_context(sc_context_t *ctx); 
     731 
     732/** 
     733 * Detect new readers available on system. 
     734 * @param  ctx  OpenSC context 
     735 * @return SC_SUCCESS on success and an error code otherwise. 
     736 */ 
     737int sc_ctx_detect_readers(sc_context_t *ctx); 
    728738 
    729739/** 
  • branches/alonbl/pnp/src/libopensc/reader-ctapi.c

    r3084 r3481  
    608608} 
    609609 
     610static int ctapi_detect_readers(sc_context_t *ctx, void *prv_data) 
     611{ 
     612        return 0; 
     613} 
     614 
    610615struct sc_reader_driver * sc_get_ctapi_driver(void) 
    611616{ 
    612617        ctapi_ops.init = ctapi_init; 
    613618        ctapi_ops.finish = ctapi_finish; 
     619        ctapi_ops.detect_readers = ctapi_detect_readers; 
    614620        ctapi_ops.transmit = ctapi_transmit; 
    615621        ctapi_ops.detect_card_presence = ctapi_detect_card_presence; 
  • branches/alonbl/pnp/src/libopensc/reader-openct.c

    r3405 r3481  
    167167 
    168168/* 
     169 * We do not support Plug&Play here 
     170 */ 
     171static int openct_reader_detect_readers(sc_context_t *ctx, void *priv_data) 
     172{ 
     173        return SC_NO_ERROR; 
     174} 
     175 
     176/* 
    169177 * Called when releasing a reader.  release() has to 
    170178 * deallocate the private data.  Other fields will be 
     
    480488        openct_ops.init = openct_reader_init; 
    481489        openct_ops.finish = openct_reader_finish; 
     490        openct_ops.detect_readers = openct_reader_detect_readers; 
    482491        openct_ops.release = openct_reader_release; 
    483492        openct_ops.detect_card_presence = openct_reader_detect_card_presence; 
  • branches/alonbl/pnp/src/libopensc/reader-pcsc.c

    r3455 r3481  
    732732{ 
    733733        LONG rv; 
    734         DWORD reader_buf_size; 
    735         char *reader_buf = NULL, *p; 
    736         const char *mszGroups = NULL; 
    737         int r; 
    738734        struct pcsc_global_private_data *gpriv; 
    739735        scconf_block *conf_block = NULL; 
     
    825821                goto out; 
    826822        } 
     823 
     824        *reader_data = gpriv; 
     825        gpriv = NULL; 
     826        ret = SC_SUCCESS; 
     827 
     828out: 
     829        if (ret != SC_SUCCESS) { 
     830                if (gpriv->pcsc_ctx != 0) 
     831                        gpriv->SCardReleaseContext(gpriv->pcsc_ctx); 
     832                if (gpriv->dlhandle != NULL) 
     833                        lt_dlclose(gpriv->dlhandle); 
     834                if (gpriv != NULL) 
     835                        free(gpriv); 
     836        } 
     837 
     838        return 0; 
     839} 
     840 
     841static int pcsc_finish(sc_context_t *ctx, void *prv_data) 
     842{ 
     843        struct pcsc_global_private_data *priv = (struct pcsc_global_private_data *) prv_data; 
     844 
     845        if (priv) { 
     846                priv->SCardReleaseContext(priv->pcsc_ctx); 
     847                lt_dlclose(priv->dlhandle); 
     848                free(priv); 
     849        } 
     850 
     851        return 0; 
     852} 
     853 
     854static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) 
     855{ 
     856        struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; 
     857        LONG rv; 
     858        DWORD reader_buf_size; 
     859        char *reader_buf = NULL, *p; 
     860        const char *mszGroups = NULL; 
     861        int ret = SC_ERROR_INTERNAL; 
     862 
    827863        rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL, 
    828864                              (LPDWORD) &reader_buf_size); 
    829         if (rv != SCARD_S_SUCCESS || reader_buf_size < 2) { 
    830                 ret = pcsc_ret_to_error(rv);    /* No readers configured */ 
     865        if (rv != SCARD_S_SUCCESS) { 
     866                ret = pcsc_ret_to_error(rv); 
    831867                goto out; 
    832868        } 
     
    843879                goto out; 
    844880        } 
    845         p = reader_buf; 
    846         do { 
    847                 sc_reader_t *reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t)); 
    848                 struct pcsc_private_data *priv = (struct pcsc_private_data *) malloc(sizeof(struct pcsc_private_data)); 
    849                 struct pcsc_slot_data *pslot = (struct pcsc_slot_data *) malloc(sizeof(struct pcsc_slot_data)); 
    850                 sc_slot_info_t *slot; 
    851  
    852                 if (reader == NULL || priv == NULL || pslot == NULL) { 
    853                         if (reader) 
    854                                 free(reader); 
    855                         if (priv) 
    856                                 free(priv); 
    857                         if (pslot) 
    858                                 free(pslot); 
    859                         break; 
     881        for (p = reader_buf; *p != '\x0'; p += strlen (p) + 1) { 
     882                sc_reader_t *reader = NULL; 
     883                struct pcsc_private_data *priv = NULL; 
     884                struct pcsc_slot_data *pslot = NULL; 
     885                sc_slot_info_t *slot = NULL; 
     886                int i; 
     887                int found = 0; 
     888 
     889                for (i=0;i < sc_ctx_get_reader_count (ctx) && !found;i++) { 
     890                        sc_reader_t *reader = sc_ctx_get_reader (ctx, i); 
     891                        if (reader == NULL) { 
     892                                ret = SC_ERROR_INTERNAL; 
     893                                goto err1; 
     894                        } 
     895                        if (reader->ops == &pcsc_ops && !strcmp (reader->name, p)) { 
     896                                found = 1; 
     897                        } 
     898                } 
     899 
     900                /* Reader already available, skip */ 
     901                if (found) { 
     902                        continue; 
     903                } 
     904 
     905                if ((reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t))) == NULL) { 
     906                        ret = SC_ERROR_OUT_OF_MEMORY; 
     907                        goto err1; 
     908                } 
     909                if ((priv = (struct pcsc_private_data *) malloc(sizeof(struct pcsc_private_data))) == NULL) { 
     910                        ret = SC_ERROR_OUT_OF_MEMORY; 
     911                        goto err1; 
     912                } 
     913                if ((pslot = (struct pcsc_slot_data *) malloc(sizeof(struct pcsc_slot_data))) == NULL) { 
     914                        ret = SC_ERROR_OUT_OF_MEMORY; 
     915                        goto err1; 
    860916                } 
    861917 
     
    864920                reader->driver = &pcsc_drv; 
    865921                reader->slot_count = 1; 
    866                 reader->name = strdup(p); 
     922                if ((reader->name = strdup(p)) == NULL) { 
     923                        ret = SC_ERROR_OUT_OF_MEMORY; 
     924                        goto err1; 
     925                } 
    867926                priv->gpriv = gpriv; 
    868                 priv->reader_name = strdup(p); 
    869                 r = _sc_add_reader(ctx, reader); 
    870                 if (r) { 
    871                         free(priv->reader_name); 
    872                         free(priv); 
    873                         free(reader->name); 
    874                         free(reader); 
    875                         free(pslot); 
    876                         break; 
     927                if ((priv->reader_name = strdup(p)) == NULL) { 
     928                        ret = SC_ERROR_OUT_OF_MEMORY; 
     929                        goto err1; 
    877930                } 
    878931                slot = &reader->slot[0]; 
     
    880933                slot->drv_data = pslot; 
    881934                memset(pslot, 0, sizeof(*pslot)); 
     935                if (_sc_add_reader(ctx, reader)) { 
     936                        ret = SC_SUCCESS;       /* silent ignore */ 
     937                        goto err1; 
     938                } 
    882939                refresh_slot_attributes(reader, slot); 
    883940 
    884                 while (*p++ != 0); 
    885         } while (p < (reader_buf + reader_buf_size - 1)); 
    886  
    887         *reader_data = gpriv; 
    888         gpriv = NULL; 
     941                continue; 
     942         
     943        err1: 
     944                if (priv != NULL) { 
     945                        if (priv->reader_name) 
     946                                free(priv->reader_name); 
     947                        free(priv); 
     948                } 
     949                if (reader != NULL) { 
     950                        if (reader->name) 
     951                                free(reader->name); 
     952                        free(reader); 
     953                } 
     954                if (slot != NULL) 
     955                        free(pslot); 
     956 
     957                goto out; 
     958        } 
     959 
    889960        ret = SC_SUCCESS; 
    890961 
    891962out: 
    892         if (ret != SC_SUCCESS) { 
    893                 if (gpriv->pcsc_ctx != 0) 
    894                         gpriv->SCardReleaseContext(gpriv->pcsc_ctx); 
    895                 if (reader_buf != NULL) 
    896                         free(reader_buf); 
    897                 if (gpriv->dlhandle != NULL) 
    898                         lt_dlclose(gpriv->dlhandle); 
    899                 if (gpriv != NULL) 
    900                         free(gpriv); 
    901         } 
    902  
    903         return 0; 
    904 } 
    905  
    906 static int pcsc_finish(sc_context_t *ctx, void *prv_data) 
    907 { 
    908         struct pcsc_global_private_data *priv = (struct pcsc_global_private_data *) prv_data; 
    909  
    910         if (priv) { 
    911                 priv->SCardReleaseContext(priv->pcsc_ctx); 
    912                 lt_dlclose(priv->dlhandle); 
    913                 free(priv); 
    914         } 
    915  
    916         return 0; 
     963 
     964        if (reader_buf != NULL) 
     965                free (reader_buf); 
     966 
     967        return ret; 
    917968} 
    918969 
     
    932983        pcsc_ops.init = pcsc_init; 
    933984        pcsc_ops.finish = pcsc_finish; 
     985        pcsc_ops.detect_readers = pcsc_detect_readers; 
    934986        pcsc_ops.transmit = pcsc_transmit; 
    935987        pcsc_ops.detect_card_presence = pcsc_detect_card_presence; 
  • branches/alonbl/pnp/src/pkcs11/pkcs11-global.c

    r3459 r3481  
    348348 
    349349        sc_debug(context, "Getting slot listing\n"); 
     350        if (pSlotList == NULL_PTR) { 
     351                sc_ctx_detect_readers(context); 
     352        } 
    350353        card_detect_all(); 
    351354