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:
parent
0858a5c854
commit
72d961beb2
10
configure.ac
10
configure.ac
|
@ -205,7 +205,15 @@ AC_ARG_WITH(
|
|||
,
|
||||
[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.
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
|
|
|
@ -66,10 +66,6 @@ format</para></listitem>
|
|||
<term><option>--list-drivers, -D</option></term>
|
||||
<listitem><para>Lists all installed card drivers</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--list-rdrivers, -R</option></term>
|
||||
<listitem><para>Lists all installed reader drivers</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--reader</option> num, <option>-r</option> num</term>
|
||||
<listitem><para>Use the given reader number. The default is 0, the first reader
|
||||
|
|
|
@ -28,18 +28,7 @@ app default {
|
|||
#
|
||||
# profile_dir = @pkgdatadir@;
|
||||
|
||||
# What reader drivers to load at start-up
|
||||
#
|
||||
# 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;
|
||||
|
||||
# CT-API module configuration.
|
||||
reader_driver ctapi {
|
||||
# module /usr/local/towitoko/lib/libtowitoko.so {
|
||||
# CT-API ports:
|
||||
|
@ -51,11 +40,7 @@ app default {
|
|||
# }
|
||||
}
|
||||
|
||||
# Define parameters specific to your 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.
|
||||
# The following section shows definitions for PC/SC readers.
|
||||
reader_driver pcsc {
|
||||
# This sets the maximum send and receive sizes.
|
||||
# Some reader drivers have limitations, so you need
|
||||
|
@ -431,7 +416,7 @@ app tokend {
|
|||
|
||||
app cardmod {
|
||||
#allow only cardmodule pcsc reader for minidriver (mandatory)
|
||||
reader_drivers = cardmod;
|
||||
# FIXME cardmod pcsc hack is now broken.
|
||||
|
||||
reader_driver cardmod {
|
||||
# Enable pinpad if detected (PC/SC v2.0.2 Part 10)
|
||||
|
|
|
@ -98,21 +98,6 @@ static const struct _sc_driver_entry internal_card_drivers[] = {
|
|||
{ 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_driver_entry rdrv[SC_MAX_READER_DRIVERS];
|
||||
int rcount;
|
||||
|
@ -132,38 +117,28 @@ static int reader_list_seeker(const void *el, const void *key) {
|
|||
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;
|
||||
int *cp, i;
|
||||
|
||||
if (type == 0) {
|
||||
lst = opts->rdrv;
|
||||
cp = &opts->rcount;
|
||||
} else {
|
||||
lst = opts->cdrv;
|
||||
cp = &opts->ccount;
|
||||
}
|
||||
lst = opts->cdrv;
|
||||
cp = &opts->ccount;
|
||||
|
||||
for (i = 0; i < *cp; i++) {
|
||||
free((void *)lst[i].name);
|
||||
}
|
||||
*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;
|
||||
int *cp, max, i;
|
||||
|
||||
if (type == 0) {
|
||||
lst = opts->rdrv;
|
||||
cp = &opts->rcount;
|
||||
max = SC_MAX_READER_DRIVERS;
|
||||
} else {
|
||||
lst = opts->cdrv;
|
||||
cp = &opts->ccount;
|
||||
max = SC_MAX_CARD_DRIVERS;
|
||||
}
|
||||
|
||||
lst = opts->cdrv;
|
||||
cp = &opts->ccount;
|
||||
max = SC_MAX_CARD_DRIVERS;
|
||||
if (*cp == max) /* No space for more drivers... */
|
||||
return;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
int i;
|
||||
|
||||
if (type == 0)
|
||||
lst = internal_reader_drivers;
|
||||
else
|
||||
lst = internal_card_drivers;
|
||||
lst = internal_card_drivers;
|
||||
i = 0;
|
||||
while (lst[i].name != NULL) {
|
||||
add_drv(opts, type, lst[i].name);
|
||||
add_drv(opts, lst[i].name);
|
||||
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");
|
||||
#endif
|
||||
ctx->forced_driver = NULL;
|
||||
add_internal_drvs(opts, 0);
|
||||
add_internal_drvs(opts, 1);
|
||||
add_internal_drvs(opts);
|
||||
}
|
||||
|
||||
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);
|
||||
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");
|
||||
if (list != NULL)
|
||||
del_drvs(opts, 1);
|
||||
del_drvs(opts);
|
||||
while (list != NULL) {
|
||||
if (strcmp(list->data, s_internal) == 0)
|
||||
add_internal_drvs(opts, 1);
|
||||
add_internal_drvs(opts);
|
||||
else
|
||||
add_drv(opts, 1, list->data);
|
||||
add_drv(opts, list->data);
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void load_reader_driver_options(sc_context_t *ctx,
|
||||
struct sc_reader_driver *driver)
|
||||
static void load_reader_driver_options(sc_context_t *ctx)
|
||||
{
|
||||
const char *name = driver->short_name;
|
||||
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;
|
||||
}
|
||||
|
||||
struct sc_reader_driver *driver = ctx->reader_driver;
|
||||
scconf_block *conf_block = NULL;
|
||||
|
||||
driver->max_send_size = SC_DEFAULT_MAX_SEND_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) {
|
||||
driver->max_send_size = scconf_get_int(conf_block,
|
||||
"max_send_size", SC_DEFAULT_MAX_SEND_SIZE);
|
||||
driver->max_recv_size = scconf_get_int(conf_block,
|
||||
"max_recv_size", SC_DEFAULT_MAX_RECV_SIZE);
|
||||
driver->max_send_size = scconf_get_int(conf_block, "max_send_size", driver->max_send_size);
|
||||
driver->max_recv_size = scconf_get_int(conf_block, "max_recv_size", driver->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
|
||||
* 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;
|
||||
const char *libname = NULL;
|
||||
scconf_block **blocks, *blk;
|
||||
|
||||
for (i = 0; ctx->conf_blocks[i]; i++) {
|
||||
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
|
||||
(type==0) ? "reader_driver" : "card_driver", name);
|
||||
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", name);
|
||||
if (!blocks)
|
||||
continue;
|
||||
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()
|
||||
* used to initialize static modules
|
||||
* 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,
|
||||
const char *name, int type)
|
||||
static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name)
|
||||
{
|
||||
const char *version, *libname;
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
libname = find_library(ctx, name, type);
|
||||
libname = find_library(ctx, name);
|
||||
if (libname == NULL)
|
||||
return NULL;
|
||||
handle = lt_dlopen(libname);
|
||||
|
@ -376,57 +318,10 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
|
|||
return NULL;
|
||||
}
|
||||
*dll = handle;
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "successfully loaded %s driver '%s'\n",
|
||||
type ? "card" : "reader", name);
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "successfully loaded card driver '%s'\n", 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,
|
||||
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 (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 (func == NULL) {
|
||||
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 i;
|
||||
int r;
|
||||
const struct sc_reader_driver *drv = ctx->reader_driver;
|
||||
|
||||
sc_mutex_lock(ctx, ctx->mutex);
|
||||
|
||||
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
|
||||
const struct sc_reader_driver *drv = ctx->reader_drivers[i];
|
||||
|
||||
if (drv->ops->detect_readers != NULL)
|
||||
drv->ops->detect_readers(ctx, ctx->reader_drv_data[i]);
|
||||
}
|
||||
|
||||
if (drv->ops->detect_readers != NULL)
|
||||
r = drv->ops->detect_readers(ctx);
|
||||
|
||||
sc_mutex_unlock(ctx, ctx->mutex);
|
||||
|
||||
/* XXX: Do not ignore erros? */
|
||||
return SC_SUCCESS;
|
||||
return r;
|
||||
}
|
||||
|
||||
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, "opensc version: %s\n", sc_get_version());
|
||||
|
||||
/* initialize ltdl */
|
||||
/* initialize ltdl */
|
||||
if (lt_dlinit() != 0) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "lt_dlinit failed\n");
|
||||
sc_release_context(ctx);
|
||||
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_atrs(ctx, &opts);
|
||||
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);
|
||||
free(opts.forced_card_driver);
|
||||
}
|
||||
del_drvs(&opts, 0);
|
||||
del_drvs(&opts, 1);
|
||||
del_drvs(&opts);
|
||||
sc_ctx_detect_readers(ctx);
|
||||
*ctx_out = ctx;
|
||||
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 */
|
||||
int sc_cancel(sc_context_t *ctx)
|
||||
{
|
||||
int i;
|
||||
const struct sc_reader_driver *driver;
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
||||
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s", ctx->reader_drivers[i]->short_name);
|
||||
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;
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
||||
if (ctx->reader_driver->ops->cancel != NULL)
|
||||
return ctx->reader_driver->ops->cancel(ctx);
|
||||
|
||||
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,
|
||||
void **reader_states)
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
const struct sc_reader_driver *driver;
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
||||
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);
|
||||
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;
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
||||
if (ctx->reader_driver->ops->wait_for_event != NULL)
|
||||
return ctx->reader_driver->ops->wait_for_event(ctx, 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);
|
||||
}
|
||||
|
||||
for (i = 0; ctx->reader_drivers[i] != NULL; i++) {
|
||||
const struct sc_reader_driver *drv = ctx->reader_drivers[i];
|
||||
if (ctx->reader_driver->ops->finish != NULL)
|
||||
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++) {
|
||||
struct sc_card_driver *drv = ctx->card_drivers[i];
|
||||
|
||||
|
|
|
@ -283,14 +283,14 @@ typedef struct sc_serial_number {
|
|||
struct sc_reader_operations {
|
||||
/* Called during sc_establish_context(), when the driver
|
||||
* 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
|
||||
* deallocate the private data and any resources. */
|
||||
int (*finish)(struct sc_context *ctx, void *priv_data);
|
||||
* release any resources. */
|
||||
int (*finish)(struct sc_context *ctx);
|
||||
/* Called when library wish to detect new readers
|
||||
* should add only new readers. */
|
||||
int (*detect_readers)(struct sc_context *ctx, void *priv_data);
|
||||
int (*cancel)(struct sc_context *ctx, void *priv_data);
|
||||
int (*detect_readers)(struct sc_context *ctx);
|
||||
int (*cancel)(struct sc_context *ctx);
|
||||
/* Called when releasing a reader. release() has to
|
||||
* deallocate the private data. Other fields will be
|
||||
* freed by OpenSC. */
|
||||
|
@ -308,8 +308,7 @@ struct sc_reader_operations {
|
|||
int (*perform_verify)(struct sc_reader *, struct sc_pin_cmd_data *);
|
||||
|
||||
/* Wait for an event */
|
||||
int (*wait_for_event)(struct sc_context *ctx, void *priv_data,
|
||||
unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
|
||||
int (*wait_for_event)(struct sc_context *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
|
||||
int timeout, void **reader_states);
|
||||
/* Reset a reader */
|
||||
int (*reset)(struct sc_reader *);
|
||||
|
@ -561,10 +560,10 @@ typedef struct sc_context {
|
|||
|
||||
list_t readers;
|
||||
|
||||
const struct sc_reader_driver *reader_drivers[SC_MAX_READER_DRIVERS];
|
||||
void *reader_drv_data[SC_MAX_READER_DRIVERS];
|
||||
struct sc_reader_driver *reader_driver;
|
||||
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;
|
||||
|
||||
sc_thread_context_t *thread_ctx;
|
||||
|
|
|
@ -499,7 +499,7 @@ symerr:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int ctapi_init(sc_context_t *ctx, void **reader_data)
|
||||
static int ctapi_init(sc_context_t *ctx)
|
||||
{
|
||||
int i;
|
||||
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));
|
||||
if (gpriv == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
*reader_data = gpriv;
|
||||
ctx->reader_drv_data = gpriv;
|
||||
|
||||
for (i = 0; ctx->conf_blocks[i] != NULL; 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
int i;
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include "internal.h"
|
||||
|
||||
/* 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_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_detect_card_presence(sc_reader_t *reader);
|
||||
static int openct_reader_connect(sc_reader_t *reader);
|
||||
|
@ -64,7 +64,7 @@ struct driver_data {
|
|||
* is loaded
|
||||
*/
|
||||
static int
|
||||
openct_reader_init(sc_context_t *ctx, void **priv_data)
|
||||
openct_reader_init(sc_context_t *ctx)
|
||||
{
|
||||
unsigned int i,max_virtual;
|
||||
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
|
||||
* 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);
|
||||
return SC_NO_ERROR;
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
#ifndef _WIN32
|
||||
|
@ -579,13 +579,12 @@ static struct sc_reader_driver pcsc_drv = {
|
|||
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;
|
||||
scconf_block *conf_block = NULL;
|
||||
int ret = SC_ERROR_INTERNAL;
|
||||
|
||||
*reader_data = NULL;
|
||||
|
||||
gpriv = calloc(1, sizeof(struct pcsc_global_private_data));
|
||||
if (gpriv == NULL) {
|
||||
|
@ -677,7 +676,7 @@ static int pcsc_init(sc_context_t *ctx, void **reader_data)
|
|||
goto out;
|
||||
}
|
||||
|
||||
*reader_data = gpriv;
|
||||
ctx->reader_drv_data = gpriv;
|
||||
gpriv = NULL;
|
||||
ret = SC_SUCCESS;
|
||||
|
||||
|
@ -691,9 +690,9 @@ out:
|
|||
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);
|
||||
|
||||
|
@ -708,13 +707,13 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data)
|
|||
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;
|
||||
SCARDHANDLE card_handle;
|
||||
u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
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;
|
||||
DWORD reader_buf_size, rcount, feature_len;
|
||||
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);
|
||||
|
||||
if (!gpriv) {
|
||||
/* FIXME: this is not the correct error */
|
||||
ret = SC_ERROR_NO_READERS_FOUND;
|
||||
goto out;
|
||||
}
|
||||
|
@ -967,11 +967,10 @@ out:
|
|||
|
||||
/* Wait for an event to occur.
|
||||
*/
|
||||
static int pcsc_wait_for_event(sc_context_t *ctx, void *reader_data,
|
||||
unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
|
||||
static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event,
|
||||
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;
|
||||
SCARD_READERSTATE *rgReaderStates;
|
||||
size_t i;
|
||||
|
|
|
@ -56,7 +56,6 @@ static const struct option options[] = {
|
|||
{ "set-conf-entry", 1, NULL, 'S' },
|
||||
{ "list-readers", 0, NULL, 'l' },
|
||||
{ "list-drivers", 0, NULL, 'D' },
|
||||
{ "list-rdrivers", 0, NULL, 'R' },
|
||||
{ "list-files", 0, NULL, 'f' },
|
||||
{ "send-apdu", 1, NULL, 's' },
|
||||
{ "reader", 1, NULL, 'r' },
|
||||
|
@ -74,9 +73,8 @@ static const char *option_help[] = {
|
|||
"Identify the card and print its name",
|
||||
"Get configuration key, format: section:name:key",
|
||||
"Set configuration key, format: section:name:key:value",
|
||||
"Lists all configured readers",
|
||||
"Lists readers",
|
||||
"Lists all installed card drivers",
|
||||
"Lists all installed reader drivers",
|
||||
"Recursively lists files stored on card",
|
||||
"Sends an APDU in format AA:BB:CC:DD:EE:FF...",
|
||||
"Uses reader number <arg> [0]",
|
||||
|
@ -271,22 +269,6 @@ static int list_readers(void)
|
|||
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)
|
||||
{
|
||||
int i;
|
||||
|
@ -640,7 +622,6 @@ int main(int argc, char * const argv[])
|
|||
int do_set_conf_entry = 0;
|
||||
int do_list_readers = 0;
|
||||
int do_list_drivers = 0;
|
||||
int do_list_rdrivers = 0;
|
||||
int do_list_files = 0;
|
||||
int do_send_apdu = 0;
|
||||
int do_print_atr = 0;
|
||||
|
@ -656,7 +637,7 @@ int main(int argc, char * const argv[])
|
|||
setbuf(stdout, NULL);
|
||||
|
||||
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)
|
||||
break;
|
||||
if (c == '?')
|
||||
|
@ -684,10 +665,6 @@ int main(int argc, char * const argv[])
|
|||
do_list_drivers = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'R':
|
||||
do_list_rdrivers = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'f':
|
||||
do_list_files = 1;
|
||||
action_count++;
|
||||
|
@ -759,11 +736,6 @@ int main(int argc, char * const argv[])
|
|||
goto end;
|
||||
action_count--;
|
||||
}
|
||||
if (do_list_rdrivers) {
|
||||
if ((err = list_reader_drivers()))
|
||||
goto end;
|
||||
action_count--;
|
||||
}
|
||||
if (do_list_readers) {
|
||||
if ((err = list_readers()))
|
||||
goto end;
|
||||
|
|
Loading…
Reference in New Issue