Update smartcard code to use new UTF-8 calls
This commit is contained in:
parent
1b286a0469
commit
d722ffe357
@ -34,10 +34,6 @@
|
|||||||
* Section 14 : Describes the NDR
|
* Section 14 : Describes the NDR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* smartcard redirection support
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(HAVE_CONFIG_H)
|
#if defined(HAVE_CONFIG_H)
|
||||||
#include <config_ac.h>
|
#include <config_ac.h>
|
||||||
#endif
|
#endif
|
||||||
@ -1094,6 +1090,17 @@ scard_send_IsContextValid(IRP *irp, char *context, int context_bytes)
|
|||||||
free_stream(s);
|
free_stream(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
static void
|
||||||
|
align_s(struct stream *s, unsigned int boundary)
|
||||||
|
{
|
||||||
|
unsigned int over = (unsigned int)(s->p - s->data) % boundary;
|
||||||
|
if (over != 0)
|
||||||
|
{
|
||||||
|
out_uint8s(s, boundary - over);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -1144,13 +1151,10 @@ scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
|
|||||||
SMARTCARD *sc;
|
SMARTCARD *sc;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int bytes;
|
int bytes;
|
||||||
int bytes_groups; // Length of NDR for groups + 2 terminators
|
int bytes_groups = 0; // Length of NDR for groups + 2 terminators
|
||||||
int val; // Referent Id for mszGroups (assume NULL)
|
int val = 0; // Referent Id for mszGroups (assume NULL)
|
||||||
int index;
|
int groups_len = 0; // strlen(groups)
|
||||||
int num_chars;
|
|
||||||
tui32 ioctl;
|
tui32 ioctl;
|
||||||
twchar w_groups[100];
|
|
||||||
|
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
@ -1167,18 +1171,18 @@ scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_chars = 0;
|
if (groups != NULL && *groups != '\0')
|
||||||
bytes_groups = 0;
|
|
||||||
w_groups[0] = 0;
|
|
||||||
val = 0;
|
|
||||||
if (groups != 0)
|
|
||||||
{
|
{
|
||||||
if (groups[0] != 0)
|
groups_len = g_strlen(groups);
|
||||||
|
if (wide)
|
||||||
{
|
{
|
||||||
num_chars = g_mbstowcs(w_groups, groups, 99);
|
bytes_groups = (utf8_as_utf16_word_count(groups, groups_len) + 2) * 2;
|
||||||
bytes_groups = wide ? (num_chars + 2) * 2 : num_chars + 2;
|
|
||||||
val = 0x00020004;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytes_groups = groups_len + 2;
|
||||||
|
}
|
||||||
|
val = 0x00020004;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||||
@ -1204,25 +1208,19 @@ scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
|
|||||||
// mszGroups is also a Uni-dimensional conformant array of bytes
|
// mszGroups is also a Uni-dimensional conformant array of bytes
|
||||||
if (bytes_groups > 0)
|
if (bytes_groups > 0)
|
||||||
{
|
{
|
||||||
|
align_s(s, 4);
|
||||||
|
out_uint32_le(s, bytes_groups);
|
||||||
if (wide)
|
if (wide)
|
||||||
{
|
{
|
||||||
out_uint32_le(s, bytes_groups);
|
out_utf8_as_utf16_le(s, groups, groups_len);
|
||||||
for (index = 0; index < num_chars; index++)
|
|
||||||
{
|
|
||||||
out_uint16_le(s, w_groups[index]);
|
|
||||||
}
|
|
||||||
out_uint16_le(s, 0);
|
out_uint16_le(s, 0);
|
||||||
out_uint16_le(s, 0);
|
out_uint16_le(s, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out_uint32_le(s, bytes_groups);
|
out_uint8p(s, groups, groups_len);
|
||||||
for (index = 0; index < num_chars; index++)
|
out_uint8(s, 0);
|
||||||
{
|
out_uint8(s, 0);
|
||||||
out_uint8(s, w_groups[index]);
|
|
||||||
}
|
|
||||||
out_uint16_le(s, 0);
|
|
||||||
out_uint16_le(s, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1249,18 +1247,46 @@ scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static int
|
/**
|
||||||
align_s(struct stream *s, int bytes)
|
* Outputs the pointed-to-data for one of these IDL pointer types:-
|
||||||
|
* [string] const wchar_t* str; (wide != 0)
|
||||||
|
* [string] const char* str; (wide == 0)
|
||||||
|
*
|
||||||
|
* It is assumed that the referent identifier for the string has already
|
||||||
|
* been sent
|
||||||
|
*
|
||||||
|
* @param s Output stream
|
||||||
|
* @param str UTF-8 string to output
|
||||||
|
* @param wide Whether to output as a wide string or ASCII
|
||||||
|
*
|
||||||
|
* Note that wchar_t on Windows is 16-bit
|
||||||
|
* TODO: These strings have two terminators. Is this necessary?
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
out_conformant_and_varying_string(struct stream *s, const char *str, int wide)
|
||||||
{
|
{
|
||||||
int i32;
|
align_s(s, 4);
|
||||||
|
unsigned int len = strlen(str);
|
||||||
i32 = (int) (s->p - s->data);
|
if (wide)
|
||||||
while ((i32 % bytes) != 0)
|
|
||||||
{
|
{
|
||||||
out_uint8s(s, 1);
|
unsigned int num_chars = utf8_as_utf16_word_count(str, len);
|
||||||
i32 = (int) (s->p - s->data);
|
// Max number, offset and actual count
|
||||||
|
out_uint32_le(s, num_chars + 2);
|
||||||
|
out_uint32_le(s, 0);
|
||||||
|
out_uint32_le(s, num_chars + 2);
|
||||||
|
out_utf8_as_utf16_le(s, str, len);
|
||||||
|
out_uint16_le(s, 0); // Terminate string
|
||||||
|
out_uint16_le(s, 0); // ?
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out_uint32_le(s, len + 2);
|
||||||
|
out_uint32_le(s, 0);
|
||||||
|
out_uint32_le(s, len + 2);
|
||||||
|
out_uint8p(s, str, len);
|
||||||
|
out_uint8(s, 0);
|
||||||
|
out_uint8(s, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1347,9 +1373,6 @@ scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes,
|
|||||||
tui32 ioctl;
|
tui32 ioctl;
|
||||||
int bytes;
|
int bytes;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int num_chars;
|
|
||||||
int index;
|
|
||||||
twchar w_reader_name[100];
|
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
@ -1386,6 +1409,7 @@ scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes,
|
|||||||
out_uint8a(s, context, context_bytes);
|
out_uint8a(s, context, context_bytes);
|
||||||
|
|
||||||
// rgReaderState is a Uni-dimensional conformant array
|
// rgReaderState is a Uni-dimensional conformant array
|
||||||
|
align_s(s, 4);
|
||||||
out_uint32_le(s, num_readers);
|
out_uint32_le(s, num_readers);
|
||||||
|
|
||||||
/* insert card reader state */
|
/* insert card reader state */
|
||||||
@ -1406,43 +1430,11 @@ scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes,
|
|||||||
out_uint8s(s, 3);
|
out_uint8s(s, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wide)
|
/* insert card reader names */
|
||||||
|
for (i = 0; i < num_readers; i++)
|
||||||
{
|
{
|
||||||
/* insert card reader names */
|
rs = &rsa[i];
|
||||||
for (i = 0; i < num_readers; i++)
|
out_conformant_and_varying_string(s, rs->reader_name, wide);
|
||||||
{
|
|
||||||
rs = &rsa[i];
|
|
||||||
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
|
||||||
out_uint32_le(s, num_chars + 2);
|
|
||||||
out_uint32_le(s, 0);
|
|
||||||
out_uint32_le(s, num_chars + 2);
|
|
||||||
for (index = 0; index < num_chars; index++)
|
|
||||||
{
|
|
||||||
out_uint16_le(s, w_reader_name[index]);
|
|
||||||
}
|
|
||||||
out_uint16_le(s, 0);
|
|
||||||
out_uint16_le(s, 0);
|
|
||||||
align_s(s, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* insert card reader names */
|
|
||||||
for (i = 0; i < num_readers; i++)
|
|
||||||
{
|
|
||||||
rs = &rsa[i];
|
|
||||||
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
|
||||||
out_uint32_le(s, num_chars + 2);
|
|
||||||
out_uint32_le(s, 0);
|
|
||||||
out_uint32_le(s, num_chars + 2);
|
|
||||||
for (index = 0; index < num_chars; index++)
|
|
||||||
{
|
|
||||||
out_uint8(s, w_reader_name[index]);
|
|
||||||
}
|
|
||||||
out_uint8(s, 0);
|
|
||||||
out_uint8(s, 0);
|
|
||||||
align_s(s, 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
@ -1525,14 +1517,10 @@ scard_send_Connect(IRP *irp, char *context, int context_bytes,
|
|||||||
* ?? Conformant Array pointed to by pbContext
|
* ?? Conformant Array pointed to by pbContext
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SMARTCARD *sc;
|
SMARTCARD *sc;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
tui32 ioctl;
|
tui32 ioctl;
|
||||||
int bytes;
|
int bytes;
|
||||||
int num_chars;
|
|
||||||
int index;
|
|
||||||
twchar w_reader_name[100];
|
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
@ -1564,34 +1552,13 @@ scard_send_Connect(IRP *irp, char *context, int context_bytes,
|
|||||||
out_uint32_le(s, rs->dwPreferredProtocols);
|
out_uint32_le(s, rs->dwPreferredProtocols);
|
||||||
|
|
||||||
/* insert card reader name */
|
/* insert card reader name */
|
||||||
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
out_conformant_and_varying_string(s, rs->reader_name, wide);
|
||||||
out_uint32_le(s, num_chars + 2);
|
|
||||||
out_uint32_le(s, 0x00000000);
|
|
||||||
out_uint32_le(s, num_chars + 2);
|
|
||||||
if (wide)
|
|
||||||
{
|
|
||||||
for (index = 0; index < num_chars; index++)
|
|
||||||
{
|
|
||||||
out_uint16_le(s, w_reader_name[index]);
|
|
||||||
}
|
|
||||||
out_uint16_le(s, 0);
|
|
||||||
out_uint16_le(s, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (index = 0; index < num_chars; index++)
|
|
||||||
{
|
|
||||||
out_uint8(s, w_reader_name[index]);
|
|
||||||
}
|
|
||||||
out_uint8(s, 0);
|
|
||||||
out_uint8(s, 0);
|
|
||||||
}
|
|
||||||
align_s(s, 4);
|
|
||||||
|
|
||||||
/* insert context */
|
/* insert context */
|
||||||
|
align_s(s, 4);
|
||||||
out_uint32_le(s, context_bytes);
|
out_uint32_le(s, context_bytes);
|
||||||
out_uint8a(s, context, context_bytes);
|
out_uint8a(s, context, context_bytes);
|
||||||
out_uint32_le(s, 0);
|
out_uint32_le(s, 0); // ?
|
||||||
|
|
||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @file sesman/chansrv/smartcard_pcsc.c
|
|
||||||
*
|
|
||||||
* smartcard redirection support, PCSC daemon standin
|
* smartcard redirection support, PCSC daemon standin
|
||||||
* this will act like pcsc daemon
|
* this will act like pcsc daemon
|
||||||
* pcsc lib and daemon write struct on unix domain socket for communication
|
* pcsc lib and daemon write struct on unix domain socket for communication
|
||||||
@ -653,6 +651,44 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Counts the number of non-NULL strings in a multistring
|
||||||
|
*
|
||||||
|
* [MS-RDPESC] A multistring is "A series of null-terminated character
|
||||||
|
* strings terminated by a final null character stored in a contiguous
|
||||||
|
* block of memory."
|
||||||
|
*
|
||||||
|
* The string is guaranteed to have at least the returned number of NULL
|
||||||
|
* characters in it
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
count_multistring_elements(const char *str, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int rv = 0;
|
||||||
|
|
||||||
|
if (str != NULL)
|
||||||
|
{
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
// Look for a terminator
|
||||||
|
const char *p = (const char *)memchr(str, '\0', len);
|
||||||
|
if (!p || p == str)
|
||||||
|
{
|
||||||
|
// No terminator, or an empty string encountered */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++rv;
|
||||||
|
++p; // Skip terminator
|
||||||
|
len -= (p - str);
|
||||||
|
str = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
scard_function_list_readers_return(void *user_data,
|
scard_function_list_readers_return(void *user_data,
|
||||||
@ -685,19 +721,16 @@ scard_function_list_readers_return(void *user_data,
|
|||||||
* 16 Multistring data
|
* 16 Multistring data
|
||||||
*/
|
*/
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
int chr;
|
|
||||||
int readers;
|
int readers;
|
||||||
int rn_index;
|
|
||||||
int index;
|
int index;
|
||||||
int bytes;
|
int bytes;
|
||||||
int cchReaders;
|
int cchReaders;
|
||||||
int llen;
|
int llen;
|
||||||
int uds_client_id;
|
int uds_client_id;
|
||||||
twchar reader_name[100];
|
|
||||||
char lreader_name[16][100];
|
|
||||||
struct pcsc_uds_client *uds_client;
|
struct pcsc_uds_client *uds_client;
|
||||||
struct trans *con;
|
struct trans *con;
|
||||||
struct pcsc_list_readers *pcscListReaders;
|
struct pcsc_list_readers *pcscListReaders;
|
||||||
|
char *msz_readers = NULL;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_list_readers_return:");
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_list_readers_return:");
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
|
LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
|
||||||
@ -721,9 +754,6 @@ scard_function_list_readers_return(void *user_data,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
con = uds_client->con;
|
con = uds_client->con;
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
|
||||||
g_memset(lreader_name, 0, sizeof(lreader_name));
|
|
||||||
rn_index = 0;
|
|
||||||
readers = 0;
|
readers = 0;
|
||||||
llen = 0;
|
llen = 0;
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
@ -733,39 +763,23 @@ scard_function_list_readers_return(void *user_data,
|
|||||||
// Move to length of multistring in bytes
|
// Move to length of multistring in bytes
|
||||||
in_uint8s(in_s, 12);
|
in_uint8s(in_s, 12);
|
||||||
|
|
||||||
in_uint32_le(in_s, len);
|
in_uint32_le(in_s, llen);
|
||||||
llen = len;
|
|
||||||
if (cchReaders > 0)
|
if (cchReaders > 0)
|
||||||
{
|
{
|
||||||
while (len > 0)
|
// Convert the wide multistring to a UTF-8 multistring
|
||||||
|
unsigned int u8len;
|
||||||
|
u8len = in_utf16_le_fixed_as_utf8_length(in_s, len / 2);
|
||||||
|
msz_readers = (char *)malloc(u8len);
|
||||||
|
if (msz_readers == NULL)
|
||||||
{
|
{
|
||||||
in_uint16_le(in_s, chr);
|
LOG(LOG_LEVEL_ERROR, "scard_function_list_readers_return: "
|
||||||
len -= 2;
|
"Can't allocate %u bytes of memory", u8len);
|
||||||
if (chr == 0)
|
readers = 0;
|
||||||
{
|
|
||||||
if (reader_name[0] != 0)
|
|
||||||
{
|
|
||||||
g_wcstombs(lreader_name[readers], reader_name, 99);
|
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
|
||||||
readers++;
|
|
||||||
}
|
|
||||||
reader_name[0] = 0;
|
|
||||||
rn_index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reader_name[rn_index] = chr;
|
|
||||||
rn_index++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
if (rn_index > 0)
|
|
||||||
{
|
|
||||||
if (reader_name[0] != 0)
|
|
||||||
{
|
{
|
||||||
g_wcstombs(lreader_name[readers], reader_name, 99);
|
in_utf16_le_fixed_as_utf8(in_s, len / 2, msz_readers, u8len);
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
readers = count_multistring_elements(msz_readers, u8len);
|
||||||
readers++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -778,10 +792,25 @@ scard_function_list_readers_return(void *user_data,
|
|||||||
s_push_layer(out_s, iso_hdr, 8);
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
out_uint32_le(out_s, llen);
|
out_uint32_le(out_s, llen);
|
||||||
out_uint32_le(out_s, readers);
|
out_uint32_le(out_s, readers);
|
||||||
for (index = 0; index < readers; index++)
|
|
||||||
{
|
{
|
||||||
out_uint8a(out_s, lreader_name[index], 100);
|
const char *p = msz_readers;
|
||||||
|
for (index = 0; index < readers; index++)
|
||||||
|
{
|
||||||
|
unsigned int slen = strlen(p);
|
||||||
|
if (slen < 100)
|
||||||
|
{
|
||||||
|
out_uint8a(out_s, p, slen);
|
||||||
|
out_uint8s(out_s, 100 - slen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out_uint8a(out_s, p, 99);
|
||||||
|
out_uint8s(out_s, 1);
|
||||||
|
}
|
||||||
|
p += (slen + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
free(msz_readers);
|
||||||
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||||
s_mark_end(out_s);
|
s_mark_end(out_s);
|
||||||
bytes = (int) (out_s->end - out_s->data);
|
bytes = (int) (out_s->end - out_s->data);
|
||||||
@ -1466,14 +1495,12 @@ scard_function_status_return(void *user_data,
|
|||||||
* 60 Multistring data
|
* 60 Multistring data
|
||||||
*/
|
*/
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
int index;
|
|
||||||
int bytes;
|
int bytes;
|
||||||
int dwReaderLen;
|
int dwReaderLen;
|
||||||
int dwState;
|
int dwState;
|
||||||
int dwProtocol;
|
int dwProtocol;
|
||||||
int dwAtrLen;
|
int dwAtrLen;
|
||||||
char attr[32];
|
char attr[32];
|
||||||
twchar reader_name[100];
|
|
||||||
char lreader_name[100];
|
char lreader_name[100];
|
||||||
int uds_client_id;
|
int uds_client_id;
|
||||||
struct pcsc_uds_client *uds_client;
|
struct pcsc_uds_client *uds_client;
|
||||||
@ -1519,33 +1546,20 @@ scard_function_status_return(void *user_data,
|
|||||||
in_uint32_le(in_s, dwProtocol);
|
in_uint32_le(in_s, dwProtocol);
|
||||||
in_uint8a(in_s, attr, 32);
|
in_uint8a(in_s, attr, 32);
|
||||||
in_uint32_le(in_s, dwAtrLen);
|
in_uint32_le(in_s, dwAtrLen);
|
||||||
if (dwReaderLen > 0)
|
|
||||||
|
// Length of multistring and multistring data
|
||||||
|
if (dwReaderLen <= 0)
|
||||||
{
|
{
|
||||||
in_uint32_le(in_s, dwReaderLen);
|
lreader_name[0] = '\0';
|
||||||
dwReaderLen /= 2;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dwReaderLen = 1;
|
in_uint8s(in_s, 4); // Skip length of msz in bytes
|
||||||
|
|
||||||
|
// TODO: why are we just returning the first name of the card?
|
||||||
|
in_utf16_le_terminated_as_utf8(in_s, lreader_name,
|
||||||
|
sizeof(lreader_name));
|
||||||
}
|
}
|
||||||
if (dwReaderLen < 1)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR, "scard_function_status_return: dwReaderLen < 1");
|
|
||||||
dwReaderLen = 1;
|
|
||||||
}
|
|
||||||
if (dwReaderLen > 99)
|
|
||||||
{
|
|
||||||
LOG_DEVEL(LOG_LEVEL_WARNING, "scard_function_status_return: dwReaderLen too big "
|
|
||||||
"0x%8.8x", dwReaderLen);
|
|
||||||
dwReaderLen = 99;
|
|
||||||
}
|
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
|
||||||
g_memset(lreader_name, 0, sizeof(lreader_name));
|
|
||||||
for (index = 0; index < dwReaderLen - 1; index++)
|
|
||||||
{
|
|
||||||
in_uint16_le(in_s, reader_name[index]);
|
|
||||||
}
|
|
||||||
g_wcstombs(lreader_name, reader_name, 99);
|
|
||||||
}
|
}
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_status_return: dwAtrLen %d dwReaderLen %d "
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_status_return: dwAtrLen %d dwReaderLen %d "
|
||||||
"dwProtocol %d dwState %d name %s",
|
"dwProtocol %d dwState %d name %s",
|
||||||
|
Loading…
Reference in New Issue
Block a user