aboutsummaryrefslogtreecommitdiffstats
path: root/scd/apdu.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-05-03 11:10:49 +0000
committerWerner Koch <[email protected]>2011-01-25 20:51:58 +0000
commitca2d3157656d542ceec50607d0b92f13542a0fe7 (patch)
tree45557ff38af38a9eca3690dadbbf4a7523974487 /scd/apdu.c
parentFix setting of default homedir for Wince (diff)
downloadgnupg-ca2d3157656d542ceec50607d0b92f13542a0fe7.tar.gz
gnupg-ca2d3157656d542ceec50607d0b92f13542a0fe7.zip
Detect non operational readers.
Backport from 2.0.
Diffstat (limited to '')
-rw-r--r--scd/apdu.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/scd/apdu.c b/scd/apdu.c
index 80c933e59..dcb0e23bb 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -304,6 +304,9 @@ long (* DLSTDCALL pcsc_transmit) (unsigned long card,
long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
unsigned long timeout);
+/* Flag set if PC/SC returned the no-service error. */
+static int pcsc_no_service;
+
/* Prototypes. */
static int pcsc_get_status (int slot, unsigned int *status);
@@ -1504,8 +1507,11 @@ open_pcsc_reader_direct (const char *portstr)
log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
pcsc_error_string (err), err);
reader_table[slot].used = 0;
+ if (err == 0x8010001d)
+ pcsc_no_service = 1;
return -1;
}
+ pcsc_no_service = 0;
err = pcsc_list_readers (reader_table[slot].pcsc.context,
NULL, NULL, &nreader);
@@ -2338,14 +2344,18 @@ unlock_slot (int slot)
error. If PORTSTR is NULL we default to a suitable port (for ctAPI:
the first USB reader. For PC/SC the first listed reader). */
int
-apdu_open_reader (const char *portstr)
+apdu_open_reader (const char *portstr, int *r_no_service)
{
static int pcsc_api_loaded, ct_api_loaded;
+ int slot;
+
+ if (r_no_service)
+ *r_no_service = 0;
#ifdef HAVE_LIBUSB
if (!opt.disable_ccid)
{
- int slot, i;
+ int i;
const char *s;
slot = open_ccid_reader (portstr);
@@ -2475,7 +2485,11 @@ apdu_open_reader (const char *portstr)
pcsc_api_loaded = 1;
}
- return open_pcsc_reader (portstr);
+ slot = open_pcsc_reader (portstr);
+ if (slot == -1 && r_no_service && pcsc_no_service)
+ *r_no_service = 1;
+
+ return slot;
}