Fix #216: initial go with multiple reader subsystem removal.

* One sc_context has only a single reader driver.
 * remove dynamic reader driver loading capabilities
 * remove opensc-tool -R command
 * change the internal API, we don't need to pass around a "driver data" pointer as it can be found directly from the context.
 * check in ./configure for only a single enabled reader driver

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4709 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2010-09-11 13:00:47 +00:00
parent 0858a5c854
commit 72d961beb2
9 changed files with 105 additions and 263 deletions

View File

@ -205,7 +205,15 @@ AC_ARG_WITH(
, ,
[with_pcsc_provider="detect"] [with_pcsc_provider="detect"]
) )
dnl ./configure check
reader_count=""
for rdriver in "${enable_pcsc}" "${enable_openct}" "${enable_ctapi}"; do
test "${rdriver}" = "yes" && reader_count="${reader_count}x"
done
if test "${reader_count}" != "x"; then
AC_MSG_ERROR([Only one of --enable-pcsc, --enable-openct, --enable-ctapi can be specified!])
fi
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CPP AC_PROG_CPP
AC_PROG_INSTALL AC_PROG_INSTALL

View File

@ -66,10 +66,6 @@ format</para></listitem>
<term><option>--list-drivers, -D</option></term> <term><option>--list-drivers, -D</option></term>
<listitem><para>Lists all installed card drivers</para></listitem> <listitem><para>Lists all installed card drivers</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--list-rdrivers, -R</option></term>
<listitem><para>Lists all installed reader drivers</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--reader</option> num, <option>-r</option> num</term> <term><option>--reader</option> num, <option>-r</option> num</term>
<listitem><para>Use the given reader number. The default is 0, the first reader <listitem><para>Use the given reader number. The default is 0, the first reader

View File

@ -28,18 +28,7 @@ app default {
# #
# profile_dir = @pkgdatadir@; # profile_dir = @pkgdatadir@;
# What reader drivers to load at start-up # CT-API module configuration.
#
# A special value of 'internal' will load all
# statically linked drivers. If an unknown (ie. not
# internal) driver is supplied, a separate configuration
# configuration block has to be written for the driver.
# Default: internal
# NOTE: if "internal" keyword is used, must be the
# last entry in reader_drivers list
#
# reader_drivers = openct, pcsc, ctapi;
reader_driver ctapi { reader_driver ctapi {
# module /usr/local/towitoko/lib/libtowitoko.so { # module /usr/local/towitoko/lib/libtowitoko.so {
# CT-API ports: # CT-API ports:
@ -51,11 +40,7 @@ app default {
# } # }
} }
# Define parameters specific to your readers. # The following section shows definitions for PC/SC readers.
# The following section shows definitions for PC/SC readers,
# but the same set of variables are applicable to ctapi and
# openct readers, simply by using "reader_driver ctapi" and
# "reader_driver openct", respectively.
reader_driver pcsc { reader_driver pcsc {
# This sets the maximum send and receive sizes. # This sets the maximum send and receive sizes.
# Some reader drivers have limitations, so you need # Some reader drivers have limitations, so you need
@ -431,7 +416,7 @@ app tokend {
app cardmod { app cardmod {
#allow only cardmodule pcsc reader for minidriver (mandatory) #allow only cardmodule pcsc reader for minidriver (mandatory)
reader_drivers = cardmod; # FIXME cardmod pcsc hack is now broken.
reader_driver cardmod { reader_driver cardmod {
# Enable pinpad if detected (PC/SC v2.0.2 Part 10) # Enable pinpad if detected (PC/SC v2.0.2 Part 10)

View File

@ -98,21 +98,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static const struct _sc_driver_entry internal_reader_drivers[] = {
#ifdef ENABLE_PCSC
{ "pcsc", (void *(*)(void)) sc_get_pcsc_driver },
#endif
#ifdef ENABLE_CTAPI
{ "ctapi", (void *(*)(void)) sc_get_ctapi_driver },
#endif
#ifndef _WIN32
#ifdef ENABLE_OPENCT
{ "openct", (void *(*)(void)) sc_get_openct_driver },
#endif
#endif
{ NULL, NULL }
};
struct _sc_ctx_options { struct _sc_ctx_options {
struct _sc_driver_entry rdrv[SC_MAX_READER_DRIVERS]; struct _sc_driver_entry rdrv[SC_MAX_READER_DRIVERS];
int rcount; int rcount;
@ -132,38 +117,28 @@ static int reader_list_seeker(const void *el, const void *key) {
return 0; return 0;
} }
static void del_drvs(struct _sc_ctx_options *opts, int type) static void del_drvs(struct _sc_ctx_options *opts)
{ {
struct _sc_driver_entry *lst; struct _sc_driver_entry *lst;
int *cp, i; int *cp, i;
if (type == 0) { lst = opts->cdrv;
lst = opts->rdrv; cp = &opts->ccount;
cp = &opts->rcount;
} else {
lst = opts->cdrv;
cp = &opts->ccount;
}
for (i = 0; i < *cp; i++) { for (i = 0; i < *cp; i++) {
free((void *)lst[i].name); free((void *)lst[i].name);
} }
*cp = 0; *cp = 0;
} }
static void add_drv(struct _sc_ctx_options *opts, int type, const char *name) static void add_drv(struct _sc_ctx_options *opts, const char *name)
{ {
struct _sc_driver_entry *lst; struct _sc_driver_entry *lst;
int *cp, max, i; int *cp, max, i;
if (type == 0) { lst = opts->cdrv;
lst = opts->rdrv; cp = &opts->ccount;
cp = &opts->rcount; max = SC_MAX_CARD_DRIVERS;
max = SC_MAX_READER_DRIVERS;
} else {
lst = opts->cdrv;
cp = &opts->ccount;
max = SC_MAX_CARD_DRIVERS;
}
if (*cp == max) /* No space for more drivers... */ if (*cp == max) /* No space for more drivers... */
return; return;
for (i = 0; i < *cp; i++) for (i = 0; i < *cp; i++)
@ -174,18 +149,15 @@ static void add_drv(struct _sc_ctx_options *opts, int type, const char *name)
*cp = *cp + 1; *cp = *cp + 1;
} }
static void add_internal_drvs(struct _sc_ctx_options *opts, int type) static void add_internal_drvs(struct _sc_ctx_options *opts)
{ {
const struct _sc_driver_entry *lst; const struct _sc_driver_entry *lst;
int i; int i;
if (type == 0) lst = internal_card_drivers;
lst = internal_reader_drivers;
else
lst = internal_card_drivers;
i = 0; i = 0;
while (lst[i].name != NULL) { while (lst[i].name != NULL) {
add_drv(opts, type, lst[i].name); add_drv(opts, lst[i].name);
i++; i++;
} }
} }
@ -203,8 +175,7 @@ static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts)
ctx->debug_file = fopen("/tmp/opensc-tokend.log", "a"); ctx->debug_file = fopen("/tmp/opensc-tokend.log", "a");
#endif #endif
ctx->forced_driver = NULL; ctx->forced_driver = NULL;
add_internal_drvs(opts, 0); add_internal_drvs(opts);
add_internal_drvs(opts, 1);
} }
static int load_parameters(sc_context_t *ctx, scconf_block *block, static int load_parameters(sc_context_t *ctx, scconf_block *block,
@ -237,58 +208,34 @@ static int load_parameters(sc_context_t *ctx, scconf_block *block,
free(opts->forced_card_driver); free(opts->forced_card_driver);
opts->forced_card_driver = strdup(val); opts->forced_card_driver = strdup(val);
} }
list = scconf_find_list(block, "reader_drivers");
if (list != NULL)
del_drvs(opts, 0);
while (list != NULL) {
if (strcmp(list->data, s_internal) == 0)
add_internal_drvs(opts, 0);
else
add_drv(opts, 0, list->data);
list = list->next;
}
list = scconf_find_list(block, "card_drivers"); list = scconf_find_list(block, "card_drivers");
if (list != NULL) if (list != NULL)
del_drvs(opts, 1); del_drvs(opts);
while (list != NULL) { while (list != NULL) {
if (strcmp(list->data, s_internal) == 0) if (strcmp(list->data, s_internal) == 0)
add_internal_drvs(opts, 1); add_internal_drvs(opts);
else else
add_drv(opts, 1, list->data); add_drv(opts, list->data);
list = list->next; list = list->next;
} }
return err; return err;
} }
static void load_reader_driver_options(sc_context_t *ctx, static void load_reader_driver_options(sc_context_t *ctx)
struct sc_reader_driver *driver)
{ {
const char *name = driver->short_name; struct sc_reader_driver *driver = ctx->reader_driver;
scconf_block *conf_block = NULL; scconf_block *conf_block = NULL;
int i;
for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
scconf_block **blocks;
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
"reader_driver", name);
if (blocks) {
conf_block = blocks[0];
free(blocks);
}
if (conf_block != NULL)
break;
}
driver->max_send_size = SC_DEFAULT_MAX_SEND_SIZE; driver->max_send_size = SC_DEFAULT_MAX_SEND_SIZE;
driver->max_recv_size = SC_DEFAULT_MAX_RECV_SIZE; driver->max_recv_size = SC_DEFAULT_MAX_RECV_SIZE;
conf_block = sc_get_conf_block(ctx, "reader_driver", driver->name, 1);
if (conf_block != NULL) { if (conf_block != NULL) {
driver->max_send_size = scconf_get_int(conf_block, driver->max_send_size = scconf_get_int(conf_block, "max_send_size", driver->max_send_size);
"max_send_size", SC_DEFAULT_MAX_SEND_SIZE); driver->max_recv_size = scconf_get_int(conf_block, "max_recv_size", driver->max_recv_size);
driver->max_recv_size = scconf_get_int(conf_block,
"max_recv_size", SC_DEFAULT_MAX_RECV_SIZE);
} }
} }
@ -296,15 +243,14 @@ static void load_reader_driver_options(sc_context_t *ctx,
* find library module for provided driver in configuration file * find library module for provided driver in configuration file
* if not found assume library name equals to module name * if not found assume library name equals to module name
*/ */
static const char *find_library(sc_context_t *ctx, const char *name, int type) static const char *find_library(sc_context_t *ctx, const char *name)
{ {
int i; int i;
const char *libname = NULL; const char *libname = NULL;
scconf_block **blocks, *blk; scconf_block **blocks, *blk;
for (i = 0; ctx->conf_blocks[i]; i++) { for (i = 0; ctx->conf_blocks[i]; i++) {
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", name);
(type==0) ? "reader_driver" : "card_driver", name);
if (!blocks) if (!blocks)
continue; continue;
blk = blocks[0]; blk = blocks[0];
@ -332,12 +278,8 @@ static const char *find_library(sc_context_t *ctx, const char *name, int type)
* that returns a pointer to the function _sc_get_xxxx_driver() * that returns a pointer to the function _sc_get_xxxx_driver()
* used to initialize static modules * used to initialize static modules
* Also, an exported "char *sc_module_version" variable should exist in module * Also, an exported "char *sc_module_version" variable should exist in module
*
* type == 0 -> reader driver
* type == 1 -> card driver
*/ */
static void *load_dynamic_driver(sc_context_t *ctx, void **dll, static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name)
const char *name, int type)
{ {
const char *version, *libname; const char *version, *libname;
lt_dlhandle handle; lt_dlhandle handle;
@ -350,7 +292,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"No module specified\n",name); sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"No module specified\n",name);
return NULL; return NULL;
} }
libname = find_library(ctx, name, type); libname = find_library(ctx, name);
if (libname == NULL) if (libname == NULL)
return NULL; return NULL;
handle = lt_dlopen(libname); handle = lt_dlopen(libname);
@ -376,57 +318,10 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
return NULL; return NULL;
} }
*dll = handle; *dll = handle;
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "successfully loaded %s driver '%s'\n", sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "successfully loaded card driver '%s'\n", name);
type ? "card" : "reader", name);
return modinit(name); return modinit(name);
} }
static int load_reader_drivers(sc_context_t *ctx,
struct _sc_ctx_options *opts)
{
const struct _sc_driver_entry *ent;
int drv_count;
int i;
for (drv_count = 0; ctx->reader_drivers[drv_count] != NULL; drv_count++);
for (i = 0; i < opts->rcount; i++) {
struct sc_reader_driver *driver;
struct sc_reader_driver *(*func)(void) = NULL;
struct sc_reader_driver *(**tfunc)(void) = &func;
int j;
void *dll = NULL;
ent = &opts->rdrv[i];
for (j = 0; internal_reader_drivers[j].name != NULL; j++)
if (strcmp(ent->name, internal_reader_drivers[j].name) == 0) {
func = (struct sc_reader_driver *(*)(void)) internal_reader_drivers[j].func;
break;
}
#ifdef ENABLE_CARDMOD
/* carmod reader driver is subset of pcsc driver and
must be required on config file not set with 'internal' */
if (strcmp(ent->name, "cardmod") == 0) func = sc_get_cardmod_driver;
#endif
/* if not initialized assume external module */
if (func == NULL)
*(void**)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name, 0);
/* if still null, assume driver not found */
if (func == NULL) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to load '%s'.\n", ent->name);
continue;
}
driver = func();
driver->dll = dll;
load_reader_driver_options(ctx, driver);
driver->ops->init(ctx, &ctx->reader_drv_data[i]);
ctx->reader_drivers[drv_count] = driver;
drv_count++;
}
return SC_SUCCESS;
}
static int load_card_driver_options(sc_context_t *ctx, static int load_card_driver_options(sc_context_t *ctx,
struct sc_card_driver *driver) struct sc_card_driver *driver)
{ {
@ -473,7 +368,7 @@ static int load_card_drivers(sc_context_t *ctx,
} }
/* if not initialized assume external module */ /* if not initialized assume external module */
if (func == NULL) if (func == NULL)
*(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name, 1); *(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name);
/* if still null, assume driver not found */ /* if still null, assume driver not found */
if (func == NULL) { if (func == NULL) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to load '%s'.\n", ent->name); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to load '%s'.\n", ent->name);
@ -660,21 +555,17 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
int sc_ctx_detect_readers(sc_context_t *ctx) int sc_ctx_detect_readers(sc_context_t *ctx)
{ {
int i; int r;
const struct sc_reader_driver *drv = ctx->reader_driver;
sc_mutex_lock(ctx, ctx->mutex); sc_mutex_lock(ctx, ctx->mutex);
for (i = 0; ctx->reader_drivers[i] != NULL; i++) { if (drv->ops->detect_readers != NULL)
const struct sc_reader_driver *drv = ctx->reader_drivers[i]; r = drv->ops->detect_readers(ctx);
if (drv->ops->detect_readers != NULL)
drv->ops->detect_readers(ctx, ctx->reader_drv_data[i]);
}
sc_mutex_unlock(ctx, ctx->mutex); sc_mutex_unlock(ctx, ctx->mutex);
/* XXX: Do not ignore erros? */ return r;
return SC_SUCCESS;
} }
sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i) sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i)
@ -747,14 +638,24 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "===================================\n"); /* first thing in the log */ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "===================================\n"); /* first thing in the log */
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "opensc version: %s\n", sc_get_version()); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "opensc version: %s\n", sc_get_version());
/* initialize ltdl */ /* initialize ltdl */
if (lt_dlinit() != 0) { if (lt_dlinit() != 0) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "lt_dlinit failed\n"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "lt_dlinit failed\n");
sc_release_context(ctx); sc_release_context(ctx);
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
} }
load_reader_drivers(ctx, &opts); #ifdef ENABLE_PCSC
ctx->reader_driver = sc_get_pcsc_driver();
#elif ENABLE_CTAPI
ctx->reader_driver = sc_get_ctapi_driver();
#elif ENABLE_OPENCT
ctx->reader_driver = sc_get_openct_driver();
#endif
load_reader_driver_options(ctx);
ctx->reader_driver->ops->init(ctx);
load_card_drivers(ctx, &opts); load_card_drivers(ctx, &opts);
load_card_atrs(ctx, &opts); load_card_atrs(ctx, &opts);
if (opts.forced_card_driver) { if (opts.forced_card_driver) {
@ -762,8 +663,7 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
sc_set_card_driver(ctx, opts.forced_card_driver); sc_set_card_driver(ctx, opts.forced_card_driver);
free(opts.forced_card_driver); free(opts.forced_card_driver);
} }
del_drvs(&opts, 0); del_drvs(&opts);
del_drvs(&opts, 1);
sc_ctx_detect_readers(ctx); sc_ctx_detect_readers(ctx);
*ctx_out = ctx; *ctx_out = ctx;
return SC_SUCCESS; return SC_SUCCESS;
@ -772,33 +672,21 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
/* Following two are only implemented with internal PC/SC and don't consume a reader object */ /* Following two are only implemented with internal PC/SC and don't consume a reader object */
int sc_cancel(sc_context_t *ctx) int sc_cancel(sc_context_t *ctx)
{ {
int i; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
const struct sc_reader_driver *driver; if (ctx->reader_driver->ops->cancel != NULL)
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); return ctx->reader_driver->ops->cancel(ctx);
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s", ctx->reader_drivers[i]->short_name); return SC_ERROR_NOT_SUPPORTED;
driver = ctx->reader_drivers[i];
if (driver->ops->cancel != NULL)
return driver->ops->cancel(ctx, ctx->reader_drv_data[i]);
}
return SC_ERROR_NOT_SUPPORTED;
} }
int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, int timeout, int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, int timeout, void **reader_states)
void **reader_states)
{ {
int i; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
const struct sc_reader_driver *driver; if (ctx->reader_driver->ops->wait_for_event != NULL)
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); return ctx->reader_driver->ops->wait_for_event(ctx, event_mask, event_reader, event, timeout, reader_states);
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying to wait event from %s", ctx->reader_drivers[i]->short_name); return SC_ERROR_NOT_SUPPORTED;
driver = ctx->reader_drivers[i];
if (driver->ops->wait_for_event != NULL)
return driver->ops->wait_for_event(ctx, ctx->reader_drv_data[i], event_mask, event_reader, event, timeout,
reader_states);
}
return SC_ERROR_NOT_SUPPORTED;
} }
@ -816,14 +704,9 @@ int sc_release_context(sc_context_t *ctx)
free(rdr); free(rdr);
} }
for (i = 0; ctx->reader_drivers[i] != NULL; i++) { if (ctx->reader_driver->ops->finish != NULL)
const struct sc_reader_driver *drv = ctx->reader_drivers[i]; ctx->reader_driver->ops->finish(ctx);
if (drv->ops->finish != NULL)
drv->ops->finish(ctx, ctx->reader_drv_data[i]);
if (drv->dll)
lt_dlclose(drv->dll);
}
for (i = 0; ctx->card_drivers[i]; i++) { for (i = 0; ctx->card_drivers[i]; i++) {
struct sc_card_driver *drv = ctx->card_drivers[i]; struct sc_card_driver *drv = ctx->card_drivers[i];

View File

@ -283,14 +283,14 @@ typedef struct sc_serial_number {
struct sc_reader_operations { struct sc_reader_operations {
/* Called during sc_establish_context(), when the driver /* Called during sc_establish_context(), when the driver
* is loaded */ * is loaded */
int (*init)(struct sc_context *ctx, void **priv_data); int (*init)(struct sc_context *ctx);
/* Called when the driver is being unloaded. finish() has to /* Called when the driver is being unloaded. finish() has to
* deallocate the private data and any resources. */ * release any resources. */
int (*finish)(struct sc_context *ctx, void *priv_data); int (*finish)(struct sc_context *ctx);
/* Called when library wish to detect new readers /* Called when library wish to detect new readers
* should add only new readers. */ * should add only new readers. */
int (*detect_readers)(struct sc_context *ctx, void *priv_data); int (*detect_readers)(struct sc_context *ctx);
int (*cancel)(struct sc_context *ctx, void *priv_data); int (*cancel)(struct sc_context *ctx);
/* Called when releasing a reader. release() has to /* Called when releasing a reader. release() has to
* deallocate the private data. Other fields will be * deallocate the private data. Other fields will be
* freed by OpenSC. */ * freed by OpenSC. */
@ -308,8 +308,7 @@ struct sc_reader_operations {
int (*perform_verify)(struct sc_reader *, struct sc_pin_cmd_data *); int (*perform_verify)(struct sc_reader *, struct sc_pin_cmd_data *);
/* Wait for an event */ /* Wait for an event */
int (*wait_for_event)(struct sc_context *ctx, void *priv_data, int (*wait_for_event)(struct sc_context *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
int timeout, void **reader_states); int timeout, void **reader_states);
/* Reset a reader */ /* Reset a reader */
int (*reset)(struct sc_reader *); int (*reset)(struct sc_reader *);
@ -561,10 +560,10 @@ typedef struct sc_context {
list_t readers; list_t readers;
const struct sc_reader_driver *reader_drivers[SC_MAX_READER_DRIVERS]; struct sc_reader_driver *reader_driver;
void *reader_drv_data[SC_MAX_READER_DRIVERS]; void *reader_drv_data;
struct sc_card_driver *card_drivers[SC_MAX_CARD_DRIVERS]; struct sc_card_driver *card_drivers[SC_MAX_CARD_DRIVERS];
struct sc_card_driver *forced_driver; struct sc_card_driver *forced_driver;
sc_thread_context_t *thread_ctx; sc_thread_context_t *thread_ctx;

View File

@ -499,7 +499,7 @@ symerr:
return -1; return -1;
} }
static int ctapi_init(sc_context_t *ctx, void **reader_data) static int ctapi_init(sc_context_t *ctx)
{ {
int i; int i;
struct ctapi_global_private_data *gpriv; struct ctapi_global_private_data *gpriv;
@ -508,7 +508,7 @@ static int ctapi_init(sc_context_t *ctx, void **reader_data)
gpriv = calloc(1, sizeof(struct ctapi_global_private_data)); gpriv = calloc(1, sizeof(struct ctapi_global_private_data));
if (gpriv == NULL) if (gpriv == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
*reader_data = gpriv; ctx->reader_drv_data = gpriv;
for (i = 0; ctx->conf_blocks[i] != NULL; i++) { for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
@ -529,9 +529,9 @@ static int ctapi_init(sc_context_t *ctx, void **reader_data)
return 0; return 0;
} }
static int ctapi_finish(sc_context_t *ctx, void *prv_data) static int ctapi_finish(sc_context_t *ctx)
{ {
struct ctapi_global_private_data *priv = (struct ctapi_global_private_data *) prv_data; struct ctapi_global_private_data *priv = (struct ctapi_global_private_data *) ctx->reader_drv_data;
if (priv) { if (priv) {
int i; int i;

View File

@ -25,9 +25,9 @@
#include "internal.h" #include "internal.h"
/* function declarations */ /* function declarations */
static int openct_reader_init(sc_context_t *ctx, void **priv_data); static int openct_reader_init(sc_context_t *ctx);
static int openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info); static int openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info);
static int openct_reader_finish(sc_context_t *ctx, void *priv_data); static int openct_reader_finish(sc_context_t *ctx);
static int openct_reader_release(sc_reader_t *reader); static int openct_reader_release(sc_reader_t *reader);
static int openct_reader_detect_card_presence(sc_reader_t *reader); static int openct_reader_detect_card_presence(sc_reader_t *reader);
static int openct_reader_connect(sc_reader_t *reader); static int openct_reader_connect(sc_reader_t *reader);
@ -64,7 +64,7 @@ struct driver_data {
* is loaded * is loaded
*/ */
static int static int
openct_reader_init(sc_context_t *ctx, void **priv_data) openct_reader_init(sc_context_t *ctx)
{ {
unsigned int i,max_virtual; unsigned int i,max_virtual;
scconf_block *conf_block; scconf_block *conf_block;
@ -135,7 +135,7 @@ openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info)
* Called when the driver is being unloaded. finish() has to * Called when the driver is being unloaded. finish() has to
* deallocate the private data and any resources. * deallocate the private data and any resources.
*/ */
static int openct_reader_finish(sc_context_t *ctx, void *priv_data) static int openct_reader_finish(sc_context_t *ctx)
{ {
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
return SC_NO_ERROR; return SC_NO_ERROR;

View File

@ -547,10 +547,10 @@ static int pcsc_reset(sc_reader_t *reader)
} }
static int pcsc_cancel(sc_context_t *ctx, void *reader_data) static int pcsc_cancel(sc_context_t *ctx)
{ {
LONG rv = SCARD_S_SUCCESS; LONG rv = SCARD_S_SUCCESS;
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)reader_data; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)ctx->reader_drv_data;
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
#ifndef _WIN32 #ifndef _WIN32
@ -579,13 +579,12 @@ static struct sc_reader_driver pcsc_drv = {
0, 0, NULL 0, 0, NULL
}; };
static int pcsc_init(sc_context_t *ctx, void **reader_data) static int pcsc_init(sc_context_t *ctx)
{ {
struct pcsc_global_private_data *gpriv; struct pcsc_global_private_data *gpriv;
scconf_block *conf_block = NULL; scconf_block *conf_block = NULL;
int ret = SC_ERROR_INTERNAL; int ret = SC_ERROR_INTERNAL;
*reader_data = NULL;
gpriv = calloc(1, sizeof(struct pcsc_global_private_data)); gpriv = calloc(1, sizeof(struct pcsc_global_private_data));
if (gpriv == NULL) { if (gpriv == NULL) {
@ -677,7 +676,7 @@ static int pcsc_init(sc_context_t *ctx, void **reader_data)
goto out; goto out;
} }
*reader_data = gpriv; ctx->reader_drv_data = gpriv;
gpriv = NULL; gpriv = NULL;
ret = SC_SUCCESS; ret = SC_SUCCESS;
@ -691,9 +690,9 @@ out:
return ret; return ret;
} }
static int pcsc_finish(sc_context_t *ctx, void *prv_data) static int pcsc_finish(sc_context_t *ctx)
{ {
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
@ -708,13 +707,13 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data)
return SC_SUCCESS; return SC_SUCCESS;
} }
static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) static int pcsc_detect_readers(sc_context_t *ctx)
{ {
DWORD active_proto; DWORD active_proto;
SCARDHANDLE card_handle; SCARDHANDLE card_handle;
u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE];
PCSC_TLV_STRUCTURE *pcsc_tlv; PCSC_TLV_STRUCTURE *pcsc_tlv;
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
LONG rv; LONG rv;
DWORD reader_buf_size, rcount, feature_len; DWORD reader_buf_size, rcount, feature_len;
char *reader_buf = NULL, *reader_name; char *reader_buf = NULL, *reader_name;
@ -724,6 +723,7 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL); SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
if (!gpriv) { if (!gpriv) {
/* FIXME: this is not the correct error */
ret = SC_ERROR_NO_READERS_FOUND; ret = SC_ERROR_NO_READERS_FOUND;
goto out; goto out;
} }
@ -967,11 +967,10 @@ out:
/* Wait for an event to occur. /* Wait for an event to occur.
*/ */
static int pcsc_wait_for_event(sc_context_t *ctx, void *reader_data, static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
int timeout, void **reader_states) int timeout, void **reader_states)
{ {
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)reader_data; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)ctx->reader_drv_data;
LONG rv; LONG rv;
SCARD_READERSTATE *rgReaderStates; SCARD_READERSTATE *rgReaderStates;
size_t i; size_t i;

View File

@ -56,7 +56,6 @@ static const struct option options[] = {
{ "set-conf-entry", 1, NULL, 'S' }, { "set-conf-entry", 1, NULL, 'S' },
{ "list-readers", 0, NULL, 'l' }, { "list-readers", 0, NULL, 'l' },
{ "list-drivers", 0, NULL, 'D' }, { "list-drivers", 0, NULL, 'D' },
{ "list-rdrivers", 0, NULL, 'R' },
{ "list-files", 0, NULL, 'f' }, { "list-files", 0, NULL, 'f' },
{ "send-apdu", 1, NULL, 's' }, { "send-apdu", 1, NULL, 's' },
{ "reader", 1, NULL, 'r' }, { "reader", 1, NULL, 'r' },
@ -74,9 +73,8 @@ static const char *option_help[] = {
"Identify the card and print its name", "Identify the card and print its name",
"Get configuration key, format: section:name:key", "Get configuration key, format: section:name:key",
"Set configuration key, format: section:name:key:value", "Set configuration key, format: section:name:key:value",
"Lists all configured readers", "Lists readers",
"Lists all installed card drivers", "Lists all installed card drivers",
"Lists all installed reader drivers",
"Recursively lists files stored on card", "Recursively lists files stored on card",
"Sends an APDU in format AA:BB:CC:DD:EE:FF...", "Sends an APDU in format AA:BB:CC:DD:EE:FF...",
"Uses reader number <arg> [0]", "Uses reader number <arg> [0]",
@ -271,22 +269,6 @@ static int list_readers(void)
return 0; return 0;
} }
static int list_reader_drivers(void)
{
int i;
if (ctx->reader_drivers[0] == NULL) {
printf("No reader drivers installed!\n");
return 0;
}
printf("Configured reader drivers:\n");
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
printf(" %-16s %s\n", ctx->reader_drivers[i]->short_name,
ctx->reader_drivers[i]->name);
}
return 0;
}
static int list_drivers(void) static int list_drivers(void)
{ {
int i; int i;
@ -640,7 +622,6 @@ int main(int argc, char * const argv[])
int do_set_conf_entry = 0; int do_set_conf_entry = 0;
int do_list_readers = 0; int do_list_readers = 0;
int do_list_drivers = 0; int do_list_drivers = 0;
int do_list_rdrivers = 0;
int do_list_files = 0; int do_list_files = 0;
int do_send_apdu = 0; int do_send_apdu = 0;
int do_print_atr = 0; int do_print_atr = 0;
@ -656,7 +637,7 @@ int main(int argc, char * const argv[])
setbuf(stdout, NULL); setbuf(stdout, NULL);
while (1) { while (1) {
c = getopt_long(argc, argv, "inlG:S:fr:vs:DRc:aw", options, &long_optind); c = getopt_long(argc, argv, "inlG:S:fr:vs:Dc:aw", options, &long_optind);
if (c == -1) if (c == -1)
break; break;
if (c == '?') if (c == '?')
@ -684,10 +665,6 @@ int main(int argc, char * const argv[])
do_list_drivers = 1; do_list_drivers = 1;
action_count++; action_count++;
break; break;
case 'R':
do_list_rdrivers = 1;
action_count++;
break;
case 'f': case 'f':
do_list_files = 1; do_list_files = 1;
action_count++; action_count++;
@ -759,11 +736,6 @@ int main(int argc, char * const argv[])
goto end; goto end;
action_count--; action_count--;
} }
if (do_list_rdrivers) {
if ((err = list_reader_drivers()))
goto end;
action_count--;
}
if (do_list_readers) { if (do_list_readers) {
if ((err = list_readers())) if ((err = list_readers()))
goto end; goto end;