chansrv: work on smartcard

ulab-next
Jay Sorg 11 years ago
parent b206de3314
commit d926a5becd

@ -155,63 +155,64 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */
/****************************************************************************** /******************************************************************************
** static functions local to this file ** ** static functions local to this file **
******************************************************************************/ ******************************************************************************/
static struct stream *scard_make_new_ioctl(IRP *irp, tui32 ioctl); static struct stream * APP_CC scard_make_new_ioctl(IRP *irp, tui32 ioctl);
static int scard_add_new_device(tui32 device_id); static int APP_CC scard_add_new_device(tui32 device_id);
static int scard_get_free_slot(void); static int APP_CC scard_get_free_slot(void);
static void scard_release_resources(void); static void APP_CC scard_release_resources(void);
static void scard_send_EstablishContext(IRP* irp, int scope); static void APP_CC scard_send_EstablishContext(IRP* irp, int scope);
static void scard_send_ReleaseContext(IRP* irp, tui32 context); static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context);
static void scard_send_ListReaders(IRP* irp, tui32 context, int wide); static void APP_CC scard_send_ListReaders(IRP* irp, tui32 context, int wide);
static void scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide,
tui32 timeout, tui32 num_readers, tui32 timeout, tui32 num_readers,
READER_STATE* rsa); READER_STATE* rsa);
static void scard_send_Connect(IRP* irp, tui32 context, int wide, static void APP_CC scard_send_Connect(IRP* irp, tui32 context, int wide,
READER_STATE* rs); READER_STATE* rs);
static void scard_send_BeginTransaction(IRP* irp, tui32 sc_handle); static void APP_CC scard_send_BeginTransaction(IRP* irp, tui32 sc_handle);
static void scard_send_EndTransaction(IRP* irp, tui32 sc_handle); static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle);
static void scard_send_Status(IRP* irp, int wide, tui32 sc_handle); static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle);
static void scard_send_Disconnect(IRP* irp, tui32 context, tui32 sc_handle); static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
tui32 sc_handle);
/****************************************************************************** /******************************************************************************
** local callbacks into this module ** ** local callbacks into this module **
******************************************************************************/ ******************************************************************************/
static void scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_EstablishContext_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_ListReaders_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_Connect_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_Connect_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_Status_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_Status_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
static void scard_handle_Disconnect_Return(struct stream *s, IRP *irp, static void APP_CC scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus); tui32 IoStatus);
@ -310,8 +311,8 @@ scard_send_irp_establish_context(struct trans *con, int scope)
/** /**
* Release a previously established Smart Card context * Release a previously established Smart Card context
*****************************************************************************/ *****************************************************************************/
int int APP_CC
APP_CC scard_send_release_context(struct trans *con, tui32 context) scard_send_irp_release_context(struct trans *con, tui32 context)
{ {
IRP *irp; IRP *irp;
@ -432,8 +433,8 @@ scard_send_irp_connect(struct trans *con, tui32 context, int wide,
* *
* @param con connection to client * @param con connection to client
*****************************************************************************/ *****************************************************************************/
int int APP_CC
APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle) scard_send_begin_transaction(struct trans *con, tui32 sc_handle)
{ {
IRP *irp; IRP *irp;
@ -463,8 +464,8 @@ APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle)
* @param con connection to client * @param con connection to client
* @param sc_handle handle to smartcard * @param sc_handle handle to smartcard
*****************************************************************************/ *****************************************************************************/
int int APP_CC
APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle) scard_send_end_transaction(struct trans *con, tui32 sc_handle)
{ {
IRP *irp; IRP *irp;
@ -493,8 +494,8 @@ APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle)
* @param con connection to client * @param con connection to client
* @param wide TRUE if unicode string * @param wide TRUE if unicode string
*****************************************************************************/ *****************************************************************************/
int int APP_CC
APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle) scard_send_status(struct trans *con, int wide, tui32 sc_handle)
{ {
IRP *irp; IRP *irp;
@ -523,8 +524,8 @@ APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle)
* @param con connection to client * @param con connection to client
* @param sc_handle handle to smartcard * @param sc_handle handle to smartcard
*****************************************************************************/ *****************************************************************************/
int int APP_CC
APP_CC scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle) scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
{ {
IRP *irp; IRP *irp;
@ -718,7 +719,7 @@ scard_send_EstablishContext(IRP *irp, int scope)
/** /**
* Release a previously established Smart Card context * Release a previously established Smart Card context
*****************************************************************************/ *****************************************************************************/
static void static void APP_CC
scard_send_ReleaseContext(IRP* irp, tui32 context) scard_send_ReleaseContext(IRP* irp, tui32 context)
{ {
/* see [MS-RDPESC] 3.1.4.2 */ /* see [MS-RDPESC] 3.1.4.2 */
@ -856,6 +857,21 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
*/ */
} }
/*****************************************************************************/
static int
align_s(struct stream *s, int bytes)
{
int i32;
i32 = (int) (s->p - s->data);
while ((i32 % bytes) != 0)
{
out_uint8s(s, 1);
i32 = (int) (s->p - s->data);
}
return 0;
}
/** /**
* Get change in status * Get change in status
* *
@ -865,7 +881,7 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
* @param num_readers number of entries in rsa * @param num_readers number of entries in rsa
* @param rsa array of READER_STATEs * @param rsa array of READER_STATEs
*****************************************************************************/ *****************************************************************************/
static void static void APP_CC
scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout, scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
tui32 num_readers, READER_STATE* rsa) tui32 num_readers, READER_STATE* rsa)
{ {
@ -932,6 +948,7 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
{ {
xstream_wr_u16_le(s, w_reader_name[index]); xstream_wr_u16_le(s, w_reader_name[index]);
} }
align_s(s, 4);
} }
} }
else else
@ -948,6 +965,7 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
{ {
xstream_wr_u8(s, w_reader_name[index]); xstream_wr_u8(s, w_reader_name[index]);
} }
align_s(s, 4);
} }
} }
@ -969,8 +987,8 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
* @param wide TRUE if unicode string * @param wide TRUE if unicode string
* @param rs reader state * @param rs reader state
*****************************************************************************/ *****************************************************************************/
static void scard_send_Connect(IRP* irp, tui32 context, int wide, static void APP_CC
READER_STATE* rs) scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
{ {
/* see [MS-RDPESC] 2.2.2.13 for ASCII */ /* see [MS-RDPESC] 2.2.2.13 for ASCII */
/* see [MS-RDPESC] 2.2.2.14 for Wide char */ /* see [MS-RDPESC] 2.2.2.14 for Wide char */
@ -1021,13 +1039,17 @@ static void scard_send_Connect(IRP* irp, tui32 context, int wide,
if (wide) if (wide)
{ {
for (index = 0; index < num_chars; index++) for (index = 0; index < num_chars; index++)
{
xstream_wr_u16_le(s, w_reader_name[index]); xstream_wr_u16_le(s, w_reader_name[index]);
} }
}
else else
{ {
for (index = 0; index < num_chars; index++) for (index = 0; index < num_chars; index++)
{
xstream_wr_u8(s, w_reader_name[index]); xstream_wr_u8(s, w_reader_name[index]);
} }
}
/* insert context */ /* insert context */
xstream_wr_u32_le(s, 4); xstream_wr_u32_le(s, 4);
@ -1050,7 +1072,7 @@ static void scard_send_Connect(IRP* irp, tui32 context, int wide,
* *
* @param con connection to client * @param con connection to client
*****************************************************************************/ *****************************************************************************/
static void static void APP_CC
scard_send_BeginTransaction(IRP *irp, tui32 sc_handle) scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
{ {
/* see [MS-RDPESC] 4.9 */ /* see [MS-RDPESC] 4.9 */
@ -1104,7 +1126,7 @@ scard_send_BeginTransaction(IRP* irp, tui32 sc_handle)
* @param con connection to client * @param con connection to client
* @param sc_handle handle to smartcard * @param sc_handle handle to smartcard
*****************************************************************************/ *****************************************************************************/
static void static void APP_CC
scard_send_EndTransaction(IRP *irp, tui32 sc_handle) scard_send_EndTransaction(IRP *irp, tui32 sc_handle)
{ {
/* see [MS-RDPESC] 3.1.4.32 */ /* see [MS-RDPESC] 3.1.4.32 */
@ -1161,7 +1183,7 @@ scard_send_EndTransaction(IRP* irp, tui32 sc_handle)
* @param con connection to client * @param con connection to client
* @param wide TRUE if unicode string * @param wide TRUE if unicode string
*****************************************************************************/ *****************************************************************************/
static void static void APP_CC
scard_send_Status(IRP *irp, int wide, tui32 sc_handle) scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
{ {
/* see [MS-RDPESC] 2.2.2.18 */ /* see [MS-RDPESC] 2.2.2.18 */
@ -1227,7 +1249,7 @@ scard_send_Status(IRP* irp, int wide, tui32 sc_handle)
* @param con connection to client * @param con connection to client
* @param sc_handle handle to smartcard * @param sc_handle handle to smartcard
*****************************************************************************/ *****************************************************************************/
static void static void APP_CC
scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle) scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
{ {
/* see [MS-RDPESC] 3.1.4.30 */ /* see [MS-RDPESC] 3.1.4.30 */
@ -1296,57 +1318,27 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId, tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus) tui32 IoStatus)
{ {
tui32 context;
tui32 len; tui32 len;
int tmp; struct trans *con;
SMARTCARD *sc;
log_debug("entered"); log_debug("entered");
/* sanity check */ /* sanity check */
if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
{ {
log_error("DeviceId/CompletionId do not match those in IRP"); log_error("DeviceId/CompletionId do not match those in IRP");
return; return;
} }
if (IoStatus != 0) if (IoStatus != 0)
{ {
log_error("failed to establish context - device not usable"); log_error("failed to establish context - device not usable");
/* LK_TODO delete irp and smartcard entry */ /* LK_TODO delete irp and smartcard entry */
return; return;
} }
sc = smartcards[irp->scard_index];
/* get OutputBufferLen */ /* get OutputBufferLen */
xstream_rd_u32_le(s, len); xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
/* LK_TODO */ scard_function_establish_context_return(con, s, len);
g_hexdump(s->p, len);
xstream_rd_u32_le(s, tmp); /* should be len 8, LE, V1 */
xstream_rd_u32_le(s, tmp); /* marshalling flag */
xstream_rd_u32_le(s, tmp); /* ?? */
xstream_rd_u32_le(s, tmp); /* ?? */
xstream_rd_u32_le(s, tmp); /* ?? */
xstream_rd_u32_le(s, tmp); /* ?? */
xstream_rd_u32_le(s, tmp); /* ?? */
xstream_rd_u32_le(s, len); /* len of context in bytes, always 4 */
xstream_rd_u32_le(s, context);
if (LOG_LEVEL == LOG_DEBUG)
log_debug("dumping: )", context);
// LK_TODO delete this
//irp->callback = scard_handle_ListReaders_Return;
scard_function_establish_context_return((struct trans *) (irp->user_data),
context);
devredir_irp_delete(irp); devredir_irp_delete(irp);
/* LK_TODO need to delete IRP */
log_debug("leaving"); log_debug("leaving");
} }
@ -1359,26 +1351,26 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
tui32 IoStatus) tui32 IoStatus)
{ {
tui32 len; tui32 len;
struct trans *con;
log_debug("entered"); log_debug("entered");
/* sanity check */ /* sanity check */
if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
{ {
log_error("DeviceId/CompletionId do not match those in IRP"); log_error("DeviceId/CompletionId do not match those in IRP");
return; return;
} }
if (IoStatus != 0) if (IoStatus != 0)
{ {
log_error("ReleaseContext failed, device not usable"); log_error("ReleaseContext failed, device not usable");
/* LK_TODO delete irp and smartcard entry */ /* LK_TODO delete irp and smartcard entry */
return; return;
} }
/* get OutputBufferLen */ /* get OutputBufferLen */
xstream_rd_u32_le(s, len); xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
scard_function_release_context_return(con, s, len);
devredir_irp_delete(irp);
log_debug("leaving"); log_debug("leaving");
} }
@ -1391,28 +1383,26 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
tui32 IoStatus) tui32 IoStatus)
{ {
tui32 len; tui32 len;
struct trans *con;
log_debug("entered"); log_debug("entered");
/* sanity check */ /* sanity check */
if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
{ {
log_error("DeviceId/CompletionId do not match those in IRP"); log_error("DeviceId/CompletionId do not match those in IRP");
return; return;
} }
if (IoStatus != 0) if (IoStatus != 0)
{ {
log_error("failed to list readers - device not usable"); log_error("failed to list readers - device not usable");
/* LK_TODO delete irp and smartcard entry */ /* LK_TODO delete irp and smartcard entry */
return; return;
} }
/* get OutputBufferLen */ /* get OutputBufferLen */
xstream_rd_u32_le(s, len); xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
scard_function_list_readers_return((struct trans *) irp->user_data, scard_function_list_readers_return(con, s, len);
s, len); devredir_irp_delete(irp);
log_debug("leaving"); log_debug("leaving");
} }
@ -1425,26 +1415,26 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
tui32 IoStatus) tui32 IoStatus)
{ {
tui32 len; tui32 len;
struct trans *con;
log_debug("entered"); log_debug("entered");
/* sanity check */ /* sanity check */
if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
{ {
log_error("DeviceId/CompletionId do not match those in IRP"); log_error("DeviceId/CompletionId do not match those in IRP");
return; return;
} }
if (IoStatus != 0) if (IoStatus != 0)
{ {
log_error("failed to get status change - device not usable"); log_error("failed to get status change - device not usable");
/* LK_TODO delete irp and smartcard entry */ /* LK_TODO delete irp and smartcard entry */
return; return;
} }
/* get OutputBufferLen */ /* get OutputBufferLen */
xstream_rd_u32_le(s, len); xstream_rd_u32_le(s, len);
con = (struct trans *) (irp->user_data);
scard_function_get_status_change_return(con, s, len);
devredir_irp_delete(irp);
log_debug("leaving"); log_debug("leaving");
} }

@ -74,7 +74,7 @@ int APP_CC scard_check_wait_objs(void);
int APP_CC scard_init(void); int APP_CC scard_init(void);
int APP_CC scard_deinit(void); int APP_CC scard_deinit(void);
int APP_CC scard_send_irp_establish_context(struct trans *con, int scope); int APP_CC scard_send_irp_establish_context(struct trans *con, int scope);
int APP_CC scard_send_release_context(struct trans *con, tui32 context); int APP_CC scard_send_irp_release_context(struct trans *con, tui32 context);
int APP_CC scard_send_irp_list_readers(struct trans *con, tui32 context, int wide); int APP_CC scard_send_irp_list_readers(struct trans *con, tui32 context, int wide);
int APP_CC scard_send_irp_get_status_change(struct trans *con, tui32 context, int APP_CC scard_send_irp_get_status_change(struct trans *con, tui32 context,

@ -50,74 +50,13 @@
} \ } \
while (0) while (0)
/* using pcsc-lite-1.7.4 */
struct establish_struct
{
tui32 dwScope;
tui32 hContext;
tui32 rv;
};
struct release_struct
{
tui32 hContext;
tui32 rv;
};
/** Major version of the current message protocol */
#define PROTOCOL_VERSION_MAJOR 4
/** Minor version of the current message protocol */
#define PROTOCOL_VERSION_MINOR 2
struct version_struct
{
tsi32 major; /**< IPC major \ref PROTOCOL_VERSION_MAJOR */
tsi32 minor; /**< IPC minor \ref PROTOCOL_VERSION_MINOR */
tui32 rv;
};
#define SCARD_S_SUCCESS 0x00000000 /**< No error was encountered. */
#define SCARD_F_INTERNAL_ERROR 0x80100001 /**< An internal consistency
* check failed. */
#define SCARD_E_TIMEOUT 0x8010000A /**< The user-specified timeout
* value has expired. */
#define MAX_READERNAME 100
#define MAX_ATR_SIZE 33
struct pubReaderStatesList
{
char readerName[MAX_READERNAME]; /**< reader name */
tui32 eventCounter; /**< number of card events */
tui32 readerState; /**< SCARD_* bit field */
tsi32 readerSharing; /**< PCSCLITE_SHARING_* sharing status */
tui8 cardAtr[MAX_ATR_SIZE]; /**< ATR */
tui32 cardAtrLength; /**< ATR length */
tui32 cardProtocol; /**< SCARD_PROTOCOL_* value */
};
#define PCSCLITE_MAX_READERS_CONTEXTS 16
static int g_num_readers = 0;
/* pcsc list */
static struct pubReaderStatesList
g_pcsc_reader_states[PCSCLITE_MAX_READERS_CONTEXTS];
/* rdp list */
static READER_STATE g_xrdp_reader_states[PCSCLITE_MAX_READERS_CONTEXTS];
struct wait_reader_state_change
{
tui32 timeOut; /**< timeout in ms */
tui32 rv;
};
#define XRDP_PCSC_STATE_NONE 0 #define XRDP_PCSC_STATE_NONE 0
#define XRDP_PCSC_STATE_GOT_RSC (1 << 0) /* read state change */ #define XRDP_PCSC_STATE_GOT_EC (1 << 0) /* establish context */
#define XRDP_PCSC_STATE_GOT_EC (1 << 1) /* establish context */ #define XRDP_PCSC_STATE_GOT_LR (1 << 1) /* list readers */
#define XRDP_PCSC_STATE_GOT_LR (1 << 2) /* list readers */ #define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */
#define XRDP_PCSC_STATE_GOT_RC (1 << 3) /* release context */ #define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */
/* TODO: put this in con */
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE; static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
extern int g_display_num; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */
@ -135,7 +74,6 @@ static struct trans *g_lis = 0;
static struct trans *g_con = 0; /* todo, remove this */ static struct trans *g_con = 0; /* todo, remove this */
static char g_pcsclite_ipc_dir[256] = ""; static char g_pcsclite_ipc_dir[256] = "";
static int g_pub_file_fd = 0; static int g_pub_file_fd = 0;
static char g_pub_file_name[256] = "";
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
@ -174,7 +112,7 @@ scard_pcsc_check_wait_objs(void)
int APP_CC int APP_CC
scard_process_establish_context(struct trans *con, struct stream *in_s) scard_process_establish_context(struct trans *con, struct stream *in_s)
{ {
struct establish_struct in_es; int dwScope;
LLOGLN(0, ("scard_process_establish_context:")); LLOGLN(0, ("scard_process_establish_context:"));
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC)
@ -183,112 +121,122 @@ scard_process_establish_context(struct trans *con, struct stream *in_s)
return 1; return 1;
} }
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC; g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
in_uint8a(in_s, &in_es, sizeof(in_es)); in_uint32_le(in_s, dwScope);
LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
in_es.dwScope)); scard_send_irp_establish_context(con, dwScope);
scard_send_irp_establish_context(con, in_es.dwScope);
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
scard_function_establish_context_return(struct trans *con, tui32 context) scard_function_establish_context_return(struct trans *con,
struct stream *in_s,
int len)
{ {
struct establish_struct out_es; int bytes;
tui32 context;
tui32 context_len;
struct stream *out_s; struct stream *out_s;
LLOGLN(0, ("scard_function_establish_context_return: context %d", LLOGLN(0, ("scard_function_establish_context_return:"));
context));
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0) if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
{ {
LLOGLN(0, ("scard_function_establish_context_return: opps")); LLOGLN(0, ("scard_function_establish_context_return: opps"));
return 1; return 1;
} }
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC; g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
out_es.dwScope = 0; in_uint8s(in_s, 28);
out_es.hContext = context; in_uint32_le(in_s, context_len);
out_es.rv = SCARD_S_SUCCESS; if (context_len != 4)
{
LLOGLN(0, ("scard_function_establish_context_return: opps"));
return 1;
}
in_uint32_le(in_s, context);
LLOGLN(0, ("scard_function_establish_context_return: context 0x%8.8x", context));
out_s = trans_get_out_s(con, 8192); out_s = trans_get_out_s(con, 8192);
out_uint8a(out_s, &out_es, sizeof(out_es)); s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, context);
out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
s_mark_end(out_s); s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
out_uint32_le(out_s, bytes - 8);
out_uint32_le(out_s, 0x01); /* SCARD_ESTABLISH_CONTEXT 0x01 */
return trans_force_write(con); return trans_force_write(con);
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
scard_process_release_context(struct stream *in_s) scard_process_release_context(struct trans *con, struct stream *in_s)
{ {
struct release_struct in_rs; int hContext;
struct release_struct out_rs;
struct stream *out_s;
LLOGLN(0, ("scard_process_release_context:")); LLOGLN(0, ("scard_process_release_context:"));
in_uint8a(in_s, &in_rs, sizeof(in_rs)); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC)
LLOGLN(0, ("scard_process_release_context: hContext %d", in_rs.hContext)); {
LLOGLN(0, ("scard_process_establish_context: opps"));
/* TODO: use XRDP_PCSC_STATE_GOT_RC */ return 1;
}
out_rs.hContext = in_rs.hContext; g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
out_rs.rv = SCARD_S_SUCCESS; in_uint32_le(in_s, hContext);
out_s = trans_get_out_s(g_con, 8192); LLOGLN(0, ("scard_process_release_context: hContext 0x%8.8x", hContext));
out_uint8a(out_s, &out_rs, sizeof(out_rs)); scard_send_irp_release_context(con, hContext);
s_mark_end(out_s); return 0;
return trans_force_write(g_con);
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
scard_process_version(struct trans *con, struct stream *in_s) scard_function_release_context_return(struct trans *con,
struct stream *in_s,
int len)
{ {
int bytes;
struct stream *out_s; struct stream *out_s;
struct version_struct in_version; tui32 context;
struct version_struct out_version;
LLOGLN(0, ("scard_function_release_context_return:"));
LLOGLN(0, ("scard_process_version:")); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
in_uint8a(in_s, &in_version, sizeof(in_version)); {
/* todo: check if version is compatible */ LLOGLN(0, ("scard_function_release_context_return: opps"));
LLOGLN(0, ("scard_process_version: version major %d minor %d", return 1;
in_version.major, in_version.minor)); }
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RC;
out_s = trans_get_out_s(con, 8192); out_s = trans_get_out_s(con, 8192);
out_version.major = PROTOCOL_VERSION_MAJOR; s_push_layer(out_s, iso_hdr, 8);
out_version.minor = PROTOCOL_VERSION_MINOR; out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
out_version.rv = SCARD_S_SUCCESS;
out_uint8a(out_s, &out_version, sizeof(out_version));
s_mark_end(out_s); s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
out_uint32_le(out_s, bytes - 8);
out_uint32_le(out_s, 0x02); /* SCARD_RELEASE_CONTEXT 0x02 */
return trans_force_write(con); return trans_force_write(con);
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
scard_process_get_readers_state(struct trans *con, struct stream *in_s) scard_process_list_readers(struct trans *con, struct stream *in_s)
{ {
//struct stream *out_s; int hContext;
LLOGLN(0, ("scard_process_get_readers_state:"));
//out_s = trans_get_out_s(con, 8192);
//out_uint8a(out_s, g_pcsc_reader_states, sizeof(g_pcsc_reader_states));
//s_mark_end(out_s);
//return trans_force_write(con);
LLOGLN(0, ("scard_process_list_readers:"));
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
{ {
LLOGLN(0, ("scard_process_get_readers_state: opps")); LLOGLN(0, ("scard_process_list_readers: opps"));
return 1; return 1;
} }
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR; g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
in_uint32_le(in_s, hContext);
scard_send_irp_list_readers(con, JAY_TODO_CONTEXT, JAY_TODO_WIDE); LLOGLN(0, ("scard_process_list_readers: dwScope 0x%8.8x", hContext));
scard_send_irp_list_readers(con, hContext, 1);
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */
int APP_CC int APP_CC
scard_function_list_readers_return(struct trans *con, scard_function_list_readers_return(struct trans *con,
struct stream *in_s, struct stream *in_s,
@ -298,23 +246,28 @@ scard_function_list_readers_return(struct trans *con,
int chr; int chr;
int readers; int readers;
int rn_index; int rn_index;
char reader_name[100]; int index;
int bytes;
twchar reader_name[100];
char lreader_name[16][100];
LLOGLN(10, ("scard_function_list_readers_return:"));
g_hexdump(in_s->p, len); g_hexdump(in_s->p, len);
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0) if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0)
{ {
LLOGLN(0, ("scard_function_list_readers_return: opps")); LLOGLN(10, ("scard_function_list_readers_return: opps"));
return 1; return 1;
} }
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR; g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
g_memset(reader_name, 0, sizeof(reader_name));
g_memset(lreader_name, 0, sizeof(lreader_name));
in_uint8s(in_s, 28); in_uint8s(in_s, 28);
len -= 28; len -= 28;
in_uint32_le(in_s, len); in_uint32_le(in_s, len);
g_writeln("len %d", len); g_writeln("len %d", len);
rn_index = 0; rn_index = 0;
readers = 1; readers = 0;
while (len > 0) while (len > 0)
{ {
in_uint16_le(in_s, chr); in_uint16_le(in_s, chr);
@ -323,7 +276,9 @@ scard_function_list_readers_return(struct trans *con,
{ {
if (reader_name[0] != 0) if (reader_name[0] != 0)
{ {
g_writeln("1 %s", reader_name); g_wcstombs(lreader_name[readers], reader_name, 99);
g_writeln("1 %s", lreader_name[readers]);
g_memset(reader_name, 0, sizeof(reader_name));
readers++; readers++;
} }
reader_name[0] = 0; reader_name[0] = 0;
@ -339,181 +294,136 @@ scard_function_list_readers_return(struct trans *con,
{ {
if (reader_name[0] != 0) if (reader_name[0] != 0)
{ {
g_writeln("2 %s", reader_name); g_wcstombs(lreader_name[readers], reader_name, 99);
g_writeln("2 %s", lreader_name[readers]);
g_memset(reader_name, 0, sizeof(reader_name));
readers++; readers++;
} }
} }
#if 0
g_strcpy(g_reader_states[0].readerName, "ACS AET65 00 00");
g_reader_states[0].readerState = 0x14;
g_reader_states[0].cardProtocol = 3;
g_reader_states[0].cardAtrLength = 10;
g_reader_states[0].cardAtr[0] = 0x3B;
g_reader_states[0].cardAtr[1] = 0x95;
g_reader_states[0].cardAtr[2] = 0x95;
g_reader_states[0].cardAtr[3] = 0x40;
g_reader_states[0].cardAtr[4] = 0xFF;
g_reader_states[0].cardAtr[5] = 0xD0;
g_reader_states[0].cardAtr[6] = 0x00;
g_reader_states[0].cardAtr[7] = 0x54;
g_reader_states[0].cardAtr[8] = 0x01;
g_reader_states[0].cardAtr[9] = 0x32;
//g_reader_states[0].eventCounter++;
out_s = trans_get_out_s(con, 8192); out_s = trans_get_out_s(con, 8192);
out_uint8a(out_s, g_reader_states, sizeof(g_reader_states)); s_push_layer(out_s, iso_hdr, 8);
s_mark_end(out_s); out_uint32_le(out_s, readers);
return trans_force_write(con); for (index = 0; index < readers; index++)
#endif
return 0;
}
/*****************************************************************************/
/* callback from chansrv when timeout occurs */
void DEFAULT_CC
scard_read_state_chage_timeout(void* data)
{ {
struct trans *con; g_writeln("3 - %s", lreader_name[index]);
struct stream *out_s; out_uint8a(out_s, lreader_name[index], 100);
struct wait_reader_state_change out_rsc;
LLOGLN(0, ("scard_read_state_chage_timeout:"));
con = (struct trans *) data;
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC)
{
out_s = trans_get_out_s(con, 8192);
out_rsc.timeOut = 0;
out_rsc.rv = SCARD_S_SUCCESS;
out_uint8a(out_s, &out_rsc, sizeof(out_rsc));
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RSC;
s_mark_end(out_s);
trans_force_write(con);
}
else
{
LLOGLN(0, ("scard_read_state_chage_timeout: already stopped"));
} }
out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
out_uint32_le(out_s, bytes - 8);
out_uint32_le(out_s, 0x03); /* SCARD_LIST_READERS 0x03 */
return trans_force_write(con);
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
scard_process_read_state_change(struct trans *con, struct stream *in_s) scard_process_get_status_change(struct trans *con, struct stream *in_s)
{ {
struct wait_reader_state_change in_rsc;
struct stream *out_s;
int index; int index;
int hContext;
int dwTimeout;
int cReaders;
READER_STATE *rsa;
LLOGLN(0, ("scard_process_read_state_change:")); LLOGLN(0, ("scard_process_get_status_change:"));
in_uint8a(in_s, &in_rsc, sizeof(in_rsc)); if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC)
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC)
{ {
LLOGLN(0, ("scard_process_read_state_change: opps")); LLOGLN(0, ("scard_process_get_status_change: opps"));
return 0; return 1;
} }
in_uint32_le(in_s, hContext);
#if 0 in_uint32_le(in_s, dwTimeout);
for (index = 0; index < 16; index++) in_uint32_le(in_s, cReaders);
if ((cReaders < 0) || (cReaders > 16))
{ {
//g_memcpy(rd[index].reader_name, g_pcsc_reader_states[index].readerName, 99); LLOGLN(0, ("scard_process_get_status_change: bad cReaders %d", cReaders));
g_strncpy(rd[index].reader_name, "Gemalto PC Twin Reader 00 00", 99); return 1;
rd[index].current_state = g_pcsc_reader_states[index].readerState;
rd[index].event_state = g_pcsc_reader_states[index].eventCounter;
rd[index].atr_len = g_pcsc_reader_states[index].cardAtrLength;
g_memcpy(rd[index].atr, g_pcsc_reader_states[index].cardAtr, 33);
} }
#endif rsa = (READER_STATE *) g_malloc(sizeof(READER_STATE) * cReaders, 1);
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RSC; for (index = 0; index < cReaders; index++)
scard_send_irp_get_status_change(con, JAY_TODO_CONTEXT, 1, in_rsc.timeOut, g_num_readers, {
g_xrdp_reader_states); in_uint8a(in_s, rsa[index].reader_name, 100);
LLOGLN(10, ("scard_process_get_status_change: reader_name %s",
rsa[index].reader_name));
in_uint32_le(in_s, rsa[index].current_state);
LLOGLN(10, ("scard_process_get_status_change: current_state %d",
rsa[index].current_state));
in_uint32_le(in_s, rsa[index].event_state);
LLOGLN(10, ("scard_process_get_status_change: event_state %d",
rsa[index].event_state));
in_uint32_le(in_s, rsa[index].atr_len);
LLOGLN(10, ("scard_process_get_status_change: atr_len %d",
rsa[index].atr_len));
in_uint8a(in_s, rsa[index].atr, 36);
}
LLOGLN(0, ("scard_process_read_state_change: timeout %d rv %d", LLOGLN(0, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
in_rsc.timeOut, in_rsc.rv)); "%d cReaders %d", hContext, dwTimeout, cReaders));
add_timeout(in_rsc.timeOut, scard_read_state_chage_timeout, con); g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
return 0; scard_send_irp_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa);
}
/*****************************************************************************/ g_free(rsa);
/* returns error */
int APP_CC
scard_process_stop_read_state_change(struct trans *con, struct stream *in_s)
{
struct wait_reader_state_change in_rsc;
struct wait_reader_state_change out_rsc;
struct stream *out_s;
LLOGLN(0, ("scard_process_stop_read_state_change:"));
in_uint8a(in_s, &in_rsc, sizeof(in_rsc));
LLOGLN(0, ("scard_process_stop_read_state_change: timeout %d rv %d",
in_rsc.timeOut, in_rsc.rv));
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RSC)
{
out_s = trans_get_out_s(con, 8192);
out_rsc.timeOut = in_rsc.timeOut;
out_rsc.rv = SCARD_S_SUCCESS;
out_uint8a(out_s, &out_rsc, sizeof(out_rsc));
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RSC;
s_mark_end(out_s);
return trans_force_write(con);
}
else
{
LLOGLN(0, ("scard_process_stop_read_state_change: already stopped"));
}
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */
int APP_CC int APP_CC
scard_function_get_status_change_return(struct trans *con, scard_function_get_status_change_return(struct trans *con,
struct stream *in_s, struct stream *in_s,
int len) int len)
{ {
struct stream *out_s; int bytes;
int num_readers;
int index; int index;
int current_state; int cReaders;
int event_state; tui32 current_state;
int atr_len; tui32 event_state;
char atr[36]; tui32 atr_len; /* number of bytes in atr[] */
tui8 atr[36];
struct stream *out_s;
LLOGLN(0, ("scard_function_get_status_change_return:")); LLOGLN(0, ("scard_function_get_status_change_return:"));
g_hexdump(in_s->p, len);
//g_hexdump(in_s->p, len); if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0)
{
LLOGLN(0, ("scard_function_establish_context_return: opps"));
return 1;
}
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;
in_uint8s(in_s, 28); in_uint8s(in_s, 28);
in_uint32_le(in_s, num_readers); in_uint32_le(in_s, cReaders);
LLOGLN(0, (" num_reader %d", num_readers)); if (cReaders > 0)
{
g_num_readers = num_readers; out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
for (index = 0; index < num_readers; index++) out_uint32_le(out_s, cReaders);
for (index = 0; index < cReaders; index++)
{ {
in_uint32_le(in_s, current_state); in_uint32_le(in_s, current_state);
out_uint32_le(out_s, current_state);
in_uint32_le(in_s, event_state); in_uint32_le(in_s, event_state);
out_uint32_le(out_s, event_state);
in_uint32_le(in_s, atr_len); in_uint32_le(in_s, atr_len);
out_uint32_le(out_s, atr_len);
in_uint8a(in_s, atr, 36); in_uint8a(in_s, atr, 36);
LLOGLN(0, (" current_state 0x%8.8x event_state 0x%8.8x " out_uint8a(out_s, atr, 36);
"atr_len 0x%8.8x", current_state, event_state, atr_len)); }
g_xrdp_reader_states[index].current_state = current_state; out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
g_xrdp_reader_states[index].event_state = event_state; s_mark_end(out_s);
g_xrdp_reader_states[index].atr_len = atr_len; bytes = (int) (out_s->end - out_s->data);
g_memcpy(g_xrdp_reader_states[index].atr, atr, 36); s_pop_layer(out_s, iso_hdr);
out_uint32_le(out_s, bytes - 8);
out_uint32_le(out_s, 0x0C); /* SCARD_ESTABLISH_CONTEXT 0x0C */
return trans_force_write(con);
} }
//out_s = trans_get_out_s(con, 8192);
//out_uint8a(out_s, g_reader_states, sizeof(g_reader_states));
//s_mark_end(out_s);
//return trans_force_write(con);
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -533,11 +443,12 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
break; break;
case 0x02: /* SCARD_RELEASE_CONTEXT */ case 0x02: /* SCARD_RELEASE_CONTEXT */
LLOGLN(0, ("scard_process_msg: SCARD_RELEASE_CONTEXT")); LLOGLN(0, ("scard_process_msg: SCARD_RELEASE_CONTEXT"));
rv = scard_process_release_context(in_s); rv = scard_process_release_context(con, in_s);
break; break;
case 0x03: /* SCARD_LIST_READERS */ case 0x03: /* SCARD_LIST_READERS */
LLOGLN(0, ("scard_process_msg: SCARD_LIST_READERS")); LLOGLN(0, ("scard_process_msg: SCARD_LIST_READERS"));
rv = scard_process_list_readers(con, in_s);
break; break;
case 0x04: /* SCARD_CONNECT */ case 0x04: /* SCARD_CONNECT */
@ -574,6 +485,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
case 0x0C: /* SCARD_GET_STATUS_CHANGE */ case 0x0C: /* SCARD_GET_STATUS_CHANGE */
LLOGLN(0, ("scard_process_msg: SCARD_GET_STATUS_CHANGE")); LLOGLN(0, ("scard_process_msg: SCARD_GET_STATUS_CHANGE"));
rv = scard_process_get_status_change(con, in_s);
break; break;
case 0x0D: /* SCARD_CANCEL */ case 0x0D: /* SCARD_CANCEL */
@ -592,22 +504,6 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
LLOGLN(0, ("scard_process_msg: SCARD_SET_ATTRIB")); LLOGLN(0, ("scard_process_msg: SCARD_SET_ATTRIB"));
break; break;
case 0x11: /* CMD_VERSION */
LLOGLN(0, ("scard_process_msg: CMD_VERSION"));
rv = scard_process_version(con, in_s);
break;
case 0x12: /* CMD_GET_READERS_STATE */
LLOGLN(0, ("scard_process_msg: CMD_GET_READERS_STATE"));
rv = scard_process_get_readers_state(con, in_s);
break;
case 0x13: /* CMD_WAIT_READER_STATE_CHANGE */
LLOGLN(0, ("scard_process_msg: CMD_WAIT_READER_STATE_CHANGE"));
rv = scard_process_read_state_change(con, in_s);
break;
case 0x14: /* CMD_STOP_WAITING_READER_STATE_CHANGE */
LLOGLN(0, ("scard_process_msg: CMD_STOP_WAITING_READER_STATE_CHANGE"));
rv = scard_process_stop_read_state_change(con, in_s);
break;
default: default:
LLOGLN(0, ("scard_process_msg: unknown mtype 0x%4.4x", command)); LLOGLN(0, ("scard_process_msg: unknown mtype 0x%4.4x", command));
rv = 1; rv = 1;
@ -693,8 +589,6 @@ scard_pcsc_init(void)
int index; int index;
LLOGLN(0, ("scard_pcsc_init:")); LLOGLN(0, ("scard_pcsc_init:"));
g_memset(g_pcsc_reader_states, 0, sizeof(g_pcsc_reader_states));
g_memset(g_xrdp_reader_states, 0, sizeof(g_xrdp_reader_states));
if (g_lis == 0) if (g_lis == 0)
{ {
g_lis = trans_create(2, 8192, 8192); g_lis = trans_create(2, 8192, 8192);
@ -725,14 +619,6 @@ scard_pcsc_init(void)
port)); port));
return 1; return 1;
} }
g_snprintf(g_pub_file_name, 255, "%s/pcscd.pub", g_pcsclite_ipc_dir);
g_pub_file_fd = g_file_open(g_pub_file_name);
index = 0;
while (index < 65537)
{
g_file_write(g_pub_file_fd, "", 1);
index++;
}
} }
return 0; return 0;
} }
@ -749,8 +635,6 @@ scard_pcsc_deinit(void)
g_file_close(g_pub_file_fd); g_file_close(g_pub_file_fd);
g_pub_file_fd = 0; g_pub_file_fd = 0;
g_file_delete(g_pub_file_name);
g_pub_file_name[0] = 0;
if (g_remove_dir(g_pcsclite_ipc_dir) != 0) if (g_remove_dir(g_pcsclite_ipc_dir) != 0)
{ {

@ -28,13 +28,18 @@ int APP_CC scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout);
int APP_CC scard_pcsc_check_wait_objs(void); int APP_CC scard_pcsc_check_wait_objs(void);
int APP_CC scard_pcsc_init(void); int APP_CC scard_pcsc_init(void);
int APP_CC scard_pcsc_deinit(void); int APP_CC scard_pcsc_deinit(void);
int APP_CC scard_function_establish_context_return(struct trans *con, tui32 context); int APP_CC scard_function_establish_context_return(struct trans *con,
struct stream *in_s,
int len);
int APP_CC scard_function_release_context_return(struct trans *con,
struct stream *in_s,
int len);
int APP_CC scard_function_list_readers_return(struct trans *con, int APP_CC scard_function_list_readers_return(struct trans *con,
struct stream *in_s, struct stream *in_s,
int len); int len);
int APP_CC scard_function_get_status_change_return(struct trans *con, int APP_CC scard_function_get_status_change_return(struct trans *con,
struct stream *in_s, int len); struct stream *in_s,
int len);
#endif /* end #ifndef _SMARTCARD_PCSC_H */ #endif /* end #ifndef _SMARTCARD_PCSC_H */

Loading…
Cancel
Save