channel smartcard hardend

This commit is contained in:
Martin Haimberger 2015-07-03 04:09:03 -07:00
parent ba34ff6096
commit d9e2834a70
5 changed files with 872 additions and 503 deletions

View File

@ -5,6 +5,8 @@
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2011 Anthony Tong <atong@trustedcs.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -34,7 +36,7 @@
void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
{
DWORD nCount;
DWORD status;
LONG status;
HANDLE hEvents[2];
wMessage message;
SMARTCARD_DEVICE* smartcard;
@ -61,7 +63,11 @@ void* smartcard_context_thread(SMARTCARD_CONTEXT* pContext)
if (operation)
{
status = smartcard_irp_device_control_call(smartcard, operation);
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
{
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu", status);
break;
}
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) operation->irp);
@ -232,26 +238,30 @@ static WIN32ERROR smartcard_init(DEVICE* device)
return CHANNEL_RC_OK;
}
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
WIN32ERROR smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
void* key;
key = (void*) (size_t) irp->CompletionId;
ListDictionary_Remove(smartcard->rgOutstandingMessages, key);
irp->Complete(irp);
return irp->Complete(irp);
}
void* smartcard_process_irp_worker_proc(SMARTCARD_OPERATION* operation)
{
IRP* irp;
UINT32 status;
LONG status;
SMARTCARD_DEVICE* smartcard;
irp = operation->irp;
smartcard = (SMARTCARD_DEVICE*) irp->device;
status = smartcard_irp_device_control_call(smartcard, operation);
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
{
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu", status);
//TODO report error
}
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
@ -266,23 +276,30 @@ void* smartcard_process_irp_worker_proc(SMARTCARD_OPERATION* operation)
* http://musclecard.996296.n3.nabble.com/Multiple-threads-and-SCardGetStatusChange-td4430.html
*/
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
WIN32ERROR smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
void* key;
UINT32 status;
LONG status;
BOOL asyncIrp = FALSE;
SMARTCARD_CONTEXT* pContext = NULL;
SMARTCARD_OPERATION* operation = NULL;
key = (void*) (size_t) irp->CompletionId;
ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp);
if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp))
{
WLog_ERR(TAG, "ListDictionary_Add failed!");
return ERROR_INTERNAL_ERROR;
}
if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
operation = (SMARTCARD_OPERATION*) calloc(1, sizeof(SMARTCARD_OPERATION));
if (!operation)
return;
{
WLog_ERR(TAG, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
operation->irp = irp;
@ -290,11 +307,15 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
if (status != SCARD_S_SUCCESS)
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
irp->IoStatus = (UINT32)STATUS_UNSUCCESSFUL;
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp))
{
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
}
return;
return CHANNEL_RC_OK;
}
asyncIrp = TRUE;
@ -375,15 +396,27 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
if (!asyncIrp)
{
status = smartcard_irp_device_control_call(smartcard, operation);
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
if ((status = smartcard_irp_device_control_call(smartcard, operation)))
{
WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %lu!", status);
return (UINT32)status;
}
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp))
{
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
}
free(operation);
}
else
{
if (pContext)
{
MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*) operation, NULL);
if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*) operation, NULL))
{
WLog_ERR(TAG, "MessageQueue_Post failed!");
return ERROR_INTERNAL_ERROR;
}
}
}
}
@ -391,10 +424,15 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp)
{
WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X",
irp->MajorFunction, irp->MinorFunction);
irp->IoStatus = STATUS_NOT_SUPPORTED;
irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED;
Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp);
if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp))
{
WLog_ERR(TAG, "Queue_Enqueue failed!");
return ERROR_INTERNAL_ERROR;
}
}
return CHANNEL_RC_OK;
}
static void* smartcard_thread_func(void* arg)
@ -405,6 +443,7 @@ static void* smartcard_thread_func(void* arg)
HANDLE hEvents[2];
wMessage message;
SMARTCARD_DEVICE* smartcard = (SMARTCARD_DEVICE*) arg;
WIN32ERROR error = CHANNEL_RC_OK;
nCount = 0;
hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue);
@ -434,7 +473,11 @@ static void* smartcard_thread_func(void* arg)
irp->thread = NULL;
}
smartcard_complete_irp(smartcard, irp);
if ((error = smartcard_complete_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
goto out;
}
}
}
@ -445,7 +488,11 @@ static void* smartcard_thread_func(void* arg)
if (irp)
{
smartcard_process_irp(smartcard, irp);
if ((error = smartcard_process_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_process_irp failed with error %lu!", error);
goto out;
}
}
}
@ -462,12 +509,17 @@ static void* smartcard_thread_func(void* arg)
irp->thread = NULL;
}
smartcard_complete_irp(smartcard, irp);
if ((error = smartcard_complete_irp(smartcard, irp)))
{
WLog_ERR(TAG, "smartcard_complete_irp failed with error %lu!", error);
goto out;
}
}
}
ExitThread(0);
}
out:
//TODO signal error
ExitThread((DWORD)error);
return NULL;
}
@ -481,13 +533,15 @@ static WIN32ERROR smartcard_irp_request(DEVICE* device, IRP* irp)
/* smartcard is always built-in */
#define DeviceServiceEntry smartcard_DeviceServiceEntry
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
WIN32ERROR DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
char* name;
char* path;
int length, ck;
size_t length;
int ck;
RDPDR_SMARTCARD* device;
SMARTCARD_DEVICE* smartcard;
WIN32ERROR error = CHANNEL_RC_NO_MEMORY;
device = (RDPDR_SMARTCARD*) pEntryPoints->device;
@ -496,7 +550,10 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE));
if (!smartcard)
return -1;
{
WLog_ERR(TAG, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
smartcard->device.type = RDPDR_DTYP_SMARTCARD;
smartcard->device.name = "SCARD";
@ -507,7 +564,10 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
length = strlen(smartcard->device.name);
smartcard->device.data = Stream_New(NULL, length + 1);
if (!smartcard->device.data)
{
WLog_ERR(TAG, "Stream_New failed!");
goto error_device_data;
}
Stream_Write(smartcard->device.data, "SCARD", 6);
@ -529,33 +589,55 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
smartcard->IrpQueue = MessageQueue_New(NULL);
if (!smartcard->IrpQueue)
{
WLog_ERR(TAG, "MessageQueue_New failed!");
goto error_irp_queue;
}
smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1);
if (!smartcard->CompletedIrpQueue)
{
WLog_ERR(TAG, "Queue_New failed!");
goto error_completed_irp_queue;
}
smartcard->rgSCardContextList = ListDictionary_New(TRUE);
if (!smartcard->rgSCardContextList)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
goto error_context_list;
}
ListDictionary_ValueObject(smartcard->rgSCardContextList)->fnObjectFree =
(OBJECT_FREE_FN) smartcard_context_free;
smartcard->rgOutstandingMessages = ListDictionary_New(TRUE);
if (!smartcard->rgOutstandingMessages)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
goto error_outstanding_messages;
}
if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard)))
{
WLog_ERR(TAG, "RegisterDevice failed!");
goto error_outstanding_messages;
}
smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func,
smartcard, CREATE_SUSPENDED, NULL);
if (!smartcard->thread)
{
WLog_ERR(TAG, "ListDictionary_New failed!");
error = ERROR_INTERNAL_ERROR;
goto error_thread;
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) smartcard);
}
ResumeThread(smartcard->thread);
return 0;
return CHANNEL_RC_OK;
error_thread:
ListDictionary_Free(smartcard->rgOutstandingMessages);
@ -569,6 +651,6 @@ error_irp_queue:
Stream_Free(smartcard->device.data, TRUE);
error_device_data:
free(smartcard);
return -1;
return error;
}

View File

@ -4,6 +4,8 @@
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -122,11 +124,11 @@ struct _SMARTCARD_DEVICE
SMARTCARD_CONTEXT* smartcard_context_new(SMARTCARD_DEVICE* smartcard, SCARDCONTEXT hContext);
void smartcard_context_free(SMARTCARD_CONTEXT* pContext);
void smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
WIN32ERROR smartcard_complete_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
WIN32ERROR smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp);
UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
UINT32 smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
LONG smartcard_irp_device_control_call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation);
#include "smartcard_pack.h"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
* Smart Card Structure Packing
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -434,8 +436,8 @@ typedef struct _WriteCacheW_Call
#include "smartcard_main.h"
UINT32 smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment);
UINT32 smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment);
LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment);
LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 size, UINT32 alignment);
SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDCONTEXT* context);
void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext);
@ -443,96 +445,96 @@ void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_
SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle);
void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle, SCARDHANDLE hCard);
UINT32 smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
UINT32 smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
LONG smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
UINT32 smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
UINT32 smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength);
LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s);
LONG smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s, UINT32 objectBufferLength);
UINT32 smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
UINT32 smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
LONG smartcard_unpack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
UINT32 smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
UINT32 smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDCONTEXT* context);
UINT32 smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
UINT32 smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
LONG smartcard_unpack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
UINT32 smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
UINT32 smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s, REDIR_SCARDHANDLE* handle);
UINT32 smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Call* call);
LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Call* call);
void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard, EstablishContext_Call* call);
UINT32 smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Return* ret);
LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s, EstablishContext_Return* ret);
void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard, EstablishContext_Return* ret);
UINT32 smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call);
LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call);
void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, Context_Call* call, const char* name);
void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, Long_Return* ret, const char* name);
UINT32 smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call);
LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Call* call);
void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard, ListReaders_Call* call, BOOL unicode);
UINT32 smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Return* ret);
LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Return* ret);
void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard, ListReaders_Return* ret, BOOL unicode);
UINT32 smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call);
LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call);
void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, ConnectA_Call* call);
UINT32 smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call);
LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call);
void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, ConnectW_Call* call);
UINT32 smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Connect_Return* ret);
LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Connect_Return* ret);
void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, Connect_Return* ret);
UINT32 smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call);
LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call);
void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, Reconnect_Call* call);
UINT32 smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Return* ret);
LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Return* ret);
void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, Reconnect_Return* ret);
UINT32 smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, HCardAndDisposition_Call* call);
LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s, HCardAndDisposition_Call* call);
void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, HCardAndDisposition_Call* call, const char* name);
UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeA_Call* call);
LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeA_Call* call);
void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeA_Call* call);
UINT32 smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call);
LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChangeW_Call* call);
void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, GetStatusChangeW_Call* call);
UINT32 smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChange_Return* ret);
LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetStatusChange_Return* ret);
void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard, GetStatusChange_Return* ret, BOOL unicode);
UINT32 smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call);
UINT32 smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret);
LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call);
LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, State_Return* ret);
UINT32 smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call);
LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call);
void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, Status_Call* call, BOOL unicode);
UINT32 smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Return* ret);
LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Return* ret);
void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, Status_Return* ret, BOOL unicode);
UINT32 smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call);
LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call);
void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, GetAttrib_Call* call);
UINT32 smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret);
LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Return* ret);
void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard, GetAttrib_Return* ret, DWORD dwAttrId);
UINT32 smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call);
LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call);
void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, Control_Call* call);
UINT32 smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Return* ret);
LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Return* ret);
void smartcard_trace_control_return(SMARTCARD_DEVICE* smartcard, Control_Return* ret);
UINT32 smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call);
LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call);
void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, Transmit_Call* call);
UINT32 smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Return* ret);
LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Return* ret);
void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, Transmit_Return* ret);
UINT32 smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call);
LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, LocateCardsByATRA_Call* call);
void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, LocateCardsByATRA_Call* call);